decoder_fifo.h 10 KB
Newer Older
1
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
2
 * decoder_fifo.h: interface for decoders PES fifo
3
 *****************************************************************************
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * 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-1307, USA.
 *****************************************************************************/

/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
25 26 27
 * Required headers:
 * - "config.h"
 * - "common.h"
28
 * - "threads.h"
Michel Kaempf's avatar
Michel Kaempf committed
29
 * - "input.h"
30
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
31

32
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
33
 * Macros
34
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
35

36
/* FIXME: move to inline functions ??*/
Michel Kaempf's avatar
Michel Kaempf committed
37 38 39 40
#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 ] )
41 42
#define DECODER_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1)\
                                                           & FIFO_SIZE )
Michel Kaempf's avatar
Michel Kaempf committed
43 44 45 46
#define DECODER_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
#define DECODER_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
                                                         & FIFO_SIZE )

47
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
48
 * decoder_fifo_t
49
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
50
 * This rotative FIFO contains PES packets that are to be decoded...
51
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
52 53
typedef struct
{
54 55
    vlc_mutex_t         data_lock;                         /* fifo data lock */
    vlc_cond_t          data_wait;         /* fifo data conditional variable */
Michel Kaempf's avatar
Michel Kaempf committed
56 57 58 59 60 61 62

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

} decoder_fifo_t;
63

64
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
65
 * bit_fifo_t : bit fifo descriptor
66
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
67
 * This type describes a bit fifo used to store bits while working with the
68
 * input stream at the bit level.
69
 *****************************************************************************/
70 71 72 73 74 75 76 77 78 79 80 81
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;

82
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
83
 * bit_stream_t : bit stream descriptor
84
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
85
 * This type, based on a PES stream, includes all the structures needed to
86
 * handle the input stream like a bit stream.
87
 *****************************************************************************/
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
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;
103
   /* Pointer to the next byte that is to be read (in the current TS packet) */
104 105 106
    byte_t *            p_byte;
    /* Pointer to the last byte that is to be read (in the current TS packet */
    byte_t *            p_end;
107 108 109 110 111 112 113 114 115

    /*
     * Bit structures
     */
    bit_fifo_t          fifo;

} bit_stream_t;


116
void decoder_fifo_next( bit_stream_t * p_bit_stream );
117 118 119 120 121 122
/*****************************************************************************
 * 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 ? */
123 124
    /* could change this test to have a if (! (bytes--)) instead */
    if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
125
    {
126 127
        /* no, switch to next TS packet */
        decoder_fifo_next( p_bit_stream );
128
    }
129

130
    return( *(p_bit_stream->p_byte++));
131 132
}

133
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
134
 * NeedBits : reads i_bits new bits in the bit stream and stores them in the
135
 *            bit buffer
136
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
137
 * - i_bits must be less or equal 32 !
138 139 140 141 142 143
 * - 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 !
144
 *****************************************************************************/
145 146 147 148 149 150 151 152 153
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;
    }
}

154
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
155
 * DumpBits : removes i_bits bits from the bit buffer
156
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
157
 * - i_bits <= i_available
158
 * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
159
 *****************************************************************************/
160 161 162 163 164
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;
}
165

166
/*****************************************************************************
167
 * DumpBits32 : removes 32 bits from the bit buffer
168
 *****************************************************************************
169 170
 * This function actually believes that you have already put 32 bits in the
 * bit buffer, so you can't you use it anytime.
171
 *****************************************************************************/
172 173 174 175 176 177 178 179 180 181 182 183 184
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).
 */

185
/*****************************************************************************
186
 * RemoveBits : removes i_bits bits from the bit buffer
187
 *****************************************************************************/
188 189 190 191 192 193
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 );
}

194
/*****************************************************************************
195
 * RemoveBits32 : removes 32 bits from the bit buffer
196
 *****************************************************************************/
197 198 199 200 201 202
static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
{
    NeedBits( p_bit_stream, 32 );
    DumpBits32( p_bit_stream );
}

203
/*****************************************************************************
204
 * ShowBits : return i_bits bits from the bit stream
205
 *****************************************************************************/
206 207 208 209 210 211
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) );
}

212
/*****************************************************************************
213
 * GetBits : returns i_bits bits from the bit stream and removes them
214
 *****************************************************************************/
215 216 217 218 219 220 221 222 223 224
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 );
}

225
/*****************************************************************************
226
 * GetBits32 : returns 32 bits from the bit stream and removes them
227
 *****************************************************************************/
228 229 230 231 232 233 234 235 236 237
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 );
}

238
/*****************************************************************************
239
 * RealignBits : realigns the bit buffer on an 8-bit boundary
240
 *****************************************************************************/
241 242 243 244
static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
{
    DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
}