From 3eaecf3aed01d7c56b5f629e27ee0441ece306b3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 15 Jul 2011 16:26:06 +0100 Subject: [PATCH] v4l2: improve bufferpool config setting Pass the caps and the default video size to the bufferpool config. Don't activate the bufferpool, this will be done by the object that decides to use the bufferpool. Improve debugging and error reporting. --- sys/v4l2/gstv4l2object.c | 89 +++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index cf850dff33..43b387e849 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -2042,7 +2042,7 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object, } static gboolean -gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object) +gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps) { GST_DEBUG_OBJECT (v4l2object->element, "initializing the capture system"); @@ -2066,13 +2066,9 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object) v4l2object->use_mmap = TRUE; config = gst_buffer_pool_get_config (v4l2object->pool); - gst_buffer_pool_config_set (config, NULL, 0, num_buffers, num_buffers, - 0, 0); + gst_buffer_pool_config_set (config, caps, v4l2object->info.size, + num_buffers, num_buffers, 0, 0); gst_buffer_pool_set_config (v4l2object->pool, config); - - if (!gst_buffer_pool_set_active (v4l2object->pool, TRUE)) - goto activate_failed; - } else if (v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) { GST_INFO_OBJECT (v4l2object->element, "capturing buffers via read()"); v4l2object->use_mmap = FALSE; @@ -2101,14 +2097,6 @@ no_supported_capture_method: "method."), v4l2object->videodev), (NULL)); return FALSE; } -activate_failed: - { - GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ, - (_("Could not map buffers from device '%s'"), - v4l2object->videodev), - ("Failed to activate buffer pool: %s", g_strerror (errno))); - return FALSE; - } } @@ -2270,7 +2258,7 @@ done: v4l2object->fmtdesc = fmtdesc; /* now configure ther pools */ - if (!gst_v4l2_object_setup_pool (v4l2object)) + if (!gst_v4l2_object_setup_pool (v4l2object, caps)) goto pool_failed; return TRUE; @@ -2671,18 +2659,27 @@ GstFlowReturn gst_v4l2_object_output_buffer (GstV4l2Object * v4l2object, GstBuffer * buf) { GstFlowReturn ret; - GstBuffer *newbuf = NULL; + GstBuffer *to_queue = NULL; GstMetaV4l2 *meta; meta = GST_META_V4L2_GET (buf); - if (meta == NULL || buf->pool != v4l2object->pool) { + if (meta && buf->pool == v4l2object->pool) { + GST_LOG_OBJECT (v4l2object->element, + "buffer from our pool, queueing directly"); + to_queue = buf; + ret = GST_FLOW_OK; + } else { guint8 *data; gsize size; /* not our buffer */ - GST_DEBUG_OBJECT (v4l2object->element, "slow-path.. need to memcpy"); - ret = gst_buffer_pool_acquire_buffer (v4l2object->pool, &newbuf, NULL); + GST_LOG_OBJECT (v4l2object->element, "buffer not from our pool, copying"); + + if (!gst_buffer_pool_set_active (v4l2object->pool, TRUE)) + goto activate_failed; + + ret = gst_buffer_pool_acquire_buffer (v4l2object->pool, &to_queue, NULL); if (ret != GST_FLOW_OK) goto acquire_failed; @@ -2691,9 +2688,15 @@ gst_v4l2_object_output_buffer (GstV4l2Object * v4l2object, GstBuffer * buf) GST_DEBUG_OBJECT (v4l2object->element, "copy video frame"); /* we have raw video, use videoframe copy to get strides right */ - gst_video_frame_map (&src_frame, &v4l2object->info, buf, GST_MAP_READ); - gst_video_frame_map (&dest_frame, &v4l2object->info, newbuf, - GST_MAP_WRITE); + if (!gst_video_frame_map (&src_frame, &v4l2object->info, buf, + GST_MAP_READ)) + goto invalid_buffer; + + if (!gst_video_frame_map (&dest_frame, &v4l2object->info, to_queue, + GST_MAP_WRITE)) { + gst_video_frame_unmap (&src_frame); + goto invalid_buffer; + } gst_video_frame_copy (&dest_frame, &src_frame); @@ -2702,35 +2705,57 @@ gst_v4l2_object_output_buffer (GstV4l2Object * v4l2object, GstBuffer * buf) } else { GST_DEBUG_OBJECT (v4l2object->element, "copy raw bytes"); data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); - gst_buffer_fill (newbuf, 0, data, size); + gst_buffer_fill (to_queue, 0, data, size); gst_buffer_unmap (buf, data, size); } - GST_DEBUG_OBJECT (v4l2object->element, "render copied buffer: %p", newbuf); - buf = newbuf; + GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2object->element, + "slow copy into bufferpool buffer %p", to_queue); } - if (!gst_v4l2_buffer_pool_qbuf (v4l2object->pool, buf)) + if (!gst_v4l2_buffer_pool_qbuf (v4l2object->pool, to_queue)) goto queue_failed; if (!v4l2object->streaming) { if (!gst_v4l2_object_start (v4l2object)) { - return GST_FLOW_ERROR; + goto start_failed; } } - if (newbuf) - gst_buffer_unref (newbuf); - return GST_FLOW_OK; +done: + if (to_queue != buf) + gst_buffer_unref (to_queue); + + return ret; /* ERRORS */ +activate_failed: + { + GST_ERROR_OBJECT (v4l2object->element, "failed to activate bufferpool."); + ret = GST_FLOW_ERROR; + goto done; + } acquire_failed: { GST_DEBUG_OBJECT (v4l2object->element, "could not get buffer from pool"); return ret; } +invalid_buffer: + { + /* No Window available to put our image into */ + GST_WARNING_OBJECT (v4l2object->element, "could not map image"); + ret = GST_FLOW_OK; + goto done; + } queue_failed: { GST_DEBUG_OBJECT (v4l2object->element, "failed to queue buffer"); - return GST_FLOW_ERROR; + ret = GST_FLOW_ERROR; + goto done; + } +start_failed: + { + GST_DEBUG_OBJECT (v4l2object->element, "failed to start streaming"); + ret = GST_FLOW_ERROR; + goto done; } }