]> git.sesse.net Git - vlc/blobdiff - src/input/input_ext-dec.c
* Forgot a file in my last commit.
[vlc] / src / input / input_ext-dec.c
index be42a8e7576c4384b44b81783a22510a66739bb4..9706b4bdc30c16eb93241e8934f85c4c1fa6b932 100644 (file)
@@ -1,9 +1,10 @@
 /*****************************************************************************
  * input_ext-dec.c: services to the decoders
  *****************************************************************************
- * Copyright (C) 1998, 1999, 2000 VideoLAN
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: input_ext-dec.c,v 1.25 2001/12/30 05:46:14 sam Exp $
  *
- * Authors: 
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *****************************************************************************/
 #include "defs.h"
 
-#include "config.h"
+#include <string.h>                                    /* memcpy(), memset() */
+#include <sys/types.h>                                              /* off_t */
+
 #include "common.h"
+#include "intf_msg.h"
 #include "threads.h"
 #include "mtime.h"
 
-#include "intf_msg.h"
-
 #include "stream_control.h"
 #include "input_ext-dec.h"
 #include "input_ext-intf.h"
-
-#include "input.h"
+#include "input_ext-plugins.h"
 
 /*****************************************************************************
  * InitBitstream: initialize a bit_stream_t structure
  *****************************************************************************/
-void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
+void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
+                    void (* pf_bitstream_callback)( struct bit_stream_s *,
+                                                    boolean_t ),
+                    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 = NULL;
-    p_bit_stream->p_callback_arg = NULL;
+    p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
+    p_bit_stream->p_callback_arg = p_callback_arg;
 
     /* Get the first data packet. */
     vlc_mutex_lock( &p_fifo->data_lock );
-    while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
+    while ( p_fifo->p_first == NULL )
     {
         if ( p_fifo->b_die )
         {
@@ -59,12 +63,50 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
         }
         vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
     }
-    p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
+    p_bit_stream->p_data = p_fifo->p_first->p_first;
     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
     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;
     vlc_mutex_unlock( &p_fifo->data_lock );
+
+    /* Call back the decoder. */
+    if( p_bit_stream->pf_bitstream_callback != NULL )
+    {
+        p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
+    }
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        /* Get aligned on a word boundary.
+         * NB : we _will_ get aligned, because we have at most 
+         * sizeof(WORD_TYPE) - 1 bytes to store, and at least
+         * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
+        AlignWord( p_bit_stream );
+    }
+}
+
+/*****************************************************************************
+ * DecoderError : an error occured, use this function to empty the fifo
+ *****************************************************************************/
+void DecoderError( decoder_fifo_t * p_fifo )
+{
+    /* We take the lock, because we are going to read/write the start/end
+     * indexes of the decoder fifo */
+    vlc_mutex_lock (&p_fifo->data_lock);
+
+    /* Wait until a `die' order is sent */
+    while (!p_fifo->b_die)
+    {
+        /* Trash all received PES packets */
+        p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
+
+        /* Waiting for the input thread to put new PES packets in the fifo */
+        vlc_cond_wait (&p_fifo->data_wait, &p_fifo->data_lock);
+    }
+
+    /* We can release the lock before leaving */
+    vlc_mutex_unlock (&p_fifo->data_lock);
 }
 
 /*****************************************************************************
@@ -83,24 +125,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
          * time to jump to the next PES packet */
         if( p_bit_stream->p_data->p_next == NULL )
         {
-            /* We are going to read/write the start and end indexes of the
-             * decoder fifo and to use the fifo's conditional variable,
-             * that's why we need to take the lock before. */
+            pes_packet_t * p_next;
+
             vlc_mutex_lock( &p_fifo->data_lock );
 
             /* 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,
-                                   DECODER_FIFO_START( *p_fifo ) );
-            DECODER_FIFO_INCSTART( *p_fifo );
+                                   p_fifo->p_first );
+            p_fifo->p_first = p_next;
+            p_fifo->i_depth--;
 
-            if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
+            if( p_fifo->p_first == NULL )
             {
+                /* No PES in the FIFO. p_last is no longer valid. */
+                p_fifo->pp_last = &p_fifo->p_first;
+
                 /* 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 = DECODER_FIFO_START( *p_fifo )->p_first;
+            p_bit_stream->p_data = p_fifo->p_first->p_first;
 
             vlc_mutex_unlock( &p_fifo->data_lock );
 
@@ -128,25 +175,8 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
     }
 }
 
-void OldKludge( bit_stream_t * p_bit_stream )
-{
-    WORD_TYPE           buffer_left;
-    ptrdiff_t           i_bytes_left;
-
-    /* Put the remaining bytes (not aligned on a word boundary) in a
-     * temporary buffer. */
-    i_bytes_left = p_bit_stream->p_end - p_bit_stream->p_byte;
-    buffer_left = *((WORD_TYPE *)p_bit_stream->p_end - 1);
-
-    p_bit_stream->pf_next_data_packet( p_bit_stream );
-
-    /* Copy remaining bits of the previous packet */
-    *((WORD_TYPE *)p_bit_stream->p_byte - 1) = buffer_left;
-    p_bit_stream->p_byte -= i_bytes_left;
-}
-
 /*****************************************************************************
- * UnalignedShowBits : return i_bits bits from the bit stream, even when
+ * UnalignedShowBits : places i_bits bits into the bit buffer, even when
  * not aligned on a word boundary
  *****************************************************************************/
 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
@@ -164,13 +194,62 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
         else
         {
             p_bit_stream->pf_next_data_packet( p_bit_stream );
-            p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
-                                            << (8 * sizeof(WORD_TYPE) - 8
-                                            - p_bit_stream->fifo.i_available);
-            p_bit_stream->fifo.i_available += 8;
+
+            if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
+            {
+                /* We are not aligned anymore. */
+                if( ((ptrdiff_t)p_bit_stream->p_byte
+                                    & (sizeof(WORD_TYPE) - 1)) * 8
+                        < p_bit_stream->fifo.i_available )
+                {
+                    /* We are not aligned, and won't be. Copy the first word
+                     * of the packet in a temporary buffer, and we'll see
+                     * later. */
+                    int     i;
+
+                    /* sizeof(WORD_TYPE) - number of bytes to trash
+                     * from the last payload */
+                    int     j;
+
+                    p_bit_stream->i_showbits_buffer = 0;
+
+                    for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
+                    {
+                        if( p_bit_stream->p_byte >= p_bit_stream->p_end )
+                        {
+                            j = i;
+                            p_bit_stream->pf_next_data_packet( p_bit_stream );
+                        }
+                        ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
+                            * p_bit_stream->p_byte;
+                        p_bit_stream->p_byte++;
+                    }
+
+                    /* This is kind of kludgy. */
+                    p_bit_stream->p_data->p_payload_start +=
+                                                         sizeof(WORD_TYPE) - j;
+                    p_bit_stream->p_byte =
+                        (byte_t *)&p_bit_stream->i_showbits_buffer;
+                    p_bit_stream->p_end =
+                        (byte_t *)&p_bit_stream->i_showbits_buffer
+                            + sizeof(WORD_TYPE);
+                    p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
+                    p_bit_stream->p_data = &p_bit_stream->showbits_data;
+                }
+                else
+                {
+                    /* We are not aligned, but we can be. */
+                    AlignWord( p_bit_stream );
+                }
+            }
+
+            /* We have 32 bits ready for reading, it will be enough. */
+            break;
         }
     }
-    return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
+
+    /* It shouldn't loop :-)) */
+    return( ShowBits( p_bit_stream, i_bits ) );
 }
 
 /*****************************************************************************
@@ -184,7 +263,7 @@ u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
 
     i_result = p_bit_stream->fifo.buffer
                     >> (8 * sizeof(WORD_TYPE) - i_bits);
-    i_bits -= p_bit_stream->fifo.i_available;
+    i_bits = -p_bit_stream->fifo.i_available;
 
     /* Gather missing bytes. */
     while( i_bits >= 8 )
@@ -233,7 +312,7 @@ u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
     {
         /* Get aligned on a word boundary. Otherwise it is safer
          * to do it the next time.
-         * NB : we _will_ get aligned, because we have at most 
+         * NB : we _will_ get aligned, because we have at most
          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
         AlignWord( p_bit_stream );