]> git.sesse.net Git - vlc/blob - include/input_ext-dec.h
Backported support for VLS CVS with regards to A/52 streams. Also
[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.59.2.1 2002/09/25 23:11:51 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 /* ES streams types - see ISO/IEC 13818-1 table 2-29 numbers */
26 #define MPEG1_VIDEO_ES      0x01
27 #define MPEG2_VIDEO_ES      0x02
28 #define MPEG1_AUDIO_ES      0x03
29 #define MPEG2_AUDIO_ES      0x04
30 #define AC3_AUDIO_ES        0x81
31 /* These ones might violate the usage : */
32 #define DVD_SPU_ES          0x82
33 #define LPCM_AUDIO_ES       0x83
34 /* These ones are only here to work around a bug in VLS - VLS doesn't
35  * skip the first bytes of the PES payload (stream private ID) when
36  * streaming. This is incompatible with all equipments. 'B' is for
37  * buggy. Please note that they are associated with FOURCCs '***b'.
38  * --Meuuh 2002-08-30
39  */
40 #define A52B_AUDIO_ES       0x91
41 #define DVDB_SPU_ES         0x92
42 #define LPCMB_AUDIO_ES      0x93
43
44 #define MSMPEG4v1_VIDEO_ES  0x40
45 #define MSMPEG4v2_VIDEO_ES  0x41
46 #define MSMPEG4v3_VIDEO_ES  0x42
47 #define MPEG4_VIDEO_ES      0x50
48
49 #define UNKNOWN_ES          0xFF
50
51 /* Structures exported to the decoders */
52
53 /*****************************************************************************
54  * data_packet_t
55  *****************************************************************************
56  * Describe a data packet.
57  *****************************************************************************/
58 typedef struct data_packet_s
59 {
60     /* Used to chain the packets that carry data for a same PES or PSI */
61     struct data_packet_s *  p_next;
62
63     /* start of the PS or TS packet */
64     byte_t *                p_demux_start;
65     /* start of the PES payload in this packet */
66     byte_t *                p_payload_start;
67     byte_t *                p_payload_end; /* guess ? :-) */
68     /* is the packet messed up ? */
69     boolean_t               b_discard_payload;
70
71     /* pointer to the real data */
72     struct data_buffer_s *  p_buffer;
73 } data_packet_t;
74
75 /*****************************************************************************
76  * pes_packet_t
77  *****************************************************************************
78  * Describes an PES packet, with its properties, and pointers to the TS packets
79  * containing it.
80  *****************************************************************************/
81 typedef struct pes_packet_s
82 {
83     /* Chained list to the next PES packet (depending on the context) */
84     struct pes_packet_s *   p_next;
85
86     /* PES properties */
87     boolean_t               b_data_alignment;  /* used to find the beginning of
88                                                 * a video or audio unit      */
89     boolean_t               b_discontinuity; /* This packet doesn't follow the
90                                               * previous one                 */
91
92     mtime_t                 i_pts;    /* PTS for this packet (zero if unset) */
93     mtime_t                 i_dts;    /* DTS for this packet (zero if unset) */
94     int                     i_rate;                /* current pace of reading
95                                                     * (see stream_control.h) */
96
97     unsigned int            i_pes_size;    /* size of the current PES packet */
98
99     /* Chained list to packets */
100     data_packet_t *         p_first;      /* The first packet contained by this
101                                            * PES (used by decoders). */
102     data_packet_t *         p_last;    /* The last packet contained by this
103                                           PES (used by the buffer allocator) */
104     unsigned int            i_nb_data; /* Number of data packets in the chained
105                                                                         list */
106 } pes_packet_t;
107
108 /*****************************************************************************
109  * decoder_fifo_t
110  *****************************************************************************
111  * This rotative FIFO contains PES packets that are to be decoded.
112  *****************************************************************************/
113 typedef struct decoder_fifo_s
114 {
115     /* Thread structures */
116     vlc_mutex_t             data_lock;                     /* fifo data lock */
117     vlc_cond_t              data_wait;     /* fifo data conditional variable */
118
119     /* Data */
120     pes_packet_t *          p_first;
121     pes_packet_t **         pp_last;
122     int                     i_depth;   /* number of PES packets in the stack */
123
124     /* Communication interface between input and decoders */
125     boolean_t               b_die;          /* the decoder should return now */
126     boolean_t               b_error;      /* the decoder is in an error loop */
127     struct input_buffers_s *p_packets_mgt;   /* packets management services
128                                               * data */
129 } decoder_fifo_t;
130
131 /*****************************************************************************
132  * bit_fifo_t : bit fifo descriptor
133  *****************************************************************************
134  * This type describes a bit fifo used to store bits while working with the
135  * input stream at the bit level.
136  *****************************************************************************/
137 typedef u32         WORD_TYPE;
138
139 typedef struct bit_fifo_s
140 {
141     /* This unsigned integer allows us to work at the bit level. This buffer
142      * can contain 32 bits, and the used space can be found on the MSb's side
143      * and the available space on the LSb's side. */
144     WORD_TYPE           buffer;
145
146     /* Number of bits available in the bit buffer */
147     int                 i_available;
148
149 } bit_fifo_t;
150
151 /*****************************************************************************
152  * bit_stream_t : bit stream descriptor
153  *****************************************************************************
154  * This type, based on a PES stream, includes all the structures needed to
155  * handle the input stream like a bit stream.
156  *****************************************************************************/
157 typedef struct bit_stream_s
158 {
159     /*
160      * Bit structures
161      */
162     bit_fifo_t              fifo;
163
164     /*
165      * Input structures
166      */
167     /* The decoder fifo contains the data of the PES stream */
168     decoder_fifo_t *        p_decoder_fifo;
169
170     /* Callback to the decoder used when changing data packets ; set
171      * to NULL if your decoder doesn't need it. */
172     void                 (* pf_bitstream_callback)( struct bit_stream_s *,
173                                                     boolean_t b_new_pes );
174     /* Optional argument to the callback */
175     void *                  p_callback_arg;
176
177     /*
178      * PTS retrieval
179      */
180     mtime_t                 i_pts, i_dts;
181     byte_t *                p_pts_validity;
182
183     /*
184      * Byte structures
185      */
186     /* Current data packet (in the current PES packet of the PES stream) */
187     data_packet_t *         p_data;
188     /* Pointer to the next byte that is to be read (in the current packet) */
189     byte_t *                p_byte;
190     /* Pointer to the last byte that is to be read (in the current packet */
191     byte_t *                p_end;
192     /* Temporary buffer in case we're not aligned when changing data packets */
193     WORD_TYPE               i_showbits_buffer;
194     data_packet_t           showbits_data;
195 } bit_stream_t;
196
197 /*****************************************************************************
198  * Inline functions used by the decoders to read bit_stream_t
199  *****************************************************************************/
200
201 /*
202  * DISCUSSION : How to use the bit_stream structures
203  *
204  * sizeof(WORD_TYPE) (usually 32) bits are read at the same time, thus
205  * minimizing the number of p_byte changes.
206  * Bits are read via GetBits() or ShowBits.
207  *
208  * XXX : Be aware that if, in the forthcoming functions, i_bits > 24,
209  * the data have to be already aligned on an 8-bit boundary, or wrong
210  * results will be returned. Use RealignBits() if unsure.
211  */
212
213 #if (WORD_TYPE == u32)
214 #   define WORD_AT      U32_AT
215 #   define WORD_SIGNED  s32
216 #elif (WORD_TYPE == u64)
217 #   define WORD_AT      U64_AT
218 #   define WORD_SIGNED  s64
219 #else
220 #   error Unsupported WORD_TYPE
221 #endif
222
223 /*****************************************************************************
224  * Prototypes from input_ext-dec.c
225  *****************************************************************************/
226 #ifndef __PLUGIN__
227 void InitBitstream  ( struct bit_stream_s *, struct decoder_fifo_s *,
228                       void (* pf_bitstream_callback)( struct bit_stream_s *,
229                                                       boolean_t ),
230                       void * p_callback_arg );
231 boolean_t NextDataPacket( struct decoder_fifo_s *, struct data_packet_s ** );
232 void BitstreamNextDataPacket( struct bit_stream_s * );
233 u32  UnalignedShowBits( struct bit_stream_s *, unsigned int );
234 void UnalignedRemoveBits( struct bit_stream_s * );
235 u32  UnalignedGetBits( struct bit_stream_s *, unsigned int );
236 void CurrentPTS( struct bit_stream_s *, mtime_t *, mtime_t * );
237 #else
238 #   define InitBitstream p_symbols->InitBitstream
239 #   define NextDataPacket p_symbols->NextDataPacket
240 #   define BitstreamNextDataPacket p_symbols->BitstreamNextDataPacket
241 #   define UnalignedShowBits p_symbols->UnalignedShowBits
242 #   define UnalignedRemoveBits p_symbols->UnalignedRemoveBits
243 #   define UnalignedGetBits p_symbols->UnalignedGetBits
244 #   define CurrentPTS p_symbols->CurrentPTS
245 #endif
246
247 /*****************************************************************************
248  * AlignWord : fill in the bit buffer so that the byte pointer be aligned
249  * on a word boundary (XXX: there must be at least sizeof(WORD_TYPE) - 1
250  * empty bytes in the bit buffer)
251  *****************************************************************************/
252 static inline void AlignWord( bit_stream_t * p_bit_stream )
253 {
254     while( (ptrdiff_t)p_bit_stream->p_byte
255              & (sizeof(WORD_TYPE) - 1) )
256     {
257         if( p_bit_stream->p_byte < p_bit_stream->p_end )
258         {
259             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
260                 << (8 * sizeof(WORD_TYPE) - 8
261                      - p_bit_stream->fifo.i_available);
262             p_bit_stream->fifo.i_available += 8;
263         }
264         else
265         {
266             BitstreamNextDataPacket( p_bit_stream );
267             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
268                 << (8 * sizeof(WORD_TYPE) - 8
269                      - p_bit_stream->fifo.i_available);
270             p_bit_stream->fifo.i_available += 8;
271         }
272     }
273 }
274
275 /*****************************************************************************
276  * ShowBits : return i_bits bits from the bit stream
277  *****************************************************************************/
278 static inline u32 ShowBits( bit_stream_t * p_bit_stream,
279                             unsigned int i_bits )
280 {
281     if( p_bit_stream->fifo.i_available >= i_bits )
282     {
283         return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
284     }
285
286     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
287     {
288         return( (p_bit_stream->fifo.buffer |
289                     (WORD_AT( p_bit_stream->p_byte )
290                         >> p_bit_stream->fifo.i_available))
291                     >> (8 * sizeof(WORD_TYPE) - i_bits) );
292     }
293
294     return( UnalignedShowBits( p_bit_stream, i_bits ) );
295 }
296
297 /*****************************************************************************
298  * ShowSignedBits : return i_bits bits from the bit stream, using signed
299  *                  arithmetic
300  *****************************************************************************/
301 static inline s32 ShowSignedBits( bit_stream_t * p_bit_stream,
302                                   unsigned int i_bits )
303 {
304     if( p_bit_stream->fifo.i_available >= i_bits )
305     {
306         return( (WORD_SIGNED)p_bit_stream->fifo.buffer
307                     >> (8 * sizeof(WORD_TYPE) - i_bits) );
308     }
309
310     /* You can probably do something a little faster, but now I'm tired. */
311     return( (WORD_SIGNED)(ShowBits( p_bit_stream, i_bits ) << (32 - i_bits))
312              >> (32 - i_bits) );
313 }
314
315 /*****************************************************************************
316  * RemoveBits : removes i_bits bits from the bit buffer
317  *              XXX: do not use for 32 bits, see RemoveBits32
318  *****************************************************************************/
319 static inline void RemoveBits( bit_stream_t * p_bit_stream,
320                                unsigned int i_bits )
321 {
322     p_bit_stream->fifo.i_available -= i_bits;
323
324     if( p_bit_stream->fifo.i_available >= 0 )
325     {
326         p_bit_stream->fifo.buffer <<= i_bits;
327         return;
328     }
329
330     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
331     {
332         p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
333                                         << ( -p_bit_stream->fifo.i_available );
334         ((WORD_TYPE *)p_bit_stream->p_byte)++;
335         p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
336         return;
337     }
338
339     UnalignedRemoveBits( p_bit_stream );
340 }
341
342 /*****************************************************************************
343  * RemoveBits32 : removes 32 bits from the bit buffer (and as a side effect,
344  *                refill it)
345  *****************************************************************************/
346 #if (WORD_TYPE == u32)
347 static inline void RemoveBits32( bit_stream_t * p_bit_stream )
348 {
349     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
350     {
351         if( p_bit_stream->fifo.i_available )
352         {
353             p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte )
354                             << (32 - p_bit_stream->fifo.i_available);
355             ((WORD_TYPE *)p_bit_stream->p_byte)++;
356             return;
357         }
358
359         ((WORD_TYPE *)p_bit_stream->p_byte)++;
360         return;
361     }
362
363     p_bit_stream->fifo.i_available -= 32;
364     UnalignedRemoveBits( p_bit_stream );
365 }
366 #else
367 #   define RemoveBits32( p_bit_stream )     RemoveBits( p_bit_stream, 32 )
368 #endif
369
370 /*****************************************************************************
371  * GetBits : returns i_bits bits from the bit stream and removes them
372  *           XXX: do not use for 32 bits, see GetBits32
373  *****************************************************************************/
374 static inline u32 GetBits( bit_stream_t * p_bit_stream,
375                            unsigned int i_bits )
376 {
377     u32             i_result;
378
379     p_bit_stream->fifo.i_available -= i_bits;
380
381     if( p_bit_stream->fifo.i_available >= 0 )
382     {
383         i_result = p_bit_stream->fifo.buffer
384                         >> (8 * sizeof(WORD_TYPE) - i_bits);
385         p_bit_stream->fifo.buffer <<= i_bits;
386         return( i_result );
387     }
388
389     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
390     {
391         i_result = p_bit_stream->fifo.buffer
392                         >> (8 * sizeof(WORD_TYPE) - i_bits);
393         p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
394         ((WORD_TYPE *)p_bit_stream->p_byte)++;
395         i_result |= p_bit_stream->fifo.buffer
396                         >> (8 * sizeof(WORD_TYPE)
397                                      + p_bit_stream->fifo.i_available);
398         p_bit_stream->fifo.buffer <<= ( -p_bit_stream->fifo.i_available );
399         p_bit_stream->fifo.i_available += sizeof(WORD_TYPE) * 8;
400         return( i_result );
401     }
402
403     return UnalignedGetBits( p_bit_stream, i_bits );
404 }
405
406 /*****************************************************************************
407  * GetSignedBits : returns i_bits bits from the bit stream and removes them,
408  *                 using signed arithmetic
409  *                 XXX: do not use for 32 bits
410  *****************************************************************************/
411 static inline s32 GetSignedBits( bit_stream_t * p_bit_stream,
412                                  unsigned int i_bits )
413 {
414     if( p_bit_stream->fifo.i_available >= i_bits )
415     {
416         s32             i_result;
417
418         p_bit_stream->fifo.i_available -= i_bits;
419         i_result = (WORD_SIGNED)p_bit_stream->fifo.buffer
420                         >> (8 * sizeof(WORD_TYPE) - i_bits);
421         p_bit_stream->fifo.buffer <<= i_bits;
422         return( i_result );
423     }
424
425     /* You can probably do something a little faster, but now I'm tired. */
426     return( (WORD_SIGNED)(GetBits( p_bit_stream, i_bits ) << (32 - i_bits))
427              >> (32 - i_bits) );
428 }
429
430 /*****************************************************************************
431  * GetBits32 : returns 32 bits from the bit stream and removes them
432  *****************************************************************************/
433 #if (WORD_TYPE == u32)
434 static inline u32 GetBits32( bit_stream_t * p_bit_stream )
435 {
436     u32             i_result;
437
438     if( p_bit_stream->fifo.i_available == 32 )
439     {
440         p_bit_stream->fifo.i_available = 0;
441         i_result = p_bit_stream->fifo.buffer;
442         p_bit_stream->fifo.buffer = 0;
443         return( i_result );
444     }
445
446     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
447     {
448         if( p_bit_stream->fifo.i_available )
449         {
450             i_result = p_bit_stream->fifo.buffer;
451             p_bit_stream->fifo.buffer = WORD_AT( p_bit_stream->p_byte );
452             ((WORD_TYPE *)p_bit_stream->p_byte)++;
453             i_result |= p_bit_stream->fifo.buffer
454                              >> (p_bit_stream->fifo.i_available);
455             p_bit_stream->fifo.buffer <<= (32 - p_bit_stream->fifo.i_available);
456             return( i_result );
457         }
458
459         i_result = WORD_AT( p_bit_stream->p_byte );
460         ((WORD_TYPE *)p_bit_stream->p_byte)++;
461         return( i_result );
462     }
463
464     p_bit_stream->fifo.i_available -= 32;
465     return UnalignedGetBits( p_bit_stream, 32 );
466 }
467 #else
468 #   define GetBits32( p_bit_stream )    GetBits( p_bit_stream, 32 )
469 #endif
470
471 /*****************************************************************************
472  * RealignBits : realigns the bit buffer on an 8-bit boundary
473  *****************************************************************************/
474 static inline void RealignBits( bit_stream_t * p_bit_stream )
475 {
476     p_bit_stream->fifo.buffer <<= (p_bit_stream->fifo.i_available & 0x7);
477     p_bit_stream->fifo.i_available &= ~0x7;
478 }
479
480
481 /*****************************************************************************
482  * GetChunk : reads a large chunk of data
483  *****************************************************************************
484  * The position in the stream must be byte-aligned, if unsure call
485  * RealignBits(). p_buffer must point to a buffer at least as big as i_buf_len
486  * otherwise your code will crash.
487  *****************************************************************************/
488 static inline void GetChunk( bit_stream_t * p_bit_stream,
489                              byte_t * p_buffer, size_t i_buf_len )
490 {
491     ptrdiff_t           i_available;
492
493     /* We need to take care because i_buf_len may be < 4. */
494     while( p_bit_stream->fifo.i_available > 0 && i_buf_len )
495     {
496         *p_buffer = p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - 8);
497         p_buffer++;
498         i_buf_len--;
499         p_bit_stream->fifo.buffer <<= 8;
500         p_bit_stream->fifo.i_available -= 8;
501     }
502
503     if( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
504             >= i_buf_len )
505     {
506         FAST_MEMCPY( p_buffer, p_bit_stream->p_byte, i_buf_len );
507         p_bit_stream->p_byte += i_buf_len;
508     }
509     else
510     {
511         do
512         {
513             FAST_MEMCPY( p_buffer, p_bit_stream->p_byte, i_available );
514             p_bit_stream->p_byte = p_bit_stream->p_end;
515             p_buffer += i_available;
516             i_buf_len -= i_available;
517             BitstreamNextDataPacket( p_bit_stream );
518             if( p_bit_stream->p_decoder_fifo->b_die )
519                 return;
520         }
521         while( (i_available = p_bit_stream->p_end - p_bit_stream->p_byte)
522                 <= i_buf_len );
523
524         if( i_buf_len )
525         {
526             FAST_MEMCPY( p_buffer, p_bit_stream->p_byte, i_buf_len );
527             p_bit_stream->p_byte += i_buf_len;
528         }
529     }
530
531     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
532     {
533         AlignWord( p_bit_stream );
534     }
535 }
536
537
538 /*
539  * Communication interface between input and decoders
540  */
541
542 /*****************************************************************************
543  * decoder_config_t
544  *****************************************************************************
545  * Standard pointers given to the decoders as a toolbox.
546  *****************************************************************************/
547 typedef struct decoder_config_s
548 {
549     u16                     i_id;
550     u8                      i_type;         /* type of the elementary stream */
551
552     void *                  p_demux_data;
553     struct stream_ctrl_s *  p_stream_ctrl;
554     struct decoder_fifo_s * p_decoder_fifo;
555 } decoder_config_t;
556
557 /*****************************************************************************
558  * Prototypes from input_dec.c
559  *****************************************************************************/
560 #ifndef __PLUGIN__
561 void DecoderError      ( struct decoder_fifo_s * p_fifo );
562 #else
563 #   define DecoderError p_symbols->DecoderError
564 #endif
565