diff --git a/app/cli/commandlineparser.cpp b/app/cli/commandlineparser.cpp index 7808eb80..4f2f6ce5 100644 --- a/app/cli/commandlineparser.cpp +++ b/app/cli/commandlineparser.cpp @@ -287,6 +287,7 @@ void StreamCommandLineParser::parse(const QStringList &args, StreamingPreference parser.addToggleOption("mouse-acceleration", "mouse acceleration"); parser.addToggleOption("game-optimization", "game optimizations"); 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-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 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 if (parser.isSet("video-codec")) { preferences->videoCodecConfig = mapValue(m_VideoCodecMap, parser.getChoiceOptionValue("video-codec")); diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml index b89b961c..4ff0704e 100644 --- a/app/gui/SettingsView.qml +++ b/app/gui/SettingsView.qml @@ -383,7 +383,7 @@ Flickable { CheckBox { id: vsyncCheck hoverEnabled: true - text: "Enable V-Sync" + text: "V-Sync" font.pointSize: 12 checked: prefs.enableVsync onCheckedChanged: { @@ -395,6 +395,22 @@ Flickable { ToolTip.visible: hovered 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" + } } } diff --git a/app/settings/streamingpreferences.cpp b/app/settings/streamingpreferences.cpp index e288ef71..2bf55d36 100644 --- a/app/settings/streamingpreferences.cpp +++ b/app/settings/streamingpreferences.cpp @@ -23,6 +23,7 @@ #define SER_QUITAPPAFTER "quitAppAfter" #define SER_MOUSEACCELERATION "mouseacceleration" #define SER_STARTWINDOWED "startwindowed" +#define SER_FRAMEPACING "framepacing" StreamingPreferences::StreamingPreferences(QObject *parent) : QObject(parent) @@ -47,6 +48,7 @@ void StreamingPreferences::reload() quitAppAfter = settings.value(SER_QUITAPPAFTER, false).toBool(); mouseAcceleration = settings.value(SER_MOUSEACCELERATION, false).toBool(); startWindowed = settings.value(SER_STARTWINDOWED, false).toBool(); + framePacing = settings.value(SER_FRAMEPACING, false).toBool(); audioConfig = static_cast(settings.value(SER_AUDIOCFG, static_cast(AudioConfig::AC_STEREO)).toInt()); videoCodecConfig = static_cast(settings.value(SER_VIDEOCFG, @@ -76,6 +78,7 @@ void StreamingPreferences::save() settings.setValue(SER_QUITAPPAFTER, quitAppAfter); settings.setValue(SER_MOUSEACCELERATION, mouseAcceleration); settings.setValue(SER_STARTWINDOWED, startWindowed); + settings.setValue(SER_FRAMEPACING, framePacing); settings.setValue(SER_AUDIOCFG, static_cast(audioConfig)); settings.setValue(SER_VIDEOCFG, static_cast(videoCodecConfig)); settings.setValue(SER_VIDEODEC, static_cast(videoDecoderSelection)); diff --git a/app/settings/streamingpreferences.h b/app/settings/streamingpreferences.h index 5539a0a3..3d05f82b 100644 --- a/app/settings/streamingpreferences.h +++ b/app/settings/streamingpreferences.h @@ -76,6 +76,7 @@ public: Q_PROPERTY(bool quitAppAfter MEMBER quitAppAfter NOTIFY quitAppAfterChanged) Q_PROPERTY(bool mouseAcceleration MEMBER mouseAcceleration NOTIFY mouseAccelerationChanged) 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(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged) Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged) @@ -95,6 +96,7 @@ public: bool quitAppAfter; bool mouseAcceleration; bool startWindowed; + bool framePacing; AudioConfig audioConfig; VideoCodecConfig videoCodecConfig; VideoDecoderSelection videoDecoderSelection; @@ -116,5 +118,6 @@ signals: void videoDecoderSelectionChanged(); void windowModeChanged(); void startWindowedChanged(); + void framePacingChanged(); }; diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index b356d562..97f48a33 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -99,11 +99,11 @@ void Session::clLogMessage(const char* format, ...) 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, 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 chosenDecoder = new SLVideoDecoder(); @@ -217,7 +217,7 @@ bool Session::isHardwareDecodeAvailable(StreamingPreferences::VideoDecoderSelect 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_QuitSubSystem(SDL_INIT_VIDEO); return false; @@ -257,7 +257,7 @@ int Session::getDecoderCapabilities(StreamingPreferences::VideoDecoderSelection 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_QuitSubSystem(SDL_INIT_VIDEO); return false; @@ -1120,6 +1120,7 @@ void Session::exec(int displayOriginX, int displayOriginY) m_Window, m_ActiveVideoFormat, m_ActiveVideoWidth, m_ActiveVideoHeight, m_ActiveVideoFrameRate, enableVsync, + enableVsync && m_Preferences->framePacing, s_ActiveSession->m_VideoDecoder)) { SDL_AtomicUnlock(&m_DecoderLock); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, diff --git a/app/streaming/session.h b/app/streaming/session.h index 8fec4c01..1d7be76e 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -72,7 +72,8 @@ private: static bool chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, int width, int height, - int frameRate, bool enableVsync, IVideoDecoder*& chosenDecoder); + int frameRate, bool enableVsync, bool enableFramePacing, + IVideoDecoder*& chosenDecoder); static void clStageStarting(int stage); diff --git a/app/streaming/video/decoder.h b/app/streaming/video/decoder.h index 9e55f640..ede736ba 100644 --- a/app/streaming/video/decoder.h +++ b/app/streaming/video/decoder.h @@ -33,7 +33,8 @@ public: int width, int height, int frameRate, - bool enableVsync) = 0; + bool enableVsync, + bool enableFramePacing) = 0; virtual bool isHardwareAccelerated() = 0; virtual int getDecoderCapabilities() = 0; virtual int submitDecodeUnit(PDECODE_UNIT du) = 0; diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index c73e842c..d18e69e0 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -644,9 +644,9 @@ int DXVA2Renderer::getDecoderCapabilities() return 0; } -IFFmpegRenderer::VSyncConstraint DXVA2Renderer::getVsyncConstraint() +IFFmpegRenderer::FramePacingConstraint DXVA2Renderer::getFramePacingConstraint() { - return VSYNC_ANY; + return PACING_ANY; } void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index 5b0ae473..69a62b81 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -25,7 +25,7 @@ public: virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); virtual int getDecoderCapabilities(); - virtual VSyncConstraint getVsyncConstraint(); + virtual FramePacingConstraint getFramePacingConstraint(); private: bool initializeDecoder(); diff --git a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp index c76d2f44..b4317552 100644 --- a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp +++ b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp @@ -124,15 +124,14 @@ RenderNextFrame: 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_EnableVsync = enableVsync; m_DisplayFps = StreamUtils::getDisplayRefreshRate(window); - if (m_EnableVsync) { + if (enablePacing) { 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); #if defined(Q_OS_DARWIN) @@ -150,7 +149,7 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enableVsync) } else { 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); } diff --git a/app/streaming/video/ffmpeg-renderers/pacer/pacer.h b/app/streaming/video/ffmpeg-renderers/pacer/pacer.h index 8f1f56f5..b4e9fc6f 100644 --- a/app/streaming/video/ffmpeg-renderers/pacer/pacer.h +++ b/app/streaming/video/ffmpeg-renderers/pacer/pacer.h @@ -20,7 +20,7 @@ public: 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); @@ -35,6 +35,5 @@ private: IFFmpegRenderer* m_VsyncRenderer; int m_MaxVideoFps; int m_DisplayFps; - bool m_EnableVsync; PVIDEO_STATS m_VideoStats; }; diff --git a/app/streaming/video/ffmpeg-renderers/renderer.h b/app/streaming/video/ffmpeg-renderers/renderer.h index 4ecf2a13..be4caca2 100644 --- a/app/streaming/video/ffmpeg-renderers/renderer.h +++ b/app/streaming/video/ffmpeg-renderers/renderer.h @@ -8,10 +8,10 @@ extern "C" { class IFFmpegRenderer { public: - enum VSyncConstraint { - VSYNC_FORCE_OFF, - VSYNC_FORCE_ON, - VSYNC_ANY + enum FramePacingConstraint { + PACING_FORCE_OFF, + PACING_FORCE_ON, + PACING_ANY }; virtual ~IFFmpegRenderer() {} @@ -25,7 +25,7 @@ public: virtual void renderFrameAtVsync(AVFrame* frame) = 0; virtual bool needsTestFrame() = 0; virtual int getDecoderCapabilities() = 0; - virtual VSyncConstraint getVsyncConstraint() = 0; + virtual FramePacingConstraint getFramePacingConstraint() = 0; }; class SdlRenderer : public IFFmpegRenderer { @@ -42,7 +42,7 @@ public: virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); virtual int getDecoderCapabilities(); - virtual VSyncConstraint getVsyncConstraint(); + virtual FramePacingConstraint getFramePacingConstraint(); private: SDL_Renderer* m_Renderer; diff --git a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp index 2f3d2b65..70b43132 100644 --- a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp @@ -43,9 +43,9 @@ int SdlRenderer::getDecoderCapabilities() 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, diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index cab73b14..a5eebfbb 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -177,9 +177,9 @@ VAAPIRenderer::getDecoderCapabilities() return 0; } -IFFmpegRenderer::VSyncConstraint VAAPIRenderer::getVsyncConstraint() +IFFmpegRenderer::FramePacingConstraint VAAPIRenderer::getFramePacingConstraint() { - return VSYNC_ANY; + return PACING_ANY; } void diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index 084420c9..6b9354b3 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -40,7 +40,7 @@ public: virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); virtual int getDecoderCapabilities(); - virtual VSyncConstraint getVsyncConstraint(); + virtual FramePacingConstraint getFramePacingConstraint(); private: int m_WindowSystem; diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.cpp b/app/streaming/video/ffmpeg-renderers/vdpau.cpp index 2bf65a5a..53fc81a6 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.cpp +++ b/app/streaming/video/ffmpeg-renderers/vdpau.cpp @@ -246,9 +246,9 @@ int VDPAURenderer::getDecoderCapabilities() return 0; } -IFFmpegRenderer::VSyncConstraint VDPAURenderer::getVsyncConstraint() +IFFmpegRenderer::FramePacingConstraint VDPAURenderer::getFramePacingConstraint() { - return VSYNC_ANY; + return PACING_ANY; } void VDPAURenderer::renderFrameAtVsync(AVFrame* frame) diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.h b/app/streaming/video/ffmpeg-renderers/vdpau.h index 81a5ffdd..764d543f 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.h +++ b/app/streaming/video/ffmpeg-renderers/vdpau.h @@ -23,7 +23,7 @@ public: virtual void renderFrameAtVsync(AVFrame* frame); virtual bool needsTestFrame(); virtual int getDecoderCapabilities(); - virtual VSyncConstraint getVsyncConstraint(); + virtual FramePacingConstraint getFramePacingConstraint(); private: uint32_t m_VideoWidth, m_VideoHeight; diff --git a/app/streaming/video/ffmpeg-renderers/vt.mm b/app/streaming/video/ffmpeg-renderers/vt.mm index 286d4ba8..c68ef655 100644 --- a/app/streaming/video/ffmpeg-renderers/vt.mm +++ b/app/streaming/video/ffmpeg-renderers/vt.mm @@ -211,12 +211,12 @@ public: return 0; } - virtual IFFmpegRenderer::VSyncConstraint getVsyncConstraint() override + virtual IFFmpegRenderer::FramePacingConstraint getFramePacingConstraint() override { // This renderer is inherently tied to V-sync due how we're // rendering with AVSampleBufferDisplay layer. Running without // the V-Sync source leads to massive stuttering. - return VSYNC_FORCE_ON; + return PACING_FORCE_ON; } private: diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index 5060ba94..c3159ba7 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -131,27 +131,27 @@ void FFmpegVideoDecoder::reset() bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* window, int videoFormat, int width, int height, - int maxFps, bool enableVsync, bool testOnly) + int maxFps, bool enableFramePacing, bool testOnly) { - auto vsyncConstraint = m_Renderer->getVsyncConstraint(); - if (vsyncConstraint == IFFmpegRenderer::VSYNC_FORCE_OFF && enableVsync) { + auto vsyncConstraint = m_Renderer->getFramePacingConstraint(); + if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_OFF && enableFramePacing) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "V-sync is forcefully disabled by the active renderer"); - enableVsync = false; + "Frame pacing is forcefully disabled by the active renderer"); + 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 int displayHz = StreamUtils::getDisplayRefreshRate(window); if (displayHz + 5 >= maxFps) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "V-sync is forcefully enabled by the active renderer"); - enableVsync = true; + "Frame pacing is forcefully enabled by the active renderer"); + enableFramePacing = true; } } m_StreamFps = maxFps; m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats); - if (!m_Pacer->initialize(window, maxFps, enableVsync)) { + if (!m_Pacer->initialize(window, maxFps, enableFramePacing)) { return false; } @@ -363,7 +363,8 @@ bool FFmpegVideoDecoder::initialize( int width, int height, int maxFps, - bool enableVsync) + bool enableVsync, + bool enableFramePacing) { AVCodec* decoder; @@ -399,7 +400,7 @@ bool FFmpegVideoDecoder::initialize( m_Renderer = new SdlRenderer(); if (vds != StreamingPreferences::VDS_FORCE_HARDWARE && 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; } else { @@ -416,13 +417,13 @@ bool FFmpegVideoDecoder::initialize( m_HwDecodeCfg = config; // Initialize the hardware codec and submit a test frame if the renderer needs it 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()) { // 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, enableVsync) && - completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableVsync, false)) { + completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, false)) { return true; } else { @@ -493,7 +494,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) // Flip stats windows roughly every second if (m_ActiveWndVideoStats.receivedFrames == m_StreamFps) { -#if 0 +#if 1 VIDEO_STATS lastTwoWndStats = {}; addVideoStats(m_LastWndVideoStats, lastTwoWndStats); addVideoStats(m_ActiveWndVideoStats, lastTwoWndStats); diff --git a/app/streaming/video/ffmpeg.h b/app/streaming/video/ffmpeg.h index 4ee1e250..0ab166e1 100644 --- a/app/streaming/video/ffmpeg.h +++ b/app/streaming/video/ffmpeg.h @@ -18,7 +18,8 @@ public: int width, int height, int maxFps, - bool enableVsync) override; + bool enableVsync, + bool enableFramePacing) override; virtual bool isHardwareAccelerated() override; virtual int getDecoderCapabilities() override; virtual int submitDecodeUnit(PDECODE_UNIT du) override; @@ -30,7 +31,7 @@ public: private: bool completeInitialization(AVCodec* decoder, SDL_Window* window, 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); diff --git a/app/streaming/video/sl.cpp b/app/streaming/video/sl.cpp index aac98db8..01d3124a 100644 --- a/app/streaming/video/sl.cpp +++ b/app/streaming/video/sl.cpp @@ -34,7 +34,7 @@ SLVideoDecoder::getDecoderCapabilities() bool SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds, SDL_Window*, - int videoFormat, int, int, int frameRate, bool) + int videoFormat, int, int, int frameRate, bool, bool) { // SLVideo only supports hardware decoding if (vds == StreamingPreferences::VDS_FORCE_SOFTWARE) { diff --git a/app/streaming/video/sl.h b/app/streaming/video/sl.h index 70f955b9..ca7db53d 100644 --- a/app/streaming/video/sl.h +++ b/app/streaming/video/sl.h @@ -15,7 +15,8 @@ public: int width, int height, int frameRate, - bool enableVsync); + bool enableVsync, + bool enableFramePacing); virtual bool isHardwareAccelerated(); virtual int getDecoderCapabilities(); virtual int submitDecodeUnit(PDECODE_UNIT du);