MythTV  master
mythvaapicontext.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 #include <QWaitCondition>
4 
5 // Mythtv
6 #include "mythcontext.h"
7 #include "mythmainwindow.h"
8 #include "mythlogging.h"
11 #include "videobuffers.h"
12 #include "mythvaapiinterop.h"
13 #include "mythvaapicontext.h"
14 
15 extern "C" {
16 #include "libavutil/hwcontext_vaapi.h"
17 #include "libavutil/pixdesc.h"
18 #include "libavfilter/buffersink.h"
19 }
20 
21 #define LOC QString("VAAPIDec: ")
22 
32  : MythCodecContext(Parent, CodecID)
33 {
34 }
35 
37 {
39 }
40 
41 VAProfile MythVAAPIContext::VAAPIProfileForCodec(const AVCodecContext *Codec)
42 {
43  if (!Codec)
44  return VAProfileNone;
45 
46  switch (Codec->codec_id)
47  {
48  case AV_CODEC_ID_MPEG2VIDEO:
49  switch (Codec->profile)
50  {
51  case FF_PROFILE_MPEG2_SIMPLE: return VAProfileMPEG2Simple;
52  case FF_PROFILE_MPEG2_MAIN: return VAProfileMPEG2Main;
53  default: break;
54  }
55  break;
56  case AV_CODEC_ID_H263: return VAProfileH263Baseline;
57  case AV_CODEC_ID_MPEG4:
58  switch (Codec->profile)
59  {
60  case FF_PROFILE_MPEG4_SIMPLE: return VAProfileMPEG4Simple;
61  case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: return VAProfileMPEG4AdvancedSimple;
62  case FF_PROFILE_MPEG4_MAIN: return VAProfileMPEG4Main;
63  default: break;
64  }
65  break;
66  case AV_CODEC_ID_H264:
67  switch (Codec->profile)
68  {
69  case FF_PROFILE_H264_CONSTRAINED_BASELINE: return VAProfileH264ConstrainedBaseline;
70  case FF_PROFILE_H264_MAIN: return VAProfileH264Main;
71  case FF_PROFILE_H264_HIGH: return VAProfileH264High;
72  default: break;
73  }
74  break;
75  case AV_CODEC_ID_HEVC:
76 #if VA_CHECK_VERSION(0, 37, 0)
77  switch (Codec->profile)
78  {
79  case FF_PROFILE_HEVC_MAIN: return VAProfileHEVCMain;
80  case FF_PROFILE_HEVC_MAIN_10: return VAProfileHEVCMain10;
81  default: break;
82  }
83 #endif
84  break;
85  case AV_CODEC_ID_MJPEG: return VAProfileJPEGBaseline;
86  case AV_CODEC_ID_WMV3:
87  case AV_CODEC_ID_VC1:
88  switch (Codec->profile)
89  {
90  case FF_PROFILE_VC1_SIMPLE: return VAProfileVC1Simple;
91  case FF_PROFILE_VC1_MAIN: return VAProfileVC1Main;
92  case FF_PROFILE_VC1_ADVANCED:
93  case FF_PROFILE_VC1_COMPLEX: return VAProfileVC1Advanced;
94  default: break;
95  }
96  break;
97  case AV_CODEC_ID_VP8: return VAProfileVP8Version0_3;
98  case AV_CODEC_ID_VP9:
99  switch (Codec->profile)
100  {
101 #if VA_CHECK_VERSION(0, 38, 0)
102  case FF_PROFILE_VP9_0: return VAProfileVP9Profile0;
103 #endif
104 #if VA_CHECK_VERSION(0, 39, 0)
105  case FF_PROFILE_VP9_2: return VAProfileVP9Profile2;
106 #endif
107  default: break;
108  }
109  break;
110  default: break;
111  }
112 
113  return VAProfileNone;
114 }
115 
116 inline AVPixelFormat MythVAAPIContext::FramesFormat(AVPixelFormat Format)
117 {
118  switch (Format)
119  {
120  case AV_PIX_FMT_YUV420P10: return AV_PIX_FMT_P010;
121  case AV_PIX_FMT_YUV420P12:
122  case AV_PIX_FMT_YUV420P14:
123  case AV_PIX_FMT_YUV420P16: return AV_PIX_FMT_P016;
124  default: return AV_PIX_FMT_NV12;
125  }
126 }
127 
131  AVCodec ** /*Codec*/,
132  const QString &Decoder,
133  uint StreamType)
134 {
135  bool decodeonly = Decoder == "vaapi-dec";
136  auto success = static_cast<MythCodecID>((decodeonly ? kCodec_MPEG1_VAAPI_DEC : kCodec_MPEG1_VAAPI) + (StreamType - 1));
137  auto failure = static_cast<MythCodecID>(kCodec_MPEG1 + (StreamType - 1));
138  QString vendor = HaveVAAPI();
139  if (!Decoder.startsWith("vaapi") || vendor.isEmpty() || getenv("NO_VAAPI"))
140  return failure;
141 
142  QString codec = ff_codec_id_string((*Context)->codec_id);
143  QString profile = avcodec_profile_name((*Context)->codec_id, (*Context)->profile);
144  QString pixfmt = av_get_pix_fmt_name((*Context)->pix_fmt);
145 
146  // Simple check for known profile
147  VAProfile desired = VAAPIProfileForCodec(*Context);
148  if (desired == VAProfileNone)
149  {
150  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VAAPI does not support decoding '%1 %2 %3'")
151  .arg(codec).arg(profile).arg(pixfmt));
152  return failure;
153  }
154 
155  // Check for ironlake decode only - which won't work due to FFmpeg frame format
156  // constraints. May apply to other platforms.
157  if (decodeonly)
158  {
159  if (vendor.contains("ironlake", Qt::CaseInsensitive))
160  {
161  LOG(VB_GENERAL, LOG_WARNING, LOC + "Disallowing VAAPI decode only for Ironlake");
162  return failure;
163  }
164  }
165  else
166  {
167  // If called from outside of the main thread, we need a MythPlayer instance to
168  // process the interop check callback - which may fail otherwise (depending
169  // on whether the result is cached).
170  MythPlayer* player = nullptr;
171  if (!gCoreContext->IsUIThread())
172  {
173  auto *decoder = reinterpret_cast<AvFormatDecoder*>((*Context)->opaque);
174  if (decoder)
175  player = decoder->GetPlayer();
176  }
177 
178  // Direct rendering needs interop support
180  return failure;
181  }
182 
183  // Check profile support
184  bool ok = false;
185  const VAAPIProfiles& profiles = MythVAAPIContext::GetProfiles();
186  MythCodecContext::CodecProfile mythprofile =
187  MythCodecContext::FFmpegToMythProfile((*Context)->codec_id, (*Context)->profile);
188  auto haveprofile = [=](MythCodecContext::CodecProfile Profile, QSize Size)
189  {
190  for (auto vaprofile : qAsConst(profiles))
191  {
192  if (vaprofile.first == Profile &&
193  vaprofile.second.first.width() <= Size.width() &&
194  vaprofile.second.first.height() <= Size.height() &&
195  vaprofile.second.second.width() >= Size.width() &&
196  vaprofile.second.second.height() >= Size.height())
197  {
198  return true;
199  }
200  }
201  return false;
202  };
203 
204  ok = haveprofile(mythprofile, QSize((*Context)->width, (*Context)->height));
205  // use JPEG support as a proxy for MJPEG (full range YUV)
206  if (ok && (AV_PIX_FMT_YUVJ420P == (*Context)->pix_fmt || AV_PIX_FMT_YUVJ422P == (*Context)->pix_fmt ||
207  AV_PIX_FMT_YUVJ444P == (*Context)->pix_fmt))
208  {
209  ok = haveprofile(MythCodecContext::MJPEG, QSize());
210  }
211 
212  QString desc = QString("'%1 %2 %3 %4x%5'")
213  .arg(codec).arg(profile).arg(pixfmt).arg((*Context)->width).arg((*Context)->height);
214 
215  if (ok)
216  {
217  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VAAPI supports decoding %1").arg(desc));
218  (*Context)->pix_fmt = AV_PIX_FMT_VAAPI;
219  return success;
220  }
221 
222  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VAAPI does NOT support %1").arg(desc));
223  return failure;
224 }
225 
226 AVPixelFormat MythVAAPIContext::GetFormat(AVCodecContext *Context, const AVPixelFormat *PixFmt)
227 {
228  while (*PixFmt != AV_PIX_FMT_NONE)
229  {
230  if (*PixFmt == AV_PIX_FMT_VAAPI)
232  return AV_PIX_FMT_VAAPI;
233  PixFmt++;
234  }
235  return AV_PIX_FMT_NONE;
236 }
237 
238 AVPixelFormat MythVAAPIContext::GetFormat2(AVCodecContext *Context, const AVPixelFormat *PixFmt)
239 {
240  while (*PixFmt != AV_PIX_FMT_NONE)
241  {
242  if (*PixFmt == AV_PIX_FMT_VAAPI)
243  if (InitialiseContext2(Context) >= 0)
244  return AV_PIX_FMT_VAAPI;
245  PixFmt++;
246  }
247  return AV_PIX_FMT_NONE;
248 }
249 
253 {
254  if (!Context || !gCoreContext->IsUIThread())
255  return -1;
256 
257  // We need a render device
259  if (!render)
260  return -1;
261 
262  // The interop must have a reference to the player so it can be deleted
263  // from the main thread.
264  MythPlayer *player = nullptr;
265  auto *decoder = reinterpret_cast<AvFormatDecoder*>(Context->opaque);
266  if (decoder)
267  player = decoder->GetPlayer();
268  if (!player)
269  return -1;
270 
271  // Check interop support
274  return -1;
275 
276  // Create interop
277  MythVAAPIInterop *interop = MythVAAPIInterop::Create(render, type);
278  if (!interop)
279  return -1;
280  if (!interop->GetDisplay())
281  {
282  interop->DecrRef();
283  return -1;
284  }
285 
286  // Set the player required to process interop release
287  interop->SetPlayer(player);
288 
289  // Create hardware device context
290  AVBufferRef* hwdeviceref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
291  if (!hwdeviceref || (hwdeviceref && !hwdeviceref->data))
292  {
293  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI hardware device context");
294  return -1;
295  }
296 
297  auto* hwdevicecontext = reinterpret_cast<AVHWDeviceContext*>(hwdeviceref->data);
298  if (!hwdevicecontext || (hwdevicecontext && !hwdevicecontext->hwctx))
299  return -1;
300  auto *vaapidevicectx = reinterpret_cast<AVVAAPIDeviceContext*>(hwdevicecontext->hwctx);
301  if (!vaapidevicectx)
302  return -1;
303 
304  // Set the display
305  vaapidevicectx->display = interop->GetDisplay();
306 
307  // Initialise hardware device context
308  int res = av_hwdevice_ctx_init(hwdeviceref);
309  if (res < 0)
310  {
311  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to initialise VAAPI hardware context");
312  av_buffer_unref(&hwdeviceref);
313  interop->DecrRef();
314  return res;
315  }
316 
317  // Allocate the hardware frames context for FFmpeg
318  Context->hw_frames_ctx = av_hwframe_ctx_alloc(hwdeviceref);
319  if (!Context->hw_frames_ctx)
320  {
321  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI hardware frames context");
322  av_buffer_unref(&hwdeviceref);
323  interop->DecrRef();
324  return -1;
325  }
326 
327  // Setup the frames context
328  auto* hw_frames_ctx = reinterpret_cast<AVHWFramesContext*>(Context->hw_frames_ctx->data);
329  auto* vaapi_frames_ctx = reinterpret_cast<AVVAAPIFramesContext*>(hw_frames_ctx->hwctx);
330 
331  // Workarounds for specific drivers, surface formats and codecs
332  // NV12 seems to work best across GPUs and codecs with the exception of
333  // MPEG2 on Ironlake where it seems to return I420 labelled as NV12. I420 is
334  // buggy on Sandybridge (stride?) and produces a mixture of I420/NV12 frames
335  // for H.264 on Ironlake.
336  // This may need extending for AMD etc
337 
338  QString vendor = interop->GetVendor();
339  // Intel NUC
340  if (vendor.contains("iHD", Qt::CaseInsensitive) && vendor.contains("Intel", Qt::CaseInsensitive))
341  {
342  vaapi_frames_ctx->attributes = nullptr;
343  vaapi_frames_ctx->nb_attributes = 0;
344  }
345  // i965 series
346  else
347  {
348  int format = VA_FOURCC_NV12;
349  if (vendor.contains("ironlake", Qt::CaseInsensitive))
350  if (CODEC_IS_MPEG(Context->codec_id))
351  format = VA_FOURCC_I420;
352 
353  if (format != VA_FOURCC_NV12)
354  {
355  auto vaapiid = static_cast<MythCodecID>(kCodec_MPEG1_VAAPI + (mpeg_version(Context->codec_id) - 1));
356  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Forcing surface format for %1 and %2 with driver '%3'")
357  .arg(toString(vaapiid)).arg(MythOpenGLInterop::TypeToString(type)).arg(vendor));
358  }
359 
360  VASurfaceAttrib prefs[3] = {
361  { VASurfaceAttribPixelFormat, VA_SURFACE_ATTRIB_SETTABLE, { VAGenericValueTypeInteger, { format } } },
362  { VASurfaceAttribUsageHint, VA_SURFACE_ATTRIB_SETTABLE, { VAGenericValueTypeInteger, { VA_SURFACE_ATTRIB_USAGE_HINT_DISPLAY } } },
363  { VASurfaceAttribMemoryType, VA_SURFACE_ATTRIB_SETTABLE, { VAGenericValueTypeInteger, { VA_SURFACE_ATTRIB_MEM_TYPE_VA} } } };
364  vaapi_frames_ctx->attributes = prefs;
365  vaapi_frames_ctx->nb_attributes = 3;
366  }
367 
368  hw_frames_ctx->sw_format = FramesFormat(Context->sw_pix_fmt);
369  int referenceframes = AvFormatDecoder::GetMaxReferenceFrames(Context);
370  hw_frames_ctx->initial_pool_size = static_cast<int>(VideoBuffers::GetNumBuffers(FMT_VAAPI, referenceframes, true));
371  hw_frames_ctx->format = AV_PIX_FMT_VAAPI;
372  hw_frames_ctx->width = Context->coded_width;
373  hw_frames_ctx->height = Context->coded_height;
374  // The frames context now holds the reference to MythVAAPIInterop
375  hw_frames_ctx->user_opaque = interop;
376  // Set the callback to ensure it is released
377  hw_frames_ctx->free = &MythCodecContext::FramesContextFinished;
378 
379  // Initialise hardwar frames context
380  res = av_hwframe_ctx_init(Context->hw_frames_ctx);
381  if (res < 0)
382  {
383  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to initialise VAAPI frames context");
384  av_buffer_unref(&hwdeviceref);
385  av_buffer_unref(&(Context->hw_frames_ctx));
386  return res;
387  }
388 
389  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VAAPI FFmpeg buffer pool created with %1 %2x%3 surfaces (%4 references)")
390  .arg(vaapi_frames_ctx->nb_surfaces).arg(Context->coded_width).arg(Context->coded_height)
391  .arg(referenceframes));
392  av_buffer_unref(&hwdeviceref);
393 
395 
396  return 0;
397 }
398 
407 {
408  if (!Context)
409  return -1;
410 
411  AVBufferRef *device = MythCodecContext::CreateDevice(AV_HWDEVICE_TYPE_VAAPI, nullptr,
412  gCoreContext->GetSetting("VAAPIDevice"));
413  Context->hw_frames_ctx = av_hwframe_ctx_alloc(device);
414  if (!Context->hw_frames_ctx)
415  {
416  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI hardware frames context");
417  av_buffer_unref(&device);
418  return -1;
419  }
420 
421  int referenceframes = AvFormatDecoder::GetMaxReferenceFrames(Context);
422  auto* hw_frames_ctx = reinterpret_cast<AVHWFramesContext*>(Context->hw_frames_ctx->data);
423  auto* vaapi_frames_ctx = reinterpret_cast<AVVAAPIFramesContext*>(hw_frames_ctx->hwctx);
424  hw_frames_ctx->sw_format = FramesFormat(Context->sw_pix_fmt);
425  hw_frames_ctx->format = AV_PIX_FMT_VAAPI;
426  hw_frames_ctx->width = Context->coded_width;
427  hw_frames_ctx->height = Context->coded_height;
428  hw_frames_ctx->initial_pool_size = static_cast<int>(VideoBuffers::GetNumBuffers(FMT_VAAPI, referenceframes));
429  hw_frames_ctx->free = &MythCodecContext::FramesContextFinished;
430  if (av_hwframe_ctx_init(Context->hw_frames_ctx) < 0)
431  {
432  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to initialise VAAPI frames context");
433  av_buffer_unref(&device);
434  av_buffer_unref(&(Context->hw_frames_ctx));
435  return -1;
436  }
437 
438  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("VAAPI FFmpeg buffer pool created with %1 %2x%3 surfaces (%4 references)")
439  .arg(vaapi_frames_ctx->nb_surfaces).arg(Context->coded_width).arg(Context->coded_height)
440  .arg(referenceframes));
441  av_buffer_unref(&device);
442 
444 
445  return 0;
446 }
447 
455 QString MythVAAPIContext::HaveVAAPI(bool ReCheck /*= false*/)
456 {
457  static QString s_vendor;
458  static bool s_checked = false;
459  if (s_checked && !ReCheck)
460  return s_vendor;
461  s_checked = true;
462 
463  AVBufferRef *context = MythCodecContext::CreateDevice(AV_HWDEVICE_TYPE_VAAPI, nullptr,
464  gCoreContext->GetSetting("VAAPIDevice"));
465  if (context)
466  {
467  auto *hwdevice = reinterpret_cast<AVHWDeviceContext*>(context->data);
468  auto *hwctx = reinterpret_cast<AVVAAPIDeviceContext*>(hwdevice->hwctx);
469  s_vendor = QString(vaQueryVendorString(hwctx->display));
470  if (s_vendor.contains("vdpau", Qt::CaseInsensitive))
471  {
472  s_vendor = QString();
473  LOG(VB_GENERAL, LOG_INFO, LOC + "VAAPI is using a VDPAU backend - ignoring VAAPI");
474  }
475  else if (s_vendor.isEmpty())
476  {
477  LOG(VB_GENERAL, LOG_INFO, LOC + "Unknown VAAPI vendor - ignoring VAAPI");
478  }
479  else
480  {
481  LOG(VB_GENERAL, LOG_INFO, LOC + "Supported/available VAAPI decoders:");
482  const VAAPIProfiles& profiles = MythVAAPIContext::GetProfiles();
483  for (auto profile : qAsConst(profiles))
484  {
485  if (profile.first != MythCodecContext::MJPEG)
486  {
487  LOG(VB_GENERAL, LOG_INFO, LOC +
489  }
490  }
491  }
492  av_buffer_unref(&context);
493  }
494  else
495  {
496  LOG(VB_GENERAL, LOG_INFO, LOC + "VAAPI functionality checked failed");
497  }
498 
499  return s_vendor;
500 }
501 
503 {
504  static QMutex lock(QMutex::Recursive);
505  static bool s_initialised = false;
506  static VAAPIProfiles s_profiles;
507 
508  QMutexLocker locker(&lock);
509  if (s_initialised)
510  return s_profiles;
511  s_initialised = true;
512 
513  auto VAToMythProfile = [](VAProfile Profile)
514  {
515  switch (Profile)
516  {
517  case VAProfileMPEG2Simple: return MythCodecContext::MPEG2Simple;
518  case VAProfileMPEG2Main: return MythCodecContext::MPEG2Main;
519  case VAProfileMPEG4Simple: return MythCodecContext::MPEG4Simple;
520  case VAProfileMPEG4AdvancedSimple: return MythCodecContext::MPEG4AdvancedSimple;
521  case VAProfileMPEG4Main: return MythCodecContext::MPEG4Main;
522  case VAProfileH263Baseline: return MythCodecContext::H263;
523  case VAProfileH264ConstrainedBaseline: return MythCodecContext::H264ConstrainedBaseline;
524  case VAProfileH264Main: return MythCodecContext::H264Main;
525  case VAProfileH264High: return MythCodecContext::H264High;
526  case VAProfileVC1Simple: return MythCodecContext::VC1Simple;
527  case VAProfileVC1Main: return MythCodecContext::VC1Main;
528  case VAProfileVC1Advanced: return MythCodecContext::VC1Advanced;
529  case VAProfileVP8Version0_3: return MythCodecContext::VP8;
530  #if VA_CHECK_VERSION(0, 38, 0)
531  case VAProfileVP9Profile0: return MythCodecContext::VP9_0;
532  #endif
533  #if VA_CHECK_VERSION(0, 39, 0)
534  case VAProfileVP9Profile2: return MythCodecContext::VP9_2;
535  #endif
536  #if VA_CHECK_VERSION(0, 37, 0)
537  case VAProfileHEVCMain: return MythCodecContext::HEVCMain;
538  case VAProfileHEVCMain10: return MythCodecContext::HEVCMain10;
539  #endif
540  case VAProfileJPEGBaseline: return MythCodecContext::MJPEG;
541  default: break;
542  }
544  };
545 
546  AVBufferRef *hwdevicectx = MythCodecContext::CreateDevice(AV_HWDEVICE_TYPE_VAAPI, nullptr,
547  gCoreContext->GetSetting("VAAPIDevice"));
548  if(!hwdevicectx)
549  return s_profiles;
550 
551  auto *device = reinterpret_cast<AVHWDeviceContext*>(hwdevicectx->data);
552  auto *hwctx = reinterpret_cast<AVVAAPIDeviceContext*>(device->hwctx);
553 
554  int profilecount = vaMaxNumProfiles(hwctx->display);
555  auto *profilelist = static_cast<VAProfile*>(av_malloc_array(static_cast<size_t>(profilecount), sizeof(VAProfile)));
556  if (vaQueryConfigProfiles(hwctx->display, profilelist, &profilecount) == VA_STATUS_SUCCESS)
557  {
558  for (int i = 0; i < profilecount; ++i)
559  {
560  VAProfile profile = profilelist[i];
561  if (profile == VAProfileNone || profile == VAProfileH264StereoHigh || profile == VAProfileH264MultiviewHigh)
562  continue;
563  int count = 0;
564  int entrysize = vaMaxNumEntrypoints(hwctx->display);
565  auto *entrylist = static_cast<VAEntrypoint*>(av_malloc_array(static_cast<size_t>(entrysize), sizeof(VAEntrypoint)));
566  if (vaQueryConfigEntrypoints(hwctx->display, profile, entrylist, &count) == VA_STATUS_SUCCESS)
567  {
568  for (int j = 0; j < count; ++j)
569  {
570  if (entrylist[j] != VAEntrypointVLD)
571  continue;
572 
573  QSize minsize;
574  QSize maxsize;
575  VAConfigID config = 0;
576  if (vaCreateConfig(hwctx->display, profile, VAEntrypointVLD, nullptr, 0, &config) != VA_STATUS_SUCCESS)
577  continue;
578 
579  uint attrcount = 0;
580  if (vaQuerySurfaceAttributes(hwctx->display, config, nullptr, &attrcount) == VA_STATUS_SUCCESS)
581  {
582  auto *attrlist = static_cast<VASurfaceAttrib*>(av_malloc(attrcount * sizeof(VASurfaceAttrib)));
583  if (vaQuerySurfaceAttributes(hwctx->display, config, attrlist, &attrcount) == VA_STATUS_SUCCESS)
584  {
585  for (uint k = 0; k < attrcount; ++k)
586  {
587  if (attrlist[k].type == VASurfaceAttribMaxWidth)
588  maxsize.setWidth(attrlist[k].value.value.i);
589  if (attrlist[k].type == VASurfaceAttribMaxHeight)
590  maxsize.setHeight(attrlist[k].value.value.i);
591  if (attrlist[k].type == VASurfaceAttribMinWidth)
592  minsize.setWidth(attrlist[k].value.value.i);
593  if (attrlist[k].type == VASurfaceAttribMinHeight)
594  minsize.setHeight(attrlist[k].value.value.i);
595  }
596  }
597  av_freep(&attrlist);
598  }
599  vaDestroyConfig(hwctx->display, config);
600  s_profiles.append(VAAPIProfile(VAToMythProfile(profile), QPair<QSize,QSize>(minsize, maxsize)));
601  }
602  }
603  av_freep(&entrylist);
604  }
605  }
606  av_freep(&profilelist);
607  av_buffer_unref(&hwdevicectx);
608 
609  // Once only check for EGL support for best performance
611  if (!s_profiles.isEmpty() && render)
612  {
613  if (render->IsEGL())
614  {
615  LOG(VB_GENERAL, LOG_INFO, LOC + "EGL DMABUF available for best VAAPI performance");
616  }
617  else
618  {
619  LOG(VB_GENERAL, LOG_WARNING, LOC + "No EGL support. VAAPI performance will be reduced");
620  LOG(VB_GENERAL, LOG_WARNING, LOC + "Consider setting MYTHTV_FORCE_EGL=1 to try and enable");
621  }
622  }
623  return s_profiles;
624 }
625 
626 void MythVAAPIContext::GetDecoderList(QStringList &Decoders)
627 {
628  const VAAPIProfiles& profiles = MythVAAPIContext::GetProfiles();
629  if (profiles.isEmpty())
630  return;
631  Decoders.append("VAAPI:");
632  for (auto profile : qAsConst(profiles))
633  if (profile.first != MythCodecContext::MJPEG)
634  Decoders.append(MythCodecContext::GetProfileDescription(profile.first, profile.second.second));
635 }
636 
637 void MythVAAPIContext::InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
638 {
640  {
641  Context->get_buffer2 = MythCodecContext::GetBuffer;
642  Context->get_format = MythVAAPIContext::GetFormat;
643  Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
644  return;
645  }
647  {
649  Context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
650  DirectRendering = false;
651  return;
652  }
653 
654  MythCodecContext::InitVideoCodec(Context, SelectedStream, DirectRendering);
655 }
656 
657 bool MythVAAPIContext::RetrieveFrame(AVCodecContext* /*unused*/, VideoFrame *Frame, AVFrame *AvFrame)
658 {
659  if (AvFrame->format != AV_PIX_FMT_VAAPI)
660  return false;
662  return RetrieveHWFrame(Frame, AvFrame);
663  return false;
664 }
665 
675 {
676  int ret = 0;
677 
678  while (true)
679  {
680  if (m_filterGraph && ((m_filterWidth != Context->coded_width) || (m_filterHeight != Context->coded_height)))
681  {
682  LOG(VB_GENERAL, LOG_WARNING, LOC + "Input changed - deleting filter");
684  }
685 
686  if (m_filterGraph)
687  {
688  ret = av_buffersink_get_frame(m_filterSink, Frame);
689  if (ret >= 0)
690  {
692  {
693  Frame->pts = m_filterPriorPTS[1] + (m_filterPriorPTS[1] - m_filterPriorPTS[0]) / 2;
694  Frame->scte_cc_len = 0;
695  Frame->atsc_cc_len = 0;
696  av_frame_remove_side_data(Frame, AV_FRAME_DATA_A53_CC);
697  }
698  else
699  {
700  Frame->pts = m_filterPriorPTS[1];
702  }
703  }
704  if (ret != AVERROR(EAGAIN))
705  break;
706  }
707 
708  // EAGAIN or no filter graph
709  ret = avcodec_receive_frame(Context, Frame);
710  if (ret == 0)
711  {
712  // preserve interlaced flags
713  m_lastInterlaced = Frame->interlaced_frame;
714  m_lastTopFieldFirst = (Frame->top_field_first != 0);
715  }
716 
717  if (ret < 0)
718  break;
719 
720  // some streams with missing timestamps break frame timing when doublerate
721  // so replace with dts if available
722  int64_t pts = Frame->pts;
723  if (pts == AV_NOPTS_VALUE && Frame->pkt_dts != AV_NOPTS_VALUE && m_deinterlacer2x)
724  pts = Frame->pkt_dts;
726  m_filterPriorPTS[1] = pts;
727 
728  if (!m_filterGraph)
729  break;
730 
731  ret = av_buffersrc_add_frame(m_filterSource, Frame);
732  if (ret < 0)
733  break;
734  }
735 
736  return ret;
737 }
738 
740 {
741  if (!Frame || !codec_is_vaapi_dec(m_codecID) || !Context->hw_frames_ctx)
742  return;
743 
744  // if VAAPI driver deints are errored or not available (older boards), then
745  // allow CPU/GLSL
746  if (m_filterError)
747  {
748  Frame->deinterlace_allowed = Frame->deinterlace_allowed & ~DEINT_DRIVER;
749  return;
750  }
753  {
754  // enabling VPP deinterlacing with these codecs breaks decoding for some reason.
755  // HEVC interlacing is not currently detected by FFmpeg and I can't find
756  // any interlaced VP8/9 material. Shaders and/or CPU deints will be available
757  // as appropriate
758  m_filterError = true;
759  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Disabling VAAPI VPP deinterlacer for %1")
760  .arg(toString(m_codecID)));
761  return;
762  }
763 
764  // if this frame has already been deinterlaced, then flag the deinterlacer and
765  // that the frame has already been deinterlaced.
766  // the FFmpeg vaapi deint filter will mark frames as progressive, so restore the
767  // interlaced flags to ensure auto deinterlacing continues to work
768  if (m_deinterlacer)
769  {
770  Frame->interlaced_frame = m_lastInterlaced;
771  Frame->top_field_first = m_lastTopFieldFirst;
772  Frame->deinterlace_inuse = m_deinterlacer | DEINT_DRIVER;
773  Frame->deinterlace_inuse2x = m_deinterlacer2x;
774  Frame->already_deinterlaced = true;
775  }
776 
777  // N.B. this picks up the scan tracking in MythPlayer. So we can
778  // auto enable deinterlacing etc and override Progressive/Interlaced - but
779  // no reversed interlaced.
780  MythDeintType vaapideint = DEINT_NONE;
783  bool doublerate = true;
784  bool other = false;
785 
786  // For decode only, a CPU or shader deint may also be used/preferred
787  if (doublepref)
788  vaapideint = doublepref;
790  other = true;
791 
792  if (!vaapideint && !other && singlepref)
793  {
794  doublerate = false;
795  vaapideint = singlepref;
796  }
797 
798  // nothing to see
799  if (vaapideint == DEINT_NONE)
800  {
801  if (m_deinterlacer)
803  return;
804  }
805 
806  // already setup
807  if ((m_deinterlacer == vaapideint) && (m_deinterlacer2x == doublerate))
808  return;
809 
810  // Start from scratch
812  m_framesCtx = av_buffer_ref(Context->hw_frames_ctx);
813  if (!MythVAAPIInterop::SetupDeinterlacer(vaapideint, doublerate, Context->hw_frames_ctx,
814  Context->coded_width, Context->coded_height,
816  {
817  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to create deinterlacer %1 - disabling")
818  .arg(DeinterlacerName(vaapideint | DEINT_DRIVER, doublerate, FMT_VAAPI)));
820  m_filterError = true;
821  }
822  else
823  {
824  m_deinterlacer = vaapideint;
825  m_deinterlacer2x = doublerate;
826  m_filterWidth = Context->coded_width;
827  m_filterHeight = Context->coded_height;
828  }
829 }
830 
831 bool MythVAAPIContext::IsDeinterlacing(bool &DoubleRate, bool StreamChange)
832 {
833  // the VAAPI deinterlacer can be turned on and off, so on stream changes
834  // return false to ensure auto deint works for the new format (the deinterlacer
835  // refers to the current format)
836  if (m_deinterlacer && !StreamChange)
837  {
838  DoubleRate = m_deinterlacer2x;
839  return true;
840  }
841  DoubleRate = false;
842  return false;
843 }
844 
846 {
847  // HEVC appears to be OK
848  return kCodec_H264_VAAPI == m_codecID;
849 }
850 
852 {
853  // Only MPEG2 tested so far
855 }
856 
858 {
859  if (m_filterGraph)
860  LOG(VB_GENERAL, LOG_INFO, LOC + "Destroying VAAPI deinterlacer");
861  avfilter_graph_free(&m_filterGraph);
862  m_filterGraph = nullptr;
863  m_filterSink = nullptr;
864  m_filterSource = nullptr;
865  m_filterPTSUsed = 0;
866  m_filterPriorPTS[0] = 0;
867  m_filterPriorPTS[1] = 0;
868  m_filterWidth = 0;
869  m_filterHeight = 0;
870  if (m_framesCtx)
871  av_buffer_unref(&m_framesCtx);
873  m_deinterlacer2x = false;
874 }
MythVAAPIContext::InitVideoCodec
void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering) override
Definition: mythvaapicontext.cpp:637
GetSingleRateOption
MythDeintType GetSingleRateOption(const VideoFrame *Frame, MythDeintType Type, MythDeintType Override)
Definition: mythframe.cpp:834
MythCodecContext::VC1Simple
@ VC1Simple
Definition: mythcodeccontext.h:101
DEINT_DRIVER
@ DEINT_DRIVER
Definition: mythframe.h:129
MythCodecContext::MPEG4Simple
@ MPEG4Simple
Definition: mythcodeccontext.h:65
MythCodecContext::MPEG2Simple
@ MPEG2Simple
Definition: mythcodeccontext.h:58
mythvaapiinterop.h
MythCodecContext::m_codecID
MythCodecID m_codecID
Definition: mythcodeccontext.h:165
MythCodecContext::VC1Advanced
@ VC1Advanced
Definition: mythcodeccontext.h:104
MythVAAPIContext::m_filterPriorPTS
int64_t m_filterPriorPTS[2]
Definition: mythvaapicontext.h:65
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
mpeg_version
uint mpeg_version(int codec_id)
Definition: mythcodecid.cpp:455
MythCodecContext::VP9_0
@ VP9_0
Definition: mythcodeccontext.h:107
DEINT_SHADER
@ DEINT_SHADER
Definition: mythframe.h:128
MythCodecContext::HEVCMain10
@ HEVCMain10
Definition: mythcodeccontext.h:95
MythVAAPIContext::m_filterError
bool m_filterError
Definition: mythvaapicontext.h:63
MythCodecContext::RetrieveHWFrame
virtual bool RetrieveHWFrame(VideoFrame *Frame, AVFrame *AvFrame)
Definition: mythcodeccontext.cpp:601
MythVAAPIContext::DestroyDeinterlacer
void DestroyDeinterlacer(void)
Definition: mythvaapicontext.cpp:857
MythCodecContext::NoProfile
@ NoProfile
Definition: mythcodeccontext.h:55
MythVAAPIInterop::Create
static MythVAAPIInterop * Create(MythRenderOpenGL *Context, Type InteropType)
Definition: mythvaapiinterop.cpp:56
MythCodecContext::MPEG4AdvancedSimple
@ MPEG4AdvancedSimple
Definition: mythcodeccontext.h:80
MythVAAPIContext::~MythVAAPIContext
~MythVAAPIContext() override
Definition: mythvaapicontext.cpp:36
MythCodecContext::CodecProfile
CodecProfile
Definition: mythcodeccontext.h:53
Frame
Definition: zmdefines.h:93
MythCodecContext::NewHardwareFramesContext
static void NewHardwareFramesContext(void)
Track the number of concurrent frames contexts.
Definition: mythcodeccontext.cpp:417
MythCodecContext::VC1Main
@ VC1Main
Definition: mythcodeccontext.h:102
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:123
arg
arg(title).arg(filename).arg(doDelete))
LOC
#define LOC
Definition: mythvaapicontext.cpp:21
GetDoubleRateOption
MythDeintType GetDoubleRateOption(const VideoFrame *Frame, MythDeintType Type, MythDeintType Override)
Definition: mythframe.cpp:847
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1356
MythOpenGLInterop::SetPlayer
void SetPlayer(MythPlayer *Player)
Definition: mythopenglinterop.cpp:280
Context
QHash< QString, Action * > Context
Definition: action.h:77
MythCodecContext::InitVideoCodec
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
Definition: mythcodeccontext.cpp:291
MythDate::Format
Format
Definition: mythdate.h:12
kCodec_HEVC_VAAPI_DEC
@ kCodec_HEVC_VAAPI_DEC
Definition: mythcodecid.h:94
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythCodecContext::FramesContextFinished
static void FramesContextFinished(AVHWFramesContext *Context)
Definition: mythcodeccontext.cpp:424
MythCodecContext::MPEG4Main
@ MPEG4Main
Definition: mythcodeccontext.h:68
MythPlayer
Definition: mythplayer.h:164
MythCodecContext::VP9_2
@ VP9_2
Definition: mythcodeccontext.h:109
VideoFrame
Definition: mythframe.h:137
MythCodecContext::FFmpegToMythProfile
static CodecProfile FFmpegToMythProfile(AVCodecID CodecID, int Profile)
Definition: mythcodeccontext.cpp:656
VAAPIProfiles
QList< VAAPIProfile > VAAPIProfiles
Definition: mythvaapicontext.h:21
MythVAAPIContext::GetFormat
static enum AVPixelFormat GetFormat(AVCodecContext *Context, const AVPixelFormat *PixFmt)
Definition: mythvaapicontext.cpp:226
kCodec_VP9_VAAPI_DEC
@ kCodec_VP9_VAAPI_DEC
Definition: mythcodecid.h:93
MythVAAPIInterop::SetupDeinterlacer
static bool SetupDeinterlacer(MythDeintType Deinterlacer, bool DoubleRate, AVBufferRef *FramesContext, int Width, int Height, AVFilterGraph *&Graph, AVFilterContext *&Source, AVFilterContext *&Sink)
Definition: mythvaapiinterop.cpp:170
MythCodecContext::H264ConstrainedBaseline
@ H264ConstrainedBaseline
Definition: mythcodeccontext.h:84
MythVAAPIContext::GetSupportedCodec
static MythCodecID GetSupportedCodec(AVCodecContext **Context, AVCodec **Codec, const QString &Decoder, uint StreamType)
Confirm whether VAAPI support is available given Decoder and Context.
Definition: mythvaapicontext.cpp:130
kCodec_MPEG2_VAAPI_DEC
@ kCodec_MPEG2_VAAPI_DEC
Definition: mythcodecid.h:86
mythvaapicontext.h
MythVAAPIContext::GetDecoderList
static void GetDecoderList(QStringList &Decoders)
Definition: mythvaapicontext.cpp:626
MythVAAPIContext::InitialiseContext
static int InitialiseContext(AVCodecContext *Context)
Create a VAAPI hardware context with appropriate OpenGL interop.
Definition: mythvaapicontext.cpp:252
kCodec_MPEG1_VAAPI
@ kCodec_MPEG1_VAAPI
Definition: mythcodecid.h:69
DEINT_CPU
@ DEINT_CPU
Definition: mythframe.h:127
MythVAAPIInterop
Definition: mythvaapiinterop.h:36
videobuffers.h
MythCodecID
MythCodecID
Definition: mythcodecid.h:10
AVFrame
struct AVFrame AVFrame
Definition: BorderDetector.h:15
mythrenderopengl.h
toString
QString toString(MarkTypes type)
Definition: programtypes.cpp:26
MythVAAPIContext::DecoderWillResetOnFlush
bool DecoderWillResetOnFlush(void) override
Definition: mythvaapicontext.cpp:845
Decoder
Definition: decoder.h:65
MythVAAPIContext::FilteredReceiveFrame
int FilteredReceiveFrame(AVCodecContext *Context, AVFrame *Frame) override
Retrieve decoded frame and optionally deinterlace.
Definition: mythvaapicontext.cpp:674
DeinterlacerName
QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format)
Return a user friendly description of the given deinterlacer.
Definition: mythavutil.cpp:115
mythlogging.h
hardwareprofile.scan.profile
profile
Definition: scan.py:99
MythVAAPIInterop::GetDisplay
VADisplay GetDisplay(void)
Definition: mythvaapiinterop.cpp:91
MythOpenGLInterop::Unsupported
@ Unsupported
Definition: mythopenglinterop.h:31
AvFormatDecoder::GetMaxReferenceFrames
static int GetMaxReferenceFrames(AVCodecContext *Context)
Definition: avformatdecoder.cpp:1431
MythVAAPIContext::IsDeinterlacing
bool IsDeinterlacing(bool &DoubleRate, bool StreamChange=false) override
Definition: mythvaapicontext.cpp:831
CODEC_IS_MPEG
#define CODEC_IS_MPEG(id)
Definition: mythcodecid.h:359
MythVAAPIContext::RetrieveFrame
bool RetrieveFrame(AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame) override
Definition: mythvaapicontext.cpp:657
kCodec_MPEG1
@ kCodec_MPEG1
Definition: mythcodecid.h:21
MythCodecContext::GetBuffer
static int GetBuffer(struct AVCodecContext *Context, AVFrame *Frame, int Flags)
A generic hardware buffer initialisation method when using AVHWFramesContext.
Definition: mythcodeccontext.cpp:311
MythCodecContext::H264Main
@ H264Main
Definition: mythcodeccontext.h:85
MythVAAPIContext::HaveVAAPI
static QString HaveVAAPI(bool ReCheck=false)
Check whether VAAPI is available and not emulated via VDPAU.
Definition: mythvaapicontext.cpp:455
MythVAAPIContext::m_filterSource
AVFilterContext * m_filterSource
Definition: mythvaapicontext.h:61
MythVAAPIContext::GetFormat2
static enum AVPixelFormat GetFormat2(AVCodecContext *Context, const AVPixelFormat *PixFmt)
Definition: mythvaapicontext.cpp:238
MythVAAPIContext::MythVAAPIContext
MythVAAPIContext(DecoderBase *Parent, MythCodecID CodecID)
Definition: mythvaapicontext.cpp:31
MythVAAPIContext::PostProcessFrame
void PostProcessFrame(AVCodecContext *Context, VideoFrame *Frame) override
Definition: mythvaapicontext.cpp:739
MythEGL::IsEGL
bool IsEGL(void)
Definition: mythegl.cpp:29
VAAPIProfile
QPair< MythCodecContext::CodecProfile, QPair< QSize, QSize > > VAAPIProfile
Definition: mythvaapicontext.h:20
VA_FOURCC_I420
#define VA_FOURCC_I420
Definition: mythvaapiinterop.h:22
MythVAAPIContext::m_filterGraph
AVFilterGraph * m_filterGraph
Definition: mythvaapicontext.h:62
AvFormatDecoder
A decoder for video files.
Definition: avformatdecoder.h:88
MythCodecContext::H263
@ H263
Definition: mythcodeccontext.h:81
MythVAAPIContext::DecoderWillResetOnAspect
bool DecoderWillResetOnAspect(void) override
Definition: mythvaapicontext.cpp:851
uint
unsigned int uint
Definition: compat.h:140
kCodec_VP8_VAAPI_DEC
@ kCodec_VP8_VAAPI_DEC
Definition: mythcodecid.h:92
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
MythVAAPIContext::InitialiseContext2
static int InitialiseContext2(AVCodecContext *Context)
Create a VAAPI hardware context without OpenGL interop.
Definition: mythvaapicontext.cpp:406
MythOpenGLInterop::Type
Type
Definition: mythopenglinterop.h:29
MythVAAPIContext::m_filterWidth
int m_filterWidth
Definition: mythvaapicontext.h:67
MythVAAPIContext::m_deinterlacer2x
bool m_deinterlacer2x
Definition: mythvaapicontext.h:57
MythRenderOpenGL
Definition: mythrenderopengl.h:86
kCodec_MPEG2_VAAPI
@ kCodec_MPEG2_VAAPI
Definition: mythcodecid.h:70
MythVAAPIContext::m_filterHeight
int m_filterHeight
Definition: mythvaapicontext.h:68
MythCodecContext::CreateDevice
static AVBufferRef * CreateDevice(AVHWDeviceType Type, MythOpenGLInterop *Interop, const QString &Device=QString())
Definition: mythcodeccontext.cpp:532
MythDeintType
MythDeintType
Definition: mythframe.h:121
MythCodecContext::MPEG2Main
@ MPEG2Main
Definition: mythcodeccontext.h:59
MythVAAPIContext::GetProfiles
static const VAAPIProfiles & GetProfiles(void)
Definition: mythvaapicontext.cpp:502
MythVAAPIInterop::GetVendor
QString GetVendor(void)
Definition: mythvaapiinterop.cpp:96
codec_is_vaapi_dec
#define codec_is_vaapi_dec(id)
Definition: mythcodecid.h:313
codec_is_vaapi
#define codec_is_vaapi(id)
Definition: mythcodecid.h:311
avformatdecoder.h
MythVAAPIContext::m_filterPTSUsed
int64_t m_filterPTSUsed
Definition: mythvaapicontext.h:66
kCodec_H264_VAAPI
@ kCodec_H264_VAAPI
Definition: mythcodecid.h:73
MythRenderOpenGL::GetOpenGLRender
static MythRenderOpenGL * GetOpenGLRender(void)
Definition: mythrenderopengl.cpp:63
mythcontext.h
MythCodecContext::MJPEG
@ MJPEG
Definition: mythcodeccontext.h:119
MythVAAPIContext::FramesFormat
static AVPixelFormat FramesFormat(AVPixelFormat Format)
Definition: mythvaapicontext.cpp:116
MythVAAPIContext::m_filterSink
AVFilterContext * m_filterSink
Definition: mythvaapicontext.h:60
av_malloc
void * av_malloc(unsigned int size)
MythVAAPIContext::VAAPIProfileForCodec
static VAProfile VAAPIProfileForCodec(const AVCodecContext *Codec)
Definition: mythvaapicontext.cpp:41
MythVAAPIContext::m_lastTopFieldFirst
bool m_lastTopFieldFirst
Definition: mythvaapicontext.h:59
MythOpenGLInterop::TypeToString
static QString TypeToString(Type InteropType)
Definition: mythopenglinterop.cpp:35
MythCodecContext
Definition: mythcodeccontext.h:50
MythCodecContext::H264High
@ H264High
Definition: mythcodeccontext.h:87
MythCodecContext::GetProfileDescription
static QString GetProfileDescription(CodecProfile Profile, QSize Size, VideoFrameType Format=FMT_NONE, uint ColorDepth=0)
Definition: mythcodeccontext.cpp:759
MythVAAPIContext::m_framesCtx
AVBufferRef * m_framesCtx
Definition: mythvaapicontext.h:64
FMT_VAAPI
@ FMT_VAAPI
Definition: mythframe.h:62
MythOpenGLInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format, MythPlayer *Player)
Check whether we support direct rendering for the given VideoFrameType.
Definition: mythopenglinterop.cpp:77
mythmainwindow.h
MythVAAPIContext::m_lastInterlaced
int m_lastInterlaced
Definition: mythvaapicontext.h:58
MythCodecContext::HEVCMain
@ HEVCMain
Definition: mythcodeccontext.h:94
VideoBuffers::GetNumBuffers
static uint GetNumBuffers(int PixelFormat, int MaxReferenceFrames=16, bool Decoder=false)
Definition: videobuffers.cpp:135
MythCodecContext::InitialiseDecoder
static int InitialiseDecoder(AVCodecContext *Context, CreateHWDecoder Callback, const QString &Debug)
Initialise a hardware decoder that is expected to use AVHWFramesContext.
Definition: mythcodeccontext.cpp:493
DecoderBase
Definition: decoderbase.h:119
MythVAAPIContext::m_deinterlacer
MythDeintType m_deinterlacer
Definition: mythvaapicontext.h:56
MythCodecContext::VP8
@ VP8
Definition: mythcodeccontext.h:105
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:916
kCodec_MPEG1_VAAPI_DEC
@ kCodec_MPEG1_VAAPI_DEC
Definition: mythcodecid.h:85