Ignore:
Timestamp:
Mar 22, 2012 9:56:52 AM (12 years ago)
Author:
bennylp
Message:

Re: #1463 (Third party media support). Tnitial work and it works, tested on Linux. Details:

  • add PJSUA_MEDIA_HAS_PJMEDIA macro
  • move pjmedia specific implementation in pjsua_media.c and pjsua_call.c into pjsua_aud.c
  • add pjsip-apps/src/third_party_media sample containing:
    • alt_pjsua_aud.c
    • alt_pjsua_vid.c
  • moved pjmedia_vid_stream_info_from_sdp() into pjmedia/vid_stream_info.c
  • moved pjmedia_stream_info_from_sdp() into pjmedia/stream_info.c
  • misc: fixed mips_test.c if codecs are disabled
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r3917 r3982  
    27942794} 
    27952795 
    2796  
    2797 static const pj_str_t ID_AUDIO = { "audio", 5}; 
    2798 static const pj_str_t ID_IN = { "IN", 2 }; 
    2799 static const pj_str_t ID_IP4 = { "IP4", 3}; 
    2800 static const pj_str_t ID_IP6 = { "IP6", 3}; 
    2801 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 
    2802 static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 
    2803 //static const pj_str_t ID_SDP_NAME = { "pjmedia", 7 }; 
    2804 static const pj_str_t ID_RTPMAP = { "rtpmap", 6 }; 
    2805 static const pj_str_t ID_TELEPHONE_EVENT = { "telephone-event", 15 }; 
    2806  
    2807 static const pj_str_t STR_INACTIVE = { "inactive", 8 }; 
    2808 static const pj_str_t STR_SENDRECV = { "sendrecv", 8 }; 
    2809 static const pj_str_t STR_SENDONLY = { "sendonly", 8 }; 
    2810 static const pj_str_t STR_RECVONLY = { "recvonly", 8 }; 
    2811  
    2812  
    2813 /* 
    2814  * Internal function for collecting codec info and param from the SDP media. 
    2815  */ 
    2816 static pj_status_t get_audio_codec_info_param(pjmedia_stream_info *si, 
    2817                                               pj_pool_t *pool, 
    2818                                               pjmedia_codec_mgr *mgr, 
    2819                                               const pjmedia_sdp_media *local_m, 
    2820                                               const pjmedia_sdp_media *rem_m) 
    2821 { 
    2822     const pjmedia_sdp_attr *attr; 
    2823     pjmedia_sdp_rtpmap *rtpmap; 
    2824     unsigned i, fmti, pt = 0; 
    2825     pj_status_t status; 
    2826  
    2827     /* Find the first codec which is not telephone-event */ 
    2828     for ( fmti = 0; fmti < local_m->desc.fmt_count; ++fmti ) { 
    2829         pjmedia_sdp_rtpmap r; 
    2830  
    2831         if ( !pj_isdigit(*local_m->desc.fmt[fmti].ptr) ) 
    2832             return PJMEDIA_EINVALIDPT; 
    2833         pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
    2834  
    2835         if (pt < 96) { 
    2836             /* This is known static PT. Skip rtpmap checking because it is 
    2837              * optional. */ 
    2838             break; 
    2839         } 
    2840  
    2841         attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP, 
    2842                                            &local_m->desc.fmt[fmti]); 
    2843         if (attr == NULL) 
    2844             continue; 
    2845  
    2846         status = pjmedia_sdp_attr_get_rtpmap(attr, &r); 
    2847         if (status != PJ_SUCCESS) 
    2848             continue; 
    2849  
    2850         if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) != 0) 
    2851             break; 
    2852     } 
    2853     if ( fmti >= local_m->desc.fmt_count ) 
    2854         return PJMEDIA_EINVALIDPT; 
    2855  
    2856     /* Get payload type for receiving direction */ 
    2857     si->rx_pt = pt; 
    2858  
    2859     /* Get codec info. 
    2860      * For static payload types, get the info from codec manager. 
    2861      * For dynamic payload types, MUST get the rtpmap. 
    2862      */ 
    2863     if (pt < 96) { 
    2864         pj_bool_t has_rtpmap; 
    2865  
    2866         rtpmap = NULL; 
    2867         has_rtpmap = PJ_TRUE; 
    2868  
    2869         attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
    2870                                            &local_m->desc.fmt[fmti]); 
    2871         if (attr == NULL) { 
    2872             has_rtpmap = PJ_FALSE; 
    2873         } 
    2874         if (attr != NULL) { 
    2875             status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 
    2876             if (status != PJ_SUCCESS) 
    2877                 has_rtpmap = PJ_FALSE; 
    2878         } 
    2879  
    2880         /* Build codec format info: */ 
    2881         if (has_rtpmap) { 
    2882             si->fmt.type = si->type; 
    2883             si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
    2884             pj_strdup(pool, &si->fmt.encoding_name, &rtpmap->enc_name); 
    2885             si->fmt.clock_rate = rtpmap->clock_rate; 
    2886              
    2887 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 
    2888             /* The session info should have the actual clock rate, because  
    2889              * this info is used for calculationg buffer size, etc in stream  
    2890              */ 
    2891             if (si->fmt.pt == PJMEDIA_RTP_PT_G722) 
    2892                 si->fmt.clock_rate = 16000; 
    2893 #endif 
    2894  
    2895             /* For audio codecs, rtpmap parameters denotes the number of 
    2896              * channels. 
    2897              */ 
    2898             if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 
    2899                 si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 
    2900             } else { 
    2901                 si->fmt.channel_cnt = 1; 
    2902             } 
    2903  
    2904         } else {             
    2905             const pjmedia_codec_info *p_info; 
    2906  
    2907             status = pjmedia_codec_mgr_get_codec_info( mgr, pt, &p_info); 
    2908             if (status != PJ_SUCCESS) 
    2909                 return status; 
    2910  
    2911             pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info)); 
    2912         } 
    2913  
    2914         /* For static payload type, pt's are symetric */ 
    2915         si->tx_pt = pt; 
    2916  
    2917     } else { 
    2918         pjmedia_codec_id codec_id; 
    2919         pj_str_t codec_id_st; 
    2920         const pjmedia_codec_info *p_info; 
    2921  
    2922         attr = pjmedia_sdp_media_find_attr(local_m, &ID_RTPMAP,  
    2923                                            &local_m->desc.fmt[fmti]); 
    2924         if (attr == NULL) 
    2925             return PJMEDIA_EMISSINGRTPMAP; 
    2926  
    2927         status = pjmedia_sdp_attr_to_rtpmap(pool, attr, &rtpmap); 
    2928         if (status != PJ_SUCCESS) 
    2929             return status; 
    2930  
    2931         /* Build codec format info: */ 
    2932  
    2933         si->fmt.type = si->type; 
    2934         si->fmt.pt = pj_strtoul(&local_m->desc.fmt[fmti]); 
    2935         si->fmt.encoding_name = rtpmap->enc_name; 
    2936         si->fmt.clock_rate = rtpmap->clock_rate; 
    2937  
    2938         /* For audio codecs, rtpmap parameters denotes the number of 
    2939          * channels. 
    2940          */ 
    2941         if (si->type == PJMEDIA_TYPE_AUDIO && rtpmap->param.slen) { 
    2942             si->fmt.channel_cnt = (unsigned) pj_strtoul(&rtpmap->param); 
    2943         } else { 
    2944             si->fmt.channel_cnt = 1; 
    2945         } 
    2946  
    2947         /* Normalize the codec info from codec manager. Note that the 
    2948          * payload type will be resetted to its default (it might have 
    2949          * been rewritten by the SDP negotiator to match to the remote 
    2950          * offer), this is intentional as currently some components may 
    2951          * prefer (or even require) the default PT in codec info. 
    2952          */ 
    2953         pjmedia_codec_info_to_id(&si->fmt, codec_id, sizeof(codec_id)); 
    2954  
    2955         i = 1; 
    2956         codec_id_st = pj_str(codec_id); 
    2957         status = pjmedia_codec_mgr_find_codecs_by_id(mgr, &codec_id_st, 
    2958                                                      &i, &p_info, NULL); 
    2959         if (status != PJ_SUCCESS) 
    2960             return status; 
    2961  
    2962         pj_memcpy(&si->fmt, p_info, sizeof(pjmedia_codec_info)); 
    2963  
    2964         /* Determine payload type for outgoing channel, by finding 
    2965          * dynamic payload type in remote SDP that matches the answer. 
    2966          */ 
    2967         si->tx_pt = 0xFFFF; 
    2968         for (i=0; i<rem_m->desc.fmt_count; ++i) { 
    2969             unsigned rpt; 
    2970             pjmedia_sdp_attr *r_attr; 
    2971             pjmedia_sdp_rtpmap r_rtpmap; 
    2972  
    2973             rpt = pj_strtoul(&rem_m->desc.fmt[i]); 
    2974             if (rpt < 96) 
    2975                 continue; 
    2976  
    2977             r_attr = pjmedia_sdp_media_find_attr(rem_m, &ID_RTPMAP, 
    2978                                                  &rem_m->desc.fmt[i]); 
    2979             if (!r_attr) 
    2980                 continue; 
    2981  
    2982             if (pjmedia_sdp_attr_get_rtpmap(r_attr, &r_rtpmap) != PJ_SUCCESS) 
    2983                 continue; 
    2984  
    2985             if (!pj_stricmp(&rtpmap->enc_name, &r_rtpmap.enc_name) && 
    2986                 rtpmap->clock_rate == r_rtpmap.clock_rate) 
    2987             { 
    2988                 /* Found matched codec. */ 
    2989                 si->tx_pt = rpt; 
    2990  
    2991                 break; 
    2992             } 
    2993         } 
    2994  
    2995         if (si->tx_pt == 0xFFFF) 
    2996             return PJMEDIA_EMISSINGRTPMAP; 
    2997     } 
    2998  
    2999    
    3000     /* Now that we have codec info, get the codec param. */ 
    3001     si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param); 
    3002     status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt, 
    3003                                                  si->param); 
    3004  
    3005     /* Get remote fmtp for our encoder. */ 
    3006     pjmedia_stream_info_parse_fmtp(pool, rem_m, si->tx_pt, 
    3007                                    &si->param->setting.enc_fmtp); 
    3008  
    3009     /* Get local fmtp for our decoder. */ 
    3010     pjmedia_stream_info_parse_fmtp(pool, local_m, si->rx_pt, 
    3011                                    &si->param->setting.dec_fmtp); 
    3012  
    3013     /* Get the remote ptime for our encoder. */ 
    3014     attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
    3015                                   "ptime", NULL); 
    3016     if (attr) { 
    3017         pj_str_t tmp_val = attr->value; 
    3018         unsigned frm_per_pkt; 
    3019   
    3020         pj_strltrim(&tmp_val); 
    3021  
    3022         /* Round up ptime when the specified is not multiple of frm_ptime */ 
    3023         frm_per_pkt = (pj_strtoul(&tmp_val) +  
    3024                       si->param->info.frm_ptime/2) / 
    3025                       si->param->info.frm_ptime; 
    3026         if (frm_per_pkt != 0) { 
    3027             si->param->setting.frm_per_pkt = (pj_uint8_t)frm_per_pkt; 
    3028         } 
    3029     } 
    3030  
    3031     /* Get remote maxptime for our encoder. */ 
    3032     attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
    3033                                   "maxptime", NULL); 
    3034     if (attr) { 
    3035         pj_str_t tmp_val = attr->value; 
    3036  
    3037         pj_strltrim(&tmp_val); 
    3038         si->tx_maxptime = pj_strtoul(&tmp_val); 
    3039     } 
    3040  
    3041     /* When direction is NONE (it means SDP negotiation has failed) we don't 
    3042      * need to return a failure here, as returning failure will cause 
    3043      * the whole SDP to be rejected. See ticket #: 
    3044      *  http:// 
    3045      * 
    3046      * Thanks Alain Totouom  
    3047      */ 
    3048     if (status != PJ_SUCCESS && si->dir != PJMEDIA_DIR_NONE) 
    3049         return status; 
    3050  
    3051  
    3052     /* Get incomming payload type for telephone-events */ 
    3053     si->rx_event_pt = -1; 
    3054     for (i=0; i<local_m->attr_count; ++i) { 
    3055         pjmedia_sdp_rtpmap r; 
    3056  
    3057         attr = local_m->attr[i]; 
    3058         if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 
    3059             continue; 
    3060         if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 
    3061             continue; 
    3062         if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 
    3063             si->rx_event_pt = pj_strtoul(&r.pt); 
    3064             break; 
    3065         } 
    3066     } 
    3067  
    3068     /* Get outgoing payload type for telephone-events */ 
    3069     si->tx_event_pt = -1; 
    3070     for (i=0; i<rem_m->attr_count; ++i) { 
    3071         pjmedia_sdp_rtpmap r; 
    3072  
    3073         attr = rem_m->attr[i]; 
    3074         if (pj_strcmp(&attr->name, &ID_RTPMAP) != 0) 
    3075             continue; 
    3076         if (pjmedia_sdp_attr_get_rtpmap(attr, &r) != PJ_SUCCESS) 
    3077             continue; 
    3078         if (pj_strcmp(&r.enc_name, &ID_TELEPHONE_EVENT) == 0) { 
    3079             si->tx_event_pt = pj_strtoul(&r.pt); 
    3080             break; 
    3081         } 
    3082     } 
    3083  
    3084     return PJ_SUCCESS; 
    3085 } 
    3086  
    3087  
    3088  
    3089 /* 
    3090  * Create stream info from SDP media line. 
    3091  */ 
    3092 PJ_DEF(pj_status_t) pjmedia_stream_info_from_sdp( 
    3093                                            pjmedia_stream_info *si, 
    3094                                            pj_pool_t *pool, 
    3095                                            pjmedia_endpt *endpt, 
    3096                                            const pjmedia_sdp_session *local, 
    3097                                            const pjmedia_sdp_session *remote, 
    3098                                            unsigned stream_idx) 
    3099 { 
    3100     pjmedia_codec_mgr *mgr; 
    3101     const pjmedia_sdp_attr *attr; 
    3102     const pjmedia_sdp_media *local_m; 
    3103     const pjmedia_sdp_media *rem_m; 
    3104     const pjmedia_sdp_conn *local_conn; 
    3105     const pjmedia_sdp_conn *rem_conn; 
    3106     int rem_af, local_af; 
    3107     pj_sockaddr local_addr; 
    3108     pj_status_t status; 
    3109  
    3110      
    3111     /* Validate arguments: */ 
    3112     PJ_ASSERT_RETURN(pool && si && local && remote, PJ_EINVAL); 
    3113     PJ_ASSERT_RETURN(stream_idx < local->media_count, PJ_EINVAL); 
    3114     PJ_ASSERT_RETURN(stream_idx < remote->media_count, PJ_EINVAL); 
    3115  
    3116     /* Keep SDP shortcuts */ 
    3117     local_m = local->media[stream_idx]; 
    3118     rem_m = remote->media[stream_idx]; 
    3119  
    3120     local_conn = local_m->conn ? local_m->conn : local->conn; 
    3121     if (local_conn == NULL) 
    3122         return PJMEDIA_SDP_EMISSINGCONN; 
    3123  
    3124     rem_conn = rem_m->conn ? rem_m->conn : remote->conn; 
    3125     if (rem_conn == NULL) 
    3126         return PJMEDIA_SDP_EMISSINGCONN; 
    3127  
    3128     /* Media type must be audio */ 
    3129     if (pj_stricmp(&local_m->desc.media, &ID_AUDIO) != 0) 
    3130         return PJMEDIA_EINVALIMEDIATYPE; 
    3131  
    3132     /* Get codec manager. */ 
    3133     mgr = pjmedia_endpt_get_codec_mgr(endpt); 
    3134  
    3135     /* Reset: */ 
    3136  
    3137     pj_bzero(si, sizeof(*si)); 
    3138  
    3139 #if PJMEDIA_HAS_RTCP_XR && PJMEDIA_STREAM_ENABLE_XR 
    3140     /* Set default RTCP XR enabled/disabled */ 
    3141     si->rtcp_xr_enabled = PJ_TRUE; 
    3142 #endif 
    3143  
    3144     /* Media type: */ 
    3145     si->type = PJMEDIA_TYPE_AUDIO; 
    3146  
    3147     /* Transport protocol */ 
    3148  
    3149     /* At this point, transport type must be compatible,  
    3150      * the transport instance will do more validation later. 
    3151      */ 
    3152     status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,  
    3153                                        &local_m->desc.transport); 
    3154     if (status != PJ_SUCCESS) 
    3155         return PJMEDIA_SDPNEG_EINVANSTP; 
    3156  
    3157     if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) { 
    3158  
    3159         si->proto = PJMEDIA_TP_PROTO_RTP_AVP; 
    3160  
    3161     } else if (pj_stricmp(&local_m->desc.transport, &ID_RTP_SAVP) == 0) { 
    3162  
    3163         si->proto = PJMEDIA_TP_PROTO_RTP_SAVP; 
    3164  
    3165     } else { 
    3166  
    3167         si->proto = PJMEDIA_TP_PROTO_UNKNOWN; 
    3168         return PJ_SUCCESS; 
    3169     } 
    3170  
    3171  
    3172     /* Check address family in remote SDP */ 
    3173     rem_af = pj_AF_UNSPEC(); 
    3174     if (pj_stricmp(&rem_conn->net_type, &ID_IN)==0) { 
    3175         if (pj_stricmp(&rem_conn->addr_type, &ID_IP4)==0) { 
    3176             rem_af = pj_AF_INET(); 
    3177         } else if (pj_stricmp(&rem_conn->addr_type, &ID_IP6)==0) { 
    3178             rem_af = pj_AF_INET6(); 
    3179         } 
    3180     } 
    3181  
    3182     if (rem_af==pj_AF_UNSPEC()) { 
    3183         /* Unsupported address family */ 
    3184         return PJ_EAFNOTSUP; 
    3185     } 
    3186  
    3187     /* Set remote address: */ 
    3188     status = pj_sockaddr_init(rem_af, &si->rem_addr, &rem_conn->addr,  
    3189                               rem_m->desc.port); 
    3190     if (status != PJ_SUCCESS) { 
    3191         /* Invalid IP address. */ 
    3192         return PJMEDIA_EINVALIDIP; 
    3193     } 
    3194  
    3195     /* Check address family of local info */ 
    3196     local_af = pj_AF_UNSPEC(); 
    3197     if (pj_stricmp(&local_conn->net_type, &ID_IN)==0) { 
    3198         if (pj_stricmp(&local_conn->addr_type, &ID_IP4)==0) { 
    3199             local_af = pj_AF_INET(); 
    3200         } else if (pj_stricmp(&local_conn->addr_type, &ID_IP6)==0) { 
    3201             local_af = pj_AF_INET6(); 
    3202         } 
    3203     } 
    3204  
    3205     if (local_af==pj_AF_UNSPEC()) { 
    3206         /* Unsupported address family */ 
    3207         return PJ_SUCCESS; 
    3208     } 
    3209  
    3210     /* Set remote address: */ 
    3211     status = pj_sockaddr_init(local_af, &local_addr, &local_conn->addr,  
    3212                               local_m->desc.port); 
    3213     if (status != PJ_SUCCESS) { 
    3214         /* Invalid IP address. */ 
    3215         return PJMEDIA_EINVALIDIP; 
    3216     } 
    3217  
    3218     /* Local and remote address family must match */ 
    3219     if (local_af != rem_af) 
    3220         return PJ_EAFNOTSUP; 
    3221  
    3222     /* Media direction: */ 
    3223  
    3224     if (local_m->desc.port == 0 ||  
    3225         pj_sockaddr_has_addr(&local_addr)==PJ_FALSE || 
    3226         pj_sockaddr_has_addr(&si->rem_addr)==PJ_FALSE || 
    3227         pjmedia_sdp_media_find_attr(local_m, &STR_INACTIVE, NULL)!=NULL) 
    3228     { 
    3229         /* Inactive stream. */ 
    3230  
    3231         si->dir = PJMEDIA_DIR_NONE; 
    3232  
    3233     } else if (pjmedia_sdp_media_find_attr(local_m, &STR_SENDONLY, NULL)!=NULL) { 
    3234  
    3235         /* Send only stream. */ 
    3236  
    3237         si->dir = PJMEDIA_DIR_ENCODING; 
    3238  
    3239     } else if (pjmedia_sdp_media_find_attr(local_m, &STR_RECVONLY, NULL)!=NULL) { 
    3240  
    3241         /* Recv only stream. */ 
    3242  
    3243         si->dir = PJMEDIA_DIR_DECODING; 
    3244  
    3245     } else { 
    3246  
    3247         /* Send and receive stream. */ 
    3248  
    3249         si->dir = PJMEDIA_DIR_ENCODING_DECODING; 
    3250  
    3251     } 
    3252  
    3253     /* No need to do anything else if stream is rejected */ 
    3254     if (local_m->desc.port == 0) { 
    3255         return PJ_SUCCESS; 
    3256     } 
    3257  
    3258     /* If "rtcp" attribute is present in the SDP, set the RTCP address 
    3259      * from that attribute. Otherwise, calculate from RTP address. 
    3260      */ 
    3261     attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
    3262                                   "rtcp", NULL); 
    3263     if (attr) { 
    3264         pjmedia_sdp_rtcp_attr rtcp; 
    3265         status = pjmedia_sdp_attr_get_rtcp(attr, &rtcp); 
    3266         if (status == PJ_SUCCESS) { 
    3267             if (rtcp.addr.slen) { 
    3268                 status = pj_sockaddr_init(rem_af, &si->rem_rtcp, &rtcp.addr, 
    3269                                           (pj_uint16_t)rtcp.port); 
    3270             } else { 
    3271                 pj_sockaddr_init(rem_af, &si->rem_rtcp, NULL,  
    3272                                  (pj_uint16_t)rtcp.port); 
    3273                 pj_memcpy(pj_sockaddr_get_addr(&si->rem_rtcp), 
    3274                           pj_sockaddr_get_addr(&si->rem_addr), 
    3275                           pj_sockaddr_get_addr_len(&si->rem_addr)); 
    3276             } 
    3277         } 
    3278     } 
    3279      
    3280     if (!pj_sockaddr_has_addr(&si->rem_rtcp)) { 
    3281         int rtcp_port; 
    3282  
    3283         pj_memcpy(&si->rem_rtcp, &si->rem_addr, sizeof(pj_sockaddr)); 
    3284         rtcp_port = pj_sockaddr_get_port(&si->rem_addr) + 1; 
    3285         pj_sockaddr_set_port(&si->rem_rtcp, (pj_uint16_t)rtcp_port); 
    3286     } 
    3287  
    3288  
    3289     /* Get the payload number for receive channel. */ 
    3290     /* 
    3291        Previously we used to rely on fmt[0] being the selected codec, 
    3292        but some UA sends telephone-event as fmt[0] and this would 
    3293        cause assert failure below. 
    3294  
    3295        Thanks Chris Hamilton <chamilton .at. cs.dal.ca> for this patch. 
    3296  
    3297     // And codec must be numeric! 
    3298     if (!pj_isdigit(*local_m->desc.fmt[0].ptr) ||  
    3299         !pj_isdigit(*rem_m->desc.fmt[0].ptr)) 
    3300     { 
    3301         return PJMEDIA_EINVALIDPT; 
    3302     } 
    3303  
    3304     pt = pj_strtoul(&local_m->desc.fmt[0]); 
    3305     pj_assert(PJMEDIA_RTP_PT_TELEPHONE_EVENTS==0 || 
    3306               pt != PJMEDIA_RTP_PT_TELEPHONE_EVENTS); 
    3307     */ 
    3308  
    3309     /* Get codec info and param */ 
    3310     status = get_audio_codec_info_param(si, pool, mgr, local_m, rem_m); 
    3311  
    3312     /* Leave SSRC to random. */ 
    3313     si->ssrc = pj_rand(); 
    3314  
    3315     /* Set default jitter buffer parameter. */ 
    3316     si->jb_init = si->jb_max = si->jb_min_pre = si->jb_max_pre = -1; 
    3317  
    3318     return status; 
    3319 } 
    3320  
    33212796/* 
    33222797 * Send RTCP SDES. 
Note: See TracChangeset for help on using the changeset viewer.