The current BAP QoS configuration allows to register a sampling
frequency based on the configuration done using wireplumber configuration.
However, for a scenario were the user need to use a specific SDU framelength
it cannot be done as the select_bap_qos function selects the QOS based on
priority and hence it will use the best possible config rather than the user
configured.
This PR adds option to select the QoS set based on user configured value. If
the remote device doesn't have the user configured capabilities it will always
use the best priority config.
Further, this change also allows the user to set RTN, Latency, Delay QoS config
for certain use case to have controller use optimum bandwidth usage.
Below are the example configuration on setting LC3 capabilities in config file:
bluez5.bap.set_name = "48_2_1"
bluez5.bap.rtn = 5
bluez5.bap.latency = 20
bluez5.bap.delay = 40000
bluez5.framing = false
The current BAP unicast QoS configuration allows to register a sampling
frequency based on the configuration done using wireplumber configuration.
However, for a scenario were the user need to use a specific SDU framelength
it cannot be done as the select_bap_qos function selects the QoS based on
priority and hence it will use the best possible config rather than the user
configured.
This PR adds option to select the QoS set based on user configured value. If
the remote device doesn't have the user configured capabilities it will always
use the best priority config.
Further, this change also allows the user to set RTN, Latency, Delay QoS config
for certain use case to have controller use optimum bandwidth usage.
Below is the example for the options that can be configured & selected
in config file:
bluez5.bap.set_name = "48_2_1"
bluez5.bap.rtn = 5
bluez5.bap.latency = 20
bluez5.bap.delay = 40000
bluez5.framing = false
Parameter values read into a 512 byte long buffer, which is insufficient
for medium to long filter-graph parameters.
Increase the buffer to 4096 bytes to give some wiggle-room.
Add support for FairPlay SAP v2.5 (encryption type 5) type devices such as Apple Home Pod Minis.
Apparently only these devices require the `POST /feedback` heartbeat, so fix that.
When PW source is used with something like Camera and the camera is
disconnected, all buffers are removed and stream will be paused.
When using PW sink with source, the sink side pipeline can go to EOS.
This again results in all the buffers being removed and stream being
paused on the source side. PW source side pipeline can also crash if
the sink was in the middle of frame copying a buffer to render which
got removed.
Handle this scenario by sending a flush-start event at the start of
buffer removal and flush-stop at the end followed by an end of stream
or pipeline error depending on user selection.
Initialize the byte array with bytes instead of a string because the 0
byte at the end of the string does not fit in the array and causes a
compiler warning.
For a pipeline like below, we might want to dynamically switch the audio
source.
gst-launch-1.0 -e pipewiresrc autoconnect=false ! queue ! audioconvert ! autoaudiosink
On switching to a different audio source, any one of driver, quantum
or clock rate might change which changes the return `result` value of
gst_pipewire_clock_get_internal_time.
This can result in the basesrc create function incorrectly waiting in
gst_clock_id_wait. We post clock lost message to fix this. In the case
of gst-launch, it will set the pipeline to PAUSED and then PLAYING to
to force a new clock and a new base_time distribution.
Without the clock lost message, the following can be seen
before re-linking to a different source
0:00:30.887602864 79499 0x7fffe8000d40 DEBUG GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:17.024565416 now 0:00:17.024109144 diff (time-now) 456272
after re-linking to a different source
0:00:45.790843245 79499 0x7fffe8000d40 DEBUG GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:31.927694059 now 0:00:17.066883864 diff (time-now) 14860810195
With the clock lost message, the following can be seen
before re-linking to a different source
0:01:09.336533552 89461 0x7fffe8000d40 DEBUG GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:58.198536772 now 0:00:58.197444926 diff (time-now) 1091846
after re-linking to a different source
0:01:21.659827958 89461 0x7fffe8000d40 DEBUG GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:28:24.853517646 now 0:28:24.853527204 diff (time-now) -9558
Note the difference in `time` and `now` fields of the above log message.
This is easy to reproduce by using a pipewiresink as the audio source
with a pipeline like below, as one of the sources during switching.
gst-launch-1.0 -e audiotestsrc wave=ticks ! audioconvert ! audio/x-raw,format=F32LE,rate=48000,channels=1 !
pipewiresink stream-properties="props,media.class=Audio/Source,node.description=pwsink" client-name=pwsink
Applications need to handle the GST_MESSAGE_CLOCK_LOST message in their
bus handlers.
Let's make sure we own the memory in buffers, so that we can be
resilient to the PW link going away. This currently maintains the status
quo of copying data into the pipewirepool for sending to the remote end,
but moves the allocation of buffers so that ownership is maintained by
the sink in all cases.
There are some tricky corners, especially with bufferpool vs. buffers
param negotiation -- bufferpool parameters can be negotiated in
GStreamer before the link even comes up, so we try to adapt the buffers
param to use the negotiated value. For now, that is more brittle than
tying those two aspects together. We can revisit this if we can find a
way to tie pipeline state and link state more closely.
Co-authored-by: Arun Raghavan <arun@asymptotic.io>
Parse and use DSP formats.
Redo the conversion setup when the formats changed. We usually do this
when starting the node but the formats can change while running as well.
When the builder is overflowed, we might get a NULL pod. This is a valid
situation that we need to handle because it can be used to get the
required builder buffer size.
Get the dataType field from the Buffer param. This is a mask of the
supported data types for the buffers. Pass this to the allocating node
if there is one, otherwise use MemPtr as the allocated format.
The set_format function can return 1 when the format was adjusted to the
nearest supported format so return this from the port_set_param
function.
This instructs the adapter to recheck the configured format so that it
can store the adjuted format on the converter.
Because we advertize on out ports that we support DYNAMIC data, we need
to read the data pointer directly from the buffer and only fall back to
our cache (mmaped) pointer when it is NULL.
With DYNAMIC data, the peer element (mixer-dsp) directly copies the
input data pointer into the buffer data in the processing loop in order
to avoid a memcpy when there is no mixing needed.
When there is no data and the buffer is mmapable, try to mmap it. Unmap
again when clearing the buffers.
Use the mmaped data pointer of the buffer when processing.
Prefer to let the follower allocate buffers. If we are allocating
buffers, first do use_buffers on the allocating node or else the
non-allocating node just ends up with NULL buffers.
Keep the passthrough flag up to date when we unset a port format or when
it changes.
We should only fill in the buffer data/fd when the ALLOC flag is set.
We should only take the passthrough input buffer as output when we are
in passthrough mode.
Copy the header metadata.
A number of changes for correctness.
1) We expose the actualy min and max values we support in the
allocation query.
2) We don't support max_buffers as 0, as unlimited buffers is not an
option
3) In ParamBuffers, we request the max_buffers from bufferpool config,
as we cannot dynamically allocate buffers
We need to make sure the memory sizes are correctly initialised so the
meta makes sense, and we don't copy the meta from the input buffer as
that doesn't make sense given we have our own meta already.