]> git.sesse.net Git - vlc/blobdiff - src/input/input_ext-dec.c
*A lock was not released;
[vlc] / src / input / input_ext-dec.c
index fe39a1d2923b70a114e6fabca22fc12dc11604f3..449ad06ffa50b05e0db71bd92edfd9ecee30700e 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-dec.c: services to the decoders
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ext-dec.c,v 1.27 2001/12/31 03:26:27 massiot Exp $
+ * $Id: input_ext-dec.c,v 1.30 2002/03/01 00:33:18 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -43,7 +43,6 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
                     void * p_callback_arg )
 {
     p_bit_stream->p_decoder_fifo = p_fifo;
-    p_bit_stream->pf_next_data_packet = NextDataPacket;
     p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
     p_bit_stream->p_callback_arg = p_callback_arg;
 
@@ -63,6 +62,9 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
     p_bit_stream->p_end  = p_bit_stream->p_data->p_payload_end;
     p_bit_stream->fifo.buffer = 0;
     p_bit_stream->fifo.i_available = 0;
+    p_bit_stream->i_pts = p_fifo->p_first->i_pts;
+    p_bit_stream->i_dts = p_fifo->p_first->i_dts;
+    p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
     vlc_mutex_unlock( &p_fifo->data_lock );
 
     /* Call back the decoder. */
@@ -94,7 +96,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
     while (!p_fifo->b_die)
     {
         /* Trash all received PES packets */
-        p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
+        input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
         p_fifo->p_first = NULL;
         p_fifo->pp_last = &p_fifo->p_first;
 
@@ -107,12 +109,13 @@ void DecoderError( decoder_fifo_t * p_fifo )
 }
 
 /*****************************************************************************
- * NextDataPacket: go to the next data packet
+ * NextDataPacket: go to the data packet after *pp_data, return 1 if we
+ * changed PES
  *****************************************************************************/
-void NextDataPacket( bit_stream_t * p_bit_stream )
+static __inline__ boolean_t _NextDataPacket( decoder_fifo_t * p_fifo,
+                                             data_packet_t ** pp_data )
 {
-    decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
-    boolean_t           b_new_pes;
+    boolean_t b_new_pes;
 
     /* We are looking for the next data packet that contains real data,
      * and not just a PES header */
@@ -120,7 +123,7 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
     {
         /* We were reading the last data packet of this PES packet... It's
          * time to jump to the next PES packet */
-        if( p_bit_stream->p_data->p_next == NULL )
+        if( (*pp_data)->p_next == NULL )
         {
             pes_packet_t * p_next;
 
@@ -129,8 +132,7 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
             /* Free the previous PES packet. */
             p_next = p_fifo->p_first->p_next;
             p_fifo->p_first->p_next = NULL;
-            p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
-                                   p_fifo->p_first );
+            input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
             p_fifo->p_first = p_next;
             p_fifo->i_depth--;
 
@@ -139,12 +141,17 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
                 /* No PES in the FIFO. p_last is no longer valid. */
                 p_fifo->pp_last = &p_fifo->p_first;
 
+                /* Signal the input thread we're waiting. This is only
+                 * needed in case of slave clock (ES plug-in)  but it won't
+                 * harm. */
+                vlc_cond_signal( &p_fifo->data_wait );
+
                 /* Wait for the input to tell us when we receive a packet. */
                 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
             }
 
-            /* The next byte could be found in the next PES packet */
-            p_bit_stream->p_data = p_fifo->p_first->p_first;
+            /* The next packet could be found in the next PES packet */
+            *pp_data = p_fifo->p_first->p_first;
 
             vlc_mutex_unlock( &p_fifo->data_lock );
 
@@ -154,12 +161,30 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
         {
             /* Perhaps the next data packet of the current PES packet contains
              * real data (ie its payload's size is greater than 0). */
-            p_bit_stream->p_data = p_bit_stream->p_data->p_next;
+            *pp_data = (*pp_data)->p_next;
 
             b_new_pes = 0;
         }
-    } while ( p_bit_stream->p_data->p_payload_start
-               == p_bit_stream->p_data->p_payload_end );
+    } while ( (*pp_data)->p_payload_start == (*pp_data)->p_payload_end );
+
+    return( b_new_pes );
+}
+
+boolean_t NextDataPacket( decoder_fifo_t * p_fifo, data_packet_t ** pp_data )
+{
+    return( _NextDataPacket( p_fifo, pp_data ) );
+}
+
+/*****************************************************************************
+ * BitstreamNextDataPacket: go to the next data packet, and update bitstream
+ * context
+ *****************************************************************************/
+static __inline__ void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
+{
+    decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
+    boolean_t           b_new_pes;
+
+    b_new_pes = _NextDataPacket( p_fifo, &p_bit_stream->p_data );
 
     /* We've found a data packet which contains interesting data... */
     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
@@ -170,6 +195,25 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
     {
         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
     }
+
+    /* Discontinuity management. */
+    if( p_bit_stream->p_data->b_discard_payload )
+    {
+        p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
+    }
+
+    /* Retrieve the PTS. */
+    if( b_new_pes && p_fifo->p_first->i_pts )
+    {
+        p_bit_stream->i_pts = p_fifo->p_first->i_pts;
+        p_bit_stream->i_dts = p_fifo->p_first->i_dts;
+        p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
+    }
+}
+
+void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
+{
+    _BitstreamNextDataPacket( p_bit_stream );
 }
 
 /*****************************************************************************
@@ -190,7 +234,7 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
         }
         else
         {
-            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            _BitstreamNextDataPacket( p_bit_stream );
 
             if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
             {
@@ -215,7 +259,7 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
                         if( p_bit_stream->p_byte >= p_bit_stream->p_end )
                         {
                             j = i;
-                            p_bit_stream->pf_next_data_packet( p_bit_stream );
+                            _BitstreamNextDataPacket( p_bit_stream );
                         }
                         ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
                             * p_bit_stream->p_byte;
@@ -272,7 +316,7 @@ u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
         }
         else
         {
-            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            _BitstreamNextDataPacket( p_bit_stream );
             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
             i_bits -= 8;
         }
@@ -292,7 +336,7 @@ u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
         }
         else
         {
-            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            _BitstreamNextDataPacket( p_bit_stream );
             i_result |= *p_bit_stream->p_byte >> i_tmp;
             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
                  << ( sizeof(WORD_TYPE) * 8 - i_tmp );
@@ -334,7 +378,7 @@ void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
         }
         else
         {
-            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            _BitstreamNextDataPacket( p_bit_stream );
             p_bit_stream->p_byte++;
             p_bit_stream->fifo.i_available += 8;
         }
@@ -352,7 +396,7 @@ void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
         }
         else
         {
-            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            _BitstreamNextDataPacket( p_bit_stream );
             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
                  << ( sizeof(WORD_TYPE) * 8 - 8
                          - p_bit_stream->fifo.i_available );
@@ -375,3 +419,28 @@ void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
     }
 }
 
+/*****************************************************************************
+ * CurrentPTS: returns the current PTS and DTS
+ *****************************************************************************/
+void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
+                 mtime_t * pi_dts )
+{
+    /* Check if the current PTS is already valid (ie. if the first byte
+     * of the packet has already been used in the decoder). */
+    ptrdiff_t p_diff = p_bit_stream->p_byte - p_bit_stream->p_pts_validity;
+    if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
+         || (p_diff * 8) >= p_bit_stream->fifo.i_available
+            /* We have buffered less bytes than actually read */ )
+    {
+        *pi_pts = p_bit_stream->i_pts;
+        if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
+        p_bit_stream->i_pts = 0;
+        p_bit_stream->i_dts = 0;
+    }
+    else
+    {
+        *pi_pts = 0;
+        if( pi_dts != NULL) *pi_dts = 0;
+    }
+}
+