Changeset 1d135a804f2d2fafddc12567f066fb866c9ccd07
- Timestamp:
- 18/10/05 23:03:34
(3 years ago)
- Author:
- Jean-Paul Saman <jpsaman@videolan.org>
- git-committer:
- Jean-Paul Saman <jpsaman@videolan.org> 1129669414 +0000
- git-parent:
[52932184a4d386ea98ef71ba504222026da46a5d]
- git-author:
- Jean-Paul Saman <jpsaman@videolan.org> 1129669414 +0000
- Message:
RTP reordering fixes.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| re75daaa |
r1d135a8 |
|
| 112 | 112 | block_t *p_list; /* list of packets to rearrange */ |
|---|
| 113 | 113 | block_t *p_end; /* last packet in p_list */ |
|---|
| 114 | | block_t *p_next; /* p_next ?? */ |
|---|
| 115 | 114 | }; |
|---|
| 116 | 115 | |
|---|
| … | … | |
| 253 | 252 | p_sys->p_list = NULL; |
|---|
| 254 | 253 | p_sys->p_end = NULL; |
|---|
| 255 | | p_sys->p_next = NULL; |
|---|
| 256 | 254 | |
|---|
| 257 | 255 | return VLC_SUCCESS; |
|---|
| … | … | |
| 337 | 335 | } |
|---|
| 338 | 336 | |
|---|
| 339 | | if( p_block->i_buffer >= p_sys->i_mtu && p_sys->b_auto_mtu && |
|---|
| | 337 | if( (p_block->i_buffer >= p_sys->i_mtu) && p_sys->b_auto_mtu && |
|---|
| 340 | 338 | p_sys->i_mtu < 32767 ) |
|---|
| 341 | 339 | { |
|---|
| … | … | |
| 352 | 350 | * look at the sequence numbers. |
|---|
| 353 | 351 | */ |
|---|
| 354 | | static inline void rtp_ChainInsert( access_t *p_access, block_t **pp_list, block_t **pp_end, block_t *p_block ) |
|---|
| 355 | | { |
|---|
| 356 | | block_t *p_tmp = NULL; |
|---|
| | 352 | static inline void rtp_ChainInsert( access_t *p_access, block_t *p_block ) |
|---|
| | 353 | { |
|---|
| | 354 | access_sys_t *p_sys = (access_sys_t *) p_access->p_sys; |
|---|
| | 355 | block_t *p_list = p_sys->p_list; |
|---|
| | 356 | block_t *p_end = p_sys->p_end; |
|---|
| 357 | 357 | block_t *p = NULL; |
|---|
| 358 | 358 | uint16_t i_new = 0; |
|---|
| … | … | |
| 362 | 362 | |
|---|
| 363 | 363 | if( !p_block ) return; |
|---|
| 364 | | if( *pp_list == NULL ) |
|---|
| 365 | | { |
|---|
| 366 | | *pp_list = p_block; |
|---|
| 367 | | *pp_end = p_block; |
|---|
| | 364 | if( !p_list ) |
|---|
| | 365 | { |
|---|
| | 366 | p_sys->p_list = p_block; |
|---|
| | 367 | p_sys->p_end = p_block; |
|---|
| 368 | 368 | return; |
|---|
| 369 | 369 | } |
|---|
| | 370 | |
|---|
| 370 | 371 | /* Appending packets at the end of the chain is the normal case */ |
|---|
| 371 | 372 | i_pcr_new = ( (p_block->p_buffer[4] << 24) + |
|---|
| … | … | |
| 374 | 375 | p_block->p_buffer[7] ); |
|---|
| 375 | 376 | i_new = ( (p_block->p_buffer[2] << 8 ) + p_block->p_buffer[3] ); |
|---|
| 376 | | |
|---|
| 377 | | p = *pp_end; |
|---|
| | 377 | i_cur = ( (p_end->p_buffer[2] << 8 ) + p_end->p_buffer[3] ); |
|---|
| | 378 | |
|---|
| | 379 | i_expected = i_cur + 1; |
|---|
| | 380 | if( (i_new - i_expected) >= 0 ) /* Append at the end? */ |
|---|
| | 381 | { |
|---|
| | 382 | msg_Dbg( p_access, "RTP: append %u after %u", i_new, i_cur ); |
|---|
| | 383 | p_end->p_next = p_block; |
|---|
| | 384 | p_sys->p_end = p_end->p_next; |
|---|
| | 385 | return; |
|---|
| | 386 | } |
|---|
| | 387 | /* Add to the front fo the chain? */ |
|---|
| | 388 | p = p_list; |
|---|
| 378 | 389 | i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] ); |
|---|
| 379 | | i_expected = ((i_cur+1) % RTP_SEQ_NUM_SIZE); |
|---|
| 380 | | if( (i_new - i_expected) >= 0 ) /* Append at the end? */ |
|---|
| 381 | | { |
|---|
| 382 | | msg_Dbg( p_access, ">> append %p(%u)==%p(%u)\n", p_block, i_cur, p, i_new ); |
|---|
| 383 | | p->p_next = *pp_end = p_block; |
|---|
| 384 | | return; |
|---|
| 385 | | } |
|---|
| 386 | | /* Add to the front fo the chain? */ |
|---|
| 387 | | p = *pp_list; |
|---|
| 388 | | i_new = ( (p_block->p_buffer[2] << 8 ) + p_block->p_buffer[3] ); |
|---|
| 389 | | i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] ); |
|---|
| 390 | | if( i_cur > i_new ) |
|---|
| 391 | | { |
|---|
| 392 | | msg_Dbg( p_access, ">> prepend %p(%u)==%p(%u)\n", p_block, i_cur, p, i_new ); |
|---|
| | 390 | if( (i_expected - i_new) > 0 ) |
|---|
| | 391 | { |
|---|
| | 392 | msg_Dbg( p_access, "RTP: prepend %u before %u", i_cur, i_new ); |
|---|
| 393 | 393 | p_block->p_next = p; |
|---|
| 394 | | *pp_list = p_block; |
|---|
| | 394 | p_sys->p_list = p_block; |
|---|
| 395 | 395 | return; |
|---|
| 396 | 396 | } |
|---|
| … | … | |
| 401 | 401 | { |
|---|
| 402 | 402 | i_cur = (p->p_buffer[2] << 8 ) + p->p_buffer[3]; |
|---|
| 403 | | i_expected = (i_cur+1) % RTP_SEQ_NUM_SIZE; |
|---|
| 404 | | |
|---|
| 405 | | msg_Dbg( p_access, "i_cur: %u, i_new: %u", i_cur, i_new); |
|---|
| 406 | | if( i_cur == i_new ) |
|---|
| | 403 | i_expected = i_cur+1; |
|---|
| | 404 | |
|---|
| | 405 | if( (i_cur - i_new) == 0 ) |
|---|
| 407 | 406 | { |
|---|
| 408 | 407 | uint32_t i_pcr_cur = ( (p->p_buffer[4] << 24) + |
|---|
| … | … | |
| 421 | 420 | break; |
|---|
| 422 | 421 | } |
|---|
| 423 | | else if( i_expected >= i_new ) /* insert in chain */ |
|---|
| | 422 | else if( (i_expected - i_new) >= 0 ) /* insert in chain */ |
|---|
| 424 | 423 | { |
|---|
| | 424 | block_t *p_tmp = NULL; |
|---|
| | 425 | |
|---|
| 425 | 426 | p_tmp = p->p_next; |
|---|
| 426 | | msg_Dbg( p_access, ">> insert between %p(%u)==%p(%u)", p, i_cur, p_tmp, i_new ); |
|---|
| | 427 | msg_Dbg( p_access, "RTP: insert %u after %u", i_new, i_cur ); |
|---|
| 427 | 428 | p->p_next = p_block; |
|---|
| 428 | 429 | p_block->p_next = p_tmp; |
|---|
| … | … | |
| 432 | 433 | p = p->p_next; |
|---|
| 433 | 434 | } |
|---|
| | 435 | msg_Dbg(p_access, "RTP: trashing duplicate %d", i_new ); |
|---|
| | 436 | block_Release( p_block ); |
|---|
| 434 | 437 | } |
|---|
| 435 | 438 | |
|---|
| … | … | |
| 459 | 462 | while( p ) |
|---|
| 460 | 463 | { |
|---|
| 461 | | i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] ); |
|---|
| 462 | | msg_Dbg( p_access, "rtp_ChainSend: i_cur %u, i_seq %u", i_cur, i_seq ); |
|---|
| 463 | | if( i_cur == i_seq ) |
|---|
| | 464 | i_cur = (p->p_buffer[2] << 8 ) + p->p_buffer[3]; |
|---|
| | 465 | if( (i_cur - i_seq) == 0 ) |
|---|
| 464 | 466 | { |
|---|
| | 467 | msg_Dbg( p_access, "rtp_ChainSend: sequence number %u", i_seq ); |
|---|
| | 468 | |
|---|
| 465 | 469 | i_seq++; /* sent all packets that are received in order */ |
|---|
| 466 | 470 | |
|---|
| … | … | |
| 490 | 494 | p->p_buffer += i_skip; |
|---|
| 491 | 495 | } |
|---|
| 492 | | else if( i_cur > i_seq ) |
|---|
| | 496 | else if( (i_cur - i_seq) > 0 ) |
|---|
| 493 | 497 | { |
|---|
| 494 | 498 | if( p_prev ) |
|---|
| 495 | 499 | { |
|---|
| 496 | | *pp_list = p; |
|---|
| | 500 | p_sys->p_list = p; |
|---|
| 497 | 501 | p_prev->p_next = NULL; |
|---|
| 498 | 502 | p_sys->i_last_pcr = i_pcr_prev; |
|---|
| … | … | |
| 500 | 504 | return p_send; |
|---|
| 501 | 505 | } |
|---|
| 502 | | /* FiXME: or should we return NULL here? */ |
|---|
| 503 | | return NULL; |
|---|
| | 506 | goto out; |
|---|
| 504 | 507 | } |
|---|
| 505 | 508 | p_prev = p; |
|---|
| … | … | |
| 507 | 510 | p = p->p_next; |
|---|
| 508 | 511 | } |
|---|
| | 512 | |
|---|
| | 513 | out: |
|---|
| 509 | 514 | /* We have walked through the complete chain and all packets are |
|---|
| 510 | 515 | * in sequence - so send the whole chain |
|---|
| … | … | |
| 521 | 526 | |
|---|
| 522 | 527 | /* Update the list pointers */ |
|---|
| 523 | | *pp_list = NULL; |
|---|
| 524 | | p_sys->p_next = NULL; |
|---|
| | 528 | p_sys->p_list = NULL; |
|---|
| 525 | 529 | p_sys->p_end = NULL; |
|---|
| 526 | 530 | p_sys->i_sequence_number = ( (p->p_buffer[2] << 8 ) + |
|---|
| … | … | |
| 603 | 607 | if( p_sys->b_first_seqno ) |
|---|
| 604 | 608 | { |
|---|
| 605 | | p_sys->i_sequence_number = i_sequence_number - 1; |
|---|
| | 609 | p_sys->i_sequence_number = i_sequence_number; |
|---|
| 606 | 610 | p_sys->i_last_pcr = i_pcr; |
|---|
| 607 | 611 | p_sys->b_first_seqno = VLC_FALSE; |
|---|
| 608 | | } |
|---|
| | 612 | i_sequence_expected = i_sequence_number; |
|---|
| | 613 | } |
|---|
| | 614 | else |
|---|
| | 615 | i_sequence_expected = p_sys->i_sequence_number + 1; |
|---|
| | 616 | |
|---|
| 609 | 617 | #if 0 |
|---|
| 610 | 618 | /* Emulate packet loss */ |
|---|
| … | … | |
| 616 | 624 | } |
|---|
| 617 | 625 | #endif |
|---|
| 618 | | i_sequence_expected = ((p_sys->i_sequence_number + 1) % RTP_SEQ_NUM_SIZE); |
|---|
| 619 | | if( i_sequence_expected != i_sequence_number ) |
|---|
| | 626 | |
|---|
| | 627 | if( (i_sequence_expected - i_sequence_number) != 0 ) |
|---|
| 620 | 628 | { |
|---|
| 621 | 629 | /* Handle out of order packets */ |
|---|
| 622 | 630 | if( p_sys->i_rtp_late > 0 ) |
|---|
| 623 | 631 | { |
|---|
| 624 | | if( i_sequence_number > i_sequence_expected ) |
|---|
| | 632 | if( (i_sequence_number - i_sequence_expected) > 0 ) |
|---|
| 625 | 633 | { |
|---|
| 626 | 634 | msg_Warn( p_access, |
|---|
| 627 | 635 | "RTP packet out of order (too early) expected %u, current %u", |
|---|
| 628 | 636 | i_sequence_expected, i_sequence_number ); |
|---|
| 629 | | if( (i_pcr - p_sys->i_last_pcr) > (p_sys->i_rtp_late*90) ) |
|---|
| | 637 | if( (i_pcr - p_sys->i_last_pcr) >= (p_sys->i_rtp_late*90) ) |
|---|
| 630 | 638 | { |
|---|
| 631 | 639 | block_t *p_start = p_sys->p_list; |
|---|
| … | … | |
| 639 | 647 | "Gap too big resyncing: delta %u, held for %d ms", |
|---|
| 640 | 648 | (i_pcr - p_sys->i_last_pcr), p_sys->i_rtp_late ); |
|---|
| 641 | | rtp_ChainInsert( p_access, &p_sys->p_list, &p_sys->p_end, p_block ); |
|---|
| | 649 | rtp_ChainInsert( p_access, p_block ); |
|---|
| 642 | 650 | return rtp_ChainSend( p_access, &p_sys->p_list, i_start ); |
|---|
| 643 | 651 | } |
|---|
| 644 | 652 | /* hold packets that arrive too early. */ |
|---|
| 645 | | rtp_ChainInsert( p_access, &p_sys->p_list, &p_sys->p_end, p_block ); |
|---|
| | 653 | rtp_ChainInsert( p_access, p_block ); |
|---|
| 646 | 654 | return rtp_ChainSend( p_access, &p_sys->p_list, i_sequence_expected ); |
|---|
| 647 | 655 | } |
|---|
| 648 | 656 | else if( /* ((i_sequence_expected - i_sequence_number ) > 0) && */ |
|---|
| 649 | | (i_pcr <= p_sys->i_last_pcr) ) |
|---|
| | 657 | (p_sys->i_last_pcr - i_pcr) >= 0 ) |
|---|
| 650 | 658 | { |
|---|
| 651 | 659 | msg_Warn( p_access, |
|---|
| … | … | |
| 699 | 707 | else if( (p_sys->i_rtp_late > 0) && p_sys->p_list ) |
|---|
| 700 | 708 | { |
|---|
| 701 | | if( i_pcr <= p_sys->i_last_pcr ) |
|---|
| | 709 | if( (p_sys->i_last_pcr - i_pcr) >= 0 ) |
|---|
| 702 | 710 | { |
|---|
| 703 | 711 | msg_Warn( p_access, |
|---|
| … | … | |
| 709 | 717 | return NULL; |
|---|
| 710 | 718 | } |
|---|
| 711 | | rtp_ChainInsert( p_access, &p_sys->p_list, &p_sys->p_end, p_block ); |
|---|
| | 719 | rtp_ChainInsert( p_access, p_block ); |
|---|
| 712 | 720 | return rtp_ChainSend( p_access, &p_sys->p_list, i_sequence_expected ); |
|---|
| 713 | 721 | } |
|---|