mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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:
parent
2e89f4ecff
commit
66519d08b0
3 changed files with 39 additions and 42 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue