[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