mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-03 05:05:52 +00:00
v4l2codecs: Add support for multi planar buffers
V4L2 have some pixel formats that produces 2 dmabuf, this add support for these format. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1567>
This commit is contained in:
parent
e2b2ff26c9
commit
3005dbc55a
|
@ -102,12 +102,21 @@ gst_v4l2_format_to_video_info (struct v4l2_format *fmt, GstVideoInfo * out_info)
|
|||
struct v4l2_pix_format *pix = &fmt->fmt.pix;
|
||||
gint plane;
|
||||
gsize offset = 0;
|
||||
gboolean extrapolate = FALSE;
|
||||
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
if (entry->num_planes != 1) {
|
||||
GST_FIXME ("Multi allocation formats are not supported yet");
|
||||
/* validate the entry against the format */
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (fmt->type)) {
|
||||
if (entry->num_planes != pix_mp->num_planes) {
|
||||
GST_ERROR ("Miss-matched number of planes in internal entry "
|
||||
"(%i != %i)", entry->num_planes, pix_mp->num_planes);
|
||||
return FALSE;
|
||||
}
|
||||
} else if (entry->num_planes != 1) {
|
||||
GST_ERROR ("Miss-matched number of planes in internal entry "
|
||||
"(must be 1 for non-multiplanar, got %i)", entry->num_planes);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -116,28 +125,52 @@ gst_v4l2_format_to_video_info (struct v4l2_format *fmt, GstVideoInfo * out_info)
|
|||
return FALSE;
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (fmt->type)) {
|
||||
/* TODO: We don't support multi-allocation yet */
|
||||
g_return_val_if_fail (pix_mp->num_planes == 1, FALSE);
|
||||
out_info->size = pix_mp->plane_fmt[0].sizeimage;
|
||||
out_info->size = 0;
|
||||
for (plane = 0; plane < pix_mp->num_planes; plane++)
|
||||
out_info->size += pix_mp->plane_fmt[plane].sizeimage;
|
||||
} else {
|
||||
out_info->size = pix->sizeimage;
|
||||
}
|
||||
|
||||
/*
|
||||
* When single allocation formats are used for planar formats we need to
|
||||
* extrapolate the per-plane stride. Do this check once to prevent
|
||||
* complex inner loop.
|
||||
*/
|
||||
if (entry->num_planes == 1 && out_info->finfo->n_planes != entry->num_planes)
|
||||
extrapolate = TRUE;
|
||||
|
||||
for (plane = 0; plane < GST_VIDEO_INFO_N_PLANES (out_info); plane++) {
|
||||
gint stride;
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (fmt->type))
|
||||
stride = gst_video_format_info_extrapolate_stride (out_info->finfo, plane,
|
||||
pix_mp->plane_fmt[0].bytesperline);
|
||||
else
|
||||
stride = gst_video_format_info_extrapolate_stride (out_info->finfo, plane,
|
||||
pix->bytesperline);
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (fmt->type)) {
|
||||
if (extrapolate)
|
||||
stride = gst_video_format_info_extrapolate_stride (out_info->finfo,
|
||||
plane, pix_mp->plane_fmt[0].bytesperline);
|
||||
else
|
||||
stride = pix_mp->plane_fmt[plane].bytesperline;
|
||||
} else {
|
||||
if (extrapolate)
|
||||
stride = gst_video_format_info_extrapolate_stride (out_info->finfo,
|
||||
plane, pix->bytesperline);
|
||||
else
|
||||
stride = pix->bytesperline;
|
||||
}
|
||||
|
||||
set_stride (out_info, plane, stride);
|
||||
out_info->offset[plane] = offset;
|
||||
|
||||
offset += stride * GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_info->finfo,
|
||||
plane, pix_mp->height);
|
||||
if ((V4L2_TYPE_IS_MULTIPLANAR (fmt->type) && !extrapolate))
|
||||
offset += pix_mp->plane_fmt[plane].sizeimage;
|
||||
else
|
||||
offset += stride * GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_info->finfo,
|
||||
plane, pix_mp->height);
|
||||
}
|
||||
|
||||
/* Check that the extrapolation didn't overflow the reported sizeimage */
|
||||
if (extrapolate && offset > out_info->size) {
|
||||
GST_ERROR ("Extrapolated plane offset overflow the image size.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in a new issue