[vlc-commits] [Git][videolan/vlc][master] 6 commits: orient: remove old hacks for 4:2:2 subsampling

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Tue Feb 8 19:35:57 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
aaea4c84 by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: remove old hacks for 4:2:2 subsampling

This is a relic from whence the user-specified transform could be
handled solely by the transform filter whence this code originates.
Now the display modules can accept 4:2:2 chroma subsampling *and*
handle the orientation at the same time and without silently
down-sampling the Cb and Cr components to 4:2:0.

- - - - -
295c5968 by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: factor inner loops

So far, there was one common loop for vertical flip, and six loops per
bit depth for each other (non-trivial) transform, or 19 different inner
loops in total via macro expansion.

This keeps the common loop for vertical flip and reduces the other down
to two per bit depth: transposition and horizontal flip.
Antitransposition and the three rectangular rotations are obtained by
composing the previous two transforms with vertical flips before and/or
after the main transform. Those vertical flips are achieved for "free"
by using negative strides.

- - - - -
2b74f9dd by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: remove/inline the plane functions

- - - - -
ffb7d46e by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: handle NV12

- - - - -
5ad644a3 by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: inline the mouse coordinate callbacks

They are only used in a single place nowadays, so adding a layer of
indirection is no longer useful.

- - - - -
55eaaa32 by Rémi Denis-Courmont at 2022-02-08T19:06:06+00:00
orient: remove unnecessary pointer to chroma description

This was only used to track the number of planes. We already know that
from the input (or output) picture.

- - - - -


1 changed file:

- modules/video_chroma/orient.c


Changes:

=====================================
modules/video_chroma/orient.c
=====================================
@@ -34,189 +34,147 @@
 #include <vlc_mouse.h>
 #include <vlc_picture.h>
 
-static void HFlip(int *sx, int *sy, int w, int h, int dx, int dy)
+static void vflip(void *restrict dst, ptrdiff_t dst_stride,
+                  const void *restrict src, ptrdiff_t src_stride,
+                  int width, int height, int order)
 {
-    VLC_UNUSED( h );
-    *sx = w - 1 - dx;
-    *sy = dy;
-}
-static void VFlip(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    VLC_UNUSED( w );
-    *sx = dx;
-    *sy = h - 1 - dy;
-}
-static void Transpose(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    VLC_UNUSED( h ); VLC_UNUSED( w );
-    *sx = dy;
-    *sy = dx;
-}
-static void AntiTranspose(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    *sx = h - 1 - dy;
-    *sy = w - 1 - dx;
-}
-static void R90(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    VLC_UNUSED( h );
-    *sx = dy;
-    *sy = w - 1 - dx;
-}
-static void R180(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    *sx = w - 1 - dx;
-    *sy = h - 1 - dy;
-}
-static void R270(int *sx, int *sy, int w, int h, int dx, int dy)
-{
-    VLC_UNUSED( w );
-    *sx = h - 1 - dy;
-    *sy = dx;
-}
-typedef void (*convert_t)(int *, int *, int, int, int, int);
+    const unsigned char *src_pixels = src;
+    unsigned char *restrict dst_pixels = dst;
+    size_t visible_pitch = width << order;
 
-#define PLANE(f,bits) \
-static void Plane##bits##_##f(plane_t *restrict dst, const plane_t *restrict src) \
-{ \
-    const uint##bits##_t *src_pixels = (const void *)src->p_pixels; \
-    uint##bits##_t *restrict dst_pixels = (void *)dst->p_pixels; \
-    const unsigned src_width = src->i_pitch / sizeof (*src_pixels); \
-    const unsigned dst_width = dst->i_pitch / sizeof (*dst_pixels); \
-    const unsigned dst_visible_width = dst->i_visible_pitch / sizeof (*dst_pixels); \
- \
-    for (int y = 0; y < dst->i_visible_lines; y++) { \
-        for (unsigned x = 0; x < dst_visible_width; x++) { \
-            int sx, sy; \
-            (f)(&sx, &sy, dst_visible_width, dst->i_visible_lines, x, y); \
-            dst_pixels[y * dst_width + x] = \
-                src_pixels[sy * src_width + sx]; \
-        } \
-    } \
-}
+    dst_pixels += dst_stride * height;
 
-static void Plane_VFlip(plane_t *restrict dst, const plane_t *restrict src)
-{
-    const uint8_t *src_pixels = src->p_pixels;
-    uint8_t *restrict dst_pixels = dst->p_pixels;
-
-    dst_pixels += dst->i_pitch * dst->i_visible_lines;
-    for (int y = 0; y < dst->i_visible_lines; y++) {
-        dst_pixels -= dst->i_pitch;
-        memcpy(dst_pixels, src_pixels, dst->i_visible_pitch);
-        src_pixels += src->i_pitch;
+    for (int y = 0; y < height; y++) {
+        dst_pixels -= dst_stride;
+        memcpy(dst_pixels, src_pixels, visible_pitch);
+        src_pixels += src_stride;
     }
 }
 
-#define I422(f) \
-static void Plane422_##f(plane_t *restrict dst, const plane_t *restrict src) \
+#define TRANSFORMS(bits) \
+static void hflip_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                         const void *restrict src, ptrdiff_t src_stride, \
+                         int width, int height) \
 { \
-    for (int y = 0; y < dst->i_visible_lines; y += 2) { \
-        for (int x = 0; x < dst->i_visible_pitch; x++) { \
-            int sx, sy, uv; \
-            (f)(&sx, &sy, dst->i_visible_pitch, dst->i_visible_lines / 2, \
-                x, y / 2); \
-            uv = (1 + src->p_pixels[2 * sy * src->i_pitch + sx] + \
-                src->p_pixels[(2 * sy + 1) * src->i_pitch + sx]) / 2; \
-            dst->p_pixels[y * dst->i_pitch + x] = uv; \
-            dst->p_pixels[(y + 1) * dst->i_pitch + x] = uv; \
-        } \
+    const uint##bits##_t *restrict src_pixels = src; \
+    uint##bits##_t *restrict dst_pixels = dst; \
+\
+    dst_stride /= bits / 8; \
+    src_stride /= bits / 8; \
+    dst_pixels += width - 1; \
+\
+    for (int y = 0; y < height; y++) { \
+        for (int x = 0; x < width; x++) \
+            dst_pixels[-x] = src_pixels[x]; \
+\
+        src_pixels += src_stride; \
+        dst_pixels += dst_stride; \
     } \
-}
-
-#define YUY2(f) \
-static void PlaneYUY2_##f(plane_t *restrict dst, const plane_t *restrict src) \
+} \
+\
+static void vflip_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                         const void *restrict src, ptrdiff_t src_stride, \
+                         int width, int height) \
+{ \
+    vflip(dst, dst_stride, src, src_stride, width, height, ctz(bits / 8)); \
+} \
+\
+static void r180_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                        const void *restrict src, ptrdiff_t src_stride, \
+                        int width, int height) \
+{ \
+    const unsigned char *src_pixels = src; \
+\
+    src_pixels += (height - 1) * src_stride; \
+    src_stride *= -1; \
+    hflip_##bits(dst, dst_stride, src_pixels, src_stride, width, height); \
+} \
+\
+static void transpose_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                             const void *restrict src, ptrdiff_t src_stride, \
+                             int src_width, int src_height) \
 { \
-    unsigned dst_visible_width = dst->i_visible_pitch / 2; \
- \
-    for (int y = 0; y < dst->i_visible_lines; y += 2) { \
-        for (unsigned x = 0; x < dst_visible_width; x+= 2) { \
-            int sx0, sy0, sx1, sy1; \
-            (f)(&sx0, &sy0, dst_visible_width, dst->i_visible_lines, x, y); \
-            (f)(&sx1, &sy1, dst_visible_width, dst->i_visible_lines, \
-                x + 1, y + 1); \
-            dst->p_pixels[(y + 0) * dst->i_pitch + 2 * (x + 0)] = \
-                src->p_pixels[sy0 * src->i_pitch + 2 * sx0]; \
-            dst->p_pixels[(y + 0) * dst->i_pitch + 2 * (x + 1)] = \
-                src->p_pixels[sy1 * src->i_pitch + 2 * sx0]; \
-            dst->p_pixels[(y + 1) * dst->i_pitch + 2 * (x + 0)] = \
-                src->p_pixels[sy0 * src->i_pitch + 2 * sx1]; \
-            dst->p_pixels[(y + 1) * dst->i_pitch + 2 * (x + 1)] = \
-                src->p_pixels[sy1 * src->i_pitch + 2 * sx1]; \
- \
-            int sx, sy, u, v; \
-            (f)(&sx, &sy, dst_visible_width / 2, dst->i_visible_lines / 2, \
-                x / 2, y / 2); \
-            u = (1 + src->p_pixels[2 * sy * src->i_pitch + 4 * sx + 1] + \
-                src->p_pixels[(2 * sy + 1) * src->i_pitch + 4 * sx + 1]) / 2; \
-            v = (1 + src->p_pixels[2 * sy * src->i_pitch + 4 * sx + 3] + \
-                src->p_pixels[(2 * sy + 1) * src->i_pitch + 4 * sx + 3]) / 2; \
-            dst->p_pixels[(y + 0) * dst->i_pitch + 2 * x + 1] = u; \
-            dst->p_pixels[(y + 0) * dst->i_pitch + 2 * x + 3] = v; \
-            dst->p_pixels[(y + 1) * dst->i_pitch + 2 * x + 1] = u; \
-            dst->p_pixels[(y + 1) * dst->i_pitch + 2 * x + 3] = v; \
-        } \
+    const uint##bits##_t *restrict src_pixels = src; \
+    uint##bits##_t *restrict dst_pixels = dst; \
+\
+    dst_stride /= bits / 8; \
+    src_stride /= bits / 8; \
+\
+    for (int y = 0; y < src_height; y++) { \
+        for (int x = 0; x < src_width; x++) \
+            dst_pixels[x * dst_stride] = src_pixels[x]; \
+        src_pixels += src_stride; \
+        dst_pixels++; \
     } \
+} \
+\
+static void r270_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                        const void *restrict src, ptrdiff_t src_stride, \
+                        int src_width, int src_height) \
+{ \
+    unsigned char *dst_pixels = dst; \
+\
+    dst_pixels += (src_width - 1) * dst_stride; \
+    dst_stride *= -1; \
+    transpose_##bits(dst_pixels, dst_stride, src, src_stride, \
+                     src_width, src_height); \
+} \
+\
+static void r90_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                       const void *restrict src, ptrdiff_t src_stride, \
+                       int src_width, int src_height) \
+{ \
+    const unsigned char *src_pixels = src; \
+\
+    src_pixels += (src_height - 1) * src_stride; \
+    src_stride *= -1; \
+    transpose_##bits(dst, dst_stride, src_pixels, src_stride, \
+                     src_width, src_height); \
+} \
+\
+static void antitranspose_##bits(void *restrict dst, ptrdiff_t dst_stride, \
+                                 const void *restrict src, \
+                                 ptrdiff_t src_stride, \
+                                 int src_width, int src_height) \
+{ \
+    const unsigned char *src_pixels = src; \
+\
+    src_pixels += (src_height - 1) * src_stride; \
+    src_stride *= -1; \
+    r270_##bits(dst, dst_stride, src_pixels, src_stride, \
+                src_width, src_height);\
 }
 
-#undef PLANES // already exists on Windows
-#define PLANES(f) \
-PLANE(f,8) PLANE(f,16) PLANE(f,32)
-
-PLANES(HFlip)
-#define Plane8_VFlip Plane_VFlip
-#define Plane16_VFlip Plane_VFlip
-#define Plane32_VFlip Plane_VFlip
-PLANES(Transpose)
-PLANES(AntiTranspose)
-PLANES(R90)
-PLANES(R180)
-PLANES(R270)
-
-#define Plane422_HFlip Plane16_HFlip
-#define Plane422_VFlip Plane_VFlip
-#define Plane422_R180  Plane16_R180
-I422(Transpose)
-I422(AntiTranspose)
-I422(R90)
-I422(R270)
-
-#define PlaneYUY2_HFlip Plane32_HFlip
-#define PlaneYUY2_VFlip Plane_VFlip
-#define PlaneYUY2_R180  Plane32_R180
-YUY2(Transpose)
-YUY2(AntiTranspose)
-YUY2(R90)
-YUY2(R270)
+TRANSFORMS(8)
+TRANSFORMS(16)
+TRANSFORMS(32)
+
+typedef void (*plane_transform_cb)(void *, ptrdiff_t, const void *, ptrdiff_t,
+                                   int, int);
 
 typedef struct {
-    convert_t convert;
-    void      (*plane8) (plane_t *dst, const plane_t *src);
-    void      (*plane16)(plane_t *dst, const plane_t *src);
-    void      (*plane32)(plane_t *dst, const plane_t *src);
-    void      (*i422)(plane_t *dst, const plane_t *src);
-    void      (*yuyv)(plane_t *dst, const plane_t *src);
+    plane_transform_cb plane8;
+    plane_transform_cb plane16;
+    plane_transform_cb plane32;
 } transform_description_t;
 
-#define DESC(f) \
-    { f, Plane8_##f, Plane16_##f, Plane32_##f, \
-      Plane422_##f, PlaneYUY2_##f }
+#define DESC(g) \
+    { g##_8, g##_16, g##_32, }
 
 static const transform_description_t descriptions[] = {
-    [TRANSFORM_R90] =            DESC(R90),
-    [TRANSFORM_R180] =           DESC(R180),
-    [TRANSFORM_R270] =           DESC(R270),
-    [TRANSFORM_HFLIP] =          DESC(HFlip),
-    [TRANSFORM_VFLIP] =          DESC(VFlip),
-    [TRANSFORM_TRANSPOSE] =      DESC(Transpose),
-    [TRANSFORM_ANTI_TRANSPOSE] = DESC(AntiTranspose),
+    [TRANSFORM_R90] =            DESC(r90),
+    [TRANSFORM_R180] =           DESC(r180),
+    [TRANSFORM_R270] =           DESC(r270),
+    [TRANSFORM_HFLIP] =          DESC(hflip),
+    [TRANSFORM_VFLIP] =          DESC(vflip),
+    [TRANSFORM_TRANSPOSE] =      DESC(transpose),
+    [TRANSFORM_ANTI_TRANSPOSE] = DESC(antitranspose),
 };
 
 typedef struct
 {
-    const vlc_chroma_description_t *chroma;
-    void (*plane[PICTURE_PLANE_MAX])(plane_t *, const plane_t *);
-    convert_t convert;
+    video_transform_t transform;
+    plane_transform_cb plane[PICTURE_PLANE_MAX];
 } filter_sys_t;
 
 static picture_t *Filter(filter_t *filter, picture_t *src)
@@ -225,10 +183,11 @@ static picture_t *Filter(filter_t *filter, picture_t *src)
     picture_t *dst = filter_NewPicture(filter);
 
     if (likely(dst != NULL)) {
-        const vlc_chroma_description_t *chroma = sys->chroma;
-
-        for (unsigned i = 0; i < chroma->plane_count; i++)
-            (sys->plane[i])(&dst->p[i], &src->p[i]);
+        for (int i = 0; i < src->i_planes; i++)
+            (sys->plane[i])(dst->p[i].p_pixels, dst->p[i].i_pitch,
+                            src->p[i].p_pixels, src->p[i].i_pitch,
+                            src->p[i].i_visible_pitch / src->p[i].i_pixel_pitch,
+                            src->p[i].i_visible_lines);
 
         picture_CopyProperties(dst, src);
     }
@@ -244,10 +203,54 @@ static int Mouse(filter_t *filter, vlc_mouse_t *mouse,
 
     const video_format_t *fmt = &filter->fmt_out.video;
     const filter_sys_t   *sys = filter->p_sys;
+    int dw = fmt->i_visible_width, dh = fmt->i_visible_height;
+    int dx = mouse->i_x, dy = mouse->i_y;
+    int sx, sy;
+
+    switch (sys->transform) {
+        case TRANSFORM_HFLIP:
+        case TRANSFORM_R180:
+            sx = dw - 1 - dx;
+            break;
+        //case TRANSFORM_IDENTITY:
+        case TRANSFORM_VFLIP:
+            sx = dx;
+            break;
+        case TRANSFORM_TRANSPOSE:
+        case TRANSFORM_R90:
+            sx = dy;
+            break;
+        case TRANSFORM_R270:
+        case TRANSFORM_ANTI_TRANSPOSE:
+            sx = dh - 1 - dy;
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+
+    switch (sys->transform) {
+        //case TRANSFORM_IDENTITY:
+        case TRANSFORM_HFLIP:
+            sy = dy;
+            break;
+        case TRANSFORM_VFLIP:
+        case TRANSFORM_R180:
+            sy = dh - 1 - dy;
+            break;
+        case TRANSFORM_TRANSPOSE:
+        case TRANSFORM_R270:
+            sy = dx;
+            break;
+        case TRANSFORM_R90:
+        case TRANSFORM_ANTI_TRANSPOSE:
+            sy = dw - 1 - dx;
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
 
-    sys->convert(&mouse->i_x, &mouse->i_y,
-                 fmt->i_visible_width, fmt->i_visible_height,
-                 mouse->i_x, mouse->i_y);
+    mouse->i_x = sx;
+    mouse->i_y = sy;
     return VLC_SUCCESS;
 }
 
@@ -284,7 +287,7 @@ static int Open(filter_t *filter)
 
     const transform_description_t *const dsc = &descriptions[transform];
 
-    sys->chroma = chroma;
+    sys->transform = transform;
 
     switch (chroma->pixel_size) {
         case 1:
@@ -302,36 +305,19 @@ static int Open(filter_t *filter)
 
     for (unsigned i = 1; i < PICTURE_PLANE_MAX; i++)
         sys->plane[i] = sys->plane[0];
-    sys->convert = dsc->convert;
-
-    if (ORIENT_IS_SWAP(transform)) {
-        switch (src->i_chroma) {
-            case VLC_CODEC_I422:
-            case VLC_CODEC_J422:
-                sys->plane[2] = sys->plane[1] = dsc->i422;
-                break;
-            default:
-                for (unsigned i = 0; i < chroma->plane_count; i++)
-                    if (chroma->p[i].w.num * chroma->p[i].h.den
-                     != chroma->p[i].h.num * chroma->p[i].w.den)
-                        return VLC_ENOTSUP;
-        }
-    }
+
+    if (ORIENT_IS_SWAP(transform)) /* Cannot transform non-square samples */
+        for (unsigned i = 0; i < chroma->plane_count; i++)
+            if (chroma->p[i].w.num * chroma->p[i].h.den
+             != chroma->p[i].h.num * chroma->p[i].w.den)
+                return VLC_ENOTSUP;
 
     /* Deal with weird packed formats */
     switch (src->i_chroma) {
-        case VLC_CODEC_UYVY:
-        case VLC_CODEC_VYUY:
-            if (ORIENT_IS_SWAP(transform))
-                return VLC_ENOTSUP;
-            /* fallthrough */
-        case VLC_CODEC_YUYV:
-        case VLC_CODEC_YVYU:
-            sys->plane[0] = dsc->yuyv; /* 32-bits, not 16-bits! */
-            break;
         case VLC_CODEC_NV12:
         case VLC_CODEC_NV21:
-            return VLC_ENOTSUP;
+            sys->plane[1] = dsc->plane16;
+            break;
     }
 
     static const struct vlc_filter_operations filter_ops =



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a54423f138ccd180455637091a8f636d48150f1f...55eaaa320a805173eb7b0fe7297993ad9a47f640

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a54423f138ccd180455637091a8f636d48150f1f...55eaaa320a805173eb7b0fe7297993ad9a47f640
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list