v4l2: Cleanup and fix calculation of latency

Calculation of num_buffers (the max latency in buffers) was
up-side-down.  If we can allcoate, then our maximum latency match
pool maximum number of buffers. Also renamed it to max latency. Finally
introduced a min_latency for clarity.
This commit is contained in:
Nicolas Dufresne 2014-05-24 23:31:24 -04:00
parent 2e89f4ecff
commit 66519d08b0
3 changed files with 39 additions and 42 deletions

View file

@ -622,7 +622,8 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
GstStructure *config; GstStructure *config;
GstCaps *caps; GstCaps *caps;
guint size, min_buffers, max_buffers; 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"); GST_DEBUG_OBJECT (pool, "activating pool");
@ -631,31 +632,28 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
&max_buffers)) &max_buffers))
goto wrong_config; 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) { switch (obj->mode) {
case GST_V4L2_IO_RW: case GST_V4L2_IO_RW:
/* this value also instructs the latency calculation to have min_buffers can_allocate = TRUE;
* frame latency max */
num_buffers = min_buffers;
break; break;
case GST_V4L2_IO_DMABUF: case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_MMAP: case GST_V4L2_IO_MMAP:
{ {
guint count; guint count;
if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) { can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
num_buffers = min_buffers;
} else {
num_buffers = max_buffers;
}
/* first, lets request buffers, and see how many we can get: */ /* 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); V4L2_MEMORY_MMAP);
if (count < GST_V4L2_MIN_BUFFERS) { if (count < GST_V4L2_MIN_BUFFERS) {
num_buffers = count; min_buffers = count;
goto no_buffers; 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 * falling back to copy if the pipeline needed more buffers. This also
* prevent having to do REQBUFS(N)/REQBUFS(0) everytime configure is * prevent having to do REQBUFS(N)/REQBUFS(0) everytime configure is
* called. */ * called. */
if (count != num_buffers) { if (count != min_buffers) {
GST_WARNING_OBJECT (pool, "using %u buffers instead of %u", GST_WARNING_OBJECT (pool, "using %u buffers instead of %u",
count, num_buffers); count, min_buffers);
num_buffers = count; min_buffers = count;
copy_threshold = copy_threshold = min_latency;
MAX (GST_V4L2_MIN_BUFFERS, obj->min_buffers_for_capture);
/* The initial minimum could be provide either by GstBufferPool or /* The initial minimum could be provide either by GstBufferPool or
* driver needs. */ * driver needs. */
@ -682,60 +679,59 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
{ {
guint count; guint count;
if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR)) { can_allocate =
num_buffers = min_buffers; GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
} else {
num_buffers = max_buffers;
}
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); V4L2_MEMORY_USERPTR);
/* There is no rational to not get what we asked */ /* There is no rational to not get what we asked */
if (count < num_buffers) { if (count < min_buffers) {
num_buffers = count; min_buffers = count;
goto no_buffers; goto no_buffers;
} }
min_buffers = num_buffers = count; min_buffers = count;
break; break;
} }
case GST_V4L2_IO_DMABUF_IMPORT: case GST_V4L2_IO_DMABUF_IMPORT:
{ {
guint count; guint count;
if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF)) { can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
num_buffers = min_buffers;
} else {
num_buffers = max_buffers;
}
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); V4L2_MEMORY_DMABUF);
/* There is no rational to not get what we asked */ /* There is no rational to not get what we asked */
if (count < num_buffers) { if (count < min_buffers) {
num_buffers = count; min_buffers = count;
goto no_buffers; goto no_buffers;
} }
min_buffers = num_buffers = count; min_buffers = count;
break; break;
} }
default: default:
num_buffers = 0; min_buffers = 0;
copy_threshold = 0; copy_threshold = 0;
g_assert_not_reached (); g_assert_not_reached ();
break; break;
} }
if (can_allocate)
max_latency = max_buffers;
else
max_latency = min_buffers;
pool->size = size; pool->size = size;
pool->copy_threshold = copy_threshold; pool->copy_threshold = copy_threshold;
pool->num_buffers = num_buffers; pool->max_latency = max_latency;
pool->min_latency = min_latency;
pool->num_queued = 0; pool->num_queued = 0;
if (max_buffers < min_buffers) if (max_buffers < min_buffers)
@ -780,7 +776,7 @@ no_buffers:
{ {
GST_ERROR_OBJECT (pool, GST_ERROR_OBJECT (pool,
"we received %d buffer from device '%s', we want at least %d", "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); gst_structure_free (config);
return FALSE; return FALSE;
} }

View file

@ -60,7 +60,8 @@ struct _GstV4l2BufferPool
gboolean add_videometa; /* set if video meta should be added */ 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 num_queued; /* number of buffers queued in the driver */
guint copy_threshold; /* when our pool runs lower, start handing out copies */ guint copy_threshold; /* when our pool runs lower, start handing out copies */

View file

@ -505,7 +505,7 @@ gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query)
/* max latency is total duration of the frame buffer */ /* max latency is total duration of the frame buffer */
if (obj->pool != NULL) 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) if (num_buffers == 0)
max_latency = -1; max_latency = -1;