mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
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
This commit is contained in:
parent
bb980775f8
commit
1e777ede92
2 changed files with 53 additions and 0 deletions
|
@ -157,6 +157,28 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
|
||||||
case GST_V4L2_IO_MMAP:
|
case GST_V4L2_IO_MMAP:
|
||||||
case GST_V4L2_IO_DMABUF:
|
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 ();
|
newbuf = gst_buffer_new ();
|
||||||
meta = GST_V4L2_META_ADD (newbuf);
|
meta = GST_V4L2_META_ADD (newbuf);
|
||||||
|
|
||||||
|
@ -250,6 +272,24 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
/* ERRORS */
|
/* 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:
|
querybuf_failed:
|
||||||
{
|
{
|
||||||
gint errnosave = errno;
|
gint errnosave = errno;
|
||||||
|
@ -793,6 +833,17 @@ gst_v4l2_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
|
||||||
/* start copying buffers when we are running low on buffers */
|
/* start copying buffers when we are running low on buffers */
|
||||||
if (pool->num_queued < pool->copy_threshold) {
|
if (pool->num_queued < pool->copy_threshold) {
|
||||||
GstBuffer *copy;
|
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 the memory */
|
||||||
copy = gst_buffer_copy (*buffer);
|
copy = gst_buffer_copy (*buffer);
|
||||||
|
@ -989,6 +1040,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
|
||||||
pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL);
|
pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL);
|
||||||
pool->video_fd = fd;
|
pool->video_fd = fd;
|
||||||
pool->obj = obj;
|
pool->obj = obj;
|
||||||
|
pool->can_alloc = TRUE;
|
||||||
|
|
||||||
s = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
|
s = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
|
||||||
gst_buffer_pool_config_set_params (s, caps, obj->sizeimage, 2, 0);
|
gst_buffer_pool_config_set_params (s, caps, obj->sizeimage, 2, 0);
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct _GstV4l2BufferPool
|
||||||
GstAllocationParams params;
|
GstAllocationParams params;
|
||||||
guint size;
|
guint size;
|
||||||
gboolean add_videometa;
|
gboolean add_videometa;
|
||||||
|
gboolean can_alloc; /* if extra buffers can be allocated */
|
||||||
|
|
||||||
guint num_buffers; /* number of buffers we use */
|
guint num_buffers; /* number of buffers we use */
|
||||||
guint num_allocated; /* number of buffers allocated by the driver */
|
guint num_allocated; /* number of buffers allocated by the driver */
|
||||||
|
|
Loading…
Reference in a new issue