Summary:ASTERISK-16117: Asterisk transcodes audio "internally" when calling between two SIP peers when it should not
Reporter:Dayton Turner (dayton)Labels:
Date Opened:2010-11-11 13:40:40.000-0600Date Closed:
Versions:Frequency of
Description:I am reporting this on the presumption that it is a bug, but it may be "by design", so please do explain if so, and if that is the case, please offer an explanation why, as it is completely beyond my understanding.

First, I will paint a picture of topology:

Host A (external) ---> ME (Asterisk 1.4.32) <----> Host B (external)

For context, lets define host A as my ITSP.  They are a tier 1 carrier using a Nextone switch.
Host B is a freeswitch server, that routes calls to another asterisk server internally.
Defining each host is merely for ease of reading and understanding, i dont believe it to be relevant at all.

On "ME", I define host A in sip.conf like:

Host B is defined like:

In this particular instance, I realize that the order in which you list your codecs, asterisk uses to determine priority or preference order.  This is an assumption, but i believe it is a correct one.

So, a call comes in to ME as originated by Host A.  Host A offers G729, G711u, G711a, in that order in the SDP.  By default, we establish G.729 with this provider, with the intent that on some incoming calls (for instance, for FAX) we use asterisk dialplan to set the SIP_CODEC variable to ulaw, which will quickly cause asterisk to send the next SDP offer to include only G711u.   This part seems to work okay, as evidenced by packet captures and analysis in wireshark.  (Note: There are often 7-10 packets of G729 RTP data that originate from asterisk before the new SDP is sent and the other side ACK's.  I suppose this is fairly normal, for early media, etc, and i dont consider this to be a problem)

So now, "ME" has accepted the call from Host A, has requested the codec on the inbound call be changed to ULAW, and in our dial plan, we call Host B, with the intent of connecting to a FAX (ulaw) peer behind Host B.  This happens just fine.  The problem arises from the codec negotiation between ME and Host B.   As I laid out above, in my sip.conf for Host B, i define g729 as the first codec.  Because asterisk (at least 1.4) has no way to, in the dialplan, request ulaw be the preferred (or only) codec, we rely on SDP to work it out.

Host B does not speak g729, and therefore I would expect that in the negotiation process, ME and Host B would determine that g729 was out of the question, and just use ULAW, and everything will be okay.

Well, according to the SDP and the packet capture, this does happen, and we are now speaking ULAW to Host A, and ULAW to Host B.    !!HOWEVER!! - the audio looks like crap when looking at it in waveform format.  Upon further investigation, while the call is up, I notice that two G729 transcoders are in use.  WTF? - this cant be, we're speaking ULAW!

Well as it would turn out, for -some- reason, during the negotiation process, asterisk decided that while both peers would need to speak G711u, because the allow=g729 was the FIRST codec in Host B's priority list, that it would be prudent to transcode from G711u to G729a and BACK to G711u again, making the final stream actually BE g711u, but be horribly compressed and ultimately fail.

I apologize for the lengthy and wordy explanation, but i wanted to make sure i properly conveyed the problem.

I thought for a minute that this could be attributed to not allowing reinvites and asterisk being forced to figure out what to do while both sides negotiated, and  deciding to use G729 before both sides had agreed upon ULAW, or something? Maybe some sort of SIP SDP negotiation delay would be in order?  I am 100% wildly assuming how this could have been the desired effect.

The interim fix was to remove g729 from the list of allowed codecs to Host B, when i know full well they dont yet support it - but wow what a gotcha on my part.

Also, I used to have G711u as Host A's preferred codec, and while leaving G729a as Host B's preferred codec, this was never an issue.  So i suspect it absolutely has something to do with the fact that the incoming call is starting out on G729a and then i'm using SIP_CODEC to ask it to change to G711u.

Lastly, I realize 1.4.32 is not the newest 1.4 branch, but after a brief search i didnt find any reason to believe this was fixed in a newer 1.4 release.

Please advise! :)