]> git.sesse.net Git - vlc/blob - plugins/mpeg/input_ps.c
c04de149c1fc9dbd861bdb32dbf03a1c4752cab4
[vlc] / plugins / mpeg / input_ps.c
1 /*****************************************************************************
2  * input_ps.c: PS demux and packet management
3  *****************************************************************************
4  * Copyright (C) 1998, 1999, 2000 VideoLAN
5  * $Id: input_ps.c,v 1.19 2001/04/27 23:29:14 stef Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Cyril Deguet <asmax@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 #define MODULE_NAME ps
26 #include "modules_inner.h"
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include "defs.h"
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include "config.h"
43 #include "common.h"
44 #include "threads.h"
45 #include "mtime.h"
46 #include "tests.h"
47
48 #include "intf_msg.h"
49
50 #include "main.h"
51
52 #include "stream_control.h"
53 #include "input_ext-intf.h"
54 #include "input_ext-dec.h"
55
56 #include "input.h"
57
58 #include "input_ps.h"
59 #include "mpeg_system.h"
60
61 #include "debug.h"
62
63 #include "modules.h"
64
65 /*****************************************************************************
66  * Local prototypes
67  *****************************************************************************/
68 static int  PSProbe     ( probedata_t * );
69 static int  PSRead      ( struct input_thread_s *,
70                           data_packet_t * p_packets[INPUT_READ_ONCE] );
71 static void PSInit      ( struct input_thread_s * );
72 static void PSEnd       ( struct input_thread_s * );
73 static void PSSeek      ( struct input_thread_s *, off_t );
74 static struct pes_packet_s *  NewPES    ( void * );
75 static struct data_packet_s * NewPacket ( void *, size_t );
76 static void DeletePacket( void *, struct data_packet_s * );
77 static void DeletePES   ( void *, struct pes_packet_s * );
78
79 /*****************************************************************************
80  * Functions exported as capabilities. They are declared as static so that
81  * we don't pollute the namespace too much.
82  *****************************************************************************/
83 void _M( input_getfunctions )( function_list_t * p_function_list )
84 {
85 #define input p_function_list->functions.input
86     p_function_list->pf_probe = PSProbe;
87     input.pf_init             = PSInit;
88     input.pf_open             = input_FileOpen;
89     input.pf_close            = input_FileClose;
90     input.pf_end              = PSEnd;
91     input.pf_set_area         = NULL;
92     input.pf_read             = PSRead;
93     input.pf_demux            = input_DemuxPS;
94     input.pf_new_packet       = NewPacket;
95     input.pf_new_pes          = NewPES;
96     input.pf_delete_packet    = DeletePacket;
97     input.pf_delete_pes       = DeletePES;
98     input.pf_rewind           = NULL;
99     input.pf_seek             = PSSeek;
100 #undef input
101 }
102
103 /*
104  * Data reading functions
105  */
106
107 /*****************************************************************************
108  * PSProbe: verifies that the stream is a PS stream
109  *****************************************************************************/
110 static int PSProbe( probedata_t *p_data )
111 {
112     input_thread_t * p_input = (input_thread_t *)p_data;
113
114     char * psz_name = p_input->p_source;
115     int i_handle;
116     int i_score = 10;
117
118     if( TestMethod( INPUT_METHOD_VAR, "ps" ) )
119     {
120         return( 999 );
121     }
122
123     if( ( strlen(psz_name) > 5 ) && !strncasecmp( psz_name, "file:", 5 ) )
124     {
125         /* If the user specified "file:" then it's probably a file */
126         i_score = 100;
127         psz_name += 5;
128     }
129
130     i_handle = open( psz_name, 0 );
131     if( i_handle == -1 )
132     {
133         return( 0 );
134     }
135     close( i_handle );
136
137     return( i_score );
138 }
139
140 /*****************************************************************************
141  * PSInit: initializes PS structures
142  *****************************************************************************/
143 static void PSInit( input_thread_t * p_input )
144 {
145     thread_ps_data_t *  p_method;
146     packet_cache_t *    p_packet_cache;
147
148     if( (p_method =
149          (thread_ps_data_t *)malloc( sizeof(thread_ps_data_t) )) == NULL )
150     {
151         intf_ErrMsg( "Out of memory" );
152         p_input->b_error = 1;
153         return;
154     }
155     p_input->p_plugin_data = (void *)p_method;
156     
157     /* creates the packet cache structure */
158     p_packet_cache = malloc( sizeof(packet_cache_t) );
159     if ( p_packet_cache == NULL )
160     {
161         intf_ErrMsg( "Out of memory" );
162         p_input->b_error = 1;
163         return;
164     }
165     p_input->p_method_data = (void *)p_packet_cache;
166     
167     /* allocates the data cache */
168     p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE * 
169         sizeof(data_packet_t*) );
170     if ( p_packet_cache->data.p_stack == NULL )
171     {
172         intf_ErrMsg( "Out of memory" );
173         p_input->b_error = 1;
174         return;
175     }
176     p_packet_cache->data.l_index = 0;
177     
178     /* allocates the PES cache */
179     p_packet_cache->pes.p_stack = malloc( PES_CACHE_SIZE * 
180         sizeof(pes_packet_t*) );
181     if ( p_packet_cache->pes.p_stack == NULL )
182     {
183         intf_ErrMsg( "Out of memory" );
184         p_input->b_error = 1;
185         return;
186     }
187     p_packet_cache->pes.l_index = 0;
188     
189     /* allocates the small buffer cache */
190     p_packet_cache->small.p_stack = malloc( SMALL_CACHE_SIZE * 
191         sizeof(packet_buffer_t) );
192     if ( p_packet_cache->small.p_stack == NULL )
193     {
194         intf_ErrMsg( "Out of memory" );
195         p_input->b_error = 1;
196         return;
197     }
198     p_packet_cache->small.l_index = 0;
199     
200     /* allocates the large buffer cache */
201     p_packet_cache->large.p_stack = malloc( LARGE_CACHE_SIZE * 
202         sizeof(packet_buffer_t) );
203     if ( p_packet_cache->large.p_stack == NULL )
204     {
205         intf_ErrMsg( "Out of memory" );
206         p_input->b_error = 1;
207         return;
208     }
209     p_packet_cache->large.l_index = 0;
210     
211     /* Re-open the socket as a buffered FILE stream */
212     if( (p_method->stream = fdopen( p_input->i_handle, "r" )) == NULL )
213     {
214         intf_ErrMsg( "Cannot open file (%s)", strerror(errno) );
215         p_input->b_error = 1;
216         return;
217     }
218     rewind( p_method->stream );
219
220     /* FIXME : detect if InitStream failed */
221     input_InitStream( p_input, sizeof( stream_ps_data_t ) );
222     input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
223
224     if( p_input->stream.b_seekable )
225     {
226         stream_ps_data_t * p_demux_data =
227              (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
228
229         /* Pre-parse the stream to gather stream_descriptor_t. */
230         p_input->stream.pp_programs[0]->b_is_ok = 0;
231         p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
232
233         while( !p_input->b_die && !p_input->b_error
234                 && !p_demux_data->b_has_PSM )
235         {
236             int                 i_result, i;
237             data_packet_t *     pp_packets[INPUT_READ_ONCE];
238
239             i_result = PSRead( p_input, pp_packets );
240             if( i_result == 1 )
241             {
242                 /* EOF */
243                 vlc_mutex_lock( &p_input->stream.stream_lock );
244                 p_input->stream.pp_programs[0]->b_is_ok = 1;
245                 vlc_mutex_unlock( &p_input->stream.stream_lock );
246                 break;
247             }
248             if( i_result == -1 )
249             {
250                 p_input->b_error = 1;
251                 break;
252             }
253
254             for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
255             {
256                 /* FIXME: use i_p_config_t */
257                 input_ParsePS( p_input, pp_packets[i] );
258                 DeletePacket( p_input->p_method_data, pp_packets[i] );
259             }
260
261             /* File too big. */
262             if( p_input->stream.p_selected_area->i_tell >
263                                                     INPUT_PREPARSE_LENGTH )
264             {
265                 break;
266             }
267         }
268         rewind( p_method->stream );
269         vlc_mutex_lock( &p_input->stream.stream_lock );
270
271         p_input->stream.i_method = INPUT_METHOD_FILE;
272         p_input->stream.p_selected_area->i_tell = 0;
273
274         if( p_demux_data->b_has_PSM )
275         {
276             /* (The PSM decoder will care about spawning the decoders) */
277             p_input->stream.pp_programs[0]->b_is_ok = 1;
278         }
279 #ifdef AUTO_SPAWN
280         else
281         {
282             /* (We have to do it ourselves) */
283             int                 i_es;
284
285             /* FIXME: we should do multiple passes in case an audio type
286              * is not present */
287             for( i_es = 0;
288                  i_es < p_input->stream.pp_programs[0]->i_es_number;
289                  i_es++ )
290             {
291 #define p_es p_input->stream.pp_programs[0]->pp_es[i_es]
292                 switch( p_es->i_type )
293                 {
294                     case MPEG1_VIDEO_ES:
295                     case MPEG2_VIDEO_ES:
296                         input_SelectES( p_input, p_es );
297                         break;
298
299                     case MPEG1_AUDIO_ES:
300                     case MPEG2_AUDIO_ES:
301                         if( main_GetIntVariable( INPUT_CHANNEL_VAR, 0 )
302                                 == (p_es->i_id & 0x1F) )
303                         switch( main_GetIntVariable( INPUT_AUDIO_VAR, 0 ) )
304                         {
305                         case 0:
306                             main_PutIntVariable( INPUT_AUDIO_VAR,
307                                                  REQUESTED_MPEG );
308                         case REQUESTED_MPEG:
309                             input_SelectES( p_input, p_es );
310                         }
311                         break;
312
313                     case AC3_AUDIO_ES:
314                         if( main_GetIntVariable( INPUT_CHANNEL_VAR, 0 )
315                                 == ((p_es->i_id & 0xF00) >> 8) )
316                         switch( main_GetIntVariable( INPUT_AUDIO_VAR, 0 ) )
317                         {
318                         case 0:
319                             main_PutIntVariable( INPUT_AUDIO_VAR,
320                                                  REQUESTED_AC3 );
321                         case REQUESTED_AC3:
322                             input_SelectES( p_input, p_es );
323                         }
324                         break;
325
326                     case DVD_SPU_ES:
327                         if( main_GetIntVariable( INPUT_SUBTITLE_VAR, -1 )
328                                 == ((p_es->i_id & 0x1F00) >> 8) )
329                         {
330                             input_SelectES( p_input, p_es );
331                         }
332                         break;
333
334                     case LPCM_AUDIO_ES:
335                         /* FIXME ! */
336                         break;
337                 }
338             }
339                     
340         }
341 #endif
342 #ifdef STATS
343         input_DumpStream( p_input );
344 #endif
345         vlc_mutex_unlock( &p_input->stream.stream_lock );
346     }
347     else
348     {
349         /* The programs will be added when we read them. */
350         vlc_mutex_lock( &p_input->stream.stream_lock );
351         p_input->stream.i_method = INPUT_METHOD_FILE;
352         p_input->stream.pp_programs[0]->b_is_ok = 0;
353         vlc_mutex_unlock( &p_input->stream.stream_lock );
354     }
355 }
356
357 /*****************************************************************************
358  * PSEnd: frees unused data
359  *****************************************************************************/
360 static void PSEnd( input_thread_t * p_input )
361 {
362     free( p_input->p_plugin_data );
363 }
364
365 /*****************************************************************************
366  * SafeRead: reads a chunk of stream and correctly detects errors
367  *****************************************************************************/
368 static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
369                                 size_t i_len )
370 {
371     thread_ps_data_t *  p_method;
372     int                 i_error;
373
374     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
375     while( fread( p_buffer, i_len, 1, p_method->stream ) != 1 )
376     {
377         if( feof( p_method->stream ) )
378         {
379             return( 1 );
380         }
381
382         if( (i_error = ferror( p_method->stream )) )
383         {
384             intf_ErrMsg( "Read failed (%s)", strerror(i_error) );
385             return( -1 );
386         }
387     }
388     vlc_mutex_lock( &p_input->stream.stream_lock );
389     p_input->stream.p_selected_area->i_tell += i_len;
390     vlc_mutex_unlock( &p_input->stream.stream_lock );
391     return( 0 );
392 }
393
394 /*****************************************************************************
395  * PSRead: reads data packets
396  *****************************************************************************
397  * Returns -1 in case of error, 0 if everything went well, and 1 in case of
398  * EOF.
399  *****************************************************************************/
400 static int PSRead( input_thread_t * p_input,
401                    data_packet_t * pp_packets[INPUT_READ_ONCE] )
402 {
403     byte_t              p_header[6];
404     data_packet_t *     p_data;
405     size_t              i_packet_size;
406     int                 i_packet, i_error;
407     thread_ps_data_t *  p_method;
408
409     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
410
411     memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
412     for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
413     {
414         /* Read what we believe to be a packet header. */
415         if( (i_error = SafeRead( p_input, p_header, 6 )) )
416         {
417             return( i_error );
418         }
419
420         if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
421         {
422             /* This is not the startcode of a packet. Read the stream
423              * until we find one. */
424             u32         i_startcode = U32_AT(p_header);
425             int         i_dummy;
426
427             if( i_startcode )
428             {
429                 /* It is common for MPEG-1 streams to pad with zeros
430                  * (although it is forbidden by the recommendation), so
431                  * don't bother everybody in this case. */
432                 intf_WarnMsg( 1, "Garbage at input (%.8x)", i_startcode );
433             }
434
435             while( (i_startcode & 0xFFFFFF00) != 0x100L )
436             {
437                 i_startcode <<= 8;
438                 if( (i_dummy = getc( p_method->stream )) != EOF )
439                 {
440                     i_startcode |= i_dummy;
441                 }
442                 else
443                 {
444                     return( 1 );
445                 }
446             }
447             /* Packet found. */
448             *(u32 *)p_header = U32_AT(&i_startcode);
449             if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
450             {
451                 return( i_error );
452             }
453         }
454
455         if( U32_AT(p_header) != 0x1BA )
456         {
457             /* That's the case for all packets, except pack header. */
458             i_packet_size = U16_AT(&p_header[4]);
459         }
460         else
461         {
462             /* Pack header. */
463             if( (p_header[4] & 0xC0) == 0x40 )
464             {
465                 /* MPEG-2 */
466                 i_packet_size = 8;
467             }
468             else if( (p_header[4] & 0xF0) == 0x20 )
469             {
470                 /* MPEG-1 */
471                 i_packet_size = 6;
472             }
473             else
474             {
475                 intf_ErrMsg( "Unable to determine stream type" );
476                 return( -1 );
477             }
478         }
479
480         /* Fetch a packet of the appropriate size. */
481         if( (p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 )) 
482             == NULL )
483         {
484             intf_ErrMsg( "Out of memory" );
485             return( -1 );
486         }
487
488         /* Copy the header we already read. */
489         memcpy( p_data->p_buffer, p_header, 6 );
490
491         /* Read the remaining of the packet. */
492         if( i_packet_size && (i_error =
493                 SafeRead( p_input, p_data->p_buffer + 6, i_packet_size )) )
494         {
495             return( i_error );
496         }
497
498         /* In MPEG-2 pack headers we still have to read stuffing bytes. */
499         if( U32_AT(p_header) == 0x1BA )
500         {
501             if( i_packet_size == 8 && (p_data->p_buffer[13] & 0x7) != 0 )
502             {
503                 /* MPEG-2 stuffing bytes */
504                 byte_t      p_garbage[8];
505                 if( (i_error = SafeRead( p_input, p_garbage,
506                                          p_data->p_buffer[13] & 0x7)) )
507                 {
508                     return( i_error );
509                 }
510             }
511         }
512
513         /* Give the packet to the other input stages. */
514         pp_packets[i_packet] = p_data;
515     }
516
517     return( 0 );
518 }
519
520 /*****************************************************************************
521  * PSSeek: changes the stream position indicator
522  *****************************************************************************/
523 static void PSSeek( input_thread_t * p_input, off_t i_position )
524 {
525     thread_ps_data_t *  p_method;
526
527     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
528
529     /* A little bourrin but should work for a while --Meuuh */
530     fseeko( p_method->stream, i_position, SEEK_SET );
531
532     p_input->stream.p_selected_area->i_tell = i_position;
533 }
534
535 /*
536  * Packet management utilities
537  */
538
539
540 /*****************************************************************************
541  * NewPacket: allocates a data packet
542  *****************************************************************************/
543 static struct data_packet_s * NewPacket( void * p_packet_cache,
544                                          size_t l_size )
545
546     packet_cache_t *   p_cache;
547     data_packet_t *    p_data;
548     long               l_index;
549
550     p_cache = (packet_cache_t *)p_packet_cache;
551
552 #ifdef DEBUG
553     if ( p_cache == NULL )
554     {
555         intf_ErrMsg( "PPacket cache not initialized" );
556         return NULL;
557     }
558 #endif
559
560     /* Safety check */
561     if( l_size > INPUT_MAX_PACKET_SIZE )
562     {
563         intf_ErrMsg( "Packet too big (%d)", l_size );
564         return NULL;
565     }
566
567     /* Checks whether the data cache is empty */
568     if( p_cache->data.l_index == 0 )
569     {
570         /* Allocates a new packet */
571         if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL )
572         {
573             intf_ErrMsg( "Out of memory" );
574             return NULL;
575         }
576 #ifdef TRACE_INPUT
577         intf_DbgMsg( "PS input: data packet allocated" );
578 #endif
579     }
580     else
581     {
582         /* Takes the packet out from the cache */
583         if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ]) 
584             == NULL )
585         {
586             intf_ErrMsg( "NULL packet in the data cache" );
587             return NULL;
588         }
589     }
590     
591     if( l_size < MAX_SMALL_SIZE )
592     {
593         /* Small buffer */  
594    
595         /* Checks whether the buffer cache is empty */
596         if( p_cache->small.l_index == 0 )
597         {
598             /* Allocates a new packet */
599             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
600             {
601                 intf_DbgMsg( "Out of memory" );
602                 free( p_data );
603                 return NULL;
604             }
605 #ifdef TRACE_INPUT
606             intf_DbgMsg( "PS input: small buffer allocated" );
607 #endif
608             p_data->l_size = l_size;
609         }
610         else
611         {
612             /* Takes the packet out from the cache */
613             l_index = -- p_cache->small.l_index;    
614             if( (p_data->p_buffer = p_cache->small.p_stack[l_index].p_data)
615                 == NULL )
616             {
617                 intf_ErrMsg( "NULL packet in the small buffer cache" );
618                 free( p_data );
619                 return NULL;
620             }
621                 /* Reallocates the packet if it is too small or too large */
622             if( p_cache->small.p_stack[l_index].l_size < l_size ||
623                 p_cache->small.p_stack[l_index].l_size > 2*l_size )
624             {
625                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
626                 p_data->l_size = l_size;
627             }
628             else
629             {
630                 p_data->l_size = p_cache->small.p_stack[l_index].l_size;
631             }
632         }
633     }
634     else
635     {
636         /* Large buffer */  
637    
638         /* Checks whether the buffer cache is empty */
639         if( p_cache->large.l_index == 0 )
640         {
641             /* Allocates a new packet */
642             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
643             {
644                 intf_ErrMsg( "Out of memory" );
645                 free( p_data );
646                 return NULL;
647             }
648 #ifdef TRACE_INPUT
649             intf_DbgMsg( "PS input: large buffer allocated" );
650 #endif
651             p_data->l_size = l_size;
652         }
653         else
654         {
655             /* Takes the packet out from the cache */
656             l_index = -- p_cache->large.l_index;    
657             if( (p_data->p_buffer = p_cache->large.p_stack[l_index].p_data)
658                 == NULL )
659             {
660                 intf_ErrMsg( "NULL packet in the small buffer cache" );
661                 free( p_data );
662                 return NULL;
663             }
664                 /* Reallocates the packet if it is too small or too large */
665             if( p_cache->large.p_stack[l_index].l_size < l_size ||
666                 p_cache->large.p_stack[l_index].l_size > 2*l_size )
667             {
668                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
669                 p_data->l_size = l_size;
670             }
671             else
672             {
673                 p_data->l_size = p_cache->large.p_stack[l_index].l_size;
674             }
675             }
676     }
677
678     /* Initialize data */
679     p_data->p_next = NULL;
680     p_data->b_discard_payload = 0;
681     p_data->p_payload_start = p_data->p_buffer;
682     p_data->p_payload_end = p_data->p_buffer + l_size;
683
684     return( p_data );
685         
686 }
687
688
689 /*****************************************************************************
690  * NewPES: allocates a pes packet
691  *****************************************************************************/
692 static pes_packet_t * NewPES( void * p_packet_cache )
693 {
694     packet_cache_t *   p_cache;
695     pes_packet_t *     p_pes;
696
697     p_cache = (packet_cache_t *)p_packet_cache;
698
699 #ifdef DEBUG
700     if ( p_cache == NULL )
701     {
702         intf_ErrMsg( "Packet cache not initialized" );
703         return NULL;
704     }
705 #endif
706
707     /* Checks whether the PES cache is empty */
708     if( p_cache->pes.l_index == 0 )
709     {
710         /* Allocates a new packet */
711         if ( (p_pes = malloc( sizeof(pes_packet_t) )) == NULL )
712         {
713             intf_DbgMsg( "Out of memory" );
714             return NULL;
715         }
716 #ifdef TRACE_INPUT
717         intf_DbgMsg( "PS input: PES packet allocated" );
718 #endif
719     }
720     else
721     {
722         /* Takes the packet out from the cache */
723         if( (p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ]) 
724             == NULL )
725         {
726             intf_ErrMsg( "NULL packet in the data cache" );
727             return NULL;
728         }
729     }
730         
731     p_pes->b_data_alignment = p_pes->b_discontinuity =
732         p_pes->i_pts = p_pes->i_dts = 0;
733     p_pes->i_pes_size = 0;
734     p_pes->p_first = NULL;
735
736     return( p_pes );
737     
738 }
739
740 /*****************************************************************************
741  * DeletePacket: deletes a data packet
742  *****************************************************************************/
743 static void DeletePacket( void * p_packet_cache,
744                           data_packet_t * p_data )
745 {
746     packet_cache_t *   p_cache;
747
748     p_cache = (packet_cache_t *)p_packet_cache;
749
750 #ifdef DEBUG
751     if ( p_cache == NULL )
752     {
753         intf_ErrMsg( "Packet cache not initialized" );
754         return;
755     }
756 #endif
757
758         ASSERT( p_data );
759
760     /* Checks whether the data cache is full */
761     if ( p_cache->data.l_index < DATA_CACHE_SIZE )
762     {
763         /* Cache not full: store the packet in it */
764         p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data;
765         /* Small buffer or large buffer? */
766         if ( p_data->l_size < MAX_SMALL_SIZE )
767         {
768             /* Checks whether the small buffer cache is full */
769             if ( p_cache->small.l_index < SMALL_CACHE_SIZE )
770             {
771                 p_cache->small.p_stack[ p_cache->small.l_index ].l_size = 
772                     p_data->l_size;
773                 p_cache->small.p_stack[ p_cache->small.l_index ++ ].p_data = 
774                     p_data->p_buffer;
775             }
776             else
777             {
778                 ASSERT( p_data->p_buffer );
779                 free( p_data->p_buffer );
780 #ifdef TRACE_INPUT
781                 intf_DbgMsg( "PS input: small buffer freed" );
782 #endif
783             }
784         }
785         else
786         {
787             /* Checks whether the large buffer cache is full */
788             if ( p_cache->large.l_index < LARGE_CACHE_SIZE )
789             {
790                 p_cache->large.p_stack[ p_cache->large.l_index ].l_size = 
791                     p_data->l_size;
792                 p_cache->large.p_stack[ p_cache->large.l_index ++ ].p_data = 
793                     p_data->p_buffer;
794             }
795             else
796             {
797                 ASSERT( p_data->p_buffer );
798                 free( p_data->p_buffer );
799 #ifdef TRACE_INPUT
800                 intf_DbgMsg( "PS input: large buffer freed" );
801 #endif
802             }
803         }
804     }
805     else
806     {
807         /* Cache full: the packet must be freed */
808         free( p_data->p_buffer );
809         free( p_data );
810 #ifdef TRACE_INPUT
811         intf_DbgMsg( "PS input: data packet freed" );
812 #endif
813     }
814
815 }
816
817 /*****************************************************************************
818  * DeletePES: deletes a PES packet and associated data packets
819  *****************************************************************************/
820 static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
821 {
822     packet_cache_t *    p_cache;
823     data_packet_t *     p_data;
824     data_packet_t *     p_next;
825
826     p_cache = (packet_cache_t *)p_packet_cache;
827
828 #ifdef DEBUG
829     if ( p_cache == NULL )
830     {
831         intf_ErrMsg( "Packet cache not initialized" );
832         return;
833     }
834 #endif
835
836     ASSERT( p_pes);
837
838     p_data = p_pes->p_first;
839
840     while( p_data != NULL )
841     {
842         p_next = p_data->p_next;
843         DeletePacket( p_cache, p_data );
844         p_data = p_next;
845     }
846
847     /* Checks whether the PES cache is full */
848     if ( p_cache->pes.l_index < PES_CACHE_SIZE )
849     {
850         /* Cache not full: store the packet in it */
851         p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
852     }
853     else
854     {
855         /* Cache full: the packet must be freed */
856         free( p_pes );
857 #ifdef TRACE_INPUT
858         intf_DbgMsg( "PS input: PES packet freed" );
859 #endif
860     }
861 }
862