[Home]

Summary:ASTERISK-25166: No audio when using direct media and a codec with a dynamic payload
Reporter:Kevin Harwell (kharwell)Labels:
Date Opened:2015-06-16 11:52:13Date Closed:
Priority:MajorRegression?No
Status:Open/NewComponents:Channels/chan_sip/CodecHandling Resources/res_pjsip
Versions:13.4.0 Frequency of
Occurrence
Constant
Related
Issues:
is duplicated byASTERISK-25862 No support for dynamic payload types in direct media
is related toASTERISK-27056 codec_opus responds with incorrect RTP Payload Type
is related toASTERISK-17410 Video dynamic RTP payload type negotiation incorrect when directmedia enabled
Environment:Attachments:( 0) 11-sip.log.txt
( 1) 13-res_pjsip.log.txt
( 2) 13-sip.log.txt
( 3) pjsip.conf
( 4) sip.conf
Description:I was able to duplicate this issue in Asterisk 11 (sip) and 13 (sip and res_pjsip).

If two endpoints are configured to use a codec with a dynamic payload and that payload number is something different than what Asterisk expects for the given codec then when using direct media the wrong payload is sent in the SDP of the reinvites. This results in no audio being heard.

Steps to reproduce:
1. Using chan_sip or res_pjsip configure two endpoints to use direct media and only allow a codec with a dynamic payload.
2. Make a call and either one way or no audio heard.

Note: I used g726 as the allowed codec, but you also have to make sure the payload being sent to Asterisk from the phone is different that what Asterisk uses for the payload type (111 in this case). The cisco phone I had allowed me to configure the payload numbers for g726. I also had an Aastra phone that sent g726 out with a different payload number (115) and I believe Linphone uses a different number as well.
Comments:By: Richard Mudgett (rmudgett) 2015-07-31 20:43:39.901-0500

The patches currently up on gerrit for the master branch lay the necessary ground work to actually fix the direct media dynamic payload type issue.

What is needed to get the issue fixed is a potential multi-step negotiation series.  The first step is to reINVITE the bridge peers to send media directly to each other after exchanging the payload types.  When the reINVITE transactions complete, the updated payload types need to be reexamined to see if they are compatible.  If they aren't compatible then it needs to be determined which side should get another reINVITE with updated payload types from the peer.

# Use ast_rtp_codecs_payloads_xover() to put the tx mapping of c0 into the rx mapping of c1 and vice versa.
# When the reINVITEs of both channels complete, compare the tx mapping of c0 with the rx mapping of c1 and vice versa.  If they are different then the mappings are incompatible and another reINVITE is needed by one channel or the other.  The below pseudo code gives a rough idea of what should need to be done.

{noformat}
function bool check_if_needs_updating(ast_channel c0, ast_channel c1, ast_rtp_codecs rtp0, ast_rtp_codecs rtp1)
if rtp0-rx != rtp1-tx
/* Payload types from c0 not compatible toward c1 */
if rtp0-rx != rtp0-tx
/* c0 not following RFC3264 6.1 SHOULD use requested values in answer */
return TRUE /* rtp0-rx needs updating */
else /* rtp0-rx == rtp0-tx */
if rtp1-rx == rtp1-tx
/*
* uniqueids should never be the same.
* It sort of violates the premise of uniqueness
*/
if strcmp(c0-uniqueid, c1-uniqueid) < 0
return TRUE /* rtp0-rx needs updating */
else
return TRUE /* rtp0-rx needs updating */
return FALSE

/*
* A queued NULL frame can be used to wake up the native bridge
* to check if the direct media reINVITE's have completed.
*/
native_rtp_bridge_write()
   if direct-media not established
&& reINVITEs have completed on both native channels
read-lock rtp0 and rtp1
   c0-needs-update = check_if_needs_updating(c0, c1, rtp0, rtp1)
   c1-needs-update = check_if_needs_updating(c1, c0, rtp1, rtp0)
unlock rtp0 and rtp1
if c0-needs-update
   Mark c0 reinvite not completed
   ast_rtp_codecs_payloads_xover(rtp1, rtp0)
   glue0->update_peer(c0)
if c1-needs-update
   Mark c1 reinvite not completed
   ast_rtp_codecs_payloads_xover(rtp0, rtp1)
   glue1->update_peer(c1)
if !c0-needs-update && !c1-needs-update
Mark direct-media established

return ast_bridge_queue_everyone_else()
{noformat}


By: Thomas Sevestre (to) 2019-03-12 10:44:54.250-0500

Hello, Is this going to be merged in asterisk 13 ?


By: Joshua C. Colp (jcolp) 2019-03-12 11:04:59.764-0500

All open changes were merged to the best of my knowledge at the time, but the core issue has not been resolved.