[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