Ignore:
Timestamp:
Mar 30, 2012 7:10:13 AM (12 years ago)
Author:
bennylp
Message:

Re #1474: Merged all changes from 1.12 - HEAD (from the 1.x branch)

Location:
pjproject/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk

  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r3982 r3999  
    156156    pj_bool_t                initial_rr;    /**< Initial RTCP RR sent       */ 
    157157    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. */ 
    158161 
    159162    /* RFC 2833 DTMF transmission queue: */ 
     
    246249 
    247250 
     251static 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 
    248257#if TRACE_JB 
    249258 
     
    426435 
    427436    /* 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); 
    430438 
    431439#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER 
     
    914922 
    915923 
     924static 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 
    9161032/** 
    9171033 * check_tx_rtcp() 
     
    9271043     */ 
    9281044 
    929  
    9301045    if (stream->rtcp_last_tx == 0) { 
    9311046         
     
    9331048 
    9341049    } 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        } 
    9421074 
    9431075        stream->rtcp_last_tx = timestamp; 
    9441076    } 
    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 #endif 
    994 } 
    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); 
    10561077} 
    10571078 
     
    13491370 
    13501371    /* 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    } 
    13531379 
    13541380    /* Update stat */ 
     
    18201846    /* Send RTCP RR and SDES after we receive some RTP packets */ 
    18211847    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        } 
    18481856    } 
    18491857} 
     
    18831891    pjmedia_channel *channel; 
    18841892    pj_status_t status; 
    1885     unsigned min_out_pkt_size; 
    18861893     
    18871894    /* Allocate memory for channel descriptor */ 
     
    19151922    } 
    19161923 
    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  
    19261924    channel->out_pkt = pj_pool_alloc(pool, channel->out_pkt_size); 
    19271925    PJ_ASSERT_RETURN(channel->out_pkt != NULL, PJ_ENOMEM); 
     
    22662264 
    22672265        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); 
    22692290 
    22702291    /* Only attach transport when stream is ready. */ 
     
    23922413    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 
    23932414 
    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) */ 
    24332416    if (!stream->rtcp_sdes_bye_disabled) { 
    2434         pjmedia_stream_send_rtcp_bye(stream); 
     2417        send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_TRUE); 
    24352418    } 
    24362419 
     
    28002783pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream ) 
    28012784{ 
    2802     unsigned len; 
    2803  
    28042785    PJ_ASSERT_RETURN(stream, PJ_EINVAL); 
    28052786 
    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); 
    28142788} 
    28152789 
     
    28232797 
    28242798    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); 
    28332800    } 
    28342801 
Note: See TracChangeset for help on using the changeset viewer.