]> git.sesse.net Git - vlc/blob - plugins/mpeg/input_ps.c
-corrected some bugs in gnome interface: language menu are now
[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.16 2001/04/20 05:40:03 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.pp_programs[0]->b_is_ok = 0;
352         vlc_mutex_unlock( &p_input->stream.stream_lock );
353     }
354 }
355
356 /*****************************************************************************
357  * PSEnd: frees unused data
358  *****************************************************************************/
359 static void PSEnd( input_thread_t * p_input )
360 {
361     free( p_input->p_plugin_data );
362 }
363
364 /*****************************************************************************
365  * SafeRead: reads a chunk of stream and correctly detects errors
366  *****************************************************************************/
367 static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
368                                 size_t i_len )
369 {
370     thread_ps_data_t *  p_method;
371     int                 i_error;
372
373     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
374     while( fread( p_buffer, i_len, 1, p_method->stream ) != 1 )
375     {
376         if( feof( p_method->stream ) )
377         {
378             return( 1 );
379         }
380
381         if( (i_error = ferror( p_method->stream )) )
382         {
383             intf_ErrMsg( "Read failed (%s)", strerror(i_error) );
384             return( -1 );
385         }
386     }
387     vlc_mutex_lock( &p_input->stream.stream_lock );
388     p_input->stream.p_selected_area->i_tell += i_len;
389     vlc_mutex_unlock( &p_input->stream.stream_lock );
390     return( 0 );
391 }
392
393 /*****************************************************************************
394  * PSRead: reads data packets
395  *****************************************************************************
396  * Returns -1 in case of error, 0 if everything went well, and 1 in case of
397  * EOF.
398  *****************************************************************************/
399 static int PSRead( input_thread_t * p_input,
400                    data_packet_t * pp_packets[INPUT_READ_ONCE] )
401 {
402     byte_t              p_header[6];
403     data_packet_t *     p_data;
404     size_t              i_packet_size;
405     int                 i_packet, i_error;
406     thread_ps_data_t *  p_method;
407
408     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
409
410     memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
411     for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
412     {
413         /* Read what we believe to be a packet header. */
414         if( (i_error = SafeRead( p_input, p_header, 6 )) )
415         {
416             return( i_error );
417         }
418
419         if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
420         {
421             /* This is not the startcode of a packet. Read the stream
422              * until we find one. */
423             u32         i_startcode = U32_AT(p_header);
424             int         i_dummy;
425
426             if( i_startcode )
427             {
428                 /* It is common for MPEG-1 streams to pad with zeros
429                  * (although it is forbidden by the recommendation), so
430                  * don't bother everybody in this case. */
431                 intf_WarnMsg( 1, "Garbage at input (%.8x)", i_startcode );
432             }
433
434             while( (i_startcode & 0xFFFFFF00) != 0x100L )
435             {
436                 i_startcode <<= 8;
437                 if( (i_dummy = getc( p_method->stream )) != EOF )
438                 {
439                     i_startcode |= i_dummy;
440                 }
441                 else
442                 {
443                     return( 1 );
444                 }
445             }
446             /* Packet found. */
447             *(u32 *)p_header = U32_AT(&i_startcode);
448             if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
449             {
450                 return( i_error );
451             }
452         }
453
454         if( U32_AT(p_header) != 0x1BA )
455         {
456             /* That's the case for all packets, except pack header. */
457             i_packet_size = U16_AT(&p_header[4]);
458         }
459         else
460         {
461             /* Pack header. */
462             if( (p_header[4] & 0xC0) == 0x40 )
463             {
464                 /* MPEG-2 */
465                 i_packet_size = 8;
466             }
467             else if( (p_header[4] & 0xF0) == 0x20 )
468             {
469                 /* MPEG-1 */
470                 i_packet_size = 6;
471             }
472             else
473             {
474                 intf_ErrMsg( "Unable to determine stream type" );
475                 return( -1 );
476             }
477         }
478
479         /* Fetch a packet of the appropriate size. */
480         if( (p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 )) 
481             == NULL )
482         {
483             intf_ErrMsg( "Out of memory" );
484             return( -1 );
485         }
486
487         /* Copy the header we already read. */
488         memcpy( p_data->p_buffer, p_header, 6 );
489
490         /* Read the remaining of the packet. */
491         if( i_packet_size && (i_error =
492                 SafeRead( p_input, p_data->p_buffer + 6, i_packet_size )) )
493         {
494             return( i_error );
495         }
496
497         /* In MPEG-2 pack headers we still have to read stuffing bytes. */
498         if( U32_AT(p_header) == 0x1BA )
499         {
500             if( i_packet_size == 8 && (p_data->p_buffer[13] & 0x7) != 0 )
501             {
502                 /* MPEG-2 stuffing bytes */
503                 byte_t      p_garbage[8];
504                 if( (i_error = SafeRead( p_input, p_garbage,
505                                          p_data->p_buffer[13] & 0x7)) )
506                 {
507                     return( i_error );
508                 }
509             }
510         }
511
512         /* Give the packet to the other input stages. */
513         pp_packets[i_packet] = p_data;
514     }
515
516     return( 0 );
517 }
518
519 /*****************************************************************************
520  * PSSeek: changes the stream position indicator
521  *****************************************************************************/
522 static void PSSeek( input_thread_t * p_input, off_t i_position )
523 {
524     thread_ps_data_t *  p_method;
525
526     p_method = (thread_ps_data_t *)p_input->p_plugin_data;
527
528     /* A little bourrin but should work for a while --Meuuh */
529     fseeko( p_method->stream, i_position, SEEK_SET );
530
531     p_input->stream.p_selected_area->i_tell = i_position;
532 }
533
534 /*
535  * Packet management utilities
536  */
537
538
539 /*****************************************************************************
540  * NewPacket: allocates a data packet
541  *****************************************************************************/
542 static struct data_packet_s * NewPacket( void * p_packet_cache,
543                                          size_t l_size )
544
545     packet_cache_t *   p_cache;
546     data_packet_t *    p_data;
547     long               l_index;
548
549     if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
550     {
551         intf_ErrMsg( "PPacket cache not initialized" );
552         return NULL;
553     }
554     /* Safety check */
555     if( l_size > INPUT_MAX_PACKET_SIZE )
556     {
557         intf_ErrMsg( "Packet too big (%d)", l_size );
558         return NULL;
559     }
560
561     /* Checks whether the data cache is empty */
562     if( p_cache->data.l_index == 0 )
563     {
564         /* Allocates a new packet */
565         if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL )
566         {
567             intf_DbgMsg( "Out of memory" );
568             return NULL;
569         }
570         intf_WarnMsg( 1, "PS input: data packet allocated" );
571     }
572     else
573     {
574         /* Takes the packet out from the cache */
575         if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ]) 
576             == NULL )
577         {
578             intf_DbgMsg( "NULL packet in the data cache" );
579             return NULL;
580         }
581     }
582     
583     if( l_size < MAX_SMALL_SIZE )
584     {
585         /* Small buffer */  
586    
587         /* Checks whether the buffer cache is empty */
588         if( p_cache->small.l_index == 0 )
589         {
590             /* Allocates a new packet */
591             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
592             {
593                 intf_DbgMsg( "Out of memory" );
594                 free( p_data );
595                 return NULL;
596             }
597             intf_WarnMsg( 1, "PS input: small buffer allocated" );
598             p_data->l_size = l_size;
599         }
600         else
601         {
602             /* Takes the packet out from the cache */
603             l_index = -- p_cache->small.l_index;    
604             if( (p_data->p_buffer = p_cache->small.p_stack[l_index].p_data)
605                 == NULL )
606             {
607                 intf_DbgMsg( "NULL packet in the small buffer cache" );
608                 free( p_data );
609                 return NULL;
610             }
611                 /* Reallocates the packet if it is too small or too large */
612             if( p_cache->small.p_stack[l_index].l_size < l_size ||
613                 p_cache->small.p_stack[l_index].l_size > 2*l_size )
614             {
615                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
616                 p_data->l_size = l_size;
617             }
618             else
619             {
620                 p_data->l_size = p_cache->small.p_stack[l_index].l_size;
621             }
622         }
623     }
624     else
625     {
626         /* Large buffer */  
627    
628         /* Checks whether the buffer cache is empty */
629         if( p_cache->large.l_index == 0 )
630         {
631             /* Allocates a new packet */
632             if ( (p_data->p_buffer = malloc( l_size )) == NULL )
633             {
634                 intf_DbgMsg( "Out of memory" );
635                 free( p_data );
636                 return NULL;
637             }
638             intf_WarnMsg( 1, "PS input: large buffer allocated" );
639             p_data->l_size = l_size;
640         }
641         else
642         {
643             /* Takes the packet out from the cache */
644             l_index = -- p_cache->large.l_index;    
645             if( (p_data->p_buffer = p_cache->large.p_stack[l_index].p_data)
646                 == NULL )
647             {
648                 intf_DbgMsg( "NULL packet in the small buffer cache" );
649                 free( p_data );
650                 return NULL;
651             }
652                 /* Reallocates the packet if it is too small or too large */
653             if( p_cache->large.p_stack[l_index].l_size < l_size ||
654                 p_cache->large.p_stack[l_index].l_size > 2*l_size )
655             {
656                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
657                 p_data->l_size = l_size;
658             }
659             else
660             {
661                 p_data->l_size = p_cache->large.p_stack[l_index].l_size;
662             }
663             }
664     }
665
666     /* Initialize data */
667     p_data->p_next = NULL;
668     p_data->b_discard_payload = 0;
669     p_data->p_payload_start = p_data->p_buffer;
670     p_data->p_payload_end = p_data->p_buffer + l_size;
671
672     return( p_data );
673         
674 }
675
676
677 /*****************************************************************************
678  * NewPES: allocates a pes packet
679  *****************************************************************************/
680 static pes_packet_t * NewPES( void * p_packet_cache )
681 {
682     packet_cache_t *   p_cache;
683     pes_packet_t *     p_pes;
684
685     if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
686     {
687         intf_ErrMsg( "Packet cache not initialized" );
688         return NULL;
689     }
690     /* Checks whether the PES cache is empty */
691     if( p_cache->pes.l_index == 0 )
692     {
693         /* Allocates a new packet */
694         if ( (p_pes = malloc( sizeof(pes_packet_t) )) == NULL )
695         {
696             intf_DbgMsg( "Out of memory" );
697             return NULL;
698         }
699         intf_WarnMsg( 1, "PS input: PES packet allocated" );
700     }
701     else
702     {
703         /* Takes the packet out from the cache */
704         if( (p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ]) 
705             == NULL )
706         {
707             intf_DbgMsg( "NULL packet in the data cache" );
708             return NULL;
709         }
710     }
711         
712     p_pes->b_data_alignment = p_pes->b_discontinuity =
713         p_pes->i_pts = p_pes->i_dts = 0;
714     p_pes->i_pes_size = 0;
715     p_pes->p_first = NULL;
716
717     return( p_pes );
718     
719 }
720
721 /*****************************************************************************
722  * DeletePacket: deletes a data packet
723  *****************************************************************************/
724 static void DeletePacket( void * p_packet_cache,
725                           data_packet_t * p_data )
726 {
727     packet_cache_t *   p_cache;
728         
729     if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
730     {
731         intf_ErrMsg( "Packet cache not initialized" );
732         return;
733     }
734
735         ASSERT( p_data );
736
737     /* Checks whether the data cache is full */
738     if ( p_cache->data.l_index < DATA_CACHE_SIZE )
739     {
740         /* Cache not full: store the packet in it */
741         p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data;
742         /* Small buffer or large buffer? */
743         if ( p_data->l_size < MAX_SMALL_SIZE )
744         {
745             /* Checks whether the small buffer cache is full */
746             if ( p_cache->small.l_index < SMALL_CACHE_SIZE )
747             {
748                 p_cache->small.p_stack[ p_cache->small.l_index ].l_size = 
749                     p_data->l_size;
750                 p_cache->small.p_stack[ p_cache->small.l_index ++ ].p_data = 
751                     p_data->p_buffer;
752             }
753             else
754             {
755                 ASSERT( p_data->p_buffer );
756                 free( p_data->p_buffer );
757                 intf_WarnMsg( 1, "PS input: small buffer freed" );
758             }
759         }
760         else
761         {
762             /* Checks whether the large buffer cache is full */
763             if ( p_cache->large.l_index < LARGE_CACHE_SIZE )
764             {
765                 p_cache->large.p_stack[ p_cache->large.l_index ].l_size = 
766                     p_data->l_size;
767                 p_cache->large.p_stack[ p_cache->large.l_index ++ ].p_data = 
768                     p_data->p_buffer;
769             }
770             else
771             {
772                 ASSERT( p_data->p_buffer );
773                 free( p_data->p_buffer );
774                 intf_WarnMsg( 1, "PS input: large buffer freed" );
775             }
776         }
777     }
778     else
779     {
780         /* Cache full: the packet must be freed */
781         free( p_data->p_buffer );
782         free( p_data );
783         intf_WarnMsg( 1, "PS input: data packet freed" );
784     }
785
786 }
787
788 /*****************************************************************************
789  * DeletePES: deletes a PES packet and associated data packets
790  *****************************************************************************/
791 static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
792 {
793     packet_cache_t *    p_cache;
794     data_packet_t *     p_data;
795     data_packet_t *     p_next;
796
797     if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
798     {
799         intf_ErrMsg( "Packet cache not initialized" );
800         return;
801     }
802
803     ASSERT( p_pes);
804
805     p_data = p_pes->p_first;
806
807     while( p_data != NULL )
808     {
809         p_next = p_data->p_next;
810         DeletePacket( p_cache, p_data );
811         p_data = p_next;
812     }
813
814     /* Checks whether the PES cache is full */
815     if ( p_cache->pes.l_index < PES_CACHE_SIZE )
816     {
817         /* Cache not full: store the packet in it */
818         p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
819     }
820     else
821     {
822         /* Cache full: the packet must be freed */
823         free( p_pes );
824         intf_WarnMsg( 1, "PS input: PES packet freed" );
825     }
826 }
827