[pulseaudio-discuss] [PATCH] bluetooth: Fix rendering a2dp data

Luiz Augusto von Dentz luiz.dentz at gmail.com
Thu Dec 23 06:05:49 PST 2010


Hi,

On Thu, Dec 16, 2010 at 5:36 AM, caiiiyua <yuanqing.cai at tieto.com> wrote:
>  Hi:-)
>
> On 12/15/2010 05:33 AM, Luiz Augusto von Dentz wrote:
>>
>> Hi,
>>
>> On Tue, Dec 14, 2010 at 11:10 AM, Maarten Lankhorst
>> <m.b.lankhorst at gmail.com>  wrote:
>>>
>>>  Hi Luiz,
>>>
>>> Op 13-12-10 09:55, Luiz Augusto von Dentz schreef:
>>>>
>>>> Hi,
>>>>
>>>> On Sat, Dec 11, 2010 at 1:05 AM, Maarten Lankhorst
>>>> <m.b.lankhorst at gmail.com>    wrote:
>>>>>
>>>>> makes my android phone slightly happier
>>>>> ---
>>>>>  src/modules/bluetooth/module-bluetooth-device.c |   11 ++++++++---
>>>>>  1 files changed, 8 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/src/modules/bluetooth/module-bluetooth-device.c
>>>>> b/src/modules/bluetooth/module-bluetooth-device.c
>>>>> index 6d31c1e..8664001 100644
>>>>> --- a/src/modules/bluetooth/module-bluetooth-device.c
>>>>> +++ b/src/modules/bluetooth/module-bluetooth-device.c
>>>>> @@ -1387,7 +1387,7 @@ static int a2dp_process_push(struct userdata *u)
>>>>> {
>>>>>     pa_assert(u->source);
>>>>>     pa_assert(u->read_smoother);
>>>>>
>>>>> -    memchunk.memblock = pa_memblock_new(u->core->mempool,
>>>>> u->block_size);
>>>>> +    memchunk.memblock = pa_memblock_new(u->core->mempool,
>>>>> u->block_size
>>>>> * 2);
>>>>>     memchunk.index = memchunk.length = 0;
>>>>
>>>> Im not sure how this would help, we decode sbc frame by frame so
>>>> having twice as much memory doesn't really make any sense, there could
>>>> be that we should decode the entire buffer read, but that would take
>>>> much more memory. What could be the real problem is that the source is
>>>> changing the bitpool but that shouldn't be a problem since the
>>>> block_size is supposed to be calculated from maximum bitpool range so
>>>> the buffer will always be big enough.
>>>
>>> Well it seems the block_size is not fixed on my phone, sometimes it is 1
>>> sample more, sometimes 2, the net effect is 1 or 2 frames stay undecoded
>>> leading to massive underruns.
>>>
>>> I don't think u->block_size has to be fixed per se, a2dp->code_size seems
>>> to
>>> be though.
>>
>> Again if we want to be able to support devices that changes bitpool we
>> have to recalculate the block_size on every frame (if bitpool has
>> really changed), doubling the buffer is not the right fix, sorry.
>>
>>>>>     for (;;) {
>>>>> @@ -1442,7 +1442,8 @@ static int a2dp_process_push(struct userdata *u)
>>>>> {
>>>>>         to_decode = l - sizeof(*header) - sizeof(*payload);
>>>>>
>>>>>         d = pa_memblock_acquire(memchunk.memblock);
>>>>> -        to_write = memchunk.length =
>>>>> pa_memblock_get_length(memchunk.memblock);
>>>>> +        to_write = pa_memblock_get_length(memchunk.memblock);
>>>>> +        memchunk.length = 0;
>>>>>
>>>>>         while (PA_LIKELY(to_decode>    0&&    to_write>    0)) {
>>>>>             size_t written;
>>>>> @@ -1464,7 +1465,7 @@ static int a2dp_process_push(struct userdata *u)
>>>>> {
>>>>>  /*             pa_log_debug("SBC: frame_length: %lu; codesize: %lu",
>>>>> (unsigned long) a2dp->frame_length, (unsigned long) a2dp->codesize); */
>>>>>
>>>>>             pa_assert_fp((size_t) decoded<= to_decode);
>>>>> -            pa_assert_fp((size_t) decoded == a2dp->frame_length);
>>>>> +            pa_assert_fp((size_t) decoded<= a2dp->frame_length);
>>>>
>>>> This is the real problem, either we do this if the bitpool is changing
>>>> or we have to call sbc_reinit in each frame.
>>>
>>> Well, a2dp->frame_length was calculated based on the maximum bitpool
>>> size.
>>> The frames decoded have a smaller bitpool size. a2dp->codesize is still
>>> the
>>> same though, so I don't think this change matters much.
>>
>> It was you that suggested this changes, so when you say it doesn't
>> matter it makes me wonder why this is part of the patch then, Btw,
>> changing bitpool changes the frame length and it actually does assert,
>> I tried it myself with this patch to source:
>>
>>
>> http://gitorious.org/pulseaudio/mainline/commit/9b938f8f8f40772e626b3e71fa4d7b7cbd5de5e7
>>
>  That's really good to change "bitpool" dynamically.
>  As in your patch source,I saw a function called "a2dp_reduce_bitpool",in
> some cases,we need bitpool to be increased,
>  shall we think about this situation?

Ive tried some approaches like if we are sleep for more then some msec
increase the bitpool, but it sometimes cause too many/quickly changes
and some headsets just crashes, so for now it just reduces to a limit
of 32 which is considered mid quality by a2dp spec, I couldn't notice
any difference but the audio definably stopped skipping.

>> Well what other bitpool would you use instead? If we don't have any
>> frame to parse obviously we need to start with the biggest possible
>> one, it the only possible way to avoid decode errors due to too small
>> buffer to decode.
>
> IMO,as a A2DP sink,we should get some information from source before
> decoding,thus,we can decide the size of framelen and blocksize .I am still a
> Pulseaudio newbie,so I don't complete realise how a2dp works for
> pulseaudio,could you teach me how this "blocksize" be fixed when we start to
> decode the sound.

Ive figure out what was the problem, for source we need to initialize
the bitpool to the minimum, this will generate the possible frames per
packet and thus the maximum possible block size. Off course this could
be done differently with sbc_parse but I don't think it worth doing,
it would cause to much overhead.

This 2 patches should fix the problem:

http://gitorious.org/pulseaudio/mainline/commit/e4979ab5cff84ef64c88bba3a1b6b4c5e02f7777
http://gitorious.org/pulseaudio/mainline/commit/4163b44f1fd39be030dda282417f1aa167e7cb55

@Maarten: Can you try with those 2? You can pull from here:
git://gitorious.org/pulseaudio/mainline.git

Im about to send a pull request to the list but I would like to have
at least some feedback on the last commit since I don't have an
android phone to test it.

-- 
Luiz Augusto von Dentz
Computer Engineer



More information about the pulseaudio-discuss mailing list