diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-11-16 20:56:11 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2022-01-19 14:16:30 +0100 |
commit | cbf377366ccb3b30c1b0dd945c3aec0700c5d271 (patch) | |
tree | 0559eaa35ad12904af72e696d99d2e02df365b71 /src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp | |
parent | 4863b1bcb9fa695dad329cc2503fe1577998c1a1 (diff) |
FFmpeg: Zero copy support on macOS
Implement zero copy rendering for macOS. This brings down CPU load
to ~30% for rendering our 4K HDR test video.
Change-Id: I8953a1b55fb49ad52bde94c3dfc681f8b1a22dc4
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp')
-rw-r--r-- | src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp index b5fa5324c..5ab8373b8 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpeghwaccel_vaapi.cpp @@ -180,6 +180,21 @@ static const quint32 *fourccFromPixelFormat(const QVideoFrameFormat::PixelFormat } } +class VAAPITextureSet : public TextureSet +{ +public: + ~VAAPITextureSet(); + qint64 texture(int plane) override { + return textures[plane]; + } + + QRhi *rhi = nullptr; + QOpenGLContext *glContext = nullptr; + int nPlanes = 0; + GLuint textures[4] = {}; +}; + + VAAPIAccel::VAAPIAccel(AVBufferRef *hwContext) : HWAccelBackend(hwContext) { @@ -230,14 +245,13 @@ void VAAPIAccel::setRhi(QRhi *rhi) } //#define VA_EXPORT_USE_LAYERS -bool VAAPIAccel::getTextures(AVFrame *frame, qint64 *textures) +TextureSet *VAAPIAccel::getTextures(AVFrame *frame) { // qDebug() << "VAAPIAccel::getTextures"; if (frame->format != AV_PIX_FMT_VAAPI || !eglDisplay) { qDebug() << "format/egl error" << frame->format << eglDisplay; - return false; + return nullptr; } - Q_UNUSED(textures); VASurfaceID vaSurface = (uintptr_t)frame->data[3]; @@ -253,7 +267,7 @@ bool VAAPIAccel::getTextures(AVFrame *frame, qint64 *textures) &prime) != VA_STATUS_SUCCESS) { qWarning() << "vaExportSurfaceHandle failed"; - return false; + return nullptr; } // ### Check that prime.fourcc is what we expect vaSyncSurface(vaDisplay, vaSurface); @@ -269,7 +283,7 @@ bool VAAPIAccel::getTextures(AVFrame *frame, qint64 *textures) auto *drm_formats = fourccFromPixelFormat(qtFormat); if (!drm_formats || needsConversion) { qWarning() << "can't use DMA transfer for pixel format" << fmt << qtFormat; - return false; + return nullptr; } auto *desc = QVideoTextureHelper::textureDescription(qtFormat); @@ -312,7 +326,7 @@ bool VAAPIAccel::getTextures(AVFrame *frame, qint64 *textures) 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 false; + return nullptr; } functions.glActiveTexture(GL_TEXTURE0 + i); functions.glBindTexture(GL_TEXTURE_2D, glTextures[i]); @@ -333,30 +347,25 @@ bool VAAPIAccel::getTextures(AVFrame *frame, qint64 *textures) eglDestroyImage(eglDisplay, images[i]); } + VAAPITextureSet *textureSet = new VAAPITextureSet; + textureSet->nPlanes = nPlanes; + textureSet->rhi = rhi; + textureSet->glContext = glContext; for (int i = 0; i < 4; ++i) - textures[i] = glTextures[i]; + textureSet->textures[i] = glTextures[i]; // qDebug() << "VAAPIAccel: got textures" << textures[0] << textures[1] << textures[2] << textures[3]; - return true; + return textureSet; } -void VAAPIAccel::freeTextures(qint64 *textures) +VAAPITextureSet::~VAAPITextureSet() { if (rhi) { rhi->makeThreadLocalNativeContextCurrent(); - int nPlanes = 0; - GLuint glTextures[4] = {}; - for (; nPlanes < 4; ++nPlanes) { - glTextures[nPlanes] = textures[nPlanes]; - if (textures[nPlanes] == 0) - break; - } - QOpenGLFunctions functions(glContext); - functions.glDeleteTextures(nPlanes, glTextures); + functions.glDeleteTextures(nPlanes, textures); } - } AVPixelFormat VAAPIAccel::format(AVFrame *frame) const |