Changeset 3837


Ignore:
Timestamp:
Oct 23, 2011 6:59:48 AM (8 years ago)
Author:
nanang
Message:

Re #1300: Implemented symmetric payload type in generating SDP answer in SDP negotiator.
This should work for all codecs, audio & video. Can be disabled at compile-time
using PJMEDIA_SDP_NEG_REWRITE_ANSWER_PT macro setting.

Location:
pjproject/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/config.h

    r3835 r3837  
    621621 
    622622/** 
     623 * This specifies if the SDP negotiator should rewrite answer payload 
     624 * type numbers to use the same payload type numbers as the remote offer 
     625 * for all matched codecs. 
     626 * 
     627 * Default is 1 (yes) 
     628 */ 
     629#ifndef PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT 
     630#   define PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT          1 
     631#endif 
     632 
     633 
     634/** 
    623635 * Support for sending and decoding RTCP port in SDP (RFC 3605). 
    624636 * Default is equal to PJMEDIA_ADVERTISE_RTCP setting. 
  • pjproject/trunk/pjmedia/include/pjmedia/stream.h

    r3664 r3837  
    111111    pjmedia_codec_param *param;     /**< Optional codec param.              */ 
    112112    unsigned            tx_pt;      /**< Outgoing codec paylaod type.       */ 
     113    unsigned            rx_pt;      /**< Incoming codec paylaod type.       */ 
    113114    unsigned            tx_maxptime;/**< Outgoing codec max ptime.          */ 
    114115    int                 tx_event_pt;/**< Outgoing pt for telephone-events.  */ 
  • pjproject/trunk/pjmedia/src/pjmedia/sdp_neg.c

    r3714 r3837  
    11211121} 
    11221122 
     1123 
     1124/* Internal function to rewrite the format string in SDP attribute rtpmap 
     1125 * and fmtp. 
     1126 */ 
     1127PJ_INLINE(void) rewrite_pt(pj_pool_t *pool, pj_str_t *attr_val, 
     1128                           const pj_str_t *old_pt, const pj_str_t *new_pt) 
     1129{ 
     1130    int len_diff = new_pt->slen - old_pt->slen; 
     1131 
     1132    /* Note that attribute value should be null-terminated. */ 
     1133    if (len_diff > 0) { 
     1134        pj_str_t new_val; 
     1135        new_val.ptr = (char*)pj_pool_alloc(pool, attr_val->slen+len_diff+1); 
     1136        new_val.slen = attr_val->slen + len_diff; 
     1137        pj_memcpy(new_val.ptr + len_diff, attr_val->ptr, attr_val->slen + 1); 
     1138        *attr_val = new_val; 
     1139    } else if (len_diff < 0) { 
     1140        pj_memmove(attr_val->ptr, attr_val->ptr - len_diff, 
     1141                   attr_val->slen + len_diff + 1); 
     1142    } 
     1143    pj_memcpy(attr_val->ptr, new_pt->ptr, new_pt->slen); 
     1144} 
     1145 
     1146 
     1147/* Internal function to apply symmetric PT for the local answer. */ 
     1148static void apply_answer_symmetric_pt(pj_pool_t *pool, 
     1149                                      pjmedia_sdp_media *answer, 
     1150                                      unsigned pt_cnt, 
     1151                                      const pj_str_t pt_offer[], 
     1152                                      const pj_str_t pt_answer[]) 
     1153{ 
     1154    pjmedia_sdp_attr *a_tmp[PJMEDIA_MAX_SDP_ATTR]; 
     1155    unsigned i, a_tmp_cnt = 0; 
     1156 
     1157    /* Rewrite the payload types in the answer if different to 
     1158     * the ones in the offer. 
     1159     */ 
     1160    for (i = 0; i < pt_cnt; ++i) { 
     1161        pjmedia_sdp_attr *a; 
     1162 
     1163        /* Skip if the PTs are the same already, e.g: static PT. */ 
     1164        if (pj_strcmp(&pt_answer[i], &pt_offer[i]) == 0) 
     1165            continue; 
     1166 
     1167        /* Rewrite payload type in the answer to match to the offer */ 
     1168        pj_strdup(pool, &answer->desc.fmt[i], &pt_offer[i]); 
     1169 
     1170        /* Also update payload type in rtpmap */ 
     1171        a = pjmedia_sdp_media_find_attr2(answer, "rtpmap", &pt_answer[i]); 
     1172        if (a) { 
     1173            rewrite_pt(pool, &a->value, &pt_answer[i], &pt_offer[i]); 
     1174            /* Temporarily remove the attribute in case the new payload 
     1175             * type is being used by another format in the media. 
     1176             */ 
     1177            pjmedia_sdp_media_remove_attr(answer, a); 
     1178            a_tmp[a_tmp_cnt++] = a; 
     1179        } 
     1180 
     1181        /* Also update payload type in fmtp */ 
     1182        a = pjmedia_sdp_media_find_attr2(answer, "fmtp", &pt_answer[i]); 
     1183        if (a) { 
     1184            rewrite_pt(pool, &a->value, &pt_answer[i], &pt_offer[i]); 
     1185            /* Temporarily remove the attribute in case the new payload 
     1186             * type is being used by another format in the media. 
     1187             */ 
     1188            pjmedia_sdp_media_remove_attr(answer, a); 
     1189            a_tmp[a_tmp_cnt++] = a; 
     1190        } 
     1191    } 
     1192 
     1193    /* Return back 'rtpmap' and 'fmtp' attributes */ 
     1194    for (i = 0; i < a_tmp_cnt; ++i) 
     1195        pjmedia_sdp_media_add_attr(answer, a_tmp[i]); 
     1196} 
     1197 
     1198 
    11231199/* Try to match offer with answer. */ 
    11241200static pj_status_t match_offer(pj_pool_t *pool, 
     
    11381214    unsigned pt_answer_count = 0; 
    11391215    pj_str_t pt_answer[PJMEDIA_MAX_SDP_FMT]; 
     1216    pj_str_t pt_offer[PJMEDIA_MAX_SDP_FMT]; 
    11401217    pjmedia_sdp_media *answer; 
    11411218    const pjmedia_sdp_media *master, *slave; 
     
    12021279                    if (p == pt && pj_isdigit(*slave->desc.fmt[j].ptr)) { 
    12031280                        found_matching_codec = 1; 
     1281                        pt_offer[pt_answer_count] = slave->desc.fmt[j]; 
    12041282                        pt_answer[pt_answer_count++] = slave->desc.fmt[j]; 
    12051283                        break; 
     
    13011379                            } 
    13021380 
     1381                            pt_offer[pt_answer_count] =  
     1382                                                prefer_remote_codec_order? 
     1383                                                offer->desc.fmt[i]: 
     1384                                                offer->desc.fmt[j]; 
    13031385                            pt_answer[pt_answer_count++] =  
    13041386                                                prefer_remote_codec_order?  
     
    13261408                    /* Match */ 
    13271409                    found_matching_other = 1; 
     1410                    pt_offer[pt_answer_count] = prefer_remote_codec_order? 
     1411                                                offer->desc.fmt[i]: 
     1412                                                offer->desc.fmt[j]; 
    13281413                    pt_answer[pt_answer_count++] = prefer_remote_codec_order?  
    13291414                                                   preanswer->desc.fmt[j]: 
     
    13901475    } 
    13911476    answer->desc.fmt_count = pt_answer_count; 
     1477 
     1478#if PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT 
     1479    apply_answer_symmetric_pt(pool, answer, pt_answer_count, 
     1480                              pt_offer, pt_answer); 
     1481#endif 
    13921482 
    13931483    /* Update media direction. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r3664 r3837  
    22212221 
    22222222    status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,  
    2223                              info->fmt.pt, info, &stream->dec); 
     2223                             info->rx_pt, info, &stream->dec); 
    22242224    if (status != PJ_SUCCESS) 
    22252225        goto err_cleanup; 
     
    28352835        return PJMEDIA_EINVALIDPT; 
    28362836 
     2837    /* Get payload type for receiving direction */ 
     2838    si->rx_pt = pt; 
     2839 
    28372840    /* Get codec info. 
    28382841     * For static payload types, get the info from codec manager. 
     
    28942897 
    28952898    } else { 
     2899        pjmedia_codec_id codec_id; 
     2900        pj_str_t codec_id_st; 
     2901        const pjmedia_codec_info *p_info; 
    28962902 
    28972903        attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
     
    29082914        si->fmt.type = si->type; 
    29092915        si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
    2910         pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 
     2916        si->fmt.encoding_name = rtpmap->enc_name; 
    29112917        si->fmt.clock_rate = rtpmap->clock_rate; 
    29122918 
     
    29192925            si->fmt.channel_cnt = 1; 
    29202926        } 
     2927 
     2928        /* Normalize the codec info from codec manager. Note that the 
     2929         * payload type will be resetted to its default (it might have 
     2930         * been rewritten by the SDP negotiator to match to the remote 
     2931         * offer), this is intentional as currently some components may 
     2932         * prefer (or even require) the default PT in codec info. 
     2933         */ 
     2934        pjmedia_codec_info_to_id(&si->fmt, codec_id, sizeof(codec_id)); 
     2935 
     2936        i = 1; 
     2937        codec_id_st = pj_str(codec_id); 
     2938        status = pjmedia_codec_mgr_find_codecs_by_id(mgr, &codec_id_st, 
     2939                                                     &i, &p_info, NULL); 
     2940        if (status != PJ_SUCCESS) 
     2941            return status; 
     2942 
     2943        pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info)); 
    29212944 
    29222945        /* Determine payload type for outgoing channel, by finding 
     
    29662989 
    29672990    /* Get local fmtp for our decoder. */ 
    2968     pjmedia_stream_info_parse_fmtp(pool, local_m, si->fmt.pt, 
     2991    pjmedia_stream_info_parse_fmtp(pool, local_m, si->rx_pt, 
    29692992                                   &si->param->setting.dec_fmtp); 
    29702993 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c

    r3835 r3837  
    17831783    pt = pj_strtoul(&local_m->desc.fmt[0]); 
    17841784 
    1785     /* Get codec info. */ 
    1786     status = pjmedia_vid_codec_mgr_get_codec_info(mgr, pt, &p_info); 
    1787     if (status != PJ_SUCCESS) 
    1788         return status; 
    1789  
    1790     si->codec_info = *p_info; 
    1791  
    17921785    /* Get payload type for receiving direction */ 
    17931786    si->rx_pt = pt; 
    17941787 
    1795     /* Get payload type for transmitting direction */ 
     1788    /* Get codec info and payload type for transmitting direction. */ 
    17961789    if (pt < 96) { 
    1797         /* For static payload type, pt's are symetric */ 
     1790        /* For static payload types, get the codec info from codec manager. */ 
     1791        status = pjmedia_vid_codec_mgr_get_codec_info(mgr, pt, &p_info); 
     1792        if (status != PJ_SUCCESS) 
     1793            return status; 
     1794 
     1795        si->codec_info = *p_info; 
     1796 
     1797        /* Get payload type for transmitting direction. 
     1798         * For static payload type, pt's are symetric. 
     1799         */ 
    17981800        si->tx_pt = pt; 
    1799  
    18001801    } else { 
     1802        const pjmedia_sdp_attr *attr; 
     1803        pjmedia_sdp_rtpmap *rtpmap; 
     1804        pjmedia_codec_id codec_id; 
     1805        pj_str_t codec_id_st; 
    18011806        unsigned i; 
    18021807 
     
    18191824        if (si->tx_pt == 0xFFFF) 
    18201825            return PJMEDIA_EMISSINGRTPMAP; 
     1826 
     1827        /* For dynamic payload types, get codec name from the rtpmap */ 
     1828        attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
     1829                                           &local_m->desc.fmt[0]); 
     1830        if (attr == NULL) 
     1831            return PJMEDIA_EMISSINGRTPMAP; 
     1832 
     1833        status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 
     1834        if (status != PJ_SUCCESS) 
     1835            return status; 
     1836 
     1837        /* Then get the codec info from the codec manager */ 
     1838        pj_ansi_snprintf(codec_id, sizeof(codec_id), "%.*s/",  
     1839                         rtpmap->enc_name.slen, rtpmap->enc_name.ptr); 
     1840        codec_id_st = pj_str(codec_id); 
     1841        i = 1; 
     1842        status = pjmedia_vid_codec_mgr_find_codecs_by_id(mgr, &codec_id_st, 
     1843                                                         &i, &p_info, NULL); 
     1844        if (status != PJ_SUCCESS) 
     1845            return status; 
     1846 
     1847        si->codec_info = *p_info; 
    18211848    } 
    18221849 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_dump.c

    r3667 r3837  
    308308                             info.fmt.clock_rate / 1000); 
    309309            pj_ansi_snprintf(rx_info, sizeof(rx_info), "pt=%d,", 
    310                              info.fmt.pt); 
     310                             info.rx_pt); 
    311311            pj_ansi_snprintf(tx_info, sizeof(tx_info), "pt=%d, ptime=%d,", 
    312312                             info.tx_pt, 
Note: See TracChangeset for help on using the changeset viewer.