Changeset 3374 for pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
- Timestamp:
- Nov 25, 2010 9:27:06 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r3371 r3374 124 124 call->rem_srtp_use = PJMEDIA_SRTP_DISABLED; 125 125 call->local_hold = PJ_FALSE; 126 pj_bzero(&call->lock_codec, sizeof(call->lock_codec)); 126 127 } 127 128 … … 3061 3062 const pj_str_t STR_UPDATE = {"UPDATE", 6}; 3062 3063 const pjmedia_sdp_session *local_sdp = NULL, *new_sdp; 3063 const pjmedia_sdp_media *re m_m;3064 const pjmedia_sdp_media *ref_m; 3064 3065 pjmedia_sdp_media *m; 3065 3066 unsigned i, codec_cnt = 0; … … 3077 3078 pjmedia_sdp_neg_get_state(call->inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) 3078 3079 { 3079 return PJ _SUCCESS;3080 return PJMEDIA_SDPNEG_EINSTATE; 3080 3081 } 3081 3082 … … 3084 3085 call->inv->cause >= 200) 3085 3086 { 3086 return PJ_ SUCCESS;3087 return PJ_EINVALIDOP; 3087 3088 } 3088 3089 … … 3096 3097 return PJMEDIA_SDP_EINVER; 3097 3098 3099 /* Verify if media is deactivated */ 3100 if (call->media_st == PJSUA_CALL_MEDIA_NONE || 3101 call->media_st == PJSUA_CALL_MEDIA_ERROR || 3102 call->media_dir == PJMEDIA_DIR_NONE) 3103 { 3104 return PJ_EINVALIDOP; 3105 } 3106 3098 3107 PJ_LOG(3, (THIS_FILE, "Updating media session to use only one codec..")); 3099 3108 … … 3103 3112 */ 3104 3113 new_sdp = pjmedia_sdp_session_clone(call->inv->pool_prov, local_sdp); 3105 rem_m = local_sdp->media[call->audio_idx];3106 3114 m = new_sdp->media[call->audio_idx]; 3115 ref_m = local_sdp->media[call->audio_idx]; 3116 pj_assert(ref_m->desc.port); 3107 3117 codec_cnt = 0; 3108 3118 i = 0; … … 3126 3136 } 3127 3137 3128 /* Last check if SDP trully needs to be u dpated. It is possible that OA3129 * negotiations have completed and SDP has changed but remote didn't3130 * increase it's SDP version.3138 /* Last check if SDP trully needs to be updated. It is possible that OA 3139 * negotiations have completed and SDP has changed but we didn't 3140 * increase the SDP version (should not happen!). 3131 3141 */ 3132 if (rem_m->desc.fmt_count == m->desc.fmt_count || 3133 rem_m->desc.port == 0 || m->desc.port == 0) 3134 { 3142 if (ref_m->desc.fmt_count == m->desc.fmt_count) 3135 3143 return PJ_SUCCESS; 3136 }3137 3144 3138 3145 /* Send UPDATE or re-INVITE */ … … 3180 3187 { 3181 3188 pjsip_inv_session *inv = call->inv; 3182 const pjmedia_sdp_session *local_sdp; 3183 const pjmedia_sdp_session *remote_sdp; 3184 const pjmedia_sdp_media *rem_m; 3189 const pjmedia_sdp_session *local_sdp, *remote_sdp; 3190 const pjmedia_sdp_media *rem_m, *loc_m; 3185 3191 unsigned codec_cnt=0, i; 3186 3192 pj_time_val delay = {0, 0}; 3193 const pj_str_t st_update = {"UPDATE", 6}; 3187 3194 pj_status_t status; 3188 3189 if (!pjmedia_sdp_neg_was_answer_remote(inv->neg))3190 return PJ_SUCCESS;3191 3192 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);3193 if (status != PJ_SUCCESS)3194 return status;3195 status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);3196 if (status != PJ_SUCCESS)3197 return status;3198 3199 PJ_ASSERT_RETURN(call->audio_idx>=0 &&3200 call->audio_idx < (int)remote_sdp->media_count,3201 PJ_EINVALIDOP);3202 3203 rem_m = remote_sdp->media[call->audio_idx];3204 3205 /* Check if media is disabled or only one format in the answer. */3206 if (rem_m->desc.port==0 || rem_m->desc.fmt_count==1)3207 return PJ_SUCCESS;3208 3209 /* Count the formats in the answer. */3210 for (i=0; i<rem_m->desc.fmt_count && codec_cnt <= 1; ++i) {3211 if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[i]))3212 ++codec_cnt;3213 }3214 3215 if (codec_cnt <= 1) {3216 /* Answer contains single codec. */3217 return PJ_SUCCESS;3218 }3219 3220 PJ_LOG(3, (THIS_FILE, "Got answer with multiple codecs, scheduling "3221 "updating media session to use only one codec.."));3222 3223 call->lock_codec.sdp_ver = local_sdp->origin.version;3224 call->lock_codec.retry_cnt = 0;3225 3195 3226 3196 /* Stop lock codec timer, if it is active */ … … 3230 3200 call->lock_codec.reinv_timer.id = PJ_FALSE; 3231 3201 } 3202 3203 /* Skip this if we are the answerer */ 3204 if (!inv->neg || !pjmedia_sdp_neg_was_answer_remote(inv->neg)) { 3205 return PJ_SUCCESS; 3206 } 3207 3208 /* Skip this if the media is inactive or error */ 3209 if (call->media_st == PJSUA_CALL_MEDIA_NONE || 3210 call->media_st == PJSUA_CALL_MEDIA_ERROR || 3211 call->media_dir == PJMEDIA_DIR_NONE) 3212 { 3213 return PJ_SUCCESS; 3214 } 3215 3216 /* Delay this when the SDP negotiation done in call state EARLY and 3217 * remote does not support UPDATE method. 3218 */ 3219 if (inv->state == PJSIP_INV_STATE_EARLY && 3220 pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &st_update)!= 3221 PJSIP_DIALOG_CAP_SUPPORTED) 3222 { 3223 call->lock_codec.pending = PJ_TRUE; 3224 return PJ_SUCCESS; 3225 } 3226 3227 status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp); 3228 if (status != PJ_SUCCESS) 3229 return status; 3230 status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp); 3231 if (status != PJ_SUCCESS) 3232 return status; 3233 3234 PJ_ASSERT_RETURN(call->audio_idx>=0 && 3235 call->audio_idx < (int)remote_sdp->media_count, 3236 PJ_EINVALIDOP); 3237 3238 rem_m = remote_sdp->media[call->audio_idx]; 3239 loc_m = local_sdp->media[call->audio_idx]; 3240 3241 /* Verify that media must be active. */ 3242 pj_assert(loc_m->desc.port && rem_m->desc.port); 3243 3244 /* Count the formats in the answer. */ 3245 if (rem_m->desc.fmt_count==1) { 3246 codec_cnt = 1; 3247 } else { 3248 for (i=0; i<rem_m->desc.fmt_count && codec_cnt <= 1; ++i) { 3249 if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[i])) 3250 ++codec_cnt; 3251 } 3252 } 3253 if (codec_cnt <= 1) { 3254 /* Answer contains single codec. */ 3255 call->lock_codec.retry_cnt = 0; 3256 return PJ_SUCCESS; 3257 } 3258 3259 /* Remote keeps answering with multiple codecs, let's just give up 3260 * locking codec to avoid infinite retry loop. 3261 */ 3262 if (++call->lock_codec.retry_cnt > LOCK_CODEC_MAX_RETRY) 3263 return PJ_SUCCESS; 3264 3265 PJ_LOG(3, (THIS_FILE, "Got answer with multiple codecs, scheduling " 3266 "updating media session to use only one codec..")); 3267 3268 call->lock_codec.sdp_ver = local_sdp->origin.version; 3232 3269 3233 3270 /* Can't send UPDATE or re-INVITE now, so just schedule it immediately. … … 3277 3314 pj_gettimeofday(&call->conn_time); 3278 3315 3279 /* Ticket #476, locking a codec in the media session. */ 3280 { 3316 /* See if lock codec was pended as media update was done in the 3317 * EARLY state and remote does not support UPDATE. 3318 */ 3319 if (call->lock_codec.pending) { 3281 3320 pj_status_t status; 3282 3321 status = lock_codec(call); 3283 3322 if (status != PJ_SUCCESS) { 3284 3323 pjsua_perror(THIS_FILE, "Unable to lock codec", status); 3285 } 3324 } 3325 call->lock_codec.pending = PJ_FALSE; 3286 3326 } 3287 3288 3327 break; 3289 3328 case PJSIP_INV_STATE_DISCONNECTED: … … 3516 3555 const pjmedia_sdp_session *local_sdp; 3517 3556 const pjmedia_sdp_session *remote_sdp; 3518 const pj_str_t st_update = {"UPDATE", 6};3557 //const pj_str_t st_update = {"UPDATE", 6}; 3519 3558 3520 3559 PJSUA_LOCK(); … … 3588 3627 } 3589 3628 3590 /* Ticket #476, handle the case of early media and remote support UPDATE */ 3591 if (inv->state == PJSIP_INV_STATE_EARLY && 3592 pjmedia_sdp_neg_was_answer_remote(inv->neg) && 3593 pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &st_update)== 3594 PJSIP_DIALOG_CAP_SUPPORTED) 3595 { 3596 status = lock_codec(call); 3597 if (status != PJ_SUCCESS) { 3598 pjsua_perror(THIS_FILE, "Unable to lock codec", status); 3599 } 3600 } else if (inv->state == PJSIP_INV_STATE_CONFIRMED && 3601 call->media_st == PJSUA_CALL_MEDIA_ACTIVE) 3602 { 3603 /* https://trac.pjsip.org/repos/ticket/1149 */ 3604 status = lock_codec(call); 3605 if (status != PJ_SUCCESS) { 3606 pjsua_perror(THIS_FILE, "Unable to lock codec", status); 3607 } 3629 /* Ticket #476: make sure only one codec is specified in the answer. */ 3630 status = lock_codec(call); 3631 if (status != PJ_SUCCESS) { 3632 pjsua_perror(THIS_FILE, "Unable to lock codec", status); 3608 3633 } 3609 3634
Note: See TracChangeset
for help on using the changeset viewer.