Test all renderers before use

Every renderer except SDL had opted-in for testing due to various
quirks discovered over the years, so just do away with this option
and test all renderers.
This commit is contained in:
Cameron Gutman
2025-12-22 23:58:26 -06:00
parent 526d815930
commit d501a627f0
20 changed files with 15 additions and 107 deletions

View File

@@ -48,11 +48,6 @@ void CUDARenderer::renderFrame(AVFrame*)
SDL_assert(false);
}
bool CUDARenderer::needsTestFrame()
{
return true;
}
bool CUDARenderer::isDirectRenderingSupported()
{
// We only support rendering via SDL read-back

View File

@@ -15,7 +15,6 @@ public:
virtual bool initialize(PDECODER_PARAMETERS) override;
virtual bool prepareDecoderContext(AVCodecContext* context, AVDictionary** options) override;
virtual void renderFrame(AVFrame* frame) override;
virtual bool needsTestFrame() override;
virtual bool isDirectRenderingSupported() override;
virtual int getDecoderCapabilities() override;

View File

@@ -1151,15 +1151,6 @@ int D3D11VARenderer::getDecoderCapabilities()
CAPABILITY_REFERENCE_FRAME_INVALIDATION_AV1;
}
bool D3D11VARenderer::needsTestFrame()
{
// We can usually determine when D3D11VA will work based on which decoder GUIDs are supported,
// however there are some strange cases (Quadro P400 + Radeon HD 5570) where something goes
// horribly wrong and D3D11VideoDevice::CreateVideoDecoder() fails inside FFmpeg. We need to
// catch that case before we commit to using D3D11VA.
return true;
}
IFFmpegRenderer::InitFailureReason D3D11VARenderer::getInitFailureReason()
{
// In the specific case where we found at least one D3D11 hardware device but none of the

View File

@@ -23,7 +23,6 @@ public:
virtual void notifyOverlayUpdated(Overlay::OverlayType) override;
virtual int getRendererAttributes() override;
virtual int getDecoderCapabilities() override;
virtual bool needsTestFrame() override;
virtual InitFailureReason getInitFailureReason() override;
enum PixelShaders {

View File

@@ -1353,11 +1353,6 @@ void DrmRenderer::renderFrame(AVFrame* frame)
drmModeRmFB(m_DrmFd, lastFbId);
}
bool DrmRenderer::needsTestFrame()
{
return true;
}
bool DrmRenderer::testRenderFrame(AVFrame* frame) {
uint32_t fbId;

View File

@@ -59,7 +59,6 @@ public:
virtual enum AVPixelFormat getPreferredPixelFormat(int videoFormat) override;
virtual bool isPixelFormatSupported(int videoFormat, AVPixelFormat pixelFormat) override;
virtual int getRendererAttributes() override;
virtual bool needsTestFrame() override;
virtual bool testRenderFrame(AVFrame* frame) override;
virtual bool isDirectRenderingSupported() override;
virtual int getDecoderColorspace() override;

View File

@@ -48,11 +48,6 @@ void GenericHwAccelRenderer::renderFrame(AVFrame*)
SDL_assert(false);
}
bool GenericHwAccelRenderer::needsTestFrame()
{
return true;
}
bool GenericHwAccelRenderer::isDirectRenderingSupported()
{
// We only support rendering via read-back

View File

@@ -10,7 +10,6 @@ public:
virtual bool initialize(PDECODER_PARAMETERS) override;
virtual bool prepareDecoderContext(AVCodecContext* context, AVDictionary** options) override;
virtual void renderFrame(AVFrame* frame) override;
virtual bool needsTestFrame() override;
virtual bool isDirectRenderingSupported() override;
virtual int getDecoderCapabilities() override;

View File

@@ -340,13 +340,6 @@ int MmalRenderer::getRendererAttributes()
return RENDERER_ATTRIBUTE_1080P_MAX;
}
bool MmalRenderer::needsTestFrame()
{
// We won't be able to decode if the GPU memory is 64 MB or lower,
// so we must test before allowing the decoder to be used.
return true;
}
void MmalRenderer::renderFrame(AVFrame* frame)
{
MMAL_BUFFER_HEADER_T* buffer = (MMAL_BUFFER_HEADER_T*)frame->data[3];

View File

@@ -16,7 +16,6 @@ public:
virtual void prepareToRender() override;
virtual void renderFrame(AVFrame* frame) override;
virtual enum AVPixelFormat getPreferredPixelFormat(int videoFormat) override;
virtual bool needsTestFrame() override;
virtual int getRendererAttributes() override;
virtual int getDecoderColorspace() override;

View File

@@ -1021,12 +1021,6 @@ int PlVkRenderer::getDecoderCapabilities()
CAPABILITY_REFERENCE_FRAME_INVALIDATION_AV1;
}
bool PlVkRenderer::needsTestFrame()
{
// We need a test frame to verify that Vulkan video decoding is working
return true;
}
bool PlVkRenderer::isPixelFormatSupported(int videoFormat, AVPixelFormat pixelFormat)
{
if (m_HwAccelBackend) {

View File

@@ -26,7 +26,6 @@ public:
virtual int getDecoderColorspace() override;
virtual int getDecoderColorRange() override;
virtual int getDecoderCapabilities() override;
virtual bool needsTestFrame() override;
virtual bool isPixelFormatSupported(int videoFormat, enum AVPixelFormat pixelFormat) override;
virtual AVPixelFormat getPreferredPixelFormat(int videoFormat) override;

View File

@@ -193,12 +193,6 @@ public:
return true;
}
// NOTE: This can be called BEFORE initialize()!
virtual bool needsTestFrame() {
// No test frame required by default
return false;
}
virtual int getDecoderCapabilities() {
// No special capabilities by default
return 0;

View File

@@ -574,14 +574,6 @@ VAAPIRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**)
return true;
}
bool
VAAPIRenderer::needsTestFrame()
{
// We need a test frame to see if this VAAPI driver
// supports the profile used for streaming
return true;
}
bool
VAAPIRenderer::isDirectRenderingSupported()
{

View File

@@ -61,7 +61,6 @@ public:
virtual bool initialize(PDECODER_PARAMETERS params) override;
virtual bool prepareDecoderContext(AVCodecContext* context, AVDictionary** options) override;
virtual void renderFrame(AVFrame* frame) override;
virtual bool needsTestFrame() override;
virtual bool isDirectRenderingSupported() override;
virtual int getDecoderColorspace() override;
virtual int getDecoderCapabilities() override;

View File

@@ -461,13 +461,6 @@ void VDPAURenderer::notifyOverlayUpdated(Overlay::OverlayType type)
}
}
bool VDPAURenderer::needsTestFrame()
{
// We need a test frame to see if this VDPAU driver
// supports the profile used for streaming
return true;
}
int VDPAURenderer::getDecoderColorspace()
{
// VDPAU defaults to Rec 601.

View File

@@ -18,7 +18,6 @@ public:
virtual void notifyOverlayUpdated(Overlay::OverlayType type) override;
virtual void waitToRender() override;
virtual void renderFrame(AVFrame* frame) override;
virtual bool needsTestFrame() override;
virtual int getDecoderColorspace() override;
virtual int getDecoderCapabilities() override;

View File

@@ -451,15 +451,6 @@ public:
return true;
}
virtual bool needsTestFrame() override
{
// We used to trust VT to tell us whether decode will work, but
// there are cases where it can lie because the hardware technically
// can decode the format but VT is unserviceable for some other reason.
// Decoding the test frame will tell us for sure whether it will work.
return true;
}
int getDecoderColorspace() override
{
// macOS seems to handle Rec 601 best

View File

@@ -809,15 +809,6 @@ public:
return false;
}
virtual bool needsTestFrame() override
{
// We used to trust VT to tell us whether decode will work, but
// there are cases where it can lie because the hardware technically
// can decode the format but VT is unserviceable for some other reason.
// Decoding the test frame will tell us for sure whether it will work.
return true;
}
int getDecoderColorspace() override
{
// macOS seems to handle Rec 601 best

View File

@@ -1106,39 +1106,31 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
break;
}
// Initialize the backend renderer itself
if (initializeRendererInternal(m_BackendRenderer, (m_TestOnly || m_BackendRenderer->needsTestFrame()) ? &testFrameDecoderParams : params)) {
if (completeInitialization(decoder, requiredFormat,
(m_TestOnly || m_BackendRenderer->needsTestFrame()) ? &testFrameDecoderParams : params,
m_TestOnly || m_BackendRenderer->needsTestFrame(),
i == 0 /* EGL/DRM */)) {
// Initialize the backend renderer for testing
if (initializeRendererInternal(m_BackendRenderer, &testFrameDecoderParams)) {
if (completeInitialization(decoder, requiredFormat, &testFrameDecoderParams,
true, i == 0 /* EGL/DRM */)) {
if (m_TestOnly) {
// This decoder is only for testing capabilities, so don't bother
// creating a usable renderer
return true;
}
if (m_BackendRenderer->needsTestFrame()) {
// The test worked, so now let's initialize it for real
reset();
// The test worked, so now let's initialize it for real
reset();
if ((m_BackendRenderer = createRendererFunc()) == nullptr) {
// Out of memory
break;
}
if ((m_BackendRenderer = createRendererFunc()) == nullptr) {
// Out of memory
break;
}
if (initializeRendererInternal(m_BackendRenderer, params) &&
completeInitialization(decoder, requiredFormat, params, false, i == 0 /* EGL/DRM */)) {
return true;
}
else {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Decoder failed to initialize after successful test");
}
if (initializeRendererInternal(m_BackendRenderer, params) &&
completeInitialization(decoder, requiredFormat, params, false, i == 0 /* EGL/DRM */)) {
return true;
}
else {
// No test required. Good to go now.
return true;
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Decoder failed to initialize after successful test");
}
}
}