Refactor parameter passing to decoders and split backend/decode-only and frontend renderers

This commit is contained in:
Cameron Gutman
2019-04-11 22:27:20 -07:00
parent 9dcd770df2
commit 25e5175c54
16 changed files with 173 additions and 168 deletions
@@ -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;
}
+1 -6
View File
@@ -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;
+37 -12
View File
@@ -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());
+1 -6
View File
@@ -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());
+1 -6
View File
@@ -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();
+4 -9
View File
@@ -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());