- Timestamp:
- Jul 13, 2011 8:51:10 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.