2008-06-05 17:05:04     G729 on linphone

Document created by Aaronwu Employee on Aug 6, 2013
Version 1Show Document
  • View in full screen mode

2008-06-05 17:05:04     G729 on linphone

Nathan Whittington (UNITED STATES)

Message: 56762   

 

I'm using 2008R1, and I've followed the instructions in the linphone/g729_patch/ directory and updated the source.  I also compiled and successfully linked against the libbfgdots (libg729ab.so) library.  When I transmit a g729 stream at mediastreamer, I get several debug statements suggesting it's receiving the stream and is decoding it but I get no audio from the speaker.

 

I can play ulaw and alaw streams fine using the same transmission software.

 

I was able to verify the 729 stream is being sent correctly (with separate 729 client software).

 

Why won't it play g729 audio?

QuoteReplyEditDelete

 

 

2008-06-05 22:04:35     Re: G729 on linphone

Yi Li (CHINA)

Message: 56777   

 

Are you making two linphones(with g729 enabled) talking to each other? I tested with two linphones (on two boards), I can make calls and talk. But I didn't test with other g729 client.

QuoteReplyEditDelete

 

 

2008-06-06 08:27:15     Re: G729 on linphone

Michele d'Amico (ITALY)

Message: 56811   

 

That patch can work ONLY between two linphone.

 

1) The stream produced by the patch contains some hardcoded data useful for the libbfgdots library but not compliant on the standard

2) Anyway, the packets are 10 ms instead 20 ms

 

If you would like use g729 between patched linphone and an other phone you need rewrite the patch. You can found an example on how use libbfgdots for encoding/decoding standard g729 streams on astfin project: David Rowe wrote an asterisk module that do it, you could adapt it to mediastreamer2.

 

Regards

 

--Michele

QuoteReplyEditDelete

 

 

2008-06-06 13:30:17     Re: G729 on linphone

Nathan Whittington (UNITED STATES)

Message: 56824   

 

Ah, I didn't realize the 729 patch worked only between linphones.

 

Thanks for the tip Michele, I'll look into astfin.

<br type="_moz" />

QuoteReplyEditDelete

 

 

2008-06-06 15:56:45     Re: G729 on linphone

Mike Frysinger (UNITED STATES)

Message: 56830   

 

are you suggesting it is possible to adapt the code to some standard so that a g729 stream coming from linphone can work with any device ?

QuoteReplyEditDelete

 

 

2008-06-09 03:47:42     Re: G729 on linphone

Michele d'Amico (ITALY)

Message: 56855   

 

Hi Mike,

 

I did it. I test it with Snom and it works well. That is just a draft that it work only with g729a frames (it doesn't manage b frames). I attach my code to that mail, could you test it? ... I would like to know if it work with other devices.

 

 

 

Regards

 

 

 

--Michele

 

g729.c

QuoteReplyEditDelete

 

 

2008-06-09 11:08:54     Re: G729 on linphone

Nathan Whittington (UNITED STATES)

Message: 56871   

 

Thanks Michele!

 

I was in the process of doing my own patch but it looks like you beat me to it.

 

I just tested it and it seems to be working with my 729 streaming client.  The audio seems a little scratchy but it's passible. 

 

I haven't gone through it in detail but you mentioned this only handles a frames - how much more work will it be to update it to handle b frames as well?

QuoteReplyEditDelete

 

 

2008-06-09 15:49:54     Re: G729 on linphone

Mike Frysinger (UNITED STATES)

Message: 56881   

 

thanks, ive opened a tracker (#4157) for this

QuoteReplyEditDelete

 

 

2008-06-10 03:59:44     Re: G729 on linphone

Michele d'Amico (ITALY)

Message: 56897   

 

Hi Nathan,

 

Maybe you don't need a lot effort to have b frames (aka annexb frames) works as well in g729. The library could produce and undestand annexb fames. Anyway you coul declare "fmtp:18 annexb=no" (18 is the G729 paylod code) in your sdp message in order the inform the other end point that you don't want annexb frames.

 

Anyway, you sholud simply discard annexb frames because they mean a silence detected frames... the audio could be little choppy but accptable.

 

Regards

 

 

 

--Michele

QuoteReplyEditDelete

 

 

2008-06-11 07:10:21     Re: G729 on linphone

Yi Li (CHINA)

Message: 56993   

 

Hi Michele,

 

I tested linphone using code similiar with yours (also from astfin) when I worked on the linphone g729 patch. The only g729 device I have is a Soundpoint IP300SIP phone. However, even using this code, I cannot make linphone talk with this phone.

 

It looks your g729.c changes these ( for encoder):

 

1. Discard the header "[0x6b21][0x0050]" of each encoded packet

 

2. Swap bit order of each byte

 

I am not sure what is the exact requirement of G.729 (A/AB) standard. But without the packet header, how can the decoder identify a packet if using g729ab (the packet length can be either 80, 16, or 0 bits)?.

 

Other problems with this code:

 

1. Using unpacked mode (each bit is represented using a 16-bit word) is highly inefficiant.

 

2. The bit swap code is not optimized.

 

It is interesting that the libbfgdots works well using stardard g729a/g729ab test vectors, but cannot talk to other g729 devices.

 

-Yi

 

 

QuoteReplyEditDelete

 

 

2008-06-11 09:11:45     Re: G729 on linphone

Michele d'Amico (ITALY)

Message: 56994   

 

Hi Yi,

 

I do it simply by an reverse enginering of Snom's g729 stream: that device don't send any header for the packet.

 

By googleing i found that you can understand the type of packet simply by its len. The libbfgdots needs the header, but the  rtp stream no.

 

 

 

Now I'm trying to answer to yours questions:

 

1. Discard the header "[0x6b21][0x0050]" of each encoded packet

 

I do it because on the rtp stream produced by Snom there isn't any trace of that headers... maybe because the rtp is packetized and not a stream: that implies you can identify the packet type by size instead header.

 

2. Swap bit order of each byte:

 

I don't understand: why you're speaking of "Swap"... You must read the stream from left" to "right", aka "from MSB to LSB"

 

1. Using unpacked mode (each bit is represented using a 16-bit word) is highly inefficiant.

 

What I'm doing is the same that do the asm code if packet mode is set: IMHO the difference is minimal... I didn't any efficiant's test  but I could bet that we lost not much cycles.

 

2. The bit swap code is not optimized.

 

Maybe it could be optimized. Now that isn't my first goal. My goals are:

 

1) g729a that work with any devices (Now it seams ok for Snom, Cisco, Avaya and Thompson).

 

2) Implement the annexb handling and make it g729ab compliant

 

3) Optimize it .... if I heve some time that I could spending on that task

 

p.s. Could you post a pcap's trace of a call between your linphone and Soundpoint?

 

 

 

Regards

 

 

 

--Michele

QuoteReplyEditDelete

 

 

2008-06-24 03:41:55     Re: G729 on linphone

Yi Li (CHINA)

Message: 57753   

 

Hi Michele,

 

I tried your g729.c using linphone-1.6.0, talking to the SoundPoint IP phone, and it works! I dumped the g729a encoded packet - it is 20-byte long, without header. So it looks this format is kind of "standard".

 

I am going to check in your code to uclinux-dist as linphone patch. But there is still one thing I cannot understand. I changed your code to use packed mode, as showed bellow. But it cannot work. Is there anything wrong?

 

Thanks.

 

-Yi

 

 

--- g729.c    2008-06-24 15:49:48.000000000 +0800

+++ g729.c.packed    2008-06-24 15:51:57.000000000 +0800

@@ -79,7 +79,7 @@

     g729ab_enc_process = G729AB_ENC_PROCESS; /* function pointers: special for FDPIC g729 lib */

     G729AB_ENC_RESET(&s->state);

   

-    G729AB_ENC_CONFIG(&s->state, G729_ENC_OUTPUTFORMAT, FMT_UNPACKED); /* unpacked */

+    G729AB_ENC_CONFIG(&s->state, G729_ENC_OUTPUTFORMAT, FMT_PACKED); /* packed */

   

     //G729AB_ENC_CONFIG(&s->state, G729_ENC_VAD, 1 ); /* g729ab */

     G729AB_ENC_CONFIG(&s->state, G729_ENC_VAD, 0 ); /* g729a */

@@ -104,7 +104,7 @@

     int pck;

     int i,byte,bit;

     short ibuf[_SAMPLES * n_pck] __attribute__ ((aligned (4)));

-    short obuf[_ADSP_G729_H_LEN + _PCK_BITSTREAM_LEN] __attribute__ ((aligned (4)));

+    short obuf[_ADSP_G729_H_LEN + _PCK_BITSTREAM_LEN_BYTES] __attribute__ ((aligned (4)));

     int obuf_len_byte = n_pck * _PCK_BITSTREAM_LEN_BYTES;

 

     while((im=ms_queue_get(f->inputs[0]))!=NULL){

@@ -115,14 +115,7 @@

         memset(om->b_wptr, 0 , obuf_len_byte);

         for (pck=0;pck<n_pck;++pck){

             G729AB_ENC(&s->state, ibuf + (pck * _SAMPLES), obuf);

-

-            for(i=0; i<_PCK_BITSTREAM_LEN; i++) {

-                byte = i>>3;

-                bit = i & 0x7;

-                if (obuf[i+2] == 0x81)

-                    om->b_wptr[byte] |= 1 << (7-bit);

-            }

-

+            memcpy(om->b_wptr, (char *)&obuf[2], _PCK_BITSTREAM_LEN_BYTES);

             om->b_wptr += _PCK_BITSTREAM_LEN_BYTES;

         }

         mblk_set_timestamp_info(om,s->ts);

@@ -171,7 +164,7 @@

     DecState *s = ms_new(DecState, 1);

     g729ab_dec_process = G729AB_DEC_PROCESS;

     G729AB_DEC_RESET(s);

-    G729AB_DEC_CONFIG(s, G729_DEC_INPUTFORMAT, FMT_UNPACKED); /* unpacked */

+    G729AB_DEC_CONFIG(s, G729_DEC_INPUTFORMAT, FMT_PACKED); /* packed */

     f->data= s;

}

 

@@ -185,21 +178,12 @@

     mblk_t *im;

     mblk_t *om;

     int i,byte,bit;

-    short __attribute__ ((aligned (4))) _pck[_ADSP_G729_H_LEN + _PCK_BITSTREAM_LEN];

+    short __attribute__ ((aligned (4))) _pck[_ADSP_G729_H_LEN + _PCK_BITSTREAM_LEN_BYTES];

     _pck[0] = SYNCWORD;

     while((im=ms_queue_get(f->inputs[0]))!=NULL){

         while (im->b_wptr - im->b_rptr >= _PCK_BITSTREAM_LEN_BYTES){

             _pck[1] = BITNUM_G729A;

-

-            for(i=0; i<80; i++) {

-                byte = i>>3;

-                bit = i & 0x7;

-                if ((im->b_rptr[byte] >> (7-bit)) & 0x1)

-                    _pck[i+2] = 0x81;

-                else

-                    _pck[i+2] = 0x7f;

-            }

-

+            memcpy((char *)&_pck[2], im->b_rptr, _PCK_BITSTREAM_LEN_BYTES);

             om=allocb(_PCK_SIZE,0); /* 80 * 2 */

             G729AB_DEC(s, _pck,(short *) om->b_wptr);

             om->b_wptr += _PCK_SIZE;

 

QuoteReplyEditDelete

 

 

2008-06-24 05:43:00     Re: G729 on linphone

Michele d'Amico (ITALY)

Message: 57805   

 

Hi Yi,

 

Since two months ago I spend some time on that issue; I took a look to the asm code of libbfgdots for packet mode and It seems that the code does the same work of our for sentences.

 

yes, of course... It colud be better if we can make it work in packet mode, but also David Rowe don't use packet mode in his astfin's module.... maybe is not really necessary.

 

Just a shot... You could to try to remove the casts in memcpy istances and cast the buffers to short.

 

Regards

 

 

 

--Michele

Attachments

    Outcomes