Ignore:
Timestamp:
Apr 6, 2006 7:29:03 PM (18 years ago)
Author:
bennylp
Message:

Integrate (stream) quality monitoring into RTCP framework, and update all RTCP clients accordingly

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/rtp.c

    r223 r390  
    3535#define MIN_SEQUENTIAL  ((pj_int16_t)2) 
    3636 
     37static void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *seq_ctrl,  
     38                                    pj_uint16_t seq); 
     39 
    3740 
    3841PJ_DEF(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses, 
     
    162165 
    163166 
    164 PJ_DEF(pj_status_t) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, const pjmedia_rtp_hdr *hdr) 
    165 { 
    166     int status; 
     167PJ_DEF(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses,  
     168                                         const pjmedia_rtp_hdr *hdr, 
     169                                         pjmedia_rtp_status *p_seq_st) 
     170{ 
     171    pjmedia_rtp_status seq_st; 
    167172 
    168173    /* Check SSRC. */ 
     
    176181    */ 
    177182 
     183    /* Init status */ 
     184    seq_st.status.value = 0; 
     185    seq_st.diff = 0; 
     186 
    178187    /* Check payload type. */ 
    179188    if (hdr->pt != ses->out_pt) { 
    180         PJ_LOG(4, (THIS_FILE, "pjmedia_rtp_session_update: ses=%p, invalid payload type %d (!=%d)", 
     189        PJ_LOG(4, (THIS_FILE,  
     190                   "pjmedia_rtp_session_update: ses=%p, invalid payload " 
     191                   "type %d (expecting %d)", 
    181192                   ses, hdr->pt, ses->out_pt)); 
    182         return PJMEDIA_RTP_EINPT; 
     193        if (p_seq_st) { 
     194            p_seq_st->status.flag.bad = 1; 
     195            p_seq_st->status.flag.badpt = 1; 
     196        } 
     197        return; 
    183198    } 
    184199 
     
    188203 
    189204    /* Check sequence number to see if remote session has been restarted. */ 
    190     status = pjmedia_rtp_seq_update( &ses->seq_ctrl, pj_ntohs(hdr->seq)); 
    191     if (status == PJMEDIA_RTP_ESESSRESTART) { 
    192         pjmedia_rtp_seq_restart( &ses->seq_ctrl, pj_ntohs(hdr->seq)); 
     205    pjmedia_rtp_seq_update( &ses->seq_ctrl, pj_ntohs(hdr->seq), &seq_st); 
     206    if (seq_st.status.flag.restart) { 
    193207        ++ses->received; 
    194     } else if (status == 0 || status == PJMEDIA_RTP_ESESSPROBATION) { 
     208 
     209    } else if (!seq_st.status.flag.bad) { 
    195210        ++ses->received; 
    196211    } 
    197212 
    198  
    199     return status; 
    200 } 
    201  
    202  
    203 void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *sctrl, pj_uint16_t seq) 
    204 { 
    205     sctrl->base_seq = seq; 
    206     sctrl->max_seq = seq; 
    207     sctrl->bad_seq = RTP_SEQ_MOD + 1; 
    208     sctrl->cycles = 0; 
    209 } 
    210  
    211  
    212 void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *sctrl, pj_uint16_t seq) 
    213 { 
    214     pjmedia_rtp_seq_restart(sctrl, seq); 
    215  
    216     sctrl->max_seq = (pj_uint16_t) (seq - 1); 
    217     sctrl->probation = MIN_SEQUENTIAL; 
    218 } 
    219  
    220  
    221 pj_status_t pjmedia_rtp_seq_update(pjmedia_rtp_seq_session *sctrl,  
    222                                    pj_uint16_t seq) 
    223 { 
    224     pj_uint16_t udelta = (pj_uint16_t) (seq - sctrl->max_seq); 
     213    if (p_seq_st) { 
     214        p_seq_st->status.value = seq_st.status.value; 
     215        p_seq_st->diff = seq_st.diff; 
     216    } 
     217} 
     218 
     219 
     220void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *sess, pj_uint16_t seq) 
     221{ 
     222    sess->base_seq = seq; 
     223    sess->max_seq = seq; 
     224    sess->bad_seq = RTP_SEQ_MOD + 1; 
     225    sess->cycles = 0; 
     226} 
     227 
     228 
     229void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *sess, pj_uint16_t seq) 
     230{ 
     231    pjmedia_rtp_seq_restart(sess, seq); 
     232 
     233    sess->max_seq = (pj_uint16_t) (seq - 1); 
     234    sess->probation = MIN_SEQUENTIAL; 
     235} 
     236 
     237 
     238void pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *sess,  
     239                             pj_uint16_t seq, 
     240                             pjmedia_rtp_status *seq_status) 
     241{ 
     242    pj_uint16_t udelta = (pj_uint16_t) (seq - sess->max_seq); 
     243    pjmedia_rtp_status st; 
    225244     
     245    /* Init status */ 
     246    st.status.value = 0; 
     247    st.diff = 0; 
     248 
    226249    /* 
    227250     * Source is not valid until MIN_SEQUENTIAL packets with 
    228251     * sequential sequence numbers have been received. 
    229252     */ 
    230     if (sctrl->probation) { 
    231         /* packet is in sequence */ 
    232         if (seq == sctrl->max_seq+ 1) { 
    233             sctrl->probation--; 
    234             sctrl->max_seq = seq; 
    235             if (sctrl->probation == 0) { 
    236                 return PJMEDIA_RTP_ESESSRESTART; 
     253    if (sess->probation) { 
     254 
     255        st.status.flag.probation = 1; 
     256         
     257        if (seq == sess->max_seq+ 1) { 
     258            /* packet is in sequence */ 
     259            st.diff = 1; 
     260            sess->probation--; 
     261            sess->max_seq = seq; 
     262            if (sess->probation == 0) { 
     263                st.status.flag.probation = 0; 
    237264            } 
    238265        } else { 
    239             sctrl->probation = MIN_SEQUENTIAL - 1; 
    240             sctrl->max_seq = seq; 
     266 
     267            st.diff = 0; 
     268 
     269            st.status.flag.bad = 1; 
     270            if (seq == sess->max_seq) 
     271                st.status.flag.dup = 1; 
     272            else 
     273                st.status.flag.outorder = 1; 
     274 
     275            sess->probation = MIN_SEQUENTIAL - 1; 
     276            sess->max_seq = seq; 
    241277        } 
    242         return PJMEDIA_RTP_ESESSPROBATION; 
     278 
     279 
     280    } else if (udelta == 0) { 
     281 
     282        st.status.flag.dup = 1; 
    243283 
    244284    } else if (udelta < MAX_DROPOUT) { 
    245285        /* in order, with permissible gap */ 
    246         if (seq < sctrl->max_seq) { 
     286        if (seq < sess->max_seq) { 
    247287            /* Sequence number wrapped - count another 64K cycle. */ 
    248             sctrl->cycles += RTP_SEQ_MOD; 
     288            sess->cycles += RTP_SEQ_MOD; 
    249289        } 
    250         sctrl->max_seq = seq; 
     290        sess->max_seq = seq; 
     291 
     292        st.diff = udelta; 
    251293 
    252294    } else if (udelta <= (RTP_SEQ_MOD - MAX_MISORDER)) { 
    253295        /* the sequence number made a very large jump */ 
    254         if (seq == sctrl->bad_seq) { 
     296        if (seq == sess->bad_seq) { 
    255297            /* 
    256298             * Two sequential packets -- assume that the other side 
     
    258300             * (i.e., pretend this was the first packet). 
    259301             */ 
    260             return PJMEDIA_RTP_ESESSRESTART; 
     302            pjmedia_rtp_seq_restart(sess, seq); 
     303            st.status.flag.restart = 1; 
     304            st.status.flag.probation = 1; 
     305            st.diff = 1; 
    261306        } 
    262307        else { 
    263             sctrl->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1); 
    264             return PJMEDIA_RTP_EBADSEQ; 
     308            sess->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1); 
     309            st.status.flag.bad = 1; 
     310            st.status.flag.outorder = 1; 
    265311        } 
    266312    } else { 
    267         /* duplicate or reordered packet */ 
     313        /* old duplicate or reordered packet. 
     314         * Not necessarily bad packet (?) 
     315         */ 
     316        st.status.flag.outorder = 1; 
    268317    } 
    269318     
    270     return PJ_SUCCESS; 
    271 } 
    272  
    273  
     319 
     320    if (seq_status) { 
     321        seq_status->diff = st.diff; 
     322        seq_status->status.value = st.status.value; 
     323    } 
     324} 
     325 
     326 
Note: See TracChangeset for help on using the changeset viewer.