Changeset 427
- Timestamp:
- May 2, 2006 5:47:51 PM (18 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/rtcp.h
r408 r427 71 71 #else 72 72 pj_uint32_t fract_lost:8; /**< Fraction lost. */ 73 pj_uint32_t total_lost_ 0:8; /**< Total lost, bit 0-7. */73 pj_uint32_t total_lost_2:8; /**< Total lost, bit 0-7. */ 74 74 pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */ 75 pj_uint32_t total_lost_ 2:8; /**< Total lost, bit 16-23. */75 pj_uint32_t total_lost_0:8; /**< Total lost, bit 16-23. */ 76 76 #endif 77 77 pj_uint32_t last_seq; /**< Last sequence number. */ … … 112 112 113 113 /** 114 * RTCP packet. 114 * This structure declares default RTCP packet (SR) that is sent by pjmedia. 115 * Incoming RTCP packet may have different format, and must be parsed 116 * manually by application. 115 117 */ 116 118 struct pjmedia_rtcp_pkt -
pjproject/trunk/pjmedia/src/pjmedia/rtcp.c
r411 r427 51 51 { 52 52 /* Seconds between 1900-01-01 to 1970-01-01 */ 53 #define NTP_DIFF ((70 * 365 + 17) * 86400UL)53 #define JAN_1970 (2208988800UL) 54 54 pj_timestamp ts; 55 55 pj_status_t status; … … 59 59 /* Fill up the high 32bit part */ 60 60 ntp->hi = (pj_uint32_t)((ts.u64 - sess->ts_base.u64) / sess->ts_freq.u64) 61 + sess->tv_base.sec + NTP_DIFF;61 + sess->tv_base.sec + JAN_1970; 62 62 63 63 /* Calculate seconds fractions */ … … 95 95 pj_gettimeofday(&elapsed); 96 96 97 ts_time.sec = ntp->hi - sess->tv_base.sec - NTP_DIFF;97 ts_time.sec = ntp->hi - sess->tv_base.sec - JAN_1970; 98 98 ts_time.msec = (long)(ntp->lo * 1000.0 / 0xFFFFFFFF); 99 99 … … 114 114 115 115 116 ntp->hi = elapsed.sec + sess->tv_base.sec + NTP_DIFF;116 ntp->hi = elapsed.sec + sess->tv_base.sec + JAN_1970; 117 117 ntp->lo = (elapsed.msec * 65536 / 1000) << 16; 118 118 } … … 217 217 } 218 218 219 /* Only mark "good" packets */ 220 ++sess->received; 221 219 222 /* Calculate loss periods. */ 220 223 if (seq_st.diff > 1) { … … 224 227 period = count * sess->pkt_size * 1000 / sess->clock_rate; 225 228 period *= 1000; 229 230 /* Update packet lost. 231 * The packet lost number will also be updated when we're sending 232 * outbound RTCP RR. 233 */ 234 sess->stat.rx.loss += (seq_st.diff - 1); 226 235 227 236 /* Update loss period stat */ … … 241 250 242 251 243 /* Only mark "good" packets */244 ++sess->received;245 246 247 252 /* 248 253 * Calculate jitter only when sequence is good (see RFC 3550 section A.8) … … 304 309 pj_size_t size) 305 310 { 306 const struct pjmedia_rtcp_pkt *rtcp = pkt; 311 const pjmedia_rtcp_common *common = pkt; 312 const pjmedia_rtcp_rr *rr = NULL; 313 const pjmedia_rtcp_sr *sr = NULL; 307 314 pj_uint32_t last_loss, jitter_samp, jitter; 308 315 309 /* Must at least contain SR */ 310 pj_assert(size >= sizeof(pjmedia_rtcp_common)+sizeof(pjmedia_rtcp_sr)); 311 312 /* Save LSR from NTP timestamp of RTCP packet */ 313 sess->rx_lsr = ((pj_ntohl(rtcp->sr.ntp_sec) & 0x0000FFFF) << 16) | 314 ((pj_ntohl(rtcp->sr.ntp_frac) >> 16) & 0xFFFF); 315 316 /* Calculate SR arrival time for DLSR */ 317 pj_get_timestamp(&sess->rx_lsr_time); 318 319 TRACE_((sess->name, "Rx RTCP SR: ntp_ts=%p", 320 sess->rx_lsr, 321 (pj_uint32_t)(sess->rx_lsr_time.u64*65536/sess->ts_freq.u64))); 322 323 /* Nothing more to do if this is an SR only RTCP packet */ 324 if (size < sizeof(pjmedia_rtcp_pkt)) 316 /* Parse RTCP */ 317 if (common->pt == RTCP_SR) { 318 sr = (pjmedia_rtcp_sr*) (((char*)pkt) + sizeof(pjmedia_rtcp_common)); 319 if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_pkt))) { 320 rr = (pjmedia_rtcp_rr*)(((char*)pkt) + (sizeof(pjmedia_rtcp_common) 321 + sizeof(pjmedia_rtcp_sr))); 322 } 323 } else if (common->pt == RTCP_RR && common->count > 0) 324 rr = (pjmedia_rtcp_rr*)(((char*)pkt) +sizeof(pjmedia_rtcp_common) +4); 325 326 327 if (sr) { 328 /* Save LSR from NTP timestamp of RTCP packet */ 329 sess->rx_lsr = ((pj_ntohl(sr->ntp_sec) & 0x0000FFFF) << 16) | 330 ((pj_ntohl(sr->ntp_frac) >> 16) & 0xFFFF); 331 332 /* Calculate SR arrival time for DLSR */ 333 pj_get_timestamp(&sess->rx_lsr_time); 334 335 TRACE_((sess->name, "Rx RTCP SR: ntp_ts=%p", 336 sess->rx_lsr, 337 (pj_uint32_t)(sess->rx_lsr_time.u64*65536/sess->ts_freq.u64))); 338 } 339 340 341 /* Nothing more to do if there's no RR packet */ 342 if (rr == NULL) 325 343 return; 326 344 327 345 328 346 last_loss = sess->stat.tx.loss; 329 347 330 348 /* Get packet loss */ 331 sess->stat.tx.loss = (rtcp->rr.total_lost_2 << 16) + 332 (rtcp->rr.total_lost_1 << 8) + 333 rtcp->rr.total_lost_0; 349 sess->stat.tx.loss = (rr->total_lost_2 << 16) + 350 (rr->total_lost_1 << 8) + 351 rr->total_lost_0; 352 353 TRACE_((sess->name, "Rx RTCP RR: total_lost_2=%x, 1=%x, 0=%x, lost=%d", 354 (int)rr->total_lost_2, 355 (int)rr->total_lost_1, 356 (int)rr->total_lost_0, 357 sess->stat.tx.loss)); 334 358 335 359 /* We can't calculate the exact loss period for TX, so just give the … … 360 384 361 385 /* Get jitter value in usec */ 362 jitter_samp = pj_ntohl(r tcp->rr.jitter);386 jitter_samp = pj_ntohl(rr->jitter); 363 387 /* Calculate jitter in usec, avoiding overflows */ 364 388 if (jitter_samp <= 4294) … … 383 407 384 408 /* Can only calculate if LSR and DLSR is present in RR */ 385 if (r tcp->rr.lsr && rtcp->rr.dlsr) {409 if (rr->lsr && rr->dlsr) { 386 410 pj_uint32_t lsr, now, dlsr; 387 411 pj_uint64_t eedelay; … … 391 415 * resolution 392 416 */ 393 lsr = pj_ntohl(r tcp->rr.lsr);417 lsr = pj_ntohl(rr->lsr); 394 418 395 419 /* DLSR is delay since LSR, also in 1/65536 resolution */ 396 dlsr = pj_ntohl(r tcp->rr.dlsr);420 dlsr = pj_ntohl(rr->dlsr); 397 421 398 422 /* Get current time, and convert to 1/65536 resolution */ … … 425 449 unsigned rtt = (pj_uint32_t)eedelay; 426 450 427 TRACE_((sess->name, "RTCP RTT is set to %d usec", rtt));428 429 if (rtt >= 1000000) {430 pjmedia_rtcp_ntp_rec ntp2;431 pj_thread_sleep(50); 432 pjmedia_rtcp_get_ntp_time(sess, &ntp2);433 ntp2.lo = ntp2.lo;451 /* Check that eedelay value really makes sense. 452 * We allow up to 30 seconds RTT! 453 */ 454 if (eedelay > 30 * 1000 * 1000UL) { 455 456 TRACE_((sess->name, "RTT not making any sense, ignored..")); 457 goto end_rtt_calc; 434 458 } 435 459 436 460 if (sess->stat.rtt_update_cnt == 0) 437 461 sess->stat.rtt.min = rtt; 462 463 /* "Normalize" rtt value that is exceptionally high. 464 * For such values, "normalize" the rtt to be three times 465 * the average value. 466 */ 467 if (rtt > (sess->stat.rtt.avg*3) && sess->stat.rtt_update_cnt!=0) { 468 unsigned orig_rtt = rtt; 469 rtt = sess->stat.rtt.avg*3; 470 PJ_LOG(5,(sess->name, 471 "RTT value %d usec is normalized to %d usec", 472 orig_rtt, rtt)); 473 } 474 475 TRACE_((sess->name, "RTCP RTT is set to %d usec", rtt)); 438 476 439 477 if (rtt < sess->stat.rtt.min && rtt) … … 458 496 } 459 497 } 498 499 end_rtt_calc: 460 500 461 501 pj_gettimeofday(&sess->stat.tx.update); … … 508 548 if (expected >= sess->received) 509 549 sess->stat.rx.loss = expected - sess->received; 550 else 551 sess->stat.rx.loss = 0; 552 510 553 rtcp_pkt->rr.total_lost_2 = (sess->stat.rx.loss >> 16) & 0xFF; 511 554 rtcp_pkt->rr.total_lost_1 = (sess->stat.rx.loss >> 8) & 0xFF;
Note: See TracChangeset
for help on using the changeset viewer.