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