video: don't perform subsampling while packing
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 1 Apr 2013 14:16:27 +0000 (16:16 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 27 May 2013 09:05:06 +0000 (11:05 +0200)
Don't perform subsampling when packing but let this be done by a
separate subsampling step.

gst-libs/gst/video/video-format.c
gst-libs/gst/video/video-format.h
gst-libs/gst/video/video-orc.orc

index 8fb69f7..427874f 100644 (file)
@@ -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);
index c0c7390..e8cf54c 100644 (file)
@@ -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,
index 445be24..1dab8a9 100644 (file)
@@ -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