9 #include "libavutil/hwcontext_drm.h"
15 #define LOC QString("VAAPIDRM: ")
23 device =
"/dev/dri/renderD128";
30 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create DRM VADisplay");
36 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to open %1").arg(device));
45 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 for interop")
46 .arg(
m_usePrime ?
"DRM PRIME" :
"VAAPI handle"));
51 #ifdef USING_DRM_VIDEO
72 std::vector<MythVideoTextureOpenGL*> textures = it.value();
73 for (
auto & texture : textures)
78 texture->m_data =
nullptr;
83 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Deleted %1 EGL images in %2 groups")
94 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting deinterlacer frame cache");
104 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting progressive frame cache");
114 av_buffer_unref(&ref);
125 (
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[0]->data)) ==
126 static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
Buffer->data))))
137 av_buffer_unref(&ref);
143 std::vector<MythVideoTextureOpenGL*> result;
148 auto next =
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[0]->data));
150 auto last =
static_cast<VASurfaceID
>(
reinterpret_cast<uintptr_t
>(
m_referenceFrames[size > 2 ? 2 : 0]->data));
155 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Reference frame error");
165 std::vector<MythVideoTextureOpenGL*>
171 std::vector<MythVideoTextureOpenGL*> result;
188 bool needreferenceframes =
false;
197 bool glsldeint =
false;
206 if (shader && !driver)
212 else if (!shader && !driver)
218 if (shader && !driver)
243 if (needreferenceframes)
255 #ifdef USING_DRM_VIDEO
256 if (!m_drmTriedAndFailed)
257 if (HandleDRMVideo(ColourSpace,
id,
Frame))
264 if (needreferenceframes)
272 if (needreferenceframes)
277 #ifndef DRM_FORMAT_R8
278 #define MKTAG2(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | (static_cast<unsigned>(d) << 24))
279 #define DRM_FORMAT_R8 MKTAG2('R', '8', ' ', ' ')
280 #define DRM_FORMAT_GR88 MKTAG2('G', 'R', '8', '8')
281 #define DRM_FORMAT_R16 MKTAG2('R', '1', '6', ' ')
282 #define DRM_FORMAT_GR1616 MKTAG2('G', 'R', '3', '2')
285 std::vector<MythVideoTextureOpenGL*>
290 std::vector<MythVideoTextureOpenGL*> result;
293 memset(&vaimage, 0,
sizeof(vaimage));
294 vaimage.buf = vaimage.image_id = VA_INVALID_ID;
296 va_status = vaDeriveImage(
m_vaDisplay, Id, &vaimage);
298 uint numplanes = vaimage.num_planes;
300 VABufferInfo vabufferinfo;
301 memset(&vabufferinfo, 0,
sizeof(vabufferinfo));
302 vabufferinfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
303 va_status = vaAcquireBufferHandle(
m_vaDisplay, vaimage.buf, &vabufferinfo);
309 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unsupported VA fourcc: %1")
310 .arg(
fourcc_str(
static_cast<int32_t
>(vaimage.format.fourcc))));
316 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Inconsistent plane count %1 != %2")
321 AVDRMFrameDescriptor drmdesc;
322 memset(&drmdesc, 0,
sizeof(drmdesc));
323 drmdesc.nb_objects = 1;
324 drmdesc.nb_layers =
static_cast<int>(numplanes);
325 drmdesc.objects[0].fd =
static_cast<int>(vabufferinfo.handle);
326 drmdesc.objects[0].size = 0;
327 drmdesc.objects[0].format_modifier = 0;
329 for (
uint i = 0; i < numplanes; ++i)
334 drmdesc.layers[i].nb_planes = 1;
335 drmdesc.layers[i].format = fourcc;
336 drmdesc.layers[i].planes[0].object_index = 0;
337 drmdesc.layers[i].planes[0].pitch = vaimage.pitches[i];
338 drmdesc.layers[i].planes[0].offset = vaimage.offsets[i];
345 va_status = vaReleaseBufferHandle(
m_vaDisplay, vaimage.buf);
347 va_status = vaDestroyImage(
m_vaDisplay, vaimage.image_id);
359 case VA_FOURCC_NV12:
return FMT_NV12;
361 case VA_FOURCC_UYVY:
return FMT_YUY2;
362 #if defined (VA_FOURCC_P010)
363 case VA_FOURCC_P010:
return FMT_P010;
365 #if defined (VA_FOURCC_P016)
366 case VA_FOURCC_P016:
return FMT_P016;
379 #if VA_CHECK_VERSION(1, 1, 0)
380 static inline void VADRMtoPRIME(VADRMPRIMESurfaceDescriptor* VaDRM, AVDRMFrameDescriptor* Prime)
382 Prime->nb_objects =
static_cast<int>(VaDRM->num_objects);
383 for (
uint i = 0; i < VaDRM->num_objects; i++)
385 Prime->objects[i].fd = VaDRM->objects[i].fd;
386 Prime->objects[i].size = VaDRM->objects[i].size;
387 Prime->objects[i].format_modifier = VaDRM->objects[i].drm_format_modifier;
389 Prime->nb_layers =
static_cast<int>(VaDRM->num_layers);
390 for (
uint i = 0; i < VaDRM->num_layers; i++)
392 Prime->layers[i].format = VaDRM->layers[i].drm_format;
393 Prime->layers[i].nb_planes =
static_cast<int>(VaDRM->layers[i].num_planes);
394 for (
uint j = 0; j < VaDRM->layers[i].num_planes; j++)
396 Prime->layers[i].planes[j].object_index =
static_cast<int>(VaDRM->layers[i].object_index[j]);
397 Prime->layers[i].planes[j].offset = VaDRM->layers[i].offset[j];
398 Prime->layers[i].planes[j].pitch = VaDRM->layers[i].pitch[j];
409 std::vector<MythVideoTextureOpenGL*>
414 std::vector<MythVideoTextureOpenGL*> result;
416 #if VA_CHECK_VERSION(1, 1, 0)
428 #if VA_CHECK_VERSION(1, 1, 0)
430 uint32_t exportflags = VA_EXPORT_SURFACE_SEPARATE_LAYERS | VA_EXPORT_SURFACE_READ_ONLY;
431 VADRMPRIMESurfaceDescriptor vadesc;
433 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
434 exportflags, &vadesc);
437 auto * drmdesc =
reinterpret_cast<AVDRMFrameDescriptor*
>(av_mallocz(
sizeof(AVDRMFrameDescriptor)));
438 VADRMtoPRIME(&vadesc, drmdesc);
450 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Releasing %1 DRM descriptors").arg(
m_drmFrames.size()));
453 for (
int i = 0; i < frame->nb_objects; i++)
454 close(frame->objects[i].fd);
455 av_freep(
reinterpret_cast<void*
>(&frame));
462 #if VA_CHECK_VERSION(1, 1, 0)
463 static bool s_supported =
false;
464 static bool s_checked =
false;
472 VASurfaceID surface = 0;
474 VASurfaceAttrib attribs = {};
475 attribs.flags = VA_SURFACE_ATTRIB_SETTABLE;
476 attribs.type = VASurfaceAttribPixelFormat;
477 attribs.value.type = VAGenericValueTypeInteger;
478 attribs.value.value.i = VA_FOURCC_NV12;
480 if (vaCreateSurfaces(
m_vaDisplay, VA_RT_FORMAT_YUV420, 1920, 1080,
481 &surface, 1, &attribs, 1) == VA_STATUS_SUCCESS)
483 VADRMPRIMESurfaceDescriptor vadesc;
484 VAStatus status = vaExportSurfaceHandle(
m_vaDisplay, surface, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
485 VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
487 if (status == VA_STATUS_SUCCESS)
491 AVDRMFrameDescriptor drmdesc;
492 memset(&drmdesc, 0,
sizeof(drmdesc));
493 VADRMtoPRIME(&vadesc, &drmdesc);
494 std::vector<MythVideoTextureOpenGL*> textures =
497 if (!textures.empty())
500 for (
auto & texture : textures)
501 s_supported &= texture->m_data && (texture->m_textureId != 0U);
504 for (uint32_t i = 0; i < vadesc.num_objects; ++i)
505 close(vadesc.objects[i].fd);
509 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"VAAPI DRM PRIME interop is %1supported")
510 .arg(s_supported ?
"" :
"not "));
517 #ifdef USING_DRM_VIDEO
528 if (m_drm->IsValid())
537 if (!m_drm->IsValid())
539 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Disabling DRM video");
540 m_drmTriedAndFailed =
true;