]> git.sesse.net Git - vlc/blob - include/input_ext-dec.h
* m4/vlc.m4: output all modules to vlc-config, not just those who define
[vlc] / include / input_ext-dec.h
1 /*****************************************************************************
2  * input_ext-dec.h: structures exported to the VideoLAN decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: input_ext-dec.h,v 1.79 2003/03/04 13:21:19 massiot Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Michel Kaempf <maxx@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #ifndef _VLC_INPUT_EXT_DEC_H
26 #define _VLC_INPUT_EXT_DEC_H 1
27
28 /* Structures exported to the decoders */
29
30 /*****************************************************************************
31  * data_packet_t
32  *****************************************************************************
33  * Describe a data packet.
34  *****************************************************************************/
35 struct data_packet_t
36 {
37     /* Used to chain the packets that carry data for a same PES or PSI */
38     data_packet_t *  p_next;
39
40     /* start of the PS or TS packet */
41     byte_t *         p_demux_start;
42     /* start of the PES payload in this packet */
43     byte_t *         p_payload_start;
44     byte_t *         p_payload_end; /* guess ? :-) */
45     /* is the packet messed up ? */
46     vlc_bool_t       b_discard_payload;
47
48     /* pointer to the real data */
49     data_buffer_t *  p_buffer;
50 };
51
52 /*****************************************************************************
53  * pes_packet_t
54  *****************************************************************************
55  * Describes an PES packet, with its properties, and pointers to the TS packets
56  * containing it.
57  *****************************************************************************/
58 struct pes_packet_t
59 {
60     /* Chained list to the next PES packet (depending on the context) */
61     pes_packet_t *  p_next;
62
63     /* PES properties */
64     vlc_bool_t      b_data_alignment;          /* used to find the beginning of
65                                                 * a video or audio unit */
66     vlc_bool_t      b_discontinuity;          /* This packet doesn't follow the
67                                                * previous one */
68
69     mtime_t         i_pts;            /* PTS for this packet (zero if unset) */
70     mtime_t         i_dts;            /* DTS for this packet (zero if unset) */
71     int             i_rate;   /* current reading pace (see stream_control.h) */
72
73     unsigned int    i_pes_size;            /* size of the current PES packet */
74
75     /* Chained list to packets */
76     data_packet_t * p_first;              /* The first packet contained by this
77                                            * PES (used by decoders). */
78     data_packet_t * p_last;            /* The last packet contained by this
79                                         * PES (used by the buffer allocator) */
80     unsigned int    i_nb_data; /* Number of data packets in the chained list */
81 };
82
83 /*****************************************************************************
84  * decoder_fifo_t
85  *****************************************************************************
86  * This rotative FIFO contains PES packets that are to be decoded.
87  *****************************************************************************/
88 struct decoder_fifo_t
89 {
90     VLC_COMMON_MEMBERS
91
92     /* Thread structures */
93     vlc_mutex_t         data_lock;                         /* fifo data lock */
94     vlc_cond_t          data_wait;         /* fifo data conditional variable */
95
96     /* Data */
97     pes_packet_t *      p_first;
98     pes_packet_t **     pp_last;
99     int                 i_depth;       /* number of PES packets in the stack */
100
101     /* Communication interface between input and decoders */
102     input_buffers_t    *p_packets_mgt;   /* packets management services data */
103
104     /* Standard pointers given to the decoders as a toolbox. */
105     uint16_t            i_id;
106     vlc_fourcc_t        i_fourcc;
107     es_sys_t *          p_demux_data;
108     stream_ctrl_t *     p_stream_ctrl;
109     sout_instance_t *   p_sout;
110     void *              p_waveformatex;
111     void *              p_bitmapinfoheader;
112
113     /* Module properties */
114     module_t *              p_module;
115     int                 ( * pf_run ) ( decoder_fifo_t * );
116 };
117
118 /*****************************************************************************
119  * bit_fifo_t : bit fifo descriptor
120  *****************************************************************************
121  * This type describes a bit fifo used to store bits while working with the
122  * input stream at the bit level.
123  *****************************************************************************/
124 typedef uint32_t    WORD_TYPE;
125
126 typedef struct bit_fifo_t
127 {
128     /* This unsigned integer allows us to work at the bit level. This buffer
129      * can contain 32 bits, and the used space can be found on the MSb's side
130      * and the available space on the LSb's side. */
131     WORD_TYPE           buffer;
132
133     /* Number of bits available in the bit buffer */
134     int                 i_available;
135
136 } bit_fifo_t;
137
138 /*****************************************************************************
139  * bit_stream_t : bit stream descriptor
140  *****************************************************************************
141  * This type, based on a PES stream, includes all the structures needed to
142  * handle the input stream like a bit stream.
143  *****************************************************************************/
144 struct bit_stream_t
145 {
146     /*
147      * Bit structures
148      */
149     bit_fifo_t       fifo;
150
151     /*
152      * Input structures
153      */
154     /* The decoder fifo contains the data of the PES stream */
155     decoder_fifo_t * p_decoder_fifo;
156
157     /* Callback to the decoder used when changing data packets ; set
158      * to NULL if your decoder doesn't need it. */
159     void          (* pf_bitstream_callback)( bit_stream_t *, vlc_bool_t );
160     /* Optional argument to the callback */
161     void *           p_callback_arg;
162
163     /*
164      * PTS retrieval
165      */
166     mtime_t          i_pts, i_dts;
167     byte_t *         p_pts_validity;
168
169     /*
170      * Byte structures
171      */
172     /* Current PES packet (extracted from the PES stream) */
173     pes_packet_t *          p_pes;
174     /* Current data packet (in the current PES packet) */
175     data_packet_t *         p_data;
176     /* Pointer to the next byte that is to be read (in the current packet) */
177     byte_t *                p_byte;
178     /* Pointer to the last byte that is to be read (in the current packet */
179     byte_t *                p_end;
180     /* Temporary buffer in case we're not aligned when changing data packets */
181     WORD_TYPE               i_showbits_buffer;
182     data_packet_t           showbits_data;
183 };
184
185 /*****************************************************************************
186  * Inline functions used by the decoders to read bit_stream_t
187  *****************************************************************************/
188
189 /*
190  * DISCUSSION : How to use the bit_stream structures
191  *
192  * sizeof(WORD_TYPE) (usually 32) bits are read at the same time, thus
193  * minimizing the number of p_byte changes.
194  * Bits are read via GetBits() or ShowBits.
195  *
196  * XXX : Be aware that if, in the forthcoming functions, i_bits > 24,
197  * the data have to be already aligned on an 8-bit boundary, or wrong
198  * results will be returned. Use RealignBits() if unsure.
199  */
200
201 #if (WORD_TYPE == uint32_t)
202 #   define WORD_AT      U32_AT
203 #   define WORD_SIGNED  int32_t
204 #elif (WORD_TYPE == uint64_t)
205 #   define WORD_AT      U64_AT
206 #   define WORD_SIGNED  int64_t
207 #else
208 #   error Unsupported WORD_TYPE
209 #endif
210
211 /*****************************************************************************
212  * Prototypes from input_ext-dec.c
213  *****************************************************************************/
214 VLC_EXPORT( void, input_ExtractPES,        ( decoder_fifo_t *, pes_packet_t ** ) );
215 VLC_EXPORT( void, input_DeletePES,         ( input_buffers_t *, pes_packet_t * ) );
216 VLC_EXPORT( int, InitBitstream, ( bit_stream_t *, decoder_fifo_t *, void ( * )( bit_stream_t *, vlc_bool_t ), void * p_callback_arg ) );
217 VLC_EXPORT( vlc_bool_t, NextDataPacket,    ( decoder_fifo_t *, bit_stream_t * ) );
218 VLC_EXPORT( void, BitstreamNextDataPacket, ( bit_stream_t * ) );
219 VLC_EXPORT( uint32_t, UnalignedShowBits,   ( bit_stream_t *, unsigned int ) );
220 VLC_EXPORT( void, UnalignedRemoveBits,     ( bit_stream_t * ) );
221 VLC_EXPORT( uint32_t, UnalignedGetBits,    ( bit_stream_t *, unsigned int ) );
222 VLC_EXPORT( void, CloseBitstream,          ( bit_stream_t * ) );
223 VLC_EXPORT( void, CurrentPTS,              ( bit_stream_t *, mtime_t *, mtime_t * ) );
224 VLC_EXPORT( void, NextPTS,                 ( bit_stream_t *, mtime_t *, mtime_t * ) );
225
226 /*****************************************************************************
227  * AlignWord : fill in the bit buffer so that the byte pointer be aligned
228  * on a word boundary (XXX: there must be at least sizeof(WORD_TYPE) - 1
229  * empty bytes in the bit buffer)
230  *****************************************************************************/
231 static inline void AlignWord( bit_stream_t * p_bit_stream )
232 {
233     while( (ptrdiff_t)p_bit_stream->p_byte
234              & (sizeof(WORD_TYPE) - 1) )
235     {
236         if( p_bit_stream->p_byte < p_bit_stream->p_end )
237         {
238             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
239                 << (8 * sizeof(WORD_TYPE) - 8
240                      - p_bit_stream->fifo.i_available);
241             p_bit_stream->fifo.i_available += 8;
242         }
243         else
244         {
245             BitstreamNextDataPacket( p_bit_stream );
246             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
247                 << (8 * sizeof(WORD_TYPE) - 8
248                      - p_bit_stream->fifo.i_available);
249             p_bit_stream->fifo.i_available += 8;
250         }
251     }
252 }
253
254 /*****************************************************************************
255  * ShowBits : return i_bits bits from the bit stream
256  *****************************************************************************/
257 static inline uint32_t ShowBits( bit_stream_t * p_bit_stream,
258                                  unsigned int i_bits )
259 {
260     if( (unsigned int)p_bit_stream->fifo.i_available >= i_bits )
261     {
262         return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
263     }
264
265     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
266     {
267         return( (p_bit_stream->fifo.buffer |
268                     (WORD_AT( p_bit_stream->p_byte )
269                         >> p_bit_stream->fifo.i_available))
270                     >> (8 * sizeof(WORD_TYPE) - i_bits) );
271     }
272
273     return( UnalignedShowBits( p_bit_stream, i_bits ) );
274 }
275
276 /*****************************************************************************
277  * ShowSignedBits : return i_bits bits from the bit stream, using signed
278  *                  arithmetic
279  *****************************************************************************/
280 static inline int32_t ShowSignedBits( bit_stream_t * p_bit_stream,
281                                       unsigned int i_bits )
282 {
283     if( (unsigned int)p_bit_stream->fifo.i_available >= i_bits )
284     {
285         return( (WORD_SIGNED)p_bit_stream->fifo.buffer
286                     >> (8 * sizeof(WORD_TYPE) - i_bits) );
287     }
288
289     /* You can probably do something a little faster, but now I'm tired. */
290     return( (WORD_SIGNED)(ShowBits( p_bit_stream, i_bits ) << (32 - i_bits))
291              >> (32 - i_bits) );
292 }
293
294 /*****************************************************************************
295  * RemoveBits : removes i_bits bits from the bit buffer
296  *              XXX: do not use for 32 bits, see RemoveBits32
297  *****************************************************************************/
298 static inline void RemoveBits( bit_stream_t * p_bit_stream,
299                                unsigned int i_bits )
300 {
301     p_bit_stream->fifo.i_available -= i_bits;
302
303     if( p_bit_stream->fifo.i_available >= 0 )
304     {
305         p_bit_stream->fifo.buffer <<= i_bits;
306         return;
307     }
308
309     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
310     {
311         p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
312                                         << ( -p_bit_stream->fifo.i_available );
313         p_bit_stream->p_byte =
314                    (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
315         p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
316         return;
317     }
318
319     UnalignedRemoveBits( p_bit_stream );
320 }
321
322 /*****************************************************************************
323  * RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
324  *                refill it)
325  *****************************************************************************/
326 #if (WORD_TYPE == uint32_t)
327 static inline void RemoveBits32( bit_stream_t * p_bit_stream )
328 {
329     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
330     {
331         if( p_bit_stream->fifo.i_available )
332         {
333             p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
334                             << (32 - p_bit_stream->fifo.i_available);
335             p_bit_stream->p_byte =
336                        (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
337             return;
338         }
339
340         p_bit_stream->p_byte =
341                    (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
342         return;
343     }
344
345     p_bit_stream->fifo.i_available -= 32;
346     UnalignedRemoveBits( p_bit_stream );
347 }
348 #else
349 #   define RemoveBits32( p_bit_stream )     RemoveBits( p_bit_stream, 32 )
350 #endif
351
352 /*****************************************************************************
353  * GetBits : returns i_bits bits from the bit stream and removes them
354  *           XXX: do not use for 32 bits, see GetBits32
355  *****************************************************************************/
356 static inline uint32_t GetBits( bit_stream_t * p_bit_stream,
357                                 unsigned int i_bits )
358 {
359     uint32_t        i_result;
360
361     p_bit_stream->fifo.i_available -= i_bits;
362
363     if( p_bit_stream->fifo.i_available >= 0 )
364     {
365         i_result = p_bit_stream->fifo.buffer
366                         >> (8 * sizeof(WORD_TYPE) - i_bits);
367         p_bit_stream->fifo.buffer <<= i_bits;
368         return( i_result );
369     }
370
371     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
372     {
373         i_result = p_bit_stream->fifo.buffer
374                         >> (8 * sizeof(WORD_TYPE) - i_bits);
375         p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
376         p_bit_stream->p_byte =
377                    (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
378         i_result |= p_bit_stream->fifo.buffer
379                         >> (8 * sizeof(WORD_TYPE)
380                                      + p_bit_stream->fifo.i_available);
381         p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
382         p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
383         return( i_result );
384     }
385
386     return UnalignedGetBits( p_bit_stream, i_bits );
387 }
388
389 /*****************************************************************************
390  * GetSignedBits : returns i_bits bits from the bit stream and removes them,
391  *                 using signed arithmetic
392  *                 XXX: do not use for 32 bits
393  *****************************************************************************/
394 static inline int32_t GetSignedBits( bit_stream_t * p_bit_stream,
395                                      unsigned int i_bits )
396 {
397     if( (unsigned int)p_bit_stream->fifo.i_available >= i_bits )
398     {
399         int32_t         i_result;
400
401         p_bit_stream->fifo.i_available -= i_bits;
402         i_result = (WORD_SIGNED)p_bit_stream->fifo.buffer
403                         >> (8 * sizeof(WORD_TYPE) - i_bits);
404         p_bit_stream->fifo.buffer <<= i_bits;
405         return( i_result );
406     }
407
408     /* You can probably do something a little faster, but now I'm tired. */
409     return( (WORD_SIGNED)(GetBits( p_bit_stream, i_bits ) << (32 - i_bits))
410              >> (32 - i_bits) );
411 }
412
413 /*****************************************************************************
414  * GetBits32 : returns 32 bits from the bit stream and removes them
415  *****************************************************************************/
416 #if (WORD_TYPE == uint32_t)
417 static inline uint32_t GetBits32( bit_stream_t * p_bit_stream )
418 {
419     uint32_t        i_result;
420
421     if( p_bit_stream->fifo.i_available == 32 )
422     {
423         p_bit_stream->fifo.i_available = 0;
424         i_result = p_bit_stream->fifo.buffer;
425         p_bit_stream->fifo.buffer = 0;
426         return( i_result );
427     }
428
429     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
430     {
431         if( p_bit_stream->fifo.i_available )
432         {
433             i_result = p_bit_stream->fifo.buffer;
434             p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
435             p_bit_stream->p_byte =
436                        (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
437             i_result |= p_bit_stream->fifo.buffer
438                              >> (p_bit_stream->fifo.i_available);
439             p_bit_stream->fifo.buffer <<= (32 - p_bit_stream->fifo.i_available);
440             return( i_result );
441         }
442
443         i_result = WORD_AT( p_bit_stream->p_byte );
444         p_bit_stream->p_byte =
445                    (byte_t *) ( ((WORD_TYPE *)p_bit_stream->p_byte) + 1 );
446         return( i_result );
447     }
448
449     p_bit_stream->fifo.i_available -= 32;
450     return UnalignedGetBits( p_bit_stream, 32 );
451 }
452 #else
453 #   define GetBits32( p_bit_stream )    GetBits( p_bit_stream, 32 )
454 #endif
455
456 /*****************************************************************************
457  * RealignBits : realigns the bit buffer on an 8-bit boundary
458  *****************************************************************************/
459 static inline void RealignBits( bit_stream_t * p_bit_stream )
460 {
461     p_bit_stream->fifo.buffer <<= (p_bit_stream->fifo.i_available & 0x7);
462     p_bit_stream->fifo.i_available &= ~0x7;
463 }
464
465
466 /*****************************************************************************
467  * GetChunk : reads a large chunk of data
468  *****************************************************************************
469  * The position in the stream must be byte-aligned, if unsure call
470  * RealignBits(). p_buffer must point to a buffer at least as big as i_buf_len
471  * otherwise your code will crash.
472  *****************************************************************************/
473 static inline void GetChunk( bit_stream_t * p_bit_stream,
474                              byte_t * p_buffer, size_t i_buf_len )
475 {
476     ptrdiff_t           i_available;
477
478     /* We need to take care because i_buf_len may be < 4. */
479     while( p_bit_stream->fifo.i_available > 0 && i_buf_len )
480     {
481         *p_buffer = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - 8);
482         p_buffer++;
483         i_buf_len--;
484         p_bit_stream->fifo.buffer <<= 8;
485         p_bit_stream->fifo.i_available -= 8;
486     }
487
488     i_available = p_bit_stream->p_end - p_bit_stream->p_byte;
489     if( i_available >= (ptrdiff_t)i_buf_len )
490     {
491         p_bit_stream->p_decoder_fifo->p_vlc->pf_memcpy( p_buffer,
492                                            p_bit_stream->p_byte, i_buf_len );
493         p_bit_stream->p_byte += i_buf_len;
494     }
495     else
496     {
497         do
498         {
499             p_bit_stream->p_decoder_fifo->p_vlc->pf_memcpy( p_buffer,
500                                            p_bit_stream->p_byte, i_available );
501             p_bit_stream->p_byte = p_bit_stream->p_end;
502             p_buffer += i_available;
503             i_buf_len -= i_available;
504             BitstreamNextDataPacket( p_bit_stream );
505             if( p_bit_stream->p_decoder_fifo->b_die )
506                 return;
507         }
508         while( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
509                 <= (ptrdiff_t)i_buf_len );
510
511         if( i_buf_len )
512         {
513             p_bit_stream->p_decoder_fifo->p_vlc->pf_memcpy( p_buffer,
514                                            p_bit_stream->p_byte, i_buf_len );
515             p_bit_stream->p_byte += i_buf_len;
516         }
517     }
518
519     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
520     {
521         AlignWord( p_bit_stream );
522     }
523 }
524
525
526 /*
527  * Communication interface between input and decoders
528  */
529
530 /*****************************************************************************
531  * Prototypes from input_dec.c
532  *****************************************************************************/
533 VLC_EXPORT( void, DecoderError, ( decoder_fifo_t * p_fifo ) );
534
535 #endif /* "input_ext-dec.h" */