Changeset 3960 for pjproject/branches/1.x/pjmedia/src/pjmedia/stream.c
- Timestamp:
- Feb 27, 2012 2:41:21 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.x/pjmedia/src/pjmedia/stream.c
r3900 r3960 235 235 236 236 237 static pj_status_t send_rtcp(pjmedia_stream *stream, 238 pj_bool_t with_sdes, 239 pj_bool_t with_bye, 240 pj_bool_t with_xr); 241 242 237 243 #if TRACE_JB 238 244 … … 415 421 416 422 /* Send RTCP */ 417 pjmedia_rtcp_build_rtcp(&stream->rtcp, &pkt, &pkt_len); 418 pjmedia_transport_send_rtcp(stream->transport, pkt, pkt_len); 423 send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE); 419 424 420 425 #elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER … … 904 909 905 910 911 static pj_status_t send_rtcp(pjmedia_stream *stream, 912 pj_bool_t with_sdes, 913 pj_bool_t with_bye, 914 pj_bool_t with_xr) 915 { 916 void *sr_rr_pkt; 917 pj_uint8_t *pkt; 918 int len, max_len; 919 pj_status_t status; 920 921 /* Build RTCP RR/SR packet */ 922 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 923 924 #if !defined(PJMEDIA_HAS_RTCP_XR) || (PJMEDIA_HAS_RTCP_XR == 0) 925 with_xr = PJ_FALSE; 926 #endif 927 928 if (with_sdes || with_bye || with_xr) { 929 pkt = (pj_uint8_t*) stream->enc->out_pkt; 930 pj_memcpy(pkt, sr_rr_pkt, len); 931 max_len = stream->enc->out_pkt_size; 932 } else { 933 pkt = sr_rr_pkt; 934 max_len = len; 935 } 936 937 /* Build RTCP SDES packet */ 938 if (with_sdes) { 939 pjmedia_rtcp_sdes sdes; 940 unsigned sdes_len; 941 942 pj_bzero(&sdes, sizeof(sdes)); 943 sdes.cname = stream->cname; 944 sdes_len = max_len - len; 945 status = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len, 946 &sdes_len, &sdes); 947 if (status != PJ_SUCCESS) { 948 PJ_PERROR(4,(stream->port.info.name.ptr, status, 949 "Error generating RTCP SDES")); 950 } else { 951 len += sdes_len; 952 } 953 } 954 955 /* Build RTCP XR packet */ 956 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 957 if (with_xr) { 958 int i; 959 pjmedia_jb_state jb_state; 960 void *xr_pkt; 961 int xr_len; 962 963 /* Update RTCP XR with current JB states */ 964 pjmedia_jbuf_get_state(stream->jb, &jb_state); 965 966 i = jb_state.avg_delay; 967 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 968 PJMEDIA_RTCP_XR_INFO_JB_NOM, i); 969 pj_assert(status == PJ_SUCCESS); 970 971 i = jb_state.max_delay; 972 status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 973 PJMEDIA_RTCP_XR_INFO_JB_MAX, i); 974 pj_assert(status == PJ_SUCCESS); 975 976 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, 977 &xr_pkt, &xr_len); 978 979 if (xr_len + len <= max_len) { 980 pj_memcpy(pkt+len, xr_pkt, xr_len); 981 len += xr_len; 982 983 /* Send the RTCP XR to third-party destination if specified */ 984 if (stream->rtcp_xr_dest_len) { 985 pjmedia_transport_send_rtcp2(stream->transport, 986 &stream->rtcp_xr_dest, 987 stream->rtcp_xr_dest_len, 988 xr_pkt, xr_len); 989 } 990 991 } else { 992 PJ_PERROR(4,(stream->port.info.name.ptr, PJ_ETOOBIG, 993 "Error generating RTCP-XR")); 994 } 995 } 996 #endif 997 998 /* Build RTCP BYE packet */ 999 if (with_bye) { 1000 unsigned bye_len; 1001 1002 bye_len = max_len - len; 1003 status = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len, 1004 &bye_len, NULL); 1005 if (status != PJ_SUCCESS) { 1006 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1007 "Error generating RTCP BYE")); 1008 } else { 1009 len += bye_len; 1010 } 1011 } 1012 1013 /* Send! */ 1014 status = pjmedia_transport_send_rtcp(stream->transport, pkt, len); 1015 1016 return status; 1017 } 1018 906 1019 /** 907 1020 * check_tx_rtcp() … … 917 1030 */ 918 1031 919 920 1032 if (stream->rtcp_last_tx == 0) { 921 1033 … … 923 1035 924 1036 } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) { 925 926 void *rtcp_pkt; 927 int len; 1037 pj_bool_t with_xr = PJ_FALSE; 928 1038 pj_status_t status; 929 1039 930 pjmedia_rtcp_build_rtcp(&stream->rtcp, &rtcp_pkt, &len); 931 932 status=pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); 1040 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 1041 if (stream->rtcp.xr_enabled) { 1042 if (stream->rtcp_xr_last_tx == 0) { 1043 stream->rtcp_xr_last_tx = timestamp; 1044 } else if (timestamp - stream->rtcp_xr_last_tx >= 1045 stream->rtcp_xr_interval) 1046 { 1047 with_xr = PJ_TRUE; 1048 1049 /* Update last tx RTCP XR */ 1050 stream->rtcp_xr_last_tx = timestamp; 1051 } 1052 } 1053 #endif 1054 1055 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE, 1056 with_xr); 933 1057 if (status != PJ_SUCCESS) { 934 1058 PJ_PERROR(4,(stream->port.info.name.ptr, status, 935 1059 "Error sending RTCP")); 936 1060 } 937 1061 938 1062 stream->rtcp_last_tx = timestamp; 939 1063 } 940 941 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)942 if (stream->rtcp.xr_enabled) {943 944 if (stream->rtcp_xr_last_tx == 0) {945 946 stream->rtcp_xr_last_tx = timestamp;947 948 } else if (timestamp - stream->rtcp_xr_last_tx >=949 stream->rtcp_xr_interval)950 {951 int i;952 pjmedia_jb_state jb_state;953 void *rtcp_pkt;954 int len;955 956 /* Update RTCP XR with current JB states */957 pjmedia_jbuf_get_state(stream->jb, &jb_state);958 959 i = jb_state.avg_delay;960 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,961 PJMEDIA_RTCP_XR_INFO_JB_NOM,962 i);963 964 i = jb_state.max_delay;965 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,966 PJMEDIA_RTCP_XR_INFO_JB_MAX,967 i);968 969 /* Build RTCP XR packet */970 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0,971 &rtcp_pkt, &len);972 973 /* Send the RTCP XR to remote address */974 pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len);975 976 /* Send the RTCP XR to third-party destination if specified */977 if (stream->rtcp_xr_dest_len) {978 pjmedia_transport_send_rtcp2(stream->transport,979 &stream->rtcp_xr_dest,980 stream->rtcp_xr_dest_len,981 rtcp_pkt, len);982 }983 984 /* Update last tx RTCP XR */985 stream->rtcp_xr_last_tx = timestamp;986 }987 }988 #endif989 }990 991 /* Build RTCP SDES packet */992 static unsigned create_rtcp_sdes(pjmedia_stream *stream, pj_uint8_t *pkt,993 unsigned max_len)994 {995 pjmedia_rtcp_common hdr;996 pj_uint8_t *p = pkt;997 998 /* SDES header */999 hdr.version = 2;1000 hdr.p = 0;1001 hdr.count = 1;1002 hdr.pt = 202;1003 hdr.length = 2 + (4+stream->cname.slen+3)/4 - 1;1004 if (max_len < (hdr.length << 2)) {1005 pj_assert(!"Not enough buffer for SDES packet");1006 return 0;1007 }1008 hdr.length = pj_htons((pj_uint16_t)hdr.length);1009 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;1010 pj_memcpy(p, &hdr, sizeof(hdr));1011 p += sizeof(hdr);1012 1013 /* CNAME item */1014 *p++ = 1;1015 *p++ = (pj_uint8_t)stream->cname.slen;1016 pj_memcpy(p, stream->cname.ptr, stream->cname.slen);1017 p += stream->cname.slen;1018 1019 /* END */1020 *p++ = '\0';1021 *p++ = '\0';1022 1023 /* Pad to 32bit */1024 while ((p-pkt) % 4)1025 *p++ = '\0';1026 1027 return (p - pkt);1028 }1029 1030 /* Build RTCP BYE packet */1031 static unsigned create_rtcp_bye(pjmedia_stream *stream, pj_uint8_t *pkt,1032 unsigned max_len)1033 {1034 pjmedia_rtcp_common hdr;1035 1036 /* BYE header */1037 hdr.version = 2;1038 hdr.p = 0;1039 hdr.count = 1;1040 hdr.pt = 203;1041 hdr.length = 1;1042 if (max_len < (hdr.length << 2)) {1043 pj_assert(!"Not enough buffer for SDES packet");1044 return 0;1045 }1046 hdr.length = pj_htons((pj_uint16_t)hdr.length);1047 hdr.ssrc = stream->enc->rtp.out_hdr.ssrc;1048 pj_memcpy(pkt, &hdr, sizeof(hdr));1049 1050 return sizeof(hdr);1051 1064 } 1052 1065 … … 1832 1845 /* Send RTCP RR and SDES after we receive some RTP packets */ 1833 1846 if (stream->rtcp.received >= 10 && !stream->initial_rr) { 1834 void *sr_rr_pkt; 1835 pj_uint8_t *pkt; 1836 int len; 1837 1838 /* Build RR or SR */ 1839 pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 1840 1841 if (!stream->rtcp_sdes_bye_disabled) { 1842 pkt = (pj_uint8_t*) stream->enc->out_pkt; 1843 pj_memcpy(pkt, sr_rr_pkt, len); 1844 pkt += len; 1845 1846 /* Append SDES */ 1847 len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt, 1848 stream->enc->out_pkt_size - len); 1849 if (len > 0) { 1850 pkt += len; 1851 len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->out_pkt); 1852 status = pjmedia_transport_send_rtcp(stream->transport, 1853 stream->enc->out_pkt, 1854 len); 1855 if (status != PJ_SUCCESS) { 1856 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1857 "Error sending RTCP SDES")); 1858 } 1859 } 1860 } else { 1861 status = pjmedia_transport_send_rtcp(stream->transport, 1862 sr_rr_pkt, len); 1863 if (status != PJ_SUCCESS) { 1864 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1865 "Error sending initial RTCP RR")); 1866 } 1867 } 1868 1869 stream->initial_rr = PJ_TRUE; 1847 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, 1848 PJ_FALSE, PJ_FALSE); 1849 if (status != PJ_SUCCESS) { 1850 PJ_PERROR(4,(stream->port.info.name.ptr, status, 1851 "Error sending initial RTCP RR")); 1852 } else { 1853 stream->initial_rr = PJ_TRUE; 1854 } 1870 1855 } 1871 1856 } … … 2401 2386 PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 2402 2387 2403 #if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0) 2404 /* Send RTCP XR on stream destroy */ 2405 if (stream->rtcp.xr_enabled) { 2406 int i; 2407 pjmedia_jb_state jb_state; 2408 void *rtcp_pkt; 2409 int len; 2410 2411 /* Update RTCP XR with current JB states */ 2412 pjmedia_jbuf_get_state(stream->jb, &jb_state); 2413 2414 i = jb_state.avg_delay; 2415 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 2416 PJMEDIA_RTCP_XR_INFO_JB_NOM, 2417 i); 2418 2419 i = jb_state.max_delay; 2420 pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session, 2421 PJMEDIA_RTCP_XR_INFO_JB_MAX, 2422 i); 2423 2424 /* Build RTCP XR packet */ 2425 pjmedia_rtcp_build_rtcp_xr(&stream->rtcp.xr_session, 0, 2426 &rtcp_pkt, &len); 2427 2428 /* Send the RTCP XR to remote address */ 2429 pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); 2430 2431 /* Send the RTCP XR to third-party destination if specified */ 2432 if (stream->rtcp_xr_dest_len) { 2433 pjmedia_transport_send_rtcp2(stream->transport, 2434 &stream->rtcp_xr_dest, 2435 stream->rtcp_xr_dest_len, 2436 rtcp_pkt, len); 2437 } 2438 } 2439 #endif 2440 2441 /* Send RTCP BYE */ 2388 /* Send RTCP BYE (also SDES & XR) */ 2442 2389 if (!stream->rtcp_sdes_bye_disabled) { 2443 pjmedia_stream_send_rtcp_bye(stream);2390 send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE); 2444 2391 } 2445 2392 … … 2795 2742 pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream ) 2796 2743 { 2797 unsigned len;2798 2799 2744 PJ_ASSERT_RETURN(stream, PJ_EINVAL); 2800 2745 2801 len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->out_pkt, 2802 stream->enc->out_pkt_size); 2803 if (len != 0) { 2804 return pjmedia_transport_send_rtcp(stream->transport, 2805 stream->enc->out_pkt, len); 2806 } 2807 2808 return PJ_SUCCESS; 2746 return send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE); 2809 2747 } 2810 2748 … … 2818 2756 2819 2757 if (stream->enc && stream->transport) { 2820 unsigned len; 2821 2822 len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->out_pkt, 2823 stream->enc->out_pkt_size); 2824 if (len != 0) { 2825 return pjmedia_transport_send_rtcp(stream->transport, 2826 stream->enc->out_pkt, len); 2827 } 2758 return send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE); 2828 2759 } 2829 2760
Note: See TracChangeset
for help on using the changeset viewer.