]> git.sesse.net Git - vlc/blobdiff - modules/access/udp.c
backport [13283] [13272]
[vlc] / modules / access / udp.c
index b260b9a97eedf5a7af1ce3f4fa4bebd2b1517019..602a92bbe71609abc5e5811780e2e8e7f1e2b736 100644 (file)
@@ -99,7 +99,7 @@ struct access_sys_t
     vlc_bool_t b_auto_mtu;
 
     /* reorder rtp packets when out-of-sequence */
-    int64_t i_rtp_late;
+    mtime_t i_rtp_late;
     uint16_t i_last_seqno;
     block_t *p_list;
     block_t *p_end;
@@ -191,16 +191,7 @@ static int Open( vlc_object_t *p_this )
 
     /* Set up p_access */
     p_access->pf_read = NULL;
-    if( !strcasecmp( p_access->psz_access, "rtp" )
-          || !strcasecmp( p_access->psz_access, "rtp4" )
-          || !strcasecmp( p_access->psz_access, "rtp6" ) )
-    {
-        p_access->pf_block = BlockRTP;
-    }
-    else
-    {
-        p_access->pf_block = BlockChoose;
-    }
+    p_access->pf_block = BlockChoose;
     p_access->pf_control = Control;
     p_access->pf_seek = NULL;
     p_access->info.i_update = 0;
@@ -343,7 +334,7 @@ static inline vlc_bool_t rtp_ChainInsert( access_t *p_access, block_t *p_block )
     access_sys_t *p_sys = (access_sys_t *) p_access->p_sys;
     block_t *p_prev = NULL;
     block_t *p = p_sys->p_end;
-    uint16_t i_new = p_block->i_seqno;
+    uint16_t i_new = (uint16_t) p_block->i_dts;
     uint16_t i_tmp = 0;
 
     if( !p_sys->p_list )
@@ -357,13 +348,13 @@ static inline vlc_bool_t rtp_ChainInsert( access_t *p_access, block_t *p_block )
 
     for( ;; )
     {
-        i_tmp = i_new - p->i_seqno;
+        i_tmp = i_new - (uint16_t) p->i_dts;
 
         if( !i_tmp )   /* trash duplicate */
             break; 
 
         if ( i_tmp < 32768 )
-        {   /* insert after this block ( i_new > p->i_seqno ) */
+        {   /* insert after this block ( i_new > p->i_dts ) */
             p_block->p_next = p->p_next;
             p->p_next = p_block;
             p_block->p_prev = p;
@@ -371,7 +362,7 @@ static inline vlc_bool_t rtp_ChainInsert( access_t *p_access, block_t *p_block )
             {
                 p_prev->p_prev = p_block;
                 msg_Dbg(p_access, "RTP reordering: insert after %d, new %d", 
-                    p->i_seqno, i_new );
+                    (uint16_t) p->i_dts, i_new );
             }
             else 
             {
@@ -385,7 +376,7 @@ static inline vlc_bool_t rtp_ChainInsert( access_t *p_access, block_t *p_block )
             if( !p_access->info.b_prebuffered || (i_tmp > 32767) )
             {
                 msg_Dbg(p_access, "RTP reordering: prepend %d before %d", 
-                        i_new, p->i_seqno );
+                        i_new, (uint16_t) p->i_dts );
                 p_block->p_next = p;
                 p->p_prev = p_block;
                 p_sys->p_list = p_block;
@@ -397,8 +388,8 @@ static inline vlc_bool_t rtp_ChainInsert( access_t *p_access, block_t *p_block )
 
             /* reordering failed - append the packet to the end of queue */
             msg_Dbg(p_access, "RTP: sequence changed (or buffer too small) "
-                "new: %d, buffer %d...%d", i_new, p->i_seqno
-                p_sys->p_end->i_seqno);
+                "new: %d, buffer %d...%d", i_new, (uint16_t) p->i_dts
+                (uint16_t) p_sys->p_end->i_dts);
             p_sys->p_end->p_next = p_block;
             p_block->p_prev = p_sys->p_end;
             p_sys->p_end = p_block;
@@ -455,10 +446,11 @@ static block_t *BlockParseRTP( access_t *p_access, block_t *p_block )
     if( i_skip >= p_block->i_buffer )
         goto trash;
 
-    /* Return the packet without the RTP header, remember seqno */
+    /* Return the packet without the RTP header, remember seqno in i_dts */
     p_block->i_buffer -= i_skip;
     p_block->p_buffer += i_skip;
-    p_block->i_seqno = i_sequence_number;
+    p_block->i_pts = mdate();
+    p_block->i_dts = (mtime_t) i_sequence_number;
 
 #if 0
     /* Emulate packet loss */
@@ -482,19 +474,19 @@ trash:
 static block_t *BlockPrebufferRTP( access_t *p_access, block_t *p_block )
 {
     access_sys_t *p_sys = p_access->p_sys;
-    int64_t   i_first = mdate();
+    mtime_t   i_first = mdate();
     int       i_count = 0;
     block_t   *p = p_block;
 
     for( ;; )
     {
-        int64_t i_date = mdate();
+        mtime_t i_date = mdate();
 
         if( p && rtp_ChainInsert( p_access, p ))
             i_count++;
 
-        /* Require at least 3 packets in the buffer */
-        if( i_count > 3 && (i_date - i_first) > p_sys->i_rtp_late )
+        /* Require at least 2 packets in the buffer */
+        if( i_count > 2 && (i_date - i_first) > p_sys->i_rtp_late )
             break;
 
         p = BlockParseRTP( p_access, BlockUDP( p_access ));
@@ -509,7 +501,7 @@ static block_t *BlockPrebufferRTP( access_t *p_access, block_t *p_block )
     p_access->info.b_prebuffered = VLC_TRUE;
     p = p_sys->p_list;
     p_sys->p_list = p_sys->p_list->p_next;
-    p_sys->i_last_seqno = p->i_seqno;
+    p_sys->i_last_seqno = (uint16_t) p->i_dts;
     p->p_next = NULL;
     return p;
 }
@@ -519,26 +511,25 @@ static block_t *BlockRTP( access_t *p_access )
     access_sys_t *p_sys = p_access->p_sys;
     block_t *p;
 
-again:
-    p = BlockParseRTP( p_access, BlockUDP( p_access ));
-
-    if ( !p ) 
-        return NULL;
+    while ( !p_sys->p_list || 
+             ( mdate() - p_sys->p_list->i_pts ) < p_sys->i_rtp_late )
+    {
+        p = BlockParseRTP( p_access, BlockUDP( p_access ));
 
-    if ( !p_access->info.b_prebuffered )
-        return BlockPrebufferRTP( p_access, p );
+        if ( !p ) 
+            return NULL;
 
-    if( !rtp_ChainInsert( p_access, p ))
-        goto again;
+        rtp_ChainInsert( p_access, p );
+    }
 
     p = p_sys->p_list;
     p_sys->p_list = p_sys->p_list->p_next;
     p_sys->i_last_seqno++;
-    if( p_sys->i_last_seqno != p->i_seqno )
+    if( p_sys->i_last_seqno != (uint16_t) p->i_dts )
     {
         msg_Dbg( p_access, "RTP: packet(s) lost, expected %d, got %d",
-                 p_sys->i_last_seqno, p->i_seqno );
-        p_sys->i_last_seqno = p->i_seqno;
+                 p_sys->i_last_seqno, (uint16_t) p->i_dts );
+        p_sys->i_last_seqno = (uint16_t) p->i_dts;
     }
     p->p_next = NULL;
     return p;
@@ -561,6 +552,7 @@ static block_t *BlockChoose( access_t *p_access )
     {
         msg_Dbg( p_access, "detected TS over raw UDP" );
         p_access->pf_block = BlockUDP;
+        p_access->info.b_prebuffered = VLC_TRUE;
         return p_block;
     }
 
@@ -578,6 +570,7 @@ static block_t *BlockChoose( access_t *p_access )
     {
         msg_Dbg( p_access, "no supported RTP header detected" );
         p_access->pf_block = BlockUDP;
+        p_access->info.b_prebuffered = VLC_TRUE;
         return p_block;
     }
 
@@ -601,6 +594,7 @@ static block_t *BlockChoose( access_t *p_access )
         default:
             msg_Dbg( p_access, "no RTP header detected" );
             p_access->pf_block = BlockUDP;
+            p_access->info.b_prebuffered = VLC_TRUE;
             return p_block;
     }