mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-19 02:52:58 +00:00
Add support for the status overlay on Steam Link
This commit is contained in:
parent
95c4a24d99
commit
197c1ba21b
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user