[Ffmpeg-devel] [PATCH] part 10 - portability fixes (ILP32 vs LP64)
Stephane van Hardeveld
s.vanhardeveld
Tue Jan 31 00:06:17 CET 2006
Hi list,
Lately I tried to decode an ADPCM 32 kbit/s (g.726) stream, coming from
a device with an ARM processor. The sound was recognizable, but awful.
I checked google for a definition of the standard, and it seems g.726
proscribes de bits have to be delivered in little endian. I also found
an implementation on the net (http://www.tixy.clara.net/source/#G726).
I checked the g726.c file, and I believe the g726_decode_frame does not
take the endianness into account. I changed it (see below) and it works
for me now, but I am not sure if this is the right way to do it. Maybe I
should create a seperate input reader which solves the endianness on the
fly?
Be gentle, this is my first try :-)
Stephane
static int g726_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
- AVG726Context *c = avctx->priv_data;
- short *samples = data;
- uint8_t code;
uint8_t mask;
AVG726Context *c = avctx->priv_data;
+ short *samples = (short*)data;
+ uint8_t byte;
+ uint8_t bitOffset = 0;
+ uint16_t adpcm;
+ uint8_t bits = c->code_size;
+
GetBitContext gb;
if (!buf_size)
@@ -382,14 +501,42 @@
mask = (1<<c->code_size) - 1;
init_get_bits(&gb, buf, buf_size * 8);
+ /*
if (c->bits_left) {
int s = c->code_size - c->bits_left;;
code = (c->bit_buffer << s) | get_bits(&gb, s);
*samples++ = g726_decode(&c->c, code & mask);
}
+ */
+ // Test endianness
+ byte = get_bits(&gb, 2*c->code_size);
+
+ while (get_bits_count(&gb) + c->code_size <= buf_size*8)
+ {
+ adpcm = byte;
+ if(bitOffset+bits>8)
+ {
+ get_bits(&gb, 2*c->code_size);
+ adpcm |= byte<<8; // need bits from next byte as well
+ }
+
+ // align adpcm value to bit 0
+ adpcm >>= bitOffset;
+ adpcm &= (1<<c->code_size)-1;
- while (get_bits_count(&gb) + c->code_size <= buf_size*8)
- *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask);
+ *samples = g726_decode(&c->c, adpcm);
+ samples++;
+ //*samples++ = g726_decode(&c->c, byte & mask);
+ bitOffset += bits;
+
+ // move on to next byte of input if required
+ if(bitOffset>=8) {
+ bitOffset &= 7;
+ byte = get_bits(&gb, 2*c->code_size);
+ }
+ }
c->bits_left = buf_size*8 - get_bits_count(&gb);
c->bit_buffer = get_bits(&gb, c->bits_left);
@@ -398,27 +545,43 @@
*data_size = (uint8_t*)samples - (uint8_t*)data;
return buf_size;
}
More information about the ffmpeg-devel
mailing list