MythTV  master
mythvaapiinterop.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythvideoout.h"
3 #include "videocolourspace.h"
4 #include "fourcc.h"
5 #include "mythvaapiinterop.h"
6 #include "mythvaapidrminterop.h"
7 #include "mythvaapiglxinterop.h"
8 
9 extern "C" {
10 #include "libavfilter/buffersrc.h"
11 #include "libavfilter/buffersink.h"
12 #include "libavutil/hwcontext_vaapi.h"
13 }
14 
15 #define LOC QString("VAAPIInterop: ")
16 
32 {
33  if ((FMT_VAAPI != Format) || getenv("NO_VAAPI"))
34  return Unsupported;
35 
37  if (!context)
38  return Unsupported;
39 
40  OpenGLLocker locker(context);
41  bool egl = context->IsEGL();
42  bool opengles = context->isOpenGLES();
43  bool wayland = qgetenv("XDG_SESSION_TYPE").contains("wayland");
44  // best first
45 #ifdef USING_EGL
46  if (egl && MythVAAPIInteropDRM::IsSupported(context)) // zero copy
47  return VAAPIEGLDRM;
48 #endif
49  if (!egl && !wayland && MythVAAPIInteropGLXPixmap::IsSupported(context)) // copy
50  return VAAPIGLXPIX;
51  if (!egl && !opengles && !wayland) // 2 * copy
52  return VAAPIGLXCOPY;
53  return Unsupported;
54 }
55 
57 {
58  if (!Context)
59  return nullptr;
60 #ifdef USING_EGL
61  if (InteropType == VAAPIEGLDRM)
62  return new MythVAAPIInteropDRM(Context);
63 #endif
64  if (InteropType == VAAPIGLXPIX)
66  if (InteropType == VAAPIGLXCOPY)
67  return new MythVAAPIInteropGLXCopy(Context);
68  return nullptr;
69 }
70 
79  : MythOpenGLInterop(Context, InteropType)
80 {
81 }
82 
84 {
86  if (m_vaDisplay)
87  if (vaTerminate(m_vaDisplay) != VA_STATUS_SUCCESS)
88  LOG(VB_GENERAL, LOG_WARNING, LOC + "Error closing VAAPI display");
89 }
90 
92 {
93  return m_vaDisplay;
94 }
95 
97 {
98  return m_vaVendor;
99 }
100 
102 {
103  if (!m_vaDisplay)
104  return;
105  int major = 0;
106  int minor = 0;
107  if (vaInitialize(m_vaDisplay, &major, &minor) != VA_STATUS_SUCCESS)
108  {
109  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to initialise VAAPI display");
110  vaTerminate(m_vaDisplay);
111  m_vaDisplay = nullptr;
112  }
113  else
114  {
115  m_vaVendor = vaQueryVendorString(m_vaDisplay);
116  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Created VAAPI %1.%2 display for %3 (%4)")
118  }
119 }
120 
122 {
123  if (m_filterGraph)
124  LOG(VB_GENERAL, LOG_INFO, LOC + "Destroying VAAPI deinterlacer");
125  avfilter_graph_free(&m_filterGraph);
126  m_filterGraph = nullptr;
127  m_filterSink = nullptr;
128  m_filterSource = nullptr;
130  m_deinterlacer2x = false;
131  m_firstField = true;
134  av_buffer_unref(&m_vppFramesContext);
135 }
136 
138 {
139  VASurfaceID result = 0;
140  if (!Frame)
141  return result;
142 
143  if ((Frame->pix_fmt != AV_PIX_FMT_VAAPI) || (Frame->codec != FMT_VAAPI) ||
144  !Frame->buf || !Frame->priv[1])
145  return result;
146 
147  // Sanity check the context
148  if (m_context != Context)
149  {
150  LOG(VB_GENERAL, LOG_ERR, LOC + "Mismatched OpenGL contexts!");
151  return result;
152  }
153 
154  // Check size
155  QSize surfacesize(Frame->width, Frame->height);
156  if (m_openglTextureSize != surfacesize)
157  {
158  if (!m_openglTextureSize.isEmpty())
159  LOG(VB_GENERAL, LOG_WARNING, LOC + "Video texture size changed!");
160  m_openglTextureSize = surfacesize;
161  }
162 
163  // Retrieve surface
164  auto id = static_cast<VASurfaceID>(reinterpret_cast<uintptr_t>(Frame->buf));
165  if (id)
166  result = id;
167  return result;
168 }
169 
170 bool MythVAAPIInterop::SetupDeinterlacer(MythDeintType Deinterlacer, bool DoubleRate,
171  AVBufferRef *FramesContext,
172  int Width, int Height,
173  // Outputs
174  AVFilterGraph *&Graph,
175  AVFilterContext *&Source,
176  AVFilterContext *&Sink)
177 {
178  if (!FramesContext)
179  {
180  LOG(VB_GENERAL, LOG_ERR, LOC + "No hardware frames context");
181  return false;
182  }
183 
184  int ret = 0;
185  QString args;
186  QString deinterlacer = "bob";
187  if (DEINT_MEDIUM == Deinterlacer)
188  deinterlacer = "motion_adaptive";
189  else if (DEINT_HIGH == Deinterlacer)
190  deinterlacer = "motion_compensated";
191 
192  // N.B. set auto to 0 otherwise we confuse playback if VAAPI does not deinterlace
193  QString filters = QString("deinterlace_vaapi=mode=%1:rate=%2:auto=0")
194  .arg(deinterlacer).arg(DoubleRate ? "field" : "frame");
195  const AVFilter *buffersrc = avfilter_get_by_name("buffer");
196  const AVFilter *buffersink = avfilter_get_by_name("buffersink");
197  AVFilterInOut *outputs = avfilter_inout_alloc();
198  AVFilterInOut *inputs = avfilter_inout_alloc();
199  AVBufferSrcParameters* params = nullptr;
200 
201  Graph = avfilter_graph_alloc();
202  if (!outputs || !inputs || !Graph)
203  {
204  ret = AVERROR(ENOMEM);
205  goto end;
206  }
207 
208  /* buffer video source: the decoded frames from the decoder will be inserted here. */
209  args = QString("video_size=%1x%2:pix_fmt=%3:time_base=1/1")
210  .arg(Width).arg(Height).arg(AV_PIX_FMT_VAAPI);
211 
212  ret = avfilter_graph_create_filter(&Source, buffersrc, "in",
213  args.toLocal8Bit().constData(), nullptr, Graph);
214  if (ret < 0)
215  {
216  LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer source");
217  goto end;
218  }
219 
220  params = av_buffersrc_parameters_alloc();
221  params->hw_frames_ctx = FramesContext;
222  ret = av_buffersrc_parameters_set(Source, params);
223 
224  if (ret < 0)
225  {
226  LOG(VB_GENERAL, LOG_ERR, LOC + "av_buffersrc_parameters_set failed");
227  goto end;
228  }
229  av_freep(&params);
230 
231  /* buffer video sink: to terminate the filter chain. */
232  ret = avfilter_graph_create_filter(&Sink, buffersink, "out",
233  nullptr, nullptr, Graph);
234  if (ret < 0)
235  {
236  LOG(VB_GENERAL, LOG_ERR, LOC + "avfilter_graph_create_filter failed for buffer sink");
237  goto end;
238  }
239 
240  /*
241  * Set the endpoints for the filter graph. The filter_graph will
242  * be linked to the graph described by filters_descr.
243  */
244 
245  /*
246  * The buffer source output must be connected to the input pad of
247  * the first filter described by filters_descr; since the first
248  * filter input label is not specified, it is set to "in" by
249  * default.
250  */
251  outputs->name = av_strdup("in");
252  outputs->filter_ctx = Source;
253  outputs->pad_idx = 0;
254  outputs->next = nullptr;
255 
256  /*
257  * The buffer sink input must be connected to the output pad of
258  * the last filter described by filters_descr; since the last
259  * filter output label is not specified, it is set to "out" by
260  * default.
261  */
262  inputs->name = av_strdup("out");
263  inputs->filter_ctx = Sink;
264  inputs->pad_idx = 0;
265  inputs->next = nullptr;
266 
267  if ((ret = avfilter_graph_parse_ptr(Graph, filters.toLocal8Bit(),
268  &inputs, &outputs, nullptr)) < 0)
269  {
270  LOG(VB_GENERAL, LOG_ERR, LOC + QString("avfilter_graph_parse_ptr failed for %1")
271  .arg(filters));
272  goto end;
273  }
274 
275  if ((ret = avfilter_graph_config(Graph, nullptr)) < 0)
276  {
277  LOG(VB_GENERAL, LOG_ERR, LOC +
278  QString("VAAPI deinterlacer config failed - '%1' unsupported?").arg(deinterlacer));
279  goto end;
280  }
281 
282  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Created deinterlacer '%1'")
283  .arg(DeinterlacerName(Deinterlacer | DEINT_DRIVER, DoubleRate, FMT_VAAPI)));
284 
285 end:
286  if (ret < 0)
287  {
288  avfilter_graph_free(&Graph);
289  Graph = nullptr;
290  }
291  avfilter_inout_free(&inputs);
292  avfilter_inout_free(&outputs);
293  return ret >= 0;
294 }
295 
296 VASurfaceID MythVAAPIInterop::Deinterlace(VideoFrame *Frame, VASurfaceID Current, FrameScanType Scan)
297 {
298  VASurfaceID result = Current;
299  if (!Frame)
300  return result;
301 
302  while (!m_filterError && is_interlaced(Scan))
303  {
304  // N.B. for DRM the use of a shader deint is checked before we get here
305  MythDeintType deinterlacer = DEINT_NONE;
306  bool doublerate = true;
307  // no CPU or GLSL deinterlacing so pick up these options as well
308  // N.B. Override deinterlacer_allowed to pick up any preference
311 
312  if (doublepref)
313  {
314  deinterlacer = doublepref;
315  }
316  else if (singlepref)
317  {
318  deinterlacer = singlepref;
319  doublerate = false;
320  }
321 
322  if ((m_deinterlacer == deinterlacer) && (m_deinterlacer2x == doublerate))
323  break;
324 
326 
327  if (deinterlacer != DEINT_NONE)
328  {
329  auto* frames = reinterpret_cast<AVBufferRef*>(Frame->priv[1]);
330  if (!frames)
331  break;
332 
333  AVBufferRef* hwdeviceref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
334  if (!hwdeviceref)
335  break;
336 
337  auto* hwdevicecontext = reinterpret_cast<AVHWDeviceContext*>(hwdeviceref->data);
338  hwdevicecontext->free = [](AVHWDeviceContext* /*unused*/) { LOG(VB_PLAYBACK, LOG_INFO, LOC + "VAAPI VPP device context finished"); };
339 
340  auto *vaapidevicectx = reinterpret_cast<AVVAAPIDeviceContext*>(hwdevicecontext->hwctx);
341  vaapidevicectx->display = m_vaDisplay; // re-use the existing display
342 
343  if (av_hwdevice_ctx_init(hwdeviceref) < 0)
344  {
345  av_buffer_unref(&hwdeviceref);
346  m_filterError = true;
347  break;
348  }
349 
350  AVBufferRef *newframes = av_hwframe_ctx_alloc(hwdeviceref);
351  if (!newframes)
352  {
353  m_filterError = true;
354  av_buffer_unref(&hwdeviceref);
355  break;
356  }
357 
358  auto* dstframes = reinterpret_cast<AVHWFramesContext*>(newframes->data);
359  auto* srcframes = reinterpret_cast<AVHWFramesContext*>(frames->data);
360 
361  m_filterWidth = srcframes->width;
362  m_filterHeight = srcframes->height;
363  static constexpr int kVppPoolSize = 2; // seems to be enough
364  dstframes->sw_format = srcframes->sw_format;
365  dstframes->width = m_filterWidth;
366  dstframes->height = m_filterHeight;
367  dstframes->initial_pool_size = kVppPoolSize;
368  dstframes->format = AV_PIX_FMT_VAAPI;
369  dstframes->free = [](AVHWFramesContext* /*unused*/) { LOG(VB_PLAYBACK, LOG_INFO, LOC + "VAAPI VPP frames context finished"); };
370 
371  if (av_hwframe_ctx_init(newframes) < 0)
372  {
373  m_filterError = true;
374  av_buffer_unref(&hwdeviceref);
375  av_buffer_unref(&newframes);
376  break;
377  }
378 
379  m_vppFramesContext = newframes;
380  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("New VAAPI frame pool with %1 %2x%3 surfaces")
381  .arg(kVppPoolSize).arg(m_filterWidth).arg(m_filterHeight));
382  av_buffer_unref(&hwdeviceref);
383 
384  if (!MythVAAPIInterop::SetupDeinterlacer(deinterlacer, doublerate, m_vppFramesContext,
387  {
388  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to create VAAPI deinterlacer %1 - disabling")
389  .arg(DeinterlacerName(deinterlacer | DEINT_DRIVER, doublerate, FMT_VAAPI)));
391  m_filterError = true;
392  }
393  else
394  {
395  m_deinterlacer = deinterlacer;
396  m_deinterlacer2x = doublerate;
398  break;
399  }
400  }
401  break;
402  }
403 
404  if (!is_interlaced(Scan) && m_deinterlacer)
406 
407  if (m_deinterlacer)
408  {
409  // deinterlacing the pause frame repeatedly is unnecessary and, due to the
410  // buffering in the VAAPI frames context, causes the image to 'jiggle' when using
411  // double rate deinterlacing. If we are confident this is a pause frame we have seen,
412  // return the last deinterlaced frame.
413  if (Frame->pause_frame && m_lastFilteredFrame && (m_lastFilteredFrameCount == Frame->frameCounter))
414  return m_lastFilteredFrame;
415 
416  Frame->deinterlace_inuse = m_deinterlacer | DEINT_DRIVER;
417  Frame->deinterlace_inuse2x = m_deinterlacer2x;
418 
419  // 'pump' the filter with frames until it starts returning usefull output.
420  // This minimises discontinuities at start up (where we would otherwise
421  // show a couple of progressive frames first) and memory consumption for the DRM
422  // interop as we only cache OpenGL textures for the deinterlacer's frame
423  // pool.
424  int retries = 3;
425  while ((result == Current) && retries--)
426  {
427  while (true)
428  {
429  int ret = 0;
430  MythAVFrame sinkframe;
431  sinkframe->format = AV_PIX_FMT_VAAPI;
432 
433  // only ask for a frame if we are expecting another
435  {
436  ret = av_buffersink_get_frame(m_filterSink, sinkframe);
437  if (ret >= 0)
438  {
439  // we have a filtered frame
440  result = m_lastFilteredFrame = static_cast<VASurfaceID>(reinterpret_cast<uintptr_t>(sinkframe->data[3]));
441  m_lastFilteredFrameCount = Frame->frameCounter;
442  m_firstField = true;
443  break;
444  }
445  if (ret != AVERROR(EAGAIN))
446  break;
447  }
448 
449  // add another frame
450  MythAVFrame sourceframe;
451  sourceframe->top_field_first =
452  static_cast<int>(Frame->interlaced_reversed ? !Frame->top_field_first : Frame->top_field_first);
453  sourceframe->interlaced_frame = 1;
454  sourceframe->data[3] = Frame->buf;
455  auto* buffer = reinterpret_cast<AVBufferRef*>(Frame->priv[0]);
456  sourceframe->buf[0] = buffer ? av_buffer_ref(buffer) : nullptr;
457  sourceframe->width = m_filterWidth;
458  sourceframe->height = m_filterHeight;
459  sourceframe->format = AV_PIX_FMT_VAAPI;
460  // N.B. This is required after changes in FFmpeg. Using the vpp
461  // frames context doesn't seem correct - but using the 'master'
462  // context does not work
463  sourceframe->hw_frames_ctx = av_buffer_ref(m_vppFramesContext);
464  ret = av_buffersrc_add_frame(m_filterSource, sourceframe);
465  sourceframe->data[3] = nullptr;
466  sourceframe->buf[0] = nullptr;
467  if (ret < 0)
468  break;
469 
470  // try again
471  ret = av_buffersink_get_frame(m_filterSink, sinkframe);
472  if (ret >= 0)
473  {
474  // we have a filtered frame
475  result = m_lastFilteredFrame = static_cast<VASurfaceID>(reinterpret_cast<uintptr_t>(sinkframe->data[3]));
476  m_lastFilteredFrameCount = Frame->frameCounter;
477  m_firstField = false;
478  break;
479  }
480  break;
481  }
482  }
483  }
484  return result;
485 }
MythVAAPIInterop::m_vppFramesContext
AVBufferRef * m_vppFramesContext
Definition: mythvaapiinterop.h:69
MythVAAPIInterop::m_lastFilteredFrame
VASurfaceID m_lastFilteredFrame
Definition: mythvaapiinterop.h:76
MythVAAPIInterop::m_vaVendor
QString m_vaVendor
Definition: mythvaapiinterop.h:64
Source
static QString Source(const QNetworkRequest &request)
Definition: netstream.cpp:137
GetSingleRateOption
MythDeintType GetSingleRateOption(const VideoFrame *Frame, MythDeintType Type, MythDeintType Override)
Definition: mythframe.cpp:834
build_compdb.args
args
Definition: build_compdb.py:11
MythVAAPIInterop::m_filterSource
AVFilterContext * m_filterSource
Definition: mythvaapiinterop.h:71
DEINT_DRIVER
@ DEINT_DRIVER
Definition: mythframe.h:129
MythVAAPIInterop::Deinterlace
VASurfaceID Deinterlace(VideoFrame *Frame, VASurfaceID Current, FrameScanType Scan)
Definition: mythvaapiinterop.cpp:296
DEINT_MEDIUM
@ DEINT_MEDIUM
Definition: mythframe.h:125
mythvaapiinterop.h
MythVAAPIInterop::m_deinterlacer
MythDeintType m_deinterlacer
Definition: mythvaapiinterop.h:66
mythvideoout.h
MythVAAPIInterop::MythVAAPIInterop
MythVAAPIInterop(MythRenderOpenGL *Context, Type InteropType)
Definition: mythvaapiinterop.cpp:78
DEINT_SHADER
@ DEINT_SHADER
Definition: mythframe.h:128
MythVAAPIInterop::Create
static MythVAAPIInterop * Create(MythRenderOpenGL *Context, Type InteropType)
Definition: mythvaapiinterop.cpp:56
Frame
Definition: zmdefines.h:93
MythAVFrame
MythAVFrame little utility class that act as a safe way to allocate an AVFrame which can then be allo...
Definition: mythavutil.h:43
MythVAAPIInterop::m_filterHeight
int m_filterHeight
Definition: mythvaapiinterop.h:75
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:123
arg
arg(title).arg(filename).arg(doDelete))
FrameScanType
FrameScanType
Definition: videoouttypes.h:78
GetDoubleRateOption
MythDeintType GetDoubleRateOption(const VideoFrame *Frame, MythDeintType Type, MythDeintType Override)
Definition: mythframe.cpp:847
Context
QHash< QString, Action * > Context
Definition: action.h:77
MythDate::Format
Format
Definition: mythdate.h:12
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
DEINT_ALL
@ DEINT_ALL
Definition: mythframe.h:130
VideoFrame
Definition: mythframe.h:137
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
MythVAAPIInterop::InitaliseDisplay
void InitaliseDisplay(void)
Definition: mythvaapiinterop.cpp:101
MythVAAPIInterop::DestroyDeinterlacer
virtual void DestroyDeinterlacer(void)
Definition: mythvaapiinterop.cpp:121
MythOpenGLInterop::m_type
Type m_type
Definition: mythopenglinterop.h:74
DEINT_CPU
@ DEINT_CPU
Definition: mythframe.h:127
MythVAAPIInterop
Definition: mythvaapiinterop.h:36
MythVAAPIInteropGLXCopy
Definition: mythvaapiglxinterop.h:30
mythvaapiglxinterop.h
MythVAAPIInterop::m_firstField
bool m_firstField
Definition: mythvaapiinterop.h:68
minor
#define minor(X)
Definition: compat.h:138
DeinterlacerName
QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format)
Return a user friendly description of the given deinterlacer.
Definition: mythavutil.cpp:115
MythOpenGLInterop
Definition: mythopenglinterop.h:23
MythVAAPIInterop::GetDisplay
VADisplay GetDisplay(void)
Definition: mythvaapiinterop.cpp:91
Source
Definition: channelsettings.cpp:68
MythOpenGLInterop::Unsupported
@ Unsupported
Definition: mythopenglinterop.h:31
MythVAAPIInterop::~MythVAAPIInterop
~MythVAAPIInterop() override
Definition: mythvaapiinterop.cpp:83
LOC
#define LOC
Definition: mythvaapiinterop.cpp:15
MythEGL::IsEGL
bool IsEGL(void)
Definition: mythegl.cpp:29
MythOpenGLInterop::m_context
MythRenderOpenGL * m_context
Definition: mythopenglinterop.h:73
MythOpenGLInterop::VAAPIGLXCOPY
@ VAAPIGLXCOPY
Definition: mythopenglinterop.h:32
mythvaapidrminterop.h
videocolourspace.h
MythOpenGLInterop::Type
Type
Definition: mythopenglinterop.h:29
MythVAAPIInterop::m_filterError
bool m_filterError
Definition: mythvaapiinterop.h:73
MythVAAPIInterop::m_deinterlacer2x
bool m_deinterlacer2x
Definition: mythvaapiinterop.h:67
MythVAAPIInterop::PostInitDeinterlacer
virtual void PostInitDeinterlacer(void)
Definition: mythvaapiinterop.h:60
MythOpenGLInterop::VAAPIGLXPIX
@ VAAPIGLXPIX
Definition: mythopenglinterop.h:33
MythVAAPIInterop::m_filterGraph
AVFilterGraph * m_filterGraph
Definition: mythvaapiinterop.h:72
MythRenderOpenGL
Definition: mythrenderopengl.h:86
MythDeintType
MythDeintType
Definition: mythframe.h:121
MythVAAPIInterop::m_filterSink
AVFilterContext * m_filterSink
Definition: mythvaapiinterop.h:70
MythVAAPIInteropGLXPixmap
Definition: mythvaapiglxinterop.h:48
MythVAAPIInteropDRM::IsSupported
static bool IsSupported(MythRenderOpenGL *Context)
Definition: mythvaapidrminterop.cpp:365
MythVAAPIInterop::GetVendor
QString GetVendor(void)
Definition: mythvaapiinterop.cpp:96
MythVAAPIInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Return an 'interoperability' method that is supported by the current render device.
Definition: mythvaapiinterop.cpp:31
MythOpenGLInterop::VAAPIEGLDRM
@ VAAPIEGLDRM
Definition: mythopenglinterop.h:34
MythVAAPIInteropGLXPixmap::IsSupported
static bool IsSupported(MythRenderOpenGL *Context)
Definition: mythvaapiglxinterop.cpp:480
DEINT_HIGH
@ DEINT_HIGH
Definition: mythframe.h:126
MythRenderOpenGL::GetOpenGLRender
static MythRenderOpenGL * GetOpenGLRender(void)
Definition: mythrenderopengl.cpp:63
MythVAAPIInterop::m_lastFilteredFrameCount
long long m_lastFilteredFrameCount
Definition: mythvaapiinterop.h:77
MythVAAPIInterop::VerifySurface
VASurfaceID VerifySurface(MythRenderOpenGL *Context, VideoFrame *Frame)
Definition: mythvaapiinterop.cpp:137
MythOpenGLInterop::TypeToString
static QString TypeToString(Type InteropType)
Definition: mythopenglinterop.cpp:35
MythVAAPIInterop::m_filterWidth
int m_filterWidth
Definition: mythvaapiinterop.h:74
VideoFrameType
VideoFrameType
Definition: mythframe.h:24
FMT_VAAPI
@ FMT_VAAPI
Definition: mythframe.h:62
is_interlaced
bool is_interlaced(FrameScanType Scan)
Definition: videoouttypes.h:174
MythOpenGLInterop::m_openglTextureSize
QSize m_openglTextureSize
Definition: mythopenglinterop.h:76
MythVAAPIInterop::m_vaDisplay
VADisplay m_vaDisplay
Definition: mythvaapiinterop.h:63
MythVAAPIInteropDRM
Definition: mythvaapidrminterop.h:11
fourcc.h
OpenGLLocker
Definition: mythrenderopengl.h:244