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,
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);

View 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

View 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;

View 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]);

View 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);

View 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;

View 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) {

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);
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;