]> git.sesse.net Git - vlc/commitdiff
* 32-bit aligned bitstream (not that fast).
authorChristophe Massiot <massiot@videolan.org>
Thu, 18 Jan 2001 17:40:06 +0000 (17:40 +0000)
committerChristophe Massiot <massiot@videolan.org>
Thu, 18 Jan 2001 17:40:06 +0000 (17:40 +0000)
include/common.h
include/input_ext-dec.h
src/input/input.h
src/input/input_ext-dec.c
src/video_parser/vpar_synchro.c

index 92f6b8aa726846a0855da74c16dc088934b6eb97..453aa65e10d07b816299f8a447da79dd250387aa 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.25 2001/01/18 05:13:22 sam Exp $
+ * $Id: common.h,v 1.26 2001/01/18 17:40:06 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -155,31 +155,6 @@ struct macroblock_s;
 #define MIN(a, b)   ( ((a) < (b)) ? (a) : (b) )
 #endif
 
-/*
- * This is stolen from the livid source who stole it from the kernel
- */
-
-#if defined(SYS_BEOS)
-#   define swab32(x) B_BENDIAN_TO_HOST_INT32(x)
-#else
-#   ifdef WORDS_BIG_ENDIAN
-#       define swab32(x) (x)
-#   else
-#       if defined (HAVE_X86_BSWAP)
-static __inline__ const u32 __i386_swab32( u32 x )
-{
-    __asm__("bswap %0" : "=r" (x) : "0" (x));
-    return x;
-}
-#           define swab32(x) __i386_swab32(x)
-#       else
-#           define swab32(x)                                                 \
-            ( ( (u32)(((u8*)&x)[0]) << 24 ) | ( (u32)(((u8*)&x)[1]) << 16 ) |\
-              ( (u32)(((u8*)&x)[2]) << 8 )  | ( (u32)(((u8*)&x)[3])) )
-#       endif
-#   endif
-#endif
-
 /* MSB (big endian)/LSB (little endian) conversions - network order is always
  * MSB, and should be used for both network communications and files. Note that
  * byte orders other than little and big endians are not supported, but only
@@ -204,6 +179,7 @@ static __inline__ const u32 __i386_swab32( u32 x )
 #endif
 
 /* Macros with automatic casts */
-#define U32_AT(p)   ( swab32 ( *( (u32 *)(p) ) ) )
-#define U16_AT(p)   ( ntohs ( *( (u16 *)(p) ) ) )
+#define U64_AT(p)   ( ntoh64 ( *( (u64 *)(p) ) ) )
+#define U32_AT(p)   ( ntoh32 ( *( (u32 *)(p) ) ) )
+#define U16_AT(p)   ( ntoh16 ( *( (u16 *)(p) ) ) )
 
index 197730836566544994ba2774573e5043e7d6d851..32df3f460dd9064c9e5f438576fd74e78024d71c 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-dec.h: structures exported to the VideoLAN decoders
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-dec.h,v 1.14 2001/01/13 12:57:19 sam Exp $
+ * $Id: input_ext-dec.h,v 1.15 2001/01/18 17:40:06 massiot Exp $
  *
  * Authors:
  *
@@ -113,7 +113,7 @@ typedef struct decoder_fifo_s
  * This type describes a bit fifo used to store bits while working with the
  * input stream at the bit level.
  *****************************************************************************/
-typedef u32         WORD_TYPE;        /* only u32 is supported at the moment */
+typedef u32         WORD_TYPE;
 
 typedef struct bit_fifo_s
 {
@@ -172,123 +172,88 @@ typedef struct bit_stream_s
  *****************************************************************************/
 
 /*
- * Philosophy of the first implementation : the bit buffer is first filled by
- * NeedBits, then the buffer can be read via p_bit_stream->fifo.buffer, and
- * unnecessary bits are dumped with a DumpBits() call.
+ * DISCUSSION : How to use the bit_stream structures
+ *
+ * sizeof(WORD_TYPE) (usually 32) bits are read at the same time, thus
+ * minimizing the number of p_byte changes.
+ * Bits are read via GetBits() or ShowBits.
+ *
+ * XXX : Be aware that if, in the forthcoming functions, i_bits > 24,
+ * the data have to be already aligned on an 8-bit boundary, or wrong
+ * results will be returned. Use RealignBits() if unsure.
  */
 
+#if (WORD_TYPE == u32)
+#   define WORD_AT      U32_AT
+#elif (WORD_TYPE == u64)
+#   define WORD_AT      U64_AT
+#else
+#   error Unsupported WORD_TYPE
+#endif
+
 /*****************************************************************************
- * GetByte : reads the next byte in the input stream (PRIVATE)
+ * Protoypes from input_ext-dec.c
  *****************************************************************************/
-static __inline__ byte_t _GetByte( bit_stream_t * p_bit_stream )
-{
-    /* Are there some bytes left in the current data packet ? */
-    /* could change this test to have a if (! (bytes--)) instead */
-    if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
-    {
-        /* no, switch to next data packet */
-        p_bit_stream->pf_next_data_packet( p_bit_stream );
-    }
-
-    return( *(p_bit_stream->p_byte++) );
-}
+u32  UnalignedShowBits( struct bit_stream_s *, unsigned int );
+void UnalignedRemoveBits( struct bit_stream_s * );
+u32  UnalignedGetBits( struct bit_stream_s *, unsigned int );
 
 /*****************************************************************************
- * NeedBits : reads i_bits new bits in the bit stream and stores them in the
- *            bit buffer
- *****************************************************************************
- * - i_bits must be less or equal 32 !
- * - There is something important to notice with that function : if the number
- * of bits available in the bit buffer when calling NeedBits() is greater than
- * 24 (i_available > 24) but less than the number of needed bits
- * (i_available < i_bits), the byte returned by GetByte() will be shifted with
- * a negative value and the number of bits available in the bit buffer will be
- * set to more than 32 !
+ * AlignWord : fill in the bit buffer so that the byte pointer be aligned
+ * on a word boundary (XXX: there must be at least sizeof(WORD_TYPE) - 1
+ * empty bytes in the bit buffer)
  *****************************************************************************/
-static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
+static __inline__ void AlignWord( bit_stream_t * p_bit_stream )
 {
-    while ( p_bit_stream->fifo.i_available < i_bits )
+    while( (p_bit_stream->p_byte - p_bit_stream->p_data->p_buffer)
+             & (sizeof(WORD_TYPE) - 1) )
     {
-        p_bit_stream->fifo.buffer |= ((WORD_TYPE)_GetByte( p_bit_stream ))
-                                     << (sizeof(WORD_TYPE) - 8
-                                            - p_bit_stream->fifo.i_available);
-        p_bit_stream->fifo.i_available += 8;
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            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;
+        }
+        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;
+        }
     }
 }
 
-/*****************************************************************************
- * DumpBits : removes i_bits bits from the bit buffer
- *****************************************************************************
- * - i_bits <= i_available
- * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
- *****************************************************************************/
-static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
-{
-    p_bit_stream->fifo.buffer <<= i_bits;
-    p_bit_stream->fifo.i_available -= i_bits;
-}
-
-
-/*
- * Philosophy of the second implementation : WORD_LENGTH (usually 32) bits
- * are read at the same time, thus minimizing the number of p_byte changes.
- * Bits are read via GetBits() or ShowBits. This is slightly faster. Be
- * aware that if, in the forthcoming functions, i_bits > 24, the data have to
- * be already aligned on an 8-bit boundary, or wrong results will be
- * returned.
- */
-
-#if (WORD_TYPE != u32)
-#   error Not supported word
-#endif
-
 /*****************************************************************************
  * ShowBits : return i_bits bits from the bit stream
  *****************************************************************************/
-static __inline__ WORD_TYPE _ShowWord( bit_stream_t * p_bit_stream )
-{
-    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
-    {
-        return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
-    }
-
-    p_bit_stream->pf_next_data_packet( p_bit_stream );
-    return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
-}
-
-static __inline__ WORD_TYPE ShowBits( bit_stream_t * p_bit_stream, int i_bits )
+static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream,
+                                unsigned int i_bits )
 {
     if( p_bit_stream->fifo.i_available >= i_bits )
     {
         return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
     }
 
-    return( (p_bit_stream->fifo.buffer |
-            (_ShowWord( p_bit_stream ) >> p_bit_stream->fifo.i_available))
-                    >> (8 * sizeof(WORD_TYPE) - i_bits) );
-}
-
-/*****************************************************************************
- * GetWord : returns the next word to be read (PRIVATE)
- *****************************************************************************/
-static __inline__ WORD_TYPE _GetWord( bit_stream_t * p_bit_stream )
-{
     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
     {
-        return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
-    }
-    else
-    {
-        p_bit_stream->pf_next_data_packet( p_bit_stream );
-        return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
+        return( (p_bit_stream->fifo.buffer |
+                    (WORD_AT( p_bit_stream->p_byte )
+                        >> p_bit_stream->fifo.i_available))
+                    >> (8 * sizeof(WORD_TYPE) - i_bits) );
     }
+
+    return UnalignedShowBits( p_bit_stream, i_bits );
 }
 
 /*****************************************************************************
  * RemoveBits : removes i_bits bits from the bit buffer
  *              XXX: do not use for 32 bits, see RemoveBits32
  *****************************************************************************/
-static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
+static __inline__ void RemoveBits( bit_stream_t * p_bit_stream,
+                                   unsigned int i_bits )
 {
     p_bit_stream->fifo.i_available -= i_bits;
 
@@ -297,78 +262,122 @@ static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
         p_bit_stream->fifo.buffer <<= i_bits;
         return;
     }
-    p_bit_stream->fifo.buffer = _GetWord( p_bit_stream )
-                            << ( -p_bit_stream->fifo.i_available );
-    p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
+                                        << ( -p_bit_stream->fifo.i_available );
+        ((WORD_TYPE *)p_bit_stream->p_byte)++;
+        p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
+        return;
+    }
+
+    UnalignedRemoveBits( p_bit_stream );
 }
 
 /*****************************************************************************
  * RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
  *                refill it)
  *****************************************************************************/
+#if (WORD_TYPE == u32)
 static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
 {
-    if( p_bit_stream->fifo.i_available )
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
     {
-        p_bit_stream->fifo.buffer = _GetWord( p_bit_stream )
+        if( p_bit_stream->fifo.i_available )
+        {
+            p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
                             << (32 - p_bit_stream->fifo.i_available);
+            ((WORD_TYPE *)p_bit_stream->p_byte)++;
+            return;
+        }
+
+        ((WORD_TYPE *)p_bit_stream->p_byte)++;
+        return;
     }
-    else
-    {
-        _GetWord( p_bit_stream );
-    }
+
+    p_bit_stream->fifo.i_available -= 32;
+    UnalignedRemoveBits( p_bit_stream );
 }
+#else
+#   define RemoveBits32( p_bit_stream )     RemoveBits( p_bit_stream, 32 )
+#endif
 
 /*****************************************************************************
  * GetBits : returns i_bits bits from the bit stream and removes them
  *           XXX: do not use for 32 bits, see GetBits32
  *****************************************************************************/
-static __inline__ WORD_TYPE GetBits( bit_stream_t * p_bit_stream, int i_bits )
+static __inline__ u32 GetBits( bit_stream_t * p_bit_stream,
+                               unsigned int i_bits )
 {
     u32             i_result;
 
-    p_bit_stream->fifo.i_available -= i_bits;
-    if( p_bit_stream->fifo.i_available >= 0 )
+    if( p_bit_stream->fifo.i_available >= i_bits )
     {
-        i_result = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits);
+        p_bit_stream->fifo.i_available -= i_bits;
+        i_result = p_bit_stream->fifo.buffer
+                        >> (8 * sizeof(WORD_TYPE) - i_bits);
         p_bit_stream->fifo.buffer <<= i_bits;
         return( i_result );
     }
 
-    i_result = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits);
-    p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
-    i_result |= p_bit_stream->fifo.buffer
-                             >> (8 * sizeof(WORD_TYPE)
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        p_bit_stream->fifo.i_available -= i_bits;
+        i_result = p_bit_stream->fifo.buffer
+                        >> (8 * sizeof(WORD_TYPE) - i_bits);
+        p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
+        ((WORD_TYPE *)p_bit_stream->p_byte)++;
+        i_result |= p_bit_stream->fifo.buffer
+                        >> (8 * sizeof(WORD_TYPE)
                                      + p_bit_stream->fifo.i_available);
-    p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
-    p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
+        p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
+        p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
+        return( i_result );
+    }
 
-    return( i_result );
+    return UnalignedGetBits( p_bit_stream, i_bits );
 }
 
 /*****************************************************************************
  * GetBits32 : returns 32 bits from the bit stream and removes them
  *****************************************************************************/
-static __inline__ WORD_TYPE GetBits32( bit_stream_t * p_bit_stream )
+#if (WORD_TYPE == u32)
+static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
 {
-    WORD_TYPE               i_result;
+    u32             i_result;
 
-    if( p_bit_stream->fifo.i_available )
+    if( p_bit_stream->fifo.i_available == 32 )
     {
+        p_bit_stream->fifo.i_available = 0;
         i_result = p_bit_stream->fifo.buffer;
-        p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
-
-        i_result |= p_bit_stream->fifo.buffer
-                             >> (p_bit_stream->fifo.i_available);
-        p_bit_stream->fifo.buffer <<= (8 * sizeof(WORD_TYPE)
-                                    - p_bit_stream->fifo.i_available);
+        p_bit_stream->fifo.buffer = 0;
         return( i_result );
     }
-    else
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
     {
-        return( _GetWord( p_bit_stream ) );
+        if( p_bit_stream->fifo.i_available )
+        {
+            i_result = p_bit_stream->fifo.buffer;
+            p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
+            ((WORD_TYPE *)p_bit_stream->p_byte)++;
+            i_result |= p_bit_stream->fifo.buffer
+                             >> (p_bit_stream->fifo.i_available);
+            p_bit_stream->fifo.buffer <<= (32 - p_bit_stream->fifo.i_available);
+            return( i_result );
+        }
+
+        i_result = WORD_AT( p_bit_stream->p_byte );
+        ((WORD_TYPE *)p_bit_stream->p_byte)++;
+        return( i_result );
     }
+
+    return UnalignedGetBits( p_bit_stream, 32 );
 }
+#else
+#   define GetBits32( p_bit_stream )    GetBits( p_bit_stream, 32 )
+#endif
 
 /*****************************************************************************
  * RealignBits : realigns the bit buffer on an 8-bit boundary
@@ -380,11 +389,6 @@ static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
 }
 
 
-/*
- * Philosophy of the third implementation : the decoder asks for n bytes,
- * and we will copy them in its buffer.
- */
-
 /*****************************************************************************
  * GetChunk : reads a large chunk of data
  *****************************************************************************
@@ -397,6 +401,15 @@ static __inline__ void GetChunk( bit_stream_t * p_bit_stream,
 {
     ptrdiff_t           i_available;
 
+    if( p_bit_stream->fifo.i_available )
+    {
+        *((WORD_TYPE *)p_buffer) = WORD_AT( p_bit_stream->fifo.buffer );
+        p_buffer += p_bit_stream->fifo.i_available >> 3;
+        i_buf_len -= p_bit_stream->fifo.i_available >> 3;
+        p_bit_stream->fifo.buffer = 0;
+        p_bit_stream->fifo.i_available = 0;
+    }
+
     if( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
             >= i_buf_len )
     {
@@ -422,6 +435,43 @@ static __inline__ void GetChunk( bit_stream_t * p_bit_stream,
             p_bit_stream->p_byte += i_buf_len;
         }
     }
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        AlignWord( p_bit_stream );
+    }
+}
+
+
+/*
+ * The following functions are now deprecated.
+ */
+
+static __inline__ byte_t _GetByte( bit_stream_t * p_bit_stream )
+{
+    if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
+    {
+        p_bit_stream->pf_next_data_packet( p_bit_stream );
+    }
+
+    return( *(p_bit_stream->p_byte++) );
+}
+
+static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
+{
+    while ( p_bit_stream->fifo.i_available < i_bits )
+    {
+        p_bit_stream->fifo.buffer |= ((WORD_TYPE)_GetByte( p_bit_stream ))
+                                     << (8 * sizeof(WORD_TYPE) - 8
+                                            - p_bit_stream->fifo.i_available);
+        p_bit_stream->fifo.i_available += 8;
+    }
+}
+
+static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
+{
+    p_bit_stream->fifo.buffer <<= i_bits;
+    p_bit_stream->fifo.i_available -= i_bits;
 }
 
 
index 1c82565205416a8b677e0705ed33925943a505b8..e5763ec3227d84aac9ec76868d80f39fcaa7a008 100644 (file)
@@ -2,7 +2,7 @@
  * input.h: structures of the input not exported to other modules
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input.h,v 1.10 2001/01/15 08:07:31 sam Exp $
+ * $Id: input.h,v 1.11 2001/01/18 17:40:06 massiot Exp $
  *
  * Authors:
  *
@@ -118,10 +118,6 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
         return;
     }
 
-    /* XXX FIXME SARASS TODO: remove the following one-liner kludge when
-     * we have bitstream IV, we won't need it anymore */
-    ((WORD_TYPE *)p_pad_data->p_payload_start)++;
-
     memset( p_pad_data->p_buffer, 0, PADDING_PACKET_SIZE );
     p_pad_data->b_discard_payload = 1;
     p_pes = p_es->p_pes;
index adbc9f58aac3ef72b07217ad1c47e2afe0d36171..be42a8e7576c4384b44b81783a22510a66739bb4 100644 (file)
@@ -72,16 +72,9 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
  *****************************************************************************/
 void NextDataPacket( bit_stream_t * p_bit_stream )
 {
-    WORD_TYPE           buffer_left;
-    ptrdiff_t           i_bytes_left;
     decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
     boolean_t           b_new_pes;
 
-    /* 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);
-
     /* We are looking for the next data packet that contains real data,
      * and not just a PES header */
     do
@@ -133,8 +126,176 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
     {
         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
     }
+}
+
+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
+ * not aligned on a word boundary
+ *****************************************************************************/
+u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
+{
+    /* We just fill in the bit buffer. */
+    while( p_bit_stream->fifo.i_available < i_bits )
+    {
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            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;
+        }
+        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;
+        }
+    }
+    return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
+}
+
+/*****************************************************************************
+ * UnalignedGetBits : returns i_bits bits from the bit stream and removes
+ * them from the buffer, even when the bit stream is not aligned on a word
+ * boundary
+ *****************************************************************************/
+u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
+{
+    u32         i_result;
+
+    i_result = p_bit_stream->fifo.buffer
+                    >> (8 * sizeof(WORD_TYPE) - i_bits);
+    i_bits -= p_bit_stream->fifo.i_available;
+
+    /* Gather missing bytes. */
+    while( i_bits >= 8 )
+    {
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
+            i_bits -= 8;
+        }
+        else
+        {
+            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
+            i_bits -= 8;
+        }
+    }
+
+    /* Gather missing bits. */
+    if( i_bits > 0 )
+    {
+        unsigned int    i_tmp = 8 - i_bits;
+
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            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 );
+            p_bit_stream->fifo.i_available = i_tmp;
+        }
+        else
+        {
+            p_bit_stream->pf_next_data_packet( 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 );
+            p_bit_stream->fifo.i_available = i_tmp;
+        }
+    }
+    else
+    {
+        p_bit_stream->fifo.i_available = 0;
+        p_bit_stream->fifo.buffer = 0;
+    }
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        /* 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 
+         * sizeof(WORD_TYPE) - 1 bytes to store, and at least
+         * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
+        AlignWord( p_bit_stream );
+    }
+
+    return( i_result );
+}
+
+/*****************************************************************************
+ * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
+ * buffer, even when the bit stream is not aligned on a word boundary
+ *****************************************************************************/
+void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
+{
+    /* First remove all unnecessary bytes. */
+    while( p_bit_stream->fifo.i_available <= -8 )
+    {
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            p_bit_stream->p_byte++;
+            p_bit_stream->fifo.i_available += 8;
+        }
+        else
+        {
+            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            p_bit_stream->p_byte++;
+            p_bit_stream->fifo.i_available += 8;
+        }
+    }
+
+    /* Remove unnecessary bits. */
+    if( p_bit_stream->fifo.i_available < 0 )
+    {
+        if( p_bit_stream->p_byte < p_bit_stream->p_end )
+        {
+            p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+                 << ( sizeof(WORD_TYPE) * 8 - 8
+                         - p_bit_stream->fifo.i_available );
+            p_bit_stream->fifo.i_available += 8;
+        }
+        else
+        {
+            p_bit_stream->pf_next_data_packet( p_bit_stream );
+            p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
+                 << ( sizeof(WORD_TYPE) * 8 - 8
+                         - p_bit_stream->fifo.i_available );
+            p_bit_stream->fifo.i_available += 8;
+        }
+    }
+    else
+    {
+        p_bit_stream->fifo.buffer = 0;
+    }
+
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
+    {
+        /* 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 
+         * sizeof(WORD_TYPE) - 1 bytes to store, and at least
+         * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
+        AlignWord( p_bit_stream );
+    }
+}
+
index d96433e64db3f6e492a8dd620d2268df07da40db..82e6e3e3e9207956751cc080c24cfe20f83505b3 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_synchro.c : frame dropping routines
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.78 2001/01/18 05:13:23 sam Exp $
+ * $Id: vpar_synchro.c,v 1.79 2001/01/18 17:40:06 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -222,7 +222,8 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
                                             + tau_yuv)
 #define S                           p_vpar->synchro
         /* VPAR_SYNCHRO_DEFAULT */
-        mtime_t         now, pts, period, tau_yuv;
+        mtime_t         now, period, tau_yuv;
+        mtime_t         pts = 0;
         boolean_t       b_decode = 0;
 #ifdef DEBUG_VPAR
         char            p_date[MSTRTIME_MAX_SIZE];