[vlc-devel] [PATCH v2 01/13] opengl: explicit texture scaling computation

Alexandre Janniaux ajanni at videolabs.io
Thu Apr 1 15:57:04 UTC 2021


Hi,

I´m not sure I understand this patch completely.
The explanation in the comment makes perfect sense, and is
quite depicted here by the SEMIPLANAR fourcc macro:

    #define SEMIPLANAR(w_den, h_den, size, bits) \
        { .plane_count = 2, \
          .p = { {.w = {1,    1}, .h = {1,    1}}, \
                 {.w = {2,w_den}, .h = {1,h_den}} }, \
          .pixel_size = size, \
          .pixel_bits = bits }

But then, the width will always have 2 at this location
for SEMIPLANAR descriptions and we don´t need the more
general DivideRationalByTwo macro?

Regards,
--
Alexandre Janniaux
Videolabs

On Tue, Mar 30, 2021 at 01:13:59PM +0200, Romain Vimont wrote:
> 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.31.0
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list