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