Changeset 3634
- Timestamp:
- Jul 13, 2011 8:51:10 AM (13 years ago)
- Location:
- pjproject/branches/projects/2.0-dev
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjsip-apps/src/pjsua/pjsua_app.c
r3632 r3634 1452 1452 cur_acc->vid_in_auto_show = PJ_TRUE; 1453 1453 cur_acc->vid_out_auto_transmit = PJ_TRUE; 1454 PJ_TODO(implement_pjsua_option_for_vid_auto_show_ transmit);1454 PJ_TODO(implement_pjsua_option_for_vid_auto_show_and_transmit); 1455 1455 break; 1456 1456 case OPT_EXTRA_AUDIO: … … 3316 3316 puts("| vid call rx on|off Enable/disable incoming video for current call |"); 3317 3317 puts("| vid call tx on|off Enable/disable video tx for current call |"); 3318 puts("| vid call add Add video stream for current call |"); 3319 puts("| vid call remove [idx] Remove video stream #idx for current call |"); 3318 3320 puts("| vid dev list List all video devices |"); 3319 3321 puts("| vid dev refresh Refresh video device list |"); … … 3754 3756 vid_show_help(); 3755 3757 } else if (strcmp(argv[1], "call")==0) { 3758 pjsua_call_vid_strm_op_param param; 3756 3759 pj_bool_t tx = (strcmp(argv[2], "tx") == 0); 3757 pj_bool_t on = (strcmp(argv[3], "on") == 0); 3758 3760 if (tx) { 3761 pj_bool_t on = (strcmp(argv[3], "on") == 0); 3762 } 3763 3764 if (strcmp(argv[2], "add")==0) { 3765 pjsua_call_set_vid_strm(current_call, PJSUA_CALL_VID_STRM_ADD, NULL); 3766 } 3767 if (strcmp(argv[2], "remove")==0) { 3768 param.med_idx = argc >= 4? atoi(argv[3]) : -1; 3769 pjsua_call_set_vid_strm(current_call, PJSUA_CALL_VID_STRM_REMOVE, ¶m); 3770 } 3759 3771 PJ_TODO(vid_enable_disable_video_on_call); 3760 3772 PJ_LOG(1,(THIS_FILE, "Not implemented")); -
pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua.h
r3632 r3634 368 368 369 369 } pjsua_state; 370 371 372 /** 373 * This enumeration represents video stream operation on a call. 374 * See also #pjsua_call_vid_strm_op_param for further info. 375 */ 376 typedef enum pjsua_call_vid_strm_op 377 { 378 /** 379 * Add a new video stream. 380 */ 381 PJSUA_CALL_VID_STRM_ADD, 382 383 /** 384 * Remove an existing video stream. 385 */ 386 PJSUA_CALL_VID_STRM_REMOVE, 387 388 /** 389 * Modify an existing video stream, such as changing the capture device. 390 */ 391 PJSUA_CALL_VID_STRM_MODIFY, 392 393 /** 394 * Start transmitting video stream. 395 */ 396 PJSUA_CALL_VID_STRM_START_TRANSMIT, 397 398 /** 399 * Stop transmitting video stream. 400 */ 401 PJSUA_CALL_VID_STRM_STOP_TRANSMIT, 402 403 } pjsua_call_vid_strm_op; 404 405 406 /** 407 * Parameters for video stream operation on a call. 408 */ 409 typedef struct pjsua_call_vid_strm_op_param 410 { 411 /** 412 * Specify the media stream index. This can be set to -1 to denote 413 * the default video stream in the call, which is the first active 414 * video stream or any first video stream if none is active. 415 * 416 * This field is valid for all video stream operations, except 417 * PJSUA_CALL_VID_STRM_ADD. 418 */ 419 int med_idx; 420 421 /** 422 * Specify the video capture device ID. This can be set to 423 * PJMEDIA_VID_DEFAULT_CAPTURE_DEV to specify the default capture 424 * device as configured in the account. 425 * 426 * This field is valid for the following video stream operations: 427 * PJSUA_CALL_VID_STRM_ADD, PJSUA_CALL_VID_STRM_MODIFY, and 428 * PJSUA_CALL_VID_STRM_START_TRANSMIT. 429 */ 430 pjmedia_vid_dev_index cap_dev; 431 432 } pjsua_call_vid_strm_op_param; 370 433 371 434 … … 3681 3744 PJ_DECL(int) pjsua_call_get_vid_stream_idx(pjsua_call_id call_id); 3682 3745 3683 /** 3684 * Start, stop, and/or manipulate video transmission for the specified 3685 * call. This would trigger a re-INVITE or UPDATE to be sent for the 3686 * call. This function may add, remove, or modify existing video media 3687 * stream, depending on the media index specified (the \a med_idx argument). 3688 * 3689 * To add a new or edit existing video stream (for transmission), specify 3690 * a valid video capture device ID or PJMEDIA_VID_DEFAULT_CAPTURE_DEV in 3691 * the \a cap_dev argument. If \a med_idx is set to default stream (-1), 3692 * then the function will modify existing video stream if one exists, or 3693 * add a new one if it doesn't. If \a med_idx is set to a specific stream 3694 * index, the function will modify that video stream. Otherwise if \a med_idx 3695 * is set to value larger than the current media count, a new video stream 3696 * will be added to the call. 3697 * 3698 * To remove an existing video stream, specify PJMEDIA_VID_INVALID_DEV in 3699 * \a cap_dev argument. If \a med_idx is set to default stream (-1), this 3700 * will remove the default/first video stream in the call, otherwise 3701 * application can put a specific value to request removal of that particular 3702 * video stream. 3746 3747 /** 3748 * Add, remove, modify, and/or manipulate video media stream for the 3749 * specified call. This may trigger a re-INVITE or UPDATE to be sent 3750 * for the call. 3703 3751 * 3704 3752 * @param call_id Call identification. 3705 * @param med_idx The media stream index. Currently the value MUST 3706 * be -1 to denote the default video stream in the 3707 * call. 3708 * @param cap_dev To add or modify existing video media stream, 3709 * specify PJMEDIA_VID_DEFAULT_CAPTURE_DEV to use 3710 * the default capture device as configured in the 3711 * account, or specify a specific capture device ID. 3712 * To disable an existing video stream, specify 3713 * PJMEDIA_VID_INVALID_DEV for this parameter. 3753 * @param op The video stream operation to be performed, 3754 * possible values are #pjsua_call_vid_strm_op. 3755 * @param param The parameters for the video stream operation. 3714 3756 * 3715 3757 * @return PJ_SUCCESS on success or the appropriate error. 3716 3758 */ 3717 PJ_DECL(pj_status_t) pjsua_call_set_vid_out(pjsua_call_id call_id, 3718 int med_idx, 3719 pjmedia_vid_dev_index cap_dev); 3759 PJ_DECL(pj_status_t) pjsua_call_set_vid_strm ( 3760 pjsua_call_id call_id, 3761 pjsua_call_vid_strm_op op, 3762 const pjsua_call_vid_strm_op_param *param); 3763 3720 3764 3721 3765 /** -
pjproject/branches/projects/2.0-dev/pjsip/include/pjsua-lib/pjsua_internal.h
r3632 r3634 75 75 pjsua_vid_win_id cap_win_id;/**< The video capture window */ 76 76 pjsua_vid_win_id rdr_win_id;/**< The video render window */ 77 pjmedia_vid_dev_index cap_dev; /**< The video capture device */ 78 pjmedia_vid_dev_index rdr_dev; /**< The video-in render device */ 77 79 } v; 78 80 -
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_media.c
r3632 r3634 1314 1314 1315 1315 /* Initialize the media line */ 1316 staticpj_status_t pjsua_call_media_init(pjsua_call_media *call_med,1317 1318 1319 1320 1316 pj_status_t pjsua_call_media_init(pjsua_call_media *call_med, 1317 pjmedia_type type, 1318 const pjsua_transport_config *tcfg, 1319 int security_level, 1320 int *sip_err_code) 1321 1321 { 1322 1322 pjsua_acc *acc = &pjsua_var.acc[call_med->call->acc_id]; … … 1343 1343 1344 1344 call_med->tp_st = PJSUA_MED_TP_IDLE; 1345 1346 /* While in initial call, set default video devices */ 1347 if (type == PJMEDIA_TYPE_VIDEO) { 1348 call_med->strm.v.rdr_dev = acc->cfg.vid_rend_dev; 1349 call_med->strm.v.cap_dev = acc->cfg.vid_cap_dev; 1350 if (call_med->strm.v.rdr_dev == PJMEDIA_VID_DEFAULT_RENDER_DEV) { 1351 pjmedia_vid_dev_info info; 1352 pjmedia_vid_dev_get_info(call_med->strm.v.rdr_dev, &info); 1353 call_med->strm.v.rdr_dev = info.id; 1354 } 1355 if (call_med->strm.v.cap_dev == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) { 1356 pjmedia_vid_dev_info info; 1357 pjmedia_vid_dev_get_info(call_med->strm.v.cap_dev, &info); 1358 call_med->strm.v.cap_dev = info.id; 1359 } 1360 } 1345 1361 } else if (call_med->tp_st == PJSUA_MED_TP_DISABLED) { 1346 1362 /* Media is being reenabled. */ -
pjproject/branches/projects/2.0-dev/pjsip/src/pjsua-lib/pjsua_vid.c
r3629 r3634 608 608 609 609 /* Setup decoding direction */ 610 if (si->dir & PJMEDIA_DIR_DECODING) { 610 if (si->dir & PJMEDIA_DIR_DECODING) 611 { 611 612 pjsua_vid_win_id wid; 612 613 pjsua_vid_win *w; … … 621 622 status = create_vid_win(PJSUA_WND_TYPE_STREAM, 622 623 &media_port->info.fmt, 623 acc->cfg.vid_rend_dev, 624 call_med->strm.v.rdr_dev, 625 //acc->cfg.vid_rend_dev, 624 626 PJSUA_INVALID_ID, 625 627 acc->cfg.vid_in_auto_show, … … 647 649 648 650 /* Setup encoding direction */ 649 if (si->dir & PJMEDIA_DIR_ENCODING && !call->local_hold && 650 acc->cfg.vid_out_auto_transmit) 651 if (si->dir & PJMEDIA_DIR_ENCODING && !call->local_hold) 651 652 { 652 653 pjsua_vid_win *w; … … 662 663 status = create_vid_win(PJSUA_WND_TYPE_PREVIEW, 663 664 &media_port->info.fmt, 664 acc->cfg.vid_rend_dev, 665 acc->cfg.vid_cap_dev, 665 call_med->strm.v.rdr_dev, 666 call_med->strm.v.cap_dev, 667 //acc->cfg.vid_rend_dev, 668 //acc->cfg.vid_cap_dev, 666 669 PJ_FALSE, 667 670 &wid); … … 737 740 } 738 741 742 if (acc->cfg.vid_out_auto_transmit) { 743 status = pjmedia_vid_stream_pause(call_med->strm.v.stream, 744 PJMEDIA_DIR_ENCODING); 745 if (status != PJ_SUCCESS) 746 return status; 747 } 748 739 749 return PJ_SUCCESS; 740 750 } … … 1007 1017 1008 1018 1019 static void call_get_vid_strm_info(pjsua_call *call, 1020 int *first_active, 1021 int *first_inactive, 1022 unsigned *active_cnt, 1023 unsigned *cnt) 1024 { 1025 unsigned i, var_cnt = 0; 1026 1027 if (first_active && ++var_cnt) 1028 *first_active = -1; 1029 if (first_inactive && ++var_cnt) 1030 *first_inactive = -1; 1031 if (active_cnt && ++var_cnt) 1032 *active_cnt = 0; 1033 if (cnt && ++var_cnt) 1034 *cnt = 0; 1035 1036 for (i = 0; i < call->med_cnt && var_cnt; ++i) { 1037 if (call->media[i].type == PJMEDIA_TYPE_VIDEO) { 1038 if (call->media[i].dir != PJMEDIA_DIR_NONE) 1039 { 1040 if (first_active && *first_active == -1) { 1041 *first_active = i; 1042 --var_cnt; 1043 } 1044 if (active_cnt) 1045 ++(*active_cnt); 1046 } else if (first_inactive && *first_inactive == -1) { 1047 *first_inactive = i; 1048 --var_cnt; 1049 } 1050 if (cnt) 1051 ++(*cnt); 1052 } 1053 } 1054 } 1055 1056 1057 /* Send SDP reoffer. */ 1058 static pj_status_t call_reoffer_sdp(pjsua_call_id call_id, 1059 const pjmedia_sdp_session *sdp) 1060 { 1061 pjsua_call *call; 1062 pjsip_tx_data *tdata; 1063 pjsip_dialog *dlg; 1064 pj_status_t status; 1065 1066 status = acquire_call("call_reoffer_sdp()", call_id, &call, &dlg); 1067 if (status != PJ_SUCCESS) 1068 return status; 1069 1070 if (call->inv->state != PJSIP_INV_STATE_CONFIRMED) { 1071 PJ_LOG(3,(THIS_FILE, "Can not re-INVITE call that is not confirmed")); 1072 pjsip_dlg_dec_lock(dlg); 1073 return PJSIP_ESESSIONSTATE; 1074 } 1075 1076 /* Create re-INVITE with new offer */ 1077 status = pjsip_inv_reinvite( call->inv, NULL, sdp, &tdata); 1078 if (status != PJ_SUCCESS) { 1079 pjsua_perror(THIS_FILE, "Unable to create re-INVITE", status); 1080 pjsip_dlg_dec_lock(dlg); 1081 return status; 1082 } 1083 1084 /* Send the request */ 1085 status = pjsip_inv_send_msg( call->inv, tdata); 1086 if (status != PJ_SUCCESS) { 1087 pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status); 1088 pjsip_dlg_dec_lock(dlg); 1089 return status; 1090 } 1091 1092 pjsip_dlg_dec_lock(dlg); 1093 1094 return PJ_SUCCESS; 1095 } 1096 1097 1098 pj_status_t pjsua_call_media_init(pjsua_call_media *call_med, 1099 pjmedia_type type, 1100 const pjsua_transport_config *tcfg, 1101 int security_level, 1102 int *sip_err_code); 1103 1104 1105 /* Add a new video stream into a call */ 1106 static pj_status_t call_add_video(pjsua_call *call, 1107 pjmedia_vid_dev_index cap_dev) 1108 { 1109 pj_pool_t *pool = call->inv->pool_prov; 1110 pjsua_acc_config *acc_cfg = &pjsua_var.acc[call->acc_id].cfg; 1111 pjsua_call_media *call_med; 1112 pjmedia_sdp_session *sdp; 1113 pjmedia_sdp_media *sdp_m; 1114 pjmedia_transport_info tpinfo; 1115 pjmedia_vid_dev_info vinfo; 1116 unsigned active_cnt; 1117 pj_status_t status; 1118 1119 /* Verify media slot availability */ 1120 if (call->med_cnt == PJSUA_MAX_CALL_MEDIA) 1121 return PJ_ETOOMANY; 1122 1123 call_get_vid_strm_info(call, NULL, NULL, &active_cnt, NULL); 1124 if (active_cnt == acc_cfg->max_video_cnt) 1125 return PJ_ETOOMANY; 1126 1127 /* Verify the capture device */ 1128 status = pjmedia_vid_dev_get_info(cap_dev, &vinfo); 1129 if (status != PJ_SUCCESS) 1130 return status; 1131 1132 if (vinfo.dir != PJMEDIA_DIR_CAPTURE) 1133 return PJ_EINVAL; 1134 1135 cap_dev = vinfo.id; 1136 1137 /* Get active local SDP */ 1138 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp); 1139 if (status != PJ_SUCCESS) 1140 return status; 1141 1142 /* Initialize call media */ 1143 call_med = &call->media[call->med_cnt++]; 1144 1145 status = pjsua_call_media_init(call_med, PJMEDIA_TYPE_VIDEO, 1146 &acc_cfg->rtp_cfg, call->secure_level, 1147 NULL); 1148 if (status != PJ_SUCCESS) 1149 goto on_error; 1150 1151 /* Override default capture device setting */ 1152 call_med->strm.v.cap_dev = cap_dev; 1153 1154 /* Init transport media */ 1155 status = pjmedia_transport_media_create(call_med->tp, pool, 0, 1156 NULL, call_med->idx); 1157 if (status != PJ_SUCCESS) 1158 goto on_error; 1159 1160 call_med->tp_st = PJSUA_MED_TP_INIT; 1161 1162 /* Get transport address info */ 1163 pjmedia_transport_info_init(&tpinfo); 1164 pjmedia_transport_get_info(call_med->tp, &tpinfo); 1165 1166 /* Create SDP media line */ 1167 status = pjmedia_endpt_create_video_sdp(pjsua_var.med_endpt, pool, 1168 &tpinfo.sock_info, 0, &sdp_m); 1169 if (status != PJ_SUCCESS) 1170 goto on_error; 1171 1172 sdp->media[sdp->media_count++] = sdp_m; 1173 1174 /* Update SDP media line by media transport */ 1175 status = pjmedia_transport_encode_sdp(call_med->tp, pool, 1176 sdp, NULL, call_med->idx); 1177 if (status != PJ_SUCCESS) 1178 goto on_error; 1179 1180 status = call_reoffer_sdp(call->index, sdp); 1181 if (status != PJ_SUCCESS) 1182 goto on_error; 1183 1184 return PJ_SUCCESS; 1185 1186 on_error: 1187 if (call_med->tp) { 1188 pjmedia_transport_close(call_med->tp); 1189 call_med->tp = call_med->tp_orig = NULL; 1190 } 1191 1192 return status; 1193 } 1194 1195 1196 /* Remove a video stream from a call */ 1197 static pj_status_t call_remove_video(pjsua_call *call, 1198 int med_idx) 1199 { 1200 pjsua_call_media *call_med; 1201 pjmedia_sdp_session *sdp; 1202 pj_status_t status; 1203 1204 /* Verify and normalize media index */ 1205 if (med_idx == -1) { 1206 int first_active; 1207 1208 call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL); 1209 if (first_active == -1) 1210 return PJ_ENOTFOUND; 1211 1212 med_idx = first_active; 1213 } 1214 1215 call_med = &call->media[med_idx]; 1216 1217 /* Verify if the stream media type is video */ 1218 if (call_med->type != PJMEDIA_TYPE_VIDEO) 1219 return PJ_EINVAL; 1220 1221 /* Verify if the stream already disabled */ 1222 if (call_med->dir != PJMEDIA_DIR_NONE) 1223 return PJ_SUCCESS; 1224 1225 /* Mark media transport to disabled */ 1226 // Don't close this here, as SDP negotiation has not been 1227 // done and stream may be still active. 1228 call_med->tp_st = PJSUA_MED_TP_DISABLED; 1229 1230 /* Get active local SDP */ 1231 status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp); 1232 if (status != PJ_SUCCESS) 1233 return status; 1234 1235 pj_assert(med_idx < (int)sdp->media_count); 1236 sdp->media[med_idx]->desc.port = 0; 1237 1238 status = call_reoffer_sdp(call->index, sdp); 1239 if (status != PJ_SUCCESS) 1240 return status; 1241 1242 return PJ_SUCCESS; 1243 } 1244 1245 1246 /* Modify a video stream in a call */ 1247 static pj_status_t call_modify_video(pjsua_call *call, 1248 int med_idx, 1249 pjmedia_vid_dev_index cap_dev) 1250 { 1251 pjsua_call_media *call_med; 1252 pjmedia_vid_dev_info info; 1253 pjsua_vid_win *w, *new_w = NULL; 1254 pjsua_vid_win_id wid, new_wid; 1255 pjmedia_port *media_port; 1256 pj_status_t status; 1257 1258 /* Verify and normalize media index */ 1259 if (med_idx == -1) { 1260 int first_active; 1261 1262 call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL); 1263 if (first_active == -1) 1264 return PJ_ENOTFOUND; 1265 1266 med_idx = first_active; 1267 } 1268 1269 call_med = &call->media[med_idx]; 1270 1271 /* Verify if the stream media type is video */ 1272 if (call_med->type != PJMEDIA_TYPE_VIDEO) 1273 return PJ_EINVAL; 1274 1275 /* Verify the capture device */ 1276 status = pjmedia_vid_dev_get_info(cap_dev, &info); 1277 if (status != PJ_SUCCESS) 1278 return status; 1279 1280 if (info.dir != PJMEDIA_DIR_CAPTURE) 1281 return PJ_EINVAL; 1282 1283 cap_dev = info.id; 1284 1285 /* The specified capture device is being used already */ 1286 if (call_med->strm.v.cap_dev == cap_dev) 1287 return PJ_SUCCESS; 1288 1289 /* == Apply the new capture device == */ 1290 1291 wid = call_med->strm.v.cap_win_id; 1292 w = &pjsua_var.win[wid]; 1293 pj_assert(w->type == PJSUA_WND_TYPE_PREVIEW && w->vp_cap); 1294 1295 status = pjmedia_vid_stream_get_port(call_med->strm.v.stream, 1296 PJMEDIA_DIR_ENCODING, &media_port); 1297 if (status != PJ_SUCCESS) 1298 return status; 1299 1300 /* = Detach stream port from the old capture device = */ 1301 status = pjmedia_vid_port_disconnect(w->vp_cap); 1302 if (status != PJ_SUCCESS) 1303 return status; 1304 1305 status = pjmedia_vid_tee_remove_dst_port(w->tee, media_port); 1306 if (status != PJ_SUCCESS) { 1307 /* Connect back the old capturer */ 1308 pjmedia_vid_port_connect(w->vp_cap, media_port, PJ_FALSE); 1309 return status; 1310 } 1311 1312 /* = Attach stream port to the new capture device = */ 1313 1314 /* Create preview video window */ 1315 status = create_vid_win(PJSUA_WND_TYPE_PREVIEW, 1316 &media_port->info.fmt, 1317 call_med->strm.v.rdr_dev, 1318 cap_dev, 1319 PJ_FALSE, 1320 &new_wid); 1321 if (status != PJ_SUCCESS) 1322 goto on_error; 1323 1324 inc_vid_win(new_wid); 1325 new_w = &pjsua_var.win[new_wid]; 1326 1327 /* Connect stream to capturer (via video window tee) */ 1328 status = pjmedia_vid_tee_add_dst_port2(new_w->tee, 0, media_port); 1329 if (status != PJ_SUCCESS) 1330 goto on_error; 1331 1332 /* Connect capturer to tee */ 1333 status = pjmedia_vid_port_connect(new_w->vp_cap, new_w->tee, PJ_FALSE); 1334 if (status != PJ_SUCCESS) 1335 return status; 1336 1337 /* Start renderer */ 1338 status = pjmedia_vid_port_start(new_w->vp_rend); 1339 if (status != PJ_SUCCESS) 1340 goto on_error; 1341 1342 /* Start capturer */ 1343 status = pjmedia_vid_port_start(new_w->vp_cap); 1344 if (status != PJ_SUCCESS) 1345 goto on_error; 1346 1347 /* Finally */ 1348 call_med->strm.v.cap_dev = cap_dev; 1349 call_med->strm.v.cap_win_id = new_wid; 1350 dec_vid_win(wid); 1351 1352 return PJ_SUCCESS; 1353 1354 on_error: 1355 if (new_w) { 1356 /* Disconnect media port from the new capturer */ 1357 pjmedia_vid_tee_remove_dst_port(new_w->tee, media_port); 1358 /* Release the new capturer */ 1359 dec_vid_win(new_wid); 1360 } 1361 1362 /* Revert back to the old capturer */ 1363 status = pjmedia_vid_tee_add_dst_port2(w->tee, 0, media_port); 1364 if (status != PJ_SUCCESS) 1365 return status; 1366 1367 status = pjmedia_vid_port_connect(w->vp_cap, w->tee, PJ_FALSE); 1368 if (status != PJ_SUCCESS) 1369 return status; 1370 1371 return status; 1372 } 1373 1374 1375 /* Start transmitting video stream in a call */ 1376 static pj_status_t call_start_tx_video(pjsua_call *call, 1377 int med_idx, 1378 pjmedia_vid_dev_index cap_dev) 1379 { 1380 pjsua_call_media *call_med; 1381 pj_status_t status; 1382 1383 /* Verify and normalize media index */ 1384 if (med_idx == -1) { 1385 int first_active; 1386 1387 call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL); 1388 if (first_active == -1) 1389 return PJ_ENOTFOUND; 1390 1391 med_idx = first_active; 1392 } 1393 1394 call_med = &call->media[med_idx]; 1395 1396 /* Verify if the stream is transmitting video */ 1397 if (call_med->type != PJMEDIA_TYPE_VIDEO || 1398 (call_med->dir & PJMEDIA_DIR_ENCODING) == 0) 1399 { 1400 return PJ_EINVAL; 1401 } 1402 1403 /* Apply the new capture device */ 1404 status = call_modify_video(call, med_idx, cap_dev); 1405 if (status != PJ_SUCCESS) 1406 return status; 1407 1408 /* Start stream in encoding direction */ 1409 status = pjmedia_vid_stream_resume(call_med->strm.v.stream, 1410 PJMEDIA_DIR_ENCODING); 1411 if (status != PJ_SUCCESS) 1412 return status; 1413 1414 return PJ_SUCCESS; 1415 } 1416 1417 1418 /* Stop transmitting video stream in a call */ 1419 static pj_status_t call_stop_tx_video(pjsua_call *call, 1420 int med_idx) 1421 { 1422 pjsua_call_media *call_med; 1423 pj_status_t status; 1424 1425 /* Verify and normalize media index */ 1426 if (med_idx == -1) { 1427 int first_active; 1428 1429 call_get_vid_strm_info(call, &first_active, NULL, NULL, NULL); 1430 if (first_active == -1) 1431 return PJ_ENOTFOUND; 1432 1433 med_idx = first_active; 1434 } 1435 1436 call_med = &call->media[med_idx]; 1437 1438 /* Verify if the stream is transmitting video */ 1439 if (call_med->type != PJMEDIA_TYPE_VIDEO || 1440 (call_med->dir & PJMEDIA_DIR_ENCODING) == 0) 1441 { 1442 return PJ_EINVAL; 1443 } 1444 1445 /* Pause stream in encoding direction */ 1446 status = pjmedia_vid_stream_pause( call_med->strm.v.stream, 1447 PJMEDIA_DIR_ENCODING); 1448 if (status != PJ_SUCCESS) 1449 return status; 1450 1451 return PJ_SUCCESS; 1452 } 1453 1454 1455 /* 1456 * Start, stop, and/or manipulate video transmission for the specified call. 1457 */ 1458 PJ_DEF(pj_status_t) pjsua_call_set_vid_strm ( 1459 pjsua_call_id call_id, 1460 pjsua_call_vid_strm_op op, 1461 const pjsua_call_vid_strm_op_param *param) 1462 { 1463 pjsua_call *call; 1464 pjsua_call_vid_strm_op_param param_; 1465 pj_status_t status; 1466 1467 PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls, 1468 PJ_EINVAL); 1469 1470 PJSUA_LOCK(); 1471 1472 call = &pjsua_var.calls[call_id]; 1473 1474 if (param) { 1475 param_ = *param; 1476 } else { 1477 param_.med_idx = -1; 1478 param_.cap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 1479 } 1480 1481 /* Get real capture ID, if set to PJMEDIA_VID_DEFAULT_CAPTURE_DEV */ 1482 if (param_.cap_dev == PJMEDIA_VID_DEFAULT_CAPTURE_DEV) { 1483 pjmedia_vid_dev_info info; 1484 pjmedia_vid_dev_get_info(param_.cap_dev, &info); 1485 param_.cap_dev = info.id; 1486 } 1487 1488 switch (op) { 1489 case PJSUA_CALL_VID_STRM_ADD: 1490 status = call_add_video(call, param_.cap_dev); 1491 break; 1492 case PJSUA_CALL_VID_STRM_REMOVE: 1493 status = call_remove_video(call, param_.med_idx); 1494 break; 1495 case PJSUA_CALL_VID_STRM_MODIFY: 1496 status = call_modify_video(call, param_.med_idx, param_.cap_dev); 1497 break; 1498 case PJSUA_CALL_VID_STRM_START_TRANSMIT: 1499 status = call_start_tx_video(call, param_.med_idx, param_.cap_dev); 1500 break; 1501 case PJSUA_CALL_VID_STRM_STOP_TRANSMIT: 1502 status = call_stop_tx_video(call, param_.med_idx); 1503 break; 1504 default: 1505 status = PJ_EINVALIDOP; 1506 break; 1507 } 1508 1509 PJSUA_UNLOCK(); 1510 1511 return status; 1512 } 1513 1009 1514 1010 1515 #endif /* PJSUA_HAS_VIDEO */
Note: See TracChangeset
for help on using the changeset viewer.