From 7f7cc89e61e5600c359b5ee586920a8b5449eab7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 5 Nov 2025 22:27:31 -0600 Subject: [PATCH] Switch EGLRenderer to the shared functions for CSC matrix generation and chroma co-siting --- app/shaders/egl_nv12.frag | 3 +- .../video/ffmpeg-renderers/eglvid.cpp | 72 ++++--------------- app/streaming/video/ffmpeg-renderers/eglvid.h | 12 ++-- 3 files changed, 22 insertions(+), 65 deletions(-) diff --git a/app/shaders/egl_nv12.frag b/app/shaders/egl_nv12.frag index cd1f064b..66d3a6cd 100644 --- a/app/shaders/egl_nv12.frag +++ b/app/shaders/egl_nv12.frag @@ -7,13 +7,14 @@ in vec2 vTextCoord; uniform mat3 yuvmat; uniform vec3 offset; +uniform vec2 chromaOffset; uniform samplerExternalOES plane1; uniform samplerExternalOES plane2; void main() { vec3 YCbCr = vec3( texture2D(plane1, vTextCoord)[0], - texture2D(plane2, vTextCoord).xy + texture2D(plane2, vTextCoord + chromaOffset).xy ); YCbCr -= offset; diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index 7df6677d..ac405b68 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -364,6 +364,7 @@ bool EGLRenderer::compileShaders() { m_ShaderProgramParams[NV12_PARAM_YUVMAT] = glGetUniformLocation(m_ShaderProgram, "yuvmat"); m_ShaderProgramParams[NV12_PARAM_OFFSET] = glGetUniformLocation(m_ShaderProgram, "offset"); + m_ShaderProgramParams[NV12_PARAM_CHROMA_OFFSET] = glGetUniformLocation(m_ShaderProgram, "chromaOffset"); m_ShaderProgramParams[NV12_PARAM_PLANE1] = glGetUniformLocation(m_ShaderProgram, "plane1"); m_ShaderProgramParams[NV12_PARAM_PLANE2] = glGetUniformLocation(m_ShaderProgram, "plane2"); } @@ -649,63 +650,6 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) return err == GL_NO_ERROR; } -const float *EGLRenderer::getColorOffsets(const AVFrame* frame) { - static const float limitedOffsets[] = { 16.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f }; - static const float fullOffsets[] = { 0.0f, 128.0f / 255.0f, 128.0f / 255.0f }; - - return isFrameFullRange(frame) ? fullOffsets : limitedOffsets; -} - -const float *EGLRenderer::getColorMatrix(const AVFrame* frame) { - /* The conversion matrices are shamelessly stolen from linux: - * drivers/media/platform/imx-pxp.c:pxp_setup_csc - */ - static const float bt601Lim[] = { - 1.1644f, 1.1644f, 1.1644f, - 0.0f, -0.3917f, 2.0172f, - 1.5960f, -0.8129f, 0.0f - }; - static const float bt601Full[] = { - 1.0f, 1.0f, 1.0f, - 0.0f, -0.3441f, 1.7720f, - 1.4020f, -0.7141f, 0.0f - }; - static const float bt709Lim[] = { - 1.1644f, 1.1644f, 1.1644f, - 0.0f, -0.2132f, 2.1124f, - 1.7927f, -0.5329f, 0.0f - }; - static const float bt709Full[] = { - 1.0f, 1.0f, 1.0f, - 0.0f, -0.1873f, 1.8556f, - 1.5748f, -0.4681f, 0.0f - }; - static const float bt2020Lim[] = { - 1.1644f, 1.1644f, 1.1644f, - 0.0f, -0.1874f, 2.1418f, - 1.6781f, -0.6505f, 0.0f - }; - static const float bt2020Full[] = { - 1.0f, 1.0f, 1.0f, - 0.0f, -0.1646f, 1.8814f, - 1.4746f, -0.5714f, 0.0f - }; - - bool fullRange = isFrameFullRange(frame); - switch (getFrameColorspace(frame)) { - case COLORSPACE_REC_601: - return fullRange ? bt601Full : bt601Lim; - case COLORSPACE_REC_709: - return fullRange ? bt709Full : bt709Lim; - case COLORSPACE_REC_2020: - return fullRange ? bt2020Full : bt2020Lim; - default: - SDL_assert(false); - } - - return bt601Lim; -} - bool EGLRenderer::specialize() { SDL_assert(!m_VAO); @@ -863,8 +807,18 @@ void EGLRenderer::renderFrame(AVFrame* frame) // Bind parameters for the shaders if (m_EGLImagePixelFormat == AV_PIX_FMT_NV12 || m_EGLImagePixelFormat == AV_PIX_FMT_P010) { - glUniformMatrix3fv(m_ShaderProgramParams[NV12_PARAM_YUVMAT], 1, GL_FALSE, getColorMatrix(frame)); - glUniform3fv(m_ShaderProgramParams[NV12_PARAM_OFFSET], 1, getColorOffsets(frame)); + // If the frame format has changed, we'll need to recompute the constants + if (hasFrameFormatChanged(frame)) { + getFramePremultipliedCscConstants(frame, m_PremultipliedColorMatrix, m_YuvOffsets); + + getFrameChromaCositingOffsets(frame, m_ChromaOffset); + m_ChromaOffset[0] /= frame->width; + m_ChromaOffset[1] /= frame->height; + } + + glUniformMatrix3fv(m_ShaderProgramParams[NV12_PARAM_YUVMAT], 1, GL_FALSE, m_PremultipliedColorMatrix.data()); + glUniform3fv(m_ShaderProgramParams[NV12_PARAM_OFFSET], 1, m_YuvOffsets.data()); + glUniform2fv(m_ShaderProgramParams[NV12_PARAM_CHROMA_OFFSET], 1, m_ChromaOffset.data()); glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE1], 0); glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE2], 1); } diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.h b/app/streaming/video/ffmpeg-renderers/eglvid.h index 63a0e91a..6ae79b08 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.h +++ b/app/streaming/video/ffmpeg-renderers/eglvid.h @@ -28,8 +28,6 @@ private: unsigned compileShader(const char* vertexShaderSrc, const char* fragmentShaderSrc); bool compileShaders(); bool specialize(); - const float *getColorOffsets(const AVFrame* frame); - const float *getColorMatrix(const AVFrame* frame); static int loadAndBuildShader(int shaderType, const char *filename); AVPixelFormat m_EGLImagePixelFormat; @@ -61,10 +59,14 @@ private: #define NV12_PARAM_YUVMAT 0 #define NV12_PARAM_OFFSET 1 -#define NV12_PARAM_PLANE1 2 -#define NV12_PARAM_PLANE2 3 +#define NV12_PARAM_CHROMA_OFFSET 2 +#define NV12_PARAM_PLANE1 3 +#define NV12_PARAM_PLANE2 4 #define OPAQUE_PARAM_TEXTURE 0 - int m_ShaderProgramParams[4]; + std::array m_PremultipliedColorMatrix; + std::array m_YuvOffsets; + std::array m_ChromaOffset; + int m_ShaderProgramParams[5]; #define OVERLAY_PARAM_TEXTURE 0 int m_OverlayShaderProgramParams[1];