video: Pass component index not plane index
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 18 May 2021 19:36:36 +0000 (15:36 -0400)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 19 May 2021 15:17:56 +0000 (15:17 +0000)
While so far it worked, we are about to introduce a format that break this
assuming. We have a format which consist of NV12 with alpha, and this format
does not have a direct mapping of the component against their plane indexes.

Fix this by using gst_video_format_info_component() introduced in 1.18 for
this purpose.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1151>

gst-libs/gst/gl/egl/gsteglimage.c
gst-libs/gst/gl/gstglmemory.c
gst-libs/gst/gl/gstglutils.c
gst-libs/gst/video/video-converter.c
gst-libs/gst/video/video-frame.c
gst-libs/gst/video/video-info.c
gst/compositor/compositor.c
gst/rawparse/gstrawvideoparse.c

index 6622617..173f88e 100644 (file)
@@ -573,6 +573,7 @@ GstEGLImage *
 gst_egl_image_from_dmabuf (GstGLContext * context,
     gint dmabuf, const GstVideoInfo * in_info, gint plane, gsize offset)
 {
+  gint comp[GST_VIDEO_MAX_COMPONENTS];
   GstGLFormat format = 0;
   guintptr attribs[13];
   EGLImageKHR img;
@@ -580,16 +581,17 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
   gint fourcc;
   gint i;
 
+  gst_video_format_info_component (in_info->finfo, plane, comp);
   fourcc = _drm_rgba_fourcc_from_info (in_info, plane, &format);
   GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)",
       (char *) &fourcc, fourcc, plane,
-      GST_VIDEO_INFO_COMP_WIDTH (in_info, plane),
-      GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane));
+      GST_VIDEO_INFO_COMP_WIDTH (in_info, comp[0]),
+      GST_VIDEO_INFO_COMP_HEIGHT (in_info, comp[0]));
 
   attribs[atti++] = EGL_WIDTH;
-  attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane);
+  attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, comp[0]);
   attribs[atti++] = EGL_HEIGHT;
-  attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane);
+  attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, comp[0]);
   attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
   attribs[atti++] = fourcc;
   attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
@@ -597,7 +599,7 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
   attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
   attribs[atti++] = offset;
   attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
-  attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane);
+  attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, comp[0]);
   attribs[atti] = EGL_NONE;
   g_assert (atti == G_N_ELEMENTS (attribs) - 1);
 
index e95ff55..dbc765a 100644 (file)
@@ -107,25 +107,27 @@ typedef struct
 static inline guint
 _get_plane_width (const GstVideoInfo * info, guint plane)
 {
-  if (GST_VIDEO_INFO_IS_YUV (info))
-    /* For now component width and plane width are the same and the
-     * plane-component mapping matches
-     */
-    return GST_VIDEO_INFO_COMP_WIDTH (info, plane);
-  else                          /* RGB, GRAY */
+  if (GST_VIDEO_INFO_IS_YUV (info)) {
+    gint comp[GST_VIDEO_MAX_COMPONENTS];
+    gst_video_format_info_component (info->finfo, plane, comp);
+    return GST_VIDEO_INFO_COMP_WIDTH (info, comp[0]);
+  } else {
+    /* RGB, GRAY */
     return GST_VIDEO_INFO_WIDTH (info);
+  }
 }
 
 static inline guint
 _get_plane_height (const GstVideoInfo * info, guint plane)
 {
-  if (GST_VIDEO_INFO_IS_YUV (info))
-    /* For now component width and plane width are the same and the
-     * plane-component mapping matches
-     */
-    return GST_VIDEO_INFO_COMP_HEIGHT (info, plane);
-  else                          /* RGB, GRAY */
+  if (GST_VIDEO_INFO_IS_YUV (info)) {
+    gint comp[GST_VIDEO_MAX_COMPONENTS];
+    gst_video_format_info_component (info->finfo, plane, comp);
+    return GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]);
+  } else {
+    /* RGB, GRAY */
     return GST_VIDEO_INFO_HEIGHT (info);
+  }
 }
 
 static inline void
index 899c6ec..52fa7d8 100644 (file)
@@ -613,16 +613,19 @@ gsize
 gst_gl_get_plane_data_size (const GstVideoInfo * info,
     const GstVideoAlignment * align, guint plane)
 {
+  gint comp[GST_VIDEO_MAX_COMPONENTS];
   gint padded_height;
   gsize plane_size;
 
+  gst_video_format_info_component (info->finfo, plane, comp);
+
   padded_height = info->height;
 
   if (align)
     padded_height += align->padding_top + align->padding_bottom;
 
   padded_height =
-      GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, plane, padded_height);
+      GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0], padded_height);
 
   plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height;
 
index 93186fe..1980b63 100644 (file)
@@ -5968,24 +5968,27 @@ convert_fill_border (GstVideoConverter * convert, GstVideoFrame * dest)
   n_planes = GST_VIDEO_FRAME_N_PLANES (dest);
 
   for (k = 0; k < n_planes; k++) {
+    gint comp[GST_VIDEO_MAX_COMPONENTS];
     gint i, out_x, out_y, out_width, out_height, pstride, pgroup;
     gint r_border, lb_width, rb_width;
     gint out_maxwidth, out_maxheight;
     gpointer borders;
 
-    out_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_x);
-    out_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_y);
-    out_width =
-        GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_width);
-    out_height =
-        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_height);
-    out_maxwidth =
-        GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_maxwidth);
-    out_maxheight =
-        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k,
+    gst_video_format_info_component (out_finfo, k, comp);
+    out_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, comp[0],
+        convert->out_x);
+    out_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, comp[0],
+        convert->out_y);
+    out_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, comp[0],
+        convert->out_width);
+    out_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, comp[0],
+        convert->out_height);
+    out_maxwidth = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, comp[0],
+        convert->out_maxwidth);
+    out_maxheight = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, comp[0],
         convert->out_maxheight);
 
-    pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, k);
+    pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, comp[0]);
 
     switch (GST_VIDEO_FORMAT_INFO_FORMAT (out_finfo)) {
       case GST_VIDEO_FORMAT_YUY2:
@@ -6806,45 +6809,49 @@ setup_scale (GstVideoConverter * convert)
     convert->fsplane[0] = 0;
   } else {
     for (i = 0; i < n_planes; i++) {
-      gint comp, n_comp, j, iw, ih, ow, oh, pstride;
+      gint out_comp[GST_VIDEO_MAX_COMPONENTS];
+      gint comp, j, iw, ih, ow, oh, pstride;
       gboolean need_v_scaler, need_h_scaler;
       GstStructure *config;
       gint resample_method;
 
-      n_comp = GST_VIDEO_FORMAT_INFO_N_COMPONENTS (in_finfo);
+      gst_video_format_info_component (out_finfo, i, out_comp);
+      ow = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, out_comp[0],
+          out_width);
+      oh = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, out_comp[0],
+          out_height);
+      pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, out_comp[0]);
 
       /* find the component in this plane and map it to the plane of
        * the source */
-      comp = -1;
-      for (j = 0; j < n_comp; j++) {
-        if (GST_VIDEO_FORMAT_INFO_PLANE (out_finfo, j) == i) {
-          comp = j;
-          break;
-        }
+      if (out_comp[0] < GST_VIDEO_FORMAT_INFO_N_COMPONENTS (in_finfo)) {
+        comp = out_comp[0];
+        iw = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, comp, in_width);
+        ih = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, comp, in_height);
+        convert->fin_x[i] = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, comp,
+            convert->in_x);
+        convert->fin_x[i] *= pstride;
+        convert->fin_y[i] = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, comp,
+            convert->in_y);
+      } else {
+        /* we will use a fill instead, setting the parameters to an invalid
+         * size to reduce confusion */
+        comp = -1;
+        iw = ih = -1;
+        convert->fin_x[i] = -1;
+        convert->fin_y[i] = -1;
       }
 
-      iw = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, i, in_width);
-      ih = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, i, in_height);
-      ow = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, i, out_width);
-      oh = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, out_height);
-
-      GST_DEBUG ("plane %d: %dx%d -> %dx%d", i, iw, ih, ow, oh);
-
       convert->fout_width[i] = ow;
       convert->fout_height[i] = oh;
 
-      pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, i);
-      convert->fin_x[i] =
-          GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, i, convert->in_x);
-      convert->fin_x[i] *= pstride;
-      convert->fin_y[i] =
-          GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, i, convert->in_y);
-      convert->fout_x[i] =
-          GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, i, convert->out_x);
+      convert->fout_x[i] = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo,
+          out_comp[0], convert->out_x);
       convert->fout_x[i] *= pstride;
-      convert->fout_y[i] =
-          GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, convert->out_y);
+      convert->fout_y[i] = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo,
+          out_comp[0], convert->out_y);
 
+      GST_DEBUG ("plane %d: %dx%d -> %dx%d", i, iw, ih, ow, oh);
       GST_DEBUG ("plane %d: pstride %d", i, pstride);
       GST_DEBUG ("plane %d: in_x %d, in_y %d", i, convert->fin_x[i],
           convert->fin_y[i]);
index c969bc7..a4f7365 100644 (file)
@@ -298,6 +298,7 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
   const GstVideoInfo *sinfo;
   GstVideoInfo *dinfo;
   const GstVideoFormatInfo *finfo;
+  gint comp[GST_VIDEO_MAX_COMPONENTS];
   guint8 *sp, *dp;
   guint w, h;
   gint ss, ds;
@@ -325,17 +326,16 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
     return TRUE;
   }
 
-  /* FIXME: assumes subsampling of component N is the same as plane N, which is
-   * currently true for all formats we have but it might not be in the future. */
+  gst_video_format_info_component (finfo, plane, comp);
   w = GST_VIDEO_FRAME_COMP_WIDTH (dest,
-      plane) * GST_VIDEO_FRAME_COMP_PSTRIDE (dest, plane);
+      comp[0]) * GST_VIDEO_FRAME_COMP_PSTRIDE (dest, comp[0]);
   /* FIXME: workaround for complex formats like v210, UYVP and IYU1 that have
    * pstride == 0 */
   if (w == 0)
     w = MIN (GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane),
         GST_VIDEO_INFO_PLANE_STRIDE (sinfo, plane));
 
-  h = GST_VIDEO_FRAME_COMP_HEIGHT (dest, plane);
+  h = GST_VIDEO_FRAME_COMP_HEIGHT (dest, comp[0]);
 
   ss = GST_VIDEO_INFO_PLANE_STRIDE (sinfo, plane);
   ds = GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane);
index 6f9fc7b..3d2abcf 100644 (file)
@@ -1176,13 +1176,13 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
   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];
+        gint comp[GST_VIDEO_MAX_COMPONENTS];
         guint plane_height;
 
         /* Convert plane index to component index */
-        gst_video_format_info_component (info->finfo, i, comps);
+        gst_video_format_info_component (info->finfo, i, comp);
         plane_height =
-            GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comps[0],
+            GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0],
             GST_VIDEO_INFO_FIELD_HEIGHT (info));
         plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
       } else {
@@ -1367,11 +1367,14 @@ gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
     GST_LOG ("left padding %u", align->padding_left);
     aligned = TRUE;
     for (i = 0; i < n_planes; i++) {
+      gint comp[GST_VIDEO_MAX_COMPONENTS];
       gint hedge;
 
       /* this is the amount of pixels to add as left padding */
-      hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left);
-      hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i);
+      gst_video_format_info_component (vinfo, i, comp);
+      hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0],
+          align->padding_left);
+      hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0]);
 
       GST_LOG ("plane %d, padding %d, alignment %u", i, hedge,
           align->stride_align[i]);
@@ -1419,25 +1422,20 @@ gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
   info->height = height;
 
   for (i = 0; i < n_planes; i++) {
-    gint vedge, hedge, comp;
-
-    /* Find the component for this plane, FIXME, we assume the plane number and
-     * component number is the same for now, for scaling the dimensions this is
-     * currently true for all formats but it might not be when adding new
-     * formats. We might need to add a plane subsamling in the format info to
-     * make this more generic or maybe use a plane -> component mapping. */
-    comp = i;
+    gint comp[GST_VIDEO_MAX_COMPONENTS];
+    gint vedge, hedge;
 
+    gst_video_format_info_component (info->finfo, i, comp);
     hedge =
-        GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp, align->padding_left);
+        GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0], align->padding_left);
     vedge =
-        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp, align->padding_top);
+        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp[0], align->padding_top);
 
     GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i,
-        comp, hedge, vedge, align->stride_align[i], info->stride[i]);
+        comp[0], hedge, vedge, align->stride_align[i], info->stride[i]);
 
     info->offset[i] += (vedge * info->stride[i]) +
-        (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));
+        (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0]));
   }
 
   return TRUE;
index 8a891f1..16012aa 100644 (file)
@@ -1116,6 +1116,7 @@ _draw_background (GstCompositor * comp, GstVideoFrame * outframe,
       num_planes = GST_VIDEO_FRAME_N_PLANES (outframe);
       for (plane = 0; plane < num_planes; ++plane) {
         const GstVideoFormatInfo *info;
+        gint comp[GST_VIDEO_MAX_COMPONENTS];
         guint8 *pdata;
         gsize rowsize, plane_stride;
         gint yoffset;
@@ -1123,12 +1124,14 @@ _draw_background (GstCompositor * comp, GstVideoFrame * outframe,
         info = outframe->info.finfo;
         pdata = GST_VIDEO_FRAME_PLANE_DATA (outframe, plane);
         plane_stride = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, plane);
-        rowsize = GST_VIDEO_FRAME_COMP_WIDTH (outframe, plane)
-            * GST_VIDEO_FRAME_COMP_PSTRIDE (outframe, plane);
-        height =
-            GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, plane, (y_end - y_start));
 
-        yoffset = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, plane, y_start);
+        gst_video_format_info_component (info, plane, comp);
+        rowsize = GST_VIDEO_FRAME_COMP_WIDTH (outframe, comp[0])
+            * GST_VIDEO_FRAME_COMP_PSTRIDE (outframe, comp[0]);
+        height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, comp[0],
+            (y_end - y_start));
+
+        yoffset = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info, comp[0], y_start);
 
         pdata += yoffset * plane_stride;
         for (i = 0; i < height; ++i) {
index 066dd2a..fd1a993 100644 (file)
@@ -1165,10 +1165,12 @@ gst_raw_video_parse_update_info (GstRawVideoParseConfig * config)
     gint tile_height = 1 << GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
     last_plane_size = x_tiles * y_tiles * tile_width * tile_height;
   } else {
+    gint comp[GST_VIDEO_MAX_COMPONENTS];
+    gst_video_format_info_component (info->finfo, last_plane, comp);
     last_plane_size =
         GST_VIDEO_INFO_PLANE_STRIDE (info,
         last_plane) * GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo,
-        last_plane, config->height);
+        comp[0], config->height);
   }
 
   GST_VIDEO_INFO_SIZE (info) = last_plane_offset + last_plane_size;