[Home]

Summary:ASTERISK-02099: G.726 endianness not RFC compliant
Reporter:mortenbroerup (mortenbroerup)Labels:
Date Opened:2004-07-24 05:22:06Date Closed:2011-06-07 14:10:25
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:According to RFC3551 and RFC2422, the G.726 code word packing should be big endian, not little endian.
The codec_g726.c in 1.0-RC1 uses little endian packing.


****** ADDITIONAL INFORMATION ******

Has the current G.726 implementation been tested with CISCO equipment? Interoperability is more important than RFC compliance, and CISCO probably sets the reference. I don't have any CISCO equipment available for testing, so I haven't tested myself.

Someone, please try the correct endianness:
static int
g726tolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
 struct g726_decoder_pvt *tmp = (struct g726_decoder_pvt *) pvt;
 unsigned char *b;
 int x;

 b = f->data;
 for (x=0;x<f->datalen;x++) {
  if (tmp->tail >= BUFFER_SIZE) {
ast_log(LOG_WARNING, "Out of buffer space!\n");
return -1;
}
tmp->outbuf[tmp->tail++] = g726_decode(b[x] & 0x0f, &tmp->g726);
  if (tmp->tail >= BUFFER_SIZE) {
ast_log(LOG_WARNING, "Out of buffer space!\n");
return -1;
}
tmp->outbuf[tmp->tail++] = g726_decode((b[x] >> 4) & 0xf, &tmp->g726);
 }

 return 0;
}

static int
lintog726_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
{
 struct g726_encoder_pvt *tmp = (struct g726_encoder_pvt *) pvt;
 short *s = f->data;
 int samples = f->datalen / 2;
 int x;
 for (x=0;x<samples;x++) {
  if (tmp->next_flag & 0x80) {
if (tmp->tail >= BUFFER_SIZE) {
ast_log(LOG_WARNING, "Out of buffer space\n");
return -1;
}
tmp->outbuf[tmp->tail++] = (tmp->next_flag & 0xf) | (g726_encode(s[x], &tmp->g726) << 4);
tmp->next_flag = 0;
} else {
tmp->next_flag = 0x80 | g726_encode(s[x], &tmp->g726);
}
 }
 return 0;
}

Comments:By: Mark Spencer (markster) 2004-07-24 09:16:34

Yes, we tested with Cisco.

By: Mark Spencer (markster) 2004-07-24 09:17:37

I'm relabling this a "minor" bug until someone can prove that it doesn't interoperate with cisco anymore.

By: mortenbroerup (mortenbroerup) 2004-07-24 09:43:59

I had swapped big/little endian in my initial description. The correct description would of course be:
According to RFC3551 and RFC2422, the G.726 code word packing should be little endian, not big endian.
The codec_g726.c in 1.0-RC1 uses big endian packing.

... which really doesn't matter, because Mark already confirmed that the implementation is Cisco compatible.

By: Mark Spencer (markster) 2004-07-24 09:49:41

Perhaps this is only an issue on big-endian machines?

By: mortenbroerup (mortenbroerup) 2004-07-24 10:05:13

It is not machine dependent, it describes how to pack 4-bit data in a byte.

Let's say you have an array of samples, stored in an "uint" type, but with values from 0 to 15, that you want pack into an array of bytes.

uint samples[NUMSAMPLES];
uchar byte_buffer[NUMSAMPLES/2]; // 2 samples per byte

for (i=0; i<NUMSAMPLES/2; i++) {
   //Big endian packing:
   byte_buffer[i] = samples[i*2]<<4 | samples[i*2+1];
   //Little endian packing:
   byte_buffer[i] = samples[i*2] | samples[i*2+1]<<4;
}

If the Cisco phone can run the Asterisk "echo" demo using this codec, so the actual linear-to-G.726 converter is activated for the initial prompt, I'm happy.

By: Brian West (bkw918) 2004-07-24 19:50:11

I'm accually talking g726 to mark right now without problems its from a sipura and no noticable issues.