]> git.sesse.net Git - vlc/blobdiff - include/decoder_fifo.h
. removed the sdlvlc alias
[vlc] / include / decoder_fifo.h
index 4e0dbf7b35c05861eb40175a4b46adadd1799299..e58c4907504c42c53e1a2b0af467b4369c5f9fb4 100644 (file)
@@ -1,28 +1,51 @@
 /*****************************************************************************
  * decoder_fifo.h: interface for decoders PES fifo
- * (c)1999 VideoLAN
  *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
  * Required headers:
  * - "config.h"
  * - "common.h"
- * - "vlc_thread.h"
+ * - "threads.h"
  * - "input.h"
  *****************************************************************************/
 
+#define WORD_TYPE           u32
+#define WORD_BYTE_LENGTH    4
+#define WORD_LENGTH         32
+
 /*****************************************************************************
  * Macros
  *****************************************************************************/
 
-/* ?? move to inline functions */
-#define DECODER_FIFO_ISEMPTY( fifo )    ( (fifo).i_start == (fifo).i_end )
-#define DECODER_FIFO_ISFULL( fifo )     ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
+/* FIXME: move to inline functions ??*/
+#define DECODER_FIFO_ISEMPTY( fifo )  ( (fifo).i_start == (fifo).i_end )
+#define DECODER_FIFO_ISFULL( fifo )   ( ( ((fifo).i_end + 1 - (fifo).i_start)\
                                           & FIFO_SIZE ) == 0 )
-#define DECODER_FIFO_START( fifo )      ( (fifo).buffer[ (fifo).i_start ] )
-#define DECODER_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1)\
-                                                           & FIFO_SIZE )
-#define DECODER_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
-#define DECODER_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
+#define DECODER_FIFO_START( fifo )    ( (fifo).buffer[ (fifo).i_start ] )
+#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
                                                          & FIFO_SIZE )
+#define DECODER_FIFO_END( fifo )      ( (fifo).buffer[ (fifo).i_end ] )
+#define DECODER_FIFO_INCEND( fifo )   ( (fifo).i_end = ((fifo).i_end + 1) \
+                                                       & FIFO_SIZE )
 
 /*****************************************************************************
  * decoder_fifo_t
@@ -52,7 +75,7 @@ typedef struct bit_fifo_s
     /* This unsigned integer allows us to work at the bit level. This buffer
      * can contain 32 bits, and the used space can be found on the MSb's side
      * and the available space on the LSb's side. */
-    u32                 buffer;
+    WORD_TYPE           buffer;
 
     /* Number of bits available in the bit buffer */
     int                 i_available;
@@ -80,7 +103,7 @@ typedef struct bit_stream_s
      */
     /* Current TS packet (in the current PES packet of the PES stream) */
     ts_packet_t *       p_ts;
-    /* Pointer to the next byte that is to be read (in the current TS packet) */
+   /* Pointer to the next byte that is to be read (in the current TS packet) */
     byte_t *            p_byte;
     /* Pointer to the last byte that is to be read (in the current TS packet */
     byte_t *            p_end;
@@ -103,8 +126,8 @@ static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
     /* 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 TS packet */
-       decoder_fifo_next( p_bit_stream );
+        /* no, switch to next TS packet */
+        decoder_fifo_next( p_bit_stream );
     }
 
     return( *(p_bit_stream->p_byte++));
@@ -147,7 +170,7 @@ static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
  * DumpBits32 : removes 32 bits from the bit buffer
  *****************************************************************************
  * This function actually believes that you have already put 32 bits in the
- * bit buffer, so you can't you use it anytime.
+ * bit buffer, so you can't use it anytime.
  *****************************************************************************/
 static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
 {
@@ -162,31 +185,98 @@ static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
  * need to call RealignBits() before).
  */
 
+void PeekNextPacket( bit_stream_t * p_bit_stream );
+
+//(stolen from the kernel)
+// XXX: The macro swab32 for little endian machine does
+//      not seem to work correctly
+
+#if defined(SYS_BEOS)
+#       define swab32(x) B_BENDIAN_TO_HOST_INT32(x)
+#else
+#    if __BYTE_ORDER == __BIG_ENDIAN
+#        define swab32(x) (x)
+#    else
+#        if defined (__i386__)
+#           define swab32(x) __i386_swab32(x)
+static inline const u32 __i386_swab32(u32 x)
+{
+    __asm__("bswap %0" : "=r" (x) : "0" (x));
+    return 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
+
+
+static __inline__ WORD_TYPE GetWord( bit_stream_t * p_bit_stream )
+{
+    if( p_bit_stream->p_byte <= p_bit_stream->p_end - WORD_BYTE_LENGTH )
+    {
+        return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
+    }
+    else
+    {
+        PeekNextPacket( p_bit_stream );
+        return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
+    }
+}
+
 /*****************************************************************************
  * RemoveBits : removes i_bits bits from the bit buffer
  *****************************************************************************/
 static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
 {
-    NeedBits( p_bit_stream, i_bits );
-    DumpBits( p_bit_stream, i_bits );
+    p_bit_stream->fifo.i_available -= i_bits;
+
+    if( p_bit_stream->fifo.i_available >= 0 )
+    {
+        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 += WORD_LENGTH;
 }
 
 /*****************************************************************************
- * RemoveBits32 : removes 32 bits from the bit buffer
+ * RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
+ * refill it)
  *****************************************************************************/
 static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
 {
-    NeedBits( p_bit_stream, 32 );
-    DumpBits32( p_bit_stream );
+    p_bit_stream->fifo.buffer = GetWord( p_bit_stream )
+                        << (32 - p_bit_stream->fifo.i_available);
 }
 
 /*****************************************************************************
  * 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 - WORD_BYTE_LENGTH )
+    {
+        return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
+    }
+
+    PeekNextPacket( p_bit_stream );
+    return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
+}
+
 static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
 {
-    NeedBits( p_bit_stream, i_bits );
-    return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
+    if( p_bit_stream->fifo.i_available >= i_bits )
+    {
+        return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
+    }
+
+    return( (p_bit_stream->fifo.buffer |
+            (ShowWord( p_bit_stream ) >> p_bit_stream->fifo.i_available))
+                    >> (32 - i_bits) );
 }
 
 /*****************************************************************************
@@ -194,12 +284,24 @@ static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
  *****************************************************************************/
 static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
 {
-    u32 i_buffer;
+    u32             i_result;
 
-    NeedBits( p_bit_stream, i_bits );
-    i_buffer = p_bit_stream->fifo.buffer >> (32 - i_bits);
-    DumpBits( p_bit_stream, i_bits );
-    return( i_buffer );
+    p_bit_stream->fifo.i_available -= i_bits;
+    if( p_bit_stream->fifo.i_available >= 0 )
+    {
+        i_result = p_bit_stream->fifo.buffer >> (32 - i_bits);
+        p_bit_stream->fifo.buffer <<= i_bits;
+        return( i_result );
+    }
+
+    i_result = p_bit_stream->fifo.buffer >> (32 - i_bits);
+    p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
+    i_result |= p_bit_stream->fifo.buffer
+                             >> (32 + p_bit_stream->fifo.i_available);
+    p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
+    p_bit_stream->fifo.i_available += WORD_LENGTH;
+
+    return( i_result );
 }
 
 /*****************************************************************************
@@ -207,12 +309,15 @@ static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
  *****************************************************************************/
 static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
 {
-    u32 i_buffer;
+    u32             i_result;
 
-    NeedBits( p_bit_stream, 32 );
-    i_buffer = p_bit_stream->fifo.buffer;
-    DumpBits32( p_bit_stream );
-    return( i_buffer );
+    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 <<= (32 - p_bit_stream->fifo.i_available);
+    
+    return( i_result );
 }
 
 /*****************************************************************************
@@ -220,5 +325,7 @@ static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
  *****************************************************************************/
 static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
 {
-    DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
+    p_bit_stream->fifo.buffer <<= (p_bit_stream->fifo.i_available & 0x7);
+    p_bit_stream->fifo.i_available &= ~0x7;
 }
+