MythTV  master
mythegldmabuf.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "fourcc.h"
4 #include "mythavutil.h"
5 #include "mythvideotexture.h"
6 #include "mythegldmabuf.h"
7 #include "mythegldefs.h"
8 
9 // FFmpeg
10 extern "C" {
11 #include "libavutil/hwcontext_drm.h"
12 }
13 
14 #define LOC QString("EGLDMABUF: ")
15 
17 {
18  if (Context)
19  {
20  OpenGLLocker locker(Context);
21  m_useModifiers = Context->IsEGL() && Context->HasEGLExtension("EGL_EXT_image_dma_buf_import_modifiers");
22  }
23 }
24 
26 {
27  if (!Context)
29  if (!Context)
30  return false;
31  OpenGLLocker locker(Context);
32  return (Context->IsEGL() && Context->hasExtension("GL_OES_EGL_image") &&
33  Context->HasEGLExtension("EGL_EXT_image_dma_buf_import"));
34 }
35 
36 static void inline DebugDRMFrame(AVDRMFrameDescriptor* Desc)
37 {
38  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("DRM frame: Layers %1 Objects %2")
39  .arg(Desc->nb_layers).arg(Desc->nb_objects));
40  for (int i = 0; i < Desc->nb_layers; ++i)
41  {
42  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Layer %1: Format %2 Planes %3")
43  .arg(i).arg(fourcc_str(static_cast<int>(Desc->layers[i].format)))
44  .arg(Desc->layers[i].nb_planes));
45  for (int j = 0; j < Desc->layers[i].nb_planes; ++j)
46  {
47  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString(" Plane %1: Index %2 Offset %3 Pitch %4")
48  .arg(j).arg(Desc->layers[i].planes[j].object_index)
49  .arg(Desc->layers[i].planes[j].offset).arg(Desc->layers[i].planes[j].pitch));
50  }
51  }
52  for (int i = 0; i < Desc->nb_objects; ++i)
53  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Object: %1 FD %2 Mods 0x%3")
54  .arg(i).arg(Desc->objects[i].fd).arg(Desc->objects[i].format_modifier, 0 , 16));
55 }
56 
62 inline vector<MythVideoTexture*> MythEGLDMABUF::CreateComposed(AVDRMFrameDescriptor* Desc,
64  VideoFrame *Frame, FrameScanType Scan) const
65 {
66  Frame->already_deinterlaced = true;
67  vector<MythVideoTexture*> result;
68  for (int i = 0; i < (Scan == kScan_Progressive ? 1 : 2); ++i)
69  {
70  vector<QSize> sizes;
71  int frameheight = Scan == kScan_Progressive ? Frame->height : Frame->height >> 1;
72  sizes.emplace_back(QSize(Frame->width, frameheight));
73  vector<MythVideoTexture*> textures =
76  if (textures.empty())
77  {
78  ClearDMATextures(Context, result);
79  return result;
80  }
81 
82  textures[0]->m_allowGLSLDeint = false;
83 
84  EGLint colourspace = EGL_ITU_REC709_EXT;
85  switch (Frame->colorspace)
86  {
87  case AVCOL_SPC_BT470BG:
88  case AVCOL_SPC_SMPTE170M:
89  case AVCOL_SPC_SMPTE240M:
90  colourspace = EGL_ITU_REC601_EXT;
91  break;
92  case AVCOL_SPC_BT2020_CL:
93  case AVCOL_SPC_BT2020_NCL:
94  colourspace = EGL_ITU_REC2020_EXT;
95  break;
96  default:
97  if (Frame->width < 1280)
98  colourspace = EGL_ITU_REC601_EXT;
99  break;
100  }
101 
102  static constexpr std::array<EGLint,4> kPlaneFd
105  static constexpr std::array<EGLint,4> kPlaneOffset
108  static constexpr std::array<EGLint,4> kPlanePitch
111  static constexpr std::array<EGLint,4> kPlaneModlo
114  static constexpr std::array<EGLint,4> kPlaneModhi
117 
118  AVDRMLayerDescriptor* layer = &Desc->layers[0];
119 
120  QVector<EGLint> attribs = {
121  EGL_LINUX_DRM_FOURCC_EXT, static_cast<EGLint>(layer->format),
122  EGL_WIDTH, Frame->width,
123  EGL_HEIGHT, frameheight,
124  EGL_YUV_COLOR_SPACE_HINT_EXT, colourspace,
128  };
129 
130  for (int plane = 0; plane < layer->nb_planes; ++plane)
131  {
132  AVDRMPlaneDescriptor* drmplane = &layer->planes[plane];
133  ptrdiff_t pitch = drmplane->pitch;
134  ptrdiff_t offset = drmplane->offset;
135  if (Scan != kScan_Progressive)
136  {
137  if (i > 0)
138  offset += pitch;
139  pitch = pitch << 1;
140  }
141  attribs << kPlaneFd[plane] << Desc->objects[drmplane->object_index].fd
142  << kPlaneOffset[plane] << static_cast<EGLint>(offset)
143  << kPlanePitch[plane] << static_cast<EGLint>(pitch);
144  if (m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 /* DRM_FORMAT_MOD_NONE*/))
145  {
146  attribs << kPlaneModlo[plane]
147  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
148  << kPlaneModhi[plane]
149  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier >> 32);
150  }
151  }
152  attribs << EGL_NONE;
153 
154  EGLImageKHR image = Context->eglCreateImageKHR(Context->GetEGLDisplay(), EGL_NO_CONTEXT,
155  EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
156  if (!image)
157  {
158  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No EGLImage '%1'").arg(Context->GetEGLError()));
159  // Ensure we release anything already created and return nothing
160  ClearDMATextures(Context, result);
161  return result;
162  }
163 
164  MythVideoTexture *texture = textures[0];
165  Context->glBindTexture(texture->m_target, texture->m_textureId);
166  Context->eglImageTargetTexture2DOES(texture->m_target, image);
167  Context->glBindTexture(texture->m_target, 0);
168  texture->m_data = static_cast<unsigned char *>(image);
169  result.push_back(texture);
170  }
171 
172  return result;
173 }
174 
179 inline vector<MythVideoTexture*> MythEGLDMABUF::CreateSeparate(AVDRMFrameDescriptor* Desc,
181  VideoFrame *Frame) const
182 {
183  // N.B. this works for YV12/NV12/P010 etc but will probably break for YUV422 etc
184  vector<QSize> sizes;
185  for (int plane = 0 ; plane < Desc->nb_layers; ++plane)
186  {
187  int width = Frame->width >> ((plane > 0) ? 1 : 0);
188  int height = Frame->height >> ((plane > 0) ? 1 : 0);
189  sizes.emplace_back(QSize(width, height));
190  }
191 
192  VideoFrameType format = PixelFormatToFrameType(static_cast<AVPixelFormat>(Frame->sw_pix_fmt));
193  vector<MythVideoTexture*> result =
194  MythVideoTexture::CreateTextures(Context, Frame->codec, format, sizes,
195  QOpenGLTexture::Target2D);
196  if (result.empty())
197  return result;
198 
199  for (uint plane = 0; plane < result.size(); ++plane)
200  {
201  result[plane]->m_allowGLSLDeint = true;
202  AVDRMLayerDescriptor* layer = &Desc->layers[plane];
203  AVDRMPlaneDescriptor* drmplane = &layer->planes[0];
204  QVector<EGLint> attribs = {
205  EGL_LINUX_DRM_FOURCC_EXT, static_cast<EGLint>(layer->format),
206  EGL_WIDTH, result[plane]->m_size.width(),
207  EGL_HEIGHT, result[plane]->m_size.height(),
208  EGL_DMA_BUF_PLANE0_FD_EXT, Desc->objects[drmplane->object_index].fd,
209  EGL_DMA_BUF_PLANE0_OFFSET_EXT, static_cast<EGLint>(drmplane->offset),
210  EGL_DMA_BUF_PLANE0_PITCH_EXT, static_cast<EGLint>(drmplane->pitch)
211  };
212 
213  if (m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 /* DRM_FORMAT_MOD_NONE*/))
214  {
216  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
218  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier >> 32);
219  }
220 
221  attribs << EGL_NONE;
222 
223  EGLImageKHR image = Context->eglCreateImageKHR(Context->GetEGLDisplay(), EGL_NO_CONTEXT,
224  EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
225  if (!image)
226  {
227  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No EGLImage for plane %1 %2")
228  .arg(plane).arg(Context->GetEGLError()));
229  ClearDMATextures(Context, result);
230  return result;
231  }
232 
233  Context->glBindTexture(result[plane]->m_target, result[plane]->m_textureId);
234  Context->eglImageTargetTexture2DOES(result[plane]->m_target, image);
235  Context->glBindTexture(result[plane]->m_target, 0);
236  result[plane]->m_data = static_cast<unsigned char *>(image);
237  }
238 
239  return result;
240 }
241 
242 #ifndef DRM_FORMAT_R8
243 #define MKTAG2(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | (static_cast<unsigned>(d) << 24))
244 #define DRM_FORMAT_R8 MKTAG2('R', '8', ' ', ' ')
245 #define DRM_FORMAT_GR88 MKTAG2('G', 'R', '8', '8')
246 #define DRM_FORMAT_R16 MKTAG2('R', '1', '6', ' ')
247 #define DRM_FORMAT_GR32 MKTAG2('G', 'R', '3', '2')
248 #define DRM_FORMAT_NV12 MKTAG2('N', 'V', '1', '2')
249 #define DRM_FORMAT_NV21 MKTAG2('N', 'V', '2', '1')
250 #define DRM_FORMAT_YUV420 MKTAG2('Y', 'U', '1', '2')
251 #define DRM_FORMAT_YVU420 MKTAG2('Y', 'V', '1', '2')
252 #define DRM_FORMAT_P010 MKTAG2('P', '0', '1', '0')
253 #endif
254 
269 inline vector<MythVideoTexture*> MythEGLDMABUF::CreateSeparate2(AVDRMFrameDescriptor* Desc,
271  VideoFrame *Frame) const
272 {
273  // As for CreateSeparate - may not work for some formats
274  AVDRMLayerDescriptor* layer = &Desc->layers[0];
275  vector<QSize> sizes;
276  for (int plane = 0 ; plane < layer->nb_planes; ++plane)
277  {
278  int width = Frame->width >> ((plane > 0) ? 1 : 0);
279  int height = Frame->height >> ((plane > 0) ? 1 : 0);
280  sizes.emplace_back(QSize(width, height));
281  }
282 
283  // TODO - the v4l2_m2m decoder is not setting the correct sw_fmt - so we
284  // need to deduce the frame format from the fourcc
285  VideoFrameType format = FMT_YV12;
286  EGLint fourcc1 = DRM_FORMAT_R8;
287  EGLint fourcc2 = DRM_FORMAT_R8;
288  if (layer->format == DRM_FORMAT_NV12 || layer->format == DRM_FORMAT_NV21)
289  {
290  format = FMT_NV12;
291  fourcc2 = DRM_FORMAT_GR88;
292  }
293  else if (layer->format == DRM_FORMAT_P010)
294  {
295  format = FMT_P010;
296  fourcc1 = DRM_FORMAT_R16;
297  fourcc2 = DRM_FORMAT_GR32;
298  }
299 
300  vector<MythVideoTexture*> result =
301  MythVideoTexture::CreateTextures(Context, Frame->codec, format, sizes,
302  QOpenGLTexture::Target2D);
303  if (result.empty())
304  return result;
305 
306  for (uint plane = 0; plane < result.size(); ++plane)
307  {
308  result[plane]->m_allowGLSLDeint = true;
309  EGLint fourcc = fourcc1;
310  if (plane > 0)
311  fourcc = fourcc2;
312  AVDRMPlaneDescriptor* drmplane = &layer->planes[plane];
313  QVector<EGLint> attribs = {
314  EGL_LINUX_DRM_FOURCC_EXT, fourcc,
315  EGL_WIDTH, result[plane]->m_size.width(),
316  EGL_HEIGHT, result[plane]->m_size.height(),
317  EGL_DMA_BUF_PLANE0_FD_EXT, Desc->objects[drmplane->object_index].fd,
318  EGL_DMA_BUF_PLANE0_OFFSET_EXT, static_cast<EGLint>(drmplane->offset),
319  EGL_DMA_BUF_PLANE0_PITCH_EXT, static_cast<EGLint>(drmplane->pitch)
320  };
321 
322  if (m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 /* DRM_FORMAT_MOD_NONE*/))
323  {
325  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
327  << static_cast<EGLint>(Desc->objects[drmplane->object_index].format_modifier >> 32);
328  }
329 
330  attribs << EGL_NONE;
331 
332  EGLImageKHR image = Context->eglCreateImageKHR(Context->GetEGLDisplay(), EGL_NO_CONTEXT,
333  EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
334  if (!image)
335  {
336  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No EGLImage for plane %1 %2")
337  .arg(plane).arg(Context->GetEGLError()));
338  ClearDMATextures(Context, result);
339  return result;
340  }
341 
342  Context->glBindTexture(result[plane]->m_target, result[plane]->m_textureId);
343  Context->eglImageTargetTexture2DOES(result[plane]->m_target, image);
344  Context->glBindTexture(result[plane]->m_target, 0);
345  result[plane]->m_data = static_cast<unsigned char *>(image);
346  }
347 
348  return result;
349 }
350 
352  vector<MythVideoTexture *> &Textures)
353 {
354  for (auto & texture : Textures)
355  {
356  if (texture->m_data)
357  Context->eglDestroyImageKHR(Context->GetEGLDisplay(), texture->m_data);
358  texture->m_data = nullptr;
359  if (texture->m_textureId)
360  Context->glDeleteTextures(1, &texture->m_textureId);
362  }
363  Textures.clear();
364 }
365 
366 vector<MythVideoTexture*> MythEGLDMABUF::CreateTextures(AVDRMFrameDescriptor* Desc,
368  VideoFrame *Frame,
369  bool UseSeparate,
370  FrameScanType Scan)
371 {
372  vector<MythVideoTexture*> result;
373  if (!Desc || !Context || !Frame)
374  return result;
375 
376  if (VERBOSE_LEVEL_CHECK(VB_PLAYBACK, LOG_DEBUG))
377  DebugDRMFrame(Desc);
378 
379  uint numlayers = static_cast<uint>(Desc->nb_layers);
380  if (numlayers < 1)
381  return result;
382 
383  OpenGLLocker locker(Context);
384 
385  // N.B. If the descriptor has a single layer (RGB, packed YUV), it shouldn't
386  // matter which path is taken here - the resulting calls are identical (with the
387  // exception of the colourspace hints for composed - which should be ignored per the spec for RGB).
388  // This MAY breakdown however for packed YUV formats when the frame format
389  // is not set correctly and/or the 'returned' format does not match
390  // our expectations.
391 
392  // For multiplanar formats (ie. YUV), this essentially assumes the implementation
393  // will supply a descriptor that matches the expectation of the
394  // EGL_EXT_image_dma_buf_import implementation (i.e. if it can cope with
395  // separate layers, it will supply a suitable descriptor).
396 
397  // One layer with X planes
398  if (numlayers == 1)
399  {
400  if (UseSeparate)
401  return CreateSeparate2(Desc, Context, Frame);
402  return CreateComposed(Desc, Context, Frame, Scan);
403  }
404  // X layers with one plane each
405  return CreateSeparate(Desc, Context, Frame);
406 }
EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
Definition: mythegldefs.h:59
EGL_DMA_BUF_PLANE2_FD_EXT
#define EGL_DMA_BUF_PLANE2_FD_EXT
Definition: mythegldefs.h:31
EGL_DMA_BUF_PLANE1_OFFSET_EXT
#define EGL_DMA_BUF_PLANE1_OFFSET_EXT
Definition: mythegldefs.h:29
MythEGLDMABUF::m_useModifiers
bool m_useModifiers
Definition: mythegldmabuf.h:41
EGL_DMA_BUF_PLANE0_FD_EXT
#define EGL_DMA_BUF_PLANE0_FD_EXT
Definition: mythegldefs.h:25
EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT
#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT
Definition: mythegldefs.h:58
MythVideoTexture::DeleteTexture
static void DeleteTexture(MythRenderOpenGL *Context, MythVideoTexture *Texture)
Definition: mythvideotexture.cpp:17
EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT
#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT
Definition: mythegldefs.h:36
EGL_ITU_REC601_EXT
#define EGL_ITU_REC601_EXT
Definition: mythegldefs.h:38
DRM_FORMAT_P010
#define DRM_FORMAT_P010
Definition: mythegldmabuf.cpp:252
EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
Definition: mythegldefs.h:55
Frame
Definition: zmdefines.h:94
FMT_P010
@ FMT_P010
Definition: mythframe.h:58
MythGLTexture::m_data
unsigned char * m_data
Definition: mythrenderopengl.h:59
MythVideoTexture::CreateTextures
static vector< MythVideoTexture * > CreateTextures(MythRenderOpenGL *Context, VideoFrameType Type, VideoFrameType Format, vector< QSize > Sizes, GLenum Target=QOpenGLTexture::Target2D)
Create a set of textures suitable for the given Type and Format.
Definition: mythvideotexture.cpp:57
EGL_DMA_BUF_PLANE2_OFFSET_EXT
#define EGL_DMA_BUF_PLANE2_OFFSET_EXT
Definition: mythegldefs.h:32
MythEGLDMABUF::ClearDMATextures
static void ClearDMATextures(MythRenderOpenGL *Context, vector< MythVideoTexture * > &Textures)
Definition: mythegldmabuf.cpp:351
arg
arg(title).arg(filename).arg(doDelete))
DRM_FORMAT_R16
#define DRM_FORMAT_R16
Definition: mythegldmabuf.cpp:246
PixelFormatToFrameType
VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt)
Definition: mythavutil.cpp:69
FrameScanType
FrameScanType
Definition: videoouttypes.h:79
Context
QHash< QString, Action * > Context
Definition: action.h:77
EGL_DMA_BUF_PLANE0_PITCH_EXT
#define EGL_DMA_BUF_PLANE0_PITCH_EXT
Definition: mythegldefs.h:27
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT
#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT
Definition: mythegldefs.h:52
mythvideotexture.h
VideoFrame
Definition: mythframe.h:138
MythEGLDMABUF::CreateSeparate
vector< MythVideoTexture * > CreateSeparate(AVDRMFrameDescriptor *Desc, MythRenderOpenGL *Context, VideoFrame *Frame) const
Create multiple textures that represent the planes for the given AVDRMFrameDescriptor.
Definition: mythegldmabuf.cpp:179
EGL_ITU_REC709_EXT
#define EGL_ITU_REC709_EXT
Definition: mythegldefs.h:39
MythEGLDMABUF::HaveDMABuf
static bool HaveDMABuf(MythRenderOpenGL *Context)
Definition: mythegldmabuf.cpp:25
EGL_YUV_COLOR_SPACE_HINT_EXT
#define EGL_YUV_COLOR_SPACE_HINT_EXT
Definition: mythegldefs.h:34
EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT
#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT
Definition: mythegldefs.h:56
fourcc_str
static char * fourcc_str(int i)
Definition: fourcc.h:25
mythegldmabuf.h
EGL_LINUX_DRM_FOURCC_EXT
#define EGL_LINUX_DRM_FOURCC_EXT
Definition: mythegldefs.h:24
GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES
Definition: mythrenderopengldefs.h:13
EGL_YUV_NARROW_RANGE_EXT
#define EGL_YUV_NARROW_RANGE_EXT
Definition: mythegldefs.h:42
mythrenderopengl.h
MythEGLDMABUF::CreateTextures
vector< MythVideoTexture * > CreateTextures(AVDRMFrameDescriptor *Desc, MythRenderOpenGL *Context, VideoFrame *Frame, bool UseSeparate, FrameScanType Scan=kScan_Progressive)
Definition: mythegldmabuf.cpp:366
EGL_YUV_FULL_RANGE_EXT
#define EGL_YUV_FULL_RANGE_EXT
Definition: mythegldefs.h:41
kScan_Progressive
@ kScan_Progressive
Definition: videoouttypes.h:84
EGL_SAMPLE_RANGE_HINT_EXT
#define EGL_SAMPLE_RANGE_HINT_EXT
Definition: mythegldefs.h:35
FMT_YV12
@ FMT_YV12
Definition: mythframe.h:28
EGL_ITU_REC2020_EXT
#define EGL_ITU_REC2020_EXT
Definition: mythegldefs.h:40
DRM_FORMAT_R8
#define DRM_FORMAT_R8
Definition: mythegldmabuf.cpp:244
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
Definition: mythegldefs.h:53
MythEGLDMABUF::CreateComposed
vector< MythVideoTexture * > CreateComposed(AVDRMFrameDescriptor *Desc, MythRenderOpenGL *Context, VideoFrame *Frame, FrameScanType Scan) const
Create a single RGBA32 texture using the provided AVDRMFramDescriptor.
Definition: mythegldmabuf.cpp:62
EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT
#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT
Definition: mythegldefs.h:37
DRM_FORMAT_GR88
#define DRM_FORMAT_GR88
Definition: mythegldmabuf.cpp:245
EGL_DMA_BUF_PLANE3_PITCH_EXT
#define EGL_DMA_BUF_PLANE3_PITCH_EXT
Definition: mythegldefs.h:51
uint
unsigned int uint
Definition: compat.h:140
MythGLTexture::m_target
GLenum m_target
Definition: mythrenderopengl.h:73
mythegldefs.h
MythRenderOpenGL
Definition: mythrenderopengl.h:95
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
MythEGLDMABUF::MythEGLDMABUF
MythEGLDMABUF(MythRenderOpenGL *Context)
Definition: mythegldmabuf.cpp:16
MythGLTexture::m_textureId
GLuint m_textureId
Definition: mythrenderopengl.h:61
LOC
#define LOC
Definition: mythegldmabuf.cpp:14
DRM_FORMAT_GR32
#define DRM_FORMAT_GR32
Definition: mythegldmabuf.cpp:247
EGL_DMA_BUF_PLANE3_FD_EXT
#define EGL_DMA_BUF_PLANE3_FD_EXT
Definition: mythegldefs.h:49
mythavutil.h
EGL_DMA_BUF_PLANE0_OFFSET_EXT
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT
Definition: mythegldefs.h:26
EGL_DMA_BUF_PLANE3_OFFSET_EXT
#define EGL_DMA_BUF_PLANE3_OFFSET_EXT
Definition: mythegldefs.h:50
EGL_DMA_BUF_PLANE1_FD_EXT
#define EGL_DMA_BUF_PLANE1_FD_EXT
Definition: mythegldefs.h:28
DRM_FORMAT_NV12
#define DRM_FORMAT_NV12
Definition: mythegldmabuf.cpp:248
MythRenderOpenGL::GetOpenGLRender
static MythRenderOpenGL * GetOpenGLRender(void)
Definition: mythrenderopengl.cpp:63
DRM_FORMAT_NV21
#define DRM_FORMAT_NV21
Definition: mythegldmabuf.cpp:249
EGL_DMA_BUF_PLANE1_PITCH_EXT
#define EGL_DMA_BUF_PLANE1_PITCH_EXT
Definition: mythegldefs.h:30
VideoFrameType
VideoFrameType
Definition: mythframe.h:25
FMT_NV12
@ FMT_NV12
Definition: mythframe.h:57
MythVideoTexture
Definition: mythvideotexture.h:21
EGL_YUV_CHROMA_SITING_0_EXT
#define EGL_YUV_CHROMA_SITING_0_EXT
Definition: mythegldefs.h:43
MythEGLDMABUF::CreateSeparate2
vector< MythVideoTexture * > CreateSeparate2(AVDRMFrameDescriptor *Desc, MythRenderOpenGL *Context, VideoFrame *Frame) const
Create multiple textures that represent the planes for the given AVDRMFrameDescriptor.
Definition: mythegldmabuf.cpp:269
EGL_DMA_BUF_PLANE2_PITCH_EXT
#define EGL_DMA_BUF_PLANE2_PITCH_EXT
Definition: mythegldefs.h:33
EGL_LINUX_DMA_BUF_EXT
#define EGL_LINUX_DMA_BUF_EXT
Definition: mythegldefs.h:23
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT
#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT
Definition: mythegldefs.h:54
EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
Definition: mythegldefs.h:57
DebugDRMFrame
static void DebugDRMFrame(AVDRMFrameDescriptor *Desc)
Definition: mythegldmabuf.cpp:36
fourcc.h
FMT_RGBA32
@ FMT_RGBA32
Definition: mythframe.h:39
OpenGLLocker
Definition: mythrenderopengl.h:253