diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index b53ff60b22..123200c00e 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -622,7 +622,8 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) GstStructure *config; GstCaps *caps; guint size, min_buffers, max_buffers; - guint num_buffers = 0, copy_threshold = 0; + guint max_latency, min_latency, copy_threshold = 0; + gboolean can_allocate = FALSE; GST_DEBUG_OBJECT (pool, "activating pool"); @@ -631,31 +632,28 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) &max_buffers)) goto wrong_config; + /* TODO Also consider min_buffers_for_output when implemented */ + min_latency = MAX (GST_V4L2_MIN_BUFFERS, obj->min_buffers_for_capture); + switch (obj->mode) { case GST_V4L2_IO_RW: - /* this value also instructs the latency calculation to have min_buffers - * frame latency max */ - num_buffers = min_buffers; + can_allocate = TRUE; break; case GST_V4L2_IO_DMABUF: case GST_V4L2_IO_MMAP: { guint count; - if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) { - num_buffers = min_buffers; - } else { - num_buffers = max_buffers; - } + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP); /* first, lets request buffers, and see how many we can get: */ - GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", num_buffers); + GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers); - count = gst_v4l2_allocator_start (pool->vallocator, num_buffers, + count = gst_v4l2_allocator_start (pool->vallocator, min_buffers, V4L2_MEMORY_MMAP); if (count < GST_V4L2_MIN_BUFFERS) { - num_buffers = count; + min_buffers = count; goto no_buffers; } @@ -664,12 +662,11 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) * falling back to copy if the pipeline needed more buffers. This also * prevent having to do REQBUFS(N)/REQBUFS(0) everytime configure is * called. */ - if (count != num_buffers) { + if (count != min_buffers) { GST_WARNING_OBJECT (pool, "using %u buffers instead of %u", - count, num_buffers); - num_buffers = count; - copy_threshold = - MAX (GST_V4L2_MIN_BUFFERS, obj->min_buffers_for_capture); + count, min_buffers); + min_buffers = count; + copy_threshold = min_latency; /* The initial minimum could be provide either by GstBufferPool or * driver needs. */ @@ -682,60 +679,59 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) { guint count; - if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR)) { - num_buffers = min_buffers; - } else { - num_buffers = max_buffers; - } + can_allocate = + GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR); - GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", num_buffers); + GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers); - count = gst_v4l2_allocator_start (pool->vallocator, num_buffers, + count = gst_v4l2_allocator_start (pool->vallocator, min_buffers, V4L2_MEMORY_USERPTR); /* There is no rational to not get what we asked */ - if (count < num_buffers) { - num_buffers = count; + if (count < min_buffers) { + min_buffers = count; goto no_buffers; } - min_buffers = num_buffers = count; + min_buffers = count; break; } case GST_V4L2_IO_DMABUF_IMPORT: { guint count; - if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF)) { - num_buffers = min_buffers; - } else { - num_buffers = max_buffers; - } + can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF); - GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", num_buffers); + GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers); - count = gst_v4l2_allocator_start (pool->vallocator, num_buffers, + count = gst_v4l2_allocator_start (pool->vallocator, min_buffers, V4L2_MEMORY_DMABUF); /* There is no rational to not get what we asked */ - if (count < num_buffers) { - num_buffers = count; + if (count < min_buffers) { + min_buffers = count; goto no_buffers; } - min_buffers = num_buffers = count; + min_buffers = count; break; } default: - num_buffers = 0; + min_buffers = 0; copy_threshold = 0; g_assert_not_reached (); break; } + if (can_allocate) + max_latency = max_buffers; + else + max_latency = min_buffers; + pool->size = size; pool->copy_threshold = copy_threshold; - pool->num_buffers = num_buffers; + pool->max_latency = max_latency; + pool->min_latency = min_latency; pool->num_queued = 0; if (max_buffers < min_buffers) @@ -780,7 +776,7 @@ no_buffers: { GST_ERROR_OBJECT (pool, "we received %d buffer from device '%s', we want at least %d", - num_buffers, obj->videodev, GST_V4L2_MIN_BUFFERS); + min_buffers, obj->videodev, GST_V4L2_MIN_BUFFERS); gst_structure_free (config); return FALSE; } diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h index 3459637d51..eb9e814054 100644 --- a/sys/v4l2/gstv4l2bufferpool.h +++ b/sys/v4l2/gstv4l2bufferpool.h @@ -60,7 +60,8 @@ struct _GstV4l2BufferPool gboolean add_videometa; /* set if video meta should be added */ - guint num_buffers; /* number of buffers we use */ + guint min_latency; /* number of buffers we will hold */ + guint max_latency; /* number of buffers we can hold */ guint num_queued; /* number of buffers queued in the driver */ guint copy_threshold; /* when our pool runs lower, start handing out copies */ diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 12a30df2c5..1386333e70 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -505,7 +505,7 @@ gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query) /* max latency is total duration of the frame buffer */ if (obj->pool != NULL) - num_buffers = GST_V4L2_BUFFER_POOL_CAST (obj->pool)->num_buffers; + num_buffers = GST_V4L2_BUFFER_POOL_CAST (obj->pool)->max_latency; if (num_buffers == 0) max_latency = -1;