[vlc-commits] opengl: explicit texture scaling computation
Romain Vimont
git at videolan.org
Mon Apr 12 15:28:36 UTC 2021
vlc | branch: master | Romain Vimont <rom1v at videolabs.io> | Tue Mar 30 13:13:59 2021 +0200| [fabba2aab37fe00c4d6e4ef55f806acf3e4d16a6] | committer: Alexandre Janniaux
opengl: explicit texture scaling computation
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.
Signed-off-by: Alexandre Janniaux <ajanni at videolabs.io>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fabba2aab37fe00c4d6e4ef55f806acf3e4d16a6
---
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;
More information about the vlc-commits
mailing list