From c883a9f54b58bb7acc2cd9856bbb0a84a6d629af Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20Brzezi=C5=84ski?= Date: Tue, 9 Aug 2022 09:42:23 +0200 Subject: [PATCH] videoflip: Add support for 10/12bit planar formats Implements support for I420, I422 and Y444 in 10/12 bit LE/BE variants. I422 is handled separately from the rest, as it needs to consider the endianness of the current format during most transforms. Part-of: --- .../gst-plugins-good/docs/gst_plugins_cache.json | 4 +- .../gst/videofilter/gstvideoflip.c | 500 ++++++++++++++++++++- 2 files changed, 496 insertions(+), 8 deletions(-) diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json index a230a1e..cead12b 100644 --- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json @@ -26191,12 +26191,12 @@ "long-name": "Video flipper", "pad-templates": { "sink": { - "caps": "video/x-raw:\n format: { AYUV, ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw:\n format: { AYUV, ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "sink", "presence": "always" }, "src": { - "caps": "video/x-raw:\n format: { AYUV, ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", + "caps": "video/x-raw:\n format: { AYUV, ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n", "direction": "src", "presence": "always" } diff --git a/subprojects/gst-plugins-good/gst/videofilter/gstvideoflip.c b/subprojects/gst-plugins-good/gst/videofilter/gstvideoflip.c index 2403f2a..69d9a5e 100644 --- a/subprojects/gst-plugins-good/gst/videofilter/gstvideoflip.c +++ b/subprojects/gst-plugins-good/gst/videofilter/gstvideoflip.c @@ -22,7 +22,7 @@ /* * This file was (probably) generated from gstvideoflip.c, - * gstvideoflip.c,v 1.7 2003/11/08 02:48:59 dschleef Exp + * gstvideoflip.c,v 1.7 2003/11/08 02:48:59 dschleef Exp */ /** * SECTION:element-videoflip @@ -68,8 +68,9 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, " "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, " - "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, " - "GRAY8, GRAY16_BE, GRAY16_LE }")) + "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21," + "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, " + "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }")) ); static GstStaticPadTemplate gst_video_flip_sink_template = @@ -78,8 +79,9 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, " "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, " - "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, " - "GRAY8, GRAY16_BE, GRAY16_LE }")) + "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21," + "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, " + "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }")) ); #define GST_TYPE_VIDEO_FLIP_METHOD (gst_video_flip_method_get_type()) @@ -422,8 +424,257 @@ gst_video_flip_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest, /* Flip V */ s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = s[x * src_v_stride + y]; + } + } + break; + case GST_VIDEO_ORIENTATION_UR_LL: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[(src_y_height - 1 - x) * src_y_stride + (src_y_width - 1 - y)]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[(src_u_height - 1 - x) * src_u_stride + (src_u_width - 1 - y)]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[(src_v_height - 1 - x) * src_v_stride + (src_v_width - 1 - y)]; + } + } + break; + case GST_VIDEO_ORIENTATION_IDENTITY: + gst_video_frame_copy (dest, src); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +gst_video_flip_planar_yuv_16bit (GstVideoFlip * videoflip, GstVideoFrame * dest, + const GstVideoFrame * src) +{ + gint x, y; + guint16 const *s; + guint16 *d; + gint src_y_stride, src_u_stride, src_v_stride; + gint src_y_height, src_u_height, src_v_height; + gint src_y_width, src_u_width, src_v_width; + gint dest_y_stride, dest_u_stride, dest_v_stride; + gint dest_y_height, dest_u_height, dest_v_height; + gint dest_y_width, dest_u_width, dest_v_width; + + /* Divide strides by 2 because we're operating on guint16's */ + src_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 0) / 2; + src_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 1) / 2; + src_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, 2) / 2; + + dest_y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 0) / 2; + dest_u_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 1) / 2; + dest_v_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, 2) / 2; + + src_y_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 0); + src_u_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 1); + src_v_width = GST_VIDEO_FRAME_COMP_WIDTH (src, 2); + + dest_y_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 0); + dest_u_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 1); + dest_v_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, 2); + + src_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 0); + src_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 1); + src_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, 2); + + dest_y_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 0); + dest_u_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 1); + dest_v_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, 2); + + switch (videoflip->active_method) { + case GST_VIDEO_ORIENTATION_90R: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[(src_y_height - 1 - x) * src_y_stride + y]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[(src_u_height - 1 - x) * src_u_stride + y]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[(src_v_height - 1 - x) * src_v_stride + y]; + } + } + break; + case GST_VIDEO_ORIENTATION_90L: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[x * src_y_stride + (src_y_width - 1 - y)]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[x * src_u_stride + (src_u_width - 1 - y)]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[x * src_v_stride + (src_v_width - 1 - y)]; + } + } + break; + case GST_VIDEO_ORIENTATION_180: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[(src_y_height - 1 - y) * src_y_stride + (src_y_width - 1 - x)]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[(src_u_height - 1 - y) * src_u_stride + (src_u_width - 1 - x)]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[(src_v_height - 1 - y) * src_v_stride + (src_v_width - 1 - x)]; + } + } + break; + case GST_VIDEO_ORIENTATION_HORIZ: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[y * src_y_stride + (src_y_width - 1 - x)]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[y * src_u_stride + (src_u_width - 1 - x)]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[y * src_v_stride + (src_v_width - 1 - x)]; + } + } + break; + case GST_VIDEO_ORIENTATION_VERT: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = + s[(src_y_height - 1 - y) * src_y_stride + x]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); + for (y = 0; y < dest_u_height; y++) { + for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = + s[(src_u_height - 1 - y) * src_u_stride + x]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { + d[y * dest_v_stride + x] = + s[(src_v_height - 1 - y) * src_v_stride + x]; + } + } + break; + case GST_VIDEO_ORIENTATION_UL_LR: + /* Flip Y */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 0); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 0); + for (y = 0; y < dest_y_height; y++) { + for (x = 0; x < dest_y_width; x++) { + d[y * dest_y_stride + x] = s[x * src_y_stride + y]; + } + } + /* Flip U */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 1); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 1); for (y = 0; y < dest_u_height; y++) { for (x = 0; x < dest_u_width; x++) { + d[y * dest_u_stride + x] = s[x * src_u_stride + y]; + } + } + /* Flip V */ + s = GST_VIDEO_FRAME_PLANE_DATA (src, 2); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, 2); + for (y = 0; y < dest_v_height; y++) { + for (x = 0; x < dest_v_width; x++) { d[y * dest_v_stride + x] = s[x * src_v_stride + y]; } } @@ -466,6 +717,228 @@ gst_video_flip_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest, } } +static inline void +rotate_yuv422_plane (GstVideoFrame * dest, const GstVideoFrame * src, + gint plane_index, GstVideoOrientationMethod method, + gboolean is_chroma, gboolean is_le) +{ + gint src_stride, src_height, src_width; + gint dest_stride, dest_height, dest_width; + gint x, y; + guint scale; + guint16 const *s, *addr; + guint16 *d; + guint16 val, val2; + + s = GST_VIDEO_FRAME_PLANE_DATA (src, plane_index); + d = GST_VIDEO_FRAME_PLANE_DATA (dest, plane_index); + + /* Divide strides by 2 because we're operating on guint16's */ + src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src, plane_index) / 2; + src_height = GST_VIDEO_FRAME_COMP_HEIGHT (src, plane_index); + src_width = GST_VIDEO_FRAME_COMP_WIDTH (src, plane_index); + + dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest, plane_index) / 2; + dest_height = GST_VIDEO_FRAME_COMP_HEIGHT (dest, plane_index); + dest_width = GST_VIDEO_FRAME_COMP_WIDTH (dest, plane_index); + + scale = is_chroma ? 2 : 1; + + switch (method) { + case GST_VIDEO_ORIENTATION_90R: + if (is_le) { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + (src_height - 1 - x * scale) * src_stride + y / scale; + val = GST_READ_UINT16_LE (addr); + + if (is_chroma && x * 2 + 1 < src_height) { + addr = s + (src_height - 1 - (x * 2 + 1)) * src_stride + y / 2; + val2 = GST_READ_UINT16_LE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_LE (d + y * dest_stride + x, val); + } + } + } else { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + (src_height - 1 - x * scale) * src_stride + y / scale; + val = GST_READ_UINT16_BE (addr); + + if (is_chroma && x * 2 + 1 < src_height) { + addr = s + (src_height - 1 - (x * 2 + 1)) * src_stride + y / 2; + val2 = GST_READ_UINT16_BE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_BE (d + y * dest_stride + x, val); + } + } + } + break; + case GST_VIDEO_ORIENTATION_90L: + if (is_le) { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + x * scale * src_stride + (src_width - 1 - y / scale); + val = GST_READ_UINT16_LE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + (x * 2 + 1) * src_stride + (src_width - 1 - y / 2); + val2 = GST_READ_UINT16_LE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_LE (d + y * dest_stride + x, val); + } + } + } else { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + x * scale * src_stride + (src_width - 1 - y / scale); + val = GST_READ_UINT16_BE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + (x * 2 + 1) * src_stride + (src_width - 1 - y / 2); + val2 = GST_READ_UINT16_BE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_BE (d + y * dest_stride + x, val); + } + } + } + break; + case GST_VIDEO_ORIENTATION_180: + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + d[y * dest_stride + x] = + s[(src_height - 1 - y) * src_stride + (src_width - 1 - x)]; + } + } + break; + case GST_VIDEO_ORIENTATION_HORIZ: + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + d[y * dest_stride + x] = s[y * src_stride + (src_width - 1 - x)]; + } + } + break; + case GST_VIDEO_ORIENTATION_VERT: + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + d[y * dest_stride + x] = s[(src_height - 1 - y) * src_stride + x]; + } + } + break; + case GST_VIDEO_ORIENTATION_UL_LR: + if (is_le) { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + x * scale * src_stride + y / scale; + val = GST_READ_UINT16_LE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + (x * 2 + 1) * src_stride + y / 2; + val2 = GST_READ_UINT16_LE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_LE (d + y * dest_stride + x, val); + } + } + } else { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + x * scale * src_stride + y / scale; + val = GST_READ_UINT16_BE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + (x * 2 + 1) * src_stride + y / 2; + val2 = GST_READ_UINT16_BE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_BE (d + y * dest_stride + x, val); + } + } + } + break; + case GST_VIDEO_ORIENTATION_UR_LL: + if (is_le) { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + + (src_height - 1 - x * scale) * src_stride + + (src_width - 1 - y / scale); + val = GST_READ_UINT16_LE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + + (src_height - 1 - (x * 2 + 1)) * src_stride + + (src_width - 1 - y / 2); + val2 = GST_READ_UINT16_LE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_LE (d + y * dest_stride + x, val); + } + } + } else { + for (y = 0; y < dest_height; y++) { + for (x = 0; x < dest_width; x++) { + addr = s + + (src_height - 1 - x * scale) * src_stride + + (src_width - 1 - y / scale); + val = GST_READ_UINT16_BE (addr); + + if (is_chroma && x * 2 + 1 < src_width) { + addr = s + + (src_height - 1 - (x * 2 + 1)) * src_stride + + (src_width - 1 - y / 2); + val2 = GST_READ_UINT16_BE (addr); + val = (val + val2) / 2; + } + + GST_WRITE_UINT16_BE (d + y * dest_stride + x, val); + } + } + } + break; + case GST_VIDEO_ORIENTATION_IDENTITY: + gst_video_frame_copy (dest, src); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +gst_video_flip_planar_yuv_422_16bit (GstVideoFlip * videoflip, + GstVideoFrame * dest, const GstVideoFrame * src) +{ + gboolean format_is_le; + + /* We need to consider the endianness during transforms + * which need average chrominance values between two pixels */ + format_is_le = GST_VIDEO_FORMAT_INFO_IS_LE (dest->info.finfo); + + /* Attempt to get the compiler to inline specialized variants of this function + * to avoid too much branching due to endianness checks */ + if (format_is_le) { + rotate_yuv422_plane (dest, src, 0, videoflip->active_method, FALSE, TRUE); + rotate_yuv422_plane (dest, src, 1, videoflip->active_method, TRUE, TRUE); + rotate_yuv422_plane (dest, src, 2, videoflip->active_method, TRUE, TRUE); + } else { + rotate_yuv422_plane (dest, src, 0, videoflip->active_method, FALSE, FALSE); + rotate_yuv422_plane (dest, src, 1, videoflip->active_method, TRUE, FALSE); + rotate_yuv422_plane (dest, src, 2, videoflip->active_method, TRUE, FALSE); + } +} + static void gst_video_flip_semi_planar_yuv (GstVideoFlip * videoflip, GstVideoFrame * dest, const GstVideoFrame * src) @@ -766,7 +1239,6 @@ gst_video_flip_packed_simple (GstVideoFlip * videoflip, GstVideoFrame * dest, } } - static void gst_video_flip_y422 (GstVideoFlip * videoflip, GstVideoFrame * dest, const GstVideoFrame * src) @@ -991,6 +1463,22 @@ gst_video_flip_configure_process (GstVideoFlip * vf) case GST_VIDEO_FORMAT_Y444: vf->process = gst_video_flip_planar_yuv; break; + case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_10BE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I420_12BE: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_10BE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_12BE: + vf->process = gst_video_flip_planar_yuv_16bit; + break; + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_10BE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_I422_12BE: + vf->process = gst_video_flip_planar_yuv_422_16bit; + break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: case GST_VIDEO_FORMAT_YVYU: -- 2.7.4