Why Doesn’t Asterisk Try To Prevent Transcoding

Home » Asterisk Users » Why Doesn’t Asterisk Try To Prevent Transcoding
Asterisk Users 12 Comments

Let’s say I have two devices configured and the follow call scenarios occur.

[100]
disallow=all allow=g722&ulaw

Polycom phone with g722,ulaw,alaw,g729

[101]
disallow=all allow=ulaw

Polycom phone with g722,ulaw,alaw,g729

101 dials 100 -> ulaw to ulaw is chosen
100 dials 101 -> g722 to ulaw is chosen

Ideally when 100 dials 101 ulaw would be chosen since it is the common format. Looking into this deeper

Device 100 sends INVITE to Asterisk offering g722,ulaw,alaw,g729
Asterisk sends INVITE to device 101 offering ulaw Device 101 sends 200 OK to Asterisk offering ulaw Asterisk sends 200 OK to device 100 offering g722,ulaw

I can prevent transcoding by adding SIP_CODEC_INBOUND=ulaw to the dialplan for extension 101. This causes Asterisk to send 200 OK to device 100
offering ulaw. Am I missing why Asterisk wouldn’t just offer the highest priority codec they have in common to prevent transcoding?

Ryan

12 thoughts on - Why Doesn’t Asterisk Try To Prevent Transcoding

  • I should have mentioned I’m using Asterisk 11.2-cert2. The core debug from the above shows

    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7911 sip_new:
    *** Our native formats are (g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7912 sip_new:
    *** Joint capabilities are (ulaw|g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7913 sip_new:
    *** Our capabilities are (ulaw|g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7914 sip_new:
    *** AST_CODEC_CHOOSE formats are g722

    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7911 sip_new:
    *** Our native formats are (ulaw)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7912 sip_new:
    *** Joint capabilities are (nothing)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7913 sip_new:
    *** Our capabilities are (ulaw)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7914 sip_new:
    *** AST_CODEC_CHOOSE formats are ulaw
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7916 sip_new:
    *** Our preferred formats from the incoming channel are (g722)

    I’m looking at the code now. I am hoping to write a patch, if I can wrap my head around the code, to determine join capabilities between the joint capabilities of each channel. If this exists then set both channels this codec.

    Ryan

  • I think the order or elements is relevant:

    [100]
    disallow=all allow=ulaw allow=g722
    or
    [100]
    allow=!all,ulaw,g722

    should work.

    jg

  • I see, you do want something like picking g722 provided there is no transcoding. Because Asterisk is a B2BUA it can transcode, so it would choose g722 where the other party is doing g711.

    For known parties, maybe one could change the SIP configuration on the fly using the Asterisk realtime engine, or modify the settings of the phone with an http request. Generally, an Asterisk configuration option like “prioritize_matching_codecs” would be needed, but I don’t think this is very useful. In this case there should also be all sound files available in g722. Even if you have them, some channels might still be silent as sometimes users choose to get MOH, for example, from the phone itself. Phones usually store sound files in a single format assuming that somebody else is able to transcode if necessary.

    Please correct me, if my description is incorrect.

    jg

  • If I choose that order and the phone supports both ulaw and g722 only ulaw will be used. I want to use g722 when available on both devices, fallback to ulaw without transcoding if both devices support it, or transcode if only one device supports ulaw.

    I looked at the code more and here is what happens. Device 100 dials 101. The sip_new function is called and AST_CODEC_CHOOSE g722 is set as the read/write format.

    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7911 sip_new:
    *** Our native formats are (g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7912 sip_new:
    *** Joint capabilities are (ulaw|g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7913 sip_new:
    *** Our capabilities are (ulaw|g722)
    [2013-12-14 22:51:59] DEBUG[25200][C-0000004d]: chan_sip.c:7914 sip_new:
    *** AST_CODEC_CHOOSE formats are g722

    Dial 101 is executed in the dialplan, sip_request_call is called, which in turn calls sip_new. The AST_CODEC_CHOOSE g722 from above becomes the incoming preferred format. We can only have one preferred format as sip_request_call takes in struct ast_format_cap *cap.

    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7911 sip_new:
    *** Our native formats are (ulaw)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7912 sip_new:
    *** Joint capabilities are (nothing)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7913 sip_new:
    *** Our capabilities are (ulaw)
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7914 sip_new:
    *** AST_CODEC_CHOOSE formats are ulaw
    [2013-12-14 22:51:59] DEBUG[27830][C-0000004d]: chan_sip.c:7916 sip_new:
    *** Our preferred formats from the incoming channel are (g722)

    Asterisk tries to find a common codec between this channels capabilities and the incoming channel preferred format. Of course there are none (g722
    and ulaw don’t match) so we pick ulaw and transcode. What I am proposing is Asterisk passes fallback formats to sip_request_call. If the joint capabilities are none, then check the fallback formats. In this case it would be ulaw and ulaw. If there is a match switch the incoming channel to that format (ulaw) and AST_CODEC_CHOOSE would be ulaw this for channel. However I’m not sure how to make this change as I don’t know my way around the interaction with the Asterisk core and the channels.

    Ryan

  • You are correct. Your idea of the prioritize_matching_codecs option is what I am looking for. Yes Asterisk can transcode, but why transcode when you don’t need to. If the phone is advertising both formats it should support them. If the phone only supports local MOH in one format then the phone should only advertise that format.

    If Answer and Playback are called first then the format would have already been sent back in the 200 OK and Asterisk would transcode when Dial is called. If Dial is called first, change the format for the 200 OK and use it for the rest of the call. I haven’t looked into what happens with transfers.

    The idea comes from the following setup. I have 450 users on a FreePBX /
    Asterisk server with a Sangoma transcoding card. However I am limited in the number of sessions. I also have a number of smaller 10-50 user deployments without transcoding cards.

    Remote users have phones with g729
    Local users have phones with g722,ulaw,g729
    SIP Trunks with ulaw,g729
    PRIs with ulaw

    Remote to local should use g729
    Local to local should use g722
    Remote to SIP trunk should use g729
    Local to SIP trunk should use ulaw Local to PRI should use ulaw Remote to PRI would transcode g729 to ulaw

    If I set these codecs on the devices depending on which side initiates that call transcoding occurs more often than I would like. I could reverse the codec order, however a lower bandwidth codec is chosen in cases where I
    would prefer a higher bandwidth codec.

    I looked at this a year ago on Asterisk 1.8 and ended up using ulaw for everything but remote phones. The remote phones end up transcoding g729 to ulaw for most calls.

    Ryan

  • But things may change during a call or you are stuck with whatever the phone uses for its MOH, which only some people use. A lot. You need to consider SIP INVITEs as well as Asterisk features (DTMF signals). Some time ago I had a problem with a codec mismatch when only Local channels (Asterisk features uses them)
    appeared to be involved. Is it possible to let the Sangoma card work only on the most demanding codecs? This requires some analysis to estimate the benefits. Another question is whether the user phones are provisioned or not. If provisioned, then you are the maker of rules.

    jg

  • Most users have both a desk Polycom phone and a soft phone on their mobile device or laptop. I don’t have control over how the soft phones are provisioned on mobile devices. I’ve found a workaround that prevents transcoding for outbound calls.

    remote phone allow=g729

    local phone allow=ulaw&g729

    trunk allow=ulaw&g729

    In FreePBX extensions_custom.conf I’ve added the following. This tries to force the outbound channel to match the inbound channel’s format.

    [macro-dialout-trunk-predial-hook]
    exten =>
    s,1,Set(_SIP_CODEC_OUTBOUND=${CHANNEL(audionativeformat):1:$[${LEN(${CHANNEL(audionativeformat)})}-2]})

    Remote to local g729 pass through Local to remote g729 transcoding Local to trunk ulaw pass through Remote to trunk g729 pass through (addressed by the dialout-trunk-predial-hook)
    Trunk to local ulaw pass through Trunk to remote g729 transcoding

    Alternatively I could set trunk allow=g729,ulaw, which would prevent transcoding for all inbound calls. Outbound from the local phone would use the hook to change to ulaw.

    I still don’t have a way to enable the higher quality g722 codec for internal use without making a transcoding mess. Maybe Asterisk 12 with pjsip will have a better solution.

    Ryan

  • Currently, I am no longer using g722 anymore for production setups. I had a some SIP-Phone combinations (not Polycom, not Digium) where there were problems with the mean volume when transcoding occured.

  • I have had the issue for years. The problem is that Asterisk developers are removed from the business. We desperately need simple way to eliminate transcoding when unnecessary. Transcoding brings a server to its knees. It is a very simple new setting in sip.conf prioritize_matching_codecs=yes I vote for this new feature. However, I don’t have the expertise to write a patch. I would say that only Digium developers could attempt to do this without disrupting the code too much. I also tried to migrate to PJSIP, but had to go back when I realized there was no channel variable contaning the inbound IP address. In general, any channel hast to provide the information to the dialplan, somehow, otherwise we cannot do business. I hope the PJSIP integration matures soon.

  • Maybe have a look at FreeSWITCH. It’s extremely flexible so may offer what you want to do.

    Regards, Patrick