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