v4l2: Fix support for left and top padding

In the current implementation, we support for most pixel format left
and top padding by changing the offset in the video meta. Though, to
align driver bytesused to the offset, we recalculate the offset, which
removed the modification we did before.

Instead, save the plane size, and truncate the driver reported bytesused
to the expected size, which ensures that the offsets still match. This
should also fix issues were the buffer size ended up bigger then the
pool size due to driver introduced padding.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5132>
This commit is contained in:
Nicolas Dufresne 2023-06-22 10:10:43 -04:00 committed by Tim-Philipp Müller
parent bbca6cc8c8
commit 40311bf665
3 changed files with 16 additions and 18 deletions

View file

@ -1237,8 +1237,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
GstV4l2Object *obj = pool->obj;
GstClockTime timestamp;
GstV4l2MemoryGroup *group;
GstVideoMeta *vmeta;
gsize size;
const GstVideoInfo *info = &obj->info;
gint i;
gint old_buffer_state;
@ -1289,9 +1288,9 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp);
size = 0;
vmeta = gst_buffer_get_video_meta (outbuf);
for (i = 0; i < group->n_mem; i++) {
const GstVideoFormatInfo *finfo = info->finfo;
GST_LOG_OBJECT (pool,
"dequeued buffer %p seq:%d (ix=%d), mem %p used %d, plane=%d, flags %08x, ts %"
GST_TIME_FORMAT ", pool-queued=%d, buffer=%p, previous-state=%i",
@ -1299,10 +1298,15 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
group->planes[i].bytesused, i, group->buffer.flags,
GST_TIME_ARGS (timestamp), pool->num_queued, outbuf, old_buffer_state);
if (vmeta) {
vmeta->offset[i] = size;
size += gst_memory_get_sizes (group->mem[i], NULL, NULL);
/* Ensure our offset matches the expected plane size, or image size if
* there is only one memory */
if (group->n_mem == 1) {
gst_memory_resize (group->mem[0], 0, info->size + info->offset[0]);
break;
}
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
gst_memory_resize (group->mem[i], 0, obj->plane_size[i]);
}
/* Ignore timestamp and field for OUTPUT device */

View file

@ -3441,18 +3441,11 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
if ((align->padding_left + align->padding_top) > 0)
GST_WARNING_OBJECT (v4l2object->dbg_obj,
"Left and top padding is not permitted for tiled formats");
memset (v4l2object->plane_size, 0,
sizeof (v4l2object->plane_size[0] * GST_VIDEO_MAX_PLANES));
} else {
for (i = 0; i < finfo->n_planes; i++) {
gint vedge, hedge;
/* FIXME we assume plane as component as this is true for all supported
* format we support. */
hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, i, align->padding_left);
vedge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, align->padding_top);
info->offset[i] += (vedge * info->stride[i]) +
(hedge * GST_VIDEO_INFO_COMP_PSTRIDE (info, i));
if (!gst_video_info_align_full (info, align, v4l2object->plane_size)) {
GST_WARNING_OBJECT (v4l2object->dbg_obj, "Failed to align video info");
}
}

View file

@ -146,6 +146,7 @@ struct _GstV4l2Object {
GstVideoInfo info;
GstVideoAlignment align;
GstVideoTransferFunction transfer;
gsize plane_size[GST_VIDEO_MAX_PLANES];
/* Features */
gboolean need_video_meta;