mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-04 00:36:36 +00:00
Refactor parameter passing to decoders and split backend/decode-only and frontend renderers
This commit is contained in:
parent
9dcd770df2
commit
25e5175c54
@ -143,19 +143,28 @@ void Session::clConnectionStatusUpdate(int connectionStatus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CALL_INITIALIZE(dec) (dec)->initialize(vds, window, videoFormat, width, height, frameRate, enableVsync, enableFramePacing)
|
|
||||||
|
|
||||||
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
SDL_Window* window, int videoFormat, int width, int height,
|
SDL_Window* window, int videoFormat, int width, int height,
|
||||||
int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder)
|
int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder)
|
||||||
{
|
{
|
||||||
|
DECODER_PARAMETERS params;
|
||||||
|
|
||||||
|
params.width = width;
|
||||||
|
params.height = height;
|
||||||
|
params.frameRate = frameRate;
|
||||||
|
params.videoFormat = videoFormat;
|
||||||
|
params.window = window;
|
||||||
|
params.enableVsync = enableVsync;
|
||||||
|
params.enableFramePacing = enableFramePacing;
|
||||||
|
params.vds = vds;
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"V-sync %s",
|
"V-sync %s",
|
||||||
enableVsync ? "enabled" : "disabled");
|
enableVsync ? "enabled" : "disabled");
|
||||||
|
|
||||||
#ifdef HAVE_SLVIDEO
|
#ifdef HAVE_SLVIDEO
|
||||||
chosenDecoder = new SLVideoDecoder(testOnly);
|
chosenDecoder = new SLVideoDecoder(testOnly);
|
||||||
if (CALL_INITIALIZE(chosenDecoder)) {
|
if (chosenDecoder->initialize(¶ms)) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SLVideo video decoder chosen");
|
"SLVideo video decoder chosen");
|
||||||
return true;
|
return true;
|
||||||
@ -170,7 +179,7 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
|||||||
|
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef HAVE_FFMPEG
|
||||||
chosenDecoder = new FFmpegVideoDecoder(testOnly);
|
chosenDecoder = new FFmpegVideoDecoder(testOnly);
|
||||||
if (CALL_INITIALIZE(chosenDecoder)) {
|
if (chosenDecoder->initialize(¶ms)) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"FFmpeg-based video decoder chosen");
|
"FFmpeg-based video decoder chosen");
|
||||||
return true;
|
return true;
|
||||||
|
@ -26,17 +26,22 @@ typedef struct _VIDEO_STATS {
|
|||||||
uint32_t measurementStartTimestamp;
|
uint32_t measurementStartTimestamp;
|
||||||
} VIDEO_STATS, *PVIDEO_STATS;
|
} VIDEO_STATS, *PVIDEO_STATS;
|
||||||
|
|
||||||
|
typedef struct _DECODER_PARAMETERS {
|
||||||
|
SDL_Window* window;
|
||||||
|
StreamingPreferences::VideoDecoderSelection vds;
|
||||||
|
|
||||||
|
int videoFormat;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int frameRate;
|
||||||
|
bool enableVsync;
|
||||||
|
bool enableFramePacing;
|
||||||
|
} DECODER_PARAMETERS, *PDECODER_PARAMETERS;
|
||||||
|
|
||||||
class IVideoDecoder {
|
class IVideoDecoder {
|
||||||
public:
|
public:
|
||||||
virtual ~IVideoDecoder() {}
|
virtual ~IVideoDecoder() {}
|
||||||
virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds,
|
virtual bool initialize(PDECODER_PARAMETERS params) = 0;
|
||||||
SDL_Window* window,
|
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int frameRate,
|
|
||||||
bool enableVsync,
|
|
||||||
bool enableFramePacing) = 0;
|
|
||||||
virtual bool isHardwareAccelerated() = 0;
|
virtual bool isHardwareAccelerated() = 0;
|
||||||
virtual int getDecoderCapabilities() = 0;
|
virtual int getDecoderCapabilities() = 0;
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
|
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
|
||||||
|
@ -107,7 +107,7 @@ bool DXVA2Renderer::prepareDecoderContext(AVCodecContext* context)
|
|||||||
|
|
||||||
int DXVA2Renderer::ffGetBuffer2(AVCodecContext* context, AVFrame* frame, int)
|
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);
|
frame->buf[0] = av_buffer_pool_get(me->m_Pool);
|
||||||
if (!frame->buf[0]) {
|
if (!frame->buf[0]) {
|
||||||
@ -649,11 +649,11 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync)
|
|||||||
return true;
|
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_VideoFormat = params->videoFormat;
|
||||||
m_VideoWidth = width;
|
m_VideoWidth = params->width;
|
||||||
m_VideoHeight = height;
|
m_VideoHeight = params->height;
|
||||||
|
|
||||||
RtlZeroMemory(&m_Desc, sizeof(m_Desc));
|
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.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
|
||||||
m_Desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
|
m_Desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
|
||||||
|
|
||||||
if (!initializeDevice(window, enableVsync)) {
|
if (!initializeDevice(params->window, params->enableVsync)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,12 +16,7 @@ class DXVA2Renderer : public IFFmpegRenderer
|
|||||||
public:
|
public:
|
||||||
DXVA2Renderer();
|
DXVA2Renderer();
|
||||||
virtual ~DXVA2Renderer();
|
virtual ~DXVA2Renderer();
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync) override;
|
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
||||||
virtual void renderFrame(AVFrame* frame) override;
|
virtual void renderFrame(AVFrame* frame) override;
|
||||||
virtual bool needsTestFrame() override;
|
virtual bool needsTestFrame() override;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "streaming/video/decoder.h"
|
||||||
#include "streaming/video/overlaymanager.h"
|
#include "streaming/video/overlaymanager.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -16,12 +17,7 @@ public:
|
|||||||
PACING_ANY
|
PACING_ANY
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params) = 0;
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync) = 0;
|
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
|
virtual bool prepareDecoderContext(AVCodecContext* context) = 0;
|
||||||
virtual void renderFrame(AVFrame* frame) = 0;
|
virtual void renderFrame(AVFrame* frame) = 0;
|
||||||
virtual bool needsTestFrame() = 0;
|
virtual bool needsTestFrame() = 0;
|
||||||
|
@ -144,20 +144,15 @@ bool SdlRenderer::isRenderThreadSupported()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdlRenderer::initialize(SDL_Window* window,
|
bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
|
||||||
int,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int,
|
|
||||||
bool enableVsync)
|
|
||||||
{
|
{
|
||||||
Uint32 rendererFlags = SDL_RENDERER_ACCELERATED;
|
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
|
// 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
|
// have compositors that make rendering tear-free. Linux compositor varies by distro and user
|
||||||
// configuration but doesn't seem feasible to detect here.
|
// configuration but doesn't seem feasible to detect here.
|
||||||
if (enableVsync) {
|
if (params->enableVsync) {
|
||||||
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
|
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);
|
SDL_SetHintWithPriority(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1", SDL_HINT_OVERRIDE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_Renderer = SDL_CreateRenderer(window, -1, rendererFlags);
|
m_Renderer = SDL_CreateRenderer(params->window, -1, rendererFlags);
|
||||||
if (!m_Renderer) {
|
if (!m_Renderer) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SDL_CreateRenderer() failed: %s",
|
"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
|
// The window may be smaller than the stream size, so ensure our
|
||||||
// logical rendering surface size is equal to the stream size
|
// 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
|
// Draw a black frame until the video stream starts rendering
|
||||||
SDL_SetRenderDrawColor(m_Renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
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,
|
m_Texture = SDL_CreateTexture(m_Renderer,
|
||||||
SDL_PIXELFORMAT_YV12,
|
SDL_PIXELFORMAT_YV12,
|
||||||
SDL_TEXTUREACCESS_STREAMING,
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
width,
|
params->width,
|
||||||
height);
|
params->height);
|
||||||
if (!m_Texture) {
|
if (!m_Texture) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SDL_CreateRenderer() failed: %s",
|
"SDL_CreateRenderer() failed: %s",
|
||||||
@ -252,6 +247,32 @@ void SdlRenderer::renderOverlay(Overlay::OverlayType type)
|
|||||||
|
|
||||||
void SdlRenderer::renderFrame(AVFrame* frame)
|
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,
|
SDL_UpdateYUVTexture(m_Texture, nullptr,
|
||||||
frame->data[0],
|
frame->data[0],
|
||||||
frame->linesize[0],
|
frame->linesize[0],
|
||||||
@ -271,4 +292,8 @@ void SdlRenderer::renderFrame(AVFrame* frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderPresent(m_Renderer);
|
SDL_RenderPresent(m_Renderer);
|
||||||
|
|
||||||
|
if (swFrame != nullptr) {
|
||||||
|
av_frame_free(&swFrame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,7 @@ class SdlRenderer : public IFFmpegRenderer {
|
|||||||
public:
|
public:
|
||||||
SdlRenderer();
|
SdlRenderer();
|
||||||
virtual ~SdlRenderer() override;
|
virtual ~SdlRenderer() override;
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync) override;
|
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
||||||
virtual void renderFrame(AVFrame* frame) override;
|
virtual void renderFrame(AVFrame* frame) override;
|
||||||
virtual bool needsTestFrame() override;
|
virtual bool needsTestFrame() override;
|
||||||
|
@ -29,19 +29,19 @@ VAAPIRenderer::~VAAPIRenderer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VAAPIRenderer::initialize(SDL_Window* window, int, int width, int height, int, bool)
|
VAAPIRenderer::initialize(PDECODER_PARAMETERS params)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
SDL_SysWMinfo info;
|
SDL_SysWMinfo info;
|
||||||
|
|
||||||
m_VideoWidth = width;
|
m_VideoWidth = params->width;
|
||||||
m_VideoHeight = height;
|
m_VideoHeight = params->height;
|
||||||
|
|
||||||
SDL_GetWindowSize(window, &m_DisplayWidth, &m_DisplayHeight);
|
SDL_GetWindowSize(params->window, &m_DisplayWidth, &m_DisplayHeight);
|
||||||
|
|
||||||
SDL_VERSION(&info.version);
|
SDL_VERSION(&info.version);
|
||||||
|
|
||||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SDL_GetWindowWMInfo() failed: %s",
|
"SDL_GetWindowWMInfo() failed: %s",
|
||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
|
@ -30,12 +30,7 @@ class VAAPIRenderer : public IFFmpegRenderer
|
|||||||
public:
|
public:
|
||||||
VAAPIRenderer();
|
VAAPIRenderer();
|
||||||
virtual ~VAAPIRenderer();
|
virtual ~VAAPIRenderer();
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params);
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync);
|
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrame(AVFrame* frame);
|
virtual void renderFrame(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
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;
|
int err;
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
SDL_SysWMinfo info;
|
SDL_SysWMinfo info;
|
||||||
|
|
||||||
m_VideoWidth = width;
|
m_VideoWidth = params->width;
|
||||||
m_VideoHeight = height;
|
m_VideoHeight = params->height;
|
||||||
|
|
||||||
err = av_hwdevice_ctx_create(&m_HwContext,
|
err = av_hwdevice_ctx_create(&m_HwContext,
|
||||||
AV_HWDEVICE_TYPE_VDPAU,
|
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_VIDEO_SURFACE_GET_PARAMETERS, &m_VdpVideoSurfaceGetParameters);
|
||||||
GET_PROC_ADDRESS(VDP_FUNC_ID_GET_INFORMATION_STRING, &m_VdpGetInformationString);
|
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);
|
SDL_VERSION(&info.version);
|
||||||
|
|
||||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SDL_GetWindowWMInfo() failed: %s",
|
"SDL_GetWindowWMInfo() failed: %s",
|
||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
|
@ -13,12 +13,7 @@ class VDPAURenderer : public IFFmpegRenderer
|
|||||||
public:
|
public:
|
||||||
VDPAURenderer();
|
VDPAURenderer();
|
||||||
virtual ~VDPAURenderer();
|
virtual ~VDPAURenderer();
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params);
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync);
|
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context);
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
virtual void renderFrame(AVFrame* frame);
|
virtual void renderFrame(AVFrame* frame);
|
||||||
virtual bool needsTestFrame();
|
virtual bool needsTestFrame();
|
||||||
|
@ -106,16 +106,11 @@ public:
|
|||||||
CFRelease(sampleBuffer);
|
CFRelease(sampleBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool initialize(SDL_Window* window,
|
virtual bool initialize(PDECODER_PARAMETERS params) override
|
||||||
int videoFormat,
|
|
||||||
int,
|
|
||||||
int,
|
|
||||||
int,
|
|
||||||
bool) override
|
|
||||||
{
|
{
|
||||||
int err;
|
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
|
// Prior to 10.13, we'll just assume everything has
|
||||||
// H.264 support and fail open to allow VT decode.
|
// H.264 support and fail open to allow VT decode.
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
|
||||||
@ -133,7 +128,7 @@ public:
|
|||||||
"Assuming H.264 HW decode on < macOS 10.13");
|
"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 __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
|
||||||
if (__builtin_available(macOS 10.13, *)) {
|
if (__builtin_available(macOS 10.13, *)) {
|
||||||
if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) {
|
if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC)) {
|
||||||
@ -156,7 +151,7 @@ public:
|
|||||||
|
|
||||||
SDL_VERSION(&info.version);
|
SDL_VERSION(&info.version);
|
||||||
|
|
||||||
if (!SDL_GetWindowWMInfo(window, &info)) {
|
if (!SDL_GetWindowWMInfo(params->window, &info)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"SDL_GetWindowWMInfo() failed: %s",
|
"SDL_GetWindowWMInfo() failed: %s",
|
||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
|
@ -38,7 +38,7 @@ bool FFmpegVideoDecoder::isHardwareAccelerated()
|
|||||||
|
|
||||||
int FFmpegVideoDecoder::getDecoderCapabilities()
|
int FFmpegVideoDecoder::getDecoderCapabilities()
|
||||||
{
|
{
|
||||||
return m_Renderer->getDecoderCapabilities();
|
return m_BackendRenderer->getDecoderCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AVPixelFormat FFmpegVideoDecoder::ffGetFormat(AVCodecContext* context,
|
enum AVPixelFormat FFmpegVideoDecoder::ffGetFormat(AVCodecContext* context,
|
||||||
@ -66,7 +66,8 @@ FFmpegVideoDecoder::FFmpegVideoDecoder(bool testOnly)
|
|||||||
: m_VideoDecoderCtx(nullptr),
|
: m_VideoDecoderCtx(nullptr),
|
||||||
m_DecodeBuffer(1024 * 1024, 0),
|
m_DecodeBuffer(1024 * 1024, 0),
|
||||||
m_HwDecodeCfg(nullptr),
|
m_HwDecodeCfg(nullptr),
|
||||||
m_Renderer(nullptr),
|
m_BackendRenderer(nullptr),
|
||||||
|
m_FrontendRenderer(nullptr),
|
||||||
m_ConsecutiveFailedDecodes(0),
|
m_ConsecutiveFailedDecodes(0),
|
||||||
m_Pacer(nullptr),
|
m_Pacer(nullptr),
|
||||||
m_LastFrameNumber(0),
|
m_LastFrameNumber(0),
|
||||||
@ -95,9 +96,9 @@ FFmpegVideoDecoder::~FFmpegVideoDecoder()
|
|||||||
av_log_set_level(AV_LOG_INFO);
|
av_log_set_level(AV_LOG_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFFmpegRenderer* FFmpegVideoDecoder::getRenderer()
|
IFFmpegRenderer* FFmpegVideoDecoder::getBackendRenderer()
|
||||||
{
|
{
|
||||||
return m_Renderer;
|
return m_BackendRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FFmpegVideoDecoder::reset()
|
void FFmpegVideoDecoder::reset()
|
||||||
@ -116,8 +117,14 @@ void FFmpegVideoDecoder::reset()
|
|||||||
Session::get()->getOverlayManager().setOverlayRenderer(nullptr);
|
Session::get()->getOverlayManager().setOverlayRenderer(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_Renderer;
|
// If we have a separate frontend renderer, free that first
|
||||||
m_Renderer = nullptr;
|
if (m_FrontendRenderer != m_BackendRenderer) {
|
||||||
|
delete m_FrontendRenderer;
|
||||||
|
m_FrontendRenderer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_BackendRenderer;
|
||||||
|
m_BackendRenderer = nullptr;
|
||||||
|
|
||||||
if (!m_TestOnly) {
|
if (!m_TestOnly) {
|
||||||
logVideoStats(m_GlobalVideoStats, "Global video stats");
|
logVideoStats(m_GlobalVideoStats, "Global video stats");
|
||||||
@ -128,35 +135,46 @@ void FFmpegVideoDecoder::reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* window,
|
bool FFmpegVideoDecoder::createFrontendRenderer(PDECODER_PARAMETERS params)
|
||||||
int videoFormat, int width, int height,
|
{
|
||||||
int maxFps, bool enableFramePacing, bool testFrame)
|
m_FrontendRenderer = m_BackendRenderer;
|
||||||
|
|
||||||
|
// Determine whether the frontend renderer prefers frame pacing
|
||||||
|
auto vsyncConstraint = m_FrontendRenderer->getFramePacingConstraint();
|
||||||
|
if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_OFF && params->enableFramePacing) {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Frame pacing is forcefully disabled by the frontend renderer");
|
||||||
|
params->enableFramePacing = false;
|
||||||
|
}
|
||||||
|
else if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_ON && !params->enableFramePacing) {
|
||||||
|
// FIXME: This duplicates logic in Session.cpp
|
||||||
|
int displayHz = StreamUtils::getDisplayRefreshRate(params->window);
|
||||||
|
if (displayHz + 5 >= params->frameRate) {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Frame pacing is forcefully enabled by the frontend renderer");
|
||||||
|
params->enableFramePacing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, PDECODER_PARAMETERS params, bool testFrame)
|
||||||
{
|
{
|
||||||
// In test-only mode, we should only see test frames
|
// In test-only mode, we should only see test frames
|
||||||
SDL_assert(!m_TestOnly || testFrame);
|
SDL_assert(!m_TestOnly || testFrame);
|
||||||
|
|
||||||
auto vsyncConstraint = m_Renderer->getFramePacingConstraint();
|
// Create the frontend renderer based on the capabilities of the backend renderer
|
||||||
if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_OFF && enableFramePacing) {
|
if (!createFrontendRenderer(params)) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
return false;
|
||||||
"Frame pacing is forcefully disabled by the active renderer");
|
|
||||||
enableFramePacing = false;
|
|
||||||
}
|
|
||||||
else if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_ON && !enableFramePacing) {
|
|
||||||
// FIXME: This duplicates logic in Session.cpp
|
|
||||||
int displayHz = StreamUtils::getDisplayRefreshRate(window);
|
|
||||||
if (displayHz + 5 >= maxFps) {
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Frame pacing is forcefully enabled by the active renderer");
|
|
||||||
enableFramePacing = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_StreamFps = maxFps;
|
m_StreamFps = params->frameRate;
|
||||||
|
|
||||||
// Don't bother initializing Pacer if we're not actually going to render
|
// Don't bother initializing Pacer if we're not actually going to render
|
||||||
if (!testFrame) {
|
if (!testFrame) {
|
||||||
m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats);
|
m_Pacer = new Pacer(m_FrontendRenderer, &m_ActiveWndVideoStats);
|
||||||
if (!m_Pacer->initialize(window, maxFps, enableFramePacing)) {
|
if (!m_Pacer->initialize(params->window, params->frameRate, params->enableFramePacing)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +194,7 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
m_VideoDecoderCtx->flags2 |= AV_CODEC_FLAG2_SHOW_ALL;
|
m_VideoDecoderCtx->flags2 |= AV_CODEC_FLAG2_SHOW_ALL;
|
||||||
|
|
||||||
// Enable slice multi-threading for software decoding
|
// Enable slice multi-threading for software decoding
|
||||||
if (!m_HwDecodeCfg) {
|
if (!isHardwareAccelerated()) {
|
||||||
m_VideoDecoderCtx->thread_type = FF_THREAD_SLICE;
|
m_VideoDecoderCtx->thread_type = FF_THREAD_SLICE;
|
||||||
m_VideoDecoderCtx->thread_count = qMin(MAX_SLICES, SDL_GetCPUCount());
|
m_VideoDecoderCtx->thread_count = qMin(MAX_SLICES, SDL_GetCPUCount());
|
||||||
}
|
}
|
||||||
@ -186,13 +204,13 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup decoding parameters
|
// Setup decoding parameters
|
||||||
m_VideoDecoderCtx->width = width;
|
m_VideoDecoderCtx->width = params->width;
|
||||||
m_VideoDecoderCtx->height = height;
|
m_VideoDecoderCtx->height = params->height;
|
||||||
m_VideoDecoderCtx->pix_fmt = AV_PIX_FMT_YUV420P; // FIXME: HDR
|
m_VideoDecoderCtx->pix_fmt = AV_PIX_FMT_YUV420P; // FIXME: HDR
|
||||||
m_VideoDecoderCtx->get_format = ffGetFormat;
|
m_VideoDecoderCtx->get_format = ffGetFormat;
|
||||||
|
|
||||||
// Allow the renderer to attach data to this decoder
|
// Allow the backend renderer to attach data to this decoder
|
||||||
if (!m_Renderer->prepareDecoderContext(m_VideoDecoderCtx)) {
|
if (!m_BackendRenderer->prepareDecoderContext(m_VideoDecoderCtx)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +225,7 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Unable to open decoder for format: %x",
|
"Unable to open decoder for format: %x",
|
||||||
videoFormat);
|
params->videoFormat);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +235,7 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
// now to see if things will actually work when the video stream
|
// now to see if things will actually work when the video stream
|
||||||
// comes in.
|
// comes in.
|
||||||
if (testFrame) {
|
if (testFrame) {
|
||||||
if (videoFormat & VIDEO_FORMAT_MASK_H264) {
|
if (params->videoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
m_Pkt.data = (uint8_t*)k_H264TestFrame;
|
m_Pkt.data = (uint8_t*)k_H264TestFrame;
|
||||||
m_Pkt.size = sizeof(k_H264TestFrame);
|
m_Pkt.size = sizeof(k_H264TestFrame);
|
||||||
}
|
}
|
||||||
@ -236,8 +254,8 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((videoFormat & VIDEO_FORMAT_MASK_H264) &&
|
if ((params->videoFormat & VIDEO_FORMAT_MASK_H264) &&
|
||||||
!(m_Renderer->getDecoderCapabilities() & CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC)) {
|
!(m_BackendRenderer->getDecoderCapabilities() & CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC)) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Using H.264 SPS fixup");
|
"Using H.264 SPS fixup");
|
||||||
m_NeedsSpsFixup = true;
|
m_NeedsSpsFixup = true;
|
||||||
@ -246,8 +264,8 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi
|
|||||||
m_NeedsSpsFixup = false;
|
m_NeedsSpsFixup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell overlay manager to use this renderer
|
// Tell overlay manager to use this frontend renderer
|
||||||
Session::get()->getOverlayManager().setOverlayRenderer(m_Renderer);
|
Session::get()->getOverlayManager().setOverlayRenderer(m_FrontendRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -361,25 +379,17 @@ IFFmpegRenderer* FFmpegVideoDecoder::createAcceleratedRenderer(const AVCodecHWCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FFmpegVideoDecoder::initialize(
|
bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||||
StreamingPreferences::VideoDecoderSelection vds,
|
|
||||||
SDL_Window* window,
|
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync,
|
|
||||||
bool enableFramePacing)
|
|
||||||
{
|
{
|
||||||
AVCodec* decoder;
|
AVCodec* decoder;
|
||||||
|
|
||||||
// Increase log level until the first frame is decoded
|
// Increase log level until the first frame is decoded
|
||||||
av_log_set_level(AV_LOG_DEBUG);
|
av_log_set_level(AV_LOG_DEBUG);
|
||||||
|
|
||||||
if (videoFormat & VIDEO_FORMAT_MASK_H264) {
|
if (params->videoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
decoder = avcodec_find_decoder(AV_CODEC_ID_H264);
|
decoder = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||||
}
|
}
|
||||||
else if (videoFormat & VIDEO_FORMAT_MASK_H265) {
|
else if (params->videoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
decoder = avcodec_find_decoder(AV_CODEC_ID_HEVC);
|
decoder = avcodec_find_decoder(AV_CODEC_ID_HEVC);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -390,20 +400,20 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
if (!decoder) {
|
if (!decoder) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Unable to find decoder for format: %x",
|
"Unable to find decoder for format: %x",
|
||||||
videoFormat);
|
params->videoFormat);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; i++) {
|
||||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||||
if (!config || vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
if (!config || params->vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||||
// No matching hardware acceleration support.
|
// No matching hardware acceleration support.
|
||||||
// This is not an error.
|
// This is not an error.
|
||||||
m_HwDecodeCfg = nullptr;
|
m_HwDecodeCfg = nullptr;
|
||||||
m_Renderer = new SdlRenderer();
|
m_BackendRenderer = new SdlRenderer();
|
||||||
if (vds != StreamingPreferences::VDS_FORCE_HARDWARE &&
|
if (params->vds != StreamingPreferences::VDS_FORCE_HARDWARE &&
|
||||||
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
m_BackendRenderer->initialize(params) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_TestOnly)) {
|
completeInitialization(decoder, params, m_TestOnly)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -412,27 +422,27 @@ bool FFmpegVideoDecoder::initialize(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Renderer = createAcceleratedRenderer(config);
|
m_BackendRenderer = createAcceleratedRenderer(config);
|
||||||
if (!m_Renderer) {
|
if (!m_BackendRenderer) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_HwDecodeCfg = config;
|
m_HwDecodeCfg = config;
|
||||||
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
||||||
if (m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
if (m_BackendRenderer->initialize(params) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_TestOnly || m_Renderer->needsTestFrame())) {
|
completeInitialization(decoder, params, m_TestOnly || m_BackendRenderer->needsTestFrame())) {
|
||||||
if (m_TestOnly) {
|
if (m_TestOnly) {
|
||||||
// This decoder is only for testing capabilities, so don't bother
|
// This decoder is only for testing capabilities, so don't bother
|
||||||
// creating a usable renderer
|
// creating a usable renderer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Renderer->needsTestFrame()) {
|
if (m_BackendRenderer->needsTestFrame()) {
|
||||||
// The test worked, so now let's initialize it for real
|
// The test worked, so now let's initialize it for real
|
||||||
reset();
|
reset();
|
||||||
if ((m_Renderer = createAcceleratedRenderer(config)) != nullptr &&
|
if ((m_BackendRenderer = createAcceleratedRenderer(config)) != nullptr &&
|
||||||
m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) &&
|
m_BackendRenderer->initialize(params) &&
|
||||||
completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, false)) {
|
completeInitialization(decoder, params, false)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -12,25 +12,16 @@ class FFmpegVideoDecoder : public IVideoDecoder {
|
|||||||
public:
|
public:
|
||||||
FFmpegVideoDecoder(bool testOnly);
|
FFmpegVideoDecoder(bool testOnly);
|
||||||
virtual ~FFmpegVideoDecoder() override;
|
virtual ~FFmpegVideoDecoder() override;
|
||||||
virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds,
|
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
||||||
SDL_Window* window,
|
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int maxFps,
|
|
||||||
bool enableVsync,
|
|
||||||
bool enableFramePacing) override;
|
|
||||||
virtual bool isHardwareAccelerated() override;
|
virtual bool isHardwareAccelerated() override;
|
||||||
virtual int getDecoderCapabilities() override;
|
virtual int getDecoderCapabilities() override;
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du) override;
|
virtual int submitDecodeUnit(PDECODE_UNIT du) override;
|
||||||
virtual void renderFrameOnMainThread() override;
|
virtual void renderFrameOnMainThread() override;
|
||||||
|
|
||||||
virtual IFFmpegRenderer* getRenderer();
|
virtual IFFmpegRenderer* getBackendRenderer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool completeInitialization(AVCodec* decoder, SDL_Window* window,
|
bool completeInitialization(AVCodec* decoder, PDECODER_PARAMETERS params, bool testFrame);
|
||||||
int videoFormat, int width, int height,
|
|
||||||
int maxFps, bool enableFramePacing, bool testFrame);
|
|
||||||
|
|
||||||
void stringifyVideoStats(VIDEO_STATS& stats, char* output);
|
void stringifyVideoStats(VIDEO_STATS& stats, char* output);
|
||||||
|
|
||||||
@ -38,6 +29,8 @@ private:
|
|||||||
|
|
||||||
void addVideoStats(VIDEO_STATS& src, VIDEO_STATS& dst);
|
void addVideoStats(VIDEO_STATS& src, VIDEO_STATS& dst);
|
||||||
|
|
||||||
|
bool createFrontendRenderer(PDECODER_PARAMETERS params);
|
||||||
|
|
||||||
IFFmpegRenderer* createAcceleratedRenderer(const AVCodecHWConfig* hwDecodeCfg);
|
IFFmpegRenderer* createAcceleratedRenderer(const AVCodecHWConfig* hwDecodeCfg);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -52,7 +45,8 @@ private:
|
|||||||
AVCodecContext* m_VideoDecoderCtx;
|
AVCodecContext* m_VideoDecoderCtx;
|
||||||
QByteArray m_DecodeBuffer;
|
QByteArray m_DecodeBuffer;
|
||||||
const AVCodecHWConfig* m_HwDecodeCfg;
|
const AVCodecHWConfig* m_HwDecodeCfg;
|
||||||
IFFmpegRenderer* m_Renderer;
|
IFFmpegRenderer* m_BackendRenderer;
|
||||||
|
IFFmpegRenderer* m_FrontendRenderer;
|
||||||
int m_ConsecutiveFailedDecodes;
|
int m_ConsecutiveFailedDecodes;
|
||||||
Pacer* m_Pacer;
|
Pacer* m_Pacer;
|
||||||
VIDEO_STATS m_ActiveWndVideoStats;
|
VIDEO_STATS m_ActiveWndVideoStats;
|
||||||
|
@ -32,17 +32,15 @@ SLVideoDecoder::getDecoderCapabilities()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
SLVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||||
SDL_Window*,
|
|
||||||
int videoFormat, int, int, int frameRate, bool, bool)
|
|
||||||
{
|
{
|
||||||
// SLVideo only supports hardware decoding
|
// SLVideo only supports hardware decoding
|
||||||
if (vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
if (params->vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SLVideo only supports H.264
|
// SLVideo only supports H.264
|
||||||
if (videoFormat != VIDEO_FORMAT_H264) {
|
if (params->videoFormat != VIDEO_FORMAT_H264) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLVideo_SetStreamTargetFramerate(m_VideoStream, frameRate, 1);
|
SLVideo_SetStreamTargetFramerate(m_VideoStream, params->frameRate, 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,7 @@ class SLVideoDecoder : public IVideoDecoder
|
|||||||
public:
|
public:
|
||||||
SLVideoDecoder(bool testOnly);
|
SLVideoDecoder(bool testOnly);
|
||||||
virtual ~SLVideoDecoder();
|
virtual ~SLVideoDecoder();
|
||||||
virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds,
|
virtual bool initialize(PDECODER_PARAMETERS params);
|
||||||
SDL_Window* window,
|
|
||||||
int videoFormat,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int frameRate,
|
|
||||||
bool enableVsync,
|
|
||||||
bool enableFramePacing);
|
|
||||||
virtual bool isHardwareAccelerated();
|
virtual bool isHardwareAccelerated();
|
||||||
virtual int getDecoderCapabilities();
|
virtual int getDecoderCapabilities();
|
||||||
virtual int submitDecodeUnit(PDECODE_UNIT du);
|
virtual int submitDecodeUnit(PDECODE_UNIT du);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user