[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