]> git.sesse.net Git - vlc/commitdiff
Track RTP sequence numbers and mark the first MPEG2-TS packet with a transport error...
authorJean-Paul Saman <jpsaman@videolan.org>
Mon, 8 Aug 2005 12:25:42 +0000 (12:25 +0000)
committerJean-Paul Saman <jpsaman@videolan.org>
Mon, 8 Aug 2005 12:25:42 +0000 (12:25 +0000)
modules/access/udp.c

index 06183313be907d753791e4b0825f53a8c3a78940..d40146a355b5ba413d7d3a9bb6579067ef5ed0a2 100644 (file)
@@ -7,6 +7,7 @@
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Tristan Leteurtre <tooney@via.ecp.fr>
  *          Laurent Aimar <fenrir@via.ecp.fr>
+ *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
  *
  * Reviewed: 23 October 2003, Jean-Paul Saman <jpsaman@wxs.nl>
  *
@@ -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: