MythTV  master
mythnvdeccontext.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythlogging.h"
3 #include "mythmainwindow.h"
4 #include "avformatdecoder.h"
5 #include "mythnvdecinterop.h"
6 #include "mythvideoout.h"
7 #include "mythnvdeccontext.h"
8 
9 extern "C" {
10 #include "libavutil/opt.h"
11 }
12 
13 #define LOC QString("NVDEC: ")
14 
15 
17  : MythCodecContext(Parent, CodecID)
18 {
19 }
20 
22 {
23  av_buffer_unref(&m_framesContext);
24 }
25 
35  AVCodec **Codec,
36  const QString &Decoder,
37  AVStream *Stream,
38  uint StreamType)
39 {
40  bool decodeonly = Decoder == "nvdec-dec";
41  auto success = static_cast<MythCodecID>((decodeonly ? kCodec_MPEG1_NVDEC_DEC : kCodec_MPEG1_NVDEC) + (StreamType - 1));
42  auto failure = static_cast<MythCodecID>(kCodec_MPEG1 + (StreamType - 1));
43 
44  // no brainers
45  if (!Decoder.startsWith("nvdec") || getenv("NO_NVDEC") || !HaveNVDEC() || IsUnsupportedProfile(*Context))
46  return failure;
47 
48  QString codecstr = ff_codec_id_string((*Context)->codec_id);
49  QString profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
50  QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);
51 
52  cudaVideoCodec cudacodec = cudaVideoCodec_NumCodecs;
53  switch ((*Context)->codec_id)
54  {
55  case AV_CODEC_ID_MPEG1VIDEO: cudacodec = cudaVideoCodec_MPEG1; break;
56  case AV_CODEC_ID_MPEG2VIDEO: cudacodec = cudaVideoCodec_MPEG2; break;
57  case AV_CODEC_ID_MPEG4: cudacodec = cudaVideoCodec_MPEG4; break;
58  case AV_CODEC_ID_VC1: cudacodec = cudaVideoCodec_VC1; break;
59  case AV_CODEC_ID_H264: cudacodec = cudaVideoCodec_H264; break;
60  case AV_CODEC_ID_HEVC: cudacodec = cudaVideoCodec_HEVC; break;
61  case AV_CODEC_ID_VP8: cudacodec = cudaVideoCodec_VP8; break;
62  case AV_CODEC_ID_VP9: cudacodec = cudaVideoCodec_VP9; break;
63  default: break;
64  }
65 
66  cudaVideoChromaFormat cudaformat = cudaVideoChromaFormat_Monochrome;
67  VideoFrameType type = PixelFormatToFrameType((*Context)->pix_fmt);
68  // N.B. on stream changes format is set to CUDA/NVDEC. This may break if the new
69  // stream has an unsupported chroma but the decoder should fail gracefully - just later.
70  if ((FMT_NVDEC == type) || (format_is_420(type)))
71  cudaformat = cudaVideoChromaFormat_420;
72  else if (format_is_422(type))
73  cudaformat = cudaVideoChromaFormat_422;
74  else if (format_is_444(type))
75  cudaformat = cudaVideoChromaFormat_444;
76 
77  uint depth = static_cast<uint>(ColorDepth(type) - 8);
78  bool supported = false;
79 
80  if ((cudacodec == cudaVideoCodec_NumCodecs) || (cudaformat == cudaVideoChromaFormat_Monochrome))
81  return failure;
82 
83  // iterate over known decoder capabilities
84  const std::vector<MythNVDECCaps>& profiles = MythNVDECContext::GetProfiles();
85  for (auto cap : profiles)
86  {
87  if (cap.Supports(cudacodec, cudaformat, depth, (*Context)->width, (*Context)->width))
88  {
89  supported = true;
90  break;
91  }
92  }
93 
94  QString desc = QString("'%1 %2 %3 Depth:%4 %5x%6'")
95  .arg(codecstr).arg(profile).arg(pixfmt).arg(depth + 8)
96  .arg((*Context)->width).arg((*Context)->height);
97 
98  // and finally try and retrieve the actual FFmpeg decoder
99  if (supported)
100  {
101  for (int i = 0; ; i++)
102  {
103  const AVCodecHWConfig *config = avcodec_get_hw_config(*Codec, i);
104  if (!config)
105  break;
106 
107  if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) &&
108  (config->device_type == AV_HWDEVICE_TYPE_CUDA))
109  {
110  QString name = QString((*Codec)->name) + "_cuvid";
111  if (name == "mpeg2video_cuvid")
112  name = "mpeg2_cuvid";
113  AVCodec *codec = avcodec_find_decoder_by_name(name.toLocal8Bit());
114  if (codec)
115  {
116  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("NVDEC supports decoding %1").arg(desc));
117  *Codec = codec;
118  gCodecMap->freeCodecContext(Stream);
119  *Context = gCodecMap->getCodecContext(Stream, *Codec);
120  return success;
121  }
122  break;
123  }
124  }
125  }
126 
127  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("NVDEC does NOT support %1").arg(desc));
128  return failure;
129 }
130 
132 {
133  if (!gCoreContext->IsUIThread() || !Context)
134  return -1;
135 
136  // We need a player to release the interop
137  MythPlayer *player = nullptr;
138  auto *decoder = reinterpret_cast<AvFormatDecoder*>(Context->opaque);
139  if (decoder)
140  player = decoder->GetPlayer();
141  if (!player)
142  return -1;
143 
144  // Retrieve OpenGL render context
146  if (!render)
147  return -1;
148  OpenGLLocker locker(render);
149 
150  // Check interop type
152  return -1;
153 
154  // Create interop (and CUDA context)
155  MythNVDECInterop *interop = MythNVDECInterop::Create(render);
156  if (!interop)
157  return -1;
158  if (!interop->IsValid())
159  {
160  interop->DecrRef();
161  return -1;
162  }
163 
164  // Set player
165  interop->SetPlayer(player);
166 
167  // Allocate the device context
168  AVBufferRef* hwdeviceref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
169  if (!hwdeviceref)
170  {
171  interop->DecrRef();
172  return -1;
173  }
174 
175  // Set release method, interop and CUDA context
176  auto* hwdevicecontext = reinterpret_cast<AVHWDeviceContext*>(hwdeviceref->data);
177  hwdevicecontext->free = &MythCodecContext::DeviceContextFinished;
178  hwdevicecontext->user_opaque = interop;
179  auto *devicehwctx = reinterpret_cast<AVCUDADeviceContext*>(hwdevicecontext->hwctx);
180  devicehwctx->cuda_ctx = interop->GetCUDAContext();
181  devicehwctx->stream = nullptr;
182 
183  if (av_hwdevice_ctx_init(hwdeviceref) < 0)
184  {
185  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to init CUDA hw device");
186  av_buffer_unref(&hwdeviceref);
187  return -1;
188  }
189 
190  Context->hw_device_ctx = hwdeviceref;
191  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created CUDA device context");
192  return 0;
193 }
194 
195 void MythNVDECContext::InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
196 {
198  {
199  Context->get_format = MythNVDECContext::GetFormat;
200  DirectRendering = false;
201  return;
202  }
203 
204  MythCodecContext::InitVideoCodec(Context, SelectedStream, DirectRendering);
205 }
206 
208 {
210  {
212  "Create NVDEC decoder");
213  }
215  {
216  AVBufferRef *context = MythCodecContext::CreateDevice(AV_HWDEVICE_TYPE_CUDA, nullptr,
217  gCoreContext->GetSetting("NVDECDevice"));
218  if (context)
219  {
220  Context->hw_device_ctx = context;
221  return 0;
222  }
223  }
224  return -1;
225 }
226 
234  VideoDisplayProfile *Profile, bool DoubleRate)
235 {
236  if (!Context)
237  return;
238 
239  // Don't enable for anything that cannot be interlaced
240  // We could use frame rate here but initial frame rate detection is not always accurate
241  // and we lose little by enabling deinterlacing. NVDEC will not deinterlace a
242  // progressive stream and any CUDA capable video card has memory to spare
243  // (assuming it even sets up deinterlacing for a progressive stream)
244  if (Context->height == 720) // 720P
245  return;
246 
247  MythDeintType deinterlacer = DEINT_NONE;
248  MythDeintType singlepref = DEINT_NONE;
249  MythDeintType doublepref = DEINT_NONE;
250  if (Profile)
251  {
253  if (DoubleRate)
255  }
256 
257  // Deinterlacers are not filtered (as we have no frame) - so mask appropriately
258  MythDeintType singledeint = singlepref & (DEINT_BASIC | DEINT_MEDIUM | DEINT_HIGH);
259  MythDeintType doubledeint = doublepref & (DEINT_BASIC | DEINT_MEDIUM | DEINT_HIGH);
260 
261  // With decode only/copy back, we can deinterlace here or the frames can use
262  // either CPU or shader deints. So only accept a driver deinterlacer preference.
263 
264  // When direct rendering, there is no CPU option but shaders can be used.
265  // Assume driver deints are higher quality so accept a driver preference or CPU
266  // if shader is not preferred
267  bool other = false;
269  {
270  if (DoubleRate)
271  {
272  if (doubledeint)
273  {
274  if (doublepref & (DEINT_DRIVER))
275  deinterlacer = doubledeint;
276  else if (doublepref & (DEINT_CPU | DEINT_SHADER))
277  other = true;
278  }
279  else
280  {
281  DoubleRate = false;
282  }
283  }
284 
285  if (!deinterlacer && !other && (singlepref & DEINT_DRIVER))
286  deinterlacer = singledeint;
287  }
288  else if (codec_is_nvdec(m_codecID))
289  {
290  if (DoubleRate)
291  {
292  if (doubledeint)
293  {
294  if (doublepref & (DEINT_DRIVER | DEINT_CPU))
295  deinterlacer = doubledeint;
296  else if (doublepref & DEINT_SHADER)
297  other = true;
298  }
299  else
300  {
301  DoubleRate = false;
302  }
303  }
304 
305  if (!deinterlacer && !other && singledeint)
306  {
307  if (singlepref & (DEINT_DRIVER | DEINT_CPU))
308  deinterlacer = singledeint;
309  else if (singlepref & DEINT_SHADER)
310  { }
311  }
312  }
313 
314  if (deinterlacer == DEINT_NONE)
315  return;
316 
317  QString mode = "adaptive";
318  if (DEINT_BASIC == deinterlacer)
319  mode = "bob";
320  int result = av_opt_set(Context->priv_data, "deint", mode.toLocal8Bit(), 0);
321  if (result == 0)
322  {
323  if (av_opt_set_int(Context->priv_data, "drop_second_field", static_cast<int>(!DoubleRate), 0) == 0)
324  {
325  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Setup decoder deinterlacer '%1'")
326  .arg(DeinterlacerName(deinterlacer | DEINT_DRIVER, DoubleRate, FMT_NVDEC)));
327  m_deinterlacer = deinterlacer;
328  m_deinterlacer2x = DoubleRate;
329  }
330  }
331 }
332 
333 void MythNVDECContext::PostProcessFrame(AVCodecContext* /*Context*/, VideoFrame *Frame)
334 {
335  // Remove interlacing flags and set deinterlacer if necessary
336  if (Frame && m_deinterlacer)
337  {
338  Frame->interlaced_frame = 0;
339  Frame->interlaced_reversed = 0;
340  Frame->top_field_first = 0;
341  Frame->deinterlace_inuse = m_deinterlacer | DEINT_DRIVER;
342  Frame->deinterlace_inuse2x = m_deinterlacer2x;
343  Frame->already_deinterlaced = 1;
344  }
345 }
346 
348 {
349  return codec_is_nvdec(m_codecID);
350 }
351 
352 bool MythNVDECContext::IsDeinterlacing(bool &DoubleRate, bool /*unused*/)
353 {
354  if (m_deinterlacer != DEINT_NONE)
355  {
356  DoubleRate = m_deinterlacer2x;
357  return true;
358  }
359  DoubleRate = false;
360  return false;
361 }
362 
363 enum AVPixelFormat MythNVDECContext::GetFormat(AVCodecContext* Context, const AVPixelFormat *PixFmt)
364 {
365  while (*PixFmt != AV_PIX_FMT_NONE)
366  {
367  if (*PixFmt == AV_PIX_FMT_CUDA)
368  {
369  AvFormatDecoder* decoder = reinterpret_cast<AvFormatDecoder*>(Context->opaque);
370  if (decoder)
371  {
372  MythNVDECContext* me = dynamic_cast<MythNVDECContext*>(decoder->GetMythCodecContext());
373  if (me)
375  }
376  return AV_PIX_FMT_CUDA;
377  }
378  PixFmt++;
379  }
380  return AV_PIX_FMT_NONE;
381 }
382 
384 {
385  if (AvFrame->format != AV_PIX_FMT_CUDA)
386  return false;
388  return RetrieveHWFrame(Frame, AvFrame);
390  return GetBuffer(Context, Frame, AvFrame, 0);
391  return false;
392 }
393 
399 bool MythNVDECContext::GetBuffer(struct AVCodecContext *Context, VideoFrame *Frame,
400  AVFrame *AvFrame, int /*Flags*/)
401 {
402  if ((AvFrame->format != AV_PIX_FMT_CUDA) || !AvFrame->data[0])
403  {
404  LOG(VB_GENERAL, LOG_ERR, LOC + "Not a valid CUDA hw frame");
405  return false;
406  }
407 
408  if (!Context || !Frame)
409  return false;
410 
411  auto *decoder = static_cast<AvFormatDecoder*>(Context->opaque);
412 
413  for (int i = 0; i < 3; i++)
414  {
415  Frame->pitches[i] = AvFrame->linesize[i];
416  Frame->offsets[i] = AvFrame->data[i] ? (static_cast<int>(AvFrame->data[i] - AvFrame->data[0])) : 0;
417  Frame->priv[i] = nullptr;
418  }
419 
420  Frame->width = AvFrame->width;
421  Frame->height = AvFrame->height;
422  Frame->pix_fmt = Context->pix_fmt;
423  Frame->directrendering = 1;
424 
425  AvFrame->opaque = Frame;
426  AvFrame->reordered_opaque = Context->reordered_opaque;
427 
428  // set the pixel format - normally NV12 but P010 for 10bit etc. Set here rather than guessing later.
429  if (AvFrame->hw_frames_ctx)
430  {
431  auto *context = reinterpret_cast<AVHWFramesContext*>(AvFrame->hw_frames_ctx->data);
432  if (context)
433  Frame->sw_pix_fmt = context->sw_format;
434  }
435 
436  // NVDEC 'fixes' 10/12/16bit colour values
437  Frame->colorshifted = 1;
438 
439  // Frame->data[0] holds CUdeviceptr for the frame data - offsets calculated above
440  Frame->buf = AvFrame->data[0];
441 
442  // Retain the buffer so it is not released before we display it
443  Frame->priv[0] = reinterpret_cast<unsigned char*>(av_buffer_ref(AvFrame->buf[0]));
444 
445  // We need the CUDA device context in the interop class and it also holds the reference
446  // to the interop class itself
447  Frame->priv[1] = reinterpret_cast<unsigned char*>(av_buffer_ref(Context->hw_device_ctx));
448 
449  // Set the release method
450  AvFrame->buf[1] = av_buffer_create(reinterpret_cast<uint8_t*>(Frame), 0,
451  MythCodecContext::ReleaseBuffer, decoder, 0);
452  return true;
453 }
454 
455 MythNVDECContext::MythNVDECCaps::MythNVDECCaps(cudaVideoCodec Codec, uint Depth, cudaVideoChromaFormat Format,
456  QSize Minimum, QSize Maximum, uint MacroBlocks)
457  : m_codec(Codec),
458  m_depth(Depth),
459  m_format(Format),
460  m_minimum(Minimum),
461  m_maximum(Maximum),
462  m_macroBlocks(MacroBlocks)
463 {
464  auto ToMythProfile = [](cudaVideoCodec CudaCodec)
465  {
466  switch (CudaCodec)
467  {
468  case cudaVideoCodec_MPEG1: return MythCodecContext::MPEG1;
469  case cudaVideoCodec_MPEG2: return MythCodecContext::MPEG2;
470  case cudaVideoCodec_MPEG4: return MythCodecContext::MPEG4;
471  case cudaVideoCodec_VC1: return MythCodecContext::VC1;
472  case cudaVideoCodec_H264: return MythCodecContext::H264;
473  case cudaVideoCodec_HEVC: return MythCodecContext::HEVC;
474  case cudaVideoCodec_VP8: return MythCodecContext::VP8;
475  case cudaVideoCodec_VP9: return MythCodecContext::VP9;
476  default: break;
477  }
479  };
480 
481  auto ToMythFormat = [](cudaVideoChromaFormat CudaFormat)
482  {
483  switch (CudaFormat)
484  {
485  case cudaVideoChromaFormat_420: return FMT_YV12;
486  case cudaVideoChromaFormat_422: return FMT_YUV422P;
487  case cudaVideoChromaFormat_444: return FMT_YUV444P;
488  default: break;
489  }
490  return FMT_NONE;
491  };
492  m_profile = ToMythProfile(m_codec);
493  m_type = ToMythFormat(m_format);
494 }
495 
496 bool MythNVDECContext::MythNVDECCaps::Supports(cudaVideoCodec Codec, cudaVideoChromaFormat Format,
497  uint Depth, int Width, int Height)
498 {
499  uint mblocks = static_cast<uint>((Width * Height) / 256);
500  return (Codec == m_codec) && (Format == m_format) && (Depth == m_depth) &&
501  (m_maximum.width() >= Width) && (m_maximum.height() >= Height) &&
502  (m_minimum.width() <= Width) && (m_minimum.height() <= Height) &&
503  (m_macroBlocks >= mblocks);
504 }
505 
507 {
508  static QMutex lock(QMutex::Recursive);
509  QMutexLocker locker(&lock);
510  static bool s_checked = false;
511  static bool s_available = false;
512  if (!s_checked)
513  {
514  if (gCoreContext->IsUIThread())
515  {
516  const std::vector<MythNVDECCaps>& profiles = MythNVDECContext::GetProfiles();
517  if (profiles.empty())
518  {
519  LOG(VB_GENERAL, LOG_INFO, LOC + "No NVDEC decoders found");
520  }
521  else
522  {
523  s_available = true;
524  LOG(VB_GENERAL, LOG_INFO, LOC + "Supported/available NVDEC decoders:");
525  for (auto profile : profiles)
526  {
527  LOG(VB_GENERAL, LOG_INFO, LOC +
529  profile.m_type, profile.m_depth + 8));
530  }
531  }
532  }
533  else
534  {
535  LOG(VB_GENERAL, LOG_WARNING, LOC + "HaveNVDEC must be initialised from the main thread");
536  }
537  }
538  s_checked = true;
539  return s_available;
540 }
541 
542 
543 void MythNVDECContext::GetDecoderList(QStringList &Decoders)
544 {
545  const std::vector<MythNVDECCaps>& profiles = MythNVDECContext::GetProfiles();
546  if (profiles.empty())
547  return;
548  Decoders.append("NVDEC:");
549  for (auto profile : profiles)
550  if (!(profile.m_depth % 2)) // Ignore 9/11bit etc
551  Decoders.append(MythCodecContext::GetProfileDescription(profile.m_profile, profile.m_maximum,
552  profile.m_type, profile.m_depth + 8));
553 }
554 
555 const std::vector<MythNVDECContext::MythNVDECCaps> &MythNVDECContext::GetProfiles(void)
556 {
557  static QMutex lock(QMutex::Recursive);
558  static bool s_initialised = false;
559  static std::vector<MythNVDECContext::MythNVDECCaps> s_profiles;
560 
561  QMutexLocker locker(&lock);
562  if (s_initialised)
563  return s_profiles;
564  s_initialised = true;
565 
567  CUcontext context = nullptr;
568  CudaFunctions *cuda = nullptr;
569  if (MythNVDECInterop::CreateCUDAContext(opengl, cuda, context))
570  {
571  OpenGLLocker gllocker(opengl);
572  CuvidFunctions *cuvid = nullptr;
573  CUcontext dummy = nullptr;
574  cuda->cuCtxPushCurrent(context);
575 
576  if (cuvid_load_functions(&cuvid, nullptr) == 0)
577  {
578  // basic check passed
579  if (!cuvid->cuvidGetDecoderCaps)
580  LOG(VB_GENERAL, LOG_WARNING, LOC + "Old driver - cannot check decoder capabilities");
581 
582  // now iterate over codecs, depths and formats to check support
583  for (int codec = cudaVideoCodec_MPEG1; codec < cudaVideoCodec_NumCodecs; ++codec)
584  {
585  auto cudacodec = static_cast<cudaVideoCodec>(codec);
586  if (cudacodec == cudaVideoCodec_JPEG)
587  continue;
588  for (int format = cudaVideoChromaFormat_420; format < cudaVideoChromaFormat_444; ++format)
589  {
590  auto cudaformat = static_cast<cudaVideoChromaFormat>(format);
591  for (uint depth = 0; depth < 9; ++depth)
592  {
593  CUVIDDECODECAPS caps;
594  caps.eCodecType = cudacodec;
595  caps.eChromaFormat = cudaformat;
596  caps.nBitDepthMinus8 = depth;
597  // N.B. cuvidGetDecoderCaps was not available on older drivers
598  if (cuvid->cuvidGetDecoderCaps && (cuvid->cuvidGetDecoderCaps(&caps) == CUDA_SUCCESS) &&
599  caps.bIsSupported)
600  {
601  s_profiles.emplace_back(
602  MythNVDECCaps(cudacodec, depth, cudaformat,
603  QSize(caps.nMinWidth, caps.nMinHeight),
604  QSize(static_cast<int>(caps.nMaxWidth), static_cast<int>(caps.nMaxHeight)),
605  caps.nMaxMBCount));
606  }
607  else if (!cuvid->cuvidGetDecoderCaps)
608  {
609  // dummy - just support everything:)
610  s_profiles.emplace_back(MythNVDECCaps(cudacodec, depth, cudaformat,
611  QSize(32, 32), QSize(8192, 8192),
612  (8192 * 8192) / 256));
613  }
614  }
615  }
616  }
617  cuvid_free_functions(&cuvid);
618  }
619  cuda->cuCtxPopCurrent(&dummy);
620  }
621  MythNVDECInterop::CleanupContext(opengl, cuda, context);
622 
623  return s_profiles;
624 }
625 
627 {
628  if (!Context)
629  return;
630 
631  if (m_framesContext)
632  {
633  AVHWFramesContext *frames = reinterpret_cast<AVHWFramesContext*>(m_framesContext->data);
634  if ((frames->sw_format == Context->sw_pix_fmt) && (frames->width == Context->coded_width) &&
635  (frames->height == Context->coded_height))
636  {
637  Context->hw_frames_ctx = av_buffer_ref(m_framesContext);
638  return;
639  }
640  }
641 
642  // If this is a 'spontaneous' callback from FFmpeg (i.e. not on a stream change)
643  // then we must release any direct render buffers.
645  m_parent->GetPlayer()->DiscardVideoFrames(true, true);
646 
647  av_buffer_unref(&m_framesContext);
648 
649  AVBufferRef* framesref = av_hwframe_ctx_alloc(Context->hw_device_ctx);
650  AVHWFramesContext *frames = reinterpret_cast<AVHWFramesContext*>(framesref->data);
652  frames->user_opaque = nullptr;
653  frames->sw_format = Context->sw_pix_fmt;
654  frames->format = AV_PIX_FMT_CUDA;
655  frames->width = Context->coded_width;
656  frames->height = Context->coded_height;
657  if (av_hwframe_ctx_init(framesref) < 0)
658  {
659  av_buffer_unref(&framesref);
660  }
661  else
662  {
663  Context->hw_frames_ctx = framesref;
664  m_framesContext = av_buffer_ref(framesref);
666  }
667 }
MythPlayer * GetPlayer()
Definition: decoderbase.h:154
void PostProcessFrame(AVCodecContext *Context, VideoFrame *Frame) override
void SetPlayer(MythPlayer *Player)
static void ReleaseBuffer(void *Opaque, uint8_t *Data)
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
Definition: mythplayer.cpp:944
MythCodecContext * GetMythCodecContext(void)
Definition: decoderbase.h:267
QHash< QString, Action * > Context
Definition: action.h:77
static Type GetInteropType(VideoFrameType Format, MythPlayer *Player)
Check whether we support direct rendering for the given VideoFrameType.
MythCodecContext::CodecProfile m_profile
bool DecoderWillResetOnFlush(void) override
#define LOC
MythCodecID
Definition: mythcodecid.h:10
CUcontext GetCUDAContext(void)
static QString GetProfileDescription(CodecProfile Profile, QSize Size, VideoFrameType Format=FMT_NONE, uint ColorDepth=0)
struct AVFrame AVFrame
static bool HaveNVDEC(void)
int HwDecoderInit(AVCodecContext *Context) override
void InitFramesContext(AVCodecContext *Context)
cudaVideoChromaFormat m_format
static void CleanupContext(MythRenderOpenGL *GLContext, CudaFunctions *&CudaFuncs, CUcontext &CudaContext)
VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt)
Definition: mythavutil.cpp:68
VideoFrameType
Definition: mythframe.h:23
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static bool IsUnsupportedProfile(AVCodecContext *Context)
Most hardware decoders do not support these codecs/profiles.
bool IsDeinterlacing(bool &DoubleRate, bool StreamChange=false) override
int ColorDepth(int Format)
Return the color depth for the given MythTV frame format.
Definition: mythframe.cpp:815
void freeCodecContext(const AVStream *stream)
Definition: mythavutil.cpp:557
DecoderBase * m_parent
MythCodecID m_codecID
MythDeintType
Definition: mythframe.h:120
static int format_is_420(VideoFrameType Type)
Definition: mythframe.h:85
AVBufferRef * m_framesContext
MythNVDECContext(DecoderBase *Parent, MythCodecID CodecID)
QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format)
Return a user friendly description of the given deinterlacer.
Definition: mythavutil.cpp:114
#define codec_is_nvdec_dec(id)
Definition: mythcodecid.h:330
static int format_is_444(VideoFrameType Type)
Definition: mythframe.h:97
static MythDeintType ParseDeinterlacer(const QString &Deinterlacer)
void SetDeinterlacing(AVCodecContext *Context, VideoDisplayProfile *Profile, bool DoubleRate) override
Enable NVDEC/CUDA deinterlacing if necessary.
static int InitialiseDecoder2(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is NOT expected to use AVHWFramesContext.
MythCodecMap * gCodecMap
This global variable contains the MythCodecMap instance for the app.
Definition: mythavutil.cpp:508
AVCodecContext * getCodecContext(const AVStream *stream, const AVCodec *pCodec=nullptr, bool nullCodec=false)
Definition: mythavutil.cpp:515
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
QString GetSetting(const QString &key, const QString &defaultval="")
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
A decoder for video files.
static int format_is_422(VideoFrameType Type)
Definition: mythframe.h:91
unsigned int uint
Definition: compat.h:140
static MythCodecID GetSupportedCodec(AVCodecContext **CodecContext, AVCodec **Codec, const QString &Decoder, AVStream *Stream, uint StreamType)
Determine whether NVDEC decoding is supported for this codec.
static int InitialiseDecoder(AVCodecContext *Context)
static void FramesContextFinished(AVHWFramesContext *Context)
~MythNVDECContext() override
bool Supports(cudaVideoCodec Codec, cudaVideoChromaFormat Format, uint Depth, int Width, int Height)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
MythNVDECCaps(cudaVideoCodec Codec, uint Depth, cudaVideoChromaFormat Format, QSize Minimum, QSize Maximum, uint MacroBlocks)
static MythNVDECInterop * Create(MythRenderOpenGL *Context)
static bool GetBuffer(AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame, int Flags)
Convert AVFrame data to MythFrame.
QString GetSingleRatePreferences(void) const
static void DeviceContextFinished(AVHWDeviceContext *Context)
static MythRenderOpenGL * GetOpenGLRender(void)
void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override
static enum AVPixelFormat GetFormat(AVCodecContext *Context, const AVPixelFormat *PixFmt)
bool RetrieveFrame(AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame) override
const char * frames[3]
Definition: element.c:46
static void NewHardwareFramesContext(void)
Track the number of concurrent frames contexts.
static void GetDecoderList(QStringList &Decoders)
#define codec_is_nvdec(id)
Definition: mythcodecid.h:328
virtual bool RetrieveHWFrame(VideoFrame *Frame, AVFrame *AvFrame)
static bool CreateCUDAContext(MythRenderOpenGL *GLContext, CudaFunctions *&CudaFuncs, CUcontext &CudaContext)
MythDeintType m_deinterlacer
QString GetDoubleRatePreferences(void) const
static const std::vector< MythNVDECCaps > & GetProfiles(void)
static AVBufferRef * CreateDevice(AVHWDeviceType Type, MythOpenGLInterop *Interop, const QString &Device=QString())