From acebdd86dac3e54db5c6e4004df17b94b78c67b7 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 8 Apr 2014 18:20:25 -0400 Subject: [PATCH] v4l2object: Improved decide allocation Improve decide allocation so it properly configure both local and downstream buffer pools. Also read back the pool config if it was changed to to driver limitations. --- sys/v4l2/gstv4l2object.c | 81 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 5bbc1d6517..4cecc52a1b 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -3042,7 +3042,8 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) { GstCaps *caps; GstBufferPool *pool; - guint size, min, max; + GstStructure *config; + guint size, min, max, extra = 0; gboolean update; gboolean has_video_meta, has_crop_meta; gboolean can_use_own_pool; @@ -3087,13 +3088,11 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) GST_DEBUG_OBJECT (obj->element, "driver require a minimum of %d buffers", ctl.value); obj->min_buffers_for_capture = ctl.value; - min += ctl.value; + extra += ctl.value; + } else { + obj->min_buffers_for_capture = 0; } - /* Request a bigger max, if one was suggested but it's too small */ - if (max != 0) - max = MAX (min, max); - has_video_meta = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); has_crop_meta = @@ -3133,7 +3132,6 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) 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) { @@ -3149,19 +3147,55 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) break; } - /* Size field is mandatory and we have no size if now using our own pool and - * downstream didn't provide one. */ - if (size == 0) { - GstVideoInfo info; + if (size == 0) + goto no_size; - gst_video_info_init (&info); - gst_video_info_from_caps (&info, caps); + /* Request a bigger max, if one was suggested but it's too small */ + if (max != 0) + max = MAX (min, max); - size = GST_VIDEO_INFO_SIZE (&info); + /* First step, configure our own pool */ + + /* If already configured/active, skip it */ + /* FIXME not entirely correct, See bug 728268 */ + if (gst_buffer_pool_is_active (obj->pool)) + goto setup_other_pool; + + config = gst_buffer_pool_get_config (obj->pool); + + if (obj->need_video_meta) { + GST_DEBUG_OBJECT (pool, "activate Video Meta"); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); } - if (pool) { - GstStructure *config; + if (obj->need_crop_meta) { + GST_DEBUG_OBJECT (pool, "activate VideoCrop Meta"); + gst_buffer_pool_config_add_option (config, + GST_V4L2_BUFFER_POOL_OPTION_CROP_META); + } + + gst_buffer_pool_config_set_params (config, caps, size, min + extra, 0); + + GST_DEBUG_OBJECT (pool, "setting config %" GST_PTR_FORMAT, config); + + /* Our pool often need to adjust the value */ + if (!gst_buffer_pool_set_config (obj->pool, config)) { + config = gst_buffer_pool_get_config (obj->pool); + + GST_DEBUG_OBJECT (pool, "config changed to %" GST_PTR_FORMAT, config); + + /* our pool will adjust the maximum buffer, which we are fine with */ + + if (!gst_buffer_pool_set_config (obj->pool, config)) + goto config_failed; + } + +setup_other_pool: + /* Now configure the other pool if different */ + if (pool && obj->pool != pool) { + if (gst_buffer_pool_is_active (obj->pool)) + goto done; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); @@ -3173,9 +3207,11 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) GST_BUFFER_POOL_OPTION_VIDEO_META); } + /* TODO check return value, validate changes and confirm */ gst_buffer_pool_set_config (pool, config); } +done: if (update) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else @@ -3184,9 +3220,20 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query) return TRUE; pool_failed: + { + /* setup_pool already send the error */ + return FALSE; + } +config_failed: { GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS, - (_("Video device could not create buffer pool.")), GST_ERROR_SYSTEM); + (_("Failed to configure internal buffer pool.")), (NULL)); + return FALSE; + } +no_size: + { + GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS, + (_("Video device did not suggest any buffer size.")), (NULL)); return FALSE; } }