]> git.sesse.net Git - vlc/blob - include/decoder_fifo.h
Encore un commit venu tout droit des abysses de l'enfer, d�sol� pour
[vlc] / include / decoder_fifo.h
1 /*****************************************************************************
2  * decoder_fifo.h: interface for decoders PES fifo
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors:
7  *
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.
12  *
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 GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this program; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Required headers:
26  * - "config.h"
27  * - "common.h"
28  * - "threads.h"
29  * - "input.h"
30  *****************************************************************************/
31
32 /*****************************************************************************
33  * Macros
34  *****************************************************************************/
35
36 /* FIXME: move to inline functions ??*/
37 #define DECODER_FIFO_ISEMPTY( fifo )    ( (fifo).i_start == (fifo).i_end )
38 #define DECODER_FIFO_ISFULL( fifo )     ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
39                                           & FIFO_SIZE ) == 0 )
40 #define DECODER_FIFO_START( fifo )      ( (fifo).buffer[ (fifo).i_start ] )
41 #define DECODER_FIFO_INCSTART( fifo )   ( (fifo).i_start = ((fifo).i_start + 1)\
42                                                            & FIFO_SIZE )
43 #define DECODER_FIFO_END( fifo )        ( (fifo).buffer[ (fifo).i_end ] )
44 #define DECODER_FIFO_INCEND( fifo )     ( (fifo).i_end = ((fifo).i_end + 1) \
45                                                          & FIFO_SIZE )
46
47 /*****************************************************************************
48  * decoder_fifo_t
49  *****************************************************************************
50  * This rotative FIFO contains PES packets that are to be decoded...
51  *****************************************************************************/
52 typedef struct
53 {
54     vlc_mutex_t         data_lock;                         /* fifo data lock */
55     vlc_cond_t          data_wait;         /* fifo data conditional variable */
56
57     /* buffer is an array of PES packets pointers */
58     pes_packet_t *      buffer[FIFO_SIZE + 1];
59     int                 i_start;
60     int                 i_end;
61
62 } decoder_fifo_t;
63
64 /*****************************************************************************
65  * bit_fifo_t : bit fifo descriptor
66  *****************************************************************************
67  * This type describes a bit fifo used to store bits while working with the
68  * input stream at the bit level.
69  *****************************************************************************/
70 typedef struct bit_fifo_s
71 {
72     /* This unsigned integer allows us to work at the bit level. This buffer
73      * can contain 32 bits, and the used space can be found on the MSb's side
74      * and the available space on the LSb's side. */
75     u32                 buffer;
76
77     /* Number of bits available in the bit buffer */
78     int                 i_available;
79
80 } bit_fifo_t;
81
82 /*****************************************************************************
83  * bit_stream_t : bit stream descriptor
84  *****************************************************************************
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 typedef struct bit_stream_s
89 {
90     /*
91      * Input structures
92      */
93     /* The input thread feeds the stream with fresh PES packets */
94     input_thread_t *    p_input;
95     /* The decoder fifo contains the data of the PES stream */
96     decoder_fifo_t *    p_decoder_fifo;
97
98     /*
99      * Byte structures
100      */
101     /* Current TS packet (in the current PES packet of the PES stream) */
102     ts_packet_t *       p_ts;
103    /* Pointer to the next byte that is to be read (in the current TS packet) */
104     byte_t *            p_byte;
105     /* Pointer to the last byte that is to be read (in the current TS packet */
106     byte_t *            p_end;
107
108     /*
109      * Bit structures
110      */
111     bit_fifo_t          fifo;
112
113 } bit_stream_t;
114
115
116 void decoder_fifo_next( bit_stream_t * p_bit_stream );
117 /*****************************************************************************
118  * GetByte : reads the next byte in the input stream
119  *****************************************************************************/
120 static __inline__ byte_t GetByte( bit_stream_t * p_bit_stream )
121 {
122     /* Are there some bytes left in the current TS packet ? */
123     /* could change this test to have a if (! (bytes--)) instead */
124     if ( p_bit_stream->p_byte >= p_bit_stream->p_end )
125     {
126         /* no, switch to next TS packet */
127         decoder_fifo_next( p_bit_stream );
128     }
129
130     return( *(p_bit_stream->p_byte++));
131 }
132
133 /*****************************************************************************
134  * NeedBits : reads i_bits new bits in the bit stream and stores them in the
135  *            bit buffer
136  *****************************************************************************
137  * - i_bits must be less or equal 32 !
138  * - There is something important to notice with that function : if the number
139  * of bits available in the bit buffer when calling NeedBits() is greater than
140  * 24 (i_available > 24) but less than the number of needed bits
141  * (i_available < i_bits), the byte returned by GetByte() will be shifted with
142  * a negative value and the number of bits available in the bit buffer will be
143  * set to more than 32 !
144  *****************************************************************************/
145 static __inline__ void NeedBits( bit_stream_t * p_bit_stream, int i_bits )
146 {
147     while ( p_bit_stream->fifo.i_available < i_bits )
148     {
149         p_bit_stream->fifo.buffer |= ((u32)GetByte( p_bit_stream )) << (24 - p_bit_stream->fifo.i_available);
150         p_bit_stream->fifo.i_available += 8;
151     }
152 }
153
154 /*****************************************************************************
155  * DumpBits : removes i_bits bits from the bit buffer
156  *****************************************************************************
157  * - i_bits <= i_available
158  * - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
159  *****************************************************************************/
160 static __inline__ void DumpBits( bit_stream_t * p_bit_stream, int i_bits )
161 {
162     p_bit_stream->fifo.buffer <<= i_bits;
163     p_bit_stream->fifo.i_available -= i_bits;
164 }
165
166 /*****************************************************************************
167  * DumpBits32 : removes 32 bits from the bit buffer
168  *****************************************************************************
169  * This function actually believes that you have already put 32 bits in the
170  * bit buffer, so you can't you use it anytime.
171  *****************************************************************************/
172 static __inline__ void DumpBits32( bit_stream_t * p_bit_stream )
173 {
174     p_bit_stream->fifo.buffer = 0;
175     p_bit_stream->fifo.i_available = 0;
176 }
177
178 /*
179  * For the following functions, please read VERY CAREFULLY the warning in
180  * NeedBits(). If i_bits > 24, the stream parser must be already aligned
181  * on an 8-bit boundary, or you will get curious results (that is, you
182  * need to call RealignBits() before).
183  */
184
185 /*****************************************************************************
186  * RemoveBits : removes i_bits bits from the bit buffer
187  *****************************************************************************/
188 static __inline__ void RemoveBits( bit_stream_t * p_bit_stream, int i_bits )
189 {
190     NeedBits( p_bit_stream, i_bits );
191     DumpBits( p_bit_stream, i_bits );
192 }
193
194 /*****************************************************************************
195  * RemoveBits32 : removes 32 bits from the bit buffer
196  *****************************************************************************/
197 static __inline__ void RemoveBits32( bit_stream_t * p_bit_stream )
198 {
199     NeedBits( p_bit_stream, 32 );
200     DumpBits32( p_bit_stream );
201 }
202
203 /*****************************************************************************
204  * ShowBits : return i_bits bits from the bit stream
205  *****************************************************************************/
206 static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, int i_bits )
207 {
208     NeedBits( p_bit_stream, i_bits );
209     return( p_bit_stream->fifo.buffer >> (32 - i_bits) );
210 }
211
212 /*****************************************************************************
213  * GetBits : returns i_bits bits from the bit stream and removes them
214  *****************************************************************************/
215 static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, int i_bits )
216 {
217     u32 i_buffer;
218
219     NeedBits( p_bit_stream, i_bits );
220     i_buffer = p_bit_stream->fifo.buffer >> (32 - i_bits);
221     DumpBits( p_bit_stream, i_bits );
222     return( i_buffer );
223 }
224
225 /*****************************************************************************
226  * GetBits32 : returns 32 bits from the bit stream and removes them
227  *****************************************************************************/
228 static __inline__ u32 GetBits32( bit_stream_t * p_bit_stream )
229 {
230     u32 i_buffer;
231
232     NeedBits( p_bit_stream, 32 );
233     i_buffer = p_bit_stream->fifo.buffer;
234     DumpBits32( p_bit_stream );
235     return( i_buffer );
236 }
237
238 /*****************************************************************************
239  * RealignBits : realigns the bit buffer on an 8-bit boundary
240  *****************************************************************************/
241 static __inline__ void RealignBits( bit_stream_t * p_bit_stream )
242 {
243     DumpBits( p_bit_stream, p_bit_stream->fifo.i_available & 7 );
244 }