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