Avoid the test frame for DXVA2 and VT APIs to address flickering in full-screen on Win7

This commit is contained in:
Cameron Gutman
2018-08-19 00:59:04 -07:00
parent 91c0429e2c
commit 845e84adb7
10 changed files with 56 additions and 11 deletions

View File

@@ -496,6 +496,13 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i
return true;
}
bool DXVA2Renderer::needsTestFrame()
{
// We validate the DXVA2 profiles are supported
// in initialize() so no test frame is required
return false;
}
void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame)
{
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);

View File

@@ -22,6 +22,7 @@ public:
int maxFps);
virtual bool prepareDecoderContext(AVCodecContext* context);
virtual void renderFrameAtVsync(AVFrame* frame);
virtual bool needsTestFrame();
private:
bool initializeDecoder();

View File

@@ -16,6 +16,7 @@ public:
int maxFps) = 0;
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
virtual bool needsTestFrame() = 0;
};
class SdlRenderer : public IFFmpegRenderer {
@@ -29,6 +30,7 @@ public:
int maxFps);
virtual bool prepareDecoderContext(AVCodecContext* context);
virtual void renderFrameAtVsync(AVFrame* frame);
virtual bool needsTestFrame();
private:
SDL_Renderer* m_Renderer;

View File

@@ -30,6 +30,12 @@ bool SdlRenderer::prepareDecoderContext(AVCodecContext*)
return true;
}
bool SdlRenderer::needsTestFrame()
{
// This renderer should always work
return false;
}
bool SdlRenderer::initialize(SDL_Window* window,
int,
int width,

View File

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

View File

@@ -37,6 +37,7 @@ public:
int maxFps);
virtual bool prepareDecoderContext(AVCodecContext* context);
virtual void renderFrameAtVsync(AVFrame* frame);
virtual bool needsTestFrame();
private:
int m_WindowSystem;

View File

@@ -223,6 +223,13 @@ bool VDPAURenderer::prepareDecoderContext(AVCodecContext* context)
return true;
}
bool VDPAURenderer::needsTestFrame()
{
// We need a test frame to see if this VDPAU driver
// supports the profile used for streaming
return true;
}
void VDPAURenderer::renderFrameAtVsync(AVFrame* frame)
{
VdpStatus status;

View File

@@ -20,6 +20,7 @@ public:
int maxFps);
virtual bool prepareDecoderContext(AVCodecContext* context);
virtual void renderFrameAtVsync(AVFrame* frame);
virtual bool needsTestFrame();
private:
uint32_t m_VideoWidth, m_VideoHeight;

View File

@@ -189,6 +189,12 @@ public:
return true;
}
virtual bool needsTestFrame() override
{
// We query VT to determine whether the codec is supported
return false;
}
private:
void setupDisplayLayer()
{

View File

@@ -280,20 +280,26 @@ bool FFmpegVideoDecoder::initialize(
}
m_HwDecodeCfg = config;
// Submit test frame to ensure this codec really works
// Initialize the hardware codec and submit a test frame if the renderer needs it
if (m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
completeInitialization(decoder, window, videoFormat, width, height, maxFps, true)) {
// OK, it worked, so now let's initialize it for real
reset();
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
completeInitialization(decoder, window, videoFormat, width, height, maxFps, false)) {
return true;
completeInitialization(decoder, window, videoFormat, width, height, maxFps, m_Renderer->needsTestFrame())) {
if (m_Renderer->needsTestFrame()) {
// The test worked, so now let's initialize it for real
reset();
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
completeInitialization(decoder, window, videoFormat, width, height, maxFps, false)) {
return true;
}
else {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Decoder failed to initialize after successful test");
reset();
}
}
else {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Decoder failed to initialize after successful test");
reset();
// No test required. Good to go now.
return true;
}
}
else {