mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 06:01:12 +00:00
Avoid the test frame for DXVA2 and VT APIs to address flickering in full-screen on Win7
This commit is contained in:
@@ -496,6 +496,13 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i
|
|||||||
return true;
|
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)
|
void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame)
|
||||||
{
|
{
|
||||||
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);
|
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
int maxFps);
|
int maxFps);
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
|
virtual bool needsTestFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initializeDecoder();
|
bool initializeDecoder();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public:
|
|||||||
int maxFps) = 0;
|
int maxFps) = 0;
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
|
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
|
||||||
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
|
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
|
||||||
|
virtual bool needsTestFrame() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SdlRenderer : public IFFmpegRenderer {
|
class SdlRenderer : public IFFmpegRenderer {
|
||||||
@@ -29,6 +30,7 @@ public:
|
|||||||
int maxFps);
|
int maxFps);
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
|
virtual bool needsTestFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Renderer* m_Renderer;
|
SDL_Renderer* m_Renderer;
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ bool SdlRenderer::prepareDecoderContext(AVCodecContext*)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SdlRenderer::needsTestFrame()
|
||||||
|
{
|
||||||
|
// This renderer should always work
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SdlRenderer::initialize(SDL_Window* window,
|
bool SdlRenderer::initialize(SDL_Window* window,
|
||||||
int,
|
int,
|
||||||
int width,
|
int width,
|
||||||
|
|||||||
@@ -141,6 +141,14 @@ VAAPIRenderer::prepareDecoderContext(AVCodecContext* context)
|
|||||||
return true;
|
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
|
void
|
||||||
VAAPIRenderer::renderFrameAtVsync(AVFrame* frame)
|
VAAPIRenderer::renderFrameAtVsync(AVFrame* frame)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public:
|
|||||||
int maxFps);
|
int maxFps);
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
|
virtual bool needsTestFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_WindowSystem;
|
int m_WindowSystem;
|
||||||
|
|||||||
@@ -223,6 +223,13 @@ bool VDPAURenderer::prepareDecoderContext(AVCodecContext* context)
|
|||||||
return true;
|
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)
|
void VDPAURenderer::renderFrameAtVsync(AVFrame* frame)
|
||||||
{
|
{
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
int maxFps);
|
int maxFps);
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
|
virtual bool needsTestFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_VideoWidth, m_VideoHeight;
|
uint32_t m_VideoWidth, m_VideoHeight;
|
||||||
|
|||||||
@@ -189,6 +189,12 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool needsTestFrame() override
|
||||||
|
{
|
||||||
|
// We query VT to determine whether the codec is supported
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupDisplayLayer()
|
void setupDisplayLayer()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -280,20 +280,26 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_HwDecodeCfg = config;
|
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) &&
|
if (m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, true)) {
|
completeInitialization(decoder, window, videoFormat, width, height, maxFps, m_Renderer->needsTestFrame())) {
|
||||||
// OK, it worked, so now let's initialize it for real
|
if (m_Renderer->needsTestFrame()) {
|
||||||
reset();
|
// The test worked, so now let's initialize it for real
|
||||||
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
|
reset();
|
||||||
m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
|
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, false)) {
|
m_Renderer->initialize(window, videoFormat, width, height, maxFps) &&
|
||||||
return true;
|
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 {
|
else {
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
|
// No test required. Good to go now.
|
||||||
"Decoder failed to initialize after successful test");
|
return true;
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user