mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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.
This commit is contained in:
parent
37ef3f8997
commit
3eaecf3aed
1 changed files with 57 additions and 32 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue