11 #include "libavutil/hwcontext_drm.h"
14 #define LOC QString("EGLDMABUF: ")
30 return (Context->
IsEGL() && Context->hasExtension(
"GL_OES_EGL_image") &&
36 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"DRM frame: Layers %1 Objects %2")
37 .
arg(Desc->nb_layers).arg(Desc->nb_objects));
38 for (
int i = 0; i < Desc->nb_layers; ++i)
40 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Layer %1: Format %2 Planes %3")
42 .arg(Desc->layers[i].nb_planes));
43 for (
int j = 0; j < Desc->layers[i].nb_planes; ++j)
45 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
" Plane %1: Index %2 Offset %3 Pitch %4")
46 .
arg(j).
arg(Desc->layers[i].planes[j].object_index)
47 .arg(Desc->layers[i].planes[j].offset).arg(Desc->layers[i].planes[j].pitch));
50 for (
int i = 0; i < Desc->nb_objects; ++i)
51 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Object: %1 FD %2 Mods 0x%3")
52 .
arg(i).
arg(Desc->objects[i].fd).arg(Desc->objects[i].format_modifier, 0 , 16));
64 Frame->m_alreadyDeinterlaced =
true;
65 std::vector<MythVideoTextureOpenGL*> result;
68 std::vector<QSize> sizes;
70 sizes.emplace_back(QSize(
Frame->m_width, frameheight));
71 std::vector<MythVideoTextureOpenGL*> textures =
80 textures[0]->m_allowGLSLDeint =
false;
83 switch (
Frame->m_colorspace)
85 case AVCOL_SPC_BT470BG:
86 case AVCOL_SPC_SMPTE170M:
87 case AVCOL_SPC_SMPTE240M:
90 case AVCOL_SPC_BT2020_CL:
91 case AVCOL_SPC_BT2020_NCL:
95 if (
Frame->m_width < 1280)
100 static constexpr std::array<EGLint,4> kPlaneFd
103 static constexpr std::array<EGLint,4> kPlaneOffset
106 static constexpr std::array<EGLint,4> kPlanePitch
109 static constexpr std::array<EGLint,4> kPlaneModlo
112 static constexpr std::array<EGLint,4> kPlaneModhi
116 AVDRMLayerDescriptor* layer = &Desc->layers[0];
118 QVector<EGLint> attribs = {
120 EGL_WIDTH,
Frame->m_width,
121 EGL_HEIGHT, frameheight,
128 for (
int plane = 0; plane < layer->nb_planes; ++plane)
130 AVDRMPlaneDescriptor* drmplane = &layer->planes[plane];
131 ptrdiff_t pitch = drmplane->pitch;
132 ptrdiff_t offset = drmplane->offset;
139 attribs << kPlaneFd[plane] << Desc->objects[drmplane->object_index].fd
140 << kPlaneOffset[plane] <<
static_cast<EGLint
>(offset)
141 << kPlanePitch[plane] <<
static_cast<EGLint
>(pitch);
142 if (
m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 ))
144 attribs << kPlaneModlo[plane]
145 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
146 << kPlaneModhi[plane]
147 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier >> 32);
165 Context->glBindTexture(texture->
m_target, 0);
166 texture->
m_data =
static_cast<unsigned char *
>(image);
167 result.push_back(texture);
182 std::vector<QSize> sizes;
183 for (
int plane = 0 ; plane < Desc->nb_layers; ++plane)
185 int width =
Frame->m_width >> ((plane > 0) ? 1 : 0);
186 int height =
Frame->m_height >> ((plane > 0) ? 1 : 0);
187 sizes.emplace_back(QSize(width, height));
191 std::vector<MythVideoTextureOpenGL*> result =
193 QOpenGLTexture::Target2D);
197 for (
uint plane = 0; plane < result.size(); ++plane)
199 result[plane]->m_allowGLSLDeint =
true;
200 AVDRMLayerDescriptor* layer = &Desc->layers[plane];
201 AVDRMPlaneDescriptor* drmplane = &layer->planes[0];
202 QVector<EGLint> attribs = {
204 EGL_WIDTH, result[plane]->m_size.width(),
205 EGL_HEIGHT, result[plane]->m_size.height(),
211 if (
m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 ))
214 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
216 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier >> 32);
225 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"No EGLImage for plane %1 %2")
231 Context->glBindTexture(result[plane]->m_target, result[plane]->m_textureId);
233 Context->glBindTexture(result[plane]->m_target, 0);
234 result[plane]->m_data =
static_cast<unsigned char *
>(image);
240 #ifndef DRM_FORMAT_R8
241 #define MKTAG2(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | (static_cast<unsigned>(d) << 24))
242 #define DRM_FORMAT_R8 MKTAG2('R', '8', ' ', ' ')
243 #define DRM_FORMAT_GR88 MKTAG2('G', 'R', '8', '8')
244 #define DRM_FORMAT_R16 MKTAG2('R', '1', '6', ' ')
245 #define DRM_FORMAT_GR32 MKTAG2('G', 'R', '3', '2')
246 #define DRM_FORMAT_NV12 MKTAG2('N', 'V', '1', '2')
247 #define DRM_FORMAT_NV21 MKTAG2('N', 'V', '2', '1')
248 #define DRM_FORMAT_YUV420 MKTAG2('Y', 'U', '1', '2')
249 #define DRM_FORMAT_YVU420 MKTAG2('Y', 'V', '1', '2')
250 #define DRM_FORMAT_P010 MKTAG2('P', '0', '1', '0')
272 AVDRMLayerDescriptor* layer = &Desc->layers[0];
273 std::vector<QSize> sizes;
274 for (
int plane = 0 ; plane < layer->nb_planes; ++plane)
276 int width =
Frame->m_width >> ((plane > 0) ? 1 : 0);
277 int height =
Frame->m_height >> ((plane > 0) ? 1 : 0);
278 sizes.emplace_back(QSize(width, height));
298 std::vector<MythVideoTextureOpenGL*> result =
300 QOpenGLTexture::Target2D);
304 for (
uint plane = 0; plane < result.size(); ++plane)
306 result[plane]->m_allowGLSLDeint =
true;
307 EGLint fourcc = fourcc1;
310 AVDRMPlaneDescriptor* drmplane = &layer->planes[plane];
311 QVector<EGLint> attribs = {
313 EGL_WIDTH, result[plane]->m_size.width(),
314 EGL_HEIGHT, result[plane]->m_size.height(),
320 if (
m_useModifiers && (Desc->objects[drmplane->object_index].format_modifier != 0 ))
323 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier & 0xffffffff)
325 <<
static_cast<EGLint
>(Desc->objects[drmplane->object_index].format_modifier >> 32);
334 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"No EGLImage for plane %1 %2")
340 Context->glBindTexture(result[plane]->m_target, result[plane]->m_textureId);
342 Context->glBindTexture(result[plane]->m_target, 0);
343 result[plane]->m_data =
static_cast<unsigned char *
>(image);
350 std::vector<MythVideoTextureOpenGL *> &Textures)
352 for (
auto & texture : Textures)
356 texture->m_data =
nullptr;
357 if (texture->m_textureId)
358 Context->glDeleteTextures(1, &texture->m_textureId);
370 std::vector<MythVideoTextureOpenGL*> result;
371 if (!Desc || !Context || !
Frame)
377 uint numlayers =
static_cast<uint>(Desc->nb_layers);