How to avoid unwanted transcoding?

I have two peers, both alaw- and g729-capable, with these lines in sip.conf


I expect that it should work without any transcoding. I’ve tested two g729-only gateways on Asterisk without and everything was fine… But here it doesn’t work! When I unload I see this:

[May 29 18:00:50] WARNING[18121][C-00000207]: channel.c:5105 ast_write: Codec mismatch on channel SIP/users-00000415 setting write format to g729 from alaw native formats (alaw)
[May 29 18:00:50] WARNING[18121][C-00000207]: channel.c:5333 set_format: Unable to find a codec translation path from (alaw) to (g729)
[May 29 18:00:50] WARNING[18121][C-00000207]: chan_sip.c:7301 sip_write: Asked to transmit frame type g729, while native formats is (alaw) read/write = alaw/alaw

Why?! How to avoid this behavior? It’s just totally meaningless - both peers can use alaw as well as g729.

You only have one native format, so it looks like the B party rejected G.729.

Asterisk doesn’t push codec choices upstream, and, in any case, if A can handle both codecs, it will have negotiated in both codecs, and the choice to use G.729 will that of the peer. The only way you can force the upstream codec is by only having one compatible codec - that is SIP, not Asterisk.

There are special channel variables that you can set to force the choice of codec, up to the point where Asterisk makes its SDP offer. See … +Variables

So I can’t figure out how Asterisk negotiates codecs. It performs “AND” between sip.conf settings and codecs from A party SDP, or it just sends to B party codecs from sip.conf alone?

It intersects the A party codecs, then sends the B party codecs with any in common with A listed first.

Party A will then choose the best codec from the intersection and send with that codec. If the result is in the list that B returned, it will send it untranscoded.

I’m guessing A sent A-Law or G.729, Asterisk responded likewise. Asterisk sent B A-Law or G.729. B responded A-Law only. A sent media in G.729. Asterisk was forced to transcode. B sent media in A-Law. Asterisk passed it through to A.

I make full dump of both call legs and browse it in Wireshark. The most coolest thing is that there is 4 SDP messages and all four are with G.729A and G.711A, and transcoding still occurs. BUT! I’ve changed codec order in sip.conf for party A and now it’s all the way G.729A. I don’t know how it works, as SDPs to party B are identical in both cases and problem with mismatching codec was on party B side.

Cool. Problem is solved for two peers. But it’s pretty useless. I expect that support for both codecs on all peers will prevent all problems with codec negotiation, but in reality we still need transcoding sometimes.

I know about directmedia and directrtpsetup, but for obvious reasons this is unusable for some peers. Is there a way to force Asterisk DO NOT change at all codec information in SDPs, but still perform RTP traffic proxying?

And if transcoding is inevitable evil - OK, let it be, but it often gives “robotized” and stuttered voice. There is about 20 transcoded calls at one time, Asterisk is quad core VMWare virtual machine on octa-core Xeon host. Why it distorts voice on so few calls and so big calculating power?

It shouldn’t transcode if both sides allow both codecs.

VMs tend to produce extremely high jitter.