7#error "Configuration error"
14#include "private/qvideotexturehelper_p.h"
19#include <qpa/qplatformnativeinterface.h>
25#if __has_include("drm/drm_fourcc.h")
26#include <drm/drm_fourcc.h>
27#elif __has_include("libdrm/drm_fourcc.h")
28#include <libdrm/drm_fourcc.h>
31#define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
32 ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
34#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4')
35#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')
36#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
37#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
38#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4')
39#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
40#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
41#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
42#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6')
43#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2')
44#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')
45#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')
49#include <libavutil/hwcontext_vaapi.h>
53#include <va/va_drmcommon.h>
56#include <EGL/eglext.h>
70#if G_BYTE_ORDER == G_LITTLE_ENDIAN
108 static constexpr quint32 format[] = { rgba_fourcc, 0, 0, 0 };
168VAAPITextureConverter::VAAPITextureConverter(
QRhi *rhi)
169 : TextureConverterBackend(
nullptr)
171 qCDebug(qLHWAccelVAAPI) <<
">>>> Creating VAAPI HW accelerator";
174 qWarning() <<
"VAAPITextureConverter: No rhi or non openGL based RHI";
182 qCDebug(qLHWAccelVAAPI) <<
" no GL context, disabling";
191 qCDebug(qLHWAccelVAAPI) <<
" no egl display, disabling";
194 eglImageTargetTexture2D = eglGetProcAddress(
"glEGLImageTargetTexture2DOES");
196 qCDebug(qLHWAccelVAAPI) <<
" no eglImageTargetTexture2D, disabling";
204VAAPITextureConverter::~VAAPITextureConverter()
209TextureSet *VAAPITextureConverter::getTextures(AVFrame *
frame)
212 if (
frame->format != AV_PIX_FMT_VAAPI || !eglDisplay) {
213 qCDebug(qLHWAccelVAAPI) <<
"format/egl error" <<
frame->format << eglDisplay;
217 if (!
frame->hw_frames_ctx)
220 auto *fCtx = (AVHWFramesContext *)
frame->hw_frames_ctx->data;
221 auto *
ctx = fCtx->device_ctx;
225 auto *vaCtx = (AVVAAPIDeviceContext *)
ctx->hwctx;
226 auto vaDisplay = vaCtx->display;
228 qCDebug(qLHWAccelVAAPI) <<
" no VADisplay, disabling";
232 VASurfaceID vaSurface = (uintptr_t)
frame->data[3];
234 VADRMPRIMESurfaceDescriptor prime;
235 if (vaExportSurfaceHandle(vaDisplay, vaSurface,
236 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
237 VA_EXPORT_SURFACE_READ_ONLY |
238#ifdef VA_EXPORT_USE_LAYERS
239 VA_EXPORT_SURFACE_SEPARATE_LAYERS,
241 VA_EXPORT_SURFACE_COMPOSED_LAYERS,
243 &prime) != VA_STATUS_SUCCESS)
245 qWarning() <<
"vaExportSurfaceHandle failed";
249 vaSyncSurface(vaDisplay, vaSurface);
257 bool needsConversion;
260 if (!drm_formats || needsConversion) {
261 qWarning() <<
"can't use DMA transfer for pixel format" <<
fmt << qtFormat;
267 for (; nPlanes < 5; ++nPlanes) {
268 if (drm_formats[nPlanes] == 0)
272 nPlanes =
desc->nplanes;
278 GLuint glTextures[4] = {};
279 functions.glGenTextures(nPlanes, glTextures);
280 for (
int i = 0;
i < nPlanes; ++
i) {
281#ifdef VA_EXPORT_USE_LAYERS
284 if (prime.layers[
i].drm_format != drm_formats[
i]) {
285 qWarning() <<
"expected DRM format check failed expected"
286 <<
Qt::hex << drm_formats[
i] <<
"got" << prime.layers[
i].drm_format;
294 EGL_LINUX_DRM_FOURCC_EXT, (EGLint)drm_formats[
i],
297 EGL_DMA_BUF_PLANE0_FD_EXT, prime.objects[prime.layers[
LAYER].object_index[
PLANE]].fd,
298 EGL_DMA_BUF_PLANE0_OFFSET_EXT, (EGLint)prime.layers[
LAYER].offset[
PLANE],
299 EGL_DMA_BUF_PLANE0_PITCH_EXT, (EGLint)prime.layers[
LAYER].pitch[
PLANE],
302 images[
i] = eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
nullptr, img_attr);
304 qWarning() <<
"eglCreateImage failed for plane" <<
i <<
Qt::hex << eglGetError();
308 functions.glBindTexture(GL_TEXTURE_2D, glTextures[
i]);
310 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2D = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)this->eglImageTargetTexture2D;
311 eglImageTargetTexture2D(GL_TEXTURE_2D,
images[
i]);
313 qWarning() <<
"eglImageTargetTexture2D failed";
317 for (
int i = 0;
i < (int)prime.num_objects; ++
i)
318 close(prime.objects[
i].fd);
320 for (
int i = 0;
i < nPlanes; ++
i) {
322 functions.glBindTexture(GL_TEXTURE_2D, 0);
323 eglDestroyImage(eglDisplay,
images[
i]);
326 VAAPITextureSet *textureSet =
new VAAPITextureSet;
327 textureSet->nPlanes = nPlanes;
328 textureSet->rhi = rhi;
329 textureSet->glContext = glContext;
331 for (
int i = 0;
i < 4; ++
i)
332 textureSet->textures[
i] = glTextures[
i];
static QVideoFrameFormat::PixelFormat toQtPixelFormat(AVPixelFormat avPixelFormat, bool *needsConversion=nullptr)
static AVPixelFormat format(AVFrame *frame)
qint64 textureHandle(int plane) override
QOpenGLContext * glContext
static QPlatformNativeInterface * platformNativeInterface()
QString platformName
The name of the underlying platform plugin.
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
void glDeleteTextures(GLsizei n, const GLuint *textures)
Convenience function that calls glDeleteTextures(n, textures).
\variable QRhiGles2InitParams::format
bool makeThreadLocalNativeContextCurrent()
With OpenGL this makes the OpenGL context current on the current thread.
Implementation backend() const
const QRhiNativeHandles * nativeHandles()
\macro QT_RESTRICTED_CAST_FROM_ASCII
static const quint32 * fourccFromPixelFormat(const QVideoFrameFormat::PixelFormat format)
Combined button and popup list for selecting options.
const TextureDescription * textureDescription(QVideoFrameFormat::PixelFormat format)
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
#define DRM_FORMAT_ABGR8888
#define DRM_FORMAT_GR1616
#define DRM_FORMAT_RGBA8888
#define DRM_FORMAT_RG1616
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint const GLuint GLuint const GLuint * textures
GLint GLsizei GLsizei GLenum format
QVideoFrameFormat::PixelFormat fmt
QList< QImage > images
[6]