This is a followup patch for #700781, which is not quite correct.
The buffer handling is quite complicated here.
The original code intended to the the following:
- gst_v4l2_buffer_pool_process() calls QBUF and adds the buffer to the
local list.
- The sink calls gst_buffer_unref() which returns the buffer to the pool
but not the 'free list'.
- Some time later DQBUF returns the buffer and
gst_v4l2_buffer_pool_release_buffer() puts in on the 'free list'.
If the buffer must be copied then (parent_class)->acquire_buffer() is
called directly to keep the buffer in the pool.
This has two problems:
1. If gst_v4l2_buffer_pool_release_buffer() is called before the buffer is
returned to the pool, then the buffer is put on the 'free list' twice.
This can happen if a reference to the buffer is kept outside the sink,
of if DQBUF returns the buffer, that was just queued with QBUF.
2. If buffers are copied, then all buffers are in the pool at all times. As
a result gst_v4l2_buffer_pool_stop() and gst_v4l2_buffer_pool_dqbuf()
can access pool->buffers at the same time, which can lead to memory
corruption.
The patch for #700781 fixes those problems, but with the side effect that
there are always buffers outside the pool (because they are queued) and
the pool is never stopped.
This patch fixes this by releasing the reference to the buffer after
handling it (to avoid problem 2.) so it can be returned to the pool.
gst_v4l2_buffer_pool_release_buffer() is only called if the buffer is
already in the pool (to avoid problem 1.).
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=701375
Without this, a queued buffer may be required, filled and queued before it
is dequeued.
Calling gst_buffer_pool_acquire_buffer() ensures that the buffer is set up
correctly and gst_buffer_unref() calls buffer_release().
https://bugzilla.gnome.org/show_bug.cgi?id=700781
When queuing a buffer for a sink, bytesused must contain the actual
amount of data.
For a source, the driver must overwrite this, so it doesn't matter
what is set here.
https://bugzilla.gnome.org/show_bug.cgi?id=699598
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
Don't just loop over the first num_queued buffers but loop over
all the buffers and check if they need to be freed. It is possible that
not all buffers are queued and then the entry in our array will be NULL.
Those buffers that are not queued were freed in stop().
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=696651
v4l has add a new IOCTL to export a buffer by using dmabuf.
This patch allow to use this new IOTCL if it has been defined in videodev2.h
I introduce a new IO mode (GST_V4L2_IO_DMABUF) to enable this way of working.
https://bugzilla.gnome.org/show_bug.cgi?id=693826
This was unused apparently and removed in the kernel in commit:
From 2b719d7baf490e24ce7d817c6337b7c87fda84c1 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@iki.fi>
Date: Wed, 2 May 2012 09:40:03 -0300
Subject: [PATCH] [media] v4l: drop v4l2_buffer.input and V4L2_BUF_FLAG_INPUT
Remove input field in struct v4l2_buffer and flag V4L2_BUF_FLAG_INPUT which
tells the former is valid. The flag is used by no driver currently.
https://bugzilla.gnome.org/show_bug.cgi?id=681491
Conflicts:
sys/v4l2/gstv4l2bufferpool.c
Query the amount of available buffers when doing set_config(). This allows us to
configure the parent bufferpool with the number of buffers to preallocate.
Keep track of the provided allocator and use it when we need to allocate a
buffer in RW mode.
When we are can not allocate the requested max_buffers amount of buffers, make
sure we keep 2 buffers around in the pool and copy them into an output buffer.
This makes sure that we always have a buffer to capture into. We also need to
detect those copied buffers and unref them when they return to the pool.
Only free the queued buffers that we keep track of in our buffer array. for rw
io-mode, we do allocate buffers but we don't keep track of them in the buffer
array.
Add private replacements for deprecated functions such as
g_mutex_new(), g_mutex_free(), g_cond_new() etc., mostly
to avoid the deprecation warnings. We'll change these
over to the new API once we depend on glib >= 2.32.
When nobody is using our pool, activate it ourselves.
Avoid leaking the buffer array.
Set default pool configuration with caps.
Don't keep current_caps, core does that for us now.
Use the more specialized type for the bufferpool.
Use the size from the driver as the size of the image to read.
Don't configure the pool when created. This will be done in the setup_allocation
method later or by upstream for sinks.
Remove unused properties and variables. Bufferpool sizes are now configured in
the bufferpool by the elements in the pipeline. We might want to influence the
pool size later somehow.
Prefer to always use the default bufferpool queue for the _acquire function
because it properly supports unblocking when setting inactive etc. As a result,
we need to dequeue buffers and put them back in the bufferpool queue when we
have queued all buffers in the sink.
Rename some variables to more meaningfull names to avoid a problem with
freeing the wrong amount of buffers.
Remove old method, use neww _process method for the sink.
Inform the parent bufferpool class about the settings too. This is needed to let
it know about the max-buffers.
Allocate the negotiated max-buffers and initially mmap min-buffers. The idea is
that the bufferpool will allocate more when needed.
Improve debugging.
Only poll in capture mode, it does not seem to work in playback mode on this
beagleboard.
Add different transport methods to the bufferpool (MMAP and READ/WRITE)
Do more parsing of the bufferpool config.
Start and stop streaming based on the bufferpool state.
Make separate methods for getting a buffer from the pool and filling it with
data. This allows us to fill buffers from other pools too. Either use copy or
read to fill up the target buffers.
Add property to force a transfer mode in v4l2src.
Increase default number of buffers to 4.
Negotiate bufferpool and its properties in v4l2src.
When we have all buffers queued for playback and we need a new empty buffer,
dequeue one and return it.
Set the right size for sink buffers.
Improve counting of queued buffers.
Extend from GstBufferPool.
Handle the lifetime of the pool buffers correctly with the start/stop vmethods.
Map acquire and release directly to QBUF and DQBUF. We still expose an explicit
qbuf for the v4l2sink for now.
We want to keep the default strides in the videoinfo. Keep the stride of the
video frames separate so that we can use both to copy a video frame and do
correct stride conversion.
Keep track of the currently configured format and setting in the
v4l2object.
Pass the v4l2object to the bufferpool constructor so that the bufferpool can
know everything about the currently configured settings. This also allows us
to remove some awkward code.
Various cleanups, avoids useless casts, move error handling outside of the main
code flow.
Negotiate to a resonable resolution instead of the max resolution.
Older kernels don't have these, and there's no easy way to check for the
existance of enums that doesn't involve a configure check, so just define
these if the V4L2_CAP_VIDEO_OUTPUT_OVERLAY define is not there, which was
added in the same commit as the TB/BT enum. Fixes compilation on CentOS 5.
https://bugzilla.gnome.org/show_bug.cgi?id=639339
The size of the buffer would be zero'd out in gst_v4l2_buffer_finalize()
after the buffer is qbuf'd or pushed onto the queue of available buffers..
leaving a race condition where the thread waiting for the buffer could awake
and set back a valid size before the finalizing thread zeros out the length.
This would result that the newly allocated buffer has length of zero.
We'd prefer to throttle the decoder if we run out of buffers, to keep a bound
on memory usage. Also, for OMAP4 it is a requirement of the decoder to not
alternate between memory alloced by the display driver and malloc'd userspace
memory.
note: this really only affects v4l2sink since gst_v4l2_buffer_pool_get() is
only called once per buffer in the v4l2src case (in
gst_v4l2src_buffer_pool_activate())
It seems to cause strange occasional high latencies (almost 200ms) when dequeuing buffers from _buffer_alloc(). It is simpler and seems to work much better to dqbuf from the same thread that is queuing the next buffer.
This also does the following changes:
(1) pull the bufferpool code out into gstv4l2bufferpool.c, and make a
bit more generic so it can be used both for v4l2src and v4l2sink
(2) move some of the device probing/configuration/caps stuff into
gstv4l2object.c so it does not have to be duplicated between
v4l2src and v4l2sink
Fixes bug #590280.