mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
bluez5: media-sink: Refine ASHA other-side timer setup further
Let's just directly use the next timer value from the other side directly, and the reference time as well to calculate the expected next sample position we want to send from on this side.
This commit is contained in:
parent
c5b5476aa4
commit
ce8abfc5cc
1 changed files with 29 additions and 16 deletions
|
|
@ -116,7 +116,6 @@ struct spa_bt_asha {
|
|||
uint8_t seqnum_pending;
|
||||
|
||||
uint64_t ref_t0;
|
||||
uint64_t ref_timer;
|
||||
uint64_t skip_frames;
|
||||
|
||||
uint64_t prev_time;
|
||||
|
|
@ -220,6 +219,8 @@ struct impl {
|
|||
|
||||
static struct spa_list asha_sinks;
|
||||
|
||||
static uint64_t get_reference_time(struct impl *this, uint64_t *duration_ns_ret);
|
||||
|
||||
static struct impl *find_other_asha(struct impl *this)
|
||||
{
|
||||
struct impl *other;
|
||||
|
|
@ -357,26 +358,38 @@ static int set_asha_timeout(struct impl *this, uint64_t time)
|
|||
this->asha->timerfd, SPA_FD_TIMER_ABSTIME, &ts, NULL);
|
||||
}
|
||||
|
||||
static int set_asha_timer(struct impl *this, bool snap)
|
||||
static int set_asha_timer(struct impl *this, struct impl *other)
|
||||
{
|
||||
struct timespec now;
|
||||
uint64_t now_ns, offset = 0;
|
||||
uint64_t time;
|
||||
|
||||
spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &now);
|
||||
now_ns = SPA_TIMESPEC_TO_NSEC(&now);
|
||||
if (other) {
|
||||
/* Try to line up our timer with the other side, and drop samples so we're sending
|
||||
* the same sample position on both sides */
|
||||
uint64_t other_samples = (get_reference_time(other, NULL) - other->asha->ref_t0) *
|
||||
this->port.current_format.info.raw.rate / SPA_NSEC_PER_SEC;
|
||||
|
||||
if (snap) {
|
||||
/* If requested, snap our wakeup time to a 20ms interval */
|
||||
offset = (now_ns - this->asha->ref_timer) % ASHA_CONN_INTERVAL;
|
||||
this->asha->skip_frames = offset * this->port.current_format.info.raw.rate / SPA_NSEC_PER_SEC;
|
||||
spa_log_debug(this->log, "will skip %"PRIu64 " frames", this->asha->skip_frames);
|
||||
if (other->asha->next_time < this->process_time) {
|
||||
/* Other side has not yet been scheduled in this graph cycle, we expect
|
||||
* there might be one packet left from the previous cycle at most */
|
||||
time = other->asha->next_time + ASHA_CONN_INTERVAL;
|
||||
other_samples += ASHA_CONN_INTERVAL *
|
||||
this->port.current_format.info.raw.rate / SPA_NSEC_PER_SEC;
|
||||
} else {
|
||||
/* Other side has set up its next cycle, catch up */
|
||||
time = other->asha->next_time;
|
||||
}
|
||||
|
||||
/* Since the quantum and packet size aren't correlated, drop any samples from this
|
||||
* cycle that might have been used to send a packet starting in the previous cycle */
|
||||
this->asha->skip_frames = other_samples % this->process_duration;
|
||||
} else {
|
||||
/* Else, remember when we started this timer so the other side can use it */
|
||||
this->asha->ref_timer = now_ns;
|
||||
time = this->process_time;
|
||||
this->asha->skip_frames = 0;
|
||||
}
|
||||
|
||||
this->asha->prev_time = this->asha->next_time = now_ns + offset;
|
||||
spa_log_debug(this->log, "will skip %"PRIu64 " frames", this->asha->skip_frames);
|
||||
|
||||
this->asha->next_time = time;
|
||||
|
||||
return set_asha_timeout(this, this->asha->next_time);
|
||||
}
|
||||
|
|
@ -2274,11 +2287,11 @@ static int impl_node_process(void *object)
|
|||
this->asha->ref_t0 = other->asha->ref_t0;
|
||||
this->seqnum = asha_seqnum(this);
|
||||
reset_buffer(this);
|
||||
set_asha_timer(this, true);
|
||||
set_asha_timer(this, other);
|
||||
} else {
|
||||
this->asha->ref_t0 = get_reference_time(this, NULL);
|
||||
this->seqnum = 0;
|
||||
set_asha_timer(this, false);
|
||||
set_asha_timer(this, NULL);
|
||||
}
|
||||
|
||||
this->asha->set_timer = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue