All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] android/hal-audio: Fix wrong memory access
@ 2014-05-22 13:07 Andrei Emeltchenko
  2014-05-22 13:54 ` Andrzej Kaczmarek
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-05-22 13:07 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
we access it as (int16_t *) we shall device index by 2.
---
 android/hal-audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 7305bb6..96fa5c3 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
 	int16_t *output = (void *) out->downmix_buf;
 	size_t i;
 
-	for (i = 0; i < bytes / 2; i++) {
+	for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
 		int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
 		int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-22 13:07 [RFC] android/hal-audio: Fix wrong memory access Andrei Emeltchenko
@ 2014-05-22 13:54 ` Andrzej Kaczmarek
  2014-05-22 14:16   ` Andrei Emeltchenko
  2014-05-22 14:21 ` Marcel Holtmann
  2014-05-26 12:39 ` Szymon Janc
  2 siblings, 1 reply; 10+ messages in thread
From: Andrzej Kaczmarek @ 2014-05-22 13:54 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On 22 May 2014 15:07, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
> we access it as (int16_t *) we shall device index by 2.
> ---
>  android/hal-audio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 7305bb6..96fa5c3 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
>         int16_t *output = (void *) out->downmix_buf;
>         size_t i;
>
> -       for (i = 0; i < bytes / 2; i++) {
> +       for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>                 int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
>                 int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));

Fix is correct, but commit message does not explain properly why this
is required. Basically we need to downmix X frames from input buffer
and this number is "bytes / (number_of_channels * sample_size)" - so
we were missing "sample_size" here. I think adding inline comment to
explain this would be also good.

BR,
Andrzej

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-22 13:54 ` Andrzej Kaczmarek
@ 2014-05-22 14:16   ` Andrei Emeltchenko
  0 siblings, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-05-22 14:16 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth

Hi Andrzej,

On Thu, May 22, 2014 at 03:54:34PM +0200, Andrzej Kaczmarek wrote:
> Hi Andrei,
> 
> On 22 May 2014 15:07, Andrei Emeltchenko
> <Andrei.Emeltchenko.news@gmail.com> wrote:
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
> > we access it as (int16_t *) we shall device index by 2.
> > ---
> >  android/hal-audio.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/android/hal-audio.c b/android/hal-audio.c
> > index 7305bb6..96fa5c3 100644
> > --- a/android/hal-audio.c
> > +++ b/android/hal-audio.c
> > @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
> >         int16_t *output = (void *) out->downmix_buf;
> >         size_t i;
> >
> > -       for (i = 0; i < bytes / 2; i++) {
> > +       for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
> >                 int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
> >                 int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
> 
> Fix is correct, but commit message does not explain properly why this
> is required. Basically we need to downmix X frames from input buffer
> and this number is "bytes / (number_of_channels * sample_size)" - so
> we were missing "sample_size" here. I think adding inline comment to
> explain this would be also good.

I my code I use frame_num instead of bytes.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-22 13:07 [RFC] android/hal-audio: Fix wrong memory access Andrei Emeltchenko
  2014-05-22 13:54 ` Andrzej Kaczmarek
@ 2014-05-22 14:21 ` Marcel Holtmann
  2014-05-26 12:36   ` Andrzej Kaczmarek
  2014-05-26 12:39 ` Szymon Janc
  2 siblings, 1 reply; 10+ messages in thread
From: Marcel Holtmann @ 2014-05-22 14:21 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
> we access it as (int16_t *) we shall device index by 2.
> ---
> android/hal-audio.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 7305bb6..96fa5c3 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
> 	int16_t *output = (void *) out->downmix_buf;
> 	size_t i;
> 
> -	for (i = 0; i < bytes / 2; i++) {
> +	for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
> 		int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
> 		int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));

I wonder actually what this get_unaligned is doing here? You cast the const void into const int16_t buffer. Is this really needed? Where is our input and output buffer coming from? Aren’t these aligned anyway? Meaning aren’t they allocated?

I also wonder why we are not doing the unaligned access directly on the void buffer and do proper offset calculation into the stream. Instead of casting it to an int16 array.

Regards

Marcel


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-22 14:21 ` Marcel Holtmann
@ 2014-05-26 12:36   ` Andrzej Kaczmarek
  2014-05-26 12:48     ` Marcel Holtmann
  0 siblings, 1 reply; 10+ messages in thread
From: Andrzej Kaczmarek @ 2014-05-26 12:36 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Andrei Emeltchenko, linux-bluetooth

Hi Marcel,

On 22 May 2014 16:21, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Andrei,
>
>> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
>> we access it as (int16_t *) we shall device index by 2.
>> ---
>> android/hal-audio.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/android/hal-audio.c b/android/hal-audio.c
>> index 7305bb6..96fa5c3 100644
>> --- a/android/hal-audio.c
>> +++ b/android/hal-audio.c
>> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *=
out, const uint8_t *buffer,
>>       int16_t *output =3D (void *) out->downmix_buf;
>>       size_t i;
>>
>> -     for (i =3D 0; i < bytes / 2; i++) {
>> +     for (i =3D 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>>               int16_t l =3D le16_to_cpu(get_unaligned(&input[i * 2]));
>>               int16_t r =3D le16_to_cpu(get_unaligned(&input[i * 2 + 1])=
);
>
> I wonder actually what this get_unaligned is doing here? You cast the con=
st void into const int16_t buffer. Is this really needed? Where is our inpu=
t and output buffer coming from? Aren=E2=80=99t these aligned anyway? Meani=
ng aren=E2=80=99t they allocated?

We have this buffer from AudioFlinger so we don't actually know
alignment or if this is pointer to beginning of some internal buffer
(it's most probably both, but I don't think we should assume this).

> I also wonder why we are not doing the unaligned access directly on the v=
oid buffer and do proper offset calculation into the stream. Instead of cas=
ting it to an int16 array.

Only to have buffer indexed by samples rather than by bytes.

BR,
Andrzej

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-22 13:07 [RFC] android/hal-audio: Fix wrong memory access Andrei Emeltchenko
  2014-05-22 13:54 ` Andrzej Kaczmarek
  2014-05-22 14:21 ` Marcel Holtmann
@ 2014-05-26 12:39 ` Szymon Janc
  2 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-05-26 12:39 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Thursday 22 of May 2014 16:07:02 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
> we access it as (int16_t *) we shall device index by 2.
> ---
>  android/hal-audio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 7305bb6..96fa5c3 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
>  	int16_t *output = (void *) out->downmix_buf;
>  	size_t i;
>  
> -	for (i = 0; i < bytes / 2; i++) {
> +	for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>  		int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
>  		int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
>  

Although RFC I've applied this patch but modified commit message and added
a local 'frames' variable with comment where this calculation comes from.
Thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-26 12:36   ` Andrzej Kaczmarek
@ 2014-05-26 12:48     ` Marcel Holtmann
  2014-05-26 12:59       ` Andrzej Kaczmarek
  0 siblings, 1 reply; 10+ messages in thread
From: Marcel Holtmann @ 2014-05-26 12:48 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: Andrei Emeltchenko, linux-bluetooth

Hi Andrzej,

>>> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
>>> we access it as (int16_t *) we shall device index by 2.
>>> ---
>>> android/hal-audio.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>> 
>>> diff --git a/android/hal-audio.c b/android/hal-audio.c
>>> index 7305bb6..96fa5c3 100644
>>> --- a/android/hal-audio.c
>>> +++ b/android/hal-audio.c
>>> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
>>>      int16_t *output = (void *) out->downmix_buf;
>>>      size_t i;
>>> 
>>> -     for (i = 0; i < bytes / 2; i++) {
>>> +     for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>>>              int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
>>>              int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
>> 
>> I wonder actually what this get_unaligned is doing here? You cast the const void into const int16_t buffer. Is this really needed? Where is our input and output buffer coming from? Aren’t these aligned anyway? Meaning aren’t they allocated?
> 
> We have this buffer from AudioFlinger so we don't actually know
> alignment or if this is pointer to beginning of some internal buffer
> (it's most probably both, but I don't think we should assume this).

and audio system that does not give you a guarantee here on the alignment is utterly screwed up. Seriously, that is just bad for performance. Especially bad on ARM CPUs, so I doubt that they have not thought about this.

Regards

Marcel


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-26 12:48     ` Marcel Holtmann
@ 2014-05-26 12:59       ` Andrzej Kaczmarek
  2014-05-26 13:14         ` Marcel Holtmann
  2014-05-27  7:54         ` Andrei Emeltchenko
  0 siblings, 2 replies; 10+ messages in thread
From: Andrzej Kaczmarek @ 2014-05-26 12:59 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Andrei Emeltchenko, linux-bluetooth

Hi Marcel,

On 26 May 2014 14:48, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Andrzej,
>
>>>> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, wh=
en
>>>> we access it as (int16_t *) we shall device index by 2.
>>>> ---
>>>> android/hal-audio.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/android/hal-audio.c b/android/hal-audio.c
>>>> index 7305bb6..96fa5c3 100644
>>>> --- a/android/hal-audio.c
>>>> +++ b/android/hal-audio.c
>>>> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out=
 *out, const uint8_t *buffer,
>>>>      int16_t *output =3D (void *) out->downmix_buf;
>>>>      size_t i;
>>>>
>>>> -     for (i =3D 0; i < bytes / 2; i++) {
>>>> +     for (i =3D 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>>>>              int16_t l =3D le16_to_cpu(get_unaligned(&input[i * 2]));
>>>>              int16_t r =3D le16_to_cpu(get_unaligned(&input[i * 2 + 1]=
));
>>>
>>> I wonder actually what this get_unaligned is doing here? You cast the c=
onst void into const int16_t buffer. Is this really needed? Where is our in=
put and output buffer coming from? Aren=E2=80=99t these aligned anyway? Mea=
ning aren=E2=80=99t they allocated?
>>
>> We have this buffer from AudioFlinger so we don't actually know
>> alignment or if this is pointer to beginning of some internal buffer
>> (it's most probably both, but I don't think we should assume this).
>
> and audio system that does not give you a guarantee here on the alignment=
 is utterly screwed up. Seriously, that is just bad for performance. Especi=
ally bad on ARM CPUs, so I doubt that they have not thought about this.

This is only to be on safe side and in terms of performance it does
not really matter here since this code won't probably be used at all -
who has mono A2DP headset nowadays? But of course we can change this
with proper comment. Actually I use it like this in aptX where samples
are accessed from the same buffer.

BR,
Andrzej

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-26 12:59       ` Andrzej Kaczmarek
@ 2014-05-26 13:14         ` Marcel Holtmann
  2014-05-27  7:54         ` Andrei Emeltchenko
  1 sibling, 0 replies; 10+ messages in thread
From: Marcel Holtmann @ 2014-05-26 13:14 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: Andrei Emeltchenko, linux-bluetooth

Hi Andrzej,

>>>>> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
>>>>> we access it as (int16_t *) we shall device index by 2.
>>>>> ---
>>>>> android/hal-audio.c | 2 +-
>>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>> 
>>>>> diff --git a/android/hal-audio.c b/android/hal-audio.c
>>>>> index 7305bb6..96fa5c3 100644
>>>>> --- a/android/hal-audio.c
>>>>> +++ b/android/hal-audio.c
>>>>> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
>>>>>     int16_t *output = (void *) out->downmix_buf;
>>>>>     size_t i;
>>>>> 
>>>>> -     for (i = 0; i < bytes / 2; i++) {
>>>>> +     for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
>>>>>             int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
>>>>>             int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
>>>> 
>>>> I wonder actually what this get_unaligned is doing here? You cast the const void into const int16_t buffer. Is this really needed? Where is our input and output buffer coming from? Aren’t these aligned anyway? Meaning aren’t they allocated?
>>> 
>>> We have this buffer from AudioFlinger so we don't actually know
>>> alignment or if this is pointer to beginning of some internal buffer
>>> (it's most probably both, but I don't think we should assume this).
>> 
>> and audio system that does not give you a guarantee here on the alignment is utterly screwed up. Seriously, that is just bad for performance. Especially bad on ARM CPUs, so I doubt that they have not thought about this.
> 
> This is only to be on safe side and in terms of performance it does
> not really matter here since this code won't probably be used at all -
> who has mono A2DP headset nowadays? But of course we can change this
> with proper comment. Actually I use it like this in aptX where samples
> are accessed from the same buffer.

I have no idea what that means. The important part is that the buffer itself is aligned. With binary codecs like aptX this is even more important since we have no idea if aptX does the unaligned access or not.

Regards

Marcel


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC] android/hal-audio: Fix wrong memory access
  2014-05-26 12:59       ` Andrzej Kaczmarek
  2014-05-26 13:14         ` Marcel Holtmann
@ 2014-05-27  7:54         ` Andrei Emeltchenko
  1 sibling, 0 replies; 10+ messages in thread
From: Andrei Emeltchenko @ 2014-05-27  7:54 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: Marcel Holtmann, linux-bluetooth

On Mon, May 26, 2014 at 02:59:31PM +0200, Andrzej Kaczmarek wrote:
> Hi Marcel,
> 
> On 26 May 2014 14:48, Marcel Holtmann <marcel@holtmann.org> wrote:
> > Hi Andrzej,
> >
> >>>> downmix_buf is allocated to have buffer size FIXED_BUFFER_SIZE / 2, when
> >>>> we access it as (int16_t *) we shall device index by 2.
> >>>> ---
> >>>> android/hal-audio.c | 2 +-
> >>>> 1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/android/hal-audio.c b/android/hal-audio.c
> >>>> index 7305bb6..96fa5c3 100644
> >>>> --- a/android/hal-audio.c
> >>>> +++ b/android/hal-audio.c
> >>>> @@ -984,7 +984,7 @@ static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
> >>>>      int16_t *output = (void *) out->downmix_buf;
> >>>>      size_t i;
> >>>>
> >>>> -     for (i = 0; i < bytes / 2; i++) {
> >>>> +     for (i = 0; i < bytes / (2 * sizeof(int16_t)); i++) {
> >>>>              int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
> >>>>              int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
> >>>
> >>> I wonder actually what this get_unaligned is doing here? You cast the const void into const int16_t buffer. Is this really needed? Where is our input and output buffer coming from? Aren’t these aligned anyway? Meaning aren’t they allocated?
> >>
> >> We have this buffer from AudioFlinger so we don't actually know
> >> alignment or if this is pointer to beginning of some internal buffer
> >> (it's most probably both, but I don't think we should assume this).
> >
> > and audio system that does not give you a guarantee here on the alignment is utterly screwed up. Seriously, that is just bad for performance. Especially bad on ARM CPUs, so I doubt that they have not thought about this.
> 
> This is only to be on safe side and in terms of performance it does
> not really matter here since this code won't probably be used at all -

It was definitely not used. It crashes. I have modified code for SCO where
downmix was used.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-05-27  7:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-22 13:07 [RFC] android/hal-audio: Fix wrong memory access Andrei Emeltchenko
2014-05-22 13:54 ` Andrzej Kaczmarek
2014-05-22 14:16   ` Andrei Emeltchenko
2014-05-22 14:21 ` Marcel Holtmann
2014-05-26 12:36   ` Andrzej Kaczmarek
2014-05-26 12:48     ` Marcel Holtmann
2014-05-26 12:59       ` Andrzej Kaczmarek
2014-05-26 13:14         ` Marcel Holtmann
2014-05-27  7:54         ` Andrei Emeltchenko
2014-05-26 12:39 ` Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.