Sometime cases were observed, where the time returned from
pw_stream_get_time_n() had incorrect values.
The root cause was not fully tracked down. Roughly the case was as
follows: A gstreamer pipeline with two gstpipewiresrc elements. One
audio and one libcamera besed video src, both fed into a mp4 encoding
mux. The cock was provided by the audio gstpipewiresrc. Now between
starting the pipewire video stream and receiving the first camera frame
pw_stream_get_time_n() returned strange values (It seemed like it was
using the audio rate for something internally). This wrong value was
used to initialze pclock->start_time and therefore all following calls
to gst_pipewire_clock_get_internal_time() returned completely wrong
values.
Add a warning to hopefully catch these cases. I don't have a proper use
case to test the clock interpolation done in
gst_pipewire_clock_get_internal_time() so I can't drop that (which would
remove the bogus call to pw_stream_get_time_n() alltogether), although
it feels like the right thing to do.
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
The clock has SPA_IO_CLOCK_FLAG_NO_RATE set unconditionally and the rate is usally
0/0. So all the rate calculations produce NaN and are not necessary.
Drop them.
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
When a gstreamer pipeline transits to playing state, it sets the
base_time of all elements to the internal time of the current clock. At
that point, the pipewire stream has not yet started and the
gstpipewireclock returns last_time which is initialized to 0 in
gstpipewirestream. This leads to a incorrect base_time in the gstreamer
element and various synchronization issues.
The use-case for last_time is not really clear to me. My basic guesswork
is: If a stream is no longer streaming the internal clock should pause
at that time and return last_time. So this patch keeps this behaviour
in place and only ensures that a valid time is returned when the stream
is not yet started and last_time is not in the future.
To keep the time scaling logic in place, a start time is recorded when
the stream was started, to properly match stream time and clock
monotonic.
A gstreamer pipeline that can be used to replicate the issue is:
GST_DEBUG="pipeline:5,GST_CLOCK:6,pipewiresrc:6" gst-launch-1.0 \
pipewiresrc name=video target-object=<some video target> ! \
video/x-raw,format=UYVY ! fakesink \
pipewiresrc name=audio target-object=<some audio target> ! \
audio/x-raw ! f akesink 2>&1 | \
grep PTS
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
Changes in v2:
- Drop incorrect logic in case s == NULL
- Keep clock scaling in place
It can not generically assumed that the gstreamer clock (and therefore
the base_time) is based on CLOCK_MONOTONIC.
It was tried to use the logic provided by
GstBaseSrc::gst_base_src_do_sync() in commit 004206db37
("gst/pipewiresrc: Let GstBaseSrc handle pseudo-live calculations").
This has the downside, that a potential jitter on the first buffer is
included in the calculated time offset. In gstreamer pipelines with
multiple pipewiresrc elements and big jitter on the first buffer the
streams will stay out of sync.
Improve that by checking if the gstreamer clock is provided by pipewire
and therefore known to be CLOCK_MONOTONIC or if it is provided by
gstreamer and we need to manually calculate the base_time.
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
When the close argument is true, loop_add_io is supposed to close the fd
even when an error occurs.
This makes it possible to have spa_steal_fd() work even in the case
of errors.
Make a new library.filter-path for the filter-graph that will filter and
restrict the dlopen filenames (used for the LADSPA plugin only).
By default this is false and so filter-chain can load from absolute
paths without extra checks.
Enable the extra checks for the pulse LADSPA modules and the
audioconvert filter graphs because these allow loading LADSPA plugins
into other processes.
Fixes#5222
When we are asked to add noise bits, don't call the clear function.
Make the passthrough and clear-on-empty flags available with a new flag
field to make it more extensible.
Fixes#5260
There could have been a write error or allocation error while building
the json file that we can detect in spa_json_builder_close().
Error out instead of silently using a truncated JSON.
Use spa_autofree for the memory to make cleanup easier.
Make the module valid_args a structure that includes the argument key,
description and some flags. Use this to enforce mandatory properties
in a more central place.
We should be able to generate the module usage from this as wel later to
have things a bit more structured.
Convert matrix_orig and matrix to float arrays and use variable size 2d
arrays to access the elements of the matrices. This removes the need for
storing pointers to matrix rows.
Make pw_net_get_ip also accept NULL ip to just get the port and ip
version. Make rtsp-client use pw_net_get_ip.
Make sure we initialize the iovec before logging in all cases.
Print a warning if a control value is clamped instead of silently
failing as the user might want to know if the intended
configuration was not applied successfully, such as filter
parameters.
If the pipeline is running for coverity scan, then only two jobs are needed:
* container_coverity
* build_with_coverity
but currently 4 container, 1 build, and 1 deploy jobs are running unnecessarily.
Disable the container jobs by simply extending `.not_coverity`.
The `build_on_fedora_html_docs` and `pages` jobs already extend `not_coverity`,
however, they override the `rules` section, hence it is replaced, so the "not coverity"
condition is lost. Fix that by adding the condition separately. (`build_on_fedora_html_docs`
referencesc the rules of `pages`, so modifying the latter is sufficient.)
The bluetooth VM tests require building BlueZ (specific version is
better than relying on FDO image version) and building pytest-bluezenv.
Build them and cache the results.
Add tests that check PipeWire <-> PipeWire bluetooth audio streaming for
A2DP, BAP, HFP. The tests use Qemu VMs and don't require Bluetooth
support from HW / kernel.
Full VM images are not required; similarly to BlueZ kernel tester these
use (read-only) mount of host filesystem. A monolithic kernel image
with suitable config is required. The bluetoothd binary installed on
host is used if found; otherwise tests are skipped.
These test depend on https://github.com/pv/pytest-bluezenv which manages
the VM setup.
To launch:
python3 -m pip install pytest-bluezenv
meson devenv -C builddir -w . python3 -m pytest test --kernel-build -v
which also builds a kernel image with required options.
BAP/USR/ADV/BV-01-C test requires to advertise Audio Stream Control
Service properties with General Announcement type and supported
contexts values for sink and source which should be in sync with
the PACS values.