Changeset 390 for pjproject/trunk/pjmedia/src/pjmedia/rtp.c
- Timestamp:
- Apr 6, 2006 7:29:03 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/rtp.c
r223 r390 35 35 #define MIN_SEQUENTIAL ((pj_int16_t)2) 36 36 37 static void pjmedia_rtp_seq_restart(pjmedia_rtp_seq_session *seq_ctrl, 38 pj_uint16_t seq); 39 37 40 38 41 PJ_DEF(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses, … … 162 165 163 166 164 PJ_DEF(pj_status_t) pjmedia_rtp_session_update( pjmedia_rtp_session *ses, const pjmedia_rtp_hdr *hdr) 165 { 166 int status; 167 PJ_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; 167 172 168 173 /* Check SSRC. */ … … 176 181 */ 177 182 183 /* Init status */ 184 seq_st.status.value = 0; 185 seq_st.diff = 0; 186 178 187 /* Check payload type. */ 179 188 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)", 181 192 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; 183 198 } 184 199 … … 188 203 189 204 /* 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) { 193 207 ++ses->received; 194 } else if (status == 0 || status == PJMEDIA_RTP_ESESSPROBATION) { 208 209 } else if (!seq_st.status.flag.bad) { 195 210 ++ses->received; 196 211 } 197 212 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 220 void 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 229 void 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 238 void 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; 225 244 245 /* Init status */ 246 st.status.value = 0; 247 st.diff = 0; 248 226 249 /* 227 250 * Source is not valid until MIN_SEQUENTIAL packets with 228 251 * sequential sequence numbers have been received. 229 252 */ 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; 237 264 } 238 265 } 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; 241 277 } 242 return PJMEDIA_RTP_ESESSPROBATION; 278 279 280 } else if (udelta == 0) { 281 282 st.status.flag.dup = 1; 243 283 244 284 } else if (udelta < MAX_DROPOUT) { 245 285 /* in order, with permissible gap */ 246 if (seq < s ctrl->max_seq) {286 if (seq < sess->max_seq) { 247 287 /* Sequence number wrapped - count another 64K cycle. */ 248 s ctrl->cycles += RTP_SEQ_MOD;288 sess->cycles += RTP_SEQ_MOD; 249 289 } 250 sctrl->max_seq = seq; 290 sess->max_seq = seq; 291 292 st.diff = udelta; 251 293 252 294 } else if (udelta <= (RTP_SEQ_MOD - MAX_MISORDER)) { 253 295 /* the sequence number made a very large jump */ 254 if (seq == s ctrl->bad_seq) {296 if (seq == sess->bad_seq) { 255 297 /* 256 298 * Two sequential packets -- assume that the other side … … 258 300 * (i.e., pretend this was the first packet). 259 301 */ 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; 261 306 } 262 307 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; 265 311 } 266 312 } else { 267 /* duplicate or reordered packet */ 313 /* old duplicate or reordered packet. 314 * Not necessarily bad packet (?) 315 */ 316 st.status.flag.outorder = 1; 268 317 } 269 318 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.