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