mirror of
https://github.com/videolan/vlc.git
synced 2024-12-04 07:15:24 +08:00
* 32-bit aligned bitstream (not that fast).
This commit is contained in:
parent
647cca0ebb
commit
18188c2497
@ -3,7 +3,7 @@
|
|||||||
* Collection of useful common types and macros definitions
|
* Collection of useful common types and macros definitions
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
* 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>
|
* Authors: Samuel Hocevar <sam@via.ecp.fr>
|
||||||
* Vincent Seguin <seguin@via.ecp.fr>
|
* Vincent Seguin <seguin@via.ecp.fr>
|
||||||
@ -155,31 +155,6 @@ struct macroblock_s;
|
|||||||
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
|
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
|
||||||
#endif
|
#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 (big endian)/LSB (little endian) conversions - network order is always
|
||||||
* MSB, and should be used for both network communications and files. Note that
|
* 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
|
* 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
|
#endif
|
||||||
|
|
||||||
/* Macros with automatic casts */
|
/* Macros with automatic casts */
|
||||||
#define U32_AT(p) ( swab32 ( *( (u32 *)(p) ) ) )
|
#define U64_AT(p) ( ntoh64 ( *( (u64 *)(p) ) ) )
|
||||||
#define U16_AT(p) ( ntohs ( *( (u16 *)(p) ) ) )
|
#define U32_AT(p) ( ntoh32 ( *( (u32 *)(p) ) ) )
|
||||||
|
#define U16_AT(p) ( ntoh16 ( *( (u16 *)(p) ) ) )
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* input_ext-dec.h: structures exported to the VideoLAN decoders
|
* input_ext-dec.h: structures exported to the VideoLAN decoders
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1999, 2000 VideoLAN
|
* 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:
|
* Authors:
|
||||||
*
|
*
|
||||||
@ -113,7 +113,7 @@ typedef struct decoder_fifo_s
|
|||||||
* This type describes a bit fifo used to store bits while working with the
|
* This type describes a bit fifo used to store bits while working with the
|
||||||
* input stream at the bit level.
|
* 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
|
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
|
* DISCUSSION : How to use the bit_stream structures
|
||||||
* NeedBits, then the buffer can be read via p_bit_stream->fifo.buffer, and
|
*
|
||||||
* unnecessary bits are dumped with a DumpBits() call.
|
* 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)
|
||||||
* GetByte : reads the next byte in the input stream (PRIVATE)
|
# define WORD_AT U32_AT
|
||||||
*****************************************************************************/
|
#elif (WORD_TYPE == u64)
|
||||||
static __inline__ byte_t _GetByte( bit_stream_t * p_bit_stream )
|
# define WORD_AT U64_AT
|
||||||
{
|
#else
|
||||||
/* Are there some bytes left in the current data packet ? */
|
# error Unsupported WORD_TYPE
|
||||||
/* 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++) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* 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 !
|
|
||||||
*****************************************************************************/
|
|
||||||
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 ))
|
|
||||||
<< (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
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Protoypes from input_ext-dec.c
|
||||||
|
*****************************************************************************/
|
||||||
|
u32 UnalignedShowBits( struct bit_stream_s *, unsigned int );
|
||||||
|
void UnalignedRemoveBits( struct bit_stream_s * );
|
||||||
|
u32 UnalignedGetBits( struct bit_stream_s *, unsigned int );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* 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 AlignWord( bit_stream_t * p_bit_stream )
|
||||||
|
{
|
||||||
|
while( (p_bit_stream->p_byte - p_bit_stream->p_data->p_buffer)
|
||||||
|
& (sizeof(WORD_TYPE) - 1) )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ShowBits : return i_bits bits from the bit stream
|
* ShowBits : return i_bits bits from the bit stream
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline__ WORD_TYPE _ShowWord( bit_stream_t * p_bit_stream )
|
static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream,
|
||||||
{
|
unsigned int i_bits )
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
if( p_bit_stream->fifo.i_available >= 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 >> (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) )
|
if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
|
||||||
{
|
{
|
||||||
return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
|
return( (p_bit_stream->fifo.buffer |
|
||||||
}
|
(WORD_AT( p_bit_stream->p_byte )
|
||||||
else
|
>> p_bit_stream->fifo.i_available))
|
||||||
{
|
>> (8 * sizeof(WORD_TYPE) - i_bits) );
|
||||||
p_bit_stream->pf_next_data_packet( p_bit_stream );
|
|
||||||
return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return UnalignedShowBits( p_bit_stream, i_bits );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* RemoveBits : removes i_bits bits from the bit buffer
|
* RemoveBits : removes i_bits bits from the bit buffer
|
||||||
* XXX: do not use for 32 bits, see RemoveBits32
|
* 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;
|
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;
|
p_bit_stream->fifo.buffer <<= i_bits;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream )
|
|
||||||
<< ( -p_bit_stream->fifo.i_available );
|
if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
|
||||||
p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
|
{
|
||||||
|
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,
|
* RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
|
||||||
* refill it)
|
* refill it)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
#if (WORD_TYPE == u32)
|
||||||
static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
|
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);
|
<< (32 - p_bit_stream->fifo.i_available);
|
||||||
|
((WORD_TYPE *)p_bit_stream->p_byte)++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
((WORD_TYPE *)p_bit_stream->p_byte)++;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
p_bit_stream->fifo.i_available -= 32;
|
||||||
_GetWord( p_bit_stream );
|
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
|
* GetBits : returns i_bits bits from the bit stream and removes them
|
||||||
* XXX: do not use for 32 bits, see GetBits32
|
* 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;
|
u32 i_result;
|
||||||
|
|
||||||
p_bit_stream->fifo.i_available -= i_bits;
|
if( p_bit_stream->fifo.i_available >= i_bits )
|
||||||
if( p_bit_stream->fifo.i_available >= 0 )
|
|
||||||
{
|
{
|
||||||
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;
|
p_bit_stream->fifo.buffer <<= i_bits;
|
||||||
return( i_result );
|
return( i_result );
|
||||||
}
|
}
|
||||||
|
|
||||||
i_result = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits);
|
if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
|
||||||
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
|
{
|
||||||
i_result |= p_bit_stream->fifo.buffer
|
p_bit_stream->fifo.i_available -= i_bits;
|
||||||
>> (8 * sizeof(WORD_TYPE)
|
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.i_available);
|
||||||
p_bit_stream->fifo.buffer <<= ( -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.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
|
* 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;
|
i_result = p_bit_stream->fifo.buffer;
|
||||||
p_bit_stream->fifo.buffer = _GetWord( p_bit_stream );
|
p_bit_stream->fifo.buffer = 0;
|
||||||
|
|
||||||
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);
|
|
||||||
return( i_result );
|
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
|
* 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
|
* 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;
|
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)
|
if( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
|
||||||
>= i_buf_len )
|
>= 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;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* input.h: structures of the input not exported to other modules
|
* input.h: structures of the input not exported to other modules
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1999, 2000 VideoLAN
|
* 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:
|
* Authors:
|
||||||
*
|
*
|
||||||
@ -118,10 +118,6 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
|
|||||||
return;
|
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 );
|
memset( p_pad_data->p_buffer, 0, PADDING_PACKET_SIZE );
|
||||||
p_pad_data->b_discard_payload = 1;
|
p_pad_data->b_discard_payload = 1;
|
||||||
p_pes = p_es->p_pes;
|
p_pes = p_es->p_pes;
|
||||||
|
@ -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 )
|
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;
|
decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
|
||||||
boolean_t b_new_pes;
|
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,
|
/* We are looking for the next data packet that contains real data,
|
||||||
* and not just a PES header */
|
* and not just a PES header */
|
||||||
do
|
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 );
|
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 */
|
/* Copy remaining bits of the previous packet */
|
||||||
*((WORD_TYPE *)p_bit_stream->p_byte - 1) = buffer_left;
|
*((WORD_TYPE *)p_bit_stream->p_byte - 1) = buffer_left;
|
||||||
p_bit_stream->p_byte -= i_bytes_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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* vpar_synchro.c : frame dropping routines
|
* vpar_synchro.c : frame dropping routines
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1999, 2000 VideoLAN
|
* 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>
|
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||||
* Samuel Hocevar <sam@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)
|
+ tau_yuv)
|
||||||
#define S p_vpar->synchro
|
#define S p_vpar->synchro
|
||||||
/* VPAR_SYNCHRO_DEFAULT */
|
/* 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;
|
boolean_t b_decode = 0;
|
||||||
#ifdef DEBUG_VPAR
|
#ifdef DEBUG_VPAR
|
||||||
char p_date[MSTRTIME_MAX_SIZE];
|
char p_date[MSTRTIME_MAX_SIZE];
|
||||||
|
Loading…
Reference in New Issue
Block a user