You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
9.1 KiB
224 lines
9.1 KiB
/*****************************************************************************
|
|
* decoder_fifo.h: interface for decoders PES fifo
|
|
* (c)1999 VideoLAN
|
|
*****************************************************************************
|
|
* Required headers:
|
|
* - "config.h"
|
|
* - "common.h"
|
|
* - "vlc_thread.h"
|
|
* - "input.h"
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* Macros
|
|
*****************************************************************************/
|
|
|
|
/* 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) \
|
|
& FIFO_SIZE )
|
|
|
|
/*****************************************************************************
|
|
* decoder_fifo_t
|
|
*****************************************************************************
|
|
* This rotative FIFO contains PES packets that are to be decoded...
|
|
*****************************************************************************/
|
|
typedef struct
|
|
{
|
|
vlc_mutex_t data_lock; /* fifo data lock */
|
|
vlc_cond_t data_wait; /* fifo data conditional variable */
|
|
|
|
/* buffer is an array of PES packets pointers */
|
|
pes_packet_t * buffer[FIFO_SIZE + 1];
|
|
int i_start;
|
|
int i_end;
|
|
|
|
} decoder_fifo_t;
|
|
|
|
/*****************************************************************************
|
|
* bit_fifo_t : bit fifo descriptor
|
|
*****************************************************************************
|
|
* This type describes a bit fifo used to store bits while working with the
|
|
* input stream at the bit level.
|
|
*****************************************************************************/
|
|
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;
|
|
|
|
/* Number of bits available in the bit buffer */
|
|
int i_available;
|
|
|
|
} bit_fifo_t;
|
|
|
|
/*****************************************************************************
|
|
* bit_stream_t : bit stream descriptor
|
|
*****************************************************************************
|
|
* This type, based on a PES stream, includes all the structures needed to
|
|
* handle the input stream like a bit stream.
|
|
*****************************************************************************/
|
|
typedef struct bit_stream_s
|
|
{
|
|
/*
|
|
* Input structures
|
|
*/
|
|
/* The input thread feeds the stream with fresh PES packets */
|
|
input_thread_t * p_input;
|
|
/* The decoder fifo contains the data of the PES stream */
|
|
decoder_fifo_t * p_decoder_fifo;
|
|
|
|
/*
|
|
* Byte structures
|
|
*/
|
|
/* 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) */
|
|
byte_t * p_byte;
|
|
/* Pointer to the last byte that is to be read (in the current TS packet */
|
|
byte_t * p_end;
|
|
|
|
/*
|
|
* Bit structures
|
|
*/
|
|
bit_fifo_t fifo;
|
|
|
|
} bit_stream_t;
|
|
|
|
|
|
void decoder_fifo_next( bit_stream_t * p_bit_stream );
|
|
/*****************************************************************************
|
|
* GetByte : reads the next byte in the input stream
|
|
*****************************************************************************/
|
|
static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
|
|
{
|
|
/* Are there some bytes left in the current TS 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 TS packet */
|
|
decoder_fifo_next( 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 |= ((u32)GetByte( p_bit_stream )) << (24 - 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;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* 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.
|
|
*****************************************************************************/
|
|
static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
|
|
{
|
|
p_bit_stream->fifo.buffer = 0;
|
|
p_bit_stream->fifo.i_available = 0;
|
|
}
|
|
|
|
/*
|
|
* For the following functions, please read VERY CAREFULLY the warning in
|
|
* NeedBits(). If i_bits > 24, the stream parser must be already aligned
|
|
* on an 8-bit boundary, or you will get curious results (that is, you
|
|
* need to call RealignBits() before).
|
|
*/
|
|
|
|
/*****************************************************************************
|
|
* 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 );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* RemoveBits32 : removes 32 bits from the bit buffer
|
|
*****************************************************************************/
|
|
static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
|
|
{
|
|
NeedBits( p_bit_stream, 32 );
|
|
DumpBits32( p_bit_stream );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* ShowBits : return i_bits bits from the bit stream
|
|
*****************************************************************************/
|
|
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) );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GetBits : returns i_bits bits from the bit stream and removes them
|
|
*****************************************************************************/
|
|
static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
|
|
{
|
|
u32 i_buffer;
|
|
|
|
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 );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GetBits32 : returns 32 bits from the bit stream and removes them
|
|
*****************************************************************************/
|
|
static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
|
|
{
|
|
u32 i_buffer;
|
|
|
|
NeedBits( p_bit_stream, 32 );
|
|
i_buffer = p_bit_stream->fifo.buffer;
|
|
DumpBits32( p_bit_stream );
|
|
return( i_buffer );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* RealignBits : realigns the bit buffer on an 8-bit boundary
|
|
*****************************************************************************/
|
|
static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
|
|
{
|
|
DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
|
|
}
|
|
|