From 0028de808bb7b00fb55d8dcc5ba29faffcfae7c3 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 27 Mar 2014 18:41:07 -0400 Subject: [PATCH] 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. --- sys/v4l2/gstv4l2bufferpool.c | 38 +++++++++++++++++++++++------------- sys/v4l2/gstv4l2object.c | 5 +++-- sys/v4l2/gstv4l2object.h | 1 + 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 99e679c31d..8eb0a9d282 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -165,10 +165,7 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer, memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers)); create_bufs.count = 1; create_bufs.memory = V4L2_MEMORY_MMAP; - create_bufs.format.type = obj->type; - - if (v4l2_ioctl (pool->video_fd, VIDIOC_G_FMT, &create_bufs.format) < 0) - goto g_fmt_failed; + create_bufs.format = obj->format; if (v4l2_ioctl (pool->video_fd, VIDIOC_CREATE_BUFS, &create_bufs) < 0) goto create_bufs_failed; @@ -365,14 +362,6 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer, return GST_FLOW_OK; /* 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: { gint errnosave = errno; @@ -1301,6 +1290,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps) GstStructure *config; gboolean res = FALSE; gint fd; + guint min, max; fd = v4l2_dup (obj->video_fd); 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->video_fd = fd; 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)); - 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 */ if (obj->need_video_meta) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 4b7795701e..ee759030c0 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -2331,6 +2331,7 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object, gst_video_info_align (info, align); v4l2object->info = *info; v4l2object->align = *align; + v4l2object->format = *format; v4l2object->fmtdesc = fmtdesc; /* 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 */ - if (max != 0 && max < min) - max = min; + if (max != 0) + max = MAX (min, max); has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index e29484480c..cbf27eefd0 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -96,6 +96,7 @@ struct _GstV4l2Object { /* the current format */ struct v4l2_fmtdesc *fmtdesc; + struct v4l2_format format; GstVideoInfo info; GstVideoAlignment align;