diff options
author | Tobias Modschiedler <tobias.modschiedler@cetitec.com> | 2015-03-30 13:12:35 +0200 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2015-04-02 17:29:19 -0400 |
commit | 8390288a6e34a240688f27516b88d0578f355057 (patch) | |
tree | bae70e59ed745a856240bda26b06e01d2e5746b7 /sys | |
parent | d410acf64981420c6102535c1c9ab5d5581870c8 (diff) |
v4l2: Ask the driver about its requirements for min_buffers before initiating buffer pool.
If propose_allocation() had not been called yet, it was possible that the driver was not asked at all.
In buffer pool: Consider minimum number of buffers requested by driver when setting config.
https://bugzilla.gnome.org/show_bug.cgi?id=746834
Diffstat (limited to 'sys')
-rw-r--r-- | sys/v4l2/gstv4l2bufferpool.c | 7 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2object.c | 51 |
2 files changed, 36 insertions, 22 deletions
diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 4815336d5..dec617bc5 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -549,6 +549,13 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config) GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers); } + /* respect driver requirements */ + if (min_buffers < obj->min_buffers) { + updated = TRUE; + min_buffers = obj->min_buffers; + GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers); + } + if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0) { updated = TRUE; max_buffers = VIDEO_MAX_FRAME; diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 9c8dfb2e3..1f4b84e2f 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -721,6 +721,28 @@ gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object, } static void +gst_v4l2_get_driver_min_buffers (GstV4l2Object * v4l2object) +{ + int min; + gboolean ret = FALSE; + + /* Certain driver may expose a minimum number of buffers through controls. */ + /* If the ioctl is not supported by the driver, min_buffers remains zero. */ + ret = gst_v4l2_get_attribute (v4l2object, + V4L2_TYPE_IS_OUTPUT (v4l2object->type) + ? V4L2_CID_MIN_BUFFERS_FOR_OUTPUT : V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, + &min); + + if (ret) { + GST_DEBUG_OBJECT (v4l2object->element, + "driver requires a minimum of %d buffers", min); + v4l2object->min_buffers = min; + } else { + v4l2object->min_buffers = 0; + } +} + +static void gst_v4l2_set_defaults (GstV4l2Object * v4l2object) { GstTunerNorm *norm = NULL; @@ -2407,6 +2429,11 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps) GST_INFO_OBJECT (v4l2object->element, "accessing buffers via mode %d", mode); v4l2object->mode = mode; + /* If min_buffers is not set, the driver either does not support the control or + it has not been asked yet via propose_allocation/decide_allocation. */ + if (!v4l2object->min_buffers) + gst_v4l2_get_driver_min_buffers (v4l2object); + /* Map the buffers */ GST_LOG_OBJECT (v4l2object->element, "initiating buffer pool"); @@ -3315,7 +3342,6 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) gboolean update; gboolean has_video_meta; gboolean can_share_own_pool, pushing_from_our_pool = FALSE; - struct v4l2_control ctl = { 0, }; GstAllocator *allocator = NULL; GstAllocationParams params = { 0 }; @@ -3352,16 +3378,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) can_share_own_pool = (has_video_meta || !obj->need_video_meta); - /* Certain driver may expose a minimum through controls */ - ctl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; - if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CTRL, &ctl) >= 0) { - GST_DEBUG_OBJECT (obj->element, "driver require a minimum of %d buffers", - ctl.value); - obj->min_buffers = ctl.value; - } else { - obj->min_buffers = 0; - } - + gst_v4l2_get_driver_min_buffers (obj); /* We can't share our own pool, if it exceed V4L2 capacity */ if (min + obj->min_buffers + 1 > VIDEO_MAX_FRAME) can_share_own_pool = FALSE; @@ -3597,7 +3614,6 @@ gst_v4l2_object_propose_allocation (GstV4l2Object * obj, GstQuery * query) guint size, min, max; GstCaps *caps; gboolean need_pool; - struct v4l2_control ctl = { 0, }; /* Set defaults allocation parameters */ size = obj->info.size; @@ -3629,16 +3645,7 @@ gst_v4l2_object_propose_allocation (GstV4l2Object * obj, GstQuery * query) } gst_structure_free (config); } - - /* Some devices may expose a minimum */ - ctl.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT; - if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CTRL, &ctl) >= 0) { - GST_DEBUG_OBJECT (obj->element, "driver require a miminum of %d buffers", - ctl.value); - obj->min_buffers = ctl.value; - } else { - obj->min_buffers = 0; - } + gst_v4l2_get_driver_min_buffers (obj); min = MAX (obj->min_buffers, GST_V4L2_MIN_BUFFERS); |