The "connection" address ("c=") is meant to be the address that the
RTP receiver will use to filter for incoming packets. In multicast,
it must be the multicast address, which is also the "destination"
address in this context. In unicast, however, it must be the sender's
address, i.e. the "source" in this context. The RTP receiver will
then call connect() on this address, effectively filtering the incoming
packets to the ones coming from that particular source.
Allows us to get error counts and occasional samples, which can be handy
if we are CPU-bound. There is room to improve this by having
module-profiler create aggregates, which might be more useful that
periodic instaneous samples. However, this would need more logic to
store node data in between emissions, so we'll punt that to later.
Don't wait for the completion of the Pause command of the node but send
it to the stream immediately. Delaying it might make it come after the
set_param calls are done and confuse the stream.
Follow the state of the node and update the stream state accordingly.
The most important part is that Start is async and so it's better to
wait for completion from the node before emiting the STREAMING state.
Make `client_queue_subscribe_event()` take the facility and type
separately, and calculate the mask itself, so that the caller
does not need to be concerned with that.
Make a function that can initialize raw audio info from a dict and fill
in the defaults. We can use this in many of the modules when the audio
format is parsed.
Use the helper instead of duplicating the same code.
Also add some helpers to parse a json array of uint32_t
Move some functions to convert between type name and id.
When we emit the RequestProcess event from an exported node, don't
send the RequestProcess command to ourselves but let the server
decide where to send it to.
GSTs DMA_DRM API does explicitely not support implicit modifiers and
trying to use it would result in assertions like
```
gst_video_dma_drm_fourcc_to_string: assertion 'modifier != DRM_FORMAT_MOD_INVALID' failed
```
Fixes: f1b75fc6f ("gst: Add support for DMA_DRM / explicit modifiers")
This gets the next key and value from an object. This function is better
because it will skip key/value pairs that don't fit in the array to hold
the key.
The previous code patter would stop parsing the object as soon as a key
larger than the available space was found.
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object
This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
By setting a "is-default" boolean property on the discovered GstDevice(s) the
application now gets a good hint of which device to select and use.
Fixes#4268
Intercept the Output Latency paran and parse it for later.
Use the computed latency as the ProcessLatency and expose this
as the ProcessLatency param and the updated Input latency.
Accept updates to ProcessLatency to modify the latency, which then also
updates the Input Latency param.
See #4270
Improve the Latency reporting, we always report Input and Output latency
pairs.
Keep ProcessLatency on the capture and playback streams. The capture
stream process latency is reported as input latency and the playback
process latency as output latency.
Setting ProcessLatency on the capture stream (Sink), for example, will
propagate the added latency upstream. This would then instruct players
to send the audio earlier to compensate for the delay.
See #4270
Keep the original sequence number of the port_set_param(Format) and
port_use_buffer() calls around. When they produce an error, we will
get an error with the same sequence number.
When the sync completes, check if we got an error for the pending
operation and return that as the result.
We then also mark the link in error. We don't mark the port in error
because that is not really the case.
This should make the link error when negotiation of format or buffers
fails instead of silently continuing.
Instead of binding the socket to 0.0.0.0 with port 0, make some config
options source.ip and source.port to configure this. This makes it
possible to bind to other interfaces or to use a fixed port for the
data messages.
Fixes#4144
First try to parse the float value as a JSON number and then fall
back to atof to get the locale dependent variant.
This transparently makes things work with values such as 0.5 and 0,5.
Fixes#4234
Our current AES67 sender setup requires that that PTP driver drive the
entire graph. This adds support for allowing the AES67 RTP sink to be
driven by an arbitrary driver, while still using the PTP driver for
sending data on the network.
When aes67.driver-group is specified a pw_filter is created with no
ports, node.always-process = true and node.group set to the
aes67.driver-group. When set to PTP, this gives us process callbacks at
the PTP rate which we use to get the current PTP time in the RTP sender
by interpolating the clock snapshots from the pw-filter.
Implementation ideas from Wim Taymans. Co-authored with Sanchayan Maity.
For a detailed reference, refer the following papers by Fons Adriaensen.
- Using a DLL to filter time
(https://kokkinizita.linuxaudio.org/papers/usingdll.pdf)
- Controlling adaptive resampling
(http://kokkinizita.linuxaudio.org/papers/adapt-resamp.pdf)
We allow a quantum of jitter in the write timestamp. The previous value
of 32 seems to be empirically determined, using the actual quantum
allows us to reason about this better.