1 /*****************************************************************************
2 * decoder_fifo.h: interface for decoders PES fifo
4 *****************************************************************************
10 *****************************************************************************/
12 /*****************************************************************************
14 *****************************************************************************/
16 /* ?? move to inline functions */
17 #define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
18 #define DECODER_FIFO_ISFULL( fifo ) ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
20 #define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
21 #define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
23 #define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
24 #define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
27 /*****************************************************************************
29 *****************************************************************************
30 * This rotative FIFO contains PES packets that are to be decoded...
31 *****************************************************************************/
34 vlc_mutex_t data_lock; /* fifo data lock */
35 vlc_cond_t data_wait; /* fifo data conditional variable */
37 /* buffer is an array of PES packets pointers */
38 pes_packet_t * buffer[FIFO_SIZE + 1];
44 /*****************************************************************************
45 * bit_fifo_t : bit fifo descriptor
46 *****************************************************************************
47 * This type describes a bit fifo used to store bits while working with the
48 * input stream at the bit level.
49 *****************************************************************************/
50 typedef struct bit_fifo_s
52 /* This unsigned integer allows us to work at the bit level. This buffer
53 * can contain 32 bits, and the used space can be found on the MSb's side
54 * and the available space on the LSb's side. */
57 /* Number of bits available in the bit buffer */
62 /*****************************************************************************
63 * bit_stream_t : bit stream descriptor
64 *****************************************************************************
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 typedef struct bit_stream_s
73 /* The input thread feeds the stream with fresh PES packets */
74 input_thread_t * p_input;
75 /* The decoder fifo contains the data of the PES stream */
76 decoder_fifo_t * p_decoder_fifo;
81 /* Current TS packet (in the current PES packet of the PES stream) */
83 /* Index of the next byte that is to be read (in the current TS packet) */
94 /*****************************************************************************
95 * GetByte : reads the next byte in the input stream
96 *****************************************************************************/
97 static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
99 /* Are there some bytes left in the current TS packet ? */
100 if ( p_bit_stream->i_byte < p_bit_stream->p_ts->i_payload_end )
102 return( p_bit_stream->p_ts->buffer[ p_bit_stream->i_byte++ ] );
106 /* We are looking for the next TS packet that contains real data,
107 * and not just a PES header */
110 /* We were reading the last TS packet of this PES packet... It's
111 * time to jump to the next PES packet */
112 if ( p_bit_stream->p_ts->p_next_ts == NULL )
114 /* We are going to read/write the start and end indexes of the
115 * decoder fifo and to use the fifo's conditional variable,
116 * that's why we need to take the lock before */
117 vlc_mutex_lock( &p_bit_stream->p_decoder_fifo->data_lock );
119 /* Is the input thread dying ? */
120 if ( p_bit_stream->p_input->b_die )
122 vlc_mutex_unlock( &(p_bit_stream->p_decoder_fifo->data_lock) );
126 /* We should increase the start index of the decoder fifo, but
127 * if we do this now, the input thread could overwrite the
128 * pointer to the current PES packet, and we weren't able to
129 * give it back to the netlist. That's why we free the PES
131 input_NetlistFreePES( p_bit_stream->p_input, DECODER_FIFO_START(*p_bit_stream->p_decoder_fifo) );
132 DECODER_FIFO_INCSTART( *p_bit_stream->p_decoder_fifo );
134 while ( DECODER_FIFO_ISEMPTY(*p_bit_stream->p_decoder_fifo) )
136 vlc_cond_wait( &p_bit_stream->p_decoder_fifo->data_wait, &p_bit_stream->p_decoder_fifo->data_lock );
137 if ( p_bit_stream->p_input->b_die )
139 vlc_mutex_unlock( &(p_bit_stream->p_decoder_fifo->data_lock) );
144 /* The next byte could be found in the next PES packet */
145 p_bit_stream->p_ts = DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->p_first_ts;
147 /* We can release the fifo's data lock */
148 vlc_mutex_unlock( &p_bit_stream->p_decoder_fifo->data_lock );
150 /* Perhaps the next TS packet of the current PES packet contains
151 * real data (ie its payload's size is greater than 0) */
154 p_bit_stream->p_ts = p_bit_stream->p_ts->p_next_ts;
156 } while ( p_bit_stream->p_ts->i_payload_start == p_bit_stream->p_ts->i_payload_end );
158 /* We've found a TS packet which contains interesting data... As we
159 * return the payload's first byte, we set i_byte to the following
161 p_bit_stream->i_byte = p_bit_stream->p_ts->i_payload_start;
162 return( p_bit_stream->p_ts->buffer[ p_bit_stream->i_byte++ ] );
166 /*****************************************************************************
167 * NeedBits : reads i_bits new bits in the bit stream and stores them in the
169 *****************************************************************************
170 * - i_bits must be less or equal 32 !
171 * - There is something important to notice with that function : if the number
172 * of bits available in the bit buffer when calling NeedBits() is greater than
173 * 24 (i_available > 24) but less than the number of needed bits
174 * (i_available < i_bits), the byte returned by GetByte() will be shifted with
175 * a negative value and the number of bits available in the bit buffer will be
176 * set to more than 32 !
177 *****************************************************************************/
178 static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
180 while ( p_bit_stream->fifo.i_available < i_bits )
182 p_bit_stream->fifo.buffer |= ((u32)GetByte( p_bit_stream )) << (24 - p_bit_stream->fifo.i_available);
183 p_bit_stream->fifo.i_available += 8;
187 /*****************************************************************************
188 * DumpBits : removes i_bits bits from the bit buffer
189 *****************************************************************************
190 * - i_bits <= i_available
191 * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
192 *****************************************************************************/
193 static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
195 p_bit_stream->fifo.buffer <<= i_bits;
196 p_bit_stream->fifo.i_available -= i_bits;
199 /*****************************************************************************
200 * DumpBits32 : removes 32 bits from the bit buffer
201 *****************************************************************************
202 * This function actually believes that you have already put 32 bits in the
203 * bit buffer, so you can't you use it anytime.
204 *****************************************************************************/
205 static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
207 p_bit_stream->fifo.buffer = 0;
208 p_bit_stream->fifo.i_available = 0;
212 * For the following functions, please read VERY CAREFULLY the warning in
213 * NeedBits(). If i_bits > 24, the stream parser must be already aligned
214 * on an 8-bit boundary, or you will get curious results (that is, you
215 * need to call RealignBits() before).
218 /*****************************************************************************
219 * RemoveBits : removes i_bits bits from the bit buffer
220 *****************************************************************************/
221 static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
223 NeedBits( p_bit_stream, i_bits );
224 DumpBits( p_bit_stream, i_bits );
227 /*****************************************************************************
228 * RemoveBits32 : removes 32 bits from the bit buffer
229 *****************************************************************************/
230 static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
232 NeedBits( p_bit_stream, 32 );
233 DumpBits32( p_bit_stream );
236 /*****************************************************************************
237 * ShowBits : return i_bits bits from the bit stream
238 *****************************************************************************/
239 static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
241 NeedBits( p_bit_stream, i_bits );
242 return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
245 /*****************************************************************************
246 * GetBits : returns i_bits bits from the bit stream and removes them
247 *****************************************************************************/
248 static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
252 NeedBits( p_bit_stream, i_bits );
253 i_buffer = p_bit_stream->fifo.buffer >> (32 - i_bits);
254 DumpBits( p_bit_stream, i_bits );
258 /*****************************************************************************
259 * GetBits32 : returns 32 bits from the bit stream and removes them
260 *****************************************************************************/
261 static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
265 NeedBits( p_bit_stream, 32 );
266 i_buffer = p_bit_stream->fifo.buffer;
267 DumpBits32( p_bit_stream );
271 /*****************************************************************************
272 * RealignBits : realigns the bit buffer on an 8-bit boundary
273 *****************************************************************************/
274 static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
276 DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );