Skip to content

Commit

Permalink
Filter internal delay D-Bus signals
Browse files Browse the repository at this point in the history
Only emit D-Bus delay signal for internal processing delays if the
change is >= 10ms
  • Loading branch information
borine committed Dec 23, 2024
1 parent 25a412d commit 8710c39
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 23 deletions.
69 changes: 46 additions & 23 deletions src/ba-transport-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,35 +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 dbus signals, we only notify clients
* when the codec + processing value changes by more than 10ms */
unsigned int delay = pcm->codec_delay_dms + pcm->processing_delay_dms;
unsigned int diff = delay >= pcm->reported_codec_delay_dms ?
delay - pcm->reported_codec_delay_dms :
pcm->reported_codec_delay_dms - delay;
if (diff >= 100 /* 10ms */)
pcm->reported_codec_delay_dms = delay;
else
return 0;
}
}

/* Notify all connected D-Bus clients. */
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

0 comments on commit 8710c39

Please sign in to comment.