Commit a7286563 authored by Nicolas Dufresne's avatar Nicolas Dufresne
Browse files

v4l2: Add initial support for alignment and cropping

parent 70e7868f
......@@ -141,11 +141,13 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
GstV4l2Meta *meta;
GstV4l2Object *obj;
GstVideoInfo *info;
GstVideoAlignment *align;
guint index;
gint i;
obj = pool->obj;
info = &obj->info;
align = &obj->align;
switch (obj->mode) {
case GST_V4L2_IO_RW:
......@@ -339,6 +341,15 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
GST_VIDEO_INFO_FORMAT (info), width, height, n_gst_planes,
offset, stride);
}
if (pool->add_cropmeta) {
GstVideoCropMeta *crop;
crop = gst_buffer_add_video_crop_meta (newbuf);
crop->x = align->padding_left;
crop->y = align->padding_top;
crop->width = info->width;
crop->width = info->height;
}
break;
}
case GST_V4L2_IO_USERPTR:
......@@ -1666,3 +1677,9 @@ start_failed:
return FALSE;
}
}
void
gst_v4l2_buffer_pool_add_crop_meta (GstV4l2BufferPool * bpool, gboolean add)
{
bpool->add_cropmeta = add;
}
......@@ -54,6 +54,7 @@ struct _GstV4l2BufferPool
GstAllocationParams params;
guint size;
gboolean add_videometa;
gboolean add_cropmeta;
gboolean can_alloc; /* if extra buffers can be allocated */
guint num_buffers; /* number of buffers we use */
......@@ -110,6 +111,8 @@ GstFlowReturn gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, Gst
gboolean gst_v4l2_buffer_pool_flush (GstV4l2BufferPool * pool);
void gst_v4l2_buffer_pool_add_crop_meta (GstV4l2BufferPool * bpool, gboolean add);
G_END_DECLS
#endif /*__GST_V4L2_BUFFER_POOL_H__ */
......@@ -2255,7 +2255,7 @@ no_supported_capture_method:
static void
gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format,
GstVideoInfo * info)
GstVideoInfo * info, GstVideoAlignment * align)
{
const GstVideoFormatInfo *finfo = info->finfo;
gint i;
......@@ -2302,7 +2302,25 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
GST_DEBUG_OBJECT (v4l2object->element, "Got sizeimage %u",
v4l2object->sizeimage);
/* To avoid copies, we need crop_meta if top or left padding is set */
v4l2object->need_crop_meta =
((align->padding_top + align->padding_left) != 0);
/* ... or video meta if bottom or right padding is set */
v4l2object->need_video_meta = (v4l2object->need_crop_meta ||
((align->padding_bottom + align->padding_right) != 0));
/* ... or also video meta if stride is non "standard" */
if (GST_VIDEO_INFO_PLANE_STRIDE (info, 0) != v4l2object->bytesperline[0])
v4l2object->need_video_meta = TRUE;
/* ... or also video meta if we use multiple, non-contiguous, planes */
if (v4l2object->n_v4l2_planes > 1)
v4l2object->need_video_meta = TRUE;
gst_video_info_align (info, align);
v4l2object->info = *info;
v4l2object->align = *align;
v4l2object->fmtdesc = fmtdesc;
/* if we have a framerate pre-calculate duration */
......@@ -2324,12 +2342,20 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
guint32 pixelformat;
struct v4l2_fmtdesc *fmtdesc;
GstVideoInfo info;
GstVideoAlignment align;
gint width, height, fps_n, fps_d;
gint n_v4l_planes;
gint i = 0;
gboolean is_mplane, format_changed;
GST_V4L2_CHECK_OPEN (v4l2object);
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);
gst_video_info_init (&info);
gst_video_alignment_reset (&align);
if (!gst_v4l2_object_get_caps_info (v4l2object, caps, &fmtdesc, &info))
goto invalid_caps;
......@@ -2339,9 +2365,11 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
fps_n = GST_VIDEO_INFO_FPS_N (&info);
fps_d = GST_VIDEO_INFO_FPS_D (&info);
/* get bytesperline for each plane */
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&info); i++)
v4l2object->bytesperline[i] = GST_VIDEO_INFO_PLANE_STRIDE (&info, i);
/* if encoded format (GST_VIDEO_INFO_N_PLANES return 0)
* or if contiguous is prefered */
n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info);
if (!n_v4l_planes || !v4l2object->prefered_non_contiguous)
n_v4l_planes = 1;
if (GST_VIDEO_INFO_IS_INTERLACED (&info)) {
GST_DEBUG_OBJECT (v4l2object->element, "interlaced video");
......@@ -2356,22 +2384,19 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
GST_DEBUG_OBJECT (v4l2object->element, "Desired format %dx%d, format "
"%" GST_FOURCC_FORMAT " stride: %d", width, height,
GST_FOURCC_ARGS (pixelformat), v4l2object->bytesperline[0]);
GST_FOURCC_ARGS (pixelformat), GST_VIDEO_INFO_PLANE_STRIDE (&info, 0));
memset (&format, 0x00, sizeof (struct v4l2_format));
format.type = v4l2object->type;
if (!v4l2object->no_initial_format) {
if (v4l2object->no_initial_format) {
format_changed = TRUE;
} else {
if (v4l2_ioctl (fd, VIDIOC_G_FMT, &format) < 0)
goto get_fmt_failed;
}
if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
"%" GST_FOURCC_FORMAT " colorspace %d, nb planes %d",
format.fmt.pix_mp.width, format.fmt.pix_mp.height,
GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
format.fmt.pix_mp.colorspace, format.fmt.pix_mp.num_planes);
/* Note that four first fields are the same between v4l2_pix_format and
* v4l2_pix_format_mplane, so we don't need to duplicate he checks */
/* If no size in caps, use configured size */
if (width == 0 && height == 0) {
......@@ -2379,133 +2404,108 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
height = format.fmt.pix_mp.height;
}
if (format.type != v4l2object->type ||
format_changed = format.type != v4l2object->type ||
format.fmt.pix_mp.width != width ||
format.fmt.pix_mp.height != height ||
format.fmt.pix_mp.pixelformat != pixelformat ||
format.fmt.pix_mp.field != field) {
/* even in v4l2 multiplanar mode we can work in contiguous mode
* if the device supports it */
gint n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info);
/* if encoded format (GST_VIDEO_INFO_N_PLANES return 0)
* or if contiguous is prefered */
if (!n_v4l_planes || !v4l2object->prefered_non_contiguous)
n_v4l_planes = 1;
/* something different, set the format */
GST_DEBUG_OBJECT (v4l2object->element, "Setting format to %dx%d, format "
"%" GST_FOURCC_FORMAT, width, height, GST_FOURCC_ARGS (pixelformat));
format.type = v4l2object->type;
format.fmt.pix_mp.pixelformat = pixelformat;
format.fmt.pix_mp.width = width;
format.fmt.pix_mp.height = height;
format.fmt.pix_mp.field = field;
format.fmt.pix_mp.num_planes = n_v4l_planes;
/* try to ask our prefered stride but it's not a failure
* if not accepted */
for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
format.fmt.pix_mp.plane_fmt[i].bytesperline =
v4l2object->bytesperline[i];
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED) {
format.fmt.pix_mp.plane_fmt[0].sizeimage = ENCODED_BUFFER_SIZE;
}
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
goto set_fmt_failed;
GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
"%" GST_FOURCC_FORMAT ", nb planes %d", format.fmt.pix.width,
format.fmt.pix_mp.height,
GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
format.fmt.pix_mp.num_planes);
format.fmt.pix_mp.field != field;
}
#ifndef GST_DISABLE_GST_DEBUG
for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
GST_DEBUG_OBJECT (v4l2object->element, " stride %d",
format.fmt.pix_mp.plane_fmt[i].bytesperline);
#endif
if (format.fmt.pix_mp.pixelformat != pixelformat)
goto invalid_pixelformat;
/* we set the dimensions just in case but don't validate them afterwards
* For some codecs the dimensions are *not* in the bitstream, IIRC VC1
* in ASF mode for example. */
if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED) {
if (format.fmt.pix_mp.width != width
|| format.fmt.pix_mp.height != height)
goto invalid_dimensions;
}
if (format.fmt.pix_mp.num_planes != n_v4l_planes)
goto invalid_planes;
}
if (is_mplane) {
GST_DEBUG_OBJECT (v4l2object->element, "Current size is %dx%d, format "
"%" GST_FOURCC_FORMAT " colorspace %d, nb planes %d",
format.fmt.pix_mp.width, format.fmt.pix_mp.height,
GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
format.fmt.pix_mp.colorspace, format.fmt.pix_mp.num_planes);
/* figure out the frame layout */
v4l2object->n_v4l2_planes = format.fmt.pix_mp.num_planes;
v4l2object->sizeimage = 0;
for (i = 0; i < format.fmt.pix_mp.num_planes; i++) {
v4l2object->bytesperline[i] = format.fmt.pix_mp.plane_fmt[i].bytesperline;
v4l2object->sizeimage += format.fmt.pix_mp.plane_fmt[i].sizeimage;
}
for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
GST_DEBUG_OBJECT (v4l2object->element, " stride %d",
format.fmt.pix_mp.plane_fmt[i].bytesperline);
} else {
GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
"%" GST_FOURCC_FORMAT " bytesperline %d, colorspace %d",
GST_DEBUG_OBJECT (v4l2object->element, "Current size is %dx%d, format "
"%" GST_FOURCC_FORMAT " stride %d, colorspace %d",
format.fmt.pix.width, format.fmt.pix.height,
GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
format.fmt.pix.bytesperline, format.fmt.pix.colorspace);
}
#endif
/* If no size in caps, use configured size */
if (width == 0 && height == 0) {
width = format.fmt.pix_mp.width;
height = format.fmt.pix_mp.height;
}
/* If nothing changed, we are done */
if (!format_changed)
goto done;
if (format.type != v4l2object->type ||
format.fmt.pix.width != width ||
format.fmt.pix.height != height ||
format.fmt.pix.pixelformat != pixelformat ||
format.fmt.pix.field != field) {
/* something different, set the format */
GST_DEBUG_OBJECT (v4l2object->element, "Setting format to %dx%d, format "
"%" GST_FOURCC_FORMAT " bytesperline %d", width, height,
GST_FOURCC_ARGS (pixelformat), v4l2object->bytesperline[0]);
format.type = v4l2object->type;
format.fmt.pix.width = width;
format.fmt.pix.height = height;
format.fmt.pix.pixelformat = pixelformat;
format.fmt.pix.field = field;
/* try to ask our prefered stride */
format.fmt.pix.bytesperline = v4l2object->bytesperline[0];
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED) {
format.fmt.pix.sizeimage = ENCODED_BUFFER_SIZE;
}
/* something different, set the format */
GST_DEBUG_OBJECT (v4l2object->element, "Setting format to %dx%d, format "
"%" GST_FOURCC_FORMAT, width, height, GST_FOURCC_ARGS (pixelformat));
if (is_mplane) {
format.type = v4l2object->type;
format.fmt.pix_mp.pixelformat = pixelformat;
format.fmt.pix_mp.width = width;
format.fmt.pix_mp.height = height;
format.fmt.pix_mp.field = field;
format.fmt.pix_mp.num_planes = n_v4l_planes;
/* try to ask our prefered stride but it's not a failure
* if not accepted */
for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
format.fmt.pix_mp.plane_fmt[i].bytesperline =
GST_VIDEO_INFO_PLANE_STRIDE (&info, i);
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
format.fmt.pix_mp.plane_fmt[0].sizeimage = ENCODED_BUFFER_SIZE;
} else {
format.type = v4l2object->type;
format.fmt.pix.width = width;
format.fmt.pix.height = height;
format.fmt.pix.pixelformat = pixelformat;
format.fmt.pix.field = field;
/* try to ask our prefered stride */
format.fmt.pix.bytesperline = GST_VIDEO_INFO_PLANE_STRIDE (&info, 0);
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
goto set_fmt_failed;
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
format.fmt.pix.sizeimage = ENCODED_BUFFER_SIZE;
}
GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
"%" GST_FOURCC_FORMAT " stride %d", format.fmt.pix.width,
format.fmt.pix.height, GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
format.fmt.pix.bytesperline);
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
goto set_fmt_failed;
/* we set the dimensions just in case but don't validate them afterwards
* For some codecs the dimensions are *not* in the bitstream, IIRC VC1
* in ASF mode for example. */
if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED) {
if (format.fmt.pix.width != width || format.fmt.pix.height != height)
goto invalid_dimensions;
}
GST_DEBUG_OBJECT (v4l2object->element, "Got format to %dx%d, format "
"%" GST_FOURCC_FORMAT ", nb planes %d", format.fmt.pix.width,
format.fmt.pix_mp.height,
GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
is_mplane ? format.fmt.pix_mp.num_planes : 1);
if (format.fmt.pix.pixelformat != pixelformat)
goto invalid_pixelformat;
}
#ifndef GST_DISABLE_GST_DEBUG
if (is_mplane) {
for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
GST_DEBUG_OBJECT (v4l2object->element, " stride %d",
format.fmt.pix_mp.plane_fmt[i].bytesperline);
}
#endif
if (format.fmt.pix.pixelformat != pixelformat)
goto invalid_pixelformat;
/* Only negotiate size with raw data.
* For some codecs the dimensions are *not* in the bitstream, IIRC VC1
* in ASF mode for example, there is also not reason for a driver to
* change the size. */
if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED) {
/* We can crop larger images */
if (format.fmt.pix.width < width || format.fmt.pix.height < height)
goto invalid_dimensions;
/* Note, this will be adjusted if upstream has non-centered cropping. */
align.padding_top = 0;
align.padding_bottom = format.fmt.pix.height - height;
align.padding_left = 0;
align.padding_right = format.fmt.pix.width - width;
}
if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
goto invalid_planes;
/* Is there a reason we require the caller to always specify a framerate? */
GST_DEBUG_OBJECT (v4l2object->element, "Desired framerate: %u/%u", fps_n,
......@@ -2562,9 +2562,9 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
}
done:
gst_v4l2_object_save_format (v4l2object, fmtdesc, &format, &info);
gst_v4l2_object_save_format (v4l2object, fmtdesc, &format, &info, &align);
/* now configure ther pools */
/* now configure the pool */
if (!gst_v4l2_object_setup_pool (v4l2object, caps))
goto pool_failed;
......@@ -2660,28 +2660,24 @@ pool_failed:
* gst_v4l2_object_acquire_format:
* @v4l2object the object
* @info a GstVideoInfo to be filled
* @align a GstVideoAlignment to be filled
*
* Setup the format base on the currently configured format. This is useful in
* decoder or encoder elements where the output format is dictated by the
* input.
* Acquire the driver choosen format. This is useful in decoder or encoder elements where
* the output format is choosen by the HW.
*
* Returns: %TRUE on success, %FALSE on failure.
*/
gboolean
gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info,
GstVideoAlignment * align)
gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
{
struct v4l2_fmtdesc *fmtdesc;
struct v4l2_format fmt;
struct v4l2_crop crop;
GstVideoFormat format;
guint width, height;
GstVideoAlignment align;
gst_video_info_init (info);
gst_video_alignment_reset (align);
gst_video_alignment_reset (&align);
memset (&fmt, 0x00, sizeof (struct v4l2_format));
fmt.type = v4l2object->type;
......@@ -2709,10 +2705,10 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info,
memset (&crop, 0, sizeof (struct v4l2_crop));
crop.type = v4l2object->type;
if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0) {
align->padding_left = crop.c.left;
align->padding_top = crop.c.top;
align->padding_right = width - crop.c.width - crop.c.left;
align->padding_bottom = height - crop.c.height - crop.c.top;
align.padding_left = crop.c.left;
align.padding_top = crop.c.top;
align.padding_right = width - crop.c.width - crop.c.left;
align.padding_bottom = height - crop.c.height - crop.c.top;
width = crop.c.width;
height = crop.c.height;
}
......@@ -2733,7 +2729,7 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info,
goto unsupported_field;
}
gst_v4l2_object_save_format (v4l2object, fmtdesc, &fmt, info);
gst_v4l2_object_save_format (v4l2object, fmtdesc, &fmt, info, &align);
/* Shall we setup the pool ? */
......@@ -2838,6 +2834,8 @@ gst_v4l2_object_copy (GstV4l2Object * v4l2object, GstBuffer * dest,
GST_DEBUG_OBJECT (v4l2object->element, "copy video frame");
/* FIXME This won't work if cropping apply */
/* we have raw video, use videoframe copy to get strides right */
if (!gst_video_frame_map (&src_frame, &v4l2object->info, src, GST_MAP_READ))
goto invalid_buffer;
......@@ -2932,6 +2930,8 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
GstBufferPool *pool;
guint size, min, max;
gboolean update;
gboolean has_video_meta, has_crop_meta;
gboolean can_use_own_pool;
struct v4l2_control ctl = { 0, };
GST_DEBUG_OBJECT (obj->element, "decide allocation");
......@@ -2981,16 +2981,19 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
if (max != 0 && max < min)
max = min;
has_video_meta =
gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
has_crop_meta =
gst_query_find_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE,
NULL);
can_use_own_pool = ((has_crop_meta || !obj->need_crop_meta) &&
(has_video_meta || !obj->need_video_meta));
/* select a pool */
switch (obj->mode) {
case GST_V4L2_IO_RW:
if (pool == NULL) {
/* no downstream pool, use our own then */
GST_DEBUG_OBJECT (obj->element,
"read/write mode: no downstream pool, using our own");
pool = GST_BUFFER_POOL_CAST (obj->pool);
size = obj->sizeimage;
} else {
if (pool) {
/* in READ/WRITE mode, prefer a downstream pool because our own pool
* doesn't help much, we have to write to it as well */
GST_DEBUG_OBJECT (obj->element,
......@@ -2999,19 +3002,33 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
* other size than what the hardware gives us but for downstream pools
* we can try */
size = MAX (size, obj->sizeimage);
} else if (can_use_own_pool) {
/* no downstream pool, use our own then */
GST_DEBUG_OBJECT (obj->element,
"read/write mode: no downstream pool, using our own");
pool = obj->pool;
size = obj->sizeimage;
}
break;
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_USERPTR:
case GST_V4L2_IO_DMABUF:
/* in streaming mode, prefer our own pool */
if (pool)
gst_object_unref (pool);
pool = GST_BUFFER_POOL_CAST (obj->pool);
size = obj->sizeimage;
max = 0;
GST_DEBUG_OBJECT (obj->element,
"streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
/* Check if we can use it ... */
if (can_use_own_pool) {
if (pool)
gst_object_unref (pool);
pool = obj->pool;
size = obj->sizeimage;
max = 0;
GST_DEBUG_OBJECT (obj->element,
"streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
} else if (pool) {
GST_DEBUG_OBJECT (obj->element,
"streaming mode: copying to downstream pool %" GST_PTR_FORMAT,
pool);
size = MAX (size, obj->sizeimage);
}
break;
case GST_V4L2_IO_AUTO:
default:
......@@ -3028,7 +3045,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
gst_buffer_pool_config_set_params (config, caps, size, min, max);
/* if downstream supports video metadata, add this to the pool config */
if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
if (has_video_meta) {
GST_DEBUG_OBJECT (pool, "activate Video Meta");
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
......@@ -3037,6 +3054,25 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
gst_buffer_pool_set_config (pool, config);
}
/* Our pool may be incompatible, though we'll need the metadata in order to
* copy to a downstream compatible buffer */
if (pool != obj->pool && obj->need_video_meta) {
GstStructure *config;
GstCaps *caps;
config = gst_buffer_pool_get_config (obj->pool);
gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL);
gst_buffer_pool_config_set_params (config, caps, obj->sizeimage, min, 0);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_set_config (obj->pool, config);
}
if (obj->need_crop_meta)
gst_v4l2_buffer_pool_add_crop_meta (GST_V4L2_BUFFER_POOL (obj->pool),
obj->need_crop_meta);
if (update)
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
else
......
......@@ -97,6 +97,10 @@ struct _GstV4l2Object {
/* the current format */
struct v4l2_fmtdesc *fmtdesc;
GstVideoInfo info;
GstVideoAlignment align;
gboolean need_video_meta;
gboolean need_crop_meta;
/* only used if the device supports MPLANE
* nb planes is meaning of v4l2 planes
......@@ -254,8 +258,7 @@ GstCaps * gst_v4l2_object_get_caps (GstV4l2Object * v4l2object,
GstCaps * filter);
gboolean gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object,
GstVideoInfo * info,
GstVideoAlignment * align);
GstVideoInfo * info);
gboolean gst_v4l2_object_decide_allocation (GstV4l2Object * v4l2object,
GstQuery * query);
......
......@@ -65,8 +65,6 @@ struct _GstV4l2VideoDec
gboolean active;
gboolean processing;
GstFlowReturn output_flow;
GstVideoAlignment align;
};
struct _GstV4l2VideoDecClass
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment