1 /*****************************************************************************
2 * decoder_fifo.h: interface for decoders PES fifo
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
29 *****************************************************************************/
32 #define WORD_BYTE_LENGTH 4
33 #define WORD_LENGTH 32
35 /*****************************************************************************
37 *****************************************************************************/
39 /* FIXME: move to inline functions ??*/
40 #define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
41 #define DECODER_FIFO_ISFULL( fifo ) ( ( ((fifo).i_end + 1 - (fifo).i_start)\
43 #define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
44 #define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
46 #define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
47 #define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
50 /*****************************************************************************
52 *****************************************************************************
53 * This rotative FIFO contains PES packets that are to be decoded...
54 *****************************************************************************/
57 vlc_mutex_t data_lock; /* fifo data lock */
58 vlc_cond_t data_wait; /* fifo data conditional variable */
60 /* buffer is an array of PES packets pointers */
61 pes_packet_t * buffer[FIFO_SIZE + 1];
67 /*****************************************************************************
68 * bit_fifo_t : bit fifo descriptor
69 *****************************************************************************
70 * This type describes a bit fifo used to store bits while working with the
71 * input stream at the bit level.
72 *****************************************************************************/
73 typedef struct bit_fifo_s
75 /* This unsigned integer allows us to work at the bit level. This buffer
76 * can contain 32 bits, and the used space can be found on the MSb's side
77 * and the available space on the LSb's side. */
80 /* Number of bits available in the bit buffer */
85 /*****************************************************************************
86 * bit_stream_t : bit stream descriptor
87 *****************************************************************************
88 * This type, based on a PES stream, includes all the structures needed to
89 * handle the input stream like a bit stream.
90 *****************************************************************************/
91 typedef struct bit_stream_s
96 /* The input thread feeds the stream with fresh PES packets */
97 input_thread_t * p_input;
98 /* The decoder fifo contains the data of the PES stream */
99 decoder_fifo_t * p_decoder_fifo;
104 /* Current TS packet (in the current PES packet of the PES stream) */
106 /* Pointer to the next byte that is to be read (in the current TS packet) */
108 /* Pointer to the last byte that is to be read (in the current TS packet */
119 void decoder_fifo_next( bit_stream_t * p_bit_stream );
120 /*****************************************************************************
121 * GetByte : reads the next byte in the input stream
122 *****************************************************************************/
123 static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
125 /* Are there some bytes left in the current TS packet ? */
126 /* could change this test to have a if (! (bytes--)) instead */
127 if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
129 /* no, switch to next TS packet */
130 decoder_fifo_next( p_bit_stream );
133 return( *(p_bit_stream->p_byte++));
136 /*****************************************************************************
137 * NeedBits : reads i_bits new bits in the bit stream and stores them in the
139 *****************************************************************************
140 * - i_bits must be less or equal 32 !
141 * - There is something important to notice with that function : if the number
142 * of bits available in the bit buffer when calling NeedBits() is greater than
143 * 24 (i_available > 24) but less than the number of needed bits
144 * (i_available < i_bits), the byte returned by GetByte() will be shifted with
145 * a negative value and the number of bits available in the bit buffer will be
146 * set to more than 32 !
147 *****************************************************************************/
148 static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
150 while ( p_bit_stream->fifo.i_available < i_bits )
152 p_bit_stream->fifo.buffer |= ((u32)GetByte( p_bit_stream )) << (24 - p_bit_stream->fifo.i_available);
153 p_bit_stream->fifo.i_available += 8;
157 /*****************************************************************************
158 * DumpBits : removes i_bits bits from the bit buffer
159 *****************************************************************************
160 * - i_bits <= i_available
161 * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
162 *****************************************************************************/
163 static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
165 p_bit_stream->fifo.buffer <<= i_bits;
166 p_bit_stream->fifo.i_available -= i_bits;
169 /*****************************************************************************
170 * DumpBits32 : removes 32 bits from the bit buffer
171 *****************************************************************************
172 * This function actually believes that you have already put 32 bits in the
173 * bit buffer, so you can't use it anytime.
174 *****************************************************************************/
175 static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
177 p_bit_stream->fifo.buffer = 0;
178 p_bit_stream->fifo.i_available = 0;
182 * For the following functions, please read VERY CAREFULLY the warning in
183 * NeedBits(). If i_bits > 24, the stream parser must be already aligned
184 * on an 8-bit boundary, or you will get curious results (that is, you
185 * need to call RealignBits() before).
188 void PeekNextPacket( bit_stream_t * p_bit_stream );
190 //(stolen from the kernel)
191 // XXX: The macro swab32 for little endian machine does
192 // not seem to work correctly
194 #if defined(SYS_BEOS)
195 # define swab32(x) B_BENDIAN_TO_HOST_INT32(x)
197 # if __BYTE_ORDER == __BIG_ENDIAN
198 # define swab32(x) (x)
200 # if defined (__i386__)
201 # define swab32(x) __i386_swab32(x)
202 static inline const u32 __i386_swab32(u32 x)
204 __asm__("bswap %0" : "=r" (x) : "0" (x));
209 ( ( (u32)(((u8*)&x)[0]) << 24 ) | ( (u32)(((u8*)&x)[1]) << 16 ) | \
210 ( (u32)(((u8*)&x)[2]) << 8 ) | ( (u32)(((u8*)&x)[3])) )
216 static __inline__ WORD_TYPE GetWord( bit_stream_t * p_bit_stream )
218 if( p_bit_stream->p_byte <= p_bit_stream->p_end - WORD_BYTE_LENGTH )
220 return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
224 PeekNextPacket( p_bit_stream );
225 return( swab32( *(((WORD_TYPE *)p_bit_stream->p_byte)++) ) );
229 /*****************************************************************************
230 * RemoveBits : removes i_bits bits from the bit buffer
231 *****************************************************************************/
232 static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
234 p_bit_stream->fifo.i_available -= i_bits;
236 if( p_bit_stream->fifo.i_available >= 0 )
238 p_bit_stream->fifo.buffer <<= i_bits;
241 p_bit_stream->fifo.buffer = GetWord( p_bit_stream )
242 << ( -p_bit_stream->fifo.i_available );
243 p_bit_stream->fifo.i_available += WORD_LENGTH;
246 /*****************************************************************************
247 * RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
249 *****************************************************************************/
250 static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
252 p_bit_stream->fifo.buffer = GetWord( p_bit_stream )
253 << (32 - p_bit_stream->fifo.i_available);
256 /*****************************************************************************
257 * ShowBits : return i_bits bits from the bit stream
258 *****************************************************************************/
259 static __inline__ WORD_TYPE ShowWord( bit_stream_t * p_bit_stream )
261 if( p_bit_stream->p_byte <= p_bit_stream->p_end - WORD_BYTE_LENGTH )
263 return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
266 PeekNextPacket( p_bit_stream );
267 return( swab32( *((WORD_TYPE *)p_bit_stream->p_byte) ) );
270 static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
272 if( p_bit_stream->fifo.i_available >= i_bits )
274 return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
277 return( (p_bit_stream->fifo.buffer |
278 (ShowWord( p_bit_stream ) >> p_bit_stream->fifo.i_available))
282 /*****************************************************************************
283 * GetBits : returns i_bits bits from the bit stream and removes them
284 *****************************************************************************/
285 static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
289 p_bit_stream->fifo.i_available -= i_bits;
290 if( p_bit_stream->fifo.i_available >= 0 )
292 i_result = p_bit_stream->fifo.buffer >> (32 - i_bits);
293 p_bit_stream->fifo.buffer <<= i_bits;
297 i_result = p_bit_stream->fifo.buffer >> (32 - i_bits);
298 p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
299 i_result |= p_bit_stream->fifo.buffer
300 >> (32 + p_bit_stream->fifo.i_available);
301 p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
302 p_bit_stream->fifo.i_available += WORD_LENGTH;
307 /*****************************************************************************
308 * GetBits32 : returns 32 bits from the bit stream and removes them
309 *****************************************************************************/
310 static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
314 i_result = p_bit_stream->fifo.buffer;
315 p_bit_stream->fifo.buffer = GetWord( p_bit_stream );
316 i_result |= p_bit_stream->fifo.buffer
317 >> (p_bit_stream->fifo.i_available);
318 p_bit_stream->fifo.buffer <<= (32 - p_bit_stream->fifo.i_available);
323 /*****************************************************************************
324 * RealignBits : realigns the bit buffer on an 8-bit boundary
325 *****************************************************************************/
326 static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
328 p_bit_stream->fifo.buffer <<= (p_bit_stream->fifo.i_available & 0x7);
329 p_bit_stream->fifo.i_available &= ~0x7;