Hi Luiz,
On 6/8/21 1:47 AM, Luiz Augusto von Dentz wrote:
Hi Marijn,
[..]
We've been running into a similar issue with PulseAudio. There is no
way to track a Set call for the Volume property back to the
property-change notification, running into both jitter on quick
successive volume changes and the inability to reflect peer hardware
volume in case the peer rounds the requested volume to a coarser scale.
This rounded value is supposedly returned from SetAbsoluteVolume
according to AVRCP spec 1.6.2, section 6.13.2:
The volume level which has actually been set on the TG is returned in
the response.
I would have proposed a new DBUS function SetAbsoluteVolume that accepts
volume as sole argument, blocks until the peer replies, and returns the
actual volume as per its namesake AVRCP command. This should address
both issues.
Note that it is also impossible to distinguish Volume property changes
from an action invoked on the peer (ie. the user pressing physical
buttons or using a volume slider on headphones) or the result of an
earlier Set(Volume) call as these to my knowledge all happen async, may
be intertwined, may involve rounding (on the peer) to make the resulting
number different, etc.
Yep, the volume may actually be rounded like you said, so Im not
really sure how we can queue because we will not be able to verify the
volume has been set properly, we could do a blocking call even in case
of setting as a property we only need to delay the call to
g_dbus_pending_property_success until we actually receive a response,
that said there maybe some impact on the user experience since if you
have the volume implemented with something like a slider it will not
move smoothly anymore, but I guess that is better than have it
flipping back and forth, well except that can still happens because
the volume can be changed on the device in the meantime but I guess
the client wont see those changes until the method returns if it is
blocking waiting for the reply, which means it will only see that the
value flipped to something else later when the signals are dispatched.
The main use-case is software volume compensation for devices with
limited granularity, for which we need to know exactly what is replied
to AVRCP's SetAbsoluteVolume call. Delaying
g_dbus_pending_property_success will only block the call longer but
won't exactly let us know the resulting value. We can immediately Get
the new property after (or try and relate the change notification to
it), but there's nothing preventing a change on the device intervening.
In that case we should discard requested volume (on the host) and
software compensation, and take/display device volume as-is.
This seems unfortunate as the AVRCP spec provides exactly the
consistency we're looking for here.
As for user experience it seems acceptable to make such a call block
until the peer replies, if only for a much more predictable API. It is
then up to the caller (ie. PulseAudio) to deal with that by
disabling/blocking the slider, or scheduling the most recent volume
update to be sent as soon as a reply is received (the DBus call returns).
If you feel like that is acceptable I'm happy to review any patches in
that direction.
[..]
--
Luiz Augusto von Dentz
- Marijn