<p>Florentin Mayer has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/17731">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_sdp_rtp: Preserve order of RTP codecs<br><br>The ast_rtp_codecs_payloads functions do not preserve the order in which<br>the payloads were specified on an incoming SDP media line. This leads to<br>a problem with the codec negotiation functionality, as the format<br>capabilities of the stream are extracted from the ast_rtp_codecs. This<br>commit moves the ast_rtp_codec to ast_format conversion to the place<br>where the order is still known.<br><br>ASTERISK-28863<br>ASTERISK-29320<br><br>Change-Id: I3aabcfed3f379c36654f59c1872c313d0cb57e25<br>---<br>M res/res_pjsip_sdp_rtp.c<br>1 file changed, 20 insertions(+), 10 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/31/17731/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c</span><br><span>index ae200a7..cad2c01 100644</span><br><span>--- a/res/res_pjsip_sdp_rtp.c</span><br><span>+++ b/res/res_pjsip_sdp_rtp.c</span><br><span>@@ -313,13 +313,14 @@</span><br><span> }</span><br><span> </span><br><span> static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs,</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ast_sip_session_media *session_media)</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ast_sip_session_media *session_media, struct ast_format_cap *astformats)</span><br><span> {</span><br><span>         pjmedia_sdp_attr *attr;</span><br><span>      pjmedia_sdp_rtpmap *rtpmap;</span><br><span>  pjmedia_sdp_fmtp fmtp;</span><br><span>       struct ast_format *format;</span><br><span>   int i, num = 0, tel_event = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        int payload = 0;</span><br><span>     char name[256];</span><br><span>      char media[20];</span><br><span>      char fmt_param[256];</span><br><span>@@ -329,10 +330,20 @@</span><br><span> </span><br><span>     ast_rtp_codecs_payloads_initialize(codecs);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       ast_format_cap_remove_by_type(astformats, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         /* Iterate through provided formats */</span><br><span>       for (i = 0; i < stream->desc.fmt_count; ++i) {</span><br><span>                 /* The payload is kept as a string for things like t38 but for video it is always numerical */</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+            payload = pj_strtoul(&stream->desc.fmt[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_rtp_codecs_payloads_set_m_type(codecs, NULL, payload);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Fill the ast_format_cap struct in the correct order */</span><br><span style="color: hsl(120, 100%, 40%);">+             if ((format = ast_rtp_codecs_get_payload_format(codecs, payload))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_format_cap_append(astformats, format, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                 ao2_ref(format, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          /* Look for the optional rtpmap attribute */</span><br><span>                 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {</span><br><span>                       continue;</span><br><span>@@ -350,7 +361,7 @@</span><br><span> </span><br><span>          ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));</span><br><span>                ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-                      pj_strtoul(&stream->desc.fmt[i]), media, name, options, rtpmap->clock_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+                        payload, media, name, options, rtpmap->clock_rate);</span><br><span>               /* Look for an optional associated fmtp attribute */</span><br><span>                 if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {</span><br><span>                  continue;</span><br><span>@@ -370,9 +381,11 @@</span><br><span>                             format_parsed = ast_format_parse_sdp_fmtp(format, fmt_param);</span><br><span>                                if (format_parsed) {</span><br><span>                                         ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed);</span><br><span style="color: hsl(120, 100%, 40%);">+                                    ast_format_cap_append(astformats, format_parsed, 0);</span><br><span>                                         ao2_ref(format_parsed, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+                           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ast_format_cap_append(astformats, format, 0);</span><br><span>                                }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>                            ao2_ref(format, -1);</span><br><span>                         }</span><br><span>            }</span><br><span>@@ -398,6 +411,7 @@</span><br><span>              unsigned long framing = pj_strtoul(pj_strltrim(&attr->value));</span><br><span>                if (framing && session->endpoint->media.rtp.use_ptime) {</span><br><span>                       ast_rtp_codecs_set_framing(codecs, framing);</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_format_cap_set_framing(astformats, framing);</span><br><span>             }</span><br><span>    }</span><br><span> </span><br><span>@@ -442,7 +456,6 @@</span><br><span>  struct ast_format_cap *incoming_call_offer_cap;</span><br><span>      struct ast_format_cap *remote;</span><br><span>       struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT;</span><br><span style="color: hsl(0, 100%, 40%);">-        int fmts = 0;</span><br><span>        SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));</span><br><span> </span><br><span> </span><br><span>@@ -454,8 +467,7 @@</span><br><span>   }</span><br><span> </span><br><span>        /* Get the peer's capabilities*/</span><br><span style="color: hsl(0, 100%, 40%);">-    get_codecs(session, stream, &codecs, session_media);</span><br><span style="color: hsl(0, 100%, 40%);">-        ast_rtp_codecs_payload_formats(&codecs, remote, &fmts);</span><br><span style="color: hsl(120, 100%, 40%);">+       get_codecs(session, stream, &codecs, session_media, remote);</span><br><span> </span><br><span>         incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(</span><br><span>             session, session_media->type, remote);</span><br><span>@@ -493,7 +505,6 @@</span><br><span>      RAII_VAR(struct ast_format_cap *, joint, NULL, ao2_cleanup);</span><br><span>         enum ast_media_type media_type = session_media->type;</span><br><span>     struct ast_rtp_codecs codecs = AST_RTP_CODECS_NULL_INIT;</span><br><span style="color: hsl(0, 100%, 40%);">-        int fmts = 0;</span><br><span>        int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&</span><br><span>                 ast_format_cap_count(session->direct_media_cap);</span><br><span>  int dsp_features = 0;</span><br><span>@@ -516,8 +527,7 @@</span><br><span>  }</span><br><span> </span><br><span>        /* get the capabilities on the peer */</span><br><span style="color: hsl(0, 100%, 40%);">-  get_codecs(session, stream, &codecs,  session_media);</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);</span><br><span style="color: hsl(120, 100%, 40%);">+ get_codecs(session, stream, &codecs, session_media, peer);</span><br><span> </span><br><span>   /* get the joint capabilities between peer and endpoint */</span><br><span>   ast_format_cap_get_compatible(caps, peer, joint);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/17731">change 17731</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/17731"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I3aabcfed3f379c36654f59c1872c313d0cb57e25 </div>
<div style="display:none"> Gerrit-Change-Number: 17731 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Florentin Mayer <f.mayer@commend.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>