mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 06:01:12 +00:00
Refactor parameter passing to decoders and split backend/decode-only and frontend renderers
This commit is contained in:
@@ -107,7 +107,7 @@ bool DXVA2Renderer::prepareDecoderContext(AVCodecContext* context)
|
||||
|
||||
int DXVA2Renderer::ffGetBuffer2(AVCodecContext* context, AVFrame* frame, int)
|
||||
{
|
||||
DXVA2Renderer* me = (DXVA2Renderer*)((FFmpegVideoDecoder*)context->opaque)->getRenderer();
|
||||
DXVA2Renderer* me = (DXVA2Renderer*)((FFmpegVideoDecoder*)context->opaque)->getBackendRenderer();
|
||||
|
||||
frame->buf[0] = av_buffer_pool_get(me->m_Pool);
|
||||
if (!frame->buf[0]) {
|
||||
@@ -649,11 +649,11 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, int height, int, bool enableVsync)
|
||||
bool DXVA2Renderer::initialize(PDECODER_PARAMETERS params)
|
||||
{
|
||||
m_VideoFormat = videoFormat;
|
||||
m_VideoWidth = width;
|
||||
m_VideoHeight = height;
|
||||
m_VideoFormat = params->videoFormat;
|
||||
m_VideoWidth = params->width;
|
||||
m_VideoHeight = params->height;
|
||||
|
||||
RtlZeroMemory(&m_Desc, sizeof(m_Desc));
|
||||
|
||||
@@ -682,7 +682,7 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i
|
||||
m_Desc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
|
||||
m_Desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
|
||||
|
||||
if (!initializeDevice(window, enableVsync)) {
|
||||
if (!initializeDevice(params->window, params->enableVsync)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,7 @@ class DXVA2Renderer : public IFFmpegRenderer
|
||||
public:
|
||||
DXVA2Renderer();
|
||||
virtual ~DXVA2Renderer();
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int width,
|
||||
int height,
|
||||
int maxFps,
|
||||
bool enableVsync) override;
|
||||
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
||||
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
||||
virtual void renderFrame(AVFrame* frame) override;
|
||||
virtual bool needsTestFrame() override;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "streaming/video/decoder.h"
|
||||
#include "streaming/video/overlaymanager.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -16,12 +17,7 @@ public:
|
||||
PACING_ANY
|
||||
};
|
||||
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int width,
|
||||
int height,
|
||||
int maxFps,
|
||||
bool enableVsync) = 0;
|
||||
virtual bool initialize(PDECODER_PARAMETERS params) = 0;
|
||||
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
|
||||
virtual void renderFrame(AVFrame* frame) = 0;
|
||||
virtual bool needsTestFrame() = 0;
|
||||
|
||||
@@ -144,20 +144,15 @@ bool SdlRenderer::isRenderThreadSupported()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdlRenderer::initialize(SDL_Window* window,
|
||||
int,
|
||||
int width,
|
||||
int height,
|
||||
int,
|
||||
bool enableVsync)
|
||||
bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
|
||||
{
|
||||
Uint32 rendererFlags = SDL_RENDERER_ACCELERATED;
|
||||
|
||||
if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) {
|
||||
if ((SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) {
|
||||
// In full-screen exclusive mode, we enable V-sync if requested. For other modes, Windows and Mac
|
||||
// have compositors that make rendering tear-free. Linux compositor varies by distro and user
|
||||
// configuration but doesn't seem feasible to detect here.
|
||||
if (enableVsync) {
|
||||
if (params->enableVsync) {
|
||||
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
}
|
||||
@@ -170,7 +165,7 @@ bool SdlRenderer::initialize(SDL_Window* window,
|
||||
SDL_SetHintWithPriority(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1", SDL_HINT_OVERRIDE);
|
||||
#endif
|
||||
|
||||
m_Renderer = SDL_CreateRenderer(window, -1, rendererFlags);
|
||||
m_Renderer = SDL_CreateRenderer(params->window, -1, rendererFlags);
|
||||
if (!m_Renderer) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_CreateRenderer() failed: %s",
|
||||
@@ -180,7 +175,7 @@ bool SdlRenderer::initialize(SDL_Window* window,
|
||||
|
||||
// The window may be smaller than the stream size, so ensure our
|
||||
// logical rendering surface size is equal to the stream size
|
||||
SDL_RenderSetLogicalSize(m_Renderer, width, height);
|
||||
SDL_RenderSetLogicalSize(m_Renderer, params->width, params->height);
|
||||
|
||||
// Draw a black frame until the video stream starts rendering
|
||||
SDL_SetRenderDrawColor(m_Renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
@@ -190,8 +185,8 @@ bool SdlRenderer::initialize(SDL_Window* window,
|
||||
m_Texture = SDL_CreateTexture(m_Renderer,
|
||||
SDL_PIXELFORMAT_YV12,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
width,
|
||||
height);
|
||||
params->width,
|
||||
params->height);
|
||||
if (!m_Texture) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_CreateRenderer() failed: %s",
|
||||
@@ -252,6 +247,32 @@ void SdlRenderer::renderOverlay(Overlay::OverlayType type)
|
||||
|
||||
void SdlRenderer::renderFrame(AVFrame* frame)
|
||||
{
|
||||
int err;
|
||||
AVFrame* swFrame = nullptr;
|
||||
|
||||
if (frame->hw_frames_ctx != nullptr) {
|
||||
// If we are acting as the frontend for a hardware
|
||||
// accelerated decoder, we'll need to read the frame
|
||||
// back to render it.
|
||||
|
||||
swFrame = av_frame_alloc();
|
||||
if (swFrame == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
swFrame->width = frame->width;
|
||||
swFrame->height = frame->height;
|
||||
swFrame->format = AV_PIX_FMT_YUV420P;
|
||||
|
||||
err = av_hwframe_transfer_data(swFrame, frame, 0);
|
||||
if (err != 0) {
|
||||
av_frame_free(&swFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
frame = swFrame;
|
||||
}
|
||||
|
||||
SDL_UpdateYUVTexture(m_Texture, nullptr,
|
||||
frame->data[0],
|
||||
frame->linesize[0],
|
||||
@@ -271,4 +292,8 @@ void SdlRenderer::renderFrame(AVFrame* frame)
|
||||
}
|
||||
|
||||
SDL_RenderPresent(m_Renderer);
|
||||
|
||||
if (swFrame != nullptr) {
|
||||
av_frame_free(&swFrame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,7 @@ class SdlRenderer : public IFFmpegRenderer {
|
||||
public:
|
||||
SdlRenderer();
|
||||
virtual ~SdlRenderer() override;
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int width,
|
||||
int height,
|
||||
int maxFps,
|
||||
bool enableVsync) override;
|
||||
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
||||
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
||||
virtual void renderFrame(AVFrame* frame) override;
|
||||
virtual bool needsTestFrame() override;
|
||||
|
||||
@@ -29,19 +29,19 @@ VAAPIRenderer::~VAAPIRenderer()
|
||||
}
|
||||
|
||||
bool
|
||||
VAAPIRenderer::initialize(SDL_Window* window, int, int width, int height, int, bool)
|
||||
VAAPIRenderer::initialize(PDECODER_PARAMETERS params)
|
||||
{
|
||||
int err;
|
||||
SDL_SysWMinfo info;
|
||||
|
||||
m_VideoWidth = width;
|
||||
m_VideoHeight = height;
|
||||
m_VideoWidth = params->width;
|
||||
m_VideoHeight = params->height;
|
||||
|
||||
SDL_GetWindowSize(window, &m_DisplayWidth, &m_DisplayHeight);
|
||||
SDL_GetWindowSize(params->window, &m_DisplayWidth, &m_DisplayHeight);
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
||||
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetWindowWMInfo() failed: %s",
|
||||
SDL_GetError());
|
||||
|
||||
@@ -30,12 +30,7 @@ class VAAPIRenderer : public IFFmpegRenderer
|
||||
public:
|
||||
VAAPIRenderer();
|
||||
virtual ~VAAPIRenderer();
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int width,
|
||||
int height,
|
||||
int maxFps,
|
||||
bool enableVsync);
|
||||
virtual bool initialize(PDECODER_PARAMETERS params);
|
||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||
virtual void renderFrame(AVFrame* frame);
|
||||
virtual bool needsTestFrame();
|
||||
|
||||
@@ -54,14 +54,14 @@ VDPAURenderer::~VDPAURenderer()
|
||||
}
|
||||
}
|
||||
|
||||
bool VDPAURenderer::initialize(SDL_Window* window, int, int width, int height, int, bool)
|
||||
bool VDPAURenderer::initialize(PDECODER_PARAMETERS params)
|
||||
{
|
||||
int err;
|
||||
VdpStatus status;
|
||||
SDL_SysWMinfo info;
|
||||
|
||||
m_VideoWidth = width;
|
||||
m_VideoHeight = height;
|
||||
m_VideoWidth = params->width;
|
||||
m_VideoHeight = params->height;
|
||||
|
||||
err = av_hwdevice_ctx_create(&m_HwContext,
|
||||
AV_HWDEVICE_TYPE_VDPAU,
|
||||
@@ -93,11 +93,11 @@ bool VDPAURenderer::initialize(SDL_Window* window, int, int width, int height, i
|
||||
GET_PROC_ADDRESS(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, &m_VdpVideoSurfaceGetParameters);
|
||||
GET_PROC_ADDRESS(VDP_FUNC_ID_GET_INFORMATION_STRING, &m_VdpGetInformationString);
|
||||
|
||||
SDL_GetWindowSize(window, (int*)&m_DisplayWidth, (int*)&m_DisplayHeight);
|
||||
SDL_GetWindowSize(params->window, (int*)&m_DisplayWidth, (int*)&m_DisplayHeight);
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
||||
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetWindowWMInfo() failed: %s",
|
||||
SDL_GetError());
|
||||
|
||||
@@ -13,12 +13,7 @@ class VDPAURenderer : public IFFmpegRenderer
|
||||
public:
|
||||
VDPAURenderer();
|
||||
virtual ~VDPAURenderer();
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int width,
|
||||
int height,
|
||||
int maxFps,
|
||||
bool enableVsync);
|
||||
virtual bool initialize(PDECODER_PARAMETERS params);
|
||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||
virtual void renderFrame(AVFrame* frame);
|
||||
virtual bool needsTestFrame();
|
||||
|
||||
@@ -106,16 +106,11 @@ public:
|
||||
CFRelease(sampleBuffer);
|
||||
}
|
||||
|
||||
virtual bool initialize(SDL_Window* window,
|
||||
int videoFormat,
|
||||
int,
|
||||
int,
|
||||
int,
|
||||
bool) override
|
||||
virtual bool initialize(PDECODER_PARAMETERS params) override
|
||||
{
|
||||
int err;
|
||||
|
||||
if (videoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||
if (params->videoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||
// Prior to 10.13, we'll just assume everything has
|
||||
// H.264 support and fail open to allow VT decode.
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
|
||||
@@ -133,7 +128,7 @@ public:
|
||||
"Assuming H.264 HW decode on < macOS 10.13");
|
||||
}
|
||||
}
|
||||
else if (videoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||
else if (params->videoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
|
||||
if (__builtin_available(macOS 10.13, *)) {
|
||||
if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) {
|
||||
@@ -156,7 +151,7 @@ public:
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
||||
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetWindowWMInfo() failed: %s",
|
||||
SDL_GetError());
|
||||
|
||||
Reference in New Issue
Block a user