g726 over RTP

g726 over RTP

Does anybody know how to send the output of g726 encode function
ippsEncode_G726_16s8u() over RTP..?
Can the output of the above function be sent directly as 40 bytes (for 32kbps for e.g)?

Thanks for help

15 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

No, the output of the ippsEncode_G726_16s8u() function can't be sent directly over RTP. You should pack it. For 32 kbps bitrate codewordis 4 bits. So theRTP payload format for the G726-32 looks as follows:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7....
Where 7 is LSB of the first byte. a4 is the LSB of the first codeword. b4 is the LSB of the second codeword. And ithasn't gotanypayload-specific header.

You should remember that default packet lenght is 20 ms. G726 bitsream doesn't contains any information about bitrate, so you should guees about it from the payload type. Payload type for G726-32should be defined dynamically by non-RTP means.
Igor S. Belyakov

I am sorry..I am not sure I understand..
Would you have a code snippet to show this..?

Would it be like this for eg..?

If out out of encoder looks like

01 03 03 03 04 04 05 03 04 04 04

After packing, it should look like

31 33 44 35 44 ....

40 bytes -> 20 bytes

Should the remaining 20 bytes be 0 for 32kbps payload of 40 bytes

Output of the ippsEncode_G726_16s8u doesn't contain packet bitstream. It contains codewords in separate bytes, so for 32 kbps only 4 LSB bits of each byte are used.
This function packs bitstream for20 ms for 32 kbps:
void PackG726_32_20ms(const char *pEncoderOut, char *pBitsream)
int i;
for(i=0;i<80;i+=8) { /*Loop for 1 ms*/
pBitsream[0] = (pEncoderOut[0] & 0xf) | ((pEncoderOut[1] & 0xf)<<4);
pBitsream[1] = (pEncoderOut[2] & 0xf) | ((pEncoderOut[3] & 0xf)<<4);
pBitsream[2] = (pEncoderOut[4] & 0xf) | ((pEncoderOut[5] & 0xf)<<4);
pBitsream[3] = (pEncoderOut[6] & 0xf) | ((pEncoderOut[7] & 0xf)<<4);
pBitsream += 4;
pEncoderOut += 8;

How to use:

char pInputPCM[160];/*Input PCM data*/
char pUnPckDst[80];/*Encoder output*/
char pPackDst[40];/*Packed bitstream*/
IppsEncoderState_G726_16s *pEncObj;
int sizeObj;/*Size of pEncObj*/

ippsEncodeGetStateSize_G726_16s8u(&sizeObj);/*Get size of the pEncObj*/
pEncObj = (IppsEncoderState_G726_16s *)malloc(sizeObj);

ippsEncodeInit_G726_16s8u(pEncObj,IPP_SPCHBR_32000);/*Init Encoder*/

if(ippsEncode_G726_16s8u(pEncObj, pInputPCM, pUnPckDst, 80) != ippStsNoErr){
return -1;
/*Pack encoder output*/
PackG726_32_20ms(pUnPckDst, pPackDst);

So the size of the bitstream for 20 ms packet will be 40 bytes.

Igor S. Belyakov

Thank you so much.. I did the same just like yours but for 10ms and it now works.
I was able to send it to a decoder of some other g726 implementation and I get clear audio.

Thanks again.

Strange thing happend on G729 RTP bitorder(at use of Intel IPP 4.x).

I deocode G726, but the bitorder is

a0 is the most significantbit of "Sample a" and also the most significant bit of the byte.

a0 a1 a2 a4 b0 b1 b2 b3

instead ofb0 b1 b2 b3 a0 a1 a2 a4 (according to rfc 3551)

also on other Bitrates

a0 a1 a2 b0 b1 b2 c0 c1

instead of c0 c1 b0 b1 b2 a0 a1 a3 (according torfc 3551)

where 0 is the most significant bit.

It works only with the first bit order, but this is different to descrition of rfc.

It cant be AAL2-Format because SIP says eg. G726-32 (and not G726-32-AAL2).

It works with all formats, but only with the wrong bitorder.
I like to understand why it works with the wrong bitorder format and not with the one descirbed in rfc 3551. Whats happend?

Hints are welcome.



Yes, you areright.In IPP 4.x was AAL2 format for G726. In IPP 5.0 it is rewrited according to the rfc3551. It is affected only on bitordering.

You can use my previouse code examlpe with direct call to the ippsXXX functions or do simple converter (AAL2 <> RFC 3551) if you will use IPP 4.x with USC interface.

Igor S. Belyakov

Also posted in http://softwareforums.intel.com/en-us/forums/showthread.php?t=50063#32404

I had gone back thru recent IPPv5.1 sample code and compared to RTP bit-packing defined in RFC-3551--everything in the sample code looked to follow the spec.

I recently saw a note regarding the G726 bit-packing in the Asterisk web site (http://www.asterisk.org/doxygen/Config_sip.html). In the Asterisk config it says that some phones use the AAL2 packing instead of the RTP packing. I'm not sure if there is a good catalog of which phones do which flavor of G726 bit-packing. It may be a good idea to provide both in the sample code, please. :)


I'm not sure if itbe in sample code. If you extrimelly need AAL2 packing I can help you.

Igor S. Belyakov

Hi Igor,

I would appreciate some help. I tried just a "nibble-flip" of the encoded/packed bytes, and that did not seem to work with live traffic.




Is the following true(and if it is true how can I do it efficiently)? If I would like to decode a G.726 stream which stores1 sample on 2 bit and 4 sample in 1 byte then I have to convert it to store 1 sample on 1 byte before I can decode it.



Hi Rick,

Coudl you provide some portion of your "live traffic" (which encoded and audible :))? I try to find right solution.


Hi, Bendeguy.

Youare rigth if you do the direct calls to ippsXXX functions and don't use USC.

Igor S. Belyakov

I would be happy to send along an Ethereal capture of live G726 traffic, but I don't see how to attach a file (and don't have access to an http/ftp server)... Please send me e-mail (rporter@covergence.com), and I will include the Ethereal captures in my response.


Leave a Comment

Please sign in to add a comment. Not a member? Join today