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");
// 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.

View File

@ -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;

View File

@ -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,

View File

@ -2,11 +2,13 @@
#include <SDL.h>
#include "streaming/video/overlaymanager.h"
extern "C" {
#include <libavcodec/avcodec.h>
}
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 {

View File

@ -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

View File

@ -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;
}

View File

@ -2,25 +2,40 @@
#include <QString>
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;
};
}