summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-11-06 09:34:59 +0100
committerWim Taymans <wtaymans@redhat.com>2014-11-06 10:45:13 +0100
commitcecb900704ff393e35efc159a57f30a51180830d (patch)
treec713042b7738af175d8c847badfbe6d412dcf25d /gst-libs
parent1f14077b41687aaf62928a9e6da0ff43ae873bba (diff)
downloadgstreamer-plugins-base-cecb900704ff393e35efc159a57f30a51180830d.tar.gz
video-format: fix pack of 4:2:0 formats
When packing 4:2:0 formats, we need to take the chroma from the even lines, for the odd lines we only take luminance.
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/video/video-format.c169
-rw-r--r--gst-libs/gst/video/video-orc.orc18
2 files changed, 115 insertions, 72 deletions
diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c
index 9afb85acc..9fbc39d09 100644
--- a/gst-libs/gst/video/video-format.c
+++ b/gst-libs/gst/video/video-format.c
@@ -101,17 +101,19 @@ pack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint8 *v_line = GET_V_LINE (uv);
const guint8 *ayuv = src;
- g_return_if_fail (IS_ALIGNED (src, 8));
+ if (!(y & 1)) {
+ g_return_if_fail (IS_ALIGNED (src, 8));
- video_orc_pack_I420 (y_line, u_line, v_line, src, width / 2);
+ video_orc_pack_I420 (y_line, u_line, v_line, src, width / 2);
+ if (width & 1) {
+ gint i = width - 1;
- if (width & 1) {
- gint i = width - 1;
-
- y_line[i] = ayuv[i * 4 + 1];
- u_line[i >> 1] = ayuv[i * 4 + 2];
- v_line[i >> 1] = ayuv[i * 4 + 3];
- }
+ y_line[i] = ayuv[i * 4 + 1];
+ u_line[i >> 1] = ayuv[i * 4 + 2];
+ v_line[i >> 1] = ayuv[i * 4 + 3];
+ }
+ } else
+ video_orc_pack_Y (y_line, src, width);
}
#define PACK_YUY2 GST_VIDEO_FORMAT_AYUV, unpack_YUY2, 1, pack_YUY2
@@ -1085,17 +1087,20 @@ pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint8 *uv_line = GET_PLANE_LINE (1, uv);
const guint8 *ayuv = src;
- g_return_if_fail (IS_ALIGNED (src, 8));
+ if (!(y & 1)) {
+ g_return_if_fail (IS_ALIGNED (src, 8));
- video_orc_pack_NV12 (y_line, uv_line, src, width / 2);
+ video_orc_pack_NV12 (y_line, uv_line, src, width / 2);
- if (width & 1) {
- gint i = width - 1;
+ if (width & 1) {
+ gint i = width - 1;
- y_line[i] = ayuv[i * 4 + 1];
- uv_line[i + 0] = ayuv[i * 4 + 2];
- uv_line[i + 1] = ayuv[i * 4 + 3];
- }
+ y_line[i] = ayuv[i * 4 + 1];
+ uv_line[i + 0] = ayuv[i * 4 + 2];
+ uv_line[i + 1] = ayuv[i * 4 + 3];
+ }
+ } else
+ video_orc_pack_Y (y_line, src, width);
}
#define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
@@ -1134,17 +1139,20 @@ pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint8 *uv_line = GET_PLANE_LINE (1, uv);
const guint8 *ayuv = src;
- g_return_if_fail (IS_ALIGNED (src, 8));
+ if (!(y & 1)) {
+ g_return_if_fail (IS_ALIGNED (src, 8));
- video_orc_pack_NV21 (y_line, uv_line, src, width / 2);
+ video_orc_pack_NV21 (y_line, uv_line, src, width / 2);
- if (width & 1) {
- gint i = width - 1;
+ if (width & 1) {
+ gint i = width - 1;
- y_line[i] = ayuv[i * 4 + 1];
- uv_line[i + 0] = ayuv[i * 4 + 3];
- uv_line[i + 1] = ayuv[i * 4 + 2];
- }
+ y_line[i] = ayuv[i * 4 + 1];
+ uv_line[i + 0] = ayuv[i * 4 + 3];
+ uv_line[i + 1] = ayuv[i * 4 + 2];
+ }
+ } else
+ video_orc_pack_Y (y_line, src, width);
}
#define PACK_NV16 GST_VIDEO_FORMAT_AYUV, unpack_NV16, 1, pack_NV16
@@ -1312,18 +1320,21 @@ pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint8 *a_line = GET_A_LINE (y);
const guint8 *ayuv = src;
- g_return_if_fail (IS_ALIGNED (src, 8));
+ if (!(y & 1)) {
+ g_return_if_fail (IS_ALIGNED (src, 8));
- video_orc_pack_A420 (y_line, u_line, v_line, a_line, src, width / 2);
+ video_orc_pack_A420 (y_line, u_line, v_line, a_line, src, width / 2);
- if (width & 1) {
- gint i = width - 1;
+ if (width & 1) {
+ gint i = width - 1;
- a_line[i] = ayuv[i * 4 + 0];
- y_line[i] = ayuv[i * 4 + 1];
- u_line[i >> 1] = ayuv[i * 4 + 2];
- v_line[i >> 1] = ayuv[i * 4 + 3];
- }
+ a_line[i] = ayuv[i * 4 + 0];
+ y_line[i] = ayuv[i * 4 + 1];
+ u_line[i >> 1] = ayuv[i * 4 + 2];
+ v_line[i >> 1] = ayuv[i * 4 + 3];
+ }
+ } else
+ video_orc_pack_AY (y_line, a_line, src, width);
}
#define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
@@ -1888,25 +1899,32 @@ pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint16 Y0, Y1, U, V;
const guint16 *s = src;
- for (i = 0; i < width - 1; i += 2) {
- Y0 = s[i * 4 + 1] >> 6;
- Y1 = s[i * 4 + 5] >> 6;
- U = s[i * 4 + 2] >> 6;
- V = s[i * 4 + 3] >> 6;
-
- GST_WRITE_UINT16_LE (destY + i + 0, Y0);
- GST_WRITE_UINT16_LE (destY + i + 1, Y1);
- GST_WRITE_UINT16_LE (destU + (i >> 1), U);
- GST_WRITE_UINT16_LE (destV + (i >> 1), V);
- }
- if (i == width - 1) {
- Y0 = s[i * 4 + 1] >> 6;
- U = s[i * 4 + 2] >> 6;
- V = s[i * 4 + 3] >> 6;
-
- GST_WRITE_UINT16_LE (destY + i, Y0);
- GST_WRITE_UINT16_LE (destU + (i >> 1), U);
- GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+ if (!(y & 1)) {
+ for (i = 0; i < width - 1; i += 2) {
+ Y0 = s[i * 4 + 1] >> 6;
+ Y1 = s[i * 4 + 5] >> 6;
+ U = s[i * 4 + 2] >> 6;
+ V = s[i * 4 + 3] >> 6;
+
+ GST_WRITE_UINT16_LE (destY + i + 0, Y0);
+ GST_WRITE_UINT16_LE (destY + i + 1, Y1);
+ GST_WRITE_UINT16_LE (destU + (i >> 1), U);
+ GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+ }
+ if (i == width - 1) {
+ Y0 = s[i * 4 + 1] >> 6;
+ U = s[i * 4 + 2] >> 6;
+ V = s[i * 4 + 3] >> 6;
+
+ GST_WRITE_UINT16_LE (destY + i, Y0);
+ GST_WRITE_UINT16_LE (destU + (i >> 1), U);
+ GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+ }
+ } else {
+ for (i = 0; i < width; i++) {
+ Y0 = s[i * 4 + 1] >> 6;
+ GST_WRITE_UINT16_LE (destY + i, Y0);
+ }
}
}
@@ -1955,25 +1973,32 @@ pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint16 Y0, Y1, U, V;
const guint16 *s = src;
- for (i = 0; i < width - 1; i += 2) {
- Y0 = s[i * 4 + 1] >> 6;
- Y1 = s[i * 4 + 5] >> 6;
- U = s[i * 4 + 2] >> 6;
- V = s[i * 4 + 3] >> 6;
-
- GST_WRITE_UINT16_BE (destY + i + 0, Y0);
- GST_WRITE_UINT16_BE (destY + i + 1, Y1);
- GST_WRITE_UINT16_BE (destU + (i >> 1), U);
- GST_WRITE_UINT16_BE (destV + (i >> 1), V);
- }
- if (i == width - 1) {
- Y0 = s[i * 4 + 1] >> 6;
- U = s[i * 4 + 2] >> 6;
- V = s[i * 4 + 3] >> 6;
-
- GST_WRITE_UINT16_BE (destY + i, Y0);
- GST_WRITE_UINT16_BE (destU + (i >> 1), U);
- GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+ if (!(y & 1)) {
+ for (i = 0; i < width - 1; i += 2) {
+ Y0 = s[i * 4 + 1] >> 6;
+ Y1 = s[i * 4 + 5] >> 6;
+ U = s[i * 4 + 2] >> 6;
+ V = s[i * 4 + 3] >> 6;
+
+ GST_WRITE_UINT16_BE (destY + i + 0, Y0);
+ GST_WRITE_UINT16_BE (destY + i + 1, Y1);
+ GST_WRITE_UINT16_BE (destU + (i >> 1), U);
+ GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+ }
+ if (i == width - 1) {
+ Y0 = s[i * 4 + 1] >> 6;
+ U = s[i * 4 + 2] >> 6;
+ V = s[i * 4 + 3] >> 6;
+
+ GST_WRITE_UINT16_BE (destY + i, Y0);
+ GST_WRITE_UINT16_BE (destU + (i >> 1), U);
+ GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+ }
+ } else {
+ for (i = 0; i < width; i++) {
+ Y0 = s[i * 4 + 1] >> 6;
+ GST_WRITE_UINT16_BE (destY + i, Y0);
+ }
}
}
diff --git a/gst-libs/gst/video/video-orc.orc b/gst-libs/gst/video/video-orc.orc
index d4144516b..1ea3231b4 100644
--- a/gst-libs/gst/video/video-orc.orc
+++ b/gst-libs/gst/video/video-orc.orc
@@ -96,6 +96,14 @@ x2 splitwb vv, uu, uv
select0wb u, uu
select0wb v, vv
+.function video_orc_pack_Y
+.dest 1 y guint8
+.source 4 ayuv guint8
+.temp 2 ay
+
+select0lw ay, ayuv
+select1wb y, ay
+
.function video_orc_unpack_YUY2
.dest 8 ayuv guint8
.source 4 yuy2 guint8
@@ -477,6 +485,16 @@ x2 splitwb vv, uu, uv
select0wb u, uu
select0wb v, vv
+.function video_orc_pack_AY
+.dest 1 y guint8
+.dest 1 a guint8
+.source 4 ayuv guint8
+.temp 2 ay
+
+select0lw ay, ayuv
+select1wb y, ay
+select0wb a, ay
+
.function video_orc_resample_bilinear_u32
.dest 4 d1 guint8
.source 4 s1 guint8