Allow renderers to apply size and display changes seamlessly

This commit is contained in:
Cameron Gutman
2022-04-24 15:42:08 -05:00
parent 6c339551eb
commit c989133d27
8 changed files with 106 additions and 15 deletions
+6
View File
@@ -58,6 +58,11 @@ typedef struct _DECODER_PARAMETERS {
HDR_MASTERING_METADATA hdrMetadata;
} DECODER_PARAMETERS, *PDECODER_PARAMETERS;
// Flags for applyWindowChange()
#define WINDOW_SIZE_CHANGED 0x01
#define WINDOW_DISPLAY_CHANGED 0x02
class IVideoDecoder {
public:
virtual ~IVideoDecoder() {}
@@ -71,4 +76,5 @@ public:
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
virtual void renderFrameOnMainThread() = 0;
virtual void setHdrMode(bool enabled) = 0;
virtual bool applyWindowChange(int width, int height, int flags) = 0;
};
@@ -167,6 +167,12 @@ public:
return true;
}
virtual bool applyWindowChange(int, int, int) {
// By default, we cannot apply any changes. The renderer
// will be recreated after any window change.
return false;
}
virtual AVPixelFormat getPreferredPixelFormat(int videoFormat) {
if (videoFormat == VIDEO_FORMAT_H265_MAIN10) {
// 10-bit YUV 4:2:0
+30 -12
View File
@@ -91,6 +91,8 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
Uint32 rendererFlags = SDL_RENDERER_ACCELERATED;
m_VideoFormat = params->videoFormat;
m_VideoWidth = params->width;
m_VideoHeight = params->height;
if (params->videoFormat == VIDEO_FORMAT_H265_MAIN10) {
// SDL doesn't support rendering YUV 10-bit textures yet
@@ -139,18 +141,8 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
SDL_FlushEvent(SDL_WINDOWEVENT);
}
// Calculate the video region size, scaling to fill the output size while
// preserving the aspect ratio of the video stream.
SDL_Rect src, dst;
src.x = src.y = 0;
src.w = params->width;
src.h = params->height;
dst.x = dst.y = 0;
SDL_GetRendererOutputSize(m_Renderer, &dst.w, &dst.h);
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
// Ensure the viewport is set to the desired video region
SDL_RenderSetViewport(m_Renderer, &dst);
// Set the renderer viewport to draw the video while preserving aspect ratio
updateViewport();
// Draw a black frame until the video stream starts rendering
SDL_SetRenderDrawColor(m_Renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
@@ -339,6 +331,22 @@ AVFrame* SdlRenderer::getSwFrameFromHwFrame(AVFrame* hwFrame)
return swFrame;
}
void SdlRenderer::updateViewport()
{
// Calculate the video region size, scaling to fill the output size while
// preserving the aspect ratio of the video stream.
SDL_Rect src, dst;
src.x = src.y = 0;
src.w = m_VideoWidth;
src.h = m_VideoHeight;
dst.x = dst.y = 0;
SDL_GetRendererOutputSize(m_Renderer, &dst.w, &dst.h);
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
// Ensure the viewport is set to the desired video region
SDL_RenderSetViewport(m_Renderer, &dst);
}
void SdlRenderer::renderFrame(AVFrame* frame)
{
int err;
@@ -580,3 +588,13 @@ bool SdlRenderer::testRenderFrame(AVFrame* frame)
return true;
}
bool SdlRenderer::applyWindowChange(int, int, int flags)
{
if (flags == WINDOW_SIZE_CHANGED) {
updateViewport();
return true;
}
return false;
}
@@ -16,13 +16,17 @@ public:
virtual bool isRenderThreadSupported() override;
virtual bool isPixelFormatSupported(int videoFormat, enum AVPixelFormat pixelFormat) override;
virtual bool testRenderFrame(AVFrame* frame) override;
virtual bool applyWindowChange(int width, int height, int flags) override;
private:
void renderOverlay(Overlay::OverlayType type);
bool initializeReadBackFormat(AVBufferRef* hwFrameCtxRef, AVFrame* testFrame);
AVFrame* getSwFrameFromHwFrame(AVFrame* hwFrame);
void updateViewport();
int m_VideoFormat;
int m_VideoWidth;
int m_VideoHeight;
SDL_Renderer* m_Renderer;
SDL_Texture* m_Texture;
enum AVPixelFormat m_SwPixelFormat;
+5
View File
@@ -68,6 +68,11 @@ void FFmpegVideoDecoder::setHdrMode(bool enabled)
m_FrontendRenderer->setHdrMode(enabled);
}
bool FFmpegVideoDecoder::applyWindowChange(int width, int height, int flags)
{
return m_FrontendRenderer->applyWindowChange(width, height, flags);
}
int FFmpegVideoDecoder::getDecoderCapabilities()
{
int capabilities = m_BackendRenderer->getDecoderCapabilities();
+1
View File
@@ -25,6 +25,7 @@ public:
virtual int submitDecodeUnit(PDECODE_UNIT du) override;
virtual void renderFrameOnMainThread() override;
virtual void setHdrMode(bool enabled) override;
virtual bool applyWindowChange(int width, int height, int flags) override;
virtual IFFmpegRenderer* getBackendRenderer();
+5
View File
@@ -26,6 +26,11 @@ public:
return false;
}
// SLVideo cannot apply any window changes (nor do we expect any)
virtual bool applyWindowChange(int, int, int) override {
return false;
}
private:
static void slLogCallback(void* context, ESLVideoLog logLevel, const char* message);