[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