[vlc-devel] [PATCH 01/13] opengl: explicit texture scaling computation
Romain Vimont
rom1v at videolabs.io
Fri Mar 5 13:34:38 UTC 2021
In OpenGL, some values of picture planes scaling are hardcoded, and
might differ from the values provided by in a vlc_chroma_description_t.
Make the computation explicit and explain why.
---
modules/video_output/opengl/interop.c | 53 ++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 9 deletions(-)
diff --git a/modules/video_output/opengl/interop.c b/modules/video_output/opengl/interop.c
index d9b74441ff..18273d6fea 100644
--- a/modules/video_output/opengl/interop.c
+++ b/modules/video_output/opengl/interop.c
@@ -204,6 +204,14 @@ static int GetTexFormatSize(const opengl_vtable_t *vt, int target,
return size > 0 ? size * mul : size;
}
+static inline void
+DivideRationalByTwo(vlc_rational_t *r) {
+ if (r->num % 2 == 0)
+ r->num /= 2;
+ else
+ r->den *= 2;
+}
+
static int
interop_yuv_base_init(struct vlc_gl_interop *interop, GLenum tex_target,
vlc_fourcc_t chroma,
@@ -273,12 +281,14 @@ interop_yuv_base_init(struct vlc_gl_interop *interop, GLenum tex_target,
if (desc->pixel_size == 1)
{
interop->texs[0] = (struct vlc_gl_tex_cfg) {
- { 1, 1 }, { 1, 1 }, oneplane_texfmt, oneplane_texfmt,
- GL_UNSIGNED_BYTE
+ { desc->p[0].w.num, desc->p[0].w.den },
+ { desc->p[0].h.num, desc->p[0].h.den },
+ oneplane_texfmt, oneplane_texfmt, GL_UNSIGNED_BYTE
};
interop->texs[1] = (struct vlc_gl_tex_cfg) {
- { 1, 2 }, { 1, 2 }, twoplanes_texfmt, twoplanes_texfmt,
- GL_UNSIGNED_BYTE
+ { desc->p[1].w.num, desc->p[1].w.den },
+ { desc->p[1].h.num, desc->p[1].h.den },
+ twoplanes_texfmt, twoplanes_texfmt, GL_UNSIGNED_BYTE
};
}
else if (desc->pixel_size == 2)
@@ -288,24 +298,49 @@ interop_yuv_base_init(struct vlc_gl_interop *interop, GLenum tex_target,
twoplanes16_texfmt, GL_UNSIGNED_SHORT) != 16)
return VLC_EGENERIC;
interop->texs[0] = (struct vlc_gl_tex_cfg) {
- { 1, 1 }, { 1, 1 }, oneplane16_texfmt, oneplane_texfmt,
- GL_UNSIGNED_SHORT
+ { desc->p[0].w.num, desc->p[0].w.den },
+ { desc->p[0].h.num, desc->p[0].h.den },
+ oneplane16_texfmt, oneplane_texfmt, GL_UNSIGNED_SHORT
};
interop->texs[1] = (struct vlc_gl_tex_cfg) {
- { 1, 2 }, { 1, 2 }, twoplanes16_texfmt, twoplanes_texfmt,
- GL_UNSIGNED_SHORT
+ { desc->p[1].w.num, desc->p[1].w.den },
+ { desc->p[1].h.num, desc->p[1].h.den },
+ twoplanes16_texfmt, twoplanes_texfmt, GL_UNSIGNED_SHORT
};
}
else
return VLC_EGENERIC;
+
+ /*
+ * If plane_count == 2, then the chroma is semiplanar: the U and V
+ * planes are packed in the second plane. As a consequence, the
+ * horizontal scaling, as reported in the vlc_chroma_description_t, is
+ * doubled.
+ *
+ * But once imported as an OpenGL texture, both components are stored
+ * in a single texel (the two first components of the vec4).
+ * Therefore, from OpenGL, the width is not doubled, so the horizontal
+ * scaling must be divided by 2 to compensate.
+ */
+ DivideRationalByTwo(&interop->texs[1].w);
}
else if (desc->plane_count == 1)
{
+ /* Only YUV 4:2:2 formats */
/* Y1 U Y2 V fits in R G B A */
interop->tex_count = 1;
interop->texs[0] = (struct vlc_gl_tex_cfg) {
- { 1, 2 }, { 1, 1 }, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE
+ { desc->p[0].w.num, desc->p[0].w.den },
+ { desc->p[0].h.num, desc->p[0].h.den },
+ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE
};
+
+ /*
+ * Currently, Y2 is ignored, so the texture is stored at chroma
+ * resolution. In other words, half the horizontal resolution is lost,
+ * so we must adapt the horizontal scaling.
+ */
+ DivideRationalByTwo(&interop->texs[0].w);
}
else
return VLC_EGENERIC;
--
2.30.1
More information about the vlc-devel
mailing list