Changeset 4071
- Timestamp:
- Apr 24, 2012 5:40:32 AM (13 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r3982 r4071 137 137 unsigned med_cnt; /**< Number of media in SDP. */ 138 138 pjsua_call_media media[PJSUA_MAX_CALL_MEDIA]; /**< Array of media */ 139 unsigned med_prov_cnt;/**< Number of provisional media. */ 140 pjsua_call_media media_prov[PJSUA_MAX_CALL_MEDIA]; 141 /**< Array of provisional media. */ 142 139 143 int audio_idx; /**< First active audio media. */ 140 144 pj_mutex_t *med_ch_mutex;/**< Media channel callback's mutex. */ … … 604 608 void pjsua_set_media_tp_state(pjsua_call_media *call_med, pjsua_med_tp_st tp_st); 605 609 610 void pjsua_media_prov_clean_up(pjsua_call_id call_id); 611 606 612 /* Callback to receive media events */ 607 613 pj_status_t call_media_on_event(pjmedia_event *event, -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
r4068 r4071 545 545 call->opt = *opt; 546 546 547 /* Reinit media channel when media count is changed */ 548 if (opt->aud_cnt != old_opt.aud_cnt || 549 opt->vid_cnt != old_opt.vid_cnt) 547 /* Reinit media channel when media count is changed or we are the 548 * answerer (as remote offer may 'extremely' modify the existing 549 * media session, e.g: media type order). 550 */ 551 if (rem_sdp || 552 opt->aud_cnt!=old_opt.aud_cnt || opt->vid_cnt!=old_opt.vid_cnt) 550 553 { 551 554 pjsip_role_e role = rem_sdp? PJSIP_ROLE_UAS : PJSIP_ROLE_UAC; … … 1199 1202 pjsip_dlg_terminate(dlg); 1200 1203 */ 1201 pjsua_media_channel_deinit(call->index);1202 1204 goto on_return; 1203 1205 } … … 1318 1320 if (status != PJ_SUCCESS) { 1319 1321 pjsua_perror(THIS_FILE, "Unable to send 100 response", status); 1322 pjsua_media_channel_deinit(call->index); 1320 1323 goto on_return; 1321 1324 } … … 3225 3228 pjsua_perror(THIS_FILE, "SDP negotiation has failed", status); 3226 3229 3230 /* Clean up provisional media */ 3231 pjsua_media_prov_clean_up(call->index); 3232 3227 3233 /* Do not deinitialize media since this may be a re-INVITE or 3228 3234 * UPDATE (which in this case the media should not get affected … … 3428 3434 call->opt = opt; 3429 3435 } 3430 3436 3431 3437 /* Re-init media for the new remote offer before creating SDP */ 3432 status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAS, 3433 call->secure_level, 3434 call->inv->pool_prov, 3435 offer, NULL, 3436 PJ_FALSE, NULL); 3437 if (status != PJ_SUCCESS) { 3438 pjsua_perror(THIS_FILE, "Error re-initializing media channel", status); 3439 goto on_return; 3440 } 3438 status = apply_call_setting(call, &call->opt, offer); 3439 if (status != PJ_SUCCESS) 3440 goto on_return; 3441 3441 3442 3442 status = pjsua_media_channel_create_sdp(call->index, -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r4043 r4071 2771 2771 2772 2772 PJ_LOG(3,(THIS_FILE, "Dumping media transports:")); 2773 // Suppress compile warning caused by unreferenced var.2774 PJ_UNUSED_ARG(i);2775 #if DISABLED_FOR_TICKET_11852776 2773 for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) { 2777 2774 pjsua_call *call = &pjsua_var.calls[i]; 2778 pjmedia_transport_info tpinfo; 2779 char addr_buf[80]; 2780 2781 /* MSVC complains about tpinfo not being initialized */ 2782 //pj_bzero(&tpinfo, sizeof(tpinfo)); 2783 2784 pjmedia_transport_info_init(&tpinfo); 2785 pjmedia_transport_get_info(call->med_tp, &tpinfo); 2786 2787 PJ_LOG(3,(THIS_FILE, " %s: %s", 2788 (pjsua_var.media_cfg.enable_ice ? "ICE" : "UDP"), 2789 pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name, addr_buf, 2790 sizeof(addr_buf), 3))); 2791 } 2792 #endif 2775 pjmedia_transport *tp[PJSUA_MAX_CALL_MEDIA*2]; 2776 unsigned tp_cnt = 0; 2777 unsigned j; 2778 2779 /* Collect media transports in this call */ 2780 for (j = 0; j < call->med_cnt; ++j) { 2781 if (call->media[j].tp != NULL) 2782 tp[tp_cnt++] = call->media[j].tp; 2783 } 2784 for (j = 0; j < call->med_prov_cnt; ++j) { 2785 pjmedia_transport *med_tp = call->media_prov[j].tp; 2786 if (med_tp) { 2787 unsigned k; 2788 pj_bool_t used = PJ_FALSE; 2789 for (k = 0; k < tp_cnt; ++k) { 2790 if (med_tp == tp[k]) { 2791 used = PJ_TRUE; 2792 break; 2793 } 2794 } 2795 if (!used) 2796 tp[tp_cnt++] = med_tp; 2797 } 2798 } 2799 2800 /* Dump the media transports in this call */ 2801 for (j = 0; j < tp_cnt; ++j) { 2802 pjmedia_transport_info tpinfo; 2803 char addr_buf[80]; 2804 2805 pjmedia_transport_info_init(&tpinfo); 2806 pjmedia_transport_get_info(tp[j], &tpinfo); 2807 PJ_LOG(3,(THIS_FILE, " %s: %s", 2808 (pjsua_var.media_cfg.enable_ice ? "ICE" : "UDP"), 2809 pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name, 2810 addr_buf, 2811 sizeof(addr_buf), 3))); 2812 } 2813 } 2793 2814 2794 2815 pjsip_tsx_layer_dump(detail); -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r4011 r4071 1146 1146 pjmedia_srtp_setting_default(&srtp_opt); 1147 1147 srtp_opt.close_member_tp = PJ_TRUE; 1148 1148 1149 /* If media session has been ever established, let's use remote's 1149 1150 * preference in SRTP usage policy, especially when it is stricter. … … 1180 1181 on_return: 1181 1182 if (status != PJ_SUCCESS && call_med->tp) { 1183 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 1182 1184 pjmedia_transport_close(call_med->tp); 1183 1185 call_med->tp = NULL; … … 1218 1220 call_med->type = type; 1219 1221 1220 /* Create the media transport for initial call. */ 1222 /* Create the media transport for initial call. Here are the possible 1223 * media transport state and the action needed: 1224 * - PJSUA_MED_TP_NULL or call_med->tp==NULL, create one. 1225 * - PJSUA_MED_TP_RUNNING, do nothing. 1226 * - PJSUA_MED_TP_DISABLED, re-init (media_create(), etc). Currently, 1227 * this won't happen as media_channel_update() will always clean up 1228 * the unused transport of a disabled media. 1229 */ 1221 1230 if (call_med->tp == NULL) { 1222 1231 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0) … … 1258 1267 } else if (call_med->tp_st == PJSUA_MED_TP_DISABLED) { 1259 1268 /* Media is being reenabled. */ 1260 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_INIT); 1269 //pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 1270 1271 pj_assert(!"Currently no media transport reuse"); 1261 1272 } 1262 1273 … … 1281 1292 * has completed. 1282 1293 */ 1283 call->media [info->med_idx].med_init_cb = NULL;1294 call->media_prov[info->med_idx].med_init_cb = NULL; 1284 1295 1285 1296 /* In case of failure, save the information to be returned … … 1292 1303 * callbacks. 1293 1304 */ 1294 for (mi=0; mi < call->med_ cnt; ++mi) {1295 pjsua_call_media *call_med = &call->media [mi];1305 for (mi=0; mi < call->med_prov_cnt; ++mi) { 1306 pjsua_call_media *call_med = &call->media_prov[mi]; 1296 1307 1297 1308 if (call_med->med_init_cb) { … … 1314 1325 1315 1326 if (status != PJ_SUCCESS) { 1316 pjsua_media_channel_deinit(call_id);1327 pjsua_media_prov_clean_up(call_id); 1317 1328 goto on_return; 1318 1329 } 1319 1330 1320 1331 /* Tell the media transport of a new offer/answer session */ 1321 for (mi=0; mi < call->med_ cnt; ++mi) {1322 pjsua_call_media *call_med = &call->media [mi];1332 for (mi=0; mi < call->med_prov_cnt; ++mi) { 1333 pjsua_call_media *call_med = &call->media_prov[mi]; 1323 1334 1324 1335 /* Note: tp may be NULL if this media line is disabled */ … … 1355 1366 call->med_ch_info.state = call_med->tp_st; 1356 1367 call->med_ch_info.sip_err_code = PJSIP_SC_NOT_ACCEPTABLE; 1357 pjsua_media_ channel_deinit(call_id);1368 pjsua_media_prov_clean_up(call_id); 1358 1369 goto on_return; 1359 1370 } … … 1371 1382 return status; 1372 1383 } 1384 1385 1386 /* Clean up media transports in provisional media that is not used 1387 * by call media. 1388 */ 1389 void pjsua_media_prov_clean_up(pjsua_call_id call_id) 1390 { 1391 pjsua_call *call = &pjsua_var.calls[call_id]; 1392 unsigned i; 1393 1394 for (i = 0; i < call->med_prov_cnt; ++i) { 1395 pjsua_call_media *call_med = &call->media_prov[i]; 1396 unsigned j; 1397 pj_bool_t used = PJ_FALSE; 1398 1399 if (call_med->tp == NULL) 1400 continue; 1401 1402 for (j = 0; j < call->med_cnt; ++j) { 1403 if (call->media[j].tp == call_med->tp) { 1404 used = PJ_TRUE; 1405 break; 1406 } 1407 } 1408 1409 if (!used) { 1410 if (call_med->tp_st > PJSUA_MED_TP_IDLE) { 1411 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 1412 pjmedia_transport_media_stop(call_med->tp); 1413 } 1414 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 1415 pjmedia_transport_close(call_med->tp); 1416 call_med->tp = call_med->tp_orig = NULL; 1417 } 1418 } 1419 } 1420 1373 1421 1374 1422 pj_status_t pjsua_media_channel_init(pjsua_call_id call_id, … … 1423 1471 pj_log_push_indent(); 1424 1472 1473 /* Init provisional media state */ 1474 if (call->med_cnt == 0) { 1475 /* New media session, just copy whole from call media state. */ 1476 pj_memcpy(call->media_prov, call->media, sizeof(call->media)); 1477 } else { 1478 /* Clean up any unused transports. Note that when local SDP reoffer 1479 * is rejected by remote, there may be any initialized transports that 1480 * are not used by call media and currently there is no notification 1481 * from PJSIP level regarding the reoffer rejection. 1482 */ 1483 pjsua_media_prov_clean_up(call_id); 1484 1485 /* Updating media session, copy from call media state. */ 1486 pj_memcpy(call->media_prov, call->media, 1487 sizeof(call->media[0]) * call->med_cnt); 1488 } 1489 call->med_prov_cnt = call->med_cnt; 1490 1425 1491 #if DISABLED_FOR_TICKET_1185 1426 1492 /* Return error if media transport has not been created yet … … 1442 1508 /* Expecting audio in the offer */ 1443 1509 if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 1444 pjsua_media_channel_deinit(call_id);1445 1510 status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE); 1446 1511 goto on_error; … … 1459 1524 * count setting (of the call setting) before the SDP negotiation. 1460 1525 */ 1461 if (call->med_cnt < rem_sdp->media_count) 1462 call->med_cnt = PJ_MIN(rem_sdp->media_count, PJSUA_MAX_CALL_MEDIA); 1526 if (call->med_prov_cnt < rem_sdp->media_count) 1527 call->med_prov_cnt = PJ_MIN(rem_sdp->media_count, 1528 PJSUA_MAX_CALL_MEDIA); 1463 1529 1464 1530 call->rem_offerer = PJ_TRUE; … … 1496 1562 { 1497 1563 for (mi = 0; mi < call->opt.aud_cnt - mtotaudcnt; ++mi) 1498 maudidx[maudcnt++] = (pj_uint8_t)call->med_ cnt++;1564 maudidx[maudcnt++] = (pj_uint8_t)call->med_prov_cnt++; 1499 1565 1500 1566 mtotaudcnt = call->opt.aud_cnt; … … 1507 1573 { 1508 1574 for (mi = 0; mi < call->opt.vid_cnt - mtotvidcnt; ++mi) 1509 mvididx[mvidcnt++] = (pj_uint8_t)call->med_ cnt++;1575 mvididx[mvidcnt++] = (pj_uint8_t)call->med_prov_cnt++; 1510 1576 1511 1577 mtotvidcnt = call->opt.vid_cnt; … … 1523 1589 mvididx[mi] = (pj_uint8_t)(maudcnt + mi); 1524 1590 } 1525 call->med_ cnt = maudcnt + mvidcnt;1591 call->med_prov_cnt = maudcnt + mvidcnt; 1526 1592 1527 1593 /* Need to publish supported media? */ … … 1529 1595 if (mtotaudcnt == 0) { 1530 1596 mtotaudcnt = 1; 1531 maudidx[0] = (pj_uint8_t)call->med_ cnt++;1597 maudidx[0] = (pj_uint8_t)call->med_prov_cnt++; 1532 1598 } 1533 1599 #if PJMEDIA_HAS_VIDEO 1534 1600 if (mtotvidcnt == 0) { 1535 1601 mtotvidcnt = 1; 1536 mvididx[0] = (pj_uint8_t)call->med_ cnt++;1602 mvididx[0] = (pj_uint8_t)call->med_prov_cnt++; 1537 1603 } 1538 1604 #endif … … 1543 1609 } 1544 1610 1545 if (call->med_ cnt == 0) {1611 if (call->med_prov_cnt == 0) { 1546 1612 /* Expecting at least one media */ 1547 1613 if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE_HERE; 1548 pjsua_media_channel_deinit(call_id);1549 1614 status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE_HERE); 1550 1615 goto on_error; … … 1565 1630 1566 1631 /* Initialize each media line */ 1567 for (mi=0; mi < call->med_ cnt; ++mi) {1568 pjsua_call_media *call_med = &call->media [mi];1632 for (mi=0; mi < call->med_prov_cnt; ++mi) { 1633 pjsua_call_media *call_med = &call->media_prov[mi]; 1569 1634 pj_bool_t enabled = PJ_FALSE; 1570 1635 pjmedia_type media_type = PJMEDIA_TYPE_UNKNOWN; … … 1610 1675 } 1611 1676 1612 pjsua_media_ channel_deinit(call_id);1677 pjsua_media_prov_clean_up(call_id); 1613 1678 goto on_error; 1614 1679 } … … 1619 1684 if (call_med->tp) { 1620 1685 // Don't close transport here, as SDP negotiation has not been 1621 // done and stream may be still active. 1686 // done and stream may be still active. Once SDP negotiation 1687 // is done (channel_update() invoked), this transport will be 1688 // closed there. 1622 1689 //pjmedia_transport_close(call_med->tp); 1623 1690 //call_med->tp = NULL; … … 1736 1803 /* Get one address to use in the origin field */ 1737 1804 pj_bzero(&origin, sizeof(origin)); 1738 for (mi=0; mi<call->med_ cnt; ++mi) {1805 for (mi=0; mi<call->med_prov_cnt; ++mi) { 1739 1806 pjmedia_transport_info tpinfo; 1740 1807 1741 if (call->media [mi].tp == NULL)1808 if (call->media_prov[mi].tp == NULL) 1742 1809 continue; 1743 1810 1744 1811 pjmedia_transport_info_init(&tpinfo); 1745 pjmedia_transport_get_info(call->media [mi].tp, &tpinfo);1812 pjmedia_transport_get_info(call->media_prov[mi].tp, &tpinfo); 1746 1813 pj_sockaddr_cp(&origin, &tpinfo.sock_info.rtp_addr_name); 1747 1814 break; … … 1755 1822 1756 1823 /* Process each media line */ 1757 for (mi=0; mi<call->med_ cnt; ++mi) {1758 pjsua_call_media *call_med = &call->media [mi];1824 for (mi=0; mi<call->med_prov_cnt; ++mi) { 1825 pjsua_call_media *call_med = &call->media_prov[mi]; 1759 1826 pjmedia_sdp_media *m = NULL; 1760 1827 pjmedia_transport_info tpinfo; … … 1999 2066 call_med->prev_state = call_med->state; 2000 2067 call_med->state = PJSUA_CALL_MEDIA_NONE; 2068 2069 /* Try to sync recent changes to provisional media */ 2070 if (mi<call->med_prov_cnt && call->media_prov[mi].tp==call_med->tp) 2071 { 2072 pjsua_call_media *prov_med = &call->media_prov[mi]; 2073 2074 /* Media state */ 2075 prov_med->prev_state = call_med->prev_state; 2076 prov_med->state = call_med->state; 2077 2078 /* RTP seq/ts */ 2079 prov_med->rtp_tx_seq_ts_set = call_med->rtp_tx_seq_ts_set; 2080 prov_med->rtp_tx_seq = call_med->rtp_tx_seq; 2081 prov_med->rtp_tx_ts = call_med->rtp_tx_ts; 2082 2083 /* Stream */ 2084 if (call_med->type == PJMEDIA_TYPE_AUDIO) { 2085 prov_med->strm.a.conf_slot = call_med->strm.a.conf_slot; 2086 prov_med->strm.a.stream = call_med->strm.a.stream; 2087 } 2088 #if PJMEDIA_HAS_VIDEO 2089 else if (call_med->type == PJMEDIA_TYPE_VIDEO) { 2090 prov_med->strm.v.cap_win_id = call_med->strm.v.cap_win_id; 2091 prov_med->strm.v.rdr_win_id = call_med->strm.v.rdr_win_id; 2092 prov_med->strm.v.stream = call_med->strm.v.stream; 2093 } 2094 #endif 2095 } 2001 2096 } 2002 2097 … … 2029 2124 stop_media_session(call_id); 2030 2125 2126 /* Clean up media transports */ 2127 pjsua_media_prov_clean_up(call_id); 2128 call->med_prov_cnt = 0; 2031 2129 for (mi=0; mi<call->med_cnt; ++mi) { 2032 2130 pjsua_call_media *call_med = &call->media[mi]; 2033 2131 2034 2132 if (call_med->tp_st > PJSUA_MED_TP_IDLE) { 2133 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 2035 2134 pjmedia_transport_media_stop(call_med->tp); 2036 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE); 2037 } 2038 2039 //if (call_med->tp_orig && call_med->tp && 2040 // call_med->tp != call_med->tp_orig) 2041 //{ 2042 // pjmedia_transport_close(call_med->tp); 2043 // call_med->tp = call_med->tp_orig; 2044 //} 2135 } 2136 2045 2137 if (call_med->tp) { 2138 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 2046 2139 pjmedia_transport_close(call_med->tp); 2047 2140 call_med->tp = call_med->tp_orig = NULL; … … 2089 2182 * it may not be equal when remote removed any SDP media line. 2090 2183 */ 2091 pj_assert(call->med_ cnt >= local_sdp->media_count);2184 pj_assert(call->med_prov_cnt >= local_sdp->media_count); 2092 2185 2093 2186 /* Reset audio_idx first */ … … 2136 2229 2137 2230 /* Process each media stream */ 2138 for (mi=0; mi < call->med_ cnt; ++mi) {2139 pjsua_call_media *call_med = &call->media [mi];2231 for (mi=0; mi < call->med_prov_cnt; ++mi) { 2232 pjsua_call_media *call_med = &call->media_prov[mi]; 2140 2233 2141 2234 if (mi >= local_sdp->media_count || … … 2288 2381 /* Check if no media is active */ 2289 2382 if (si->dir == PJMEDIA_DIR_NONE) { 2290 /* Call media state*/2383 /* Update call media state and direction */ 2291 2384 call_med->state = PJSUA_CALL_MEDIA_NONE; 2292 2293 /* Call media direction */2294 2385 call_med->dir = PJMEDIA_DIR_NONE; 2295 2386 … … 2394 2485 */ 2395 2486 if (local_sdp->media[mi]->desc.port==0 && call_med->tp) { 2487 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 2396 2488 pjmedia_transport_close(call_med->tp); 2397 2489 call_med->tp = call_med->tp_orig = NULL; 2398 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_IDLE);2399 2490 } 2400 2491 … … 2406 2497 } 2407 2498 } 2499 2500 /* Update call media from provisional media */ 2501 call->med_cnt = call->med_prov_cnt; 2502 pj_memcpy(call->media, call->media_prov, 2503 sizeof(call->media_prov[0]) * call->med_prov_cnt); 2408 2504 2409 2505 /* Perform SDP re-negotiation if needed. */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c
r4060 r4071 1533 1533 sdp = pjmedia_sdp_session_clone(call->inv->pool_prov, current_sdp); 1534 1534 1535 /* Clean up provisional media before using it */ 1536 pjsua_media_prov_clean_up(call->index); 1537 1538 /* Update provisional media from call media */ 1539 call->med_prov_cnt = call->med_cnt; 1540 pj_memcpy(call->media_prov, call->media, 1541 sizeof(call->media[0]) * call->med_cnt); 1542 1535 1543 /* Initialize call media */ 1536 call_med = &call->media[call->med_cnt++]; 1537 1544 call_med = &call->media_prov[call->med_prov_cnt++]; 1538 1545 status = pjsua_call_media_init(call_med, PJMEDIA_TYPE_VIDEO, 1539 1546 &acc_cfg->rtp_cfg, call->secure_level, … … 1598 1605 on_error: 1599 1606 if (call_med->tp) { 1607 pjsua_set_media_tp_state(call_med, PJSUA_MED_TP_NULL); 1600 1608 pjmedia_transport_close(call_med->tp); 1601 1609 call_med->tp = call_med->tp_orig = NULL; … … 1630 1638 } 1631 1639 1632 call_med = &call->media[med_idx]; 1640 /* Clean up provisional media before using it */ 1641 pjsua_media_prov_clean_up(call->index); 1642 1643 /* Update provisional media from call media */ 1644 call->med_prov_cnt = call->med_cnt; 1645 pj_memcpy(call->media_prov, call->media, 1646 sizeof(call->media[0]) * call->med_cnt); 1647 1648 call_med = &call->media_prov[med_idx]; 1633 1649 1634 1650 /* Verify if the stream media type is video */ … … 1736 1752 on_error: 1737 1753 if (status != PJ_SUCCESS) { 1754 pjsua_media_prov_clean_up(call->index); 1738 1755 return status; 1739 1756 }
Note: See TracChangeset
for help on using the changeset viewer.