diff options
Diffstat (limited to 'src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp')
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp | 110 |
1 files changed, 46 insertions, 64 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp index 09e06c64a..7e46e3537 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qffmpeghwaccel_vaapi_p.h" @@ -49,8 +13,7 @@ #include "qffmpegvideobuffer_p.h" #include "private/qvideotexturehelper_p.h" -#include <private/qrhi_p.h> -#include <private/qrhigles2_p.h> +#include <rhi/qrhi.h> #include <qguiapplication.h> #include <qpa/qplatformnativeinterface.h> @@ -94,7 +57,11 @@ extern "C" { #include <unistd.h> -#include <qdebug.h> +#include <qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +static Q_LOGGING_CATEGORY(qLHWAccelVAAPI, "qt.multimedia.ffmpeg.hwaccelvaapi"); namespace QFFmpeg { @@ -110,7 +77,7 @@ static const quint32 *fourccFromPixelFormat(const QVideoFrameFormat::PixelFormat const quint32 rg16_fourcc = DRM_FORMAT_RG1616; #endif -// qDebug() << "Getting DRM fourcc for pixel format" << format; +// qCDebug(qLHWAccelVAAPI) << "Getting DRM fourcc for pixel format" << format; switch (format) { case QVideoFrameFormat::Format_Invalid: @@ -187,7 +154,7 @@ class VAAPITextureSet : public TextureSet { public: ~VAAPITextureSet(); - qint64 textureHandle(int plane) override { + qint64 textureHandle(QRhi *, int plane) override { return textures[plane]; } @@ -201,7 +168,7 @@ public: VAAPITextureConverter::VAAPITextureConverter(QRhi *rhi) : TextureConverterBackend(nullptr) { - qDebug() << ">>>> Creating VAAPI HW accelerator"; + qCDebug(qLHWAccelVAAPI) << ">>>> Creating VAAPI HW accelerator"; if (!rhi || rhi->backend() != QRhi::OpenGLES2) { qWarning() << "VAAPITextureConverter: No rhi or non openGL based RHI"; @@ -212,21 +179,21 @@ VAAPITextureConverter::VAAPITextureConverter(QRhi *rhi) auto *nativeHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles()); glContext = nativeHandles->context; if (!glContext) { - qDebug() << " no GL context, disabling"; + qCDebug(qLHWAccelVAAPI) << " no GL context, disabling"; return; } const QString platform = QGuiApplication::platformName(); QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface(); - eglDisplay = pni->nativeResourceForIntegration("egldisplay"); - qDebug() << " platform is" << platform << eglDisplay; + eglDisplay = pni->nativeResourceForIntegration(QByteArrayLiteral("egldisplay")); + qCDebug(qLHWAccelVAAPI) << " platform is" << platform << eglDisplay; if (!eglDisplay) { - qDebug() << " no egl display, disabling"; + qCDebug(qLHWAccelVAAPI) << " no egl display, disabling"; return; } eglImageTargetTexture2D = eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (!eglDisplay) { - qDebug() << " no eglImageTargetTexture2D, disabling"; + qCDebug(qLHWAccelVAAPI) << " no eglImageTargetTexture2D, disabling"; return; } @@ -241,9 +208,9 @@ VAAPITextureConverter::~VAAPITextureConverter() //#define VA_EXPORT_USE_LAYERS TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) { -// qDebug() << "VAAPIAccel::getTextures"; +// qCDebug(qLHWAccelVAAPI) << "VAAPIAccel::getTextures"; if (frame->format != AV_PIX_FMT_VAAPI || !eglDisplay) { - qDebug() << "format/egl error" << frame->format << eglDisplay; + qCDebug(qLHWAccelVAAPI) << "format/egl error" << frame->format << eglDisplay; return nullptr; } @@ -258,13 +225,13 @@ TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) auto *vaCtx = (AVVAAPIDeviceContext *)ctx->hwctx; auto vaDisplay = vaCtx->display; if (!vaDisplay) { - qDebug() << " no VADisplay, disabling"; + qCDebug(qLHWAccelVAAPI) << " no VADisplay, disabling"; return nullptr; } VASurfaceID vaSurface = (uintptr_t)frame->data[3]; - VADRMPRIMESurfaceDescriptor prime; + VADRMPRIMESurfaceDescriptor prime = {}; if (vaExportSurfaceHandle(vaDisplay, vaSurface, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_READ_ONLY | @@ -278,10 +245,17 @@ TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) qWarning() << "vaExportSurfaceHandle failed"; return nullptr; } + + // Make sure all fd's in 'prime' are closed when we return from this function + QScopeGuard closeObjectsGuard([&prime]() { + for (uint32_t i = 0; i < prime.num_objects; ++i) + close(prime.objects[i].fd); + }); + // ### Check that prime.fourcc is what we expect vaSyncSurface(vaDisplay, vaSurface); -// qDebug() << "VAAPIAccel: vaSufraceDesc: width/height" << prime.width << prime.height << "num objects" +// qCDebug(qLHWAccelVAAPI) << "VAAPIAccel: vaSufraceDesc: width/height" << prime.width << prime.height << "num objects" // << prime.num_objects << "num layers" << prime.num_layers; QOpenGLFunctions functions(glContext); @@ -303,7 +277,7 @@ TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) } Q_ASSERT(nPlanes == desc->nplanes); nPlanes = desc->nplanes; -// qDebug() << "VAAPIAccel: nPlanes" << nPlanes; +// qCDebug(qLHWAccelVAAPI) << "VAAPIAccel: nPlanes" << nPlanes; rhi->makeThreadLocalNativeContextCurrent(); @@ -334,22 +308,30 @@ TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) }; images[i] = eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, img_attr); if (!images[i]) { - qWarning() << "eglCreateImage failed for plane" << i << Qt::hex << eglGetError(); - return nullptr; + const GLenum error = eglGetError(); + if (error == EGL_BAD_MATCH) { + qWarning() << "eglCreateImage failed for plane" << i << "with error code EGL_BAD_MATCH, " + "disabling hardware acceleration. This could indicate an EGL implementation issue." + "\nVAAPI driver: " << vaQueryVendorString(vaDisplay) + << "\nEGL vendor:" << eglQueryString(eglDisplay, EGL_VENDOR); + this->rhi = nullptr; // Disabling texture conversion here to fix QTBUG-112312 + return nullptr; + } + if (error) { + qWarning() << "eglCreateImage failed for plane" << i << "with error code" << error; + return nullptr; + } } functions.glActiveTexture(GL_TEXTURE0 + i); functions.glBindTexture(GL_TEXTURE_2D, glTextures[i]); PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2D = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)this->eglImageTargetTexture2D; eglImageTargetTexture2D(GL_TEXTURE_2D, images[i]); - if (glGetError()) { - qWarning() << "eglImageTargetTexture2D failed"; - } + GLenum error = glGetError(); + if (error) + qWarning() << "eglImageTargetTexture2D failed with error code" << error; } - for (int i = 0; i < (int)prime.num_objects; ++i) - close(prime.objects[i].fd); - for (int i = 0; i < nPlanes; ++i) { functions.glActiveTexture(GL_TEXTURE0 + i); functions.glBindTexture(GL_TEXTURE_2D, 0); @@ -363,7 +345,7 @@ TextureSet *VAAPITextureConverter::getTextures(AVFrame *frame) for (int i = 0; i < 4; ++i) textureSet->textures[i] = glTextures[i]; -// qDebug() << "VAAPIAccel: got textures" << textures[0] << textures[1] << textures[2] << textures[3]; +// qCDebug(qLHWAccelVAAPI) << "VAAPIAccel: got textures" << textures[0] << textures[1] << textures[2] << textures[3]; return textureSet; } |