- Timestamp:
- Dec 1, 2011 9:06:14 AM (13 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r3875 r3891 135 135 136 136 struct app_vid vid; 137 unsigned aud_cnt; 137 138 } app_config; 138 139 … … 403 404 cfg->vid.vcapture_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 404 405 cfg->vid.vrender_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV; 406 cfg->aud_cnt = 1; 405 407 } 406 408 … … 1456 1458 break; 1457 1459 case OPT_VIDEO: 1458 app_config.vid.vid_cnt = 1;1459 app_config.vid.in_auto_show = PJ_TRUE;1460 app_config.vid.out_auto_transmit = PJ_TRUE;1460 cfg->vid.vid_cnt = 1; 1461 cfg->vid.in_auto_show = PJ_TRUE; 1462 cfg->vid.out_auto_transmit = PJ_TRUE; 1461 1463 break; 1462 1464 case OPT_EXTRA_AUDIO: 1463 ++cur_acc->max_audio_cnt;1465 cfg->aud_cnt++; 1464 1466 break; 1465 1467 … … 1718 1720 if (acc_cfg->mwi_enabled) 1719 1721 pj_strcat2(result, "--mwi\n"); 1720 1721 /* Video & extra audio */1722 for (i=0; i<acc_cfg->max_video_cnt; ++i) {1723 pj_strcat2(result, "--video\n");1724 }1725 for (i=1; i<acc_cfg->max_audio_cnt; ++i) {1726 pj_strcat2(result, "--extra-audio\n");1727 }1728 1722 } 1729 1723 … … 1890 1884 1891 1885 pj_strcat2(&cfg, "\n#\n# Media settings:\n#\n"); 1886 1887 /* Video & extra audio */ 1888 for (i=0; i<config->vid.vid_cnt; ++i) { 1889 pj_strcat2(&cfg, "--video\n"); 1890 } 1891 for (i=1; i<config->aud_cnt; ++i) { 1892 pj_strcat2(&cfg, "--extra-audio\n"); 1893 } 1892 1894 1893 1895 /* SRTP */ … … 2576 2578 2577 2579 if (app_config.auto_answer > 0) { 2578 pjsua_call_answer(call_id, app_config.auto_answer, NULL, NULL); 2579 } 2580 2580 pjsua_call_setting call_opt; 2581 2582 pjsua_call_setting_default(&call_opt); 2583 call_opt.audio_cnt = app_config.aud_cnt; 2584 call_opt.video_cnt = app_config.vid.vid_cnt; 2585 2586 pjsua_call_answer2(call_id, &call_opt, app_config.auto_answer, NULL, NULL); 2587 } 2588 2581 2589 if (app_config.auto_answer < 200) { 2590 char notif_st[80] = {0}; 2591 2592 #if PJSUA_HAS_VIDEO 2593 if (call_info.rem_offerer && call_info.rem_video_cnt) { 2594 snprintf(notif_st, sizeof(notif_st), 2595 "To %s the video, type \"vid %s\" first, " 2596 "before answering the call!\n", 2597 (app_config.vid.vid_cnt? "reject":"accept"), 2598 (app_config.vid.vid_cnt? "disable":"enable")); 2599 } 2600 #endif 2601 2582 2602 PJ_LOG(3,(THIS_FILE, 2583 2603 "Incoming call for account %d!\n" 2604 "Media count: %d audio & %d video\n" 2605 "%s" 2584 2606 "From: %s\n" 2585 2607 "To: %s\n" 2586 2608 "Press a to answer or h to reject call", 2587 2609 acc_id, 2610 call_info.rem_audio_cnt, 2611 call_info.rem_video_cnt, 2612 notif_st, 2588 2613 call_info.remote_info.ptr, 2589 2614 call_info.local_info.ptr)); … … 2847 2872 pjsua_call_hangup(call_id, 500, &reason, NULL); 2848 2873 } 2874 2875 #if PJSUA_HAS_VIDEO 2876 /* Check if remote has just tried to enable video */ 2877 if (call_info.rem_offerer && call_info.rem_video_cnt) 2878 { 2879 int vid_idx; 2880 2881 /* Check if there is active video */ 2882 vid_idx = pjsua_call_get_vid_stream_idx(call_id); 2883 if (vid_idx == -1 || call_info.media[vid_idx].dir == PJMEDIA_DIR_NONE) { 2884 PJ_LOG(3,(THIS_FILE, 2885 "Just rejected incoming video offer on call %d" 2886 "use \"vid call add\" to enable video!", 2887 call_id)); 2888 } 2889 } 2890 #endif 2849 2891 } 2850 2892 … … 3423 3465 { 3424 3466 #if PJSUA_HAS_VIDEO 3467 pj_bool_t vid_enabled = (app_config.vid.vid_cnt > 0); 3468 3425 3469 puts("+=============================================================================+"); 3426 3470 puts("| Video commands: |"); 3427 3471 puts("| |"); 3428 3472 puts("| vid help Show this help screen |"); 3473 puts("| vid enable|disable Enable or disable video in next offer/answer |"); 3429 3474 puts("| vid acc show Show current account video settings |"); 3430 puts("| vid acc enable|disable Enable or disable video on current account |");3431 3475 puts("| vid acc autorx on|off Automatically show incoming video on/off |"); 3432 3476 puts("| vid acc autotx on|off Automatically offer video on/off |"); … … 3436 3480 puts("| vid call tx on|off N Enable/disable video tx for stream N in curr call |"); 3437 3481 puts("| vid call add Add video stream for current call |"); 3438 puts("| vid call enable /disable N Enable/disable stream #N in current call |");3482 puts("| vid call enable|disable N Enable/disable stream #N in current call |"); 3439 3483 puts("| vid call cap N ID Set capture dev ID for stream #N in current call |"); 3440 3484 puts("| vid dev list List all video devices |"); … … 3448 3492 puts("| vid win move ID X Y Move window ID to position X,Y |"); 3449 3493 puts("| vid win resize ID w h Resize window ID to the specified width, height |"); 3494 puts("+=============================================================================+"); 3495 printf("| Video will be %s in the next offer/answer %s |\n", 3496 (vid_enabled? "enabled" : "disabled"), (vid_enabled? " " : "")); 3450 3497 puts("+=============================================================================+"); 3451 3498 #endif … … 3864 3911 static void app_config_init_video(pjsua_acc_config *acc_cfg) 3865 3912 { 3866 acc_cfg->max_video_cnt = app_config.vid.vid_cnt;3867 3913 acc_cfg->vid_in_auto_show = app_config.vid.in_auto_show; 3868 3914 acc_cfg->vid_out_auto_transmit = app_config.vid.out_auto_transmit; … … 3880 3926 PJ_LOG(3,(THIS_FILE, 3881 3927 "Account %d:\n" 3882 " Video count: %d\n"3883 3928 " RX auto show: %d\n" 3884 3929 " TX auto transmit: %d\n" … … 3886 3931 " Render dev: %d", 3887 3932 acc_id, 3888 acc_cfg->max_video_cnt,3889 3933 acc_cfg->vid_in_auto_show, 3890 3934 acc_cfg->vid_out_auto_transmit, … … 3907 3951 if (argc == 1 || strcmp(argv[1], "help")==0) { 3908 3952 vid_show_help(); 3953 } else if (argc == 2 && (strcmp(argv[1], "enable")==0 || 3954 strcmp(argv[1], "disable")==0)) 3955 { 3956 pj_bool_t enabled = (strcmp(argv[1], "enable")==0); 3957 app_config.vid.vid_cnt = (enabled ? 1 : 0); 3958 PJ_LOG(3,(THIS_FILE, "Video will be %s in next offer/answer", 3959 (enabled?"enabled":"disabled"))); 3909 3960 } else if (strcmp(argv[1], "acc")==0) { 3910 3961 pjsua_acc_config acc_cfg; … … 3915 3966 if (argc == 3 && strcmp(argv[2], "show")==0) { 3916 3967 app_config_show_video(current_acc, &acc_cfg); 3917 3918 } else if (argc == 3 && (strcmp(argv[2], "enable")==0 ||3919 strcmp(argv[2], "disable")==0))3920 {3921 int enabled = (strcmp(argv[2], "enable")==0);3922 acc_cfg.max_video_cnt = (enabled ? 1 : 0);3923 if (enabled) {3924 app_config_init_video(&acc_cfg);3925 acc_cfg.max_video_cnt = (enabled ? 1 : 0);3926 }3927 changed = PJ_TRUE;3928 3968 } else if (argc == 4 && strcmp(argv[2], "autorx")==0) { 3929 3969 int on = (strcmp(argv[3], "on")==0); … … 4166 4206 pjsua_call_info call_info; 4167 4207 pjsua_acc_info acc_info; 4168 4208 pjsua_call_setting call_opt; 4209 4210 pjsua_call_setting_default(&call_opt); 4211 call_opt.audio_cnt = app_config.aud_cnt; 4212 call_opt.video_cnt = app_config.vid.vid_cnt; 4169 4213 4170 4214 /* If user specifies URI to call, then call the URI */ 4171 4215 if (uri_to_call->slen) { 4172 pjsua_call_make_call( current_acc, uri_to_call, 0, NULL, NULL, NULL);4216 pjsua_call_make_call( current_acc, uri_to_call, &call_opt, NULL, NULL, NULL); 4173 4217 } 4174 4218 … … 4205 4249 } 4206 4250 4251 /* Update call setting */ 4252 pjsua_call_setting_default(&call_opt); 4253 call_opt.audio_cnt = app_config.aud_cnt; 4254 call_opt.video_cnt = app_config.vid.vid_cnt; 4255 4207 4256 switch (menuin[0]) { 4208 4257 … … 4234 4283 pjsua_msg_data_init(&msg_data); 4235 4284 TEST_MULTIPART(&msg_data); 4236 pjsua_call_make_call( current_acc, &tmp, 0, NULL, &msg_data, NULL);4285 pjsua_call_make_call( current_acc, &tmp, &call_opt, NULL, &msg_data, NULL); 4237 4286 break; 4238 4287 … … 4266 4315 pj_status_t status; 4267 4316 4268 status = pjsua_call_make_call(current_acc, &tmp, 0, NULL,4317 status = pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL, 4269 4318 NULL, NULL); 4270 4319 if (status != PJ_SUCCESS) … … 4403 4452 } 4404 4453 4405 pjsua_call_answer (current_call, st_code, NULL, &msg_data);4454 pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data); 4406 4455 } 4407 4456 … … 4592 4641 * re-INVITE 4593 4642 */ 4594 pjsua_call_reinvite(current_call, PJ_TRUE, NULL); 4643 call_opt.flag |= PJSUA_CALL_UNHOLD; 4644 pjsua_call_reinvite2(current_call, &call_opt, NULL); 4595 4645 4596 4646 } else { … … 4605 4655 if (current_call != -1) { 4606 4656 4607 pjsua_call_update (current_call, 0, NULL);4657 pjsua_call_update2(current_call, &call_opt, NULL); 4608 4658 4609 4659 } else { -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r3864 r3891 2698 2698 2699 2699 /** 2700 * Maximum number of simultaneous active audio streams to be allowed2701 * for calls on this account. Setting this to zero will disable audio2702 * in calls on this account.2703 *2704 * Default: 12705 */2706 unsigned max_audio_cnt;2707 2708 /**2709 * Maximum number of simultaneous active video streams to be allowed2710 * for calls on this account. Setting this to zero will disable video2711 * in calls on this account, regardless of other video settings.2712 *2713 * Default: 12714 */2715 unsigned max_video_cnt;2716 2717 /**2718 2700 * Specify whether incoming video should be shown to screen by default. 2719 2701 * This applies to incoming call (INVITE), incoming re-INVITE, and … … 3390 3372 3391 3373 /** 3374 * Call settings. 3375 */ 3376 typedef struct pjsua_call_setting 3377 { 3378 /** 3379 * Bitmask of pjsua_call_flag constants. 3380 * 3381 * Default: 0 3382 */ 3383 unsigned flag; 3384 3385 /** 3386 * Number of simultaneous active audio streams for this call. Setting 3387 * this to zero will disable audio in this call. 3388 * 3389 * Default: 1 3390 */ 3391 unsigned audio_cnt; 3392 3393 /** 3394 * Number of simultaneous active video streams for this call. Setting 3395 * this to zero will disable video in this call. 3396 * 3397 * Default: 1 (if video feature is enabled, otherwise it is zero) 3398 */ 3399 unsigned video_cnt; 3400 3401 } pjsua_call_setting; 3402 3403 3404 /** 3392 3405 * This structure describes the information and current status of a call. 3393 3406 */ … … 3417 3430 /** Dialog Call-ID string. */ 3418 3431 pj_str_t call_id; 3432 3433 /** Call setting */ 3434 pjsua_call_setting setting; 3419 3435 3420 3436 /** Call state */ … … 3490 3506 /** Total call duration, including set-up time */ 3491 3507 pj_time_val total_duration; 3508 3509 /** Flag if remote was SDP offerer */ 3510 pj_bool_t rem_offerer; 3511 3512 /** Number of audio streams offered by remote */ 3513 unsigned rem_audio_cnt; 3514 3515 /** Number of video streams offered by remote */ 3516 unsigned rem_video_cnt; 3492 3517 3493 3518 /** Internal */ … … 3526 3551 * remote peer with the outgoing re-INVITE or UPDATE 3527 3552 */ 3528 PJSUA_CALL_UPDATE_CONTACT = 2 3553 PJSUA_CALL_UPDATE_CONTACT = 2, 3554 3555 /** 3556 * Include SDP "m=" line with port set to zero for each disabled media 3557 * (i.e when aud_cnt or vid_cnt is set to zero). This flag is only valid 3558 * for #pjsua_call_make_call(). 3559 */ 3560 PJSUA_CALL_INCLUDE_DISABLED_MEDIA = 4 3529 3561 3530 3562 } pjsua_call_flag; … … 3579 3611 * the media, regardless of whether existing video is/are present 3580 3612 * or not. This will cause re-INVITE or UPDATE to be sent to remote 3581 * party. The number of maximum active video streams in a call is 3582 * still limited by \a max_video_cnt setting in pjsua_acc_config. 3613 * party. 3583 3614 */ 3584 3615 PJSUA_CALL_VID_STRM_ADD, … … 3668 3699 3669 3700 /** 3701 * Initialize call settings. 3702 * 3703 * @param opt The call setting to be initialized. 3704 */ 3705 PJ_DECL(void) pjsua_call_setting_default(pjsua_call_setting *opt); 3706 3707 3708 /** 3670 3709 * Initialize video stream operation param with default values. 3671 3710 * … … 3710 3749 * @param dst_uri URI to be put in the To header (normally is the same 3711 3750 * as the target URI). 3712 * @param options Options (must be zero at the moment). 3751 * @param opt Optional call setting. This should be initialized 3752 * using #pjsua_call_setting_default(). 3713 3753 * @param user_data Arbitrary user data to be attached to the call, and 3714 3754 * can be retrieved later. … … 3721 3761 PJ_DECL(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id, 3722 3762 const pj_str_t *dst_uri, 3723 unsigned options,3763 const pjsua_call_setting *opt, 3724 3764 void *user_data, 3725 3765 const pjsua_msg_data *msg_data, … … 3863 3903 const pjsua_msg_data *msg_data); 3864 3904 3905 3906 /** 3907 * Send response to incoming INVITE request. Depending on the status 3908 * code specified as parameter, this function may send provisional 3909 * response, establish the call, or terminate the call. 3910 * 3911 * @param call_id Incoming call identification. 3912 * @param opt Optional call setting. 3913 * @param code Status code, (100-699). 3914 * @param reason Optional reason phrase. If NULL, default text 3915 * will be used. 3916 * @param msg_data Optional list of headers etc to be added to outgoing 3917 * response message. 3918 * 3919 * @return PJ_SUCCESS on success, or the appropriate error code. 3920 */ 3921 PJ_DECL(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id, 3922 const pjsua_call_setting *opt, 3923 unsigned code, 3924 const pj_str_t *reason, 3925 const pjsua_msg_data *msg_data); 3926 3927 3865 3928 /** 3866 3929 * Hangup call by using method that is appropriate according to the … … 3950 4013 const pjsua_msg_data *msg_data); 3951 4014 4015 4016 /** 4017 * Send re-INVITE to release hold. 4018 * The final status of the request itself will be reported on the 4019 * \a on_call_media_state() callback, which inform the application that 4020 * the media state of the call has changed. 4021 * 4022 * @param call_id Call identification. 4023 * @param opt Optional call setting. 4024 * @param msg_data Optional message components to be sent with 4025 * the request. 4026 * 4027 * @return PJ_SUCCESS on success, or the appropriate error code. 4028 */ 4029 PJ_DECL(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id, 4030 const pjsua_call_setting *opt, 4031 const pjsua_msg_data *msg_data); 4032 4033 3952 4034 /** 3953 4035 * Send UPDATE request. … … 3963 4045 unsigned options, 3964 4046 const pjsua_msg_data *msg_data); 4047 4048 4049 /** 4050 * Send UPDATE request. 4051 * 4052 * @param call_id Call identification. 4053 * @param opt Optional call setting. 4054 * @param msg_data Optional message components to be sent with 4055 * the request. 4056 * 4057 * @return PJ_SUCCESS on success, or the appropriate error code. 4058 */ 4059 PJ_DECL(pj_status_t) pjsua_call_update2(pjsua_call_id call_id, 4060 const pjsua_call_setting *opt, 4061 const pjsua_msg_data *msg_data); 4062 3965 4063 3966 4064 /** … … 4107 4205 * Get the media stream index of the default video stream in the call. 4108 4206 * Typically this will just retrieve the stream index of the first 4109 * activated video stream in the call. 4207 * activated video stream in the call. If none is active, it will return 4208 * the first inactive video stream. 4110 4209 * 4111 4210 * @param call_id Call identification. -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r3841 r3891 121 121 { 122 122 unsigned index; /**< Index in pjsua array. */ 123 pjsua_call_setting opt; /**< Call setting. */ 123 124 pjsip_inv_session *inv; /**< The invite session. */ 124 125 void *user_data; /**< User/application data. */ … … 163 164 union { 164 165 struct { 165 unsigned options; /**< Outgoing call options. */166 166 pjsua_msg_data *msg_data;/**< Headers for outgoing INVITE. */ 167 167 } out_call; … … 172 172 } async_call; /**< Temporary storage for async 173 173 outgoing/incoming call. */ 174 175 pj_bool_t rem_offerer; /**< Was remote SDP offerer? */ 176 unsigned rem_aud_cnt; /**< No of active audio in last remote 177 offer. */ 178 unsigned rem_vid_cnt; /**< No of active video in last remote 179 offer. */ 174 180 }; 175 181 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c
r3878 r3891 384 384 PJ_ASSERT_RETURN(pjsua_var.tpdata[0].data.ptr != NULL, PJ_EINVALIDOP); 385 385 386 /* Verify media count */387 #if !defined(PJMEDIA_HAS_VIDEO) || (PJMEDIA_HAS_VIDEO == 0)388 /* Enable PJMEDIA_HAS_VIDEO in your config_site.h! */389 PJ_ASSERT_RETURN(cfg->max_video_cnt == 0, PJ_EINVAL);390 #endif391 PJ_ASSERT_RETURN(cfg->max_audio_cnt + cfg->max_video_cnt <=392 PJSUA_MAX_CALL_MEDIA, PJ_ETOOMANY);393 394 386 PJ_LOG(4,(THIS_FILE, "Adding account: id=%.*s", 395 387 (int)cfg->id.slen, cfg->id.ptr)); … … 674 666 PJ_ASSERT_RETURN(acc_id>=0 && acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc), 675 667 PJ_EINVAL); 676 677 /* Verify media count */678 #if !defined(PJMEDIA_HAS_VIDEO) || (PJMEDIA_HAS_VIDEO == 0)679 PJ_ASSERT_RETURN(cfg->max_video_cnt == 0, PJ_EINVAL);680 #endif681 PJ_ASSERT_RETURN(cfg->max_audio_cnt + cfg->max_video_cnt <=682 PJSUA_MAX_CALL_MEDIA, PJ_ETOOMANY);683 668 684 669 PJ_LOG(4,(THIS_FILE, "Modifying accunt %d", acc_id)); … … 1064 1049 } 1065 1050 } 1066 1067 /* Max number of audio and video stream in a call */1068 acc->cfg.max_audio_cnt = cfg->max_audio_cnt;1069 acc->cfg.max_video_cnt = cfg->max_video_cnt;1070 1051 1071 1052 /* Video settings */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r3849 r3891 117 117 call_med->tp_auto_del = PJ_TRUE; 118 118 } 119 pjsua_call_setting_default(&call->opt); 119 120 } 120 121 … … 342 343 pjsua_acc *acc = &pjsua_var.acc[call->acc_id]; 343 344 pjsip_dialog *dlg = call->async_call.dlg; 344 unsigned options = call->async_call.call_var.out_call.options;345 unsigned options = 0; 345 346 pjsip_tx_data *tdata; 346 347 pj_status_t status = (info? info->status: PJ_SUCCESS); … … 488 489 489 490 /* 491 * Initialize call settings based on account ID. 492 */ 493 PJ_DEF(void) pjsua_call_setting_default(pjsua_call_setting *opt) 494 { 495 pj_assert(opt); 496 497 pj_bzero(opt, sizeof(*opt)); 498 opt->flag = PJSUA_CALL_INCLUDE_DISABLED_MEDIA; 499 opt->audio_cnt = 1; 500 501 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) 502 opt->video_cnt = 1; 503 //{ 504 // unsigned i; 505 // for (i = 0; i < PJ_ARRAY_SIZE(opt->vid_cap_dev); ++i) 506 // opt->vid_cap_dev[i] = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 507 //} 508 #endif 509 } 510 511 static pj_status_t apply_call_setting(pjsua_call *call, 512 const pjsua_call_setting *opt, 513 const pjmedia_sdp_session *rem_sdp) 514 { 515 pj_assert(call); 516 517 if (!opt) 518 return PJ_SUCCESS; 519 520 #if !PJMEDIA_HAS_VIDEO 521 pj_assert(opt->video_cnt == 0); 522 #endif 523 524 /* If call is established, reinit media channel */ 525 if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) { 526 pjsua_call_setting old_opt; 527 pj_status_t status; 528 529 old_opt = call->opt; 530 call->opt = *opt; 531 532 /* Reinit media channel when media count is changed */ 533 if (opt->audio_cnt != old_opt.audio_cnt || 534 opt->video_cnt != old_opt.video_cnt) 535 { 536 pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC; 537 status = pjsua_media_channel_init(call->index, role, 538 call->secure_level, 539 call->inv->pool_prov, 540 rem_sdp, NULL, 541 PJ_FALSE, NULL); 542 if (status != PJ_SUCCESS) { 543 pjsua_perror(THIS_FILE, "Error re-initializing media channel", 544 status); 545 return status; 546 } 547 } 548 } else { 549 call->opt = *opt; 550 } 551 552 return PJ_SUCCESS; 553 } 554 555 /* 490 556 * Make outgoing call to the specified URI using the specified account. 491 557 */ 492 PJ_DEF(pj_status_t) pjsua_call_make_call( 493 494 unsigned options,495 496 497 558 PJ_DEF(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id, 559 const pj_str_t *dest_uri, 560 const pjsua_call_setting *opt, 561 void *user_data, 562 const pjsua_msg_data *msg_data, 563 pjsua_call_id *p_call_id) 498 564 { 499 565 pj_pool_t *tmp_pool = NULL; … … 555 621 call->acc_id = acc_id; 556 622 call->call_hold_type = acc->cfg.call_hold_type; 623 624 /* Apply call setting */ 625 status = apply_call_setting(call, opt, NULL); 626 if (status != PJ_SUCCESS) { 627 pjsua_perror(THIS_FILE, "Failed to apply call setting", status); 628 goto on_error; 629 } 557 630 558 631 /* Create temporary pool */ … … 623 696 * media transport creation is completed. 624 697 */ 625 call->async_call.call_var.out_call.options = options;626 698 if (msg_data) { 627 699 call->async_call.call_var.out_call.msg_data = pjsua_msg_data_clone( … … 1466 1538 sizeof(info->buf_.call_id)); 1467 1539 1540 /* call setting */ 1541 pj_memcpy(&info->setting, &call->opt, sizeof(call->opt)); 1542 1468 1543 /* state, state_text */ 1469 1544 info->state = (call->inv? call->inv->state: PJSIP_INV_STATE_DISCONNECTED); … … 1487 1562 } 1488 1563 1564 /* Audio & video count offered by remote */ 1565 info->rem_offerer = call->rem_offerer; 1566 if (call->rem_offerer) { 1567 info->rem_audio_cnt = call->rem_aud_cnt; 1568 info->rem_video_cnt = call->rem_vid_cnt; 1569 } 1570 1489 1571 /* Build array of media status and dir */ 1490 1572 info->media_cnt = 0; … … 1761 1843 const pjsua_msg_data *msg_data) 1762 1844 { 1845 return pjsua_call_answer2(call_id, NULL, code, reason, msg_data); 1846 } 1847 1848 1849 /* 1850 * Send response to incoming INVITE request. 1851 */ 1852 PJ_DEF(pj_status_t) pjsua_call_answer2(pjsua_call_id call_id, 1853 const pjsua_call_setting *opt, 1854 unsigned code, 1855 const pj_str_t *reason, 1856 const pjsua_msg_data *msg_data) 1857 { 1763 1858 pjsua_call *call; 1764 1859 pjsip_dialog *dlg = NULL; … … 1775 1870 if (status != PJ_SUCCESS) 1776 1871 goto on_return; 1872 1873 /* Apply call setting */ 1874 status = apply_call_setting(call, opt, NULL); 1875 if (status != PJ_SUCCESS) { 1876 pjsua_perror(THIS_FILE, "Failed to apply call setting", status); 1877 goto on_return; 1878 } 1777 1879 1778 1880 PJSUA_LOCK(); … … 2017 2119 const pjsua_msg_data *msg_data) 2018 2120 { 2121 pjsua_call *call; 2122 pjsip_dialog *dlg = NULL; 2123 pj_status_t status; 2124 2125 status = acquire_call("pjsua_call_reinvite()", call_id, &call, &dlg); 2126 if (status != PJ_SUCCESS) 2127 goto on_return; 2128 2129 if (options != call->opt.flag) 2130 call->opt.flag = options; 2131 2132 status = pjsua_call_reinvite2(call_id, NULL, msg_data); 2133 2134 on_return: 2135 if (dlg) pjsip_dlg_dec_lock(dlg); 2136 return status; 2137 } 2138 2139 2140 /* 2141 * Send re-INVITE (to release hold). 2142 */ 2143 PJ_DEF(pj_status_t) pjsua_call_reinvite2(pjsua_call_id call_id, 2144 const pjsua_call_setting *opt, 2145 const pjsua_msg_data *msg_data) 2146 { 2019 2147 pjmedia_sdp_session *sdp; 2020 2148 pj_str_t *new_contact = NULL; … … 2031 2159 pj_log_push_indent(); 2032 2160 2033 status = acquire_call("pjsua_call_reinvite ()", call_id, &call, &dlg);2161 status = acquire_call("pjsua_call_reinvite2()", call_id, &call, &dlg); 2034 2162 if (status != PJ_SUCCESS) 2035 2163 goto on_return; … … 2041 2169 } 2042 2170 2171 status = apply_call_setting(call, opt, NULL); 2172 if (status != PJ_SUCCESS) { 2173 pjsua_perror(THIS_FILE, "Failed to apply call setting", status); 2174 goto on_return; 2175 } 2176 2043 2177 /* Create SDP */ 2044 if (call->local_hold && ( options& PJSUA_CALL_UNHOLD)==0) {2178 if (call->local_hold && (call->opt.flag & PJSUA_CALL_UNHOLD)==0) { 2045 2179 status = create_sdp_of_call_hold(call, &sdp); 2046 2180 } else { … … 2056 2190 } 2057 2191 2058 if (( options& PJSUA_CALL_UPDATE_CONTACT) &2192 if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) & 2059 2193 pjsua_acc_is_valid(call->acc_id)) 2060 2194 { … … 2091 2225 PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id, 2092 2226 unsigned options, 2227 const pjsua_msg_data *msg_data) 2228 { 2229 pjsua_call *call; 2230 pjsip_dialog *dlg = NULL; 2231 pj_status_t status; 2232 2233 status = acquire_call("pjsua_call_update()", call_id, &call, &dlg); 2234 if (status != PJ_SUCCESS) 2235 goto on_return; 2236 2237 if (options != call->opt.flag) 2238 call->opt.flag = options; 2239 2240 status = pjsua_call_update2(call_id, NULL, msg_data); 2241 2242 on_return: 2243 if (dlg) pjsip_dlg_dec_lock(dlg); 2244 return status; 2245 } 2246 2247 2248 /* 2249 * Send UPDATE request. 2250 */ 2251 PJ_DEF(pj_status_t) pjsua_call_update2(pjsua_call_id call_id, 2252 const pjsua_call_setting *opt, 2093 2253 const pjsua_msg_data *msg_data) 2094 2254 { … … 2100 2260 pj_status_t status; 2101 2261 2102 PJ_UNUSED_ARG(options);2103 2104 2262 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 2105 2263 PJ_EINVAL); … … 2108 2266 pj_log_push_indent(); 2109 2267 2110 status = acquire_call("pjsua_call_update ()", call_id, &call, &dlg);2268 status = acquire_call("pjsua_call_update2()", call_id, &call, &dlg); 2111 2269 if (status != PJ_SUCCESS) 2112 2270 goto on_return; 2271 2272 status = apply_call_setting(call, opt, NULL); 2273 if (status != PJ_SUCCESS) { 2274 pjsua_perror(THIS_FILE, "Failed to apply call setting", status); 2275 goto on_return; 2276 } 2113 2277 2114 2278 /* Create SDP */ … … 2122 2286 } 2123 2287 2124 if (( options& PJSUA_CALL_UPDATE_CONTACT) &2288 if ((call->opt.flag & PJSUA_CALL_UPDATE_CONTACT) & 2125 2289 pjsua_acc_is_valid(call->acc_id)) 2126 2290 { … … 3357 3521 pjmedia_sdp_session *answer; 3358 3522 unsigned i; 3523 int vid_idx; 3359 3524 pj_status_t status; 3360 3525 … … 3367 3532 call->index)); 3368 3533 pj_log_push_indent(); 3534 3535 #if 0 && PJMEDIA_HAS_VIDEO 3536 /* If current session has no video, let's just stay with no video. 3537 * If application want to enable video, it must send re-INVITE 3538 * with video. 3539 */ 3540 vid_idx = pjsua_call_get_vid_stream_idx(call->index); 3541 if (vid_idx == -1 || call->media[vid_idx].dir == PJMEDIA_DIR_NONE) 3542 call->opt.video_cnt = 0; 3543 #endif 3544 3545 /* Re-init media for the new remote offer before creating SDP */ 3546 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 3547 call->secure_level, 3548 call->inv->pool_prov, 3549 offer, NULL, 3550 PJ_FALSE, NULL); 3551 if (status != PJ_SUCCESS) { 3552 pjsua_perror(THIS_FILE, "Error re-initializing media channel", status); 3553 goto on_return; 3554 } 3369 3555 3370 3556 status = pjsua_media_channel_create_sdp(call->index, -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r3878 r3891 217 217 cfg->ka_interval = 15; 218 218 cfg->ka_data = pj_str("\r\n"); 219 cfg->max_audio_cnt = 1;220 219 cfg->vid_cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 221 220 cfg->vid_rend_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV; -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r3865 r3891 1158 1158 pjmedia_srtp_use use_srtp, 1159 1159 pj_uint8_t midx[], 1160 unsigned *p_count) 1160 unsigned *p_count, 1161 unsigned *p_total_count) 1161 1162 { 1162 1163 unsigned i; … … 1165 1166 1166 1167 pj_assert(*p_count >= PJSUA_MAX_CALL_MEDIA); 1168 pj_assert(*p_total_count >= PJSUA_MAX_CALL_MEDIA); 1167 1169 1168 1170 *p_count = 0; 1171 *p_total_count = 0; 1169 1172 for (i=0; i<PJSUA_MAX_CALL_MEDIA; ++i) 1170 1173 score[i] = 1; … … 1239 1242 * for us. 1240 1243 */ 1241 if (score[best] >= 0) {1242 midx[*p_count] = (pj_uint8_t)best;1244 midx[i] = (pj_uint8_t)best; 1245 if (score[best] >= 0) 1243 1246 (*p_count)++; 1244 } 1247 if (score[best] > -22000) 1248 (*p_total_count)++; 1245 1249 1246 1250 score[best] = -22000; … … 1589 1593 pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA]; 1590 1594 unsigned maudcnt = PJ_ARRAY_SIZE(maudidx); 1595 unsigned mtotaudcnt = PJ_ARRAY_SIZE(maudidx); 1591 1596 pj_uint8_t mvididx[PJSUA_MAX_CALL_MEDIA]; 1592 1597 unsigned mvidcnt = PJ_ARRAY_SIZE(mvididx); 1593 pjmedia_type media_types[PJSUA_MAX_CALL_MEDIA];1598 unsigned mtotvidcnt = PJ_ARRAY_SIZE(mvididx); 1594 1599 unsigned mi; 1595 1600 pj_bool_t pending_med_tp = PJ_FALSE; 1601 pj_bool_t reinit = PJ_FALSE; 1596 1602 pj_status_t status; 1597 1603 … … 1615 1621 } 1616 1622 1617 PJ_LOG(4,(THIS_FILE, "Call %d: initializing media..", call_id)); 1623 if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) 1624 reinit = PJ_TRUE; 1625 1626 PJ_LOG(4,(THIS_FILE, "Call %d: %sinitializing media..", 1627 call_id, (reinit?"re-":"") )); 1628 1618 1629 pj_log_push_indent(); 1619 1630 … … 1630 1641 #endif 1631 1642 1643 /* Get media count for each media type */ 1632 1644 if (rem_sdp) { 1633 1645 sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp, 1634 maudidx, &maudcnt); 1635 // Don't apply media count limitation until SDP negotiation is done. 1636 //if (maudcnt > acc->cfg.max_audio_cnt) 1637 // maudcnt = acc->cfg.max_audio_cnt; 1638 1646 maudidx, &maudcnt, &mtotaudcnt); 1639 1647 if (maudcnt==0) { 1640 1648 /* Expecting audio in the offer */ … … 1647 1655 #if PJMEDIA_HAS_VIDEO 1648 1656 sort_media(rem_sdp, &STR_VIDEO, acc->cfg.use_srtp, 1649 mvididx, &mvidcnt); 1650 // Don't apply media count limitation until SDP negotiation is done. 1651 //if (mvidcnt > acc->cfg.max_video_cnt) 1652 //mvidcnt = acc->cfg.max_video_cnt; 1657 mvididx, &mvidcnt, &mtotvidcnt); 1653 1658 #else 1654 mvidcnt = 0; 1659 mvidcnt = mtotvidcnt = 0; 1660 PJ_UNUSED_ARG(STR_VIDEO); 1655 1661 #endif 1656 1662 1657 1663 /* Update media count only when remote add any media, this media count 1658 * must never decrease. 1664 * must never decrease. Also note that we shouldn't apply the media 1665 * count setting (of the call setting) before the SDP negotiation. 1659 1666 */ 1660 1667 if (call->med_cnt < rem_sdp->media_count) 1661 1668 call->med_cnt = PJ_MIN(rem_sdp->media_count, PJSUA_MAX_CALL_MEDIA); 1662 1669 1670 call->rem_offerer = PJ_TRUE; 1671 call->rem_aud_cnt = maudcnt; 1672 call->rem_vid_cnt = mvidcnt; 1673 1663 1674 } else { 1664 maudcnt = acc->cfg.max_audio_cnt; 1665 for (mi=0; mi<maudcnt; ++mi) { 1666 maudidx[mi] = (pj_uint8_t)mi; 1667 media_types[mi] = PJMEDIA_TYPE_AUDIO; 1668 } 1675 1676 /* If call already established, calculate media count from current 1677 * local active SDP and call setting. Otherwise, calculate media 1678 * count from the call setting only. 1679 */ 1680 if (reinit) { 1681 pjmedia_sdp_session *sdp; 1682 1683 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp); 1684 pj_assert(status == PJ_SUCCESS); 1685 1686 sort_media(sdp, &STR_AUDIO, acc->cfg.use_srtp, 1687 maudidx, &maudcnt, &mtotaudcnt); 1688 pj_assert(maudcnt > 0); 1689 1690 sort_media(sdp, &STR_VIDEO, acc->cfg.use_srtp, 1691 mvididx, &mvidcnt, &mtotvidcnt); 1692 1693 /* Call setting may add or remove media. Adding media is done by 1694 * enabling any disabled/port-zeroed media first, then adding new 1695 * media whenever needed. Removing media is done by disabling 1696 * media with the lowest 'quality'. 1697 */ 1698 1699 /* Check if we need to add new audio */ 1700 if (maudcnt < call->opt.audio_cnt && 1701 mtotaudcnt < call->opt.audio_cnt) 1702 { 1703 for (mi = 0; mi < call->opt.audio_cnt - mtotaudcnt; ++mi) 1704 maudidx[maudcnt++] = (pj_uint8_t)call->med_cnt++; 1705 1706 mtotaudcnt = call->opt.audio_cnt; 1707 } 1708 maudcnt = call->opt.audio_cnt; 1709 1710 /* Check if we need to add new video */ 1711 if (mvidcnt < call->opt.video_cnt && 1712 mtotvidcnt < call->opt.video_cnt) 1713 { 1714 for (mi = 0; mi < call->opt.video_cnt - mtotvidcnt; ++mi) 1715 mvididx[mvidcnt++] = (pj_uint8_t)call->med_cnt++; 1716 1717 mtotvidcnt = call->opt.video_cnt; 1718 } 1719 mvidcnt = call->opt.video_cnt; 1720 1721 } else { 1722 1723 maudcnt = mtotaudcnt = call->opt.audio_cnt; 1724 for (mi=0; mi<maudcnt; ++mi) { 1725 maudidx[mi] = (pj_uint8_t)mi; 1726 } 1727 mvidcnt = mtotvidcnt = call->opt.video_cnt; 1728 for (mi=0; mi<mvidcnt; ++mi) { 1729 mvididx[mi] = (pj_uint8_t)(maudcnt + mi); 1730 } 1731 call->med_cnt = maudcnt + mvidcnt; 1732 1733 /* Need to publish supported media? */ 1734 if (call->opt.flag & PJSUA_CALL_INCLUDE_DISABLED_MEDIA) { 1735 if (mtotaudcnt == 0) { 1736 mtotaudcnt = 1; 1737 maudidx[0] = (pj_uint8_t)call->med_cnt++; 1738 } 1669 1739 #if PJMEDIA_HAS_VIDEO 1670 mvidcnt = acc->cfg.max_video_cnt; 1671 for (mi=0; mi<mvidcnt; ++mi) { 1672 media_types[maudcnt + mi] = PJMEDIA_TYPE_VIDEO; 1673 } 1674 #else 1675 mvidcnt = 0; 1676 #endif 1677 call->med_cnt = maudcnt + mvidcnt; 1740 if (mtotvidcnt == 0) { 1741 mtotvidcnt = 1; 1742 mvididx[0] = (pj_uint8_t)call->med_cnt++; 1743 } 1744 #endif 1745 } 1746 } 1747 1748 call->rem_offerer = PJ_FALSE; 1678 1749 } 1679 1750 … … 1703 1774 pjsua_call_media *call_med = &call->media[mi]; 1704 1775 pj_bool_t enabled = PJ_FALSE; 1705 pjmedia_type media_type = PJMEDIA_TYPE_NONE; 1706 1707 if (rem_sdp) { 1708 if (mi >= rem_sdp->media_count) { 1709 /* Media has been removed in remote re-offer */ 1710 media_type = call_med->type; 1711 } else if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_AUDIO)) { 1712 media_type = PJMEDIA_TYPE_AUDIO; 1713 if (pj_memchr(maudidx, mi, maudcnt * sizeof(maudidx[0]))) { 1714 enabled = PJ_TRUE; 1715 } 1716 } 1717 else if (!pj_stricmp(&rem_sdp->media[mi]->desc.media, &STR_VIDEO)) { 1718 media_type = PJMEDIA_TYPE_VIDEO; 1719 if (pj_memchr(mvididx, mi, mvidcnt * sizeof(mvididx[0]))) { 1720 enabled = PJ_TRUE; 1721 } 1722 } 1723 1724 } else { 1725 enabled = PJ_TRUE; 1726 media_type = media_types[mi]; 1776 pjmedia_type media_type = PJMEDIA_TYPE_UNKNOWN; 1777 1778 if (pj_memchr(maudidx, mi, mtotaudcnt * sizeof(maudidx[0]))) { 1779 media_type = PJMEDIA_TYPE_AUDIO; 1780 if (call->opt.audio_cnt && 1781 pj_memchr(maudidx, mi, maudcnt * sizeof(maudidx[0]))) 1782 { 1783 enabled = PJ_TRUE; 1784 } 1785 } else if (pj_memchr(mvididx, mi, mtotvidcnt * sizeof(mvididx[0]))) { 1786 media_type = PJMEDIA_TYPE_VIDEO; 1787 if (call->opt.video_cnt && 1788 pj_memchr(mvididx, mi, mvidcnt * sizeof(mvididx[0]))) 1789 { 1790 enabled = PJ_TRUE; 1791 } 1727 1792 } 1728 1793 … … 1808 1873 } 1809 1874 1875 1876 /* Create SDP based on the current media channel. Note that, this function 1877 * will not modify the media channel, so when receiving new offer or 1878 * updating media count (via call setting), media channel must be reinit'd 1879 * (using pjsua_media_channel_init()) first before calling this function. 1880 */ 1810 1881 pj_status_t pjsua_media_channel_create_sdp(pjsua_call_id call_id, 1811 1882 pj_pool_t *pool, … … 1825 1896 return PJ_EBUSY; 1826 1897 1898 #if 0 1899 // This function should not really change the media channel. 1827 1900 if (rem_sdp) { 1828 1901 /* If this is a re-offer, let's re-initialize media as remote may … … 1837 1910 return status; 1838 1911 } 1839 1840 #if 01841 pjsua_acc *acc = &pjsua_var.acc[call->acc_id];1842 pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA];1843 unsigned maudcnt = PJ_ARRAY_SIZE(maudidx);1844 1845 sort_media(rem_sdp, &STR_AUDIO, acc->cfg.use_srtp,1846 maudidx, &maudcnt);1847 1848 if (maudcnt==0) {1849 /* Expecting audio in the offer */1850 if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE;1851 pjsua_media_channel_deinit(call_id);1852 return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE);1853 }1854 1855 call->audio_idx = maudidx[0];1856 #endif1857 1912 } else { 1858 1913 /* Audio is first in our offer, by convention */ … … 1862 1917 //call->audio_idx = 0; 1863 1918 } 1919 #endif 1864 1920 1865 1921 #if 0 … … 2085 2141 #endif 2086 2142 2143 call->rem_offerer = (rem_sdp != NULL); 2144 2087 2145 *p_sdp = sdp; 2088 2146 return PJ_SUCCESS; … … 2464 2522 pj_uint8_t maudidx[PJSUA_MAX_CALL_MEDIA]; 2465 2523 unsigned maudcnt = PJ_ARRAY_SIZE(maudidx); 2524 unsigned mtotaudcnt = PJ_ARRAY_SIZE(maudidx); 2466 2525 pj_uint8_t mvididx[PJSUA_MAX_CALL_MEDIA]; 2467 2526 unsigned mvidcnt = PJ_ARRAY_SIZE(mvididx); 2527 unsigned mtotvidcnt = PJ_ARRAY_SIZE(mvididx); 2468 2528 pj_bool_t need_renego_sdp = PJ_FALSE; 2469 2529 … … 2485 2545 call->audio_idx = -1; 2486 2546 2487 /* Apply maximum audio/video count of the account*/2547 /* Sort audio/video based on "quality" */ 2488 2548 sort_media(local_sdp, &STR_AUDIO, acc->cfg.use_srtp, 2489 maudidx, &maudcnt );2549 maudidx, &maudcnt, &mtotaudcnt); 2490 2550 #if PJMEDIA_HAS_VIDEO 2491 2551 sort_media(local_sdp, &STR_VIDEO, acc->cfg.use_srtp, 2492 mvididx, &mvidcnt );2552 mvididx, &mvidcnt, &mtotvidcnt); 2493 2553 #else 2494 2554 PJ_UNUSED_ARG(STR_VIDEO); 2495 2555 mvidcnt = 0; 2496 2556 #endif 2497 if (maudcnt > acc->cfg.max_audio_cnt || mvidcnt > acc->cfg.max_video_cnt) 2557 2558 /* Applying media count limitation. Note that in generating SDP answer, 2559 * no media count limitation applied, as we didn't know yet which media 2560 * would pass the SDP negotiation. 2561 */ 2562 if (maudcnt > call->opt.audio_cnt || mvidcnt > call->opt.video_cnt) 2498 2563 { 2499 2564 pjmedia_sdp_session *local_sdp2; 2500 2565 2501 maudcnt = PJ_MIN(maudcnt, acc->cfg.max_audio_cnt);2502 mvidcnt = PJ_MIN(mvidcnt, acc->cfg.max_video_cnt);2566 maudcnt = PJ_MIN(maudcnt, call->opt.audio_cnt); 2567 mvidcnt = PJ_MIN(mvidcnt, call->opt.video_cnt); 2503 2568 local_sdp2 = pjmedia_sdp_session_clone(tmp_pool, local_sdp); 2504 2569 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c
r3887 r3891 1313 1313 } 1314 1314 1315 /* Make sure that renderer gets started before shown up */ 1316 if (show && !pjmedia_vid_port_is_running(w->vp_rend)) 1317 status = pjmedia_vid_port_start(w->vp_rend); 1318 1315 1319 hide = !show; 1316 1320 status = pjmedia_vid_dev_stream_set_cap(s, … … 1541 1545 pjmedia_sdp_media *sdp_m; 1542 1546 pjmedia_transport_info tpinfo; 1543 unsigned active_cnt;1544 1547 pj_status_t status; 1545 1548 1546 1549 /* Verify media slot availability */ 1547 1550 if (call->med_cnt == PJSUA_MAX_CALL_MEDIA) 1548 return PJ_ETOOMANY;1549 1550 call_get_vid_strm_info(call, NULL, NULL, &active_cnt, NULL);1551 if (active_cnt == acc_cfg->max_video_cnt)1552 1551 return PJ_ETOOMANY; 1553 1552 … … 1617 1616 if (status != PJ_SUCCESS) 1618 1617 goto on_error; 1618 1619 call->opt.video_cnt++; 1619 1620 1620 1621 return PJ_SUCCESS; … … 1759 1760 pjmedia_sdp_media_deactivate(pool, sdp->media[med_idx]); 1760 1761 1762 call->opt.video_cnt--; 1761 1763 } 1762 1764
Note: See TracChangeset
for help on using the changeset viewer.