decoder_fifo.h 9.13 KB
Newer Older
1
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
2 3
 * decoder_fifo.h: interface for decoders PES fifo
 * (c)1999 VideoLAN
4
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
5 6 7
 * Required headers:
 * - "config.h"
 * - "common.h"
8
 * - "vlc_thread.h"
Michel Kaempf's avatar
Michel Kaempf committed
9
 * - "input.h"
10
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
11

12
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
13
 * Macros
14
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
15 16 17 18 19 20

/* ?? 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 ] )
21 22
#define DECODER_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1)\
                                                           & FIFO_SIZE )
Michel Kaempf's avatar
Michel Kaempf committed
23 24 25 26
#define DECODER_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
#define DECODER_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
                                                         & FIFO_SIZE )

27
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
28
 * decoder_fifo_t
29
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
30
 * This rotative FIFO contains PES packets that are to be decoded...
31
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
32 33
typedef struct
{
34 35
    vlc_mutex_t         data_lock;                         /* fifo data lock */
    vlc_cond_t          data_wait;         /* fifo data conditional variable */
Michel Kaempf's avatar
Michel Kaempf committed
36 37 38 39 40 41 42

    /* buffer is an array of PES packets pointers */
    pes_packet_t *      buffer[FIFO_SIZE + 1];
    int                 i_start;
    int                 i_end;

} decoder_fifo_t;
43

44
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
45
 * bit_fifo_t : bit fifo descriptor
46
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
47
 * This type describes a bit fifo used to store bits while working with the
48
 * input stream at the bit level.
49
 *****************************************************************************/
50 51 52 53 54 55 56 57 58 59 60 61
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;

62
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
63
 * bit_stream_t : bit stream descriptor
64
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
65
 * This type, based on a PES stream, includes all the structures needed to
66
 * handle the input stream like a bit stream.
67
 *****************************************************************************/
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
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;
83 84 85 86
    /* 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;
87 88 89 90 91 92 93 94 95

    /*
     * Bit structures
     */
    bit_fifo_t          fifo;

} bit_stream_t;


96
void decoder_fifo_next( bit_stream_t * p_bit_stream );
97 98 99 100 101 102
/*****************************************************************************
 * 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 ? */
103 104
    /* could change this test to have a if (! (bytes--)) instead */
    if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
105
    {
106 107
	/* no, switch to next TS packet */
	decoder_fifo_next( p_bit_stream );
108
    }
109

110
    return( *(p_bit_stream->p_byte++));
111 112
}

113
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
114
 * NeedBits : reads i_bits new bits in the bit stream and stores them in the
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
115
 *            bit buffer
116
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
117
 * - i_bits must be less or equal 32 !
118 119 120 121 122 123
 * - 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 !
124
 *****************************************************************************/
125 126 127 128 129 130 131 132 133
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;
    }
}

134
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
135
 * DumpBits : removes i_bits bits from the bit buffer
136
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
137
 * - i_bits <= i_available
138
 * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
139
 *****************************************************************************/
140 141 142 143 144
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;
}
145

146
/*****************************************************************************
147
 * DumpBits32 : removes 32 bits from the bit buffer
148
 *****************************************************************************
149 150
 * This function actually believes that you have already put 32 bits in the
 * bit buffer, so you can't you use it anytime.
151
 *****************************************************************************/
152 153 154 155 156 157 158 159 160 161 162 163 164
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).
 */

165
/*****************************************************************************
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
166
 * RemoveBits : removes i_bits bits from the bit buffer
167
 *****************************************************************************/
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
168 169 170 171 172 173
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 );
}

174
/*****************************************************************************
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
175
 * RemoveBits32 : removes 32 bits from the bit buffer
176
 *****************************************************************************/
Jean-Marc Dressler's avatar
 
Jean-Marc Dressler committed
177 178 179 180 181 182
static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
{
    NeedBits( p_bit_stream, 32 );
    DumpBits32( p_bit_stream );
}

183
/*****************************************************************************
184
 * ShowBits : return i_bits bits from the bit stream
185
 *****************************************************************************/
186 187 188 189 190 191
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) );
}

192
/*****************************************************************************
193
 * GetBits : returns i_bits bits from the bit stream and removes them
194
 *****************************************************************************/
195 196 197 198 199 200 201 202 203 204
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 );
}

205
/*****************************************************************************
206
 * GetBits32 : returns 32 bits from the bit stream and removes them
207
 *****************************************************************************/
208 209 210 211 212 213 214 215 216 217
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 );
}

218
/*****************************************************************************
219
 * RealignBits : realigns the bit buffer on an 8-bit boundary
220
 *****************************************************************************/
221 222 223 224
static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
{
    DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
}