video: Pass component index not plane index

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>
This commit is contained in:
Nicolas Dufresne 2021-05-18 15:36:36 -04:00 committed by GStreamer Marge Bot
parent 42512c92de
commit 3897b24f69
8 changed files with 98 additions and 81 deletions

View file

@ -573,6 +573,7 @@ GstEGLImage *
gst_egl_image_from_dmabuf (GstGLContext * context, gst_egl_image_from_dmabuf (GstGLContext * context,
gint dmabuf, const GstVideoInfo * in_info, gint plane, gsize offset) gint dmabuf, const GstVideoInfo * in_info, gint plane, gsize offset)
{ {
gint comp[GST_VIDEO_MAX_COMPONENTS];
GstGLFormat format = 0; GstGLFormat format = 0;
guintptr attribs[13]; guintptr attribs[13];
EGLImageKHR img; EGLImageKHR img;
@ -580,16 +581,17 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
gint fourcc; gint fourcc;
gint i; gint i;
gst_video_format_info_component (in_info->finfo, plane, comp);
fourcc = _drm_rgba_fourcc_from_info (in_info, plane, &format); fourcc = _drm_rgba_fourcc_from_info (in_info, plane, &format);
GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)", GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)",
(char *) &fourcc, fourcc, plane, (char *) &fourcc, fourcc, plane,
GST_VIDEO_INFO_COMP_WIDTH (in_info, plane), GST_VIDEO_INFO_COMP_WIDTH (in_info, comp[0]),
GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane)); GST_VIDEO_INFO_COMP_HEIGHT (in_info, comp[0]));
attribs[atti++] = EGL_WIDTH; 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++] = 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++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[atti++] = fourcc; attribs[atti++] = fourcc;
attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; 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++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
attribs[atti++] = offset; attribs[atti++] = offset;
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; 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; attribs[atti] = EGL_NONE;
g_assert (atti == G_N_ELEMENTS (attribs) - 1); g_assert (atti == G_N_ELEMENTS (attribs) - 1);

View file

@ -107,25 +107,27 @@ typedef struct
static inline guint static inline guint
_get_plane_width (const GstVideoInfo * info, guint plane) _get_plane_width (const GstVideoInfo * info, guint plane)
{ {
if (GST_VIDEO_INFO_IS_YUV (info)) if (GST_VIDEO_INFO_IS_YUV (info)) {
/* For now component width and plane width are the same and the gint comp[GST_VIDEO_MAX_COMPONENTS];
* plane-component mapping matches gst_video_format_info_component (info->finfo, plane, comp);
*/ return GST_VIDEO_INFO_COMP_WIDTH (info, comp[0]);
return GST_VIDEO_INFO_COMP_WIDTH (info, plane); } else {
else /* RGB, GRAY */ /* RGB, GRAY */
return GST_VIDEO_INFO_WIDTH (info); return GST_VIDEO_INFO_WIDTH (info);
}
} }
static inline guint static inline guint
_get_plane_height (const GstVideoInfo * info, guint plane) _get_plane_height (const GstVideoInfo * info, guint plane)
{ {
if (GST_VIDEO_INFO_IS_YUV (info)) if (GST_VIDEO_INFO_IS_YUV (info)) {
/* For now component width and plane width are the same and the gint comp[GST_VIDEO_MAX_COMPONENTS];
* plane-component mapping matches gst_video_format_info_component (info->finfo, plane, comp);
*/ return GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]);
return GST_VIDEO_INFO_COMP_HEIGHT (info, plane); } else {
else /* RGB, GRAY */ /* RGB, GRAY */
return GST_VIDEO_INFO_HEIGHT (info); return GST_VIDEO_INFO_HEIGHT (info);
}
} }
static inline void static inline void

View file

@ -613,16 +613,19 @@ gsize
gst_gl_get_plane_data_size (const GstVideoInfo * info, gst_gl_get_plane_data_size (const GstVideoInfo * info,
const GstVideoAlignment * align, guint plane) const GstVideoAlignment * align, guint plane)
{ {
gint comp[GST_VIDEO_MAX_COMPONENTS];
gint padded_height; gint padded_height;
gsize plane_size; gsize plane_size;
gst_video_format_info_component (info->finfo, plane, comp);
padded_height = info->height; padded_height = info->height;
if (align) if (align)
padded_height += align->padding_top + align->padding_bottom; padded_height += align->padding_top + align->padding_bottom;
padded_height = 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; plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height;

View file

@ -5968,24 +5968,27 @@ convert_fill_border (GstVideoConverter * convert, GstVideoFrame * dest)
n_planes = GST_VIDEO_FRAME_N_PLANES (dest); n_planes = GST_VIDEO_FRAME_N_PLANES (dest);
for (k = 0; k < n_planes; k++) { 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 i, out_x, out_y, out_width, out_height, pstride, pgroup;
gint r_border, lb_width, rb_width; gint r_border, lb_width, rb_width;
gint out_maxwidth, out_maxheight; gint out_maxwidth, out_maxheight;
gpointer borders; gpointer borders;
out_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_x); gst_video_format_info_component (out_finfo, k, comp);
out_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_y); out_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, comp[0],
out_width = convert->out_x);
GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_width); out_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, comp[0],
out_height = convert->out_y);
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_height); out_width = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, comp[0],
out_maxwidth = convert->out_width);
GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_maxwidth); out_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, comp[0],
out_maxheight = convert->out_height);
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, 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); 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)) { switch (GST_VIDEO_FORMAT_INFO_FORMAT (out_finfo)) {
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
@ -6806,45 +6809,49 @@ setup_scale (GstVideoConverter * convert)
convert->fsplane[0] = 0; convert->fsplane[0] = 0;
} else { } else {
for (i = 0; i < n_planes; i++) { 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; gboolean need_v_scaler, need_h_scaler;
GstStructure *config; GstStructure *config;
gint resample_method; 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 /* find the component in this plane and map it to the plane of
* the source */ * the source */
comp = -1; if (out_comp[0] < GST_VIDEO_FORMAT_INFO_N_COMPONENTS (in_finfo)) {
for (j = 0; j < n_comp; j++) { comp = out_comp[0];
if (GST_VIDEO_FORMAT_INFO_PLANE (out_finfo, j) == i) { iw = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, comp, in_width);
comp = j; ih = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, comp, in_height);
break; 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_width[i] = ow;
convert->fout_height[i] = oh; convert->fout_height[i] = oh;
pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, i); convert->fout_x[i] = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo,
convert->fin_x[i] = out_comp[0], convert->out_x);
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] *= pstride; convert->fout_x[i] *= pstride;
convert->fout_y[i] = convert->fout_y[i] = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo,
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, convert->out_y); 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: pstride %d", i, pstride);
GST_DEBUG ("plane %d: in_x %d, in_y %d", i, convert->fin_x[i], GST_DEBUG ("plane %d: in_x %d, in_y %d", i, convert->fin_x[i],
convert->fin_y[i]); convert->fin_y[i]);

View file

@ -298,6 +298,7 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
const GstVideoInfo *sinfo; const GstVideoInfo *sinfo;
GstVideoInfo *dinfo; GstVideoInfo *dinfo;
const GstVideoFormatInfo *finfo; const GstVideoFormatInfo *finfo;
gint comp[GST_VIDEO_MAX_COMPONENTS];
guint8 *sp, *dp; guint8 *sp, *dp;
guint w, h; guint w, h;
gint ss, ds; gint ss, ds;
@ -325,17 +326,16 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
return TRUE; return TRUE;
} }
/* FIXME: assumes subsampling of component N is the same as plane N, which is gst_video_format_info_component (finfo, plane, comp);
* currently true for all formats we have but it might not be in the future. */
w = GST_VIDEO_FRAME_COMP_WIDTH (dest, 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 /* FIXME: workaround for complex formats like v210, UYVP and IYU1 that have
* pstride == 0 */ * pstride == 0 */
if (w == 0) if (w == 0)
w = MIN (GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane), w = MIN (GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane),
GST_VIDEO_INFO_PLANE_STRIDE (sinfo, 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); ss = GST_VIDEO_INFO_PLANE_STRIDE (sinfo, plane);
ds = GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane); ds = GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane);

View file

@ -1176,13 +1176,13 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
if (plane_size) { if (plane_size) {
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) { for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
if (i < GST_VIDEO_INFO_N_PLANES (info)) { if (i < GST_VIDEO_INFO_N_PLANES (info)) {
gint comps[GST_VIDEO_MAX_COMPONENTS]; gint comp[GST_VIDEO_MAX_COMPONENTS];
guint plane_height; guint plane_height;
/* Convert plane index to component index */ /* 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 = 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)); GST_VIDEO_INFO_FIELD_HEIGHT (info));
plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i); plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
} else { } else {
@ -1367,11 +1367,14 @@ gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
GST_LOG ("left padding %u", align->padding_left); GST_LOG ("left padding %u", align->padding_left);
aligned = TRUE; aligned = TRUE;
for (i = 0; i < n_planes; i++) { for (i = 0; i < n_planes; i++) {
gint comp[GST_VIDEO_MAX_COMPONENTS];
gint hedge; gint hedge;
/* this is the amount of pixels to add as left padding */ /* this is the amount of pixels to add as left padding */
hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left); gst_video_format_info_component (vinfo, i, comp);
hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i); 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, GST_LOG ("plane %d, padding %d, alignment %u", i, hedge,
align->stride_align[i]); align->stride_align[i]);
@ -1419,25 +1422,20 @@ gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
info->height = height; info->height = height;
for (i = 0; i < n_planes; i++) { for (i = 0; i < n_planes; i++) {
gint vedge, hedge, comp; gint comp[GST_VIDEO_MAX_COMPONENTS];
gint vedge, hedge;
/* 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;
gst_video_format_info_component (info->finfo, i, comp);
hedge = 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 = 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, 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]) + 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; return TRUE;

View file

@ -1116,6 +1116,7 @@ _draw_background (GstCompositor * comp, GstVideoFrame * outframe,
num_planes = GST_VIDEO_FRAME_N_PLANES (outframe); num_planes = GST_VIDEO_FRAME_N_PLANES (outframe);
for (plane = 0; plane < num_planes; ++plane) { for (plane = 0; plane < num_planes; ++plane) {
const GstVideoFormatInfo *info; const GstVideoFormatInfo *info;
gint comp[GST_VIDEO_MAX_COMPONENTS];
guint8 *pdata; guint8 *pdata;
gsize rowsize, plane_stride; gsize rowsize, plane_stride;
gint yoffset; gint yoffset;
@ -1123,12 +1124,14 @@ _draw_background (GstCompositor * comp, GstVideoFrame * outframe,
info = outframe->info.finfo; info = outframe->info.finfo;
pdata = GST_VIDEO_FRAME_PLANE_DATA (outframe, plane); pdata = GST_VIDEO_FRAME_PLANE_DATA (outframe, plane);
plane_stride = GST_VIDEO_FRAME_PLANE_STRIDE (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; pdata += yoffset * plane_stride;
for (i = 0; i < height; ++i) { for (i = 0; i < height; ++i) {

View 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); gint tile_height = 1 << GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
last_plane_size = x_tiles * y_tiles * tile_width * tile_height; last_plane_size = x_tiles * y_tiles * tile_width * tile_height;
} else { } else {
gint comp[GST_VIDEO_MAX_COMPONENTS];
gst_video_format_info_component (info->finfo, last_plane, comp);
last_plane_size = last_plane_size =
GST_VIDEO_INFO_PLANE_STRIDE (info, GST_VIDEO_INFO_PLANE_STRIDE (info,
last_plane) * GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, 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; GST_VIDEO_INFO_SIZE (info) = last_plane_offset + last_plane_size;