Changeset 3999 for pjproject/trunk/pjmedia/src/pjmedia/stream.c
- Timestamp:
- Mar 30, 2012 7:10:13 AM (11 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk
-
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r3982 r3999 156 156 pj_bool_t initial_rr; /**< Initial RTCP RR sent */ 157 157 pj_bool_t rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/ 158 void *out_rtcp_pkt; /**< Outgoing RTCP packet. */ 159 unsigned out_rtcp_pkt_size; 160 /**< Outgoing RTCP packet size. */ 158 161 159 162 /* RFC 2833 DTMF transmission queue: */ … … 246 249 247 250 251 static pj_status_t send_rtcp(pjmedia_stream *stream, 252 pj_bool_t with_sdes, 253 pj_bool_t with_bye, 254 pj_bool_t with_xr); 255 256 248 257 #if TRACE_JB 249 258 … … 426 435 427 436 /* Send RTCP */ 428 pjmedia_rtcp_build_rtcp(&stream->rtcp, &pkt, &pkt_len); 429 pjmedia_transport_send_rtcp(stream->transport, pkt, pkt_len); 437 send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE); 430 438 431 439 #elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER … … 914 922 915 923 924 static pj_status_t send_rtcp(pjmedia_stream *stream, 925 pj_bool_t with_sdes, 926 pj_bool_t with_bye, 927 pj_bool_t with_xr) 928 { 929 void *sr_rr_pkt; 930 pj_uint8_t *pkt; 931 int len, max_len; 932 pj_status_t status; 933 934 /* Build RTCP RR/SR packet */ 935 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 936 937 #if !defined(PJMEDIA_HAS_RTCP_XR) || (PJMEDIA_HAS_RTCP_XR == 0) 938 with_xr = PJ_FALSE; 939 #endif 940 941 if (with_sdes || with_bye || with_xr) { 942 pkt = (pj_uint8_t*) stream->out_rtcp_pkt; 943 pj_memcpy(pkt, sr_rr_pkt, len); 944 max_len = stream->out_rtcp_pkt_size; 945 } else { 946 pkt = sr_rr_pkt; 947 max_len = len; 948 } 949 950 /* Build RTCP SDES packet */ 951 if (with_sdes) { 952 pjmedia_rtcp_sdes sdes; 953 pj_size_t sdes_len; 954 955 pj_bzero(&sdes, sizeof(sdes)); 956 sdes.cname = stream->cname; 957 sdes_len = max_len - len; 958 status = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len, 959 &sdes_len, &sdes); 960 if (status != PJ_SUCCESS) { 961 PJ_PERROR(4,(stream->port.info.name.ptr, status, 962 "Error generating RTCP SDES")); 963 } else { 964 len += sdes_len; 965 } 966 } 967 968 /* Build RTCP XR packet */ 969 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 970 if (with_xr) { 971 int i; 972 pjmedia_jb_state jb_state; 973 void *xr_pkt; 974 int xr_len; 975 976 /* Update RTCP XR with current JB states */ 977 pjmedia_jbuf_get_state(stream->jb, &jb_state); 978 979 i = jb_state.avg_delay; 980 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 981 PJMEDIA_RTCP_XR_INFO_JB_NOM, i); 982 pj_assert(status == PJ_SUCCESS); 983 984 i = jb_state.max_delay; 985 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 986 PJMEDIA_RTCP_XR_INFO_JB_MAX, i); 987 pj_assert(status == PJ_SUCCESS); 988 989 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, 990 &xr_pkt, &xr_len); 991 992 if (xr_len + len <= max_len) { 993 pj_memcpy(pkt+len, xr_pkt, xr_len); 994 len += xr_len; 995 996 /* Send the RTCP XR to third-party destination if specified */ 997 if (stream->rtcp_xr_dest_len) { 998 pjmedia_transport_send_rtcp2(stream->transport, 999 &stream->rtcp_xr_dest, 1000 stream->rtcp_xr_dest_len, 1001 xr_pkt, xr_len); 1002 } 1003 1004 } else { 1005 PJ_PERROR(4,(stream->port.info.name.ptr, PJ_ETOOBIG, 1006 "Error generating RTCP-XR")); 1007 } 1008 } 1009 #endif 1010 1011 /* Build RTCP BYE packet */ 1012 if (with_bye) { 1013 pj_size_t bye_len; 1014 1015 bye_len = max_len - len; 1016 status = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len, 1017 &bye_len, NULL); 1018 if (status != PJ_SUCCESS) { 1019 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1020 "Error generating RTCP BYE")); 1021 } else { 1022 len += bye_len; 1023 } 1024 } 1025 1026 /* Send! */ 1027 status = pjmedia_transport_send_rtcp(stream->transport, pkt, len); 1028 1029 return status; 1030 } 1031 916 1032 /** 917 1033 * check_tx_rtcp() … … 927 1043 */ 928 1044 929 930 1045 if (stream->rtcp_last_tx == 0) { 931 1046 … … 933 1048 934 1049 } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) { 935 936 void *rtcp_pkt; 937 int len; 938 939 pjmedia_rtcp_build_rtcp(&stream->rtcp, &rtcp_pkt, &len); 940 941 pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); 1050 pj_bool_t with_xr = PJ_FALSE; 1051 pj_status_t status; 1052 1053 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 1054 if (stream->rtcp.xr_enabled) { 1055 if (stream->rtcp_xr_last_tx == 0) { 1056 stream->rtcp_xr_last_tx = timestamp; 1057 } else if (timestamp - stream->rtcp_xr_last_tx >= 1058 stream->rtcp_xr_interval) 1059 { 1060 with_xr = PJ_TRUE; 1061 1062 /* Update last tx RTCP XR */ 1063 stream->rtcp_xr_last_tx = timestamp; 1064 } 1065 } 1066 #endif 1067 1068 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE, 1069 with_xr); 1070 if (status != PJ_SUCCESS) { 1071 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1072 "Error sending RTCP")); 1073 } 942 1074 943 1075 stream->rtcp_last_tx = timestamp; 944 1076 } 945 946 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)947 if (stream->rtcp.xr_enabled) {948 949 if (stream->rtcp_xr_last_tx == 0) {950 951 stream->rtcp_xr_last_tx = timestamp;952 953 } else if (timestamp - stream->rtcp_xr_last_tx >=954 stream->rtcp_xr_interval)955 {956 int i;957 pjmedia_jb_state jb_state;958 void *rtcp_pkt;959 int len;960 961 /* Update RTCP XR with current JB states */962 pjmedia_jbuf_get_state(stream->jb, &jb_state);963 964 i = jb_state.avg_delay;965 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,966 PJMEDIA_RTCP_XR_INFO_JB_NOM,967 i);968 969 i = jb_state.max_delay;970 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,971 PJMEDIA_RTCP_XR_INFO_JB_MAX,972 i);973 974 /* Build RTCP XR packet */975 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0,976 &rtcp_pkt, &len);977 978 /* Send the RTCP XR to remote address */979 pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len);980 981 /* Send the RTCP XR to third-party destination if specified */982 if (stream->rtcp_xr_dest_len) {983 pjmedia_transport_send_rtcp2(stream->transport,984 &stream->rtcp_xr_dest,985 stream->rtcp_xr_dest_len,986 rtcp_pkt, len);987 }988 989 /* Update last tx RTCP XR */990 stream->rtcp_xr_last_tx = timestamp;991 }992 }993 #endif994 }995 996 /* Build RTCP SDES packet */997 static unsigned create_rtcp_sdes(pjmedia_stream *stream, pj_uint8_t *pkt,998 unsigned max_len)999 {1000 pjmedia_rtcp_common hdr;1001 pj_uint8_t *p = pkt;1002 1003 /* SDES header */1004 hdr.version = 2;1005 hdr.p = 0;1006 hdr.count = 1;1007 hdr.pt = 202;1008 hdr.length = 2 + (4+stream->cname.slen+3)/4 - 1;1009 if (max_len < (hdr.length << 2)) {1010 pj_assert(!"Not enough buffer for SDES packet");1011 return 0;1012 }1013 hdr.length = pj_htons((pj_uint16_t)hdr.length);1014 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;1015 pj_memcpy(p, &hdr, sizeof(hdr));1016 p += sizeof(hdr);1017 1018 /* CNAME item */1019 *p++ = 1;1020 *p++ = (pj_uint8_t)stream->cname.slen;1021 pj_memcpy(p, stream->cname.ptr, stream->cname.slen);1022 p += stream->cname.slen;1023 1024 /* END */1025 *p++ = '\0';1026 *p++ = '\0';1027 1028 /* Pad to 32bit */1029 while ((p-pkt) % 4)1030 *p++ = '\0';1031 1032 return (p - pkt);1033 }1034 1035 /* Build RTCP BYE packet */1036 static unsigned create_rtcp_bye(pjmedia_stream *stream, pj_uint8_t *pkt,1037 unsigned max_len)1038 {1039 pjmedia_rtcp_common hdr;1040 1041 /* BYE header */1042 hdr.version = 2;1043 hdr.p = 0;1044 hdr.count = 1;1045 hdr.pt = 203;1046 hdr.length = 1;1047 if (max_len < (hdr.length << 2)) {1048 pj_assert(!"Not enough buffer for SDES packet");1049 return 0;1050 }1051 hdr.length = pj_htons((pj_uint16_t)hdr.length);1052 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;1053 pj_memcpy(pkt, &hdr, sizeof(hdr));1054 1055 return sizeof(hdr);1056 1077 } 1057 1078 … … 1349 1370 1350 1371 /* Send the RTP packet to the transport. */ 1351 pjmedia_transport_send_rtp(stream->transport, channel->out_pkt, 1352 frame_out.size + sizeof(pjmedia_rtp_hdr)); 1372 status = pjmedia_transport_send_rtp(stream->transport, channel->out_pkt, 1373 frame_out.size + 1374 sizeof(pjmedia_rtp_hdr)); 1375 if (status != PJ_SUCCESS) { 1376 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1377 "Error sending RTP")); 1378 } 1353 1379 1354 1380 /* Update stat */ … … 1820 1846 /* Send RTCP RR and SDES after we receive some RTP packets */ 1821 1847 if (stream->rtcp.received >= 10 && !stream->initial_rr) { 1822 void *sr_rr_pkt; 1823 pj_uint8_t *pkt; 1824 int len; 1825 1826 /* Build RR or SR */ 1827 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 1828 1829 if (!stream->rtcp_sdes_bye_disabled) { 1830 pkt = (pj_uint8_t*) stream->enc->out_pkt; 1831 pj_memcpy(pkt, sr_rr_pkt, len); 1832 pkt += len; 1833 1834 /* Append SDES */ 1835 len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt, 1836 stream->enc->out_pkt_size - len); 1837 if (len > 0) { 1838 pkt += len; 1839 len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->out_pkt); 1840 pjmedia_transport_send_rtcp(stream->transport, 1841 stream->enc->out_pkt, len); 1842 } 1843 } else { 1844 pjmedia_transport_send_rtcp(stream->transport, sr_rr_pkt, len); 1845 } 1846 1847 stream->initial_rr = PJ_TRUE; 1848 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, 1849 PJ_FALSE, PJ_FALSE); 1850 if (status != PJ_SUCCESS) { 1851 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1852 "Error sending initial RTCP RR")); 1853 } else { 1854 stream->initial_rr = PJ_TRUE; 1855 } 1848 1856 } 1849 1857 } … … 1883 1891 pjmedia_channel *channel; 1884 1892 pj_status_t status; 1885 unsigned min_out_pkt_size;1886 1893 1887 1894 /* Allocate memory for channel descriptor */ … … 1915 1922 } 1916 1923 1917 /* It should big enough to hold (minimally) RTCP SR with an SDES. */1918 min_out_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) +1919 sizeof(pjmedia_rtcp_common) +1920 (4 + stream->cname.slen) +1921 32;1922 1923 if (channel->out_pkt_size < min_out_pkt_size)1924 channel->out_pkt_size = min_out_pkt_size;1925 1926 1924 channel->out_pkt = pj_pool_alloc(pool, channel->out_pkt_size); 1927 1925 PJ_ASSERT_RETURN(channel->out_pkt != NULL, PJ_ENOMEM); … … 2266 2264 2267 2265 pjmedia_rtcp_init2(&stream->rtcp, &rtcp_setting); 2268 } 2266 2267 if (info->rtp_seq_ts_set) { 2268 stream->rtcp.stat.rtp_tx_last_seq = info->rtp_seq; 2269 stream->rtcp.stat.rtp_tx_last_ts = info->rtp_ts; 2270 } 2271 } 2272 2273 /* Allocate outgoing RTCP buffer, should be enough to hold SR/RR, SDES, 2274 * BYE, and XR. 2275 */ 2276 stream->out_rtcp_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) + 2277 sizeof(pjmedia_rtcp_common) + 2278 (4 + stream->cname.slen) + 2279 32; 2280 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 2281 if (info->rtcp_xr_enabled) { 2282 stream->out_rtcp_pkt_size += sizeof(pjmedia_rtcp_xr_pkt); 2283 } 2284 #endif 2285 2286 if (stream->out_rtcp_pkt_size > PJMEDIA_MAX_MTU) 2287 stream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU; 2288 2289 stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size); 2269 2290 2270 2291 /* Only attach transport when stream is ready. */ … … 2392 2413 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 2393 2414 2394 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 2395 /* Send RTCP XR on stream destroy */ 2396 if (stream->rtcp.xr_enabled) { 2397 int i; 2398 pjmedia_jb_state jb_state; 2399 void *rtcp_pkt; 2400 int len; 2401 2402 /* Update RTCP XR with current JB states */ 2403 pjmedia_jbuf_get_state(stream->jb, &jb_state); 2404 2405 i = jb_state.avg_delay; 2406 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 2407 PJMEDIA_RTCP_XR_INFO_JB_NOM, 2408 i); 2409 2410 i = jb_state.max_delay; 2411 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 2412 PJMEDIA_RTCP_XR_INFO_JB_MAX, 2413 i); 2414 2415 /* Build RTCP XR packet */ 2416 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, 2417 &rtcp_pkt, &len); 2418 2419 /* Send the RTCP XR to remote address */ 2420 pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); 2421 2422 /* Send the RTCP XR to third-party destination if specified */ 2423 if (stream->rtcp_xr_dest_len) { 2424 pjmedia_transport_send_rtcp2(stream->transport, 2425 &stream->rtcp_xr_dest, 2426 stream->rtcp_xr_dest_len, 2427 rtcp_pkt, len); 2428 } 2429 } 2430 #endif 2431 2432 /* Send RTCP BYE */ 2415 /* Send RTCP BYE (also SDES & XR) */ 2433 2416 if (!stream->rtcp_sdes_bye_disabled) { 2434 pjmedia_stream_send_rtcp_bye(stream);2417 send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE); 2435 2418 } 2436 2419 … … 2800 2783 pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream ) 2801 2784 { 2802 unsigned len;2803 2804 2785 PJ_ASSERT_RETURN(stream, PJ_EINVAL); 2805 2786 2806 len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->out_pkt, 2807 stream->enc->out_pkt_size); 2808 if (len != 0) { 2809 return pjmedia_transport_send_rtcp(stream->transport, 2810 stream->enc->out_pkt, len); 2811 } 2812 2813 return PJ_SUCCESS; 2787 return send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE); 2814 2788 } 2815 2789 … … 2823 2797 2824 2798 if (stream->enc && stream->transport) { 2825 unsigned len; 2826 2827 len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->out_pkt, 2828 stream->enc->out_pkt_size); 2829 if (len != 0) { 2830 return pjmedia_transport_send_rtcp(stream->transport, 2831 stream->enc->out_pkt, len); 2832 } 2799 return send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE); 2833 2800 } 2834 2801
Note: See TracChangeset
for help on using the changeset viewer.