From 292436502068721084f2e60a6de442f09a060ed0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 1 Apr 2013 16:16:27 +0200 Subject: [PATCH] video: don't perform subsampling while packing Don't perform subsampling when packing but let this be done by a separate subsampling step. --- gst-libs/gst/video/video-format.c | 82 ++++++++++++++----------------- gst-libs/gst/video/video-format.h | 9 +++- gst-libs/gst/video/video-orc.orc | 56 +++++++-------------- 3 files changed, 65 insertions(+), 82 deletions(-) diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c index 8fb69f727d..427874fae5 100644 --- a/gst-libs/gst/video/video-format.c +++ b/gst-libs/gst/video/video-format.c @@ -318,13 +318,13 @@ pack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, y4 = s[4 * (i + 4) + 1] >> 6; y5 = s[4 * (i + 5) + 1] >> 6; - u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 7; - u1 = (s[4 * (i + 2) + 2] + s[4 * (i + 3) + 2] + 1) >> 7; - u2 = (s[4 * (i + 4) + 2] + s[4 * (i + 5) + 2] + 1) >> 7; + u0 = s[4 * (i + 0) + 2] >> 6; + u1 = s[4 * (i + 2) + 2] >> 6; + u2 = s[4 * (i + 4) + 2] >> 6; - v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 7; - v1 = (s[4 * (i + 2) + 3] + s[4 * (i + 3) + 3] + 1) >> 7; - v2 = (s[4 * (i + 4) + 3] + s[4 * (i + 5) + 3] + 1) >> 7; + v0 = s[4 * (i + 0) + 3] >> 6; + v1 = s[4 * (i + 2) + 3] >> 6; + v2 = s[4 * (i + 4) + 3] >> 6; a0 = u0 | (y0 << 10) | (v0 << 20); a1 = y1 | (u1 << 10) | (y2 << 20); @@ -402,10 +402,8 @@ pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags, destY[i + 2] = s[i * 4 + 9]; destY[i + 3] = s[i * 4 + 13]; - destU[i >> 2] = - (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14] + 2) >> 2; - destV[i >> 2] = - (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15] + 2) >> 2; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } if (i == width - 3) { @@ -413,14 +411,14 @@ pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags, destY[i + 1] = s[i * 4 + 5]; destY[i + 2] = s[i * 4 + 9]; - destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + 1) / 3; - destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + 1) / 3; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } else if (i == width - 2) { destY[i] = s[i * 4 + 1]; destY[i + 1] = s[i * 4 + 5]; - destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1; - destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } else if (i == width - 1) { destY[i + 1] = s[i * 4 + 5]; @@ -997,8 +995,8 @@ pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags, y0 = s[4 * (i + 0) + 1]; y1 = s[4 * (i + 1) + 1]; - u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 1; - v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 1; + u0 = s[4 * (i + 0) + 2]; + v0 = s[4 * (i + 0) + 3]; d[(i / 2) * 5 + 0] = u0 >> 8; d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10; @@ -1151,10 +1149,8 @@ pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, destY[i + 2] = s[i * 4 + 9]; destY[i + 3] = s[i * 4 + 13]; if (y % 4 == 0) { - destU[i >> 2] = - (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2; - destV[i >> 2] = - (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } } @@ -1163,15 +1159,15 @@ pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, destY[i + 1] = s[i * 4 + 5]; destY[i + 2] = s[i * 4 + 9]; if (y % 4 == 0) { - destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3; - destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } } else if (i == width - 2) { destY[i] = s[i * 4 + 1]; destY[i + 1] = s[i * 4 + 5]; if (y % 4 == 0) { - destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1; - destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1; + destU[i >> 2] = s[i * 4 + 2]; + destV[i >> 2] = s[i * 4 + 3]; } } else if (i == width - 1) { destY[i] = s[i * 4 + 1]; @@ -1244,23 +1240,21 @@ pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; d[(i >> 2) * 6 + 4] = s[i * 4 + 9]; d[(i >> 2) * 6 + 5] = s[i * 4 + 13]; - d[(i >> 2) * 6 + 0] = - (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2; - d[(i >> 2) * 6 + 3] = - (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2; + d[(i >> 2) * 6 + 0] = s[i * 4 + 2]; + d[(i >> 2) * 6 + 3] = s[i * 4 + 3]; } if (i == width - 3) { d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; d[(i >> 2) * 6 + 4] = s[i * 4 + 9]; - d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3; - d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3; + d[(i >> 2) * 6 + 0] = s[i * 4 + 2]; + d[(i >> 2) * 6 + 3] = s[i * 4 + 3]; } else if (i == width - 2) { d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; - d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1; - d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1; + d[(i >> 2) * 6 + 0] = s[i * 4 + 2]; + d[(i >> 2) * 6 + 3] = s[i * 4 + 3]; } else if (i == width - 1) { d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 0] = s[i * 4 + 2]; @@ -1586,10 +1580,10 @@ pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, 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] + s[i * 4 + 6] + 1) >> 1) >> 6; - V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; + 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); @@ -1655,8 +1649,8 @@ pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, 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] + s[i * 4 + 6] + 1) >> 1) >> 6; - V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 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); @@ -1718,10 +1712,10 @@ pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, 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] + s[i * 4 + 6] + 1) >> 1) >> 6; - V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; + 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); @@ -1785,8 +1779,8 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, 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] + s[i * 4 + 6] + 1) >> 1) >> 6; - V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 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); diff --git a/gst-libs/gst/video/video-format.h b/gst-libs/gst/video/video-format.h index c0c7390f45..e8cf54c68e 100644 --- a/gst-libs/gst/video/video-format.h +++ b/gst-libs/gst/video/video-format.h @@ -231,6 +231,10 @@ typedef enum * format @info. The pixels will be unpacked into @dest which each component * interleaved. @dest should at least be big enough to hold @width * * n_components * size(unpack_format) bytes. + * + * For subsampled formats, the components will be duplicated in the destination + * array. Reconstruction of the missing components can be performed in a + * separate step after unpacking. */ typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info, GstVideoPackFlags flags, gpointer dest, @@ -245,7 +249,7 @@ typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info, * @sstride: the source array stride * @data: pointers to the destination data planes * @stride: strides of the destination planes - * @chroma_site: the chroma siting of the target when subsampled + * @chroma_site: the chroma siting of the target when subsampled (not used) * @y: the y position in the image to pack to * @width: the amount of pixels to pack. * @@ -256,6 +260,9 @@ typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info, * This function operates on pack_lines lines, meaning that @src should * contain at least pack_lines lines with a stride of @sstride and @y * should be a multiple of pack_lines. + * + * Subsampled formats will use the horizontally cosited component in the + * destination. Subsampling should be performed before packing. */ typedef void (*GstVideoFormatPack) (const GstVideoFormatInfo *info, GstVideoPackFlags flags, diff --git a/gst-libs/gst/video/video-orc.orc b/gst-libs/gst/video/video-orc.orc index 445be2441e..1dab8a9b23 100644 --- a/gst-libs/gst/video/video-orc.orc +++ b/gst-libs/gst/video/video-orc.orc @@ -93,10 +93,8 @@ mergewl d, ay, uv x2 splitlw uv, ay, ayuv x2 select1wb y, ay x2 splitwb vv, uu, uv -splitwb t1, t2, uu -avgub u, t1, t2 -splitwb t1, t2, vv -avgub v, t1, t2 +select0wb u, uu +select0wb v, vv .function video_orc_unpack_YUY2 .dest 8 ayuv guint8 @@ -117,32 +115,28 @@ x2 mergewl ayuv, ayay, uvuv .dest 4 yuy2 guint8 .source 8 ayuv guint8 .temp 2 yy -.temp 2 uv1 -.temp 2 uv2 +.temp 2 uv .temp 4 ayay .temp 4 uvuv x2 splitlw uvuv, ayay, ayuv -splitlw uv1, uv2, uvuv -x2 avgub uv1, uv1, uv2 +select0lw uv, uvuv x2 select1wb yy, ayay -x2 mergebw yuy2, yy, uv1 +x2 mergebw yuy2, yy, uv .function video_orc_pack_UYVY .dest 4 yuy2 guint8 .source 8 ayuv guint8 .temp 2 yy -.temp 2 uv1 -.temp 2 uv2 +.temp 2 uv .temp 4 ayay .temp 4 uvuv x2 splitlw uvuv, ayay, ayuv -splitlw uv1, uv2, uvuv -x2 avgub uv1, uv1, uv2 +select0lw uv, uvuv x2 select1wb yy, ayay -x2 mergebw yuy2, uv1, yy +x2 mergebw yuy2, uv, yy .function video_orc_unpack_UYVY @@ -180,17 +174,15 @@ x2 mergewl ayuv, ayay, uvuv .dest 4 yuy2 guint8 .source 8 ayuv guint8 .temp 2 yy -.temp 2 uv1 -.temp 2 uv2 +.temp 2 uv .temp 4 ayay .temp 4 uvuv x2 splitlw uvuv, ayay, ayuv -splitlw uv1, uv2, uvuv -x2 avgub uv1, uv1, uv2 +select0lw uv, uvuv x2 select1wb yy, ayay -swapw uv1, uv1 -x2 mergebw yuy2, yy, uv1 +swapw uv, uv +x2 mergebw yuy2, yy, uv .function video_orc_unpack_YUV9 @@ -236,13 +228,11 @@ x2 mergewl ayuv, ayay, uvuv .source 8 ayuv guint8 .temp 4 ayay .temp 4 uvuv -.temp 2 uv1 -.temp 2 uv2 +.temp 2 uv x2 splitlw uvuv, ayay, ayuv -splitlw uv1, uv2, uvuv -x2 avgub uv1, uv1, uv2 -splitwb v, u, uv1 +select0lw uv, uvuv +splitwb v, u, uv x2 select1wb y, ayay @@ -405,8 +395,7 @@ x2 mergewl d, ay, uvuv x2 splitlw uvuv, ay, ayuv x2 select1wb y, ay -splitlw uv1, uv2, uvuv -x2 avgub uv, uv1, uv2 +select0lw uv, uvuv .function video_orc_unpack_NV21 .dest 8 d guint8 @@ -429,14 +418,11 @@ x2 mergewl d, ay, uvuv .source 8 ayuv guint8 .temp 4 ay .temp 4 uvuv -.temp 2 uv1 -.temp 2 uv2 .temp 2 uv x2 splitlw uvuv, ay, ayuv x2 select1wb y, ay -splitlw uv1, uv2, uvuv -x2 avgub uv, uv1, uv2 +select0lw uv, uvuv swapw vu, uv @@ -491,17 +477,13 @@ mergewl d, ay, uv .temp 4 uv .temp 2 uu .temp 2 vv -.temp 1 t1 -.temp 1 t2 x2 splitlw uv, ay, ayuv x2 select1wb y, ay x2 select0wb a, ay x2 splitwb vv, uu, uv -splitwb t1, t2, uu -avgub u, t1, t2 -splitwb t1, t2, vv -avgub v, t1, t2 +select0wb u, uu +select0wb v, vv .function video_orc_resample_bilinear_u32 .dest 4 d1 guint8