mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-03 08:15:37 +00:00
Add frame pacing toggle
This commit is contained in:
parent
c054536fab
commit
cfabaf334e
@ -287,6 +287,7 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
|
|||||||
parser.addToggleOption("mouse-acceleration", "mouse acceleration");
|
parser.addToggleOption("mouse-acceleration", "mouse acceleration");
|
||||||
parser.addToggleOption("game-optimization", "game optimizations");
|
parser.addToggleOption("game-optimization", "game optimizations");
|
||||||
parser.addToggleOption("audio-on-host", "audio on host PC");
|
parser.addToggleOption("audio-on-host", "audio on host PC");
|
||||||
|
parser.addToggleOption("frame-pacing", "frame pacing");
|
||||||
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
|
parser.addChoiceOption("video-codec", "video codec", m_VideoCodecMap.keys());
|
||||||
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
|
parser.addChoiceOption("video-decoder", "video decoder", m_VideoDecoderMap.keys());
|
||||||
|
|
||||||
@ -372,6 +373,9 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference
|
|||||||
// Resolve --audio-on-host and --no-audio-on-host options
|
// Resolve --audio-on-host and --no-audio-on-host options
|
||||||
preferences->playAudioOnHost = parser.getToggleOptionValue("audio-on-host", preferences->playAudioOnHost);
|
preferences->playAudioOnHost = parser.getToggleOptionValue("audio-on-host", preferences->playAudioOnHost);
|
||||||
|
|
||||||
|
// Resolve --frame-pacing and --no-frame-pacing options
|
||||||
|
preferences->framePacing = parser.getToggleOptionValue("frame-pacing", preferences->framePacing);
|
||||||
|
|
||||||
// Resolve --video-codec option
|
// Resolve --video-codec option
|
||||||
if (parser.isSet("video-codec")) {
|
if (parser.isSet("video-codec")) {
|
||||||
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));
|
preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec"));
|
||||||
|
@ -383,7 +383,7 @@ Flickable {
|
|||||||
CheckBox {
|
CheckBox {
|
||||||
id: vsyncCheck
|
id: vsyncCheck
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
text: "Enable V-Sync"
|
text: "V-Sync"
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
checked: prefs.enableVsync
|
checked: prefs.enableVsync
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
@ -395,6 +395,22 @@ Flickable {
|
|||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: "Disabling V-Sync allows sub-frame rendering latency, but it can display visible tearing"
|
ToolTip.text: "Disabling V-Sync allows sub-frame rendering latency, but it can display visible tearing"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: framePacingCheck
|
||||||
|
hoverEnabled: true
|
||||||
|
text: "Frame pacing"
|
||||||
|
font.pointSize: 12
|
||||||
|
enabled: prefs.enableVsync
|
||||||
|
checked: prefs.enableVsync && prefs.framePacing
|
||||||
|
onCheckedChanged: {
|
||||||
|
prefs.framePacing = checked
|
||||||
|
}
|
||||||
|
ToolTip.delay: 1000
|
||||||
|
ToolTip.timeout: 5000
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: "Frame pacing reduces micro-stutter by delaying frames that come in too early"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define SER_QUITAPPAFTER "quitAppAfter"
|
#define SER_QUITAPPAFTER "quitAppAfter"
|
||||||
#define SER_MOUSEACCELERATION "mouseacceleration"
|
#define SER_MOUSEACCELERATION "mouseacceleration"
|
||||||
#define SER_STARTWINDOWED "startwindowed"
|
#define SER_STARTWINDOWED "startwindowed"
|
||||||
|
#define SER_FRAMEPACING "framepacing"
|
||||||
|
|
||||||
StreamingPreferences::StreamingPreferences(QObject *parent)
|
StreamingPreferences::StreamingPreferences(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@ -47,6 +48,7 @@ void StreamingPreferences::reload()
|
|||||||
quitAppAfter = settings.value(SER_QUITAPPAFTER, false).toBool();
|
quitAppAfter = settings.value(SER_QUITAPPAFTER, false).toBool();
|
||||||
mouseAcceleration = settings.value(SER_MOUSEACCELERATION, false).toBool();
|
mouseAcceleration = settings.value(SER_MOUSEACCELERATION, false).toBool();
|
||||||
startWindowed = settings.value(SER_STARTWINDOWED, false).toBool();
|
startWindowed = settings.value(SER_STARTWINDOWED, false).toBool();
|
||||||
|
framePacing = settings.value(SER_FRAMEPACING, false).toBool();
|
||||||
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
||||||
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
static_cast<int>(AudioConfig::AC_STEREO)).toInt());
|
||||||
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
videoCodecConfig = static_cast<VideoCodecConfig>(settings.value(SER_VIDEOCFG,
|
||||||
@ -76,6 +78,7 @@ void StreamingPreferences::save()
|
|||||||
settings.setValue(SER_QUITAPPAFTER, quitAppAfter);
|
settings.setValue(SER_QUITAPPAFTER, quitAppAfter);
|
||||||
settings.setValue(SER_MOUSEACCELERATION, mouseAcceleration);
|
settings.setValue(SER_MOUSEACCELERATION, mouseAcceleration);
|
||||||
settings.setValue(SER_STARTWINDOWED, startWindowed);
|
settings.setValue(SER_STARTWINDOWED, startWindowed);
|
||||||
|
settings.setValue(SER_FRAMEPACING, framePacing);
|
||||||
settings.setValue(SER_AUDIOCFG, static_cast<int>(audioConfig));
|
settings.setValue(SER_AUDIOCFG, static_cast<int>(audioConfig));
|
||||||
settings.setValue(SER_VIDEOCFG, static_cast<int>(videoCodecConfig));
|
settings.setValue(SER_VIDEOCFG, static_cast<int>(videoCodecConfig));
|
||||||
settings.setValue(SER_VIDEODEC, static_cast<int>(videoDecoderSelection));
|
settings.setValue(SER_VIDEODEC, static_cast<int>(videoDecoderSelection));
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
Q_PROPERTY(bool quitAppAfter MEMBER quitAppAfter NOTIFY quitAppAfterChanged)
|
Q_PROPERTY(bool quitAppAfter MEMBER quitAppAfter NOTIFY quitAppAfterChanged)
|
||||||
Q_PROPERTY(bool mouseAcceleration MEMBER mouseAcceleration NOTIFY mouseAccelerationChanged)
|
Q_PROPERTY(bool mouseAcceleration MEMBER mouseAcceleration NOTIFY mouseAccelerationChanged)
|
||||||
Q_PROPERTY(bool startWindowed MEMBER startWindowed NOTIFY startWindowedChanged)
|
Q_PROPERTY(bool startWindowed MEMBER startWindowed NOTIFY startWindowedChanged)
|
||||||
|
Q_PROPERTY(bool framePacing MEMBER framePacing NOTIFY framePacingChanged)
|
||||||
Q_PROPERTY(AudioConfig audioConfig MEMBER audioConfig NOTIFY audioConfigChanged)
|
Q_PROPERTY(AudioConfig audioConfig MEMBER audioConfig NOTIFY audioConfigChanged)
|
||||||
Q_PROPERTY(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged)
|
Q_PROPERTY(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged)
|
||||||
Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged)
|
Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged)
|
||||||
@ -95,6 +96,7 @@ public:
|
|||||||
bool quitAppAfter;
|
bool quitAppAfter;
|
||||||
bool mouseAcceleration;
|
bool mouseAcceleration;
|
||||||
bool startWindowed;
|
bool startWindowed;
|
||||||
|
bool framePacing;
|
||||||
AudioConfig audioConfig;
|
AudioConfig audioConfig;
|
||||||
VideoCodecConfig videoCodecConfig;
|
VideoCodecConfig videoCodecConfig;
|
||||||
VideoDecoderSelection videoDecoderSelection;
|
VideoDecoderSelection videoDecoderSelection;
|
||||||
@ -116,5 +118,6 @@ signals:
|
|||||||
void videoDecoderSelectionChanged();
|
void videoDecoderSelectionChanged();
|
||||||
void windowModeChanged();
|
void windowModeChanged();
|
||||||
void startWindowedChanged();
|
void startWindowedChanged();
|
||||||
|
void framePacingChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,11 +99,11 @@ void Session::clLogMessage(const char* format, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CALL_INITIALIZE(dec) (dec)->initialize(vds, window, videoFormat, width, height, frameRate, enableVsync)
|
#define CALL_INITIALIZE(dec) (dec)->initialize(vds, window, videoFormat, width, height, frameRate, enableVsync, enableFramePacing)
|
||||||
|
|
||||||
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
SDL_Window* window, int videoFormat, int width, int height,
|
SDL_Window* window, int videoFormat, int width, int height,
|
||||||
int frameRate, bool enableVsync, IVideoDecoder*& chosenDecoder)
|
int frameRate, bool enableVsync, bool enableFramePacing, IVideoDecoder*& chosenDecoder)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SLVIDEO
|
#ifdef HAVE_SLVIDEO
|
||||||
chosenDecoder = new SLVideoDecoder();
|
chosenDecoder = new SLVideoDecoder();
|
||||||
@ -217,7 +217,7 @@ bool Session::isHardwareDecodeAvailable(StreamingPreferences::VideoDecoderSelect
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, decoder)) {
|
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, decoder)) {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
return false;
|
return false;
|
||||||
@ -257,7 +257,7 @@ int Session::getDecoderCapabilities(StreamingPreferences::VideoDecoderSelection
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, decoder)) {
|
if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, decoder)) {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
return false;
|
return false;
|
||||||
@ -1120,6 +1120,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
m_Window, m_ActiveVideoFormat, m_ActiveVideoWidth,
|
m_Window, m_ActiveVideoFormat, m_ActiveVideoWidth,
|
||||||
m_ActiveVideoHeight, m_ActiveVideoFrameRate,
|
m_ActiveVideoHeight, m_ActiveVideoFrameRate,
|
||||||
enableVsync,
|
enableVsync,
|
||||||
|
enableVsync && m_Preferences->framePacing,
|
||||||
s_ActiveSession->m_VideoDecoder)) {
|
s_ActiveSession->m_VideoDecoder)) {
|
||||||
SDL_AtomicUnlock(&m_DecoderLock);
|
SDL_AtomicUnlock(&m_DecoderLock);
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
@ -72,7 +72,8 @@ private:
|
|||||||
static
|
static
|
||||||
bool chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
bool chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
SDL_Window* window, int videoFormat, int width, int height,
|
SDL_Window* window, int videoFormat, int width, int height,
|
||||||
int frameRate, bool enableVsync, IVideoDecoder*& chosenDecoder);
|
int frameRate, bool enableVsync, bool enableFramePacing,
|
||||||
|
IVideoDecoder*& chosenDecoder);
|
||||||
|
|
||||||
static
|
static
|
||||||
void clStageStarting(int stage);
|
void clStageStarting(int stage);
|
||||||
|
@ -33,7 +33,8 @@ public:
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameRate,
|
int frameRate,
|
||||||
bool enableVsync) = 0;
|
bool enableVsync,
|
||||||
|
bool enableFramePacing) = 0;
|
||||||
virtual bool isHardwareAccelerated() = 0;
|
virtual bool isHardwareAccelerated() = 0;
|
||||||
virtual int getDecoderCapabilities() = 0;
|
virtual int getDecoderCapabilities() = 0;
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
|
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
|
||||||
|
@ -644,9 +644,9 @@ int DXVA2Renderer::getDecoderCapabilities()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFFmpegRenderer::VSyncConstraint DXVA2Renderer::getVsyncConstraint()
|
IFFmpegRenderer::FramePacingConstraint DXVA2Renderer::getFramePacingConstraint()
|
||||||
{
|
{
|
||||||
return VSYNC_ANY;
|
return PACING_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame)
|
void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame)
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
virtual bool needsTestFrame();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual VSyncConstraint getVsyncConstraint();
|
virtual FramePacingConstraint getFramePacingConstraint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initializeDecoder();
|
bool initializeDecoder();
|
||||||
|
@ -124,15 +124,14 @@ RenderNextFrame:
|
|||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enableVsync)
|
bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enablePacing)
|
||||||
{
|
{
|
||||||
m_MaxVideoFps = maxVideoFps;
|
m_MaxVideoFps = maxVideoFps;
|
||||||
m_EnableVsync = enableVsync;
|
|
||||||
m_DisplayFps = StreamUtils::getDisplayRefreshRate(window);
|
m_DisplayFps = StreamUtils::getDisplayRefreshRate(window);
|
||||||
|
|
||||||
if (m_EnableVsync) {
|
if (enablePacing) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Frame pacing in tear-free mode: target %d Hz with %d FPS stream",
|
"Frame pacing active: target %d Hz with %d FPS stream",
|
||||||
m_DisplayFps, m_MaxVideoFps);
|
m_DisplayFps, m_MaxVideoFps);
|
||||||
|
|
||||||
#if defined(Q_OS_DARWIN)
|
#if defined(Q_OS_DARWIN)
|
||||||
@ -150,7 +149,7 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enableVsync)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Minimal latency tearing mode: target %d Hz with %d FPS stream",
|
"Frame pacing disabled: target %d Hz with %d FPS stream",
|
||||||
m_DisplayFps, m_MaxVideoFps);
|
m_DisplayFps, m_MaxVideoFps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
void submitFrame(AVFrame* frame);
|
void submitFrame(AVFrame* frame);
|
||||||
|
|
||||||
bool initialize(SDL_Window* window, int maxVideoFps, bool enableVsync);
|
bool initialize(SDL_Window* window, int maxVideoFps, bool enablePacing);
|
||||||
|
|
||||||
void vsyncCallback(int timeUntilNextVsyncMillis);
|
void vsyncCallback(int timeUntilNextVsyncMillis);
|
||||||
|
|
||||||
@ -35,6 +35,5 @@ private:
|
|||||||
IFFmpegRenderer* m_VsyncRenderer;
|
IFFmpegRenderer* m_VsyncRenderer;
|
||||||
int m_MaxVideoFps;
|
int m_MaxVideoFps;
|
||||||
int m_DisplayFps;
|
int m_DisplayFps;
|
||||||
bool m_EnableVsync;
|
|
||||||
PVIDEO_STATS m_VideoStats;
|
PVIDEO_STATS m_VideoStats;
|
||||||
};
|
};
|
||||||
|
@ -8,10 +8,10 @@ extern "C" {
|
|||||||
|
|
||||||
class IFFmpegRenderer {
|
class IFFmpegRenderer {
|
||||||
public:
|
public:
|
||||||
enum VSyncConstraint {
|
enum FramePacingConstraint {
|
||||||
VSYNC_FORCE_OFF,
|
PACING_FORCE_OFF,
|
||||||
VSYNC_FORCE_ON,
|
PACING_FORCE_ON,
|
||||||
VSYNC_ANY
|
PACING_ANY
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~IFFmpegRenderer() {}
|
virtual ~IFFmpegRenderer() {}
|
||||||
@ -25,7 +25,7 @@ public:
|
|||||||
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
|
virtual void renderFrameAtVsync(AVFrame* frame) = 0;
|
||||||
virtual bool needsTestFrame() = 0;
|
virtual bool needsTestFrame() = 0;
|
||||||
virtual int getDecoderCapabilities() = 0;
|
virtual int getDecoderCapabilities() = 0;
|
||||||
virtual VSyncConstraint getVsyncConstraint() = 0;
|
virtual FramePacingConstraint getFramePacingConstraint() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SdlRenderer : public IFFmpegRenderer {
|
class SdlRenderer : public IFFmpegRenderer {
|
||||||
@ -42,7 +42,7 @@ public:
|
|||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
virtual bool needsTestFrame();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual VSyncConstraint getVsyncConstraint();
|
virtual FramePacingConstraint getFramePacingConstraint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Renderer* m_Renderer;
|
SDL_Renderer* m_Renderer;
|
||||||
|
@ -43,9 +43,9 @@ int SdlRenderer::getDecoderCapabilities()
|
|||||||
return CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC;
|
return CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFFmpegRenderer::VSyncConstraint SdlRenderer::getVsyncConstraint()
|
IFFmpegRenderer::FramePacingConstraint SdlRenderer::getFramePacingConstraint()
|
||||||
{
|
{
|
||||||
return VSYNC_ANY;
|
return PACING_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlRenderer::initialize(SDL_Window* window,
|
bool SdlRenderer::initialize(SDL_Window* window,
|
||||||
|
@ -177,9 +177,9 @@ VAAPIRenderer::getDecoderCapabilities()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFFmpegRenderer::VSyncConstraint VAAPIRenderer::getVsyncConstraint()
|
IFFmpegRenderer::FramePacingConstraint VAAPIRenderer::getFramePacingConstraint()
|
||||||
{
|
{
|
||||||
return VSYNC_ANY;
|
return PACING_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
virtual bool needsTestFrame();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual VSyncConstraint getVsyncConstraint();
|
virtual FramePacingConstraint getFramePacingConstraint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_WindowSystem;
|
int m_WindowSystem;
|
||||||
|
@ -246,9 +246,9 @@ int VDPAURenderer::getDecoderCapabilities()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFFmpegRenderer::VSyncConstraint VDPAURenderer::getVsyncConstraint()
|
IFFmpegRenderer::FramePacingConstraint VDPAURenderer::getFramePacingConstraint()
|
||||||
{
|
{
|
||||||
return VSYNC_ANY;
|
return PACING_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VDPAURenderer::renderFrameAtVsync(AVFrame* frame)
|
void VDPAURenderer::renderFrameAtVsync(AVFrame* frame)
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
virtual void renderFrameAtVsync(AVFrame* frame);
|
virtual void renderFrameAtVsync(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
virtual bool needsTestFrame();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual VSyncConstraint getVsyncConstraint();
|
virtual FramePacingConstraint getFramePacingConstraint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_VideoWidth, m_VideoHeight;
|
uint32_t m_VideoWidth, m_VideoHeight;
|
||||||
|
@ -211,12 +211,12 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual IFFmpegRenderer::VSyncConstraint getVsyncConstraint() override
|
virtual IFFmpegRenderer::FramePacingConstraint getFramePacingConstraint() override
|
||||||
{
|
{
|
||||||
// This renderer is inherently tied to V-sync due how we're
|
// This renderer is inherently tied to V-sync due how we're
|
||||||
// rendering with AVSampleBufferDisplay layer. Running without
|
// rendering with AVSampleBufferDisplay layer. Running without
|
||||||
// the V-Sync source leads to massive stuttering.
|
// the V-Sync source leads to massive stuttering.
|
||||||
return VSYNC_FORCE_ON;
|
return PACING_FORCE_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -131,27 +131,27 @@ void FFmpegVideoDecoder::reset()
|
|||||||
|
|
||||||
bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* window,
|
bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* window,
|
||||||
int videoFormat, int width, int height,
|
int videoFormat, int width, int height,
|
||||||
int maxFps, bool enableVsync, bool testOnly)
|
int maxFps, bool enableFramePacing, bool testOnly)
|
||||||
{
|
{
|
||||||
auto vsyncConstraint = m_Renderer->getVsyncConstraint();
|
auto vsyncConstraint = m_Renderer->getFramePacingConstraint();
|
||||||
if (vsyncConstraint == IFFmpegRenderer::VSYNC_FORCE_OFF && enableVsync) {
|
if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_OFF && enableFramePacing) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"V-sync is forcefully disabled by the active renderer");
|
"Frame pacing is forcefully disabled by the active renderer");
|
||||||
enableVsync = false;
|
enableFramePacing = false;
|
||||||
}
|
}
|
||||||
else if (vsyncConstraint == IFFmpegRenderer::VSYNC_FORCE_ON && !enableVsync) {
|
else if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_ON && !enableFramePacing) {
|
||||||
// FIXME: This duplicates logic in Session.cpp
|
// FIXME: This duplicates logic in Session.cpp
|
||||||
int displayHz = StreamUtils::getDisplayRefreshRate(window);
|
int displayHz = StreamUtils::getDisplayRefreshRate(window);
|
||||||
if (displayHz + 5 >= maxFps) {
|
if (displayHz + 5 >= maxFps) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"V-sync is forcefully enabled by the active renderer");
|
"Frame pacing is forcefully enabled by the active renderer");
|
||||||
enableVsync = true;
|
enableFramePacing = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_StreamFps = maxFps;
|
m_StreamFps = maxFps;
|
||||||
m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats);
|
m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats);
|
||||||
if (!m_Pacer->initialize(window, maxFps, enableVsync)) {
|
if (!m_Pacer->initialize(window, maxFps, enableFramePacing)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +363,8 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int maxFps,
|
int maxFps,
|
||||||
bool enableVsync)
|
bool enableVsync,
|
||||||
|
bool enableFramePacing)
|
||||||
{
|
{
|
||||||
AVCodec* decoder;
|
AVCodec* decoder;
|
||||||
|
|
||||||
@ -399,7 +400,7 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
m_Renderer = new SdlRenderer();
|
m_Renderer = new SdlRenderer();
|
||||||
if (vds != StreamingPreferences::VDS_FORCE_HARDWARE &&
|
if (vds != StreamingPreferences::VDS_FORCE_HARDWARE &&
|
||||||
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableVsync, false)) {
|
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, false)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -416,13 +417,13 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
m_HwDecodeCfg = config;
|
m_HwDecodeCfg = config;
|
||||||
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
||||||
if (m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
if (m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableVsync, m_Renderer->needsTestFrame())) {
|
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_Renderer->needsTestFrame())) {
|
||||||
if (m_Renderer->needsTestFrame()) {
|
if (m_Renderer->needsTestFrame()) {
|
||||||
// The test worked, so now let's initialize it for real
|
// The test worked, so now let's initialize it for real
|
||||||
reset();
|
reset();
|
||||||
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
|
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
|
||||||
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableVsync, false)) {
|
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, false)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -493,7 +494,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||||||
|
|
||||||
// Flip stats windows roughly every second
|
// Flip stats windows roughly every second
|
||||||
if (m_ActiveWndVideoStats.receivedFrames == m_StreamFps) {
|
if (m_ActiveWndVideoStats.receivedFrames == m_StreamFps) {
|
||||||
#if 0
|
#if 1
|
||||||
VIDEO_STATS lastTwoWndStats = {};
|
VIDEO_STATS lastTwoWndStats = {};
|
||||||
addVideoStats(m_LastWndVideoStats, lastTwoWndStats);
|
addVideoStats(m_LastWndVideoStats, lastTwoWndStats);
|
||||||
addVideoStats(m_ActiveWndVideoStats, lastTwoWndStats);
|
addVideoStats(m_ActiveWndVideoStats, lastTwoWndStats);
|
||||||
|
@ -18,7 +18,8 @@ public:
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int maxFps,
|
int maxFps,
|
||||||
bool enableVsync) override;
|
bool enableVsync,
|
||||||
|
bool enableFramePacing) override;
|
||||||
virtual bool isHardwareAccelerated() override;
|
virtual bool isHardwareAccelerated() override;
|
||||||
virtual int getDecoderCapabilities() override;
|
virtual int getDecoderCapabilities() override;
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du) override;
|
virtual int submitDecodeUnit(PDECODE_UNIT du) override;
|
||||||
@ -30,7 +31,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool completeInitialization(AVCodec* decoder, SDL_Window* window,
|
bool completeInitialization(AVCodec* decoder, SDL_Window* window,
|
||||||
int videoFormat, int width, int height,
|
int videoFormat, int width, int height,
|
||||||
int maxFps, bool enableVsync, bool testOnly);
|
int maxFps, bool enableFramePacing, bool testOnly);
|
||||||
|
|
||||||
void logVideoStats(VIDEO_STATS& stats, const char* title);
|
void logVideoStats(VIDEO_STATS& stats, const char* title);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ SLVideoDecoder::getDecoderCapabilities()
|
|||||||
bool
|
bool
|
||||||
SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
SDL_Window*,
|
SDL_Window*,
|
||||||
int videoFormat, int, int, int frameRate, bool)
|
int videoFormat, int, int, int frameRate, bool, bool)
|
||||||
{
|
{
|
||||||
// SLVideo only supports hardware decoding
|
// SLVideo only supports hardware decoding
|
||||||
if (vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
if (vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||||
|
@ -15,7 +15,8 @@ public:
|
|||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameRate,
|
int frameRate,
|
||||||
bool enableVsync);
|
bool enableVsync,
|
||||||
|
bool enableFramePacing);
|
||||||
virtual bool isHardwareAccelerated();
|
virtual bool isHardwareAccelerated();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du);
|
virtual int submitDecodeUnit(PDECODE_UNIT du);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user