diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-05-02 09:41:01 +0200 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-09-13 16:29:46 +0200 |
commit | c3c7164ffe0251869840b7d5771415696e416cc7 (patch) | |
tree | 52dfb78a06adf60948887274ed9ce4d280d11c31 | |
parent | bbc92d25bc2c0af33e8f1b7877505475145bbf9e (diff) | |
download | gst-plugins-good-c3c7164ffe0251869840b7d5771415696e416cc7.tar.gz gst-plugins-good-c3c7164ffe0251869840b7d5771415696e416cc7.tar.xz |
v4l2: try to allocate new buffers with VIDIOC_CREATE_BUFS if needed
If max_buffers is 0 then an arbitrary number of buffers (currently 4) is
allocated. If this is not enough v4l2src starts copying buffers.
With this patch VIDIOC_CREATE_BUFS is used to allocate a new buffer. If
this fails v4l2src falls back to copying buffers.
https://bugzilla.gnome.org/show_bug.cgi?id=699447
-rw-r--r-- | sys/v4l2/gstv4l2bufferpool.c | 52 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2bufferpool.h | 1 |
2 files changed, 53 insertions, 0 deletions
diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 0019c4819..fcf6a7f5c 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -159,6 +159,28 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer, case GST_V4L2_IO_MMAP: case GST_V4L2_IO_DMABUF: { +#ifdef VIDIOC_CREATE_BUFS + if (pool->num_allocated == pool->num_buffers) { + struct v4l2_create_buffers create_bufs; + + memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers)); + create_bufs.count = 1; + create_bufs.memory = V4L2_MEMORY_MMAP; + create_bufs.format.type = obj->type; + + if (v4l2_ioctl (pool->video_fd, VIDIOC_G_FMT, &create_bufs.format) < 0) + goto g_fmt_failed; + + if (v4l2_ioctl (pool->video_fd, VIDIOC_CREATE_BUFS, &create_bufs) < 0) + goto create_bufs_failed; + + GST_LOG_OBJECT (pool, "created buffer with index: %u", + create_bufs.index); + pool->num_buffers++; + pool->buffers = g_renew (GstBuffer *, pool->buffers, pool->num_buffers); + pool->buffers[pool->num_buffers - 1] = NULL; + } +#endif newbuf = gst_buffer_new (); meta = GST_V4L2_META_ADD (newbuf); @@ -252,6 +274,24 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer, return GST_FLOW_OK; /* ERRORS */ +#ifdef VIDIOC_CREATE_BUFS +g_fmt_failed: + { + gint errnosave = errno; + + GST_WARNING ("Failed G_FMT: %s", g_strerror (errnosave)); + errno = errnosave; + return GST_FLOW_ERROR; + } +create_bufs_failed: + { + gint errnosave = errno; + + GST_WARNING ("Failed CREATE_BUFS: %s", g_strerror (errnosave)); + errno = errnosave; + return GST_FLOW_ERROR; + } +#endif querybuf_failed: { gint errnosave = errno; @@ -795,6 +835,17 @@ gst_v4l2_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer, /* start copying buffers when we are running low on buffers */ if (pool->num_queued < pool->copy_threshold) { GstBuffer *copy; +#ifdef VIDIOC_CREATE_BUFS + if (pool->can_alloc) { + if (GST_BUFFER_POOL_CLASS (parent_class)->acquire_buffer (bpool, + ©, params) == GST_FLOW_OK) { + gst_v4l2_buffer_pool_release_buffer (bpool, copy); + break; + } else { + pool->can_alloc = FALSE; + } + } +#endif /* copy the memory */ copy = gst_buffer_copy (*buffer); @@ -991,6 +1042,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps) pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL); pool->video_fd = fd; pool->obj = obj; + pool->can_alloc = TRUE; s = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); gst_buffer_pool_config_set_params (s, caps, obj->sizeimage, 2, 0); diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h index a9b022e9a..64e185227 100644 --- a/sys/v4l2/gstv4l2bufferpool.h +++ b/sys/v4l2/gstv4l2bufferpool.h @@ -55,6 +55,7 @@ struct _GstV4l2BufferPool GstAllocationParams params; guint size; gboolean add_videometa; + gboolean can_alloc; /* if extra buffers can be allocated */ guint num_buffers; /* number of buffers we use */ guint num_allocated; /* number of buffers allocated by the driver */ |