video: fix some video formats
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 2 Jan 2012 12:30:53 +0000 (13:30 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 2 Jan 2012 12:30:53 +0000 (13:30 +0100)
Rename the offset field in GstVideoFormatInfo to poffset to avoid confusion with
the offset of the plane in the buffer. The poffset is the offset in the plane
where the first byte of the component data can be found.
Properly implement the COMP_OFFSET calculations.
Fix YV12 and YVU9, simply use the same offsets as the regular I420 and YUV9
variants, we use the plane info to reorder components already.
Improve the unit test.

gst-libs/gst/video/video.c
gst-libs/gst/video/video.h
tests/check/libs/video.c

index f00ebd6..94bd87b 100644 (file)
@@ -1259,6 +1259,7 @@ fill_planes (GstVideoInfo * info)
       info->size = info->stride[0] * height;
       break;
     case GST_VIDEO_FORMAT_I420:
+    case GST_VIDEO_FORMAT_YV12:        /* same as I420, but plane 1+2 swapped */
       info->stride[0] = GST_ROUND_UP_4 (width);
       info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
       info->stride[2] = info->stride[1];
@@ -1269,17 +1270,6 @@ fill_planes (GstVideoInfo * info)
       info->size = info->offset[2] +
           info->stride[2] * (GST_ROUND_UP_2 (height) / 2);
       break;
-    case GST_VIDEO_FORMAT_YV12:        /* same as I420, but plane 1+2 swapped */
-      info->stride[0] = GST_ROUND_UP_4 (width);
-      info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
-      info->stride[2] = info->stride[1];
-      info->offset[0] = 0;
-      info->offset[2] = info->stride[0] * GST_ROUND_UP_2 (height);
-      info->offset[1] = info->offset[2] +
-          info->stride[1] * (GST_ROUND_UP_2 (height) / 2);
-      info->size = info->offset[1] +
-          info->stride[2] * (GST_ROUND_UP_2 (height) / 2);
-      break;
     case GST_VIDEO_FORMAT_Y41B:
       info->stride[0] = GST_ROUND_UP_4 (width);
       info->stride[1] = GST_ROUND_UP_16 (width) / 4;
@@ -1331,6 +1321,7 @@ fill_planes (GstVideoInfo * info)
       info->size = info->offset[3] + info->stride[0];
       break;
     case GST_VIDEO_FORMAT_YUV9:
+    case GST_VIDEO_FORMAT_YVU9:
       info->stride[0] = GST_ROUND_UP_4 (width);
       info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
       info->stride[2] = info->stride[1];
@@ -1341,17 +1332,6 @@ fill_planes (GstVideoInfo * info)
       info->size = info->offset[2] +
           info->stride[2] * (GST_ROUND_UP_4 (height) / 4);
       break;
-    case GST_VIDEO_FORMAT_YVU9:
-      info->stride[0] = GST_ROUND_UP_4 (width);
-      info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
-      info->stride[2] = info->stride[1];
-      info->offset[0] = 0;
-      info->offset[2] = info->stride[0] * height;
-      info->offset[1] = info->offset[2] +
-          info->stride[1] * (GST_ROUND_UP_4 (height) / 4);
-      info->size = info->offset[2] +
-          info->stride[2] * (GST_ROUND_UP_4 (height) / 4);
-      break;
     case GST_VIDEO_FORMAT_UNKNOWN:
       GST_ERROR ("invalid format");
       g_warning ("invalid format");
index 6765120..788607f 100644 (file)
@@ -222,7 +222,7 @@ typedef void (*GstVideoFormatPack)           (GstVideoFormatInfo *info, const gp
  *    less than the amount of components when multiple components are packed into
  *    one plane.
  * @plane: the plane number where a component can be found
- * @offset: the offset in the plane where the first pixel of the components
+ * @poffset: the offset in the plane where the first pixel of the components
  *    can be found. If bits < 8 the amount is specified in bits.
  * @w_sub: subsampling factor of the width for the component. Use
  *     GST_VIDEO_SUB_SCALE to scale a width.
@@ -246,7 +246,7 @@ struct _GstVideoFormatInfo {
   gint  pixel_stride[GST_VIDEO_MAX_COMPONENTS];
   guint n_planes;
   guint plane[GST_VIDEO_MAX_COMPONENTS];
-  guint offset[GST_VIDEO_MAX_COMPONENTS];
+  guint poffset[GST_VIDEO_MAX_COMPONENTS];
   guint w_sub[GST_VIDEO_MAX_COMPONENTS];
   guint h_sub[GST_VIDEO_MAX_COMPONENTS];
 
@@ -273,7 +273,7 @@ struct _GstVideoFormatInfo {
 #define GST_VIDEO_FORMAT_INFO_PSTRIDE(info,c)    ((info)->pixel_stride[c])
 #define GST_VIDEO_FORMAT_INFO_N_PLANES(info)     ((info)->n_planes)
 #define GST_VIDEO_FORMAT_INFO_PLANE(info,c)      ((info)->plane[c])
-#define GST_VIDEO_FORMAT_INFO_OFFSET(info,c)     ((info)->offset[c])
+#define GST_VIDEO_FORMAT_INFO_POFFSET(info,c)    ((info)->poffset[c])
 #define GST_VIDEO_FORMAT_INFO_W_SUB(info,c)      ((info)->w_sub[c])
 #define GST_VIDEO_FORMAT_INFO_H_SUB(info,c)      ((info)->h_sub[c])
 
@@ -283,8 +283,10 @@ struct _GstVideoFormatInfo {
 #define GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT(info,c,h) GST_VIDEO_SUB_SCALE ((info)->h_sub[(c)],(h))
 
 #define GST_VIDEO_FORMAT_INFO_DATA(info,planes,comp) \
-  (((guint8*)(planes)[info->plane[comp]]) + info->offset[comp])
+  (((guint8*)(planes)[info->plane[comp]]) + info->poffset[comp])
 #define GST_VIDEO_FORMAT_INFO_STRIDE(info,strides,comp) ((strides)[info->plane[comp]])
+#define GST_VIDEO_FORMAT_INFO_OFFSET(info,offsets,comp) \
+  (((offsets)[info->plane[comp]]) + info->poffset[comp])
 
 /* format properties */
 GstVideoFormat gst_video_format_from_masks           (gint depth, gint bpp, gint endianness,
@@ -574,12 +576,13 @@ struct _GstVideoInfo {
 /* dealing with components */
 #define GST_VIDEO_INFO_N_COMPONENTS(i)   GST_VIDEO_FORMAT_INFO_N_COMPONENTS((i)->finfo)
 #define GST_VIDEO_INFO_COMP_DATA(i,d,c)  GST_VIDEO_FORMAT_INFO_DATA((i)->finfo,d,c)
+#define GST_VIDEO_INFO_COMP_OFFSET(i,c)  GST_VIDEO_FORMAT_INFO_OFFSET((i)->finfo,(i)->offset,c)
 #define GST_VIDEO_INFO_COMP_STRIDE(i,c)  GST_VIDEO_FORMAT_INFO_STRIDE((i)->finfo,(i)->stride,c)
 #define GST_VIDEO_INFO_COMP_WIDTH(i,c)   GST_VIDEO_FORMAT_INFO_SCALE_WIDTH((i)->finfo,c,(i)->width)
 #define GST_VIDEO_INFO_COMP_HEIGHT(i,c)  GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT((i)->finfo,c,(i)->height)
 #define GST_VIDEO_INFO_COMP_PLANE(i,c)   GST_VIDEO_FORMAT_INFO_PLANE((i)->finfo,c)
-#define GST_VIDEO_INFO_COMP_OFFSET(i,c)  GST_VIDEO_FORMAT_INFO_OFFSET((i)->finfo,c)
 #define GST_VIDEO_INFO_COMP_PSTRIDE(i,c) GST_VIDEO_FORMAT_INFO_PSTRIDE((i)->finfo,c)
+#define GST_VIDEO_INFO_COMP_POFFSET(i,c) GST_VIDEO_FORMAT_INFO_POFFSET((i)->finfo,c)
 
 void         gst_video_info_init        (GstVideoInfo *info);
 
@@ -641,11 +644,12 @@ gboolean    gst_video_frame_copy          (GstVideoFrame *dest, const GstVideoFr
 #define GST_VIDEO_FRAME_N_COMPONENTS(f)   GST_VIDEO_INFO_N_COMPONENTS(&(f)->info)
 #define GST_VIDEO_FRAME_COMP_DATA(f,c)    GST_VIDEO_INFO_COMP_DATA(&(f)->info,(f)->data,c)
 #define GST_VIDEO_FRAME_COMP_STRIDE(f,c)  GST_VIDEO_INFO_COMP_STRIDE(&(f)->info,c)
+#define GST_VIDEO_FRAME_COMP_OFFSET(f,c)  GST_VIDEO_INFO_COMP_OFFSET(&(f)->info,c)
 #define GST_VIDEO_FRAME_COMP_WIDTH(f,c)   GST_VIDEO_INFO_COMP_WIDTH(&(f)->info,c)
 #define GST_VIDEO_FRAME_COMP_HEIGHT(f,c)  GST_VIDEO_INFO_COMP_HEIGHT(&(f)->info,c)
 #define GST_VIDEO_FRAME_COMP_PLANE(f,c)   GST_VIDEO_INFO_COMP_PLANE(&(f)->info,c)
-#define GST_VIDEO_FRAME_COMP_OFFSET(f,c)  GST_VIDEO_INFO_COMP_OFFSET(&(f)->info,c)
 #define GST_VIDEO_FRAME_COMP_PSTRIDE(f,c) GST_VIDEO_INFO_COMP_PSTRIDE(&(f)->info,c)
+#define GST_VIDEO_FRAME_COMP_POFFSET(f,c) GST_VIDEO_INFO_COMP_POFFSET(&(f)->info,c)
 
 #define GST_VIDEO_SIZE_RANGE "(int) [ 1, max ]"
 #define GST_VIDEO_FPS_RANGE "(fraction) [ 0, max ]"
index 7133868..5245a24 100644 (file)
@@ -69,7 +69,7 @@ static void paint_setup_YVYU (paintinfo * p, unsigned char *dest);
 static void paint_setup_IYU2 (paintinfo * p, unsigned char *dest);
 static void paint_setup_Y41B (paintinfo * p, unsigned char *dest);
 static void paint_setup_Y42B (paintinfo * p, unsigned char *dest);
-static void paint_setup_Y800 (paintinfo * p, unsigned char *dest);
+static void paint_setup_GRAY8 (paintinfo * p, unsigned char *dest);
 static void paint_setup_AYUV (paintinfo * p, unsigned char *dest);
 
 #if 0
@@ -138,8 +138,8 @@ struct fourcc_list_struct fourcc_list[] = {
   {"Y41B", "Y41B", 12, paint_setup_Y41B},
   /* Y42B */
   {"Y42B", "Y42B", 16, paint_setup_Y42B},
-  /* Y800 grayscale */
-  {"Y800", "Y800", 8, paint_setup_Y800}
+  /* GRAY8 grayscale */
+  {"GRAY8", "GRAY8", 8, paint_setup_GRAY8}
 };
 
 /* returns the size in bytes for one video frame of the given dimensions
@@ -259,7 +259,7 @@ paint_setup_Y42B (paintinfo * p, unsigned char *dest)
 }
 
 static void
-paint_setup_Y800 (paintinfo * p, unsigned char *dest)
+paint_setup_GRAY8 (paintinfo * p, unsigned char *dest)
 {
   /* untested */
   p->yp = dest;
@@ -334,7 +334,7 @@ video_format_is_packed (GstVideoFormat fmt)
     case GST_VIDEO_FORMAT_YV12:
     case GST_VIDEO_FORMAT_Y41B:
     case GST_VIDEO_FORMAT_Y42B:
-    case GST_VIDEO_FORMAT_Y800:
+    case GST_VIDEO_FORMAT_GRAY8:
     case GST_VIDEO_FORMAT_YUV9:
     case GST_VIDEO_FORMAT_YVU9:
       return FALSE;
@@ -444,6 +444,7 @@ GST_START_TEST (test_video_formats)
         GstVideoInfo vinfo;
         paintinfo paintinfo = { 0, };
         guint off0, off1, off2, off3;
+        guint cs0, cs1, cs2, cs3;
         guint size;
 
         GST_LOG ("%s, %dx%d", fourcc_list[i].fourcc, w, h);
@@ -457,7 +458,7 @@ GST_START_TEST (test_video_formats)
         fail_unless_equals_int (GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0),
             paintinfo.ystride);
         if (!gst_video_format_is_packed (fmt)
-            && !GST_VIDEO_FORMAT_INFO_IS_GRAY (vf_info)) {
+            && !GST_VIDEO_INFO_N_PLANES (&vinfo) > 2) {
           /* planar */
           fail_unless_equals_int (GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 1),
               paintinfo.ustride);
@@ -471,6 +472,11 @@ GST_START_TEST (test_video_formats)
         off1 = GST_VIDEO_INFO_COMP_OFFSET (&vinfo, 1);
         off2 = GST_VIDEO_INFO_COMP_OFFSET (&vinfo, 2);
 
+        GST_INFO ("size %d <> %d", size, paintinfo.endptr);
+        GST_INFO ("off0 %d <> %d", off0, paintinfo.yp);
+        GST_INFO ("off1 %d <> %d", off1, paintinfo.up);
+        GST_INFO ("off2 %d <> %d", off2, paintinfo.vp);
+
         fail_unless_equals_int (size, (unsigned long) paintinfo.endptr);
         fail_unless_equals_int (off0, (unsigned long) paintinfo.yp);
         fail_unless_equals_int (off1, (unsigned long) paintinfo.up);
@@ -480,46 +486,39 @@ GST_START_TEST (test_video_formats)
         off3 = GST_VIDEO_INFO_COMP_OFFSET (&vinfo, 3);
         fail_unless_equals_int (off3, (unsigned long) paintinfo.ap);
 
-        /* some gstvideo checks ... (FIXME: fails for Y41B and Y42B; not sure
-         * if the check or the _get_component_size implementation is wrong) */
-        if (fmt != GST_VIDEO_FORMAT_Y41B && fmt != GST_VIDEO_FORMAT_Y42B
-            && fmt != GST_VIDEO_FORMAT_Y800) {
-          guint cs0, cs1, cs2, cs3;
-
-          cs0 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 0) *
-              GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 0);
-          cs1 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 1) *
-              GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 1);
-          cs2 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 2) *
-              GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 2);
+        cs0 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 0) *
+            GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 0);
+        cs1 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 1) *
+            GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 1);
+        cs2 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 2) *
+            GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 2);
+
+        /* GST_LOG ("cs0=%d,cs1=%d,cs2=%d,off0=%d,off1=%d,off2=%d,size=%d",
+           cs0, cs1, cs2, off0, off1, off2, size); */
 
-          /* GST_LOG ("cs0=%d,cs1=%d,cs2=%d,off0=%d,off1=%d,off2=%d,size=%d",
-             cs0, cs1, cs2, off0, off1, off2, size); */
-
-          if (!gst_video_format_is_packed (fmt))
-            fail_unless (cs0 <= off1);
-
-          if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (vinfo.finfo)) {
-            cs3 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 3) *
-                GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 2);
-            fail_unless (cs3 < size);
-            /* U/V/alpha shouldn't take up more space than the Y component */
-            fail_if (cs1 > cs0, "cs1 (%d) should be <= cs0 (%d)", cs1, cs0);
-            fail_if (cs2 > cs0, "cs2 (%d) should be <= cs0 (%d)", cs2, cs0);
-            fail_if (cs3 > cs0, "cs3 (%d) should be <= cs0 (%d)", cs3, cs0);
-
-            /* all components together shouldn't take up more space than size */
-            fail_unless (cs0 + cs1 + cs2 + cs3 <= size);
-          } else {
-            /* U/V shouldn't take up more space than the Y component */
-            fail_if (cs1 > cs0, "cs1 (%d) should be <= cs0 (%d)", cs1, cs0);
-            fail_if (cs2 > cs0, "cs2 (%d) should be <= cs0 (%d)", cs2, cs0);
-
-            /* all components together shouldn't take up more space than size */
-            fail_unless (cs0 + cs1 + cs2 <= size,
-                "cs0 (%d) + cs1 (%d) + cs2 (%d) should be <= size (%d)",
-                cs0, cs1, cs2, size);
-          }
+        if (!gst_video_format_is_packed (fmt))
+          fail_unless (cs0 <= off1);
+
+        if (GST_VIDEO_FORMAT_INFO_HAS_ALPHA (vinfo.finfo)) {
+          cs3 = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, 3) *
+              GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, 2);
+          fail_unless (cs3 < size);
+          /* U/V/alpha shouldn't take up more space than the Y component */
+          fail_if (cs1 > cs0, "cs1 (%d) should be <= cs0 (%d)", cs1, cs0);
+          fail_if (cs2 > cs0, "cs2 (%d) should be <= cs0 (%d)", cs2, cs0);
+          fail_if (cs3 > cs0, "cs3 (%d) should be <= cs0 (%d)", cs3, cs0);
+
+          /* all components together shouldn't take up more space than size */
+          fail_unless (cs0 + cs1 + cs2 + cs3 <= size);
+        } else {
+          /* U/V shouldn't take up more space than the Y component */
+          fail_if (cs1 > cs0, "cs1 (%d) should be <= cs0 (%d)", cs1, cs0);
+          fail_if (cs2 > cs0, "cs2 (%d) should be <= cs0 (%d)", cs2, cs0);
+
+          /* all components together shouldn't take up more space than size */
+          fail_unless (cs0 + cs1 + cs2 <= size,
+              "cs0 (%d) + cs1 (%d) + cs2 (%d) should be <= size (%d)",
+              cs0, cs1, cs2, size);
         }
       }
     }