The pool orphaning function was colling internal _stop() virtual function
implementation. This is not thread safe, as a private lock inside the buffer
pool is supposed to be held. Fix this by keeping delayed _stop() and orphaning
the GstV4L2Allocator instead (REQBUFS(0)).
Then, protect the orphaned boolean with the object lock for the case a buffer
is being released after we have orphaned the buffer. That would otherwise
cause a QBUF to happen while the queue is no longer owned by the buffer pool.
This boolean is otherwise used and set from the streaming lock, or after
threads have been stopped (final cleanup).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/648>
On streamon, we need to resurrect (queue back) some buffers, as during
flushign seek we'd endup with an empty queued. We initially started with
resurrecting as many as we could without blocking, but that miss-behaved with
dynamic CREATE_BUFS, causing the pool to grow dramatically. This was limited
by the number of allocated buffers, but this still tried to resurrect too many
buffers for the first run, as activating the pool will queued buffers.
In this patch, we calculte the missing detal in the queue and only try and
resurrect that amount of buffers.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/651>
The profiles and levels were applied to the common caps instead of the copy.
That had the side effect of setting profiles/level from one CODEC onto
another. Leaving to encoder not being registered or not-negotiated errors.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/599>
This patch will now set the maximum of buffers to 32, allowing to grow the
pool for drivers that supports that and will respect the minimum buffers
reported by the driver. This was made to fix a stall with the virtio CODEC
driver.
Fixes#672
There are often only two buffers queued in the kernel so no new buffers are
requested.
With every qbuf, the kernel receives a new DMABUF for the specified index.
This most likely differs from the last DMABUF and the old cached entry is
released. This results in a lot of map/unmap overhead if the kernel driver
needs a mapping for the buffer.
With a larger queue, it's quite likely, that both old and new DMABUFs are
also mapped for another index. So the map/unmap is skipped, because the
mapping is reference counted.
The corresponding allocated buffers don't contain any actual memory, so
allocating them is quite cheep. So the log message is updated to clarify
this.
When using this mode each frame is split in two fields, each one being
transferred using its own buffer.
This is implemented with the V4L2_FIELD_ALTERNATE field format in v4l2.
This mode is enabled using a caps filter such as
"v4l2src ! video/x-raw\(format:Interlaced\)"
Here are the main changes related to this feature:
- use the INTERLACED caps feature with this mode.
- in this mode both fields of a given frame have the same sequence/offset
so adjust the algorithm checking for lost field/frame accordingly.
- double pool's min number of buffers as each frame requires 2 buffers.
Fix#504
Co-authored-by: Zeeshan Ali <zeenix@collabora.co.uk>
Use GST_VIDEO_INFO_FIELD_HEIGHT() instead of GST_VIDEO_INFO_HEIGHT()
when we actually want the field height rather than the frame height.
So far both are equals but that won't longer be the case when
implementing alternate interlace mode.
Lower the verbosity of the 'sync' log message emitted
each buffer from gst_v4l2src_create down to LOG(6)
from INFO(4). This brings the logging behavior of
v4l2src closer to the GStreamer guidelines, which
recommend the INFO level be reserved for rare or
one-off messages.
gst_v4l2_object_set_format_full() was returning FALSE without setting
an error. Caller code (gst_v4l2src_fixate()) was then derefing a
NULL pointer when trying to handle the error.
Before we do streamon, we queue all capture buffers by calling
resurrect. When the driver supports CREATE_BUFS, this would lead
to buffers being allocated till the maximum of 32 is reached.
Instead, we now save the number of allocated buffers and queue this
amount.
libv4l2 reset the colorpace to 0 and does not do any request to the
driver. This yields an invalid colorspace which currently cause a
negotiation failure. This workaround by ignoring bad values during the
TRY_FMT step.
By passing `NULL` to `g_signal_new` instead of a marshaller, GLib will
actually internally optimize the signal (if the marshaller is available
in GLib itself) by also setting the valist marshaller. This makes the
signal emission a bit more performant than the regular marshalling,
which still needs to box into `GValue` and call libffi in case of a
generic marshaller.
Note that for custom marshallers, one would use
`g_signal_set_va_marshaller()` with the valist marshaller instead.
Try configuring the v4l2 output with the alignments from upstream when
importing its buffers. This allows us to support importing with
non-standard strides and/or heights if supported by the driver.
We were already supporting horizontal padding by setting bytesperline to
the buffer stride but not vertical one.
We are now updating the format height with the padded height and crop to
the actual video resolution if needed.
In commit e2ff87732d ("v4l2videodec: support orphaning") support for
orphaning the capture buffer pool was added when the format is
renegotiated. However, the commit forgot to check that a pool existed
before doing this. This is needed because it's possible for the format
to be renegotiated before a capture pool is allocated, which would
result in trying to orphan a NULL pool and lead to a NULL pointer
dereference.
Fix this by checking a pool exists first. If the pool doesn't exist,
there are no buffers to be reclaimed, so skip the allocation query in
that case.
Backward playback will drain and flush every frame. Stop playback
when backward playback have race condition between exit thread and
streaming thread flush. Add one check to avoid it.
Fixes#639