* SBC encoder/decoder API & errors handling
@ 2010-06-29 18:45 Siarhei Siamashka
2010-06-30 7:53 ` Johan Hedberg
0 siblings, 1 reply; 6+ messages in thread
From: Siarhei Siamashka @ 2010-06-29 18:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lennart Poettering
[-- Attachment #1: Type: Text/Plain, Size: 1038 bytes --]
Hello,
When I tried to run some SBC encoder tests a few days ago, I noticed that
there is a regression introduced by commit:
http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=c43f8bdcc1d527e2d77481a66217771038be3acd
It is caused by the change from 'int' to 'size_t' for the type of variable
'encoded' in 'sbcenc.c'. After this modification, the check for 'encoded <= 0'
does not catch the case when 'sbc_encode' tries to return a negative number in
'encoded' variable. Later we end up calling 'write' function with a negative
size for the data block.
Right now, in the case of error 'sbc_encode' function may either return a
negative number as a return value, or return a negative value in 'encoded'
variable. But this second type of error is apparently not handled by anything
other than 'sbcenc' tool at the moment.
Any opinions about how to fix it in the best way? Because it is a flaw in the
library API, comments from the interested parties are welcome.
--
Best regards,
Siarhei Siamashka
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: SBC encoder/decoder API & errors handling
2010-06-29 18:45 SBC encoder/decoder API & errors handling Siarhei Siamashka
@ 2010-06-30 7:53 ` Johan Hedberg
2010-06-30 8:31 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 6+ messages in thread
From: Johan Hedberg @ 2010-06-30 7:53 UTC (permalink / raw)
To: Siarhei Siamashka; +Cc: linux-bluetooth, Lennart Poettering
[-- Attachment #1: Type: text/plain, Size: 1449 bytes --]
Hi Siarhei,
On Tue, Jun 29, 2010, Siarhei Siamashka wrote:
> When I tried to run some SBC encoder tests a few days ago, I noticed that
> there is a regression introduced by commit:
> http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=c43f8bdcc1d527e2d77481a66217771038be3acd
>
> It is caused by the change from 'int' to 'size_t' for the type of variable
> 'encoded' in 'sbcenc.c'. After this modification, the check for 'encoded <= 0'
> does not catch the case when 'sbc_encode' tries to return a negative number in
> 'encoded' variable. Later we end up calling 'write' function with a negative
> size for the data block.
>
> Right now, in the case of error 'sbc_encode' function may either return a
> negative number as a return value, or return a negative value in 'encoded'
> variable. But this second type of error is apparently not handled by anything
> other than 'sbcenc' tool at the moment.
>
> Any opinions about how to fix it in the best way? Because it is a flaw in the
> library API, comments from the interested parties are welcome.
In general the API feels a bit weird in that it can return errors in two
different ways. A less obtrusive fix would be to make the variable type
ssize_t instead of size_t. Regarding breaking the SBC library API, I
don't see any big issue with that since it's internal to bluetoothd and
we can easily update the pulseaudio copy accordingly. Would the attached
patch make sense?
Johan
[-- Attachment #2: sbc.patch --]
[-- Type: text/x-diff, Size: 2593 bytes --]
diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c
index cddeda2..4c0ab6f 100644
--- a/audio/pcm_bluetooth.c
+++ b/audio/pcm_bluetooth.c
@@ -1007,7 +1007,7 @@ static snd_pcm_sframes_t bluetooth_a2dp_write(snd_pcm_ioplug_t *io,
snd_pcm_sframes_t ret = 0;
unsigned int bytes_left;
int frame_size, encoded;
- size_t written;
+ ssize_t written;
uint8_t *buff;
DBG("areas->step=%u areas->first=%u offset=%lu size=%lu",
diff --git a/sbc/sbc.c b/sbc/sbc.c
index 569dd7c..fa542e3 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -743,7 +743,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
* -99 not implemented
*/
-static SBC_ALWAYS_INLINE int sbc_pack_frame_internal(uint8_t *data,
+static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
struct sbc_frame *frame, size_t len,
int frame_subbands, int frame_channels,
int joint)
@@ -860,7 +860,7 @@ static SBC_ALWAYS_INLINE int sbc_pack_frame_internal(uint8_t *data,
return data_ptr - data;
}
-static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len,
+static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len,
int joint)
{
if (frame->subbands == 4) {
@@ -1005,10 +1005,10 @@ ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
}
ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
- void *output, size_t output_len, size_t *written)
+ void *output, size_t output_len, ssize_t *written)
{
struct sbc_priv *priv;
- int framelen, samples;
+ ssize_t framelen, samples;
int (*sbc_enc_process_input)(int position,
const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
int nsamples, int nchannels);
diff --git a/sbc/sbc.h b/sbc/sbc.h
index 91422a9..2f830ad 100644
--- a/sbc/sbc.h
+++ b/sbc/sbc.h
@@ -92,7 +92,7 @@ ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
/* Encodes ONE input block into ONE output block */
ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
- void *output, size_t output_len, size_t *written);
+ void *output, size_t output_len, ssize_t *written);
/* Returns the output block size in bytes */
size_t sbc_get_frame_length(sbc_t *sbc);
diff --git a/sbc/sbcenc.c b/sbc/sbcenc.c
index b5e0541..3d3a7dc 100644
--- a/sbc/sbcenc.c
+++ b/sbc/sbcenc.c
@@ -50,7 +50,7 @@ static void encode(char *filename, int subbands, int bitpool, int joint,
struct au_header au_hdr;
sbc_t sbc;
int fd, size, srate, codesize, nframes;
- size_t encoded;
+ ssize_t encoded;
ssize_t len;
if (sizeof(au_hdr) != 24) {
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: SBC encoder/decoder API & errors handling
2010-06-30 7:53 ` Johan Hedberg
@ 2010-06-30 8:31 ` Luiz Augusto von Dentz
2010-06-30 8:53 ` Johan Hedberg
0 siblings, 1 reply; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2010-06-30 8:31 UTC (permalink / raw)
To: Siarhei Siamashka, linux-bluetooth, Lennart Poettering
Hi,
On Wed, Jun 30, 2010 at 10:53 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Siarhei,
>
> On Tue, Jun 29, 2010, Siarhei Siamashka wrote:
>> When I tried to run some SBC encoder tests a few days ago, I noticed that
>> there is a regression introduced by commit:
>> http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=c43f8bdcc1d527e2d77481a66217771038be3acd
>>
>> It is caused by the change from 'int' to 'size_t' for the type of variable
>> 'encoded' in 'sbcenc.c'. After this modification, the check for 'encoded <= 0'
>> does not catch the case when 'sbc_encode' tries to return a negative number in
>> 'encoded' variable. Later we end up calling 'write' function with a negative
>> size for the data block.
>>
>> Right now, in the case of error 'sbc_encode' function may either return a
>> negative number as a return value, or return a negative value in 'encoded'
>> variable. But this second type of error is apparently not handled by anything
>> other than 'sbcenc' tool at the moment.
>>
>> Any opinions about how to fix it in the best way? Because it is a flaw in the
>> library API, comments from the interested parties are welcome.
>
> In general the API feels a bit weird in that it can return errors in two
> different ways. A less obtrusive fix would be to make the variable type
> ssize_t instead of size_t. Regarding breaking the SBC library API, I
> don't see any big issue with that since it's internal to bluetoothd and
> we can easily update the pulseaudio copy accordingly. Would the attached
> patch make sense?
I guess it make sense, but we should also fix alsa and gstreamer code
to use variables of type ssize_t instead of int:
audio/pcm_bluetooth.c:1060: encoded = sbc_encode(&a2dp->sbc,
data->buffer, a2dp->codesize,
audio/pcm_bluetooth.c:1096: encoded = sbc_encode(&a2dp->sbc, buff,
a2dp->codesize,
audio/gstsbcenc.c:391: consumed = sbc_encode(&enc->sbc, (gpointer) data,
--
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: SBC encoder/decoder API & errors handling
2010-06-30 8:31 ` Luiz Augusto von Dentz
@ 2010-06-30 8:53 ` Johan Hedberg
2010-06-30 13:07 ` Siarhei Siamashka
0 siblings, 1 reply; 6+ messages in thread
From: Johan Hedberg @ 2010-06-30 8:53 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Siarhei Siamashka, linux-bluetooth, Lennart Poettering
Hi Luiz,
On Wed, Jun 30, 2010, Luiz Augusto von Dentz wrote:
> audio/pcm_bluetooth.c:1060: encoded = sbc_encode(&a2dp->sbc,
> data->buffer, a2dp->codesize,
> audio/pcm_bluetooth.c:1096: encoded = sbc_encode(&a2dp->sbc, buff,
> a2dp->codesize,
My patch already contained the fix for these two.
> audio/gstsbcenc.c:391: consumed = sbc_encode(&enc->sbc, (gpointer) data,
This place actually passes NULL as the output parameter so no issue
there.
I'll push in a minute the fix in two separate commits (the libsbc
changes should be in an independent patch so they can easily be exported
to external copies like pulseaudio).
Johan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: SBC encoder/decoder API & errors handling
2010-06-30 13:07 ` Siarhei Siamashka
@ 2010-06-30 11:03 ` Johan Hedberg
0 siblings, 0 replies; 6+ messages in thread
From: Johan Hedberg @ 2010-06-30 11:03 UTC (permalink / raw)
To: Siarhei Siamashka
Cc: Luiz Augusto von Dentz, linux-bluetooth, Lennart Poettering
Hi Siarhei,
On Wed, Jun 30, 2010, Siarhei Siamashka wrote:
> So would it be a good idea to just fix the issues in the bluez SBC
> code as we feel appropriate and then notify pulseaudio developers
> about the changes?
Yes, I think that's a reasonable way to proceed.
Johan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: SBC encoder/decoder API & errors handling
2010-06-30 8:53 ` Johan Hedberg
@ 2010-06-30 13:07 ` Siarhei Siamashka
2010-06-30 11:03 ` Johan Hedberg
0 siblings, 1 reply; 6+ messages in thread
From: Siarhei Siamashka @ 2010-06-30 13:07 UTC (permalink / raw)
To: Johan Hedberg; +Cc: Luiz Augusto von Dentz, linux-bluetooth, Lennart Poettering
[-- Attachment #1: Type: Text/Plain, Size: 2451 bytes --]
On Wednesday 30 June 2010 08:53:47 Johan Hedberg wrote:
> Hi Luiz,
>
> On Wed, Jun 30, 2010, Luiz Augusto von Dentz wrote:
> > audio/pcm_bluetooth.c:1060: encoded = sbc_encode(&a2dp->sbc,
> > data->buffer, a2dp->codesize,
> > audio/pcm_bluetooth.c:1096: encoded = sbc_encode(&a2dp->sbc, buff,
> > a2dp->codesize,
>
> My patch already contained the fix for these two.
>
> > audio/gstsbcenc.c:391: consumed = sbc_encode(&enc->sbc,
(gpointer) data,
>
> This place actually passes NULL as the output parameter so no issue
> there.
Well, it is still kind of an issue because some types of errors are not
detected here at all.
> I'll push in a minute the fix in two separate commits (the libsbc
> changes should be in an independent patch so they can easily be exported
> to external copies like pulseaudio).
Yes, I used exactly the same patch myself and it helped. It's a bit artificial
problem and does not need an urgent fix. I found it by running a script which
uses 'sbcenc' with lots with different permutations of configuration options
(some of them are invalid) and logs md5 hashes of the encoded results. But as
long as the SBC encoder is always used with valid settings, no problems should
happen.
Anyway, API inconsistency is a bit ugly. Maybe it's better to always report
errors as a negative function return value (and have real constants defined
instead of some magic numbers)? Or just adjust encoding settings to the closest
valid configuration automatically and never fail there?
Another SBC issue (I found this report just on the last weekend) is the missing
support for the dynamically changing bitpool value:
https://tango.0pointer.de/pipermail/pulseaudio-discuss/2010-January/006042.html
It is a clear problem for the SBC decoder (in addition to the other issues like
not so good audio quality and poor performance, which would have to be
addressed eventually).
But SBC encoder could also make some use of this changing bitpool feature to
adaptively change it when connection quality is not very good and audio would
start skipping otherwise (due to the interference from wifi, walking away from
the bluetooth dongle behind a concrete wall or anything else).
So would it be a good idea to just fix the issues in the bluez SBC code as we
feel appropriate and then notify pulseaudio developers about the changes?
--
Best regards,
Siarhei Siamashka
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-06-30 13:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-29 18:45 SBC encoder/decoder API & errors handling Siarhei Siamashka
2010-06-30 7:53 ` Johan Hedberg
2010-06-30 8:31 ` Luiz Augusto von Dentz
2010-06-30 8:53 ` Johan Hedberg
2010-06-30 13:07 ` Siarhei Siamashka
2010-06-30 11:03 ` Johan Hedberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).