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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 doc/a2dpconf.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ OPTIONS
Print version and exit.

-v, --verbose
Sow verbose bit-stream details.
Show verbose bit-stream details.
Display each field as a binary mask with each bit represented by a single
character.

Expand Down
2 changes: 2 additions & 0 deletions src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "utils.h"
Expand Down Expand Up @@ -397,6 +398,7 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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: 2 additions & 0 deletions src/a2dp-aptx-hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "codec-aptx.h"
#include "io.h"
#include "rtp.h"
Expand Down Expand Up @@ -213,6 +214,7 @@ void *a2dp_aptx_hd_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 2 additions & 0 deletions src/a2dp-aptx.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "codec-aptx.h"
#include "io.h"
#include "shared/a2dp-codecs.h"
Expand Down Expand Up @@ -194,6 +195,7 @@ void *a2dp_aptx_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
2 changes: 2 additions & 0 deletions src/a2dp-faststream.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "codec-sbc.h"
#include "io.h"
#include "shared/a2dp-codecs.h"
Expand Down Expand Up @@ -221,6 +222,7 @@ void *a2dp_fs_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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: 2 additions & 0 deletions src/a2dp-lc3plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "utils.h"
Expand Down Expand Up @@ -377,6 +378,7 @@ void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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: 2 additions & 0 deletions src/a2dp-ldac.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "ba-config.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "utils.h"
Expand Down Expand Up @@ -263,6 +264,7 @@ void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm) {

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

}

Expand Down
2 changes: 2 additions & 0 deletions src/a2dp-lhdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "ba-config.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "utils.h"
Expand Down Expand Up @@ -294,6 +295,7 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {

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

}

Expand Down
2 changes: 2 additions & 0 deletions src/a2dp-mpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "utils.h"
Expand Down Expand Up @@ -316,6 +317,7 @@ void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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: 2 additions & 0 deletions src/a2dp-opus.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "ba-config.h"
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "rtp.h"
#include "shared/a2dp-codecs.h"
Expand Down Expand Up @@ -237,6 +238,7 @@ void *a2dp_opus_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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: 2 additions & 0 deletions src/a2dp-sbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "ba-config.h"
#include "bluealsa-dbus.h"
#include "codec-sbc.h"
#include "io.h"
#include "rtp.h"
Expand Down Expand Up @@ -266,6 +267,7 @@ void *a2dp_sbc_enc_thread(struct ba_transport_pcm *t_pcm) {

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

/* 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
65 changes: 42 additions & 23 deletions src/ba-transport-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,39 +750,58 @@ int ba_transport_pcm_delay_get(const struct ba_transport_pcm *pcm) {
int ba_transport_pcm_delay_sync(struct ba_transport_pcm *pcm, unsigned int update_mask) {

struct ba_transport *t = pcm->t;
int delay = 0;

delay += pcm->codec_delay_dms;
delay += pcm->processing_delay_dms;
delay += pcm->client_delay_dms;

/* In case of A2DP Sink, update the delay property of the BlueZ media
* transport interface. BlueZ should forward this value to the remote
* device, so it can adjust audio/video synchronization. */
if (t->profile == BA_TRANSPORT_PROFILE_A2DP_SINK &&
t->a2dp.delay_reporting &&
abs(delay - t->a2dp.delay) >= 100 /* 10ms */) {

GError *err = NULL;
t->a2dp.delay = delay;
g_dbus_set_property(config.dbus, t->bluez_dbus_owner, t->bluez_dbus_path,
BLUEZ_IFACE_MEDIA_TRANSPORT, "Delay", g_variant_new_uint16(delay), &err);

if (err != NULL) {
if (err->code == G_DBUS_ERROR_PROPERTY_READ_ONLY)
/* Even though BlueZ documentation says that the Delay property is
* read-write, it might not be true. In case when the delay write
* operation fails with "not writable" error, we should not try to
* update the delay report value any more. */
t->a2dp.delay_reporting = false;
warn("Couldn't set A2DP transport delay: %s", err->message);
g_error_free(err);
if (t->profile == BA_TRANSPORT_PROFILE_A2DP_SINK) {

int delay = 0;
delay += pcm->codec_delay_dms;
delay += pcm->processing_delay_dms;
delay += pcm->client_delay_dms;

if (t->a2dp.delay_reporting &&
abs(delay - t->a2dp.delay) >= 100 /* 10ms */) {

GError *err = NULL;
t->a2dp.delay = delay;
g_dbus_set_property(config.dbus, t->bluez_dbus_owner, t->bluez_dbus_path,
BLUEZ_IFACE_MEDIA_TRANSPORT, "Delay", g_variant_new_uint16(delay), &err);

if (err != NULL) {
if (err->code == G_DBUS_ERROR_PROPERTY_READ_ONLY)
/* Even though BlueZ documentation says that the Delay
* property is read-write, it might not be true. In case
* when the delay write operation fails with "not writable"
* error, we should not try to update the delay report
* value any more. */
t->a2dp.delay_reporting = false;
warn("Couldn't set A2DP transport delay: %s", err->message);
g_error_free(err);
}

}
}

/* If the remote device does not provide delay update reports we can still
* inform local D-Bus clients of our internal processing delay. */
if ((t->profile & BA_TRANSPORT_PROFILE_MASK_A2DP) == 0 ||
!t->a2dp.delay_reporting) {
if (update_mask == BA_DBUS_PCM_UPDATE_DELAY) {
/* To avoid creating a flood of D-Bus signals, we only notify clients
* when the codec + processing value changes by more than 10ms. */
int delay = pcm->codec_delay_dms + pcm->processing_delay_dms;
if (abs(delay - (int)pcm->reported_codec_delay_dms) < 100 /* 10ms */)
goto final;
pcm->reported_codec_delay_dms = delay;
}
}

/* Notify all connected D-Bus clients. */
bluealsa_dbus_pcm_update(pcm, update_mask);

final:
return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions src/ba-transport-pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ 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;
/* The last reported total codec + processing delay. It is used to limit
* the rate at which changes are reported via D-Bus. */
unsigned int reported_codec_delay_dms;
/* Positive (or negative) delay reported by the client. */
int client_delay_dms;

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

/* If 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: 2 additions & 0 deletions src/sco-cvsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "io.h"
#include "shared/defs.h"
#include "shared/ffb.h"
Expand Down Expand Up @@ -80,6 +81,7 @@ void *sco_cvsd_enc_thread(struct ba_transport_pcm *t_pcm) {
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_delay_sync(t_pcm, BA_DBUS_PCM_UPDATE_DELAY);

}

Expand Down
2 changes: 2 additions & 0 deletions src/sco-lc3-swb.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "codec-lc3-swb.h"
#include "io.h"
#include "shared/defs.h"
Expand Down Expand Up @@ -86,6 +87,7 @@ void *sco_lc3_swb_enc_thread(struct ba_transport_pcm *t_pcm) {
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_delay_sync(t_pcm, BA_DBUS_PCM_UPDATE_DELAY);

/* Move unprocessed data to the front of our linear
* buffer and clear the LC3-SWB frame counter. */
Expand Down
2 changes: 2 additions & 0 deletions src/sco-msbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "ba-transport.h"
#include "ba-transport-pcm.h"
#include "bluealsa-dbus.h"
#include "codec-msbc.h"
#include "io.h"
#include "shared/defs.h"
Expand Down Expand Up @@ -93,6 +94,7 @@ void *sco_msbc_enc_thread(struct ba_transport_pcm *t_pcm) {
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_delay_sync(t_pcm, BA_DBUS_PCM_UPDATE_DELAY);

/* 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; }
int ba_transport_pcm_delay_sync(struct ba_transport_pcm *pcm, unsigned int update_mask) {
(void)pcm; (void)update_mask; return -1; }

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