mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: iso-io: sync to ISO RX clock, align stream RX in group
Align RX of streams in same ISO group: - Ensure all streams in ISO group have same target latency also for BAP Client - Determine rate matching to ISO group clock from RX times of all streams in the group - Based on this, compute nominal packet RX times, and feed them to decode-buffer instead of the real RX time. This is enough for sub-sample level sync. - Customise buffer overrun handling for ISO so that it drops data to arrive exactly at the target, for faster convergence at RX start The ISO clock matching is done based on kernel-provided packet RX times, so it has unknown offset from the actual ISO clock, probably a few ms. Current kernels (6.17) do not provide anything better to use for the clock matching, and doing it properly appears to be controller vendor-defined (if possible at all).
This commit is contained in:
parent
94c354c290
commit
589bc4b6f4
3 changed files with 305 additions and 49 deletions
|
|
@ -572,6 +572,9 @@ static void add_data(struct impl *this, uint8_t *src, uint32_t src_size, uint64_
|
|||
|
||||
spa_log_trace(this->log, "%p: read socket data size:%d", this, src_size);
|
||||
|
||||
if (this->transport->iso_io)
|
||||
now = spa_bt_iso_io_recv(this->transport->iso_io, now);
|
||||
|
||||
do {
|
||||
int32_t consumed;
|
||||
uint32_t avail;
|
||||
|
|
@ -674,8 +677,10 @@ stop:
|
|||
this->io_error = true;
|
||||
if (this->source.loop)
|
||||
spa_loop_remove_source(this->data_loop, &this->source);
|
||||
if (this->transport && this->transport->iso_io)
|
||||
if (this->transport && this->transport->iso_io) {
|
||||
spa_bt_iso_io_set_cb(this->transport->iso_io, NULL, NULL);
|
||||
spa_bt_iso_io_set_source_buffer(this->transport->iso_io, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int media_sco_pull(void *userdata, uint8_t *buffer_read, int size_read, uint64_t now)
|
||||
|
|
@ -931,6 +936,8 @@ static int transport_start(struct impl *this)
|
|||
if (this->codec->kind != MEDIA_CODEC_HFP) {
|
||||
spa_bt_recvmsg_init(&this->recv, this->fd, this->data_system, this->log);
|
||||
|
||||
spa_loop_locked(this->data_loop, do_start_sco_iso_io, 0, NULL, 0, this);
|
||||
|
||||
this->source.data = this;
|
||||
|
||||
this->source.fd = this->fd;
|
||||
|
|
@ -944,10 +951,8 @@ static int transport_start(struct impl *this)
|
|||
spa_zero(this->source);
|
||||
if (spa_bt_transport_ensure_sco_io(this->transport, this->data_loop, this->data_system) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (this->transport->iso_io || this->transport->sco_io)
|
||||
spa_loop_locked(this->data_loop, do_start_sco_iso_io, 0, NULL, 0, this);
|
||||
}
|
||||
|
||||
this->transport_started = true;
|
||||
|
||||
|
|
@ -1045,8 +1050,10 @@ static int do_remove_transport_source(struct spa_loop *loop,
|
|||
|
||||
if (this->source.loop)
|
||||
spa_loop_remove_source(this->data_loop, &this->source);
|
||||
if (this->transport->iso_io)
|
||||
if (this->transport->iso_io) {
|
||||
spa_bt_iso_io_set_cb(this->transport->iso_io, NULL, NULL);
|
||||
spa_bt_iso_io_set_source_buffer(this->transport->iso_io, NULL);
|
||||
}
|
||||
if (this->transport->sco_io)
|
||||
spa_bt_sco_io_set_source_cb(this->transport->sco_io, NULL, NULL);
|
||||
|
||||
|
|
@ -1661,8 +1668,11 @@ static void update_target_latency(struct impl *this)
|
|||
/* BAP Client. Should use same buffer size for all streams in the same
|
||||
* group, so that capture is in sync.
|
||||
*/
|
||||
if (this->transport->iso_io)
|
||||
spa_bt_iso_io_update_source_latency(this->transport->iso_io);
|
||||
if (this->transport->iso_io) {
|
||||
int32_t target = spa_bt_iso_io_get_source_target_latency(this->transport->iso_io);
|
||||
|
||||
spa_bt_decode_buffer_set_target_latency(&port->buffer, target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1777,6 +1787,9 @@ static void process_buffering(struct impl *this)
|
|||
spa_list_append(&port->ready, &buffer->link);
|
||||
}
|
||||
|
||||
if (this->transport->iso_io && this->position)
|
||||
spa_bt_iso_io_check_rx_sync(this->transport->iso_io, this->position->clock.position);
|
||||
|
||||
if (this->update_delay_event) {
|
||||
int32_t target = spa_bt_decode_buffer_get_target_latency(&port->buffer);
|
||||
uint32_t decoder_delay = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue