v4l2: Probe for CREATE_BUFS in order to correctly set pool min/max

In order to correctly set the pool min/max, we need to probe for CREATE_BUFS
ioctl. This can be done as soon as the format has been negotiated using a
count of 0.
This commit is contained in:
Nicolas Dufresne 2014-03-27 18:41:07 -04:00
parent 8d6e72a299
commit 0028de808b
3 changed files with 28 additions and 16 deletions

View file

@ -165,10 +165,7 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers)); memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers));
create_bufs.count = 1; create_bufs.count = 1;
create_bufs.memory = V4L2_MEMORY_MMAP; create_bufs.memory = V4L2_MEMORY_MMAP;
create_bufs.format.type = obj->type; create_bufs.format = obj->format;
if (v4l2_ioctl (pool->video_fd, VIDIOC_G_FMT, &create_bufs.format) < 0)
goto g_fmt_failed;
if (v4l2_ioctl (pool->video_fd, VIDIOC_CREATE_BUFS, &create_bufs) < 0) if (v4l2_ioctl (pool->video_fd, VIDIOC_CREATE_BUFS, &create_bufs) < 0)
goto create_bufs_failed; goto create_bufs_failed;
@ -365,14 +362,6 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
return GST_FLOW_OK; return GST_FLOW_OK;
/* ERRORS */ /* ERRORS */
g_fmt_failed:
{
gint errnosave = errno;
GST_WARNING ("Failed G_FMT: %s", g_strerror (errnosave));
errno = errnosave;
return GST_FLOW_ERROR;
}
create_bufs_failed: create_bufs_failed:
{ {
gint errnosave = errno; gint errnosave = errno;
@ -1301,6 +1290,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
GstStructure *config; GstStructure *config;
gboolean res = FALSE; gboolean res = FALSE;
gint fd; gint fd;
guint min, max;
fd = v4l2_dup (obj->video_fd); fd = v4l2_dup (obj->video_fd);
if (fd < 0) if (fd < 0)
@ -1309,10 +1299,30 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL); pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL);
pool->video_fd = fd; pool->video_fd = fd;
pool->obj = obj; pool->obj = obj;
pool->can_alloc = TRUE; pool->can_alloc = FALSE;
min = max = 2;
/* Check for CREATE_BUFS support */
switch (obj->mode) {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
{
struct v4l2_create_buffers create_bufs = { 0 };
create_bufs.count = 0;
create_bufs.memory = V4L2_MEMORY_MMAP;
create_bufs.format = obj->format;
if (v4l2_ioctl (pool->video_fd, VIDIOC_CREATE_BUFS, &create_bufs) == 0) {
pool->can_alloc = TRUE;
max = 0;
}
break;
}
default:
break;
}
config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
gst_buffer_pool_config_set_params (config, caps, obj->sizeimage, 2, 0); gst_buffer_pool_config_set_params (config, caps, obj->sizeimage, min, max);
/* Ensure our internal pool has required features */ /* Ensure our internal pool has required features */
if (obj->need_video_meta) if (obj->need_video_meta)

View file

@ -2331,6 +2331,7 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
gst_video_info_align (info, align); gst_video_info_align (info, align);
v4l2object->info = *info; v4l2object->info = *info;
v4l2object->align = *align; v4l2object->align = *align;
v4l2object->format = *format;
v4l2object->fmtdesc = fmtdesc; v4l2object->fmtdesc = fmtdesc;
/* if we have a framerate pre-calculate duration */ /* if we have a framerate pre-calculate duration */
@ -3032,8 +3033,8 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
} }
/* Request a bigger max, if one was suggested but it's too small */ /* Request a bigger max, if one was suggested but it's too small */
if (max != 0 && max < min) if (max != 0)
max = min; max = MAX (min, max);
has_video_meta = has_video_meta =
gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

View file

@ -96,6 +96,7 @@ struct _GstV4l2Object {
/* the current format */ /* the current format */
struct v4l2_fmtdesc *fmtdesc; struct v4l2_fmtdesc *fmtdesc;
struct v4l2_format format;
GstVideoInfo info; GstVideoInfo info;
GstVideoAlignment align; GstVideoAlignment align;