vlc | branch: master | Romain Vimont <ro...@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 <aja...@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; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits