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 $
8 * Authors: Christophe Massiot <massiot@via.ecp.fr>
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.
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.
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 *****************************************************************************/
26 * Communication plugin -> input
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. */
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 *,
46 void * p_callback_arg );
47 void NextDataPacket ( struct bit_stream_s * );
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 *,
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,
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 * );
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 * );
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 );
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 )
98 data_packet_t * p_pad_data;
101 if( (p_pad_data = p_input->pf_new_packet(
102 p_input->p_method_data,
103 PADDING_PACKET_SIZE )) == NULL )
105 intf_ErrMsg("Out of memory");
106 p_input->b_error = 1;
110 memset( p_pad_data->p_payload_start, 0, PADDING_PACKET_SIZE );
111 p_pad_data->b_discard_payload = 1;
116 p_pes->b_discontinuity = 1;
117 p_pes->p_last->p_next = p_pad_data;
118 p_pes->p_last = p_pad_data;
123 if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL )
125 intf_ErrMsg("Out of memory");
126 p_input->b_error = 1;
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 );
140 * Optional netlist management
143 /*****************************************************************************
144 * netlist_t: structure to manage a netlist
145 *****************************************************************************/
146 typedef struct netlist_s
150 size_t i_buffer_size;
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 */
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;
163 unsigned int i_nb_iovec;
164 unsigned int i_nb_pes;
165 unsigned int i_nb_data;
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;
172 /* Reference counters for iovec */
173 unsigned int * pi_refcount;
175 /* Number of blocs read once by readv */
176 unsigned int i_read_once;
179 /*****************************************************************************
181 *****************************************************************************/
182 int input_NetlistInit( struct input_thread_s *,
186 size_t i_buffer_size,
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 * );
203 * Optional Next Generation buffer manager
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
211 /* Number of buffers for the calculation of the mean */
212 #define INPUT_BRESENHAM_NB 50
215 #define BUFFERS_NOFLAGS 0
216 #define BUFFERS_SHARED 1
217 #define BUFFERS_UNIQUE_SIZE 2 /* Only with NB_LIFO == 1 */
219 /*****************************************************************************
220 * input_buffers_t: defines a LIFO per data type to keep
221 *****************************************************************************/
222 #define PACKETS_LIFO( TYPE, NAME ) \
226 unsigned int i_depth; \
229 #define BUFFERS_LIFO( TYPE, NAME ) \
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) */\
237 #define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
238 typedef struct input_buffers_s \
241 PACKETS_LIFO( pes_packet_t, pes ) \
242 BUFFERS_LIFO( data_packet_t, data[NB_LIFO] ) \
243 size_t i_allocated; \
246 #define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
247 typedef struct input_buffers_s \
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; \
256 typedef struct data_buffer_s
260 struct data_buffer_s * p_next;
261 byte_t payload_start;
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 ) \
271 input_buffers_t * p_buffers = malloc( sizeof( input_buffers_t ) ); \
273 if( p_buffers == NULL ) \
278 memset( p_buffers, 0, sizeof( input_buffers_t ) ); \
279 vlc_mutex_init( &p_buffers->lock ); \
281 return (void *)p_buffers; \
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++ ) \
290 if( FLAGS & BUFFERS_UNIQUE_SIZE ) \
293 "input buffers stats: " #STRUCT "[%d]: %d packets", \
294 i, p_buffers->STRUCT[i].i_depth ); \
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 ); \
305 #define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \
306 BUFFERS_END_STAT_BUFFERS_LOOP( data );
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 );
314 #define BUFFERS_END_BUFFERS_LOOP \
315 while( p_buf != NULL ) \
317 p_next = p_buf->p_next; \
318 p_buffers->i_allocated -= p_buf->i_size; \
323 #define BUFFERS_END_PACKETS_LOOP \
324 while( p_packet != NULL ) \
326 p_next = p_packet->p_next; \
331 #define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \
332 for( i = 0; i < NB_LIFO; i++ ) \
334 data_packet_t * p_next; \
335 data_packet_t * p_buf = p_buffers->data[i].p_stack; \
336 BUFFERS_END_BUFFERS_LOOP; \
339 #define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \
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; \
347 for( i = 0; i < NB_LIFO; i++ ) \
349 data_buffer_t * p_next; \
350 data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \
351 BUFFERS_END_BUFFERS_LOOP; \
354 #define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \
355 static void input_BuffersEnd( void * _p_buffers ) \
357 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
359 if( _p_buffers != NULL ) \
363 if( p_main->b_stats ) \
366 intf_StatMsg( "input buffers stats: pes: %d packets", \
367 p_buffers->pes.i_depth ); \
368 STAT_LOOP( FLAGS, NB_LIFO ); \
373 pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \
374 BUFFERS_END_PACKETS_LOOP; \
377 LOOP( FLAGS, NB_LIFO ); \
379 if( p_buffers->i_allocated ) \
381 intf_ErrMsg( "input buffers error: %d bytes have not been" \
382 " freed, expect memory leak", \
383 p_buffers->i_allocated ); \
386 vlc_mutex_destroy( &p_buffers->lock ); \
387 free( _p_buffers ); \
391 #define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
392 BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
394 #define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \
395 BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \
396 BUFFERS_END_LOOP_SHARED );
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;
404 #define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \
405 data_packet_t * p_data; \
406 data_packet_t ** pp_data = &p_data;
408 #define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
410 #define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \
411 /* Find a data packet */ \
412 if( p_buffers->data.p_stack != NULL ) \
414 p_data = p_buffers->data.p_stack; \
415 p_buffers->data.p_stack = p_data->p_next; \
416 p_buffers->data.i_depth--; \
420 p_data = malloc( sizeof( data_packet_t ) ); \
421 if( p_data == NULL ) \
423 intf_ErrMsg( "Out of memory" ); \
424 vlc_mutex_unlock( &p_buffers->lock ); \
431 /* Warning : in that case, the data packet is left partly \
432 * uninitialized ; theorically only input_ShareBuffer may call \
434 p_data->p_next = NULL; \
435 p_data->b_discard_payload = 0; \
439 #define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO )
441 #define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO ) \
442 /* Initialize refcount */ \
443 p_buf->i_refcount = 1;
445 #define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \
447 static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers, \
450 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
453 EXTRA_DECLARATION( FLAGS, NB_LIFO ); \
456 if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
458 intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
459 p_buffers->i_allocated ); \
463 EXTRA( FLAGS, NB_LIFO ); \
465 for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
467 if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
468 + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
474 if( p_buffers->NAME[i_select].p_stack != NULL ) \
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--; \
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) ) \
485 p_buffers->i_allocated -= p_buf->i_size; \
486 p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \
487 if( p_buf == NULL ) \
489 intf_ErrMsg( "Out of memory" ); \
492 p_buf->i_size = i_size; \
493 p_buffers->i_allocated += i_size; \
498 /* Allocate a new packet */ \
499 p_buf = malloc( sizeof( TYPE ) + i_size ); \
500 if( p_buf == NULL ) \
502 intf_ErrMsg( "Out of memory" ); \
505 p_buf->i_size = i_size; \
506 p_buffers->i_allocated += i_size; \
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; \
517 END( FLAGS, NB_LIFO ); \
519 return( *pp_data ); \
522 static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
524 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
525 data_packet_t * p_data; \
528 if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \
530 intf_ErrMsg( "Packet too big (%d)", i_size ); \
534 vlc_mutex_lock( &p_buffers->lock ); \
535 p_data = _input_NewPacket( _p_buffers, i_size ); \
536 vlc_mutex_unlock( &p_buffers->lock ); \
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 )
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 )
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;
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; \
559 /* Get rid of the data packet */ \
560 if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \
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++; \
572 /* Decrement refcount */ \
573 p_buf->i_refcount--; \
574 if( p_buf->i_refcount > 0 ) \
579 #define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \
581 static __inline__ void _input_DeletePacket( void * _p_buffers, \
582 data_packet_t * p_data ) \
584 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
587 EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
589 for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
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 ) \
598 if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \
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++; \
605 if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
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; \
616 p_buffers->i_allocated -= p_buf->i_size; \
621 static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
623 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
625 vlc_mutex_lock( &p_buffers->lock ); \
626 _input_DeletePacket( _p_buffers, p_data ); \
627 vlc_mutex_unlock( &p_buffers->lock ); \
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 )
634 #define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \
636 BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, data_buffer_t, \
637 buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED )
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 ) \
645 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
646 pes_packet_t * p_pes; \
648 vlc_mutex_lock( &p_buffers->lock ); \
650 if( p_buffers->pes.p_stack != NULL ) \
652 p_pes = p_buffers->pes.p_stack; \
653 p_buffers->pes.p_stack = p_pes->p_next; \
654 p_buffers->pes.i_depth--; \
658 p_pes = malloc( sizeof( pes_packet_t ) ); \
659 if( p_pes == NULL ) \
661 intf_ErrMsg( "Out of memory" ); \
662 vlc_mutex_unlock( &p_buffers->lock ); \
667 vlc_mutex_unlock( &p_buffers->lock ); \
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; \
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 ) \
686 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
688 vlc_mutex_lock( &p_buffers->lock ); \
691 data_packet_t * p_data = p_pes->p_first; \
692 while( p_data != NULL ) \
694 data_packet_t * p_next = p_data->p_next; \
695 _input_DeletePacket( _p_buffers, p_data ); \
700 if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
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++; \
712 vlc_mutex_unlock( &p_buffers->lock ); \
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 ) \
722 input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
723 data_packet_t * p_data = NULL; \
726 vlc_mutex_lock( &p_buffers->lock ); \
728 for( i = i_nb - 1; i >= 0; i-- ) \
730 data_packet_t * p_next = _input_NewPacket( _p_buffers, \
731 BUFFER_SIZE /* UNIQUE_SIZE */ ); \
732 if( p_next == NULL ) \
734 while( p_data != NULL ) \
736 p_next = p_data->p_next; \
737 _input_DeletePacket( _p_buffers, p_data ); \
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; \
749 vlc_mutex_unlock( &p_buffers->lock ); \
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 ) \
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; \
765 vlc_mutex_lock( &p_buffers->lock ); \
767 /* Get new data_packet_t */ \
768 p_data = _input_NewPacket( _p_buffers, 0 ); \
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; \
776 /* Update refcount */ \
777 p_buf->i_refcount++; \
779 vlc_mutex_unlock( &p_buffers->lock ); \
786 * Optional MPEG demultiplexing
789 /*****************************************************************************
791 *****************************************************************************/
792 #define TS_PACKET_SIZE 188 /* Size of a TS packet */
793 #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */
795 #define PAT_UNINITIALIZED (1 << 6)
796 #define PMT_UNINITIALIZED (1 << 6)
798 #define PSI_IS_PAT 0x00
799 #define PSI_IS_PMT 0x01
800 #define UNKNOWN_PSI 0xff
802 /*****************************************************************************
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
810 byte_t buffer[PSI_SECTION_SIZE];
813 u8 i_last_section_number;
815 u16 i_section_length;
816 u16 i_read_in_section;
818 /* the PSI is complete */
819 boolean_t b_is_complete;
821 /* packet missed up ? */
825 boolean_t b_section_complete;
827 /* where are we currently ? */
832 /*****************************************************************************
833 * es_ts_data_t: extension of es_descriptor_t
834 *****************************************************************************/
835 typedef struct es_ts_data_s
837 boolean_t b_psi; /* Does the stream have to be handled by
838 * the PSI decoder ? */
840 int i_psi_type; /* There are different types of PSI */
842 psi_section_t * p_psi_section; /* PSI packets */
845 int i_continuity_counter;
848 /*****************************************************************************
849 * pgrm_ts_data_t: extension of pgrm_descriptor_t
850 *****************************************************************************/
851 typedef struct pgrm_ts_data_s
853 u16 i_pcr_pid; /* PCR ES, for TS streams */
857 /*****************************************************************************
858 * stream_ts_data_t: extension of stream_descriptor_t
859 *****************************************************************************/
860 typedef struct stream_ts_data_s
862 int i_pat_version; /* Current version of the PAT */
865 /*****************************************************************************
866 * stream_ps_data_t: extension of stream_descriptor_t
867 *****************************************************************************/
868 typedef struct stream_ps_data_s
870 boolean_t b_has_PSM; /* very rare, in fact */
875 /* PSM version is 5 bits, so -1 is not a valid value */
876 #define EMPTY_PSM_VERSION -1
879 /*****************************************************************************
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 );