Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable dbus delay signals for internal processing delay. #734

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client delay support landed in master (if you are using BlueALSA as a speaker system for watching videos, maybe you can test it as well; I've tested it to some extend and it seems to work quite nice with BlueALSA<->BlueALSA setup, but I wonder how it will work with smartphones or other devices, unfortunately my Android does not support delay reporting... :/), so here instead of ba_transport_pcm_update_processing_delay I would use

t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_delay_sync(t_pcm, BA_DBUS_PCM_UPDATE_DELAY);

so in case of decoder thread, the remote Bluetooth device will be notified (if it supports delay reporting). And of course move threshold logic to ba_transport_pcm_delay_sync(). I hope that it will work that way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rebuilt bluez and bluez-alsa on my test pi zero w, both from their master branches, and am testing with bluez-alsa master on my laptop with firefox, and the audio sync is really excellent - no bluealsa delay adjustment applied on either device.

I will build bluez-alsa again from this branch and try again, probably at the weekend, although I think this branch is only useful when the sink does not support delay reporting, because otherwise Delay change signals from the sink will cause the source client to pick up the internal processing delay anyway.


/* If the input buffer was not consumed, we have to append new data to
* the existing one. Since we do not use ring buffer, we will simply
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-aptx-hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ void *a2dp_aptx_hd_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp.ts_pcm_frames += pcm_frames;

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-aptx.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void *a2dp_aptx_enc_thread(struct ba_transport_pcm *t_pcm) {
asrsync_sync(&io.asrs, pcm_samples / channels);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-faststream.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void *a2dp_fs_enc_thread(struct ba_transport_pcm *t_pcm) {
asrsync_sync(&io.asrs, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-lc3plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-ldac.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

}

Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-mpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to frame alignment), we
* have to append new data to the existing one. Since we do not use
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-opus.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void *a2dp_opus_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, opus_frame_pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to encoder frame
* constraint), we have to append new data to the existing one.
Expand Down
2 changes: 1 addition & 1 deletion src/a2dp-sbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void *a2dp_sbc_enc_thread(struct ba_transport_pcm *t_pcm) {
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
Expand Down
16 changes: 16 additions & 0 deletions src/ba-transport-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,22 @@ int ba_transport_pcm_get_hardware_volume(
return 0;
}

void ba_transport_pcm_update_processing_delay(struct ba_transport_pcm *pcm, unsigned int delay) {
if (delay == pcm->processing_delay_dms)
return;
unsigned int diff = delay > pcm->reported_processing_delay_dms ?
delay - pcm->reported_processing_delay_dms :
pcm->reported_processing_delay_dms - delay;
pcm->processing_delay_dms = delay;

/* To avoid creating a flood of dbus signals, we only notify clients when
* the value changes by more than 10ms */
if (diff > 100 || pcm->reported_processing_delay_dms == 0) {
pcm->reported_processing_delay_dms = delay;
bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_DELAY);
}
}

int ba_transport_pcm_get_delay(const struct ba_transport_pcm *pcm) {

const struct ba_transport *t = pcm->t;
Expand Down
5 changes: 5 additions & 0 deletions src/ba-transport-pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct ba_transport_pcm {
* the host computational power. It is used to compensate for the time
* required to encode or decode audio. */
unsigned int processing_delay_dms;
unsigned int reported_processing_delay_dms;
/* Positive (or negative) delay reported by the client. */
int client_delay_dms;

Expand Down Expand Up @@ -253,6 +254,10 @@ int ba_transport_pcm_volume_update(
int ba_transport_pcm_get_hardware_volume(
const struct ba_transport_pcm *pcm);

void ba_transport_pcm_update_processing_delay(
struct ba_transport_pcm *pcm,
unsigned int delay);

int ba_transport_pcm_get_delay(
const struct ba_transport_pcm *pcm);

Expand Down
4 changes: 4 additions & 0 deletions src/bluealsa-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ static void bluealsa_pcm_open(GDBusMethodInvocation *inv, void *userdata) {
goto fail;
}

/* It the transport thread has updated its codec_delay value during its
* start procedure then we inform clients that the delay has changed */
if (pcm->codec_delay_dms > 0)
bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_DELAY);
}

pthread_mutex_lock(&pcm->mutex);
Expand Down
2 changes: 1 addition & 1 deletion src/sco-cvsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void *sco_cvsd_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, mtu_samples);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

}

Expand Down
2 changes: 1 addition & 1 deletion src/sco-lc3-swb.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void *sco_lc3_swb_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, codec.frames * LC3_SWB_CODESAMPLES);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* Move unprocessed data to the front of our linear
* buffer and clear the LC3-SWB frame counter. */
Expand Down
2 changes: 1 addition & 1 deletion src/sco-msbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void *sco_msbc_enc_thread(struct ba_transport_pcm *t_pcm) {
/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, msbc.frames * MSBC_CODESAMPLES);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
ba_transport_pcm_update_processing_delay(t_pcm, asrsync_get_busy_usec(&io.asrs) / 100);

/* Move unprocessed data to the front of our linear
* buffer and clear the mSBC frame counter. */
Expand Down
2 changes: 2 additions & 0 deletions test/test-a2dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ int ba_transport_pcm_state_set(struct ba_transport_pcm *pcm,
enum ba_transport_pcm_signal ba_transport_pcm_signal_recv(struct ba_transport_pcm *pcm) {
(void)pcm; return -1; }
void ba_transport_pcm_thread_cleanup(struct ba_transport_pcm *pcm) { (void)pcm; }
void ba_transport_pcm_update_processing_delay(struct ba_transport_pcm *pcm, unsigned int delay) {
(void)pcm; (void)delay;}

CK_START_TEST(test_a2dp_codecs_codec_id_from_string) {
ck_assert_uint_eq(a2dp_codecs_codec_id_from_string("SBC"), A2DP_CODEC_SBC);
Expand Down
Loading