[pulseaudio-discuss] Bluetooth aptX codec
Luiz Augusto von Dentz
luiz.dentz at gmail.com
Sun Jul 8 19:51:38 UTC 2018
On Sat, Jul 7, 2018 at 9:44 PM, Pali Rohár <pali.rohar at gmail.com> wrote:
> On Sunday 08 July 2018 01:44:39 Alexander E. Patrakov wrote:
>> сб, 7 июл. 2018 г. в 19:08, Pali Rohár <pali.rohar at gmail.com>:
>> > On Saturday 07 July 2018 09:39:53 Arun Raghavan wrote:
>> > > > This is a good idea to let external service to do codec-specific
>> > > > functions... I agree that it simplify pulseaudio code and other things
>> > > > (like proving new codec by external library -- if properly implemented),
>> > > > but in bluetooth context we should look at questions:
>> > > >
>> > > > 1) Has gstreamer support for SBC codec?
>> > > >
>> > > > 2) Has gstreamer support for aptX codec?
>> > > >
>> > > > These are two major codecs supported by bluetooth headsets.
>> > > >
>> > > > Answer is: NO
>> > > > (SBC is now provided in the "bad" set which is not pre-installed by
>> > > > gstreamer)
>> > >
>> > > Pre-installed doesn't mean much tbh. It is easy enough for packages to depend on it.
>> > Can pulseaudio build process enforce it?
>> > > > So gstreamer in current state is not very useful for pulseaudio.
>> > >
>> > > Writing a plugin around an existing decoder is pretty trivial. As is exposing libav/ffmpeg codecs.
>> > >
>> > > > Important are also MPEG1/2 (which are defined as optional by A2DP)
>> > > > and also AAC and LDAC which Jan wrote. But gstreamer has again only
>> > > > plugins in "bad" and "ugly" sets for them; nothing preinstalled by
>> > > > default.
>> > >
>> > > Again, -bad doesn't mean much in the current day (historically it was a staging ground). -ugly is for codecs that are known to be patent-encumbered (and how that's made available is up to packagers).
>> > Still more distributions does not compile ffmpeg with all codecs due to
>> > patents problems.
>> > So there is a high chance that we end up in situation that pulseaudio
>> > would not be able to encode audio into codec X (even pulseaudio declare
>> > that it support) and user would not be able to do nothing as his
>> > distribution does not enabled codec X at compile time. It could be
>> > really a legal problem or problem because packager forgot to enable it
>> > or because he think that it could be a problem and rather disabled it.
>> > The only option to prevent such situation is compile time check. Like
>> > now pulseaudio does not compile bluetooth support when sbc codec is not
>> > available. And this check should be there even after moving to
>> > ffmpeg/gstreamer/whatever. So is this check possible to write in
>> > autoconf for that ffmpeg/gstreamer/whatever?
>> I disagree here. Speaking here as an author of a patented codec (DTS)
>> implementation that is well supported by PulseAudio ;)
> But this is something different. DTS is not mandatory and devices in
> more cases can work without it (via PCM). But in bluetooth is SBC codec
> mandatory and must be always supported. And there are no license
> problems with SBC for A2DP bluetooth.
>> I was able to circumvent this kind of legal and technical issues by
>> providing a DTS encoder library (https://gitlab.com/patrakov/dcaenc)
>> and an ALSA plugin. The library implements stuff that is patented in
>> USA and thus cannot be included in USA-patent-free distributions.
>> However, the library is small and self-contained (not part of ffmpeg),
>> and users who don't care about patents can compile it anytime, and
>> they don't even have to replace any distribution-provided file by
>> installing this library. PulseAudio includes some profiles that
>> reference ALSA PCMs that are covered by the ALSA plugin that comes
>> with the library. No compile-time check needed - all the probing of
>> the form "can I open this PCM" is done at runtime in a generic way
>> that is not patched out by USA-patent-free distributions. Even the use
>> case when a product manufacturer has a DTS patent license which
>> instructs them to use a specific DTS implementation other than mine is
>> covered: that manufacturer can wrap that implementation in an ALSA
>> plugin that provides the same PCM names as mine, and PulseAudio will
>> still pick that up.
>> All of that is possible because there is a not-so-horrible extension
>> point in ALSA library that allows to write software that takes PCM
>> data in and delivers it to strange devices (like a DTS receiver on an
>> optical SPDIF link). What we need here is to find a proper equivalent
>> of this extension point in the Bluetooth land (e.g. take PCM in,
>> produce ready-to-send packets with all the needed metadata). If it
>> doesn't exist, create it and use it.
>> I fully understand the following technical difficulties:
>> 1. It is unwise to use ffmpeg because it can be compiled improperly
>> and is difficult to replace in this case.
> Yes, this is the main problem which I'm pointing. Also I do not know if
> ffmpeg has support for (mandatory) SBC codec...
> Now you can either: 1) compile pulseaudio with bluetooth support and
> bluetooth will work always (because it links to system sbc codec
> library) or 2) compile pulseaudio without bluetooth support (and it
> would not work). And for 1) dynamic linking ensure that needed codec
> (sbc) is present/installed as primary dependency.
>> 2. GStreamer can, in theory, wrap the needed libraries, and does
>> support third-party plugins, but does not properly encapsulate the
>> "give me packets ready to send via bluez" part.
> And until this is supported by external library (ffmpeg, gstreamer,
> whatever), pulseaudio needs to implement it itself.
> And encapsulating encoded data for bluez is not enough. It is needed
> also to negotiate codec selection with bluez and codec parameters (which
> are codec specific).
> In previous email I wrote about idea to move that codec stuff into bluez
> itself as bluez code already handles it for android.
We are not going to do a pulseaudio module in BlueZ, if it is even
possible to have off the tree modules, in android we did that because
it is the only option we had and Im quite sure it probably needs
updating since code must have change since then... Any architecture
that would involve copying data over would be bad for latency, though
android does that, and Im pretty sure doing encoding/decoding on
daemon would be rejected as well.
The D-Bus interface already accounts to the parameter negotiation,
obviously frameworks such as ffmeg or gstreamer would not do it for
use but the module could take up the action to register the endpoint
and respond to the method calls when necessary. Anyway, lets start
with modularization of the endpoints/codecs, that way we can add
native codec support or gstreamer/ffmpeg and each platform decides
with what they want to go.
Btw, I guess you were on irc looking for how we prioritize the
matching of endpoints, this is done in the order of endpoint
>> > > > To have working bluetooth support in pulseadio, pulseaudio needs to use
>> > > > external library for encoding which *always* provides support for SBC.
>> > > > And not only if user manually installs some special plugin for 3rd party
>> > > > library. (And not only SBC, but also those other aptX, MPEG1/2, AAC and
>> > > > LDAC codecs)
>> > >
>> > > So I continue to disagree. Using a generic framework and letting other parts of the system select the codec implementation is what makes sense for the widest set of use-cases (this also allows products to ship their own implementations of a codec without changing the PulseAudio code).
>> > Still this is not enough for bluetooth codec. For specific codec you
>> > need to create bluez dbus endpoint with codec specific parameters. Plus
>> > implement select and set methods to decide on codec parameters between
>> > pulseaudio and bluetooth headset. And finally to send encoded data you
>> > need to know how to send them. To which endpoint, how header looks like
>> > etc... Some codecs needs to wrap data into RTP (e.g. SBC), some must not
>> > have RTP (e.g. aptX). And after that comes data from codec encoder
>> > function.
>> > So is there any library which all above support? I have not find
>> > anything. Nor ffmpeg nor gstreamer.
>> > Which means that pulseaudio cannot delegate codec selection, codec
>> > initialization and codec encoding to some external library (yet).
>> > Anyway, now in bluez source code is some kind of codec encoding support
>> > for android systems. Therefore should not be a wise idea to move all
>> > these codec A2DP mess into bluez source code? Because now part of A2DP
>> > is in bluez and another part in pulseaudio. And on android is everything
>> > in bluez now.
Luiz Augusto von Dentz
More information about the pulseaudio-discuss