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(AVFrame &hwFrame, QRhi &rhi, ConverterTypeHandler &&handler)
40 if (!TextureConverter::hwTextureConversionEnabled())
43 switch (AVPixelFormat(hwFrame.format)) {
45 case AV_PIX_FMT_VAAPI:
46 handler(ConverterTypeIdentity<VAAPITextureConverter>{});
50 case AV_PIX_FMT_VIDEOTOOLBOX:
51 handler(ConverterTypeIdentity<VideoToolBoxTextureConverter>{});
55 case AV_PIX_FMT_D3D11:
56 if (D3D11TextureConverter::isSupported(hwFrame, rhi))
57 handler(ConverterTypeIdentity<D3D11TextureConverter>{});
61 case AV_PIX_FMT_MEDIACODEC:
62 handler(ConverterTypeIdentity<MediaCodecTextureConverter>{});
74TextureConverterBackend::~TextureConverterBackend() =
default;
76TextureConverter::TextureConverter(QRhi &rhi) : m_rhi(rhi) { }
78bool TextureConverter::init(AVFrame &hwFrame)
80 Q_ASSERT(hwFrame.hw_frames_ctx);
81 if (AVPixelFormat(hwFrame.format) != m_format)
82 updateBackend(hwFrame);
86QVideoFrameTexturesUPtr TextureConverter::createTextures(AVFrame &hwFrame,
87 QVideoFrameTexturesUPtr &oldTextures)
92 Q_ASSERT(hwFrame.format == m_format);
93 return m_backend->createTextures(&hwFrame, oldTextures);
96QVideoFrameTexturesHandlesUPtr
97TextureConverter::createTextureHandles(AVFrame &hwFrame, QVideoFrameTexturesHandlesUPtr oldHandles)
102 Q_ASSERT(hwFrame.format == m_format);
103 return m_backend->createTextureHandles(&hwFrame, std::move(oldHandles));
106void TextureConverter::updateBackend(AVFrame &hwFrame)
109 m_format = AVPixelFormat(hwFrame.format);
111 applyConverterTypeByPixelFormat(hwFrame, m_rhi, [
this](
auto converterTypeIdentity) {
112 using ConverterType =
typename decltype(converterTypeIdentity)::type;
113 m_backend = ConverterType::create(&m_rhi);
117bool TextureConverter::hwTextureConversionEnabled()
121 static const int disableHwConversion =
122 qEnvironmentVariableIntValue(
"QT_DISABLE_HW_TEXTURES_CONVERSION");
124 return !disableHwConversion;
127void TextureConverter::applyDecoderPreset(
const AVPixelFormat format, AVCodecContext &codecContext)
129 if (!hwTextureConversionEnabled())
132 Q_ASSERT(codecContext.codec && Codec(codecContext.codec).isDecoder());
135 if (format == AV_PIX_FMT_D3D11)
136 D3D11TextureConverter::SetupDecoderTextures(&codecContext);
137#elif defined Q_OS_ANDROID
138 if (format == AV_PIX_FMT_MEDIACODEC)
139 MediaCodecTextureConverter::setupDecoderSurface(&codecContext);
141 Q_UNUSED(codecContext);
146bool TextureConverter::isBackendAvailable(AVFrame &hwFrame, QRhi &rhi)
149 applyConverterTypeByPixelFormat(hwFrame, rhi, [&result](
auto) {
Combined button and popup list for selecting options.