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.15 2001/12/30 07:09:54 sam 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 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. */
36 /*****************************************************************************
37 * Prototypes from input_ext-dec.c
38 *****************************************************************************/
40 void InitBitstream ( struct bit_stream_s *, struct decoder_fifo_s *,
41 void (* pf_bitstream_callback)( struct bit_stream_s *,
43 void * p_callback_arg );
44 void NextDataPacket ( struct bit_stream_s * );
46 # define InitBitstream p_symbols->InitBitstream
49 /*****************************************************************************
50 * Prototypes from input_programs.c
51 *****************************************************************************/
53 int input_InitStream( struct input_thread_s *, size_t );
54 void input_EndStream ( struct input_thread_s * );
55 struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
56 struct pgrm_descriptor_s * input_AddProgram ( struct input_thread_s *,
58 void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
59 int input_SetProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
60 struct input_area_s * input_AddArea( struct input_thread_s * );
61 void input_DelArea ( struct input_thread_s *, struct input_area_s * );
62 struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
63 struct es_descriptor_s * input_AddES ( struct input_thread_s *,
64 struct pgrm_descriptor_s *, u16,
66 void input_DelES ( struct input_thread_s *, struct es_descriptor_s * );
67 int input_SelectES ( struct input_thread_s *, struct es_descriptor_s * );
68 int input_UnselectES( struct input_thread_s *, struct es_descriptor_s * );
70 # define input_InitStream p_symbols->input_InitStream
71 # define input_EndStream p_symbols->input_EndStream
72 # define input_SetProgram p_symbols->input_SetProgram
73 # define input_FindES p_symbols->input_FindES
74 # define input_AddES p_symbols->input_AddES
75 # define input_DelES p_symbols->input_DelES
76 # define input_SelectES p_symbols->input_SelectES
77 # define input_UnselectES p_symbols->input_UnselectES
78 # define input_AddProgram p_symbols->input_AddProgram
79 # define input_DelProgram p_symbols->input_DelProgram
80 # define input_AddArea p_symbols->input_AddArea
81 # define input_DelArea p_symbols->input_DelArea
84 /*****************************************************************************
85 * Prototypes from input_dec.c
86 *****************************************************************************/
88 //decoder_capabilities_s * input_ProbeDecoder( void );
89 vlc_thread_t input_RunDecoder( struct input_thread_s *,
90 struct es_descriptor_s * );
91 void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
92 void input_DecodePES ( struct decoder_fifo_s *, struct pes_packet_s * );
93 void input_EscapeDiscontinuity( struct input_thread_s *,
94 struct pgrm_descriptor_s * );
95 void input_EscapeAudioDiscontinuity( struct input_thread_s * );
97 # define input_DecodePES p_symbols->input_DecodePES
100 /*****************************************************************************
101 * Prototypes from input_clock.c
102 *****************************************************************************/
104 void input_ClockInit( struct pgrm_descriptor_s * );
105 int input_ClockManageControl( struct input_thread_s *,
106 struct pgrm_descriptor_s *, mtime_t );
107 void input_ClockManageRef( struct input_thread_s *,
108 struct pgrm_descriptor_s *, mtime_t );
109 mtime_t input_ClockGetTS( struct input_thread_s *,
110 struct pgrm_descriptor_s *, mtime_t );
112 # define input_ClockManageControl p_symbols->input_ClockManageControl
115 /*****************************************************************************
116 * Create a NULL packet for padding in case of a data loss
117 *****************************************************************************/
118 static __inline__ void input_NullPacket( input_thread_t * p_input,
119 es_descriptor_t * p_es )
121 data_packet_t * p_pad_data;
122 pes_packet_t * p_pes;
124 if( (p_pad_data = p_input->pf_new_packet(
125 p_input->p_method_data,
126 PADDING_PACKET_SIZE )) == NULL )
128 intf_ErrMsg("Out of memory");
129 p_input->b_error = 1;
133 memset( p_pad_data->p_payload_start, 0, PADDING_PACKET_SIZE );
134 p_pad_data->b_discard_payload = 1;
139 p_pes->b_discontinuity = 1;
140 p_pes->p_last->p_next = p_pad_data;
141 p_pes->p_last = p_pad_data;
146 if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL )
148 intf_ErrMsg("Out of memory");
149 p_input->b_error = 1;
153 p_pes->i_rate = p_input->stream.control.i_rate;
154 p_pes->p_first = p_pes->p_last = p_pad_data;
155 p_pes->i_nb_data = 1;
156 p_pes->b_discontinuity = 1;
157 input_DecodePES( p_es->p_decoder_fifo, p_pes );
163 * Optional Next Generation buffer manager
165 * Either buffers can only be used in one data packet (PS case), or buffers
166 * contain several data packets (DVD case). In the first case, buffers are
167 * embedded into data packets, otherwise they are allocated separately and
168 * shared with a refcount. --Meuuh
171 /* Number of buffers for the calculation of the mean */
172 #define INPUT_BRESENHAM_NB 50
175 #define BUFFERS_NOFLAGS 0
176 #define BUFFERS_UNIQUE_SIZE 1 /* Only with NB_LIFO == 1 */
178 /*****************************************************************************
179 * _input_buffers_t: defines a LIFO per data type to keep
180 *****************************************************************************/
181 #define PACKETS_LIFO( TYPE, NAME ) \
185 unsigned int i_depth; \
188 #define BUFFERS_LIFO( TYPE, NAME ) \
191 TYPE * p_stack; /* First item in the LIFO */ \
192 unsigned int i_depth; /* Number of items in the LIFO */ \
193 unsigned int i_average_size; /* Average size of the items (Bresenham) */\
196 #define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
197 typedef struct _input_buffers_s \
200 PACKETS_LIFO( pes_packet_t, pes ) \
201 BUFFERS_LIFO( _data_packet_t, data[NB_LIFO] ) \
202 size_t i_allocated; \
205 #define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
206 typedef struct _input_buffers_s \
209 PACKETS_LIFO( pes_packet_t, pes ) \
210 PACKETS_LIFO( _data_packet_t, data ) \
211 BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] ) \
212 size_t i_allocated; \
215 /* Data buffer, used in case the buffer can be shared between several data
217 typedef struct _data_buffer_s
219 struct _data_buffer_s * p_next;
221 /* number of data packets this buffer is referenced from - when it falls
222 * down to 0, the buffer is freed */
225 struct /* for compatibility with _data_packet_t */
227 /* size of the current buffer (starting right thereafter) */
232 /* We overload the data_packet_t type to add private members */
233 typedef struct _data_packet_s
235 struct _data_packet_s * p_next;
241 struct _data_buffer_s * p_buffer; /* in case of shared buffers */
242 /* size of the embedded buffer (starting right thereafter) */
248 /*****************************************************************************
249 * input_BuffersInit: initialize the cache structures, return a pointer to it
250 *****************************************************************************/
251 #define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \
252 static void * input_BuffersInit( void ) \
254 _input_buffers_t * p_buffers = malloc( sizeof( _input_buffers_t ) ); \
256 if( p_buffers == NULL ) \
261 memset( p_buffers, 0, sizeof( _input_buffers_t ) ); \
262 vlc_mutex_init( &p_buffers->lock ); \
264 return (void *)p_buffers; \
267 /*****************************************************************************
268 * input_BuffersEnd: free all cached structures
269 *****************************************************************************/
270 #define BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT ) \
271 for( i = 0; i < NB_LIFO; i++ ) \
273 if( FLAGS & BUFFERS_UNIQUE_SIZE ) \
276 "input buffers stats: " #STRUCT "[%d]: %d packets", \
277 i, p_buffers->STRUCT[i].i_depth ); \
282 "input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \
283 i, p_buffers->STRUCT[i].i_average_size, \
284 p_buffers->STRUCT[i].i_depth ); \
288 #define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \
289 BUFFERS_END_STAT_BUFFERS_LOOP( data );
291 #define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO ) \
292 intf_StatMsg( "input buffers stats: data: %d packets", \
293 p_buffers->data.i_depth ); \
294 BUFFERS_END_STAT_BUFFERS_LOOP( buffers );
297 #define BUFFERS_END_BUFFERS_LOOP \
298 while( p_buf != NULL ) \
300 p_next = p_buf->p_next; \
301 p_buffers->i_allocated -= p_buf->_private.i_size; \
306 #define BUFFERS_END_PACKETS_LOOP \
307 while( p_packet != NULL ) \
309 p_next = p_packet->p_next; \
314 #define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \
315 for( i = 0; i < NB_LIFO; i++ ) \
317 _data_packet_t * p_next; \
318 _data_packet_t * p_buf = p_buffers->data[i].p_stack; \
319 BUFFERS_END_BUFFERS_LOOP; \
322 #define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \
324 /* Free data packets */ \
325 _data_packet_t * p_next; \
326 _data_packet_t * p_packet = p_buffers->data.p_stack; \
327 BUFFERS_END_PACKETS_LOOP; \
330 for( i = 0; i < NB_LIFO; i++ ) \
332 _data_buffer_t * p_next; \
333 _data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \
334 BUFFERS_END_BUFFERS_LOOP; \
337 #define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \
338 static void input_BuffersEnd( void * _p_buffers ) \
340 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
342 if( _p_buffers != NULL ) \
346 if( p_main->b_stats ) \
349 intf_StatMsg( "input buffers stats: pes: %d packets", \
350 p_buffers->pes.i_depth ); \
351 STAT_LOOP( FLAGS, NB_LIFO ); \
356 pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \
357 BUFFERS_END_PACKETS_LOOP; \
360 LOOP( FLAGS, NB_LIFO ); \
362 if( p_buffers->i_allocated ) \
364 intf_ErrMsg( "input buffers error: %d bytes have not been" \
365 " freed, expect memory leak", \
366 p_buffers->i_allocated ); \
369 vlc_mutex_destroy( &p_buffers->lock ); \
370 free( _p_buffers ); \
374 #define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
375 BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
377 #define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \
378 BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \
379 BUFFERS_END_LOOP_SHARED );
381 /*****************************************************************************
382 * input_NewPacket: return a pointer to a data packet of the appropriate size
383 *****************************************************************************/
384 #define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO ) \
385 _data_packet_t ** pp_data = &p_buf;
387 #define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \
388 _data_packet_t * p_data; \
389 _data_packet_t ** pp_data = &p_data;
391 #define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
393 #define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \
394 /* Find a data packet */ \
395 if( p_buffers->data.p_stack != NULL ) \
397 p_data = p_buffers->data.p_stack; \
398 p_buffers->data.p_stack = p_data->p_next; \
399 p_buffers->data.i_depth--; \
403 p_data = malloc( sizeof( _data_packet_t ) ); \
404 if( p_data == NULL ) \
406 intf_ErrMsg( "Out of memory" ); \
407 vlc_mutex_unlock( &p_buffers->lock ); \
414 /* Warning : in that case, the data packet is left partly \
415 * uninitialized ; theorically only input_ShareBuffer may call \
417 p_data->p_next = NULL; \
418 p_data->b_discard_payload = 0; \
419 return( (data_packet_t *)p_data ); \
422 #define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE ) \
423 (*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE );
425 #define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE ) \
426 (*pp_data)->_private.p_buffer = p_buf; \
427 (*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer \
429 /* Initialize refcount */ \
430 p_buf->i_refcount = 1;
432 #define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \
434 /* This one doesn't take p_buffers->lock. */ \
435 static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers, \
438 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
441 EXTRA_DECLARATION( FLAGS, NB_LIFO ); \
444 if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
446 intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
447 p_buffers->i_allocated ); \
451 EXTRA( FLAGS, NB_LIFO ); \
453 for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
455 if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
456 + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
462 if( p_buffers->NAME[i_select].p_stack != NULL ) \
464 /* Take the packet from the cache */ \
465 p_buf = p_buffers->NAME[i_select].p_stack; \
466 p_buffers->NAME[i_select].p_stack = p_buf->p_next; \
467 p_buffers->NAME[i_select].i_depth--; \
469 /* Reallocate the packet if it is too small or too large */ \
470 if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && \
471 (p_buf->_private.i_size < i_size \
472 || p_buf->_private.i_size > 3 * i_size) ) \
474 p_buffers->i_allocated -= p_buf->_private.i_size; \
475 p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \
476 if( p_buf == NULL ) \
478 intf_ErrMsg( "Out of memory" ); \
481 p_buf->_private.i_size = i_size; \
482 p_buffers->i_allocated += i_size; \
487 /* Allocate a new packet */ \
488 p_buf = malloc( sizeof( TYPE ) + i_size ); \
489 if( p_buf == NULL ) \
491 intf_ErrMsg( "Out of memory" ); \
494 p_buf->_private.i_size = i_size; \
495 p_buffers->i_allocated += i_size; \
498 /* Initialize data */ \
499 END( FLAGS, NB_LIFO, TYPE ); \
500 (*pp_data)->p_next = NULL; \
501 (*pp_data)->b_discard_payload = 0; \
502 (*pp_data)->p_payload_start = (*pp_data)->p_demux_start; \
503 (*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size; \
505 return( (data_packet_t *)*pp_data ); \
508 static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
510 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
511 data_packet_t * p_data; \
514 if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \
516 intf_ErrMsg( "Packet too big (%d)", i_size ); \
520 vlc_mutex_lock( &p_buffers->lock ); \
521 p_data = _input_NewPacket( _p_buffers, i_size ); \
522 vlc_mutex_unlock( &p_buffers->lock ); \
526 #define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
527 BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data, \
528 BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA, \
529 BUFFERS_NEWPACKET_END )
531 #define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO ) \
532 BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers, \
533 BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED, \
534 BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED )
536 /*****************************************************************************
537 * input_DeletePacket: put a packet back into the cache
538 *****************************************************************************/
539 #define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
540 _data_packet_t * p_buf = p_data;
542 #define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\
543 _data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer; \
545 /* Get rid of the data packet */ \
546 if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \
548 /* Cache not full : store the packet in it */ \
549 p_data->p_next = p_buffers->data.p_stack; \
550 p_buffers->data.p_stack = p_data; \
551 p_buffers->data.i_depth++; \
558 /* Decrement refcount */ \
559 p_buf->i_refcount--; \
560 if( p_buf->i_refcount > 0 ) \
565 #define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
566 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
567 _data_packet_t * p_first = (_data_packet_t *)_p_first; \
568 _data_packet_t ** pp_last = (_data_packet_t **)_pp_last; \
570 /* Small hopeless optimization */ \
571 if( (FLAGS & BUFFERS_UNIQUE_SIZE) \
572 && p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \
574 p_buffers->data[0].i_depth += i_nb; \
575 *pp_last = p_buffers->data[0].p_stack; \
576 p_buffers->data[0].p_stack = p_first; \
578 else /* No semicolon after this or you will die */
580 #define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO, \
583 #define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \
584 NAME, EXTRA, EXTRA_STACK ) \
585 /* This one doesn't take p_buffers->lock. */ \
586 static __inline__ void _input_DeletePacket( void * _p_buffers, \
587 data_packet_t * _p_data ) \
589 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
590 _data_packet_t * p_data = (_data_packet_t *)_p_data; \
593 while( p_data != NULL ) \
595 _data_packet_t * p_next = p_data->p_next; \
597 EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
599 for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
601 if( p_buf->_private.i_size <= \
602 (2 * p_buffers->NAME[i_select].i_average_size \
603 + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
609 if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \
611 /* Cache not full : store the packet in it */ \
612 p_buf->p_next = p_buffers->NAME[i_select].p_stack; \
613 p_buffers->NAME[i_select].p_stack = p_buf; \
614 p_buffers->NAME[i_select].i_depth++; \
616 if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
618 /* Update Bresenham mean (very approximative) */ \
619 p_buffers->NAME[i_select].i_average_size = \
620 ( p_buf->_private.i_size \
621 + p_buffers->NAME[i_select].i_average_size \
622 * (INPUT_BRESENHAM_NB - 1) ) \
623 / INPUT_BRESENHAM_NB; \
628 p_buffers->i_allocated -= p_buf->_private.i_size; \
636 static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
638 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
640 vlc_mutex_lock( &p_buffers->lock ); \
641 _input_DeletePacket( _p_buffers, p_data ); \
642 vlc_mutex_unlock( &p_buffers->lock ); \
645 /* Delete a chained list of i_nb data packets. -- needed by DeletePES */ \
646 static __inline__ void _input_DeletePacketStack( void * _p_buffers, \
647 data_packet_t * _p_first, \
648 data_packet_t ** _pp_last, \
649 unsigned int i_nb ) \
651 /* Do not add code before, EXTRA_STACK makes its own declarations. */ \
652 EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
653 /* No semicolon - PLEASE */ \
655 _input_DeletePacket( _p_buffers, _p_first ); \
659 #define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
660 BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t, \
661 data, BUFFERS_DELETEPACKET_EXTRA, \
662 BUFFERS_DELETEPACKETSTACK_EXTRA )
664 #define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \
666 BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t, \
667 buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED, \
668 BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED )
670 /*****************************************************************************
671 * input_DeletePacketStack: optimize deleting of a stack of packets when
672 * knowing much information
673 *****************************************************************************/
674 /* AFAIK, this isn't used by anyone - it is here for completion.
675 * _input_DeletePacketStack is declared in DeletePacket because it is needed
677 #define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO ) \
678 static void input_DeletePacketStack( void * _p_buffers, \
679 data_packet_t * p_first, \
680 data_packet_t ** pp_last, \
681 unsigned int i_nb ) \
683 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
685 vlc_mutex_lock( &p_buffers->lock ); \
686 _input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb ); \
687 vlc_mutex_unlock( &p_buffers->lock ); \
690 /*****************************************************************************
691 * input_NewPES: return a pointer to a new PES packet
692 *****************************************************************************/
693 #define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \
694 static pes_packet_t * input_NewPES( void * _p_buffers ) \
696 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
697 pes_packet_t * p_pes; \
699 vlc_mutex_lock( &p_buffers->lock ); \
701 if( p_buffers->pes.p_stack != NULL ) \
703 p_pes = p_buffers->pes.p_stack; \
704 p_buffers->pes.p_stack = p_pes->p_next; \
705 p_buffers->pes.i_depth--; \
709 p_pes = malloc( sizeof( pes_packet_t ) ); \
710 if( p_pes == NULL ) \
712 intf_ErrMsg( "Out of memory" ); \
713 vlc_mutex_unlock( &p_buffers->lock ); \
718 vlc_mutex_unlock( &p_buffers->lock ); \
720 /* Initialize data */ \
721 p_pes->p_next = NULL; \
722 p_pes->b_data_alignment = p_pes->b_discontinuity = \
723 p_pes->i_pts = p_pes->i_dts = 0; \
724 p_pes->i_pes_size = 0; \
725 p_pes->p_first = p_pes->p_last = NULL; \
726 p_pes->i_nb_data = 0; \
731 /*****************************************************************************
732 * input_DeletePES: put a pes and all data packets back into the cache
733 *****************************************************************************/
734 #define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
735 static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \
737 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
739 vlc_mutex_lock( &p_buffers->lock ); \
741 while( p_pes != NULL ) \
743 pes_packet_t * p_next = p_pes->p_next; \
745 /* Delete all data packets */ \
746 if( p_pes->p_first != NULL ) \
748 _input_DeletePacketStack( _p_buffers, p_pes->p_first, \
749 &p_pes->p_last->p_next, \
750 p_pes->i_nb_data ); \
753 if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
755 /* Cache not full : store the packet in it */ \
756 p_pes->p_next = p_buffers->pes.p_stack; \
757 p_buffers->pes.p_stack = p_pes; \
758 p_buffers->pes.i_depth++; \
768 vlc_mutex_unlock( &p_buffers->lock ); \
771 /*****************************************************************************
772 * input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE)
773 *****************************************************************************/
774 #define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE ) \
775 static data_packet_t * input_BuffersToIO( void * _p_buffers, \
776 struct iovec * p_iovec, int i_nb )\
778 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
779 data_packet_t * p_data = NULL; \
782 vlc_mutex_lock( &p_buffers->lock ); \
784 for( i = i_nb - 1; i >= 0; i-- ) \
786 data_packet_t * p_next = _input_NewPacket( _p_buffers, \
787 BUFFER_SIZE /* UNIQUE_SIZE */ ); \
788 if( p_next == NULL ) \
790 _input_DeletePacket( _p_buffers, p_data ); \
794 p_iovec[i].iov_base = p_next->p_demux_start; \
795 p_iovec[i].iov_len = BUFFER_SIZE; \
796 p_next->p_next = p_data; \
800 vlc_mutex_unlock( &p_buffers->lock ); \
805 /*****************************************************************************
806 * input_ShareBuffer: return a new data_packet to the same buffer
807 *****************************************************************************/
808 #define DECLARE_BUFFERS_SHAREBUFFER( FLAGS ) \
809 static data_packet_t * input_ShareBuffer( void * _p_buffers, \
810 data_packet_t * _p_shared_data ) \
812 _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
813 _data_packet_t * p_shared_data = (_data_packet_t *)_p_shared_data; \
814 _data_packet_t * p_data; \
815 _data_buffer_t * p_buf = p_shared_data->_private.p_buffer; \
817 vlc_mutex_lock( &p_buffers->lock ); \
819 /* Get new data_packet_t, without a buffer through a special backdoor \
820 * in _input_NewPacket. */ \
821 p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 ); \
823 /* Finish initialization of p_data */ \
824 p_data->_private.p_buffer = p_shared_data->_private.p_buffer; \
825 p_data->p_demux_start = p_data->p_payload_start \
826 = (byte_t *)p_shared_data->_private.p_buffer \
827 + sizeof( _data_buffer_t ); \
828 p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \
830 /* Update refcount */ \
831 p_buf->i_refcount++; \
833 vlc_mutex_unlock( &p_buffers->lock ); \
835 return( (data_packet_t *)p_data ); \
840 * Optional MPEG demultiplexing
843 /*****************************************************************************
845 *****************************************************************************/
846 #define TS_PACKET_SIZE 188 /* Size of a TS packet */
847 #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */
849 #define PAT_UNINITIALIZED (1 << 6)
850 #define PMT_UNINITIALIZED (1 << 6)
852 #define PSI_IS_PAT 0x00
853 #define PSI_IS_PMT 0x01
854 #define UNKNOWN_PSI 0xff
856 /*****************************************************************************
858 *****************************************************************************
859 * Describes a PSI section. Beware, it doesn't contain pointers to the TS
860 * packets that contain it as for a PES, but the data themselves
861 *****************************************************************************/
862 typedef struct psi_section_s
864 byte_t buffer[PSI_SECTION_SIZE];
867 u8 i_last_section_number;
869 u16 i_section_length;
870 u16 i_read_in_section;
872 /* the PSI is complete */
873 boolean_t b_is_complete;
875 /* packet missed up ? */
879 boolean_t b_section_complete;
881 /* where are we currently ? */
886 /*****************************************************************************
887 * es_ts_data_t: extension of es_descriptor_t
888 *****************************************************************************/
889 typedef struct es_ts_data_s
891 boolean_t b_psi; /* Does the stream have to be handled by
892 * the PSI decoder ? */
894 int i_psi_type; /* There are different types of PSI */
896 psi_section_t * p_psi_section; /* PSI packets */
899 int i_continuity_counter;
902 /*****************************************************************************
903 * pgrm_ts_data_t: extension of pgrm_descriptor_t
904 *****************************************************************************/
905 typedef struct pgrm_ts_data_s
907 u16 i_pcr_pid; /* PCR ES, for TS streams */
911 /*****************************************************************************
912 * stream_ts_data_t: extension of stream_descriptor_t
913 *****************************************************************************/
914 typedef struct stream_ts_data_s
916 int i_pat_version; /* Current version of the PAT */
919 /*****************************************************************************
920 * stream_ps_data_t: extension of stream_descriptor_t
921 *****************************************************************************/
922 typedef struct stream_ps_data_s
924 boolean_t b_has_PSM; /* very rare, in fact */
929 /* PSM version is 5 bits, so -1 is not a valid value */
930 #define EMPTY_PSM_VERSION -1
933 /*****************************************************************************
935 *****************************************************************************/
937 void input_ParsePES ( struct input_thread_s *, struct es_descriptor_s * );
938 void input_GatherPES ( struct input_thread_s *, struct data_packet_s *,
939 struct es_descriptor_s *, boolean_t, boolean_t );
940 es_descriptor_t * input_ParsePS( struct input_thread_s *,
941 struct data_packet_s * );
942 void input_DemuxPS ( struct input_thread_s *, struct data_packet_s * );
943 void input_DemuxTS ( struct input_thread_s *, struct data_packet_s * );
944 void input_DemuxPSI ( struct input_thread_s *, struct data_packet_s *,
945 struct es_descriptor_s *, boolean_t, boolean_t );
947 # define input_ParsePES p_symbols->input_ParsePES
948 # define input_GatherPES p_symbols->input_GatherPES
949 # define input_ParsePS p_symbols->input_ParsePS
950 # define input_DemuxPS p_symbols->input_DemuxPS
951 # define input_DemuxTS p_symbols->input_DemuxTS
952 # define input_DemuxPSI p_symbols->input_DemuxPSI