Provide a renderer callback when the overlay data changes

This commit is contained in:
Cameron Gutman 2019-02-12 18:43:38 -08:00
parent 947970e07b
commit 6ed512e762
7 changed files with 80 additions and 26 deletions

View File

@ -180,8 +180,8 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
"Detected stats toggle combo"); "Detected stats toggle combo");
// Toggle the stats overlay // Toggle the stats overlay
Session::get()->getOverlayManager().setOverlayState(OverlayManager::OverlayDebug, Session::get()->getOverlayManager().setOverlayState(Overlay::OverlayDebug,
!Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)); !Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug));
// Force raise all keys just be safe across this full-screen/windowed // Force raise all keys just be safe across this full-screen/windowed
// transition just in case key events get lost. // transition just in case key events get lost.

View File

@ -37,7 +37,7 @@ public:
return s_ActiveSession; return s_ActiveSession;
} }
OverlayManager& getOverlayManager() Overlay::OverlayManager& getOverlayManager()
{ {
return m_OverlayManager; return m_OverlayManager;
} }
@ -149,7 +149,7 @@ private:
OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig; OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig;
int m_AudioSampleCount; int m_AudioSampleCount;
OverlayManager m_OverlayManager; Overlay::OverlayManager m_OverlayManager;
static AUDIO_RENDERER_CALLBACKS k_AudioCallbacks; static AUDIO_RENDERER_CALLBACKS k_AudioCallbacks;
static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks; static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks;

View File

@ -920,9 +920,9 @@ void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame)
} }
if (m_OverlayFont != nullptr) { if (m_OverlayFont != nullptr) {
if (Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)) { if (Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug)) {
m_OverlayFont->DrawTextA(nullptr, m_OverlayFont->DrawTextA(nullptr,
Session::get()->getOverlayManager().getOverlayText(OverlayManager::OverlayDebug), Session::get()->getOverlayManager().getOverlayText(Overlay::OverlayDebug),
-1, -1,
&sample.DstRect, &sample.DstRect,
DT_LEFT | DT_NOCLIP, DT_LEFT | DT_NOCLIP,

View File

@ -2,11 +2,13 @@
#include <SDL.h> #include <SDL.h>
#include "streaming/video/overlaymanager.h"
extern "C" { extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
} }
class IFFmpegRenderer { class IFFmpegRenderer : public Overlay::IOverlayRenderer {
public: public:
enum FramePacingConstraint { enum FramePacingConstraint {
PACING_FORCE_OFF, PACING_FORCE_OFF,
@ -14,7 +16,6 @@ public:
PACING_ANY PACING_ANY
}; };
virtual ~IFFmpegRenderer() {}
virtual bool initialize(SDL_Window* window, virtual bool initialize(SDL_Window* window,
int videoFormat, int videoFormat,
int width, int width,
@ -26,6 +27,11 @@ public:
virtual bool needsTestFrame() = 0; virtual bool needsTestFrame() = 0;
virtual int getDecoderCapabilities() = 0; virtual int getDecoderCapabilities() = 0;
virtual FramePacingConstraint getFramePacingConstraint() = 0; virtual FramePacingConstraint getFramePacingConstraint() = 0;
// IOverlayRenderer
virtual void notifyOverlayUpdated(Overlay::OverlayType) override {
// Nothing
}
}; };
class SdlRenderer : public IFFmpegRenderer { class SdlRenderer : public IFFmpegRenderer {

View File

@ -103,6 +103,10 @@ void FFmpegVideoDecoder::reset()
// need to delete in the renderer destructor. // need to delete in the renderer destructor.
avcodec_free_context(&m_VideoDecoderCtx); avcodec_free_context(&m_VideoDecoderCtx);
if (!m_TestOnly) {
Session::get()->getOverlayManager().setOverlayRenderer(nullptr);
}
delete m_Renderer; delete m_Renderer;
m_Renderer = nullptr; m_Renderer = nullptr;
@ -232,6 +236,9 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
else { else {
m_NeedsSpsFixup = false; m_NeedsSpsFixup = false;
} }
// Tell overlay manager to use this renderer
Session::get()->getOverlayManager().setOverlayRenderer(m_Renderer);
} }
#ifdef QT_DEBUG #ifdef QT_DEBUG
@ -508,12 +515,13 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
// Flip stats windows roughly every second // Flip stats windows roughly every second
if (SDL_TICKS_PASSED(SDL_GetTicks(), m_ActiveWndVideoStats.measurementStartTimestamp + 1000)) { if (SDL_TICKS_PASSED(SDL_GetTicks(), m_ActiveWndVideoStats.measurementStartTimestamp + 1000)) {
// Update overlay stats if it's enabled // Update overlay stats if it's enabled
if (Session::get()->getOverlayManager().isOverlayEnabled(OverlayManager::OverlayDebug)) { if (Session::get()->getOverlayManager().isOverlayEnabled(Overlay::OverlayDebug)) {
VIDEO_STATS lastTwoWndStats = {}; VIDEO_STATS lastTwoWndStats = {};
addVideoStats(m_LastWndVideoStats, lastTwoWndStats); addVideoStats(m_LastWndVideoStats, lastTwoWndStats);
addVideoStats(m_ActiveWndVideoStats, 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 // Accumulate these values into the global stats

View File

@ -1,25 +1,50 @@
#include "overlaymanager.h" #include "overlaymanager.h"
OverlayManager::OverlayManager() using namespace Overlay;
OverlayManager::OverlayManager() :
m_Renderer(nullptr)
{ {
memset(m_Overlays, 0, sizeof(m_Overlays)); memset(m_Overlays, 0, sizeof(m_Overlays));
} }
bool OverlayManager::isOverlayEnabled(OverlayManager::OverlayType type) bool OverlayManager::isOverlayEnabled(OverlayType type)
{ {
return m_Overlays[type].enabled; return m_Overlays[type].enabled;
} }
char* OverlayManager::getOverlayText(OverlayType type) char* OverlayManager::getOverlayText(OverlayType type)
{ {
return m_Overlays[type].text; return m_Overlays[type].text;
} }
void OverlayManager::setOverlayState(OverlayManager::OverlayType type, bool enabled) void OverlayManager::setOverlayTextUpdated(OverlayType type)
{ {
m_Overlays[type].enabled = enabled; // Only update the overlay state if it's enabled. If it's not enabled,
if (!enabled) { // the renderer has already been notified by setOverlayState().
// Set the text to empty string on disable if (m_Overlays[type].enabled && m_Renderer != nullptr) {
m_Overlays[type].text[0] = 0; 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;
}

View File

@ -2,25 +2,40 @@
#include <QString> #include <QString>
namespace Overlay {
enum OverlayType {
OverlayDebug,
OverlayMinorNotification,
OverlayMajorNotification,
OverlayMax
};
class IOverlayRenderer
{
public:
virtual ~IOverlayRenderer() = default;
virtual void notifyOverlayUpdated(OverlayType type) = 0;
};
class OverlayManager class OverlayManager
{ {
public: public:
enum OverlayType {
OverlayDebug,
OverlayMinorNotification,
OverlayMajorNotification,
OverlayMax
};
OverlayManager(); OverlayManager();
bool isOverlayEnabled(OverlayType type); bool isOverlayEnabled(OverlayType type);
char* getOverlayText(OverlayType type); char* getOverlayText(OverlayType type);
void setOverlayTextUpdated(OverlayType type);
void setOverlayState(OverlayType type, bool enabled); void setOverlayState(OverlayType type, bool enabled);
void setOverlayRenderer(IOverlayRenderer* renderer);
struct { struct {
bool enabled; bool enabled;
int updateSeq;
char text[512]; char text[512];
} m_Overlays[OverlayMax]; } m_Overlays[OverlayMax];
IOverlayRenderer* m_Renderer;
}; };
}