Ignore:
Timestamp:
Sep 20, 2007 1:19:03 PM (17 years ago)
Author:
bennylp
Message:

Ticket #13: Send RTCP RR if stream is not transmitting any RTP packets

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/pjproject-0.5-stable/pjmedia/src/pjmedia/rtcp.c

    r974 r1447  
    131131                               pj_uint32_t ssrc) 
    132132{ 
    133     pjmedia_rtcp_pkt *rtcp_pkt = &sess->rtcp_pkt; 
     133    pjmedia_rtcp_sr_pkt *sr_pkt = &sess->rtcp_sr_pkt; 
    134134    pj_time_val now; 
    135135     
     
    141141 
    142142    /* Name */ 
    143     sess->name = name ? name : THIS_FILE, 
     143    sess->name = name ? name : (char*)THIS_FILE, 
    144144 
    145145    /* Set clock rate */ 
     
    147147    sess->pkt_size = samples_per_frame; 
    148148 
    149     /* Init common RTCP header */ 
    150     rtcp_pkt->common.version = 2; 
    151     rtcp_pkt->common.count = 1; 
    152     rtcp_pkt->common.pt = RTCP_SR; 
    153     rtcp_pkt->common.length = pj_htons(12); 
    154      
    155     /* Init SR */ 
    156     rtcp_pkt->sr.ssrc = pj_htonl(ssrc); 
    157      
     149    /* Init common RTCP SR header */ 
     150    sr_pkt->common.version = 2; 
     151    sr_pkt->common.count = 1; 
     152    sr_pkt->common.pt = RTCP_SR; 
     153    sr_pkt->common.length = pj_htons(12); 
     154    sr_pkt->common.ssrc = pj_htonl(ssrc); 
     155     
     156    /* Copy to RTCP RR header */ 
     157    pj_memcpy(&sess->rtcp_rr_pkt.common, &sr_pkt->common,  
     158              sizeof(pjmedia_rtcp_common)); 
     159    sess->rtcp_rr_pkt.common.pt = RTCP_RR; 
     160    sess->rtcp_rr_pkt.common.length = pj_htons(7); 
     161 
    158162    /* Get time and timestamp base and frequency */ 
    159163    pj_gettimeofday(&now); 
     
    333337                                   pj_size_t size) 
    334338{ 
    335     const pjmedia_rtcp_common *common = pkt; 
     339    pjmedia_rtcp_common *common = (pjmedia_rtcp_common*) pkt; 
    336340    const pjmedia_rtcp_rr *rr = NULL; 
    337341    const pjmedia_rtcp_sr *sr = NULL; 
     
    341345    if (common->pt == RTCP_SR) { 
    342346        sr = (pjmedia_rtcp_sr*) (((char*)pkt) + sizeof(pjmedia_rtcp_common)); 
    343         if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_pkt))) { 
     347        if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_sr_pkt))) { 
    344348            rr = (pjmedia_rtcp_rr*)(((char*)pkt) + (sizeof(pjmedia_rtcp_common) 
    345349                                    + sizeof(pjmedia_rtcp_sr))); 
    346350        } 
    347351    } else if (common->pt == RTCP_RR && common->count > 0) 
    348         rr = (pjmedia_rtcp_rr*)(((char*)pkt) +sizeof(pjmedia_rtcp_common) +4); 
     352        rr = (pjmedia_rtcp_rr*)(((char*)pkt) + sizeof(pjmedia_rtcp_common)); 
    349353 
    350354 
     
    530534 
    531535PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess,  
    532                                      pjmedia_rtcp_pkt **ret_p_pkt,  
    533                                      int *len) 
     536                                     void **ret_p_pkt, int *len) 
    534537{ 
    535538    pj_uint32_t expected, expected_interval, received_interval, lost_interval; 
    536     pjmedia_rtcp_pkt *rtcp_pkt = &sess->rtcp_pkt; 
     539    pjmedia_rtcp_common *common; 
     540    pjmedia_rtcp_sr *sr; 
     541    pjmedia_rtcp_rr *rr; 
    537542    pj_timestamp ts_now; 
    538543    pjmedia_rtcp_ntp_rec ntp; 
    539      
    540     /* Packet count */ 
    541     rtcp_pkt->sr.sender_pcount = pj_htonl(sess->stat.tx.pkt); 
    542  
    543     /* Octets count */ 
    544     rtcp_pkt->sr.sender_bcount = pj_htonl(sess->stat.tx.bytes); 
     544 
     545    /* Get current NTP time. */ 
     546    pj_get_timestamp(&ts_now); 
     547    pjmedia_rtcp_get_ntp_time(sess, &ntp); 
     548 
     549 
     550    /* See if we have transmitted RTP packets since last time we 
     551     * sent RTCP SR. 
     552     */ 
     553    if (sess->stat.tx.pkt != pj_ntohl(sess->rtcp_sr_pkt.sr.sender_pcount)) { 
     554 
     555        /* So we should send RTCP SR */ 
     556        *ret_p_pkt = (void*) &sess->rtcp_sr_pkt; 
     557        *len = sizeof(pjmedia_rtcp_sr_pkt); 
     558        common = &sess->rtcp_sr_pkt.common; 
     559        rr = &sess->rtcp_sr_pkt.rr; 
     560        sr = &sess->rtcp_sr_pkt.sr; 
     561 
     562        /* Update packet count */ 
     563        sr->sender_pcount = pj_htonl(sess->stat.tx.pkt); 
     564 
     565        /* Update octets count */ 
     566        sr->sender_bcount = pj_htonl(sess->stat.tx.bytes); 
     567 
     568        /* Fill in NTP timestamp in SR. */ 
     569        sr->ntp_sec = pj_htonl(ntp.hi); 
     570        sr->ntp_frac = pj_htonl(ntp.lo); 
     571 
     572        TRACE_((sess->name, "TX RTCP SR: ntp_ts=%p",  
     573                           ((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000)  
     574                                >> 16))); 
     575 
     576 
     577    } else { 
     578        /* We should send RTCP RR then */ 
     579        *ret_p_pkt = (void*) &sess->rtcp_rr_pkt; 
     580        *len = sizeof(pjmedia_rtcp_rr_pkt); 
     581        common = &sess->rtcp_rr_pkt.common; 
     582        rr = &sess->rtcp_rr_pkt.rr; 
     583        sr = NULL; 
     584    } 
    545585     
    546586    /* SSRC and last_seq */ 
    547     rtcp_pkt->rr.ssrc = pj_htonl(sess->peer_ssrc); 
    548     rtcp_pkt->rr.last_seq = (sess->seq_ctrl.cycles & 0xFFFF0000L); 
    549     rtcp_pkt->rr.last_seq += sess->seq_ctrl.max_seq; 
    550     rtcp_pkt->rr.last_seq = pj_htonl(rtcp_pkt->rr.last_seq); 
     587    rr->ssrc = pj_htonl(sess->peer_ssrc); 
     588    rr->last_seq = (sess->seq_ctrl.cycles & 0xFFFF0000L); 
     589    /* Since this is an "+=" operation, make sure we update last_seq on 
     590     * both RR and SR. 
     591     */ 
     592    sess->rtcp_sr_pkt.rr.last_seq += sess->seq_ctrl.max_seq; 
     593    sess->rtcp_rr_pkt.rr.last_seq += sess->seq_ctrl.max_seq; 
     594    rr->last_seq = pj_htonl(rr->last_seq); 
    551595 
    552596 
    553597    /* Jitter */ 
    554     rtcp_pkt->rr.jitter = pj_htonl(sess->jitter >> 4); 
     598    rr->jitter = pj_htonl(sess->jitter >> 4); 
    555599     
    556600     
    557601    /* Total lost. */ 
    558     expected = pj_ntohl(rtcp_pkt->rr.last_seq) - sess->seq_ctrl.base_seq; 
     602    expected = pj_ntohl(rr->last_seq) - sess->seq_ctrl.base_seq; 
    559603 
    560604    /* This is bug: total lost already calculated on each incoming RTP! 
     
    565609    */ 
    566610 
    567     rtcp_pkt->rr.total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF; 
    568     rtcp_pkt->rr.total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF; 
    569     rtcp_pkt->rr.total_lost_0 = (sess->stat.rx.loss & 0xFF); 
     611    rr->total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF; 
     612    rr->total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF; 
     613    rr->total_lost_0 = (sess->stat.rx.loss & 0xFF); 
    570614 
    571615    /* Fraction lost calculation */ 
     
    576620    sess->rx_prior = sess->received; 
    577621     
    578     lost_interval = expected_interval - received_interval; 
     622    if (expected_interval >= received_interval) 
     623        lost_interval = expected_interval - received_interval; 
     624    else 
     625        lost_interval = 0; 
    579626     
    580627    if (expected_interval==0 || lost_interval == 0) { 
    581         rtcp_pkt->rr.fract_lost = 0; 
     628        rr->fract_lost = 0; 
    582629    } else { 
    583         rtcp_pkt->rr.fract_lost = (lost_interval << 8) / expected_interval; 
    584     } 
    585      
    586     /* Get current NTP time. */ 
    587     pj_get_timestamp(&ts_now); 
    588     pjmedia_rtcp_get_ntp_time(sess, &ntp); 
    589      
    590     /* Fill in NTP timestamp in SR. */ 
    591     rtcp_pkt->sr.ntp_sec = pj_htonl(ntp.hi); 
    592     rtcp_pkt->sr.ntp_frac = pj_htonl(ntp.lo); 
    593  
    594     TRACE_((sess->name, "TX RTCP SR: ntp_ts=%p",  
    595                        ((ntp.hi & 0xFFFF) << 16) + ((ntp.lo & 0xFFFF0000)  
    596                             >> 16))); 
    597  
     630        rr->fract_lost = (lost_interval << 8) / expected_interval; 
     631    } 
     632     
    598633    if (sess->rx_lsr_time.u64 == 0 || sess->rx_lsr == 0) { 
    599         rtcp_pkt->rr.lsr = 0; 
    600         rtcp_pkt->rr.dlsr = 0; 
     634        rr->lsr = 0; 
     635        rr->dlsr = 0; 
    601636    } else { 
    602637        pj_timestamp ts; 
     
    611646           LSR is the middle 32bit of the last SR NTP time received. 
    612647         */ 
    613         rtcp_pkt->rr.lsr = pj_htonl(lsr); 
     648        rr->lsr = pj_htonl(lsr); 
    614649         
    615650        /* Fill in DLSR. 
     
    623658        /* Get DLSR */ 
    624659        dlsr = (pj_uint32_t)(ts.u64 - lsr_time); 
    625         rtcp_pkt->rr.dlsr = pj_htonl(dlsr); 
     660        rr->dlsr = pj_htonl(dlsr); 
    626661 
    627662        TRACE_((sess->name,"Tx RTCP RR: lsr=%p, lsr_time=%p, now=%p, dlsr=%p" 
     
    638673    pj_gettimeofday(&sess->stat.rx.update); 
    639674    sess->stat.rx.update_cnt++; 
    640  
    641  
    642     /* Return pointer. */ 
    643     *ret_p_pkt = rtcp_pkt; 
    644     *len = sizeof(pjmedia_rtcp_pkt); 
    645675} 
    646676 
Note: See TracChangeset for help on using the changeset viewer.