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