diff --git a/app/streaming/input.cpp b/app/streaming/input.cpp index d77e9a1c..7571540f 100644 --- a/app/streaming/input.cpp +++ b/app/streaming/input.cpp @@ -180,8 +180,8 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) "Detected stats toggle combo"); // Toggle the stats overlay - Session::get()->getOverlayManager().setOverlayState(OverlayManager::OverlayDebug, - !Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)); + Session::get()->getOverlayManager().setOverlayState(Overlay::OverlayDebug, + !Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug)); // Force raise all keys just be safe across this full-screen/windowed // transition just in case key events get lost. diff --git a/app/streaming/session.h b/app/streaming/session.h index 58ecc91e..19d1d844 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -37,7 +37,7 @@ public: return s_ActiveSession; } - OverlayManager& getOverlayManager() + Overlay::OverlayManager& getOverlayManager() { return m_OverlayManager; } @@ -149,7 +149,7 @@ private: OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig; int m_AudioSampleCount; - OverlayManager m_OverlayManager; + Overlay::OverlayManager m_OverlayManager; static AUDIO_RENDERER_CALLBACKS k_AudioCallbacks; static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks; diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index d339f221..1af9b081 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -920,9 +920,9 @@ void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame) } if (m_OverlayFont != nullptr) { - if (Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)) { + if (Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug)) { m_OverlayFont->DrawTextA(nullptr, - Session::get()->getOverlayManager().getOverlayText(OverlayManager::OverlayDebug), + Session::get()->getOverlayManager().getOverlayText(Overlay::OverlayDebug), -1, &sample.DstRect, DT_LEFT | DT_NOCLIP, diff --git a/app/streaming/video/ffmpeg-renderers/renderer.h b/app/streaming/video/ffmpeg-renderers/renderer.h index be4caca2..7a44a290 100644 --- a/app/streaming/video/ffmpeg-renderers/renderer.h +++ b/app/streaming/video/ffmpeg-renderers/renderer.h @@ -2,11 +2,13 @@ #include +#include "streaming/video/overlaymanager.h" + extern "C" { #include } -class IFFmpegRenderer { +class IFFmpegRenderer : public Overlay::IOverlayRenderer { public: enum FramePacingConstraint { PACING_FORCE_OFF, @@ -14,7 +16,6 @@ public: PACING_ANY }; - virtual ~IFFmpegRenderer() {} virtual bool initialize(SDL_Window* window, int videoFormat, int width, @@ -26,6 +27,11 @@ public: virtual bool needsTestFrame() = 0; virtual int getDecoderCapabilities() = 0; virtual FramePacingConstraint getFramePacingConstraint() = 0; + + // IOverlayRenderer + virtual void notifyOverlayUpdated(Overlay::OverlayType) override { + // Nothing + } }; class SdlRenderer : public IFFmpegRenderer { diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index f7c30058..6fb28831 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -103,6 +103,10 @@ void FFmpegVideoDecoder::reset() // need to delete in the renderer destructor. avcodec_free_context(&m_VideoDecoderCtx); + if (!m_TestOnly) { + Session::get()->getOverlayManager().setOverlayRenderer(nullptr); + } + delete m_Renderer; m_Renderer = nullptr; @@ -232,6 +236,9 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi else { m_NeedsSpsFixup = false; } + + // Tell overlay manager to use this renderer + Session::get()->getOverlayManager().setOverlayRenderer(m_Renderer); } #ifdef QT_DEBUG @@ -508,12 +515,13 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) // Flip stats windows roughly every second if (SDL_TICKS_PASSED(SDL_GetTicks(), m_ActiveWndVideoStats.measurementStartTimestamp + 1000)) { // Update overlay stats if it's enabled - if (Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)) { + if (Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug)) { VIDEO_STATS lastTwoWndStats = {}; addVideoStats(m_LastWndVideoStats, lastTwoWndStats); addVideoStats(m_ActiveWndVideoStats, lastTwoWndStats); - stringifyVideoStats(lastTwoWndStats, Session::get()->getOverlayManager().getOverlayText(OverlayManager::OverlayDebug)); + stringifyVideoStats(lastTwoWndStats, Session::get()->getOverlayManager().getOverlayText(Overlay::OverlayDebug)); + Session::get()->getOverlayManager().setOverlayTextUpdated(Overlay::OverlayDebug); } // Accumulate these values into the global stats diff --git a/app/streaming/video/overlaymanager.cpp b/app/streaming/video/overlaymanager.cpp index 45bbf0de..e5ac8076 100644 --- a/app/streaming/video/overlaymanager.cpp +++ b/app/streaming/video/overlaymanager.cpp @@ -1,25 +1,50 @@ #include "overlaymanager.h" -OverlayManager::OverlayManager() +using namespace Overlay; + +OverlayManager::OverlayManager() : + m_Renderer(nullptr) { memset(m_Overlays, 0, sizeof(m_Overlays)); } -bool OverlayManager::isOverlayEnabled(OverlayManager::OverlayType type) +bool OverlayManager::isOverlayEnabled(OverlayType type) { return m_Overlays[type].enabled; } - char* OverlayManager::getOverlayText(OverlayType type) { return m_Overlays[type].text; } -void OverlayManager::setOverlayState(OverlayManager::OverlayType type, bool enabled) +void OverlayManager::setOverlayTextUpdated(OverlayType type) { - m_Overlays[type].enabled = enabled; - if (!enabled) { - // Set the text to empty string on disable - m_Overlays[type].text[0] = 0; + // Only update the overlay state if it's enabled. If it's not enabled, + // the renderer has already been notified by setOverlayState(). + if (m_Overlays[type].enabled && m_Renderer != nullptr) { + m_Renderer->notifyOverlayUpdated(type); } } + +void OverlayManager::setOverlayState(OverlayType type, bool enabled) +{ + bool stateChanged = m_Overlays[type].enabled != enabled; + + m_Overlays[type].enabled = enabled; + + if (stateChanged) { + if (!enabled) { + // Set the text to empty string on disable + m_Overlays[type].text[0] = 0; + } + + if (m_Renderer != nullptr) { + m_Renderer->notifyOverlayUpdated(type); + } + } +} + +void OverlayManager::setOverlayRenderer(IOverlayRenderer* renderer) +{ + m_Renderer = renderer; +} diff --git a/app/streaming/video/overlaymanager.h b/app/streaming/video/overlaymanager.h index 0be8453c..516cd502 100644 --- a/app/streaming/video/overlaymanager.h +++ b/app/streaming/video/overlaymanager.h @@ -2,25 +2,40 @@ #include +namespace Overlay { + +enum OverlayType { + OverlayDebug, + OverlayMinorNotification, + OverlayMajorNotification, + OverlayMax +}; + +class IOverlayRenderer +{ +public: + virtual ~IOverlayRenderer() = default; + + virtual void notifyOverlayUpdated(OverlayType type) = 0; +}; + class OverlayManager { public: - enum OverlayType { - OverlayDebug, - OverlayMinorNotification, - OverlayMajorNotification, - OverlayMax - }; - OverlayManager(); bool isOverlayEnabled(OverlayType type); char* getOverlayText(OverlayType type); + void setOverlayTextUpdated(OverlayType type); void setOverlayState(OverlayType type, bool enabled); + void setOverlayRenderer(IOverlayRenderer* renderer); + struct { bool enabled; - int updateSeq; char text[512]; } m_Overlays[OverlayMax]; + IOverlayRenderer* m_Renderer; }; + +}