4#include <QtFFmpegMediaPluginImpl/private/qffmpegtextureconverter_p.h>
6#include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_p.h>
10#include <q20type_traits.h>
13# include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_vaapi_p.h>
17# include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_videotoolbox_p.h>
21# include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_d3d11_p.h>
25# include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_mediacodec_p.h>
30using namespace QFFmpeg;
34template <
typename Converter>
37template <
typename ConverterTypeHandler>
38void applyConverterTypeByPixelFormat(AVPixelFormat fmt,
const QRhi &rhi,
39 ConverterTypeHandler &&handler)
41 if (!TextureConverter::hwTextureConversionEnabled())
46 case AV_PIX_FMT_VAAPI:
47 handler(ConverterTypeIdentity<VAAPITextureConverter>{});
51 case AV_PIX_FMT_VIDEOTOOLBOX:
52 handler(ConverterTypeIdentity<VideoToolBoxTextureConverter>{});
56 case AV_PIX_FMT_D3D11:
57 if (rhi.backend() == QRhi::Implementation::D3D11) {
58 if (rhi.driverInfo().deviceType != QRhiDriverInfo::CpuDevice)
59 handler(ConverterTypeIdentity<D3D11TextureConverter>{});
64 case AV_PIX_FMT_MEDIACODEC:
65 handler(ConverterTypeIdentity<MediaCodecTextureConverter>{});
77TextureConverterBackend::~TextureConverterBackend() =
default;
79TextureConverter::TextureConverter(QRhi &rhi) : m_rhi(rhi) { }
81bool TextureConverter::init(AVFrame &hwFrame)
83 Q_ASSERT(hwFrame.hw_frames_ctx);
84 AVPixelFormat fmt = AVPixelFormat(hwFrame.format);
90QVideoFrameTexturesUPtr TextureConverter::createTextures(AVFrame &hwFrame,
91 QVideoFrameTexturesUPtr &oldTextures)
96 Q_ASSERT(hwFrame.format == m_format);
97 return m_backend->createTextures(&hwFrame, oldTextures);
100QVideoFrameTexturesHandlesUPtr
101TextureConverter::createTextureHandles(AVFrame &hwFrame, QVideoFrameTexturesHandlesUPtr oldHandles)
106 Q_ASSERT(hwFrame.format == m_format);
107 return m_backend->createTextureHandles(&hwFrame, std::move(oldHandles));
110void TextureConverter::updateBackend(AVPixelFormat fmt)
115 applyConverterTypeByPixelFormat(m_format, m_rhi, [
this](
auto converterTypeIdentity) {
116 using ConverterType =
typename decltype(converterTypeIdentity)::type;
117 m_backend = std::make_shared<ConverterType>(&m_rhi);
121bool TextureConverter::hwTextureConversionEnabled()
125 static const int disableHwConversion =
126 qEnvironmentVariableIntValue(
"QT_DISABLE_HW_TEXTURES_CONVERSION");
128 return !disableHwConversion;
131void TextureConverter::applyDecoderPreset(
const AVPixelFormat format, AVCodecContext &codecContext)
133 if (!hwTextureConversionEnabled())
136 Q_ASSERT(codecContext.codec && Codec(codecContext.codec).isDecoder());
139 if (format == AV_PIX_FMT_D3D11)
140 D3D11TextureConverter::SetupDecoderTextures(&codecContext);
141#elif defined Q_OS_ANDROID
142 if (format == AV_PIX_FMT_MEDIACODEC)
143 MediaCodecTextureConverter::setupDecoderSurface(&codecContext);
145 Q_UNUSED(codecContext);
150bool TextureConverter::isBackendAvailable(AVFrame &hwFrame,
const QRhi &rhi)
153 applyConverterTypeByPixelFormat(AVPixelFormat(hwFrame.format), rhi, [&result](
auto) {