From 8710c3946256900f1873922873599a9594895508 Mon Sep 17 00:00:00 2001 From: borine <32966433+borine@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:20:59 +0000 Subject: [PATCH] Filter internal delay D-Bus signals Only emit D-Bus delay signal for internal processing delays if the change is >= 10ms --- src/ba-transport-pcm.c | 69 ++++++++++++++++++++++++++++-------------- src/ba-transport-pcm.h | 3 ++ 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/ba-transport-pcm.c b/src/ba-transport-pcm.c index d9306aa14..18c36198d 100644 --- a/src/ba-transport-pcm.c +++ b/src/ba-transport-pcm.c @@ -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. */ diff --git a/src/ba-transport-pcm.h b/src/ba-transport-pcm.h index acd1e9d85..7ff4f436c 100644 --- a/src/ba-transport-pcm.h +++ b/src/ba-transport-pcm.h @@ -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;