video-info: add gst_video_info_align_full()
authorGuillaume Desmottes <guillaume.desmottes@collabora.com>
Mon, 3 Jun 2019 10:56:08 +0000 (16:26 +0530)
committerGuillaume Desmottes <guillaume.desmottes@collabora.com>
Sat, 2 Nov 2019 12:05:43 +0000 (13:05 +0100)
When using gst_video_info_align() user had no easy way to retrieve the
padded size and height of each plane.
This can easily be implemented in fill_planes() as it's already called
in align() with the padded height.

Ideally we'd add a plane_size field to GstVideoInfo but the remaining
padding is too small so that would be an ABI break.

Fix #618

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

index 6efb35b..e7fddf0 100644 (file)
@@ -112,7 +112,8 @@ gst_video_info_new (void)
   return info;
 }
 
-static gboolean fill_planes (GstVideoInfo * info);
+static gboolean fill_planes (GstVideoInfo * info,
+    gsize plane_size[GST_VIDEO_MAX_PLANES]);
 
 /**
  * gst_video_info_init:
@@ -253,7 +254,7 @@ gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
   if (!gst_video_info_set_format_common (info, format, width, height))
     return FALSE;
 
-  return fill_planes (info);
+  return fill_planes (info, NULL);
 }
 
 /**
@@ -281,7 +282,7 @@ gst_video_info_set_interlaced_format (GstVideoInfo * info,
     return FALSE;
 
   GST_VIDEO_INFO_INTERLACE_MODE (info) = mode;
-  return fill_planes (info);
+  return fill_planes (info, NULL);
 }
 
 static const gchar *interlace_mode[] = {
@@ -532,7 +533,7 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
     set_default_colorimetry (info);
   }
 
-  if (!fill_planes (info))
+  if (!fill_planes (info, NULL))
     return FALSE;
 
   return TRUE;
@@ -756,7 +757,7 @@ gst_video_info_to_caps (GstVideoInfo * info)
 }
 
 static gboolean
-fill_planes (GstVideoInfo * info)
+fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
 {
   gsize width, height, cr_h;
   gint bpp = 0, i;
@@ -1135,6 +1136,25 @@ fill_planes (GstVideoInfo * info)
       return FALSE;
       break;
   }
+
+  if (plane_size) {
+    for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
+      if (i < GST_VIDEO_INFO_N_PLANES (info)) {
+        gint comps[GST_VIDEO_MAX_COMPONENTS];
+        guint plane_height;
+
+        /* Convert plane index to component index */
+        gst_video_format_info_component (info->finfo, i, comps);
+        plane_height =
+            GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comps[0],
+            GST_VIDEO_INFO_FIELD_HEIGHT (info));
+        plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
+      } else {
+        plane_size[i] = 0;
+      }
+    }
+  }
+
   return TRUE;
 }
 
@@ -1265,21 +1285,26 @@ done:
 }
 
 /**
- * gst_video_info_align:
+ * gst_video_info_align_full:
  * @info: a #GstVideoInfo
  * @align: alignment parameters
+ * @plane_size: (out) (allow-none): array used to store the plane sizes
  *
- * Adjust the offset and stride fields in @info so that the padding and
- * stride alignment in @align is respected.
+ * This variant of gst_video_info_align() provides the updated size, in bytes,
+ * of each video plane after the alignment, including all horizontal and vertical
+ * paddings.
  *
- * Extra padding will be added to the right side when stride alignment padding
- * is required and @align will be updated with the new padding values.
+ * In case of GST_VIDEO_INTERLACE_MODE_ALTERNATE info, the returned sizes are the
+ * ones used to hold a single field, not the full frame.
  *
  * Returns: %FALSE if alignment could not be applied, e.g. because the
- *   size of a frame can't be represented as a 32 bit integer (Since: 1.12)
+ *   size of a frame can't be represented as a 32 bit integer
+ *
+ * Since: 1.18
  */
 gboolean
-gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
+gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
+    gsize plane_size[GST_VIDEO_MAX_PLANES])
 {
   const GstVideoFormatInfo *vinfo = info->finfo;
   gint width, height;
@@ -1331,7 +1356,7 @@ gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
     info->width = padded_width;
     info->height = padded_height;
 
-    if (!fill_planes (info))
+    if (!fill_planes (info, plane_size))
       return FALSE;
 
     /* check alignment */
@@ -1378,3 +1403,23 @@ gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
 
   return TRUE;
 }
+
+/**
+ * gst_video_info_align:
+ * @info: a #GstVideoInfo
+ * @align: alignment parameters
+ *
+ * Adjust the offset and stride fields in @info so that the padding and
+ * stride alignment in @align is respected.
+ *
+ * Extra padding will be added to the right side when stride alignment padding
+ * is required and @align will be updated with the new padding values.
+ *
+ * Returns: %FALSE if alignment could not be applied, e.g. because the
+ *   size of a frame can't be represented as a 32 bit integer (Since: 1.12)
+ */
+gboolean
+gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
+{
+  return gst_video_info_align_full (info, align, NULL);
+}
index 6adf03c..e6a175e 100644 (file)
@@ -385,6 +385,21 @@ GType gst_video_info_get_type            (void);
 #define GST_VIDEO_INFO_N_PLANES(i)       (GST_VIDEO_FORMAT_INFO_N_PLANES((i)->finfo))
 #define GST_VIDEO_INFO_PLANE_OFFSET(i,p) ((i)->offset[p])
 #define GST_VIDEO_INFO_PLANE_STRIDE(i,p) ((i)->stride[p])
+/**
+ * GST_VIDEO_INFO_PLANE_HEIGHT:
+ *
+ * The padded height in pixels of a plane (padded size divided by the plane stride).
+ * In case of GST_VIDEO_INTERLACE_MODE_ALTERNATE info, this macro returns the
+ * plane heights used to hold a single field, not the full frame.
+ *
+ * The size passed as third argument is the size of the pixel data and should
+ * not contain any extra metadata padding.
+ *
+ * It is not valid to use this macro with a TILED format.
+ *
+ * Since: 1.18
+ */
+#define GST_VIDEO_INFO_PLANE_HEIGHT(i,p,sizes) ((i)->stride[p] == 0 ? 0 : sizes[p] / (i)->stride[p])
 
 /* dealing with components */
 #define GST_VIDEO_INFO_N_COMPONENTS(i)   GST_VIDEO_FORMAT_INFO_N_COMPONENTS((i)->finfo)
@@ -444,6 +459,9 @@ gboolean       gst_video_info_is_equal    (const GstVideoInfo *info,
 GST_VIDEO_API
 gboolean       gst_video_info_align       (GstVideoInfo * info, GstVideoAlignment * align);
 
+GST_VIDEO_API
+gboolean       gst_video_info_align_full  (GstVideoInfo * info, GstVideoAlignment * align, gsize plane_size[GST_VIDEO_MAX_PLANES]);
+
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVideoInfo, gst_video_info_free)
 
index 7b901a6..4190067 100644 (file)
@@ -3303,6 +3303,329 @@ GST_START_TEST (test_video_format_info_plane_to_components)
 
 GST_END_TEST;
 
+GST_START_TEST (test_video_info_align)
+{
+  GstVideoInfo info;
+  GstVideoAlignment align;
+  gsize plane_size[GST_VIDEO_MAX_PLANES];
+
+  /* NV12 */
+  gst_video_info_init (&info);
+  gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV12, 1920, 1080);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1080 * 1.5);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1080);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1080 / 2);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      540);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 8;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1088);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1088 / 2);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1088 * 1.5);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1088);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      544);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  /* NV16 */
+  gst_video_info_init (&info);
+  gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV16, 1920, 1080);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1080 * 2);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1080);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1080);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 8;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1088 * 2);
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1088);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1088);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1088);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      1088);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  /* RGB */
+  gst_video_info_init (&info);
+  gst_video_info_set_format (&info, GST_VIDEO_FORMAT_RGB, 1920, 1080);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1080 * 3);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1080 * 3);
+  g_assert_cmpuint (plane_size[1], ==, 0);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 5760);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 8;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1088 * 3);
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1088 * 3);
+  g_assert_cmpuint (plane_size[1], ==, 0);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 5760);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1088);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  /* I420 */
+  gst_video_info_init (&info);
+  gst_video_info_set_format (&info, GST_VIDEO_FORMAT_I420, 1920, 1080);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1080 * 1.5);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1080);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1080 / 4);
+  g_assert_cmpuint (plane_size[2], ==, 1920 * 1080 / 4);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 960);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 960);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      540);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==,
+      540);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 8;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 1088 * 1.5);
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 1088);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 1088 / 4);
+  g_assert_cmpuint (plane_size[2], ==, 1920 * 1088 / 4);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 960);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 960);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      1088);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      544);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==,
+      544);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  /* NV16 alternate */
+  gst_video_info_init (&info);
+  gst_video_info_set_interlaced_format (&info, GST_VIDEO_FORMAT_NV16,
+      GST_VIDEO_INTERLACE_MODE_ALTERNATE, 1920, 1080);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 540);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 540 * 2);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 540);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 540);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      540);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      540);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 8;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1080);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 540);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 544 * 2);
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 544);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 544);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      544);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      544);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  /* NV16 alternate with an odd height */
+  gst_video_info_init (&info);
+  gst_video_info_set_interlaced_format (&info, GST_VIDEO_FORMAT_NV16,
+      GST_VIDEO_INTERLACE_MODE_ALTERNATE, 1920, 1081);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1081);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 541);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 541 * 2);
+
+  gst_video_alignment_reset (&align);
+  /* Align with no padding to retrieve the plane heights */
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 541);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 541);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      541);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      541);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+
+  gst_video_alignment_reset (&align);
+  align.padding_bottom = 2;
+  g_assert (gst_video_info_align_full (&info, &align, plane_size));
+
+  g_assert_cmpuint (GST_VIDEO_INFO_HEIGHT (&info), ==, 1081);
+  g_assert_cmpuint (GST_VIDEO_INFO_FIELD_HEIGHT (&info), ==, 541);
+  g_assert_cmpuint (GST_VIDEO_INFO_SIZE (&info), ==, 1920 * 542 * 2);
+
+  g_assert_cmpuint (plane_size[0], ==, 1920 * 542);
+  g_assert_cmpuint (plane_size[1], ==, 1920 * 542);
+  g_assert_cmpuint (plane_size[2], ==, 0);
+  g_assert_cmpuint (plane_size[3], ==, 0);
+
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 1), ==, 1920);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 2), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_STRIDE (&info, 3), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), ==,
+      542);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 1, plane_size), ==,
+      542);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 2, plane_size), ==, 0);
+  g_assert_cmpuint (GST_VIDEO_INFO_PLANE_HEIGHT (&info, 3, plane_size), ==, 0);
+}
+
+GST_END_TEST;
+
 static Suite *
 video_suite (void)
 {
@@ -3351,6 +3674,7 @@ video_suite (void)
   tcase_add_test (tc_chain, test_hdr);
   tcase_add_test (tc_chain, test_video_color_from_to_iso);
   tcase_add_test (tc_chain, test_video_format_info_plane_to_components);
+  tcase_add_test (tc_chain, test_video_info_align);
 
   return s;
 }