Add support for the status overlay on Steam Link

This commit is contained in:
Cameron Gutman 2022-05-21 00:10:49 -05:00
parent 95c4a24d99
commit 197c1ba21b
2 changed files with 84 additions and 2 deletions

View File

@ -1,18 +1,30 @@
#include "slvid.h" #include "slvid.h"
#include "streaming/session.h"
SLVideoDecoder::SLVideoDecoder(bool) SLVideoDecoder::SLVideoDecoder(bool)
: m_VideoContext(nullptr), : m_VideoContext(nullptr),
m_VideoStream(nullptr) m_VideoStream(nullptr),
m_Overlay(nullptr)
{ {
SLVideo_SetLogFunction(SLVideoDecoder::slLogCallback, nullptr); SLVideo_SetLogFunction(SLVideoDecoder::slLogCallback, nullptr);
} }
SLVideoDecoder::~SLVideoDecoder() SLVideoDecoder::~SLVideoDecoder()
{ {
Session* session = Session::get();
if (session != nullptr) {
session->getOverlayManager().setOverlayRenderer(nullptr);
}
if (m_VideoStream != nullptr) { if (m_VideoStream != nullptr) {
SLVideo_FreeStream(m_VideoStream); SLVideo_FreeStream(m_VideoStream);
} }
if (m_Overlay != nullptr) {
SLVideo_HideOverlay(m_Overlay);
SLVideo_FreeOverlay(m_Overlay);
}
if (m_VideoContext != nullptr) { if (m_VideoContext != nullptr) {
SLVideo_FreeContext(m_VideoContext); SLVideo_FreeContext(m_VideoContext);
} }
@ -78,6 +90,14 @@ SLVideoDecoder::initialize(PDECODER_PARAMETERS params)
SLVideo_SetStreamVideoTransferMatrix(m_VideoStream, k_ESLVideoTransferMatrix_BT709); SLVideo_SetStreamVideoTransferMatrix(m_VideoStream, k_ESLVideoTransferMatrix_BT709);
SLVideo_SetStreamTargetFramerate(m_VideoStream, params->frameRate, 1); SLVideo_SetStreamTargetFramerate(m_VideoStream, params->frameRate, 1);
SDL_GetWindowSize(params->window, &m_ViewportWidth, &m_ViewportHeight);
// Register ourselves for overlay callbacks
Session* session = Session::get();
if (session != nullptr) {
session->getOverlayManager().setOverlayRenderer(this);
}
return true; return true;
} }
@ -126,6 +146,62 @@ SLVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
return DR_OK; return DR_OK;
} }
void SLVideoDecoder::notifyOverlayUpdated(Overlay::OverlayType type)
{
// SLVideo supports only one visible overlay at a time. Since we don't have
// stats like the FFmpeg-based decoders, we'll just support the status update
// overlay and nothing else.
if (type != Overlay::OverlayStatusUpdate) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unsupported overlay type: %d", type);
return;
}
SDL_Surface* newSurface = Session::get()->getOverlayManager().getUpdatedOverlaySurface(type);
if (newSurface == nullptr && Session::get()->getOverlayManager().isOverlayEnabled(type)) {
// There's no updated surface and the overlay is enabled, so just leave the old surface alone.
return;
}
// Hide and free any existing overlay
if (m_Overlay != nullptr) {
SLVideo_HideOverlay(m_Overlay);
SLVideo_FreeOverlay(m_Overlay);
m_Overlay = nullptr;
}
if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) {
SDL_FreeSurface(newSurface);
return;
}
m_Overlay = SLVideo_CreateOverlay(m_VideoContext, newSurface->w, newSurface->h);
if (m_Overlay == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SLVideo_CreateOverlay() failed");
return;
}
uint32_t* pixels;
int pitch;
SLVideo_GetOverlayPixels(m_Overlay, &pixels, &pitch);
// Copy surface pixels into the new overlay
SDL_ConvertPixels(newSurface->w, newSurface->h, newSurface->format->format, newSurface->pixels, newSurface->pitch,
SDL_PIXELFORMAT_ARGB8888, pixels, pitch);
// We're done with the surface now
SDL_FreeSurface(newSurface);
// Position the status overlay at the bottom left corner
float flWidth = (float)newSurface->w / m_ViewportWidth;
float flHeight = (float)newSurface->h / m_ViewportHeight;
SLVideo_SetOverlayDisplayArea(m_Overlay, 0.0f, 1.0f - flHeight, flWidth, flHeight);
// Show the overlay
SLVideo_ShowOverlay(m_Overlay);
}
void SLVideoDecoder::slLogCallback(void*, ESLVideoLog logLevel, const char *message) void SLVideoDecoder::slLogCallback(void*, ESLVideoLog logLevel, const char *message)
{ {
SDL_LogPriority priority; SDL_LogPriority priority;

View File

@ -1,10 +1,11 @@
#pragma once #pragma once
#include "decoder.h" #include "decoder.h"
#include "overlaymanager.h"
#include <SLVideo.h> #include <SLVideo.h>
class SLVideoDecoder : public IVideoDecoder class SLVideoDecoder : public IVideoDecoder, public Overlay::IOverlayRenderer
{ {
public: public:
SLVideoDecoder(bool testOnly); SLVideoDecoder(bool testOnly);
@ -16,6 +17,7 @@ public:
virtual int getDecoderColorspace() override; virtual int getDecoderColorspace() override;
virtual QSize getDecoderMaxResolution() override; virtual QSize getDecoderMaxResolution() override;
virtual int submitDecodeUnit(PDECODE_UNIT du) override; virtual int submitDecodeUnit(PDECODE_UNIT du) override;
virtual void notifyOverlayUpdated(Overlay::OverlayType) override;
// Unused since rendering is done directly from the decode thread // Unused since rendering is done directly from the decode thread
virtual void renderFrameOnMainThread() override {} virtual void renderFrameOnMainThread() override {}
@ -31,4 +33,8 @@ private:
CSLVideoContext* m_VideoContext; CSLVideoContext* m_VideoContext;
CSLVideoStream* m_VideoStream; CSLVideoStream* m_VideoStream;
CSLVideoOverlay* m_Overlay;
int m_ViewportWidth;
int m_ViewportHeight;
}; };