Switch EGLRenderer to the shared functions for CSC matrix generation and chroma co-siting

This commit is contained in:
Cameron Gutman 2025-11-05 22:27:31 -06:00
commit 7f7cc89e61
3 changed files with 22 additions and 65 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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<float, 9> m_PremultipliedColorMatrix;
std::array<float, 3> m_YuvOffsets;
std::array<float, 2> m_ChromaOffset;
int m_ShaderProgramParams[5];
#define OVERLAY_PARAM_TEXTURE 0
int m_OverlayShaderProgramParams[1];