11 #include "libavutil/hwcontext_drm.h"
17 #define LOC QString("VAAPIDRM: ")
25 device =
"/dev/dri/renderD128";
32 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create DRM VADisplay");
38 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to open %1").arg(device));
47 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 for interop")
48 .arg(
m_usePrime ?
"DRM PRIME" :
"VAAPI handle"));
53 #ifdef USING_DRM_VIDEO
74 std::vector<MythVideoTextureOpenGL*> textures = it.value();
75 for (
auto & texture : textures)
80 texture->m_data =
nullptr;
85 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Deleted %1 EGL images in %2 groups")
96 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting deinterlacer frame cache");
106 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting progressive frame cache");
116 av_buffer_unref(&ref);
127 (
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[0]->data)) ==
128 static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
Buffer->data))))
139 av_buffer_unref(&ref);
145 std::vector<MythVideoTextureOpenGL*> result;
150 auto next =
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[0]->data));
152 auto last =
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[size > 2 ? 2 : 0]->data));
157 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Reference frame error");
167 std::vector<MythVideoTextureOpenGL*>
173 std::vector<MythVideoTextureOpenGL*> result;
190 bool needreferenceframes =
false;
199 bool glsldeint =
false;
208 if (shader && !driver)
214 else if (!shader && !driver)
220 if (shader && !driver)
245 if (needreferenceframes)
257 #ifdef USING_DRM_VIDEO
258 if (!m_drmTriedAndFailed)
259 if (HandleDRMVideo(ColourSpace,
id,
Frame))
266 if (needreferenceframes)
274 if (needreferenceframes)
279 #ifndef DRM_FORMAT_R8
280 #define MKTAG2(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | (static_cast<unsigned>(d) << 24))
281 #define DRM_FORMAT_R8 MKTAG2('R', '8', ' ', ' ')
282 #define DRM_FORMAT_GR88 MKTAG2('G', 'R', '8', '8')
283 #define DRM_FORMAT_R16 MKTAG2('R', '1', '6', ' ')
284 #define DRM_FORMAT_GR1616 MKTAG2('G', 'R', '3', '2')
287 std::vector<MythVideoTextureOpenGL*>
292 std::vector<MythVideoTextureOpenGL*> result;
295 memset(&vaimage, 0,
sizeof(vaimage));
296 vaimage.buf = vaimage.image_id = VA_INVALID_ID;
298 va_status = vaDeriveImage(
m_vaDisplay, Id, &vaimage);
300 uint numplanes = vaimage.num_planes;
302 VABufferInfo vabufferinfo;
303 memset(&vabufferinfo, 0,
sizeof(vabufferinfo));
304 vabufferinfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
305 va_status = vaAcquireBufferHandle(
m_vaDisplay, vaimage.buf, &vabufferinfo);
311 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unsupported VA fourcc: %1")
312 .arg(
fourcc_str(
static_cast<int32_t
>(vaimage.format.fourcc))));
318 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Inconsistent plane count %1 != %2")
323 AVDRMFrameDescriptor drmdesc;
324 memset(&drmdesc, 0,
sizeof(drmdesc));
325 drmdesc.nb_objects = 1;
326 drmdesc.nb_layers =
static_cast<int>(numplanes);
327 drmdesc.objects[0].fd =
static_cast<int>(vabufferinfo.handle);
328 drmdesc.objects[0].size = 0;
329 drmdesc.objects[0].format_modifier = 0;
331 for (
uint i = 0; i < numplanes; ++i)
336 drmdesc.layers[i].nb_planes = 1;
337 drmdesc.layers[i].format = fourcc;
338 drmdesc.layers[i].planes[0].object_index = 0;
339 drmdesc.layers[i].planes[0].pitch = vaimage.pitches[i];
340 drmdesc.layers[i].planes[0].offset = vaimage.offsets[i];
347 va_status = vaReleaseBufferHandle(
m_vaDisplay, vaimage.buf);
349 va_status = vaDestroyImage(
m_vaDisplay, vaimage.image_id);
361 case VA_FOURCC_NV12:
return FMT_NV12;
363 case VA_FOURCC_UYVY:
return FMT_YUY2;
364 #if defined (VA_FOURCC_P010)
365 case VA_FOURCC_P010:
return FMT_P010;
367 #if defined (VA_FOURCC_P016)
368 case VA_FOURCC_P016:
return FMT_P016;
381 #if VA_CHECK_VERSION(1, 1, 0)
382 static inline void VADRMtoPRIME(VADRMPRIMESurfaceDescriptor* VaDRM, AVDRMFrameDescriptor* Prime)
384 Prime->nb_objects =
static_cast<int>(VaDRM->num_objects);
385 for (
uint i = 0; i < VaDRM->num_objects; i++)
387 Prime->objects[i].fd = VaDRM->objects[i].fd;
388 Prime->objects[i].size = VaDRM->objects[i].size;
389 Prime->objects[i].format_modifier = VaDRM->objects[i].drm_format_modifier;
391 Prime->nb_layers =
static_cast<int>(VaDRM->num_layers);
392 for (
uint i = 0; i < VaDRM->num_layers; i++)
394 Prime->layers[i].format = VaDRM->layers[i].drm_format;
395 Prime->layers[i].nb_planes =
static_cast<int>(VaDRM->layers[i].num_planes);
396 for (
uint j = 0; j < VaDRM->layers[i].num_planes; j++)
398 Prime->layers[i].planes[j].object_index =
static_cast<int>(VaDRM->layers[i].object_index[j]);
399 Prime->layers[i].planes[j].offset = VaDRM->layers[i].offset[j];
400 Prime->layers[i].planes[j].pitch = VaDRM->layers[i].pitch[j];
411 std::vector<MythVideoTextureOpenGL*>
416 std::vector<MythVideoTextureOpenGL*> result;
418 #if VA_CHECK_VERSION(1, 1, 0)
430 #if VA_CHECK_VERSION(1, 1, 0)
432 uint32_t exportflags = VA_EXPORT_SURFACE_SEPARATE_LAYERS | VA_EXPORT_SURFACE_READ_ONLY;
433 VADRMPRIMESurfaceDescriptor vadesc;
435 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
436 exportflags, &vadesc);
439 auto * drmdesc =
reinterpret_cast<AVDRMFrameDescriptor*
>(av_mallocz(
sizeof(AVDRMFrameDescriptor)));
440 VADRMtoPRIME(&vadesc, drmdesc);
452 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Releasing %1 DRM descriptors").arg(
m_drmFrames.size()));
455 for (
int i = 0; i < frame->nb_objects; i++)
456 close(frame->objects[i].fd);
457 av_freep(
reinterpret_cast<void*
>(&frame));
464 #if VA_CHECK_VERSION(1, 1, 0)
465 static bool s_supported =
false;
466 static bool s_checked =
false;
474 VASurfaceID surface = 0;
476 VASurfaceAttrib attribs = {};
477 attribs.flags = VA_SURFACE_ATTRIB_SETTABLE;
478 attribs.type = VASurfaceAttribPixelFormat;
479 attribs.value.type = VAGenericValueTypeInteger;
480 attribs.value.value.i = VA_FOURCC_NV12;
482 if (vaCreateSurfaces(
m_vaDisplay, VA_RT_FORMAT_YUV420, 1920, 1080,
483 &surface, 1, &attribs, 1) == VA_STATUS_SUCCESS)
485 VADRMPRIMESurfaceDescriptor vadesc;
486 VAStatus status = vaExportSurfaceHandle(
m_vaDisplay, surface, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
487 VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
489 if (status == VA_STATUS_SUCCESS)
493 AVDRMFrameDescriptor drmdesc;
494 memset(&drmdesc, 0,
sizeof(drmdesc));
495 VADRMtoPRIME(&vadesc, &drmdesc);
496 std::vector<MythVideoTextureOpenGL*> textures =
499 if (!textures.empty())
502 for (
auto & texture : textures)
503 s_supported &= texture->m_data && (texture->m_textureId != 0U);
506 for (uint32_t i = 0; i < vadesc.num_objects; ++i)
507 close(vadesc.objects[i].fd);
511 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VAAPI DRM PRIME interop is %1supported")
512 .arg(s_supported ?
"" :
"not "));
519 #ifdef USING_DRM_VIDEO
530 if (m_drm->IsValid())
539 if (!m_drm->IsValid())
541 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling DRM video");
542 m_drmTriedAndFailed =
true;