- /* Read data */
- p_block = block_New( p_access, p_sys->i_mtu );
- p_block->i_buffer = net_Read( p_access, p_sys->fd, NULL,
- p_block->p_buffer, p_sys->i_mtu,
- VLC_FALSE );
- if( p_block->i_buffer <= 0 )
- {
- block_Release( p_block );
- return NULL;
- }
-
- if( p_block->i_buffer >= p_sys->i_mtu && p_sys->b_auto_mtu &&
- p_sys->i_mtu < 32767 )
- {
- /* Increase by 100% */
- p_sys->i_mtu *= 2;
- msg_Dbg( p_access, "increasing MTU to %d", p_sys->i_mtu );
- }
-
- return p_block;
-}
-
-/*
- * rtp_ChainInsert - insert a p_block in the chain and
- * look at the sequence numbers.
- */
-static inline void rtp_ChainInsert( access_t *p_access, block_t **pp_list, block_t **pp_end, block_t *p_block )
-{
- block_t *p_tmp = NULL;
- block_t *p = NULL;
- uint16_t i_new = 0;
- uint16_t i_cur = 0;
- uint16_t i_expected = 0;
- uint32_t i_pcr_new = 0;
-
- if( *pp_list == NULL )
- {
- *pp_list = p_block;
- *pp_end = p_block;
- return;
- }
- /* Appending packets at the end of the chain is the normal case */
- i_pcr_new = ( (p_block->p_buffer[4] << 24) +
- (p_block->p_buffer[5] << 16) +
- (p_block->p_buffer[6] << 8) +
- p_block->p_buffer[7] );
- i_new = ( (p_block->p_buffer[2] << 8 ) + p_block->p_buffer[3] );
-
- p = *pp_end;
- i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] );
- i_expected = ((i_cur+1) % RTP_SEQ_NUM_SIZE);
- if( (i_new - i_expected) >= 0 ) /* Append at the end? */
- {
- msg_Dbg( p_access, ">> append %p(%u)==%p(%u)\n", p_block, i_cur, p, i_new );
- p->p_next = *pp_end = p_block;
- return;
- }
- /* Add to the front fo the chain? */
- p = *pp_list;
- i_new = ( (p_block->p_buffer[2] << 8 ) + p_block->p_buffer[3] );
- i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] );
- if( (i_cur - i_new) > 0 )
- {
- msg_Dbg( p_access, ">> prepend %p(%u)==%p(%u)\n", p_block, i_cur, p, i_new );
- p_block->p_next = p;
- *pp_list = p_block;
- return;
- }
- /* The packet can't be added to the front or the end of the chain,
- * thus walk the chain from the start.
- */
- while( p )
- {
- i_cur = (p->p_buffer[2] << 8 ) + p->p_buffer[3];
- i_expected = (i_cur+1) % RTP_SEQ_NUM_SIZE;
-
- msg_Dbg( p_access, "i_cur: %u, i_new: %u", i_cur, i_new);
- if( i_cur == i_new )
- {
- uint32_t i_pcr_cur = ( (p->p_buffer[4] << 24) +
- (p->p_buffer[5] << 16) +
- (p->p_buffer[6] << 8) +
- p->p_buffer[7] );
- /* This packet might be a duplicate, so check PCR's */
- if( i_pcr_cur >= i_pcr_new )
- {
- /* packet way too late drop it. */
- block_Release( p_block );
- return;
- }
- /* Add it to list later on
- * else if( i_pcr_cur < i_pcr_new ) */
- break;
- }
- else if( (i_expected - i_new) >= 0 ) /* insert in chain */
- {
- p_tmp = p->p_next;
- msg_Dbg( p_access, ">> insert between %p(%u)==%p(%u)", p, i_cur, p_tmp, i_new );
- p->p_next = p_block;
- p_block->p_next = p_tmp;
- return;
- }
- if( !p->p_next ) break;
- p = p->p_next;
- }
-}
-
-/*
- * rtp_ChainSend - look which packets are ready for sending.
- */
-static inline block_t *rtp_ChainSend( access_t *p_access, block_t **pp_list, uint16_t i_seq )
-{
- access_sys_t *p_sys = (access_sys_t *) p_access->p_sys;
- uint16_t i_cur = 0;
-
- if( *pp_list )
- {
- /* Parse RTP header */
- int i_skip = 0;
- int i_extension_bit = 0;
- int i_extension_length = 0;
- int i_CSRC_count = 0;
- int i_payload_type = 0;
- uint32_t i_pcr_prev = 0;
- uint16_t i_seq_prev = 0;
- /* Data pointers */
- block_t *p_prev = NULL;
- block_t *p_send = *pp_list;
- block_t *p = *pp_list;
-
- while( p )
- {
- i_cur = ( (p->p_buffer[2] << 8 ) + p->p_buffer[3] );
- msg_Dbg( p_access, "rtp_ChainSend: i_cur %u, i_seq %u", i_cur, i_seq );
- if( (i_cur - i_seq) == 0 )
- {
- i_seq++; /* sent all packets that are received in order */
-
- /* Remember PCR and sequence number of packet
- * for next iteration */
- i_pcr_prev = ( (p->p_buffer[4] << 24) +
- (p->p_buffer[5] << 16) +
- (p->p_buffer[6] << 8) +
- p->p_buffer[7] );
- i_seq_prev = ( (p->p_buffer[2] << 8 ) +
- p->p_buffer[3] );
-
- /* Parse headerfields we need */
- i_CSRC_count = p->p_buffer[0] & 0x0F;
- i_payload_type = (p->p_buffer[1] & 0x7F);
- i_extension_bit = ( p->p_buffer[0] & 0x10 ) >> 4;
- if ( i_extension_bit == 1)
- i_extension_length = ( (p->p_buffer[14] << 8 ) +
- p->p_buffer[15] );
-
- /* Skip header + CSRC extension field n*(32 bits) + extention */
- i_skip = RTP_HEADER_LEN + 4*i_CSRC_count + i_extension_length;
- if( i_payload_type == 14 ) i_skip += 4;
-
- /* Return the packet without the RTP header. */
- p->i_buffer -= i_skip;
- p->p_buffer += i_skip;
- }
- else if( (i_cur - i_seq) > 0)
- {
- if( p_prev )
- {
- *pp_list = p;
- p_prev->p_next = NULL;
- p_sys->i_last_pcr = i_pcr_prev;
- p_sys->i_sequence_number = i_seq_prev;
- return p_send;
- }
- /* FiXME: or should we return NULL here? */
- return NULL;
- }
- p_prev = p;
- if (!p->p_next) break;
- p = p->p_next;
- }
- /* We have walked through the complete chain and all packets are
- * in sequence - so send the whole chain
- */
- i_payload_type = (p->p_buffer[1] & 0x7F);
- i_CSRC_count = p->p_buffer[0] & 0x0F;
- i_extension_bit = ( p->p_buffer[0] & 0x10 ) >> 4;
- if( i_extension_bit == 1)
- i_extension_length = ( (p->p_buffer[14] << 8 ) + p->p_buffer[15] );
-
- /* Skip header + CSRC extension field n*(32 bits) + extention */
- i_skip = RTP_HEADER_LEN + 4*i_CSRC_count + i_extension_length;
- if( i_payload_type == 14 ) i_skip += 4;
-
- /* Update the list pointers */
- *pp_list = NULL;
- p_sys->p_next = NULL;
- p_sys->p_end = NULL;
- p_sys->i_sequence_number = ( (p->p_buffer[2] << 8 ) +
- p->p_buffer[3] );
- p_sys->i_last_pcr = ( (p->p_buffer[4] << 24) +
- (p->p_buffer[5] << 16) +
- (p->p_buffer[6] << 8) +
- p->p_buffer[7] );
- /* Return the packet without the RTP header. */
- p->i_buffer -= i_skip;
- p->p_buffer += i_skip;
- return p_send;
- }
- return NULL;
-}
-
-/*****************************************************************************
- * BlockParseRTP/BlockRTP:
- *****************************************************************************/
-static block_t *BlockParseRTP( access_t *p_access, block_t *p_block )
-{
- access_sys_t *p_sys = (access_sys_t *) p_access->p_sys;
- int i_rtp_version;
- int i_CSRC_count;
- int i_payload_type;
- int i_skip = 0;
- uint16_t i_sequence_number = 0;
- uint16_t i_sequence_expected = 0;
- int i_extension_bit = 0;
- int i_extension_length = 0;
- uint32_t i_pcr = 0;
-
- if( p_block == NULL )
- return NULL;
-
- if( p_block->i_buffer < RTP_HEADER_LEN )
- {
- msg_Warn( p_access, "received a too short packet for RTP" );
- block_Release( p_block );