From 30ec47f86aeeef006d8ebdfd7cb987ab99ad3051 Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman Date: Mon, 8 Aug 2005 12:25:42 +0000 Subject: [PATCH] Track RTP sequence numbers and mark the first MPEG2-TS packet with a transport error when a discontinuity occurs. --- modules/access/udp.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/modules/access/udp.c b/modules/access/udp.c index 06183313be..d40146a355 100644 --- a/modules/access/udp.c +++ b/modules/access/udp.c @@ -7,6 +7,7 @@ * Authors: Christophe Massiot * Tristan Leteurtre * Laurent Aimar + * Jean-Paul Saman * * Reviewed: 23 October 2003, Jean-Paul Saman * @@ -88,6 +89,9 @@ struct access_sys_t int i_mtu; vlc_bool_t b_auto_mtu; + + /* rtp only */ + int i_sequence_number; }; /***************************************************************************** @@ -102,7 +106,6 @@ static int Open( vlc_object_t *p_this ) char *psz_parser, *psz_server_addr, *psz_bind_addr = ""; int i_bind_port, i_server_port = 0; - /* First set ipv4/ipv6 */ var_Create( p_access, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_access, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); @@ -221,6 +224,9 @@ static int Open( vlc_object_t *p_this ) /* Update default_pts to a suitable value for udp access */ var_Create( p_access, "udp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); + /* Keep track of RTP sequence number */ + p_sys->i_sequence_number = -1; + return VLC_SUCCESS; } @@ -322,7 +328,11 @@ static block_t *BlockParseRTP( access_t *p_access, block_t *p_block ) int i_CSRC_count; int i_payload_type; int i_skip = 0; - + int i_sequence_number = 0; + + if( p_block == NULL ) + return NULL; + if( p_block->i_buffer < RTP_HEADER_LEN ) goto trash; @@ -331,6 +341,7 @@ static block_t *BlockParseRTP( access_t *p_access, block_t *p_block ) i_rtp_version = ( p_block->p_buffer[0] & 0xC0 ) >> 6; i_CSRC_count = ( p_block->p_buffer[0] & 0x0F ); i_payload_type = ( p_block->p_buffer[1] & 0x7F ); + i_sequence_number = ( (p_block->p_buffer[2] << 8 ) + p_block->p_buffer[3] ); if ( i_rtp_version != 2 ) msg_Dbg( p_access, "RTP version is %u, should be 2", i_rtp_version ); @@ -349,7 +360,26 @@ static block_t *BlockParseRTP( access_t *p_access, block_t *p_block ) /* Return the packet without the RTP header. */ p_block->i_buffer -= i_skip; p_block->p_buffer += i_skip; - + +#define RTP_SEQ_NUM_SIZE 65536 + /* Detect RTP packet loss through tracking sequence numbers. + * See RFC 1889. */ + if( p_access->p_sys->i_sequence_number == -1 ) + p_access->p_sys->i_sequence_number = i_sequence_number; + + if( ((p_access->p_sys->i_sequence_number + 1) % RTP_SEQ_NUM_SIZE) != i_sequence_number ) + { + msg_Warn( p_access, "RTP packet(s) lost, expected sequence number %d got %d", + ((p_access->p_sys->i_sequence_number + 1) % RTP_SEQ_NUM_SIZE), + i_sequence_number ); + if( i_payload_type == 33 ) + { + /* Mark transport error in the first TS packet in the RTP stream. */ + p_block->p_buffer[1] |= 0x80; + } + } + p_access->p_sys->i_sequence_number = i_sequence_number; +#undef RTP_SEQ_NUM_SIZE return p_block; trash: -- 2.39.2