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