]> git.sesse.net Git - vlc/blob - include/input_ext-plugins.h
477a1b5e29f3fb81a51519e89a2d636580defcfc
[vlc] / include / input_ext-plugins.h
1 /*****************************************************************************
2  * input_ext-plugins.h: structures of the input not exported to other modules,
3  *                      but exported to plug-ins
4  *****************************************************************************
5  * Copyright (C) 1999-2001 VideoLAN
6  * $Id: input_ext-plugins.h,v 1.16 2002/01/21 23:57:46 massiot Exp $
7  *
8  * Authors: Christophe Massiot <massiot@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 /*
26  * Communication plugin -> input
27  */
28
29 /* FIXME: you've gotta move this move this, you've gotta move this move this */
30 #define PADDING_PACKET_SIZE 188 /* Size of the NULL packet inserted in case
31                                  * of data loss (this should be < 188).      */
32 #define PADDING_PACKET_NUMBER 10 /* Number of padding packets top insert to
33                                   * escape a decoder.                        */
34 #define NO_SEEK             -1
35
36 /*****************************************************************************
37  * Prototypes from input_programs.c
38  *****************************************************************************/
39 #ifndef PLUGIN
40 int  input_InitStream( struct input_thread_s *, size_t );
41 void input_EndStream ( struct input_thread_s * );
42 struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
43 struct pgrm_descriptor_s * input_AddProgram ( struct input_thread_s *,
44                                               u16, size_t );
45 void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
46 int input_SetProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
47 struct input_area_s * input_AddArea( struct input_thread_s * );
48 void input_DelArea   ( struct input_thread_s *, struct input_area_s * );
49 struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
50 struct es_descriptor_s * input_AddES ( struct input_thread_s *,
51                                        struct pgrm_descriptor_s *, u16,
52                                        size_t );
53 void input_DelES     ( struct input_thread_s *, struct es_descriptor_s * );
54 int  input_SelectES  ( struct input_thread_s *, struct es_descriptor_s * );
55 int  input_UnselectES( struct input_thread_s *, struct es_descriptor_s * );
56 #else
57 #   define input_InitStream p_symbols->input_InitStream
58 #   define input_EndStream p_symbols->input_EndStream
59 #   define input_SetProgram p_symbols->input_SetProgram
60 #   define input_FindES p_symbols->input_FindES
61 #   define input_AddES p_symbols->input_AddES
62 #   define input_DelES p_symbols->input_DelES
63 #   define input_SelectES p_symbols->input_SelectES
64 #   define input_UnselectES p_symbols->input_UnselectES
65 #   define input_AddProgram p_symbols->input_AddProgram
66 #   define input_DelProgram p_symbols->input_DelProgram
67 #   define input_AddArea p_symbols->input_AddArea
68 #   define input_DelArea p_symbols->input_DelArea
69 #endif
70
71 /*****************************************************************************
72  * Prototypes from input_dec.c
73  *****************************************************************************/
74 #ifndef PLUGIN
75 //decoder_capabilities_s * input_ProbeDecoder( void );
76 vlc_thread_t input_RunDecoder( struct input_thread_s *,
77                                struct es_descriptor_s * );
78 void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
79 void input_DecodePES ( struct decoder_fifo_s *, struct pes_packet_s * );
80 void input_EscapeDiscontinuity( struct input_thread_s *,
81                                 struct pgrm_descriptor_s * );
82 void input_EscapeAudioDiscontinuity( struct input_thread_s * );
83 #else
84 #   define input_DecodePES p_symbols->input_DecodePES
85 #endif
86
87 /*****************************************************************************
88  * Prototypes from input_clock.c
89  *****************************************************************************/
90 #ifndef PLUGIN
91 void input_ClockInit( struct pgrm_descriptor_s * );
92 int  input_ClockManageControl( struct input_thread_s *,
93                                struct pgrm_descriptor_s *, mtime_t );
94 void input_ClockManageRef( struct input_thread_s *,
95                            struct pgrm_descriptor_s *, mtime_t );
96 mtime_t input_ClockGetTS( struct input_thread_s *,
97                           struct pgrm_descriptor_s *, mtime_t );
98 #else
99 #   define input_ClockManageControl p_symbols->input_ClockManageControl
100 #endif
101
102 /*****************************************************************************
103  * Create a NULL packet for padding in case of a data loss
104  *****************************************************************************/
105 static __inline__ void input_NullPacket( input_thread_t * p_input,
106                                          es_descriptor_t * p_es )
107 {
108     data_packet_t *             p_pad_data;
109     pes_packet_t *              p_pes;
110
111     if( (p_pad_data = p_input->pf_new_packet(
112                     p_input->p_method_data,
113                     PADDING_PACKET_SIZE )) == NULL )
114     {
115         intf_ErrMsg("Out of memory");
116         p_input->b_error = 1;
117         return;
118     }
119
120     memset( p_pad_data->p_payload_start, 0, PADDING_PACKET_SIZE );
121     p_pad_data->b_discard_payload = 1;
122     p_pes = p_es->p_pes;
123
124     if( p_pes != NULL )
125     {
126         p_pes->b_discontinuity = 1;
127         p_pes->p_last->p_next = p_pad_data;
128         p_pes->p_last = p_pad_data;
129         p_pes->i_nb_data++;
130     }
131     else
132     {
133         if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL )
134         {
135             intf_ErrMsg("Out of memory");
136             p_input->b_error = 1;
137             return;
138         }
139
140         p_pes->i_rate = p_input->stream.control.i_rate;
141         p_pes->p_first = p_pes->p_last = p_pad_data;
142         p_pes->i_nb_data = 1;
143         p_pes->b_discontinuity = 1;
144         input_DecodePES( p_es->p_decoder_fifo, p_pes );
145     }
146 }
147
148
149 /*
150  * Optional Next Generation buffer manager
151  *
152  * Either buffers can only be used in one data packet (PS case), or buffers
153  * contain several data packets (DVD case). In the first case, buffers are
154  * embedded into data packets, otherwise they are allocated separately and
155  * shared with a refcount. --Meuuh
156  */
157
158 /* Number of buffers for the calculation of the mean */
159 #define INPUT_BRESENHAM_NB      50
160
161 /* Flags */
162 #define BUFFERS_NOFLAGS         0
163 #define BUFFERS_UNIQUE_SIZE     1 /* Only with NB_LIFO == 1 */
164
165 /*****************************************************************************
166  * _input_buffers_t: defines a LIFO per data type to keep
167  *****************************************************************************/
168 #define PACKETS_LIFO( TYPE, NAME )                                          \
169 struct                                                                      \
170 {                                                                           \
171     TYPE * p_stack;                                                         \
172     unsigned int i_depth;                                                   \
173 } NAME;
174
175 #define BUFFERS_LIFO( TYPE, NAME )                                          \
176 struct                                                                      \
177 {                                                                           \
178     TYPE * p_stack; /* First item in the LIFO */                            \
179     unsigned int i_depth; /* Number of items in the LIFO */                 \
180     unsigned int i_average_size; /* Average size of the items (Bresenham) */\
181 } NAME;
182
183 #define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO )                          \
184 typedef struct _input_buffers_s                                             \
185 {                                                                           \
186     vlc_mutex_t lock;                                                       \
187     PACKETS_LIFO( pes_packet_t, pes )                                       \
188     BUFFERS_LIFO( _data_packet_t, data[NB_LIFO] )                           \
189     size_t i_allocated;                                                     \
190 } _input_buffers_t;
191
192 #define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO )                            \
193 typedef struct _input_buffers_s                                             \
194 {                                                                           \
195     vlc_mutex_t lock;                                                       \
196     PACKETS_LIFO( pes_packet_t, pes )                                       \
197     PACKETS_LIFO( _data_packet_t, data )                                    \
198     BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] )                        \
199     size_t i_allocated;                                                     \
200 } _input_buffers_t;
201
202 /* Data buffer, used in case the buffer can be shared between several data
203  * packets */
204 typedef struct _data_buffer_s
205 {
206     struct _data_buffer_s * p_next;
207
208     /* number of data packets this buffer is referenced from - when it falls
209      * down to 0, the buffer is freed */
210     int i_refcount;
211
212     struct /* for compatibility with _data_packet_t */
213     {
214         /* size of the current buffer (starting right thereafter) */
215         unsigned int i_size;
216     } _private;
217 } _data_buffer_t;
218
219 /* We overload the data_packet_t type to add private members */
220 typedef struct _data_packet_s
221 {
222     struct _data_packet_s * p_next;
223
224     DATA_PACKET
225
226     union
227     {
228         struct _data_buffer_s * p_buffer; /* in case of shared buffers */
229         /* size of the embedded buffer (starting right thereafter) */
230         unsigned int i_size;
231     } _private;
232 } _data_packet_t;
233
234
235 /*****************************************************************************
236  * input_BuffersInit: initialize the cache structures, return a pointer to it
237  *****************************************************************************/
238 #define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO )                              \
239 static void * input_BuffersInit( void )                                     \
240 {                                                                           \
241     _input_buffers_t * p_buffers = malloc( sizeof( _input_buffers_t ) );    \
242                                                                             \
243     if( p_buffers == NULL )                                                 \
244     {                                                                       \
245         return( NULL );                                                     \
246     }                                                                       \
247                                                                             \
248     memset( p_buffers, 0, sizeof( _input_buffers_t ) );                     \
249     vlc_mutex_init( &p_buffers->lock );                                     \
250                                                                             \
251     return (void *)p_buffers;                                               \
252 }
253
254 /*****************************************************************************
255  * input_BuffersEnd: free all cached structures
256  *****************************************************************************/
257 #define BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT )                             \
258     for( i = 0; i < NB_LIFO; i++ )                                          \
259     {                                                                       \
260         if( FLAGS & BUFFERS_UNIQUE_SIZE )                                   \
261         {                                                                   \
262             intf_StatMsg(                                                   \
263               "input buffers stats: " #STRUCT "[%d]: %d packets",           \
264               i, p_buffers->STRUCT[i].i_depth );                            \
265         }                                                                   \
266         else                                                                \
267         {                                                                   \
268             intf_StatMsg(                                                   \
269               "input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \
270               i, p_buffers->STRUCT[i].i_average_size,                       \
271               p_buffers->STRUCT[i].i_depth );                               \
272         }                                                                   \
273     }
274
275 #define BUFFERS_END_STAT( FLAGS, NB_LIFO )                                  \
276     BUFFERS_END_STAT_BUFFERS_LOOP( data );
277
278 #define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO )                           \
279     intf_StatMsg( "input buffers stats: data: %d packets",                  \
280                   p_buffers->data.i_depth );                                \
281     BUFFERS_END_STAT_BUFFERS_LOOP( buffers );
282
283
284 #define BUFFERS_END_BUFFERS_LOOP                                            \
285     while( p_buf != NULL )                                                  \
286     {                                                                       \
287         p_next = p_buf->p_next;                                             \
288         p_buffers->i_allocated -= p_buf->_private.i_size;                   \
289         free( p_buf );                                                      \
290         p_buf = p_next;                                                     \
291     }
292
293 #define BUFFERS_END_PACKETS_LOOP                                            \
294     while( p_packet != NULL )                                               \
295     {                                                                       \
296         p_next = p_packet->p_next;                                          \
297         free( p_packet );                                                   \
298         p_packet = p_next;                                                  \
299     }
300
301 #define BUFFERS_END_LOOP( FLAGS, NB_LIFO )                                  \
302     for( i = 0; i < NB_LIFO; i++ )                                          \
303     {                                                                       \
304         _data_packet_t * p_next;                                            \
305         _data_packet_t * p_buf = p_buffers->data[i].p_stack;                \
306         BUFFERS_END_BUFFERS_LOOP;                                           \
307     }                                                                       \
308
309 #define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO )                           \
310     {                                                                       \
311         /* Free data packets */                                             \
312         _data_packet_t * p_next;                                            \
313         _data_packet_t * p_packet = p_buffers->data.p_stack;                \
314         BUFFERS_END_PACKETS_LOOP;                                           \
315     }                                                                       \
316                                                                             \
317     for( i = 0; i < NB_LIFO; i++ )                                          \
318     {                                                                       \
319         _data_buffer_t * p_next;                                            \
320         _data_buffer_t * p_buf = p_buffers->buffers[i].p_stack;             \
321         BUFFERS_END_BUFFERS_LOOP;                                           \
322     }                                                                       \
323
324 #define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP )                      \
325 static void input_BuffersEnd( void * _p_buffers )                           \
326 {                                                                           \
327     _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers;          \
328                                                                             \
329     if( _p_buffers != NULL )                                                \
330     {                                                                       \
331         int i;                                                              \
332                                                                             \
333         if( p_main->b_stats )                                               \
334         {                                                                   \
335             int i;                                                          \
336             intf_StatMsg( "input buffers stats: pes: %d packets",           \
337                           p_buffers->pes.i_depth );                         \
338             STAT_LOOP( FLAGS, NB_LIFO );                                    \
339         }                                                                   \
340                                                                             \
341         {                                                                   \
342             /* Free PES */                                                  \
343             pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack;     \
344             BUFFERS_END_PACKETS_LOOP;                                       \
345         }                                                                   \
346                                                                             \
347         LOOP( FLAGS, NB_LIFO );                                             \
348                                                                             \
349         if( p_buffers->i_allocated )                                        \
350         {                                                                   \
351             intf_ErrMsg( "input buffers error: %d bytes have not been"      \
352                          " freed, expect memory leak",                      \
353                          p_buffers->i_allocated );                          \
354         }                                                                   \
355                                                                             \
356         vlc_mutex_destroy( &p_buffers->lock );                              \
357         free( _p_buffers );                                                 \
358     }                                                                       \
359 }
360
361 #define DECLARE_BUFFERS_END( FLAGS, NB_LIFO )                               \
362     BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
363
364 #define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO )                        \
365     BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED,                   \
366                  BUFFERS_END_LOOP_SHARED );
367
368 /*****************************************************************************
369  * input_NewPacket: return a pointer to a data packet of the appropriate size
370  *****************************************************************************/
371 #define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO )               \
372     _data_packet_t **    pp_data = &p_buf;
373
374 #define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO )        \
375     _data_packet_t *     p_data;                                            \
376     _data_packet_t **    pp_data = &p_data;
377
378 #define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
379
380 #define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO )                    \
381     /* Find a data packet */                                                \
382     if( p_buffers->data.p_stack != NULL )                                   \
383     {                                                                       \
384         p_data = p_buffers->data.p_stack;                                   \
385         p_buffers->data.p_stack = p_data->p_next;                           \
386         p_buffers->data.i_depth--;                                          \
387     }                                                                       \
388     else                                                                    \
389     {                                                                       \
390         p_data = malloc( sizeof( _data_packet_t ) );                        \
391         if( p_data == NULL )                                                \
392         {                                                                   \
393             intf_ErrMsg( "Out of memory" );                                 \
394             vlc_mutex_unlock( &p_buffers->lock );                           \
395             return( NULL );                                                 \
396         }                                                                   \
397     }                                                                       \
398                                                                             \
399     if( i_size == 0 )                                                       \
400     {                                                                       \
401         /* Warning : in that case, the data packet is left partly           \
402          * uninitialized ; theorically only input_ShareBuffer may call      \
403          * this. */                                                         \
404         p_data->p_next = NULL;                                              \
405         p_data->b_discard_payload = 0;                                      \
406         return( (data_packet_t *)p_data );                                  \
407     }
408
409 #define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE )                       \
410     (*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE );
411
412 #define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE )                \
413     (*pp_data)->_private.p_buffer = p_buf;                                  \
414     (*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer     \
415                                   + sizeof( TYPE );                         \
416     /* Initialize refcount */                                               \
417     p_buf->i_refcount = 1;
418
419 #define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION,   \
420                            EXTRA, END )                                     \
421 /* This one doesn't take p_buffers->lock. */                                \
422 static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers,      \
423                                                     size_t i_size )         \
424 {                                                                           \
425     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
426     int                 i_select;                                           \
427     TYPE *              p_buf;                                              \
428     EXTRA_DECLARATION( FLAGS, NB_LIFO );                                    \
429                                                                             \
430     /* Safety check */                                                      \
431     if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION )                     \
432     {                                                                       \
433         intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)",                   \
434                      p_buffers->i_allocated );                              \
435         return NULL;                                                        \
436     }                                                                       \
437                                                                             \
438     EXTRA( FLAGS, NB_LIFO );                                                \
439                                                                             \
440     for( i_select = 0; i_select < NB_LIFO - 1; i_select++ )                 \
441     {                                                                       \
442         if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size         \
443                   + p_buffers->NAME[i_select + 1].i_average_size) / 3 )     \
444         {                                                                   \
445             break;                                                          \
446         }                                                                   \
447     }                                                                       \
448                                                                             \
449     if( p_buffers->NAME[i_select].p_stack != NULL )                         \
450     {                                                                       \
451         /* Take the packet from the cache */                                \
452         p_buf = p_buffers->NAME[i_select].p_stack;                          \
453         p_buffers->NAME[i_select].p_stack = p_buf->p_next;                  \
454         p_buffers->NAME[i_select].i_depth--;                                \
455                                                                             \
456         /* Reallocate the packet if it is too small or too large */         \
457         if( !(FLAGS & BUFFERS_UNIQUE_SIZE) &&                               \
458             (p_buf->_private.i_size < i_size                                \
459               || p_buf->_private.i_size > 3 * i_size) )                     \
460         {                                                                   \
461             p_buffers->i_allocated -= p_buf->_private.i_size;               \
462             p_buf = realloc( p_buf, sizeof( TYPE ) + i_size );              \
463             if( p_buf == NULL )                                             \
464             {                                                               \
465                 intf_ErrMsg( "Out of memory" );                             \
466                 return NULL;                                                \
467             }                                                               \
468             p_buf->_private.i_size = i_size;                                \
469             p_buffers->i_allocated += i_size;                               \
470         }                                                                   \
471     }                                                                       \
472     else                                                                    \
473     {                                                                       \
474         /* Allocate a new packet */                                         \
475         p_buf = malloc( sizeof( TYPE ) + i_size );                          \
476         if( p_buf == NULL )                                                 \
477         {                                                                   \
478             intf_ErrMsg( "Out of memory" );                                 \
479             return NULL;                                                    \
480         }                                                                   \
481         p_buf->_private.i_size = i_size;                                    \
482         p_buffers->i_allocated += i_size;                                   \
483     }                                                                       \
484                                                                             \
485     /* Initialize data */                                                   \
486     END( FLAGS, NB_LIFO, TYPE );                                            \
487     (*pp_data)->p_next = NULL;                                              \
488     (*pp_data)->b_discard_payload = 0;                                      \
489     (*pp_data)->p_payload_start = (*pp_data)->p_demux_start;                \
490     (*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size;       \
491                                                                             \
492     return( (data_packet_t *)*pp_data );                                    \
493 }                                                                           \
494                                                                             \
495 static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size )  \
496 {                                                                           \
497     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
498     data_packet_t *     p_data;                                             \
499                                                                             \
500     /* Safety check */                                                      \
501     if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE )  \
502     {                                                                       \
503         intf_ErrMsg( "Packet too big (%d)", i_size );                       \
504         return NULL;                                                        \
505     }                                                                       \
506                                                                             \
507     vlc_mutex_lock( &p_buffers->lock );                                     \
508     p_data = _input_NewPacket( _p_buffers, i_size );                        \
509     vlc_mutex_unlock( &p_buffers->lock );                                   \
510     return( p_data );                                                       \
511 }
512
513 #define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO )                         \
514     BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data,                \
515             BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA,   \
516             BUFFERS_NEWPACKET_END )
517
518 #define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO )                  \
519     BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers,             \
520             BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED,                     \
521             BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED )
522
523 /*****************************************************************************
524  * input_DeletePacket: put a packet back into the cache
525  *****************************************************************************/
526 #define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE )       \
527     _data_packet_t * p_buf = p_data;
528
529 #define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\
530     _data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer;   \
531                                                                             \
532     /* Get rid of the data packet */                                        \
533     if( p_buffers->data.i_depth < DATA_CACHE_SIZE )                         \
534     {                                                                       \
535         /* Cache not full : store the packet in it */                       \
536         p_data->p_next = p_buffers->data.p_stack;                           \
537         p_buffers->data.p_stack = p_data;                                   \
538         p_buffers->data.i_depth++;                                          \
539     }                                                                       \
540     else                                                                    \
541     {                                                                       \
542         free( p_data );                                                     \
543     }                                                                       \
544                                                                             \
545     /* Decrement refcount */                                                \
546     p_buf->i_refcount--;                                                    \
547     if( p_buf->i_refcount > 0 )                                             \
548     {                                                                       \
549         return;                                                             \
550     }
551
552 #define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE )  \
553     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
554     _data_packet_t *    p_first = (_data_packet_t *)_p_first;               \
555     _data_packet_t **   pp_last = (_data_packet_t **)_pp_last;              \
556                                                                             \
557     /* Small hopeless optimization */                                       \
558     if( (FLAGS & BUFFERS_UNIQUE_SIZE)                                       \
559            && p_buffers->data[0].i_depth < DATA_CACHE_SIZE )                \
560     {                                                                       \
561         p_buffers->data[0].i_depth += i_nb;                                 \
562         *pp_last = p_buffers->data[0].p_stack;                              \
563         p_buffers->data[0].p_stack = p_first;                               \
564     }                                                                       \
565     else /* No semicolon after this or you will die */ 
566
567 #define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO,             \
568                                                 DATA_CACHE_SIZE )
569
570 #define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE,        \
571                               NAME, EXTRA, EXTRA_STACK )                    \
572 /* This one doesn't take p_buffers->lock. */                                \
573 static __inline__ void _input_DeletePacket( void * _p_buffers,              \
574                                             data_packet_t * _p_data )       \
575 {                                                                           \
576     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
577     _data_packet_t *    p_data = (_data_packet_t *)_p_data;                 \
578     int                 i_select;                                           \
579                                                                             \
580     while( p_data != NULL )                                                 \
581     {                                                                       \
582         _data_packet_t * p_next = p_data->p_next;                           \
583                                                                             \
584         EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE );                           \
585                                                                             \
586         for( i_select = 0; i_select < NB_LIFO - 1; i_select++ )             \
587         {                                                                   \
588             if( p_buf->_private.i_size <=                                   \
589                    (2 * p_buffers->NAME[i_select].i_average_size            \
590                       + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
591             {                                                               \
592                 break;                                                      \
593             }                                                               \
594         }                                                                   \
595                                                                             \
596         if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE )           \
597         {                                                                   \
598             /* Cache not full : store the packet in it */                   \
599             p_buf->p_next = p_buffers->NAME[i_select].p_stack;              \
600             p_buffers->NAME[i_select].p_stack = p_buf;                      \
601             p_buffers->NAME[i_select].i_depth++;                            \
602                                                                             \
603             if( !(FLAGS & BUFFERS_UNIQUE_SIZE) )                            \
604             {                                                               \
605                 /* Update Bresenham mean (very approximative) */            \
606                 p_buffers->NAME[i_select].i_average_size =                  \
607                     ( p_buf->_private.i_size                                \
608                        + p_buffers->NAME[i_select].i_average_size           \
609                        * (INPUT_BRESENHAM_NB - 1) )                         \
610                      / INPUT_BRESENHAM_NB;                                  \
611             }                                                               \
612         }                                                                   \
613         else                                                                \
614         {                                                                   \
615             p_buffers->i_allocated -= p_buf->_private.i_size;               \
616             free( p_buf );                                                  \
617         }                                                                   \
618                                                                             \
619         p_data = p_next;                                                    \
620     }                                                                       \
621 }                                                                           \
622                                                                             \
623 static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
624 {                                                                           \
625     _input_buffers_t *   p_buffers = (_input_buffers_t *)_p_buffers;        \
626                                                                             \
627     vlc_mutex_lock( &p_buffers->lock );                                     \
628     _input_DeletePacket( _p_buffers, p_data );                              \
629     vlc_mutex_unlock( &p_buffers->lock );                                   \
630 }                                                                           \
631                                                                             \
632 /* Delete a chained list of i_nb data packets. -- needed by DeletePES */    \
633 static __inline__ void _input_DeletePacketStack( void * _p_buffers,         \
634                                       data_packet_t * _p_first,             \
635                                       data_packet_t ** _pp_last,            \
636                                       unsigned int i_nb )                   \
637 {                                                                           \
638     /* Do not add code before, EXTRA_STACK makes its own declarations. */   \
639     EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE )                          \
640     /* No semicolon - PLEASE */                                             \
641     {                                                                       \
642         _input_DeletePacket( _p_buffers, _p_first );                        \
643     }                                                                       \
644 }
645
646 #define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE )     \
647     BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t,  \
648                           data, BUFFERS_DELETEPACKET_EXTRA,                 \
649                           BUFFERS_DELETEPACKETSTACK_EXTRA )
650
651 #define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO,                \
652                                              DATA_CACHE_SIZE )              \
653     BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t,  \
654                           buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED,       \
655                           BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED )
656
657 /*****************************************************************************
658  * input_DeletePacketStack: optimize deleting of a stack of packets when
659  * knowing much information
660  *****************************************************************************/
661 /* AFAIK, this isn't used by anyone - it is here for completion.
662  * _input_DeletePacketStack is declared in DeletePacket because it is needed
663  * by DeletePES. */
664 #define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO )                 \
665 static void input_DeletePacketStack( void * _p_buffers,                     \
666                                      data_packet_t * p_first,               \
667                                      data_packet_t ** pp_last,              \
668                                      unsigned int i_nb )                    \
669 {                                                                           \
670     _input_buffers_t *   p_buffers = (_input_buffers_t *)_p_buffers;        \
671                                                                             \
672     vlc_mutex_lock( &p_buffers->lock );                                     \
673     _input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb );         \
674     vlc_mutex_unlock( &p_buffers->lock );                                   \
675 }
676
677 /*****************************************************************************
678  * input_NewPES: return a pointer to a new PES packet
679  *****************************************************************************/
680 #define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO )                            \
681 static pes_packet_t * input_NewPES( void * _p_buffers )                     \
682 {                                                                           \
683     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
684     pes_packet_t *      p_pes;                                              \
685                                                                             \
686     vlc_mutex_lock( &p_buffers->lock );                                     \
687                                                                             \
688     if( p_buffers->pes.p_stack != NULL )                                    \
689     {                                                                       \
690         p_pes = p_buffers->pes.p_stack;                                     \
691         p_buffers->pes.p_stack = p_pes->p_next;                             \
692         p_buffers->pes.i_depth--;                                           \
693     }                                                                       \
694     else                                                                    \
695     {                                                                       \
696         p_pes = malloc( sizeof( pes_packet_t ) );                           \
697         if( p_pes == NULL )                                                 \
698         {                                                                   \
699             intf_ErrMsg( "Out of memory" );                                 \
700             vlc_mutex_unlock( &p_buffers->lock );                           \
701             return( NULL );                                                 \
702         }                                                                   \
703     }                                                                       \
704                                                                             \
705     vlc_mutex_unlock( &p_buffers->lock );                                   \
706                                                                             \
707     /* Initialize data */                                                   \
708     p_pes->p_next = NULL;                                                   \
709     p_pes->b_data_alignment = p_pes->b_discontinuity =                      \
710         p_pes->i_pts = p_pes->i_dts = 0;                                    \
711     p_pes->i_pes_size = 0;                                                  \
712     p_pes->p_first = p_pes->p_last = NULL;                                  \
713     p_pes->i_nb_data = 0;                                                   \
714                                                                             \
715     return( p_pes );                                                        \
716 }
717
718 /*****************************************************************************
719  * input_DeletePES: put a pes and all data packets back into the cache
720  *****************************************************************************/
721 #define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE )         \
722 static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes )      \
723 {                                                                           \
724     _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers;          \
725                                                                             \
726     vlc_mutex_lock( &p_buffers->lock );                                     \
727                                                                             \
728     while( p_pes != NULL )                                                  \
729     {                                                                       \
730         pes_packet_t * p_next = p_pes->p_next;                              \
731                                                                             \
732         /* Delete all data packets */                                       \
733         if( p_pes->p_first != NULL )                                        \
734         {                                                                   \
735             _input_DeletePacketStack( _p_buffers, p_pes->p_first,           \
736                                       &p_pes->p_last->p_next,               \
737                                       p_pes->i_nb_data );                   \
738         }                                                                   \
739                                                                             \
740         if( p_buffers->pes.i_depth < PES_CACHE_SIZE )                       \
741         {                                                                   \
742             /* Cache not full : store the packet in it */                   \
743             p_pes->p_next = p_buffers->pes.p_stack;                         \
744             p_buffers->pes.p_stack = p_pes;                                 \
745             p_buffers->pes.i_depth++;                                       \
746         }                                                                   \
747         else                                                                \
748         {                                                                   \
749             free( p_pes );                                                  \
750         }                                                                   \
751                                                                             \
752         p_pes = p_next;                                                     \
753     }                                                                       \
754                                                                             \
755     vlc_mutex_unlock( &p_buffers->lock );                                   \
756 }
757
758 /*****************************************************************************
759  * input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE)
760  *****************************************************************************/
761 #define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE )                          \
762 static data_packet_t * input_BuffersToIO( void * _p_buffers,                \
763                                           struct iovec * p_iovec, int i_nb )\
764 {                                                                           \
765     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
766     data_packet_t *     p_data = NULL;                                      \
767     int                 i;                                                  \
768                                                                             \
769     vlc_mutex_lock( &p_buffers->lock );                                     \
770                                                                             \
771     for( i = i_nb - 1; i >= 0; i-- )                                        \
772     {                                                                       \
773         data_packet_t * p_next = _input_NewPacket( _p_buffers,              \
774                                           BUFFER_SIZE /* UNIQUE_SIZE */ );  \
775         if( p_next == NULL )                                                \
776         {                                                                   \
777             _input_DeletePacket( _p_buffers, p_data );                      \
778             return( NULL );                                                 \
779         }                                                                   \
780                                                                             \
781         p_iovec[i].iov_base = p_next->p_demux_start;                        \
782         p_iovec[i].iov_len = BUFFER_SIZE;                                   \
783         p_next->p_next = p_data;                                            \
784         p_data = p_next;                                                    \
785     }                                                                       \
786                                                                             \
787     vlc_mutex_unlock( &p_buffers->lock );                                   \
788                                                                             \
789     return( p_data );                                                       \
790 }
791
792 /*****************************************************************************
793  * input_ShareBuffer: return a new data_packet to the same buffer
794  *****************************************************************************/
795 #define DECLARE_BUFFERS_SHAREBUFFER( FLAGS )                                \
796 static data_packet_t * input_ShareBuffer( void * _p_buffers,                \
797                                           data_packet_t * _p_shared_data )  \
798 {                                                                           \
799     _input_buffers_t *  p_buffers = (_input_buffers_t *)_p_buffers;         \
800     _data_packet_t *    p_shared_data = (_data_packet_t *)_p_shared_data;   \
801     _data_packet_t *    p_data;                                             \
802     _data_buffer_t *    p_buf = p_shared_data->_private.p_buffer;           \
803                                                                             \
804     vlc_mutex_lock( &p_buffers->lock );                                     \
805                                                                             \
806     /* Get new data_packet_t, without a buffer through a special backdoor   \
807      * in _input_NewPacket. */                                              \
808     p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 );           \
809                                                                             \
810     /* Finish initialization of p_data */                                   \
811     p_data->_private.p_buffer = p_shared_data->_private.p_buffer;           \
812     p_data->p_demux_start = p_data->p_payload_start                         \
813              = (byte_t *)p_shared_data->_private.p_buffer                   \
814                  + sizeof( _data_buffer_t );                                \
815     p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \
816                                                                             \
817     /* Update refcount */                                                   \
818     p_buf->i_refcount++;                                                    \
819                                                                             \
820     vlc_mutex_unlock( &p_buffers->lock );                                   \
821                                                                             \
822     return( (data_packet_t *)p_data );                                      \
823 }
824
825
826 /*
827  * Optional MPEG demultiplexing
828  */
829
830 /*****************************************************************************
831  * Constants
832  *****************************************************************************/
833 #define TS_PACKET_SIZE      188                       /* Size of a TS packet */
834 #define PSI_SECTION_SIZE    4096            /* Maximum size of a PSI section */
835
836 #define PAT_UNINITIALIZED    (1 << 6)
837 #define PMT_UNINITIALIZED    (1 << 6)
838
839 #define PSI_IS_PAT          0x00
840 #define PSI_IS_PMT          0x01
841 #define UNKNOWN_PSI         0xff
842
843 /*****************************************************************************
844  * psi_section_t
845  *****************************************************************************
846  * Describes a PSI section. Beware, it doesn't contain pointers to the TS
847  * packets that contain it as for a PES, but the data themselves
848  *****************************************************************************/
849 typedef struct psi_section_s
850 {
851     byte_t                  buffer[PSI_SECTION_SIZE];
852
853     u8                      i_section_number;
854     u8                      i_last_section_number;
855     u8                      i_version_number;
856     u16                     i_section_length;
857     u16                     i_read_in_section;
858     
859     /* the PSI is complete */
860     boolean_t               b_is_complete;
861     
862     /* packet missed up ? */
863     boolean_t               b_trash;
864
865     /*about sections  */ 
866     boolean_t               b_section_complete;
867
868     /* where are we currently ? */
869     byte_t                * p_current;
870
871 } psi_section_t;
872
873 /*****************************************************************************
874  * es_ts_data_t: extension of es_descriptor_t
875  *****************************************************************************/
876 typedef struct es_ts_data_s
877 {
878     boolean_t               b_psi;   /* Does the stream have to be handled by
879                                       *                    the PSI decoder ? */
880
881     int                     i_psi_type;  /* There are different types of PSI */
882     
883     psi_section_t *         p_psi_section;                    /* PSI packets */
884
885     /* Markers */
886     int                     i_continuity_counter;
887 } es_ts_data_t;
888
889 /*****************************************************************************
890  * pgrm_ts_data_t: extension of pgrm_descriptor_t
891  *****************************************************************************/
892 typedef struct pgrm_ts_data_s
893 {
894     u16                     i_pcr_pid;             /* PCR ES, for TS streams */
895     int                     i_pmt_version;
896 } pgrm_ts_data_t;
897
898 /*****************************************************************************
899  * stream_ts_data_t: extension of stream_descriptor_t
900  *****************************************************************************/
901 typedef struct stream_ts_data_s
902 {
903     int i_pat_version;          /* Current version of the PAT */
904 } stream_ts_data_t;
905
906 /*****************************************************************************
907  * stream_ps_data_t: extension of stream_descriptor_t
908  *****************************************************************************/
909 typedef struct stream_ps_data_s
910 {
911     boolean_t               b_has_PSM;                 /* very rare, in fact */
912
913     u8                      i_PSM_version;
914 } stream_ps_data_t;
915
916 /* PSM version is 5 bits, so -1 is not a valid value */
917 #define EMPTY_PSM_VERSION   -1
918
919
920 /*****************************************************************************
921  * Prototypes
922  *****************************************************************************/
923 #ifndef PLUGIN
924 void input_ParsePES  ( struct input_thread_s *, struct es_descriptor_s * );
925 void input_GatherPES ( struct input_thread_s *, struct data_packet_s *,
926                        struct es_descriptor_s *, boolean_t, boolean_t );
927 es_descriptor_t * input_ParsePS( struct input_thread_s *,
928                                  struct data_packet_s * );
929 void input_DemuxPS   ( struct input_thread_s *, struct data_packet_s * );
930 void input_DemuxTS   ( struct input_thread_s *, struct data_packet_s * );
931 void input_DemuxPSI  ( struct input_thread_s *, struct data_packet_s *,
932                        struct es_descriptor_s *, boolean_t, boolean_t );
933 #else
934 #   define input_ParsePES p_symbols->input_ParsePES
935 #   define input_GatherPES p_symbols->input_GatherPES
936 #   define input_ParsePS p_symbols->input_ParsePS
937 #   define input_DemuxPS p_symbols->input_DemuxPS
938 #   define input_DemuxTS p_symbols->input_DemuxTS
939 #   define input_DemuxPSI p_symbols->input_DemuxPSI
940 #endif
941