summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTobias Modschiedler <tobias.modschiedler@cetitec.com>2015-03-30 13:12:35 +0200
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2015-04-02 17:29:19 -0400
commit8390288a6e34a240688f27516b88d0578f355057 (patch)
treebae70e59ed745a856240bda26b06e01d2e5746b7 /sys
parentd410acf64981420c6102535c1c9ab5d5581870c8 (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.c7
-rw-r--r--sys/v4l2/gstv4l2object.c51
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);