]> git.sesse.net Git - vlc/blob - plugins/vcd/input_vcd.c
* Added error checking in pthread wrapper ; as a result, intf_msg.h must
[vlc] / plugins / vcd / input_vcd.c
1 /****************************************************************************
2  * input_vcd.c: VideoCD raw reading plugin.
3  *****************************************************************************
4  * Copyright (C) 1998-2001 VideoLAN
5  *
6  * Author: Johan Bilien <jobi@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #define MODULE_NAME vcd
24 #include "modules_inner.h"
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include "defs.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #ifdef HAVE_UNISTD_H
35 #   include <unistd.h>
36 #endif
37
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <string.h>
41 #include <errno.h>
42
43 #ifdef STRNCASECMP_IN_STRINGS_H
44 #   include <strings.h>
45 #endif
46
47 #if defined( WIN32 )
48 #   include <io.h>                                                 /* read() */
49 #else
50 #   include <sys/uio.h>                                      /* struct iovec */
51 #endif
52
53
54 #include "config.h"
55 #include "common.h"
56 #include "intf_msg.h"
57 #include "threads.h"
58 #include "mtime.h"
59 #include "tests.h"
60
61 #if defined( WIN32 )
62 #   include "input_iovec.h"
63 #endif
64
65 #include "main.h"
66
67 #include "stream_control.h"
68 #include "input_ext-intf.h"
69 #include "input_ext-dec.h"
70 #include "input_ext-plugins.h"
71
72 #include "debug.h"
73
74 #include "modules.h"
75 #include "modules_export.h"
76
77 #include "../mpeg/input_ps.h"
78 #include "input_vcd.h"
79 #include "linux_cdrom_tools.h"
80
81 /* how many blocks VCDRead will read in each loop */
82 #define VCD_BLOCKS_ONCE 64
83 #define VCD_DATA_ONCE  (2 * VCD_BLOCKS_ONCE)
84 #define BUFFER_SIZE VCD_DATA_SIZE
85
86
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91 /* called from outside */
92 static int  VCDProbe     ( probedata_t *p_data );
93 static void VCDInit      ( struct input_thread_s * );
94 static int  VCDRead      ( struct input_thread_s *, data_packet_t ** );
95 static int  VCDSetArea   ( struct input_thread_s *, struct input_area_s * ); 
96 static void VCDOpen      ( struct input_thread_s *);
97 static void VCDClose     ( struct input_thread_s *);
98 static void VCDEnd       ( struct input_thread_s *);
99 static void VCDSeek      ( struct input_thread_s *, off_t );
100 static int  VCDRewind    ( struct input_thread_s * );
101 static struct data_packet_s * NewPacket( void *, size_t );
102 static pes_packet_t *         NewPES   ( void * );
103 static void DeletePacket ( void *, data_packet_t * );
104 static void DeletePES    ( void *, pes_packet_t *);
105
106
107
108 /*****************************************************************************
109  * Functions exported as capabilities. They are declared as static so that
110  * we don't pollute the namespace too much.
111  *****************************************************************************/
112 void _M( input_getfunctions )( function_list_t * p_function_list )
113 {
114 #define input p_function_list->functions.input
115     p_function_list->pf_probe = VCDProbe ;
116     input.pf_init             = VCDInit ;
117     input.pf_open             = VCDOpen ;
118     input.pf_close            = VCDClose ;
119     input.pf_end              = VCDEnd ;
120     input.pf_init_bit_stream  = InitBitstream;
121     input.pf_read             = VCDRead ;
122     input.pf_set_area         = VCDSetArea ;
123     input.pf_demux            = input_DemuxPS;
124     input.pf_new_packet       = NewPacket;
125     input.pf_new_pes          = NewPES;
126     input.pf_delete_packet    = DeletePacket;
127     input.pf_delete_pes       = DeletePES;
128     input.pf_rewind           = VCDRewind ;
129     input.pf_seek             = VCDSeek ;
130 #undef input
131 }
132
133 /*
134  * Data reading functions
135  */
136
137 /*****************************************************************************
138  * VCDProbe: verifies that the stream is a PS stream
139  *****************************************************************************/
140 static int VCDProbe( probedata_t *p_data )
141 {
142     
143     input_thread_t * p_input = (input_thread_t *)p_data;
144
145     char * psz_name = p_input->p_source;
146     int i_score = 5;
147
148     if( TestMethod( INPUT_METHOD_VAR, "vcd" ) )
149     {
150         return( 999 );
151     }
152
153     if( ( strlen(psz_name) > 4 ) && !strncasecmp( psz_name, "vcd:", 4 ) )
154     {
155         /* If the user specified "vcd:" then it's probably a VCD */
156         i_score = 100;
157         psz_name += 4;
158     }
159     return( i_score );
160 }
161
162 /*****************************************************************************
163  * VCDOpen: open vcd
164  *****************************************************************************/
165 static void VCDOpen( struct input_thread_s *p_input )
166 {
167     int vcdhandle;
168
169     vlc_mutex_lock( &p_input->stream.stream_lock );
170
171     /* If we are here we can control the pace... */
172     p_input->stream.b_pace_control = 1;
173
174     p_input->stream.b_seekable = 1;
175     p_input->stream.p_selected_area->i_size = 0;
176
177     p_input->stream.p_selected_area->i_tell = 0;
178
179     vlc_mutex_unlock( &p_input->stream.stream_lock );
180     
181     
182     /* XXX: put this shit in an access plugin */
183     if( strlen( p_input->p_source ) > 4
184          && !strncasecmp( p_input->p_source, "vcd:", 4 ) )
185     {
186         vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
187     }
188     else
189     {
190         vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
191     }
192
193     if( vcdhandle == -1 )
194     {
195         p_input->b_error = 1;
196         return;
197     }
198
199     p_input->i_handle = (int) vcdhandle;
200 }
201
202 /*****************************************************************************
203  * VCDClose: close vcd
204  *****************************************************************************/
205 static void VCDClose( struct input_thread_s *p_input )
206 {
207     close( p_input->i_handle );
208 }
209
210 /*****************************************************************************
211  * VCDInit: initializes VCD structures
212  *****************************************************************************/
213 static void VCDInit( input_thread_t * p_input )
214 {
215     thread_vcd_data_t *  p_vcd;
216     int                  i_title;
217     int                  i_chapter;
218     int                  i;
219     input_area_t *       p_area;
220     es_descriptor_t *    p_es;
221     packet_cache_t *     p_packet_cache;
222     
223     p_vcd = malloc( sizeof(thread_vcd_data_t) );
224         
225     if( p_vcd == NULL )
226     {
227         intf_ErrMsg( "vcd error: out of memory" );
228         p_input->b_error = 1;
229         return;
230     }
231
232     
233     
234     p_input->p_plugin_data = (void *)p_vcd;
235     p_input->p_method_data = NULL;
236
237     p_vcd->vcdhandle = p_input->i_handle;
238     p_vcd->b_end_of_track = 0;
239
240     /* we read the Table Of Content information */
241     if ( read_toc(p_vcd) == -1 )
242     {
243         intf_ErrMsg("An error occured when reading vcd's TOC");
244     }
245     
246     p_input->i_read_once = VCD_DATA_ONCE;
247     
248     p_packet_cache = malloc( sizeof(packet_cache_t) );
249     
250     if ( p_packet_cache == NULL )
251     {
252         intf_ErrMsg( "vcd error: out of memory" );
253         p_input->b_error = 1;
254         return;
255     }
256     
257     p_input->p_method_data = (void *)p_packet_cache;
258      /* Initialize packet cache mutex */
259     vlc_mutex_init( &p_packet_cache->lock );
260     
261     /* allocates the data cache */
262     p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE * 
263         sizeof(data_packet_t*) );
264     if ( p_packet_cache->data.p_stack == NULL )
265     {
266         intf_ErrMsg( "Out of memory" );
267         p_input->b_error = 1;
268         return;
269     }
270     p_packet_cache->data.l_index = 0;
271     
272     /* allocates the PES cache */
273     p_packet_cache->pes.p_stack = malloc( PES_CACHE_SIZE * 
274         sizeof(pes_packet_t*) );
275     if ( p_packet_cache->pes.p_stack == NULL )
276     {
277         intf_ErrMsg( "Out of memory" );
278         p_input->b_error = 1;
279         return;
280     }
281     p_packet_cache->pes.l_index = 0;
282     
283     /* allocates the small buffer cache */
284     p_packet_cache->smallbuffer.p_stack = malloc( SMALL_CACHE_SIZE * 
285         sizeof(packet_buffer_t) );
286     if ( p_packet_cache->smallbuffer.p_stack == NULL )
287     {
288         intf_ErrMsg( "Out of memory" );
289         p_input->b_error = 1;
290         return;
291     }
292     p_packet_cache->smallbuffer.l_index = 0;
293     
294     /* allocates the large buffer cache */
295     p_packet_cache->largebuffer.p_stack = malloc( LARGE_CACHE_SIZE * 
296         sizeof(packet_buffer_t) );
297     if ( p_packet_cache->largebuffer.p_stack == NULL )
298     {
299         intf_ErrMsg( "Out of memory" );
300         p_input->b_error = 1;
301         return;
302     }
303     p_packet_cache->largebuffer.l_index = 0;
304
305     /* Set stream and area data */
306     vlc_mutex_lock( &p_input->stream.stream_lock );
307
308     /* Initialize ES structures */
309     input_InitStream( p_input, sizeof( stream_ps_data_t ) );
310
311     /* disc input method */
312     p_input->stream.i_method = INPUT_METHOD_VCD;
313
314
315 #define area p_input->stream.pp_areas
316     for( i = 1 ; i <= p_vcd->nb_tracks - 1 ; i++ )
317     {
318         input_AddArea( p_input );
319
320         /* Titles are Program Chains */
321         area[i]->i_id = i;
322
323         /* Absolute start offset and size */
324         area[i]->i_start = p_vcd->tracks_sector[i+1];
325         area[i]->i_size = p_vcd->tracks_sector[i+2] - p_vcd->tracks_sector[i+1];
326
327         /* Number of chapters */
328         area[i]->i_part_nb = 0;   // will be the entry points
329         area[i]->i_part = 1;
330
331         /* Number of angles */
332         area[i]->i_angle_nb = 1; // no angle support in VCDs
333         area[i]->i_angle = 1;
334
335         area[i]->i_plugin_data = p_vcd->tracks_sector[i+1];
336     }   
337 #undef area
338
339     /* Get requested title - if none try the first title */
340     i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 );
341     if( i_title <= 0)
342     {
343         i_title = 2;
344     }
345     
346     // p_vcd->current_track = i_title-1 ;
347     
348     /* Get requested chapter - if none defaults to first one */
349     i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 );
350     if( i_chapter <= 0 )
351     {
352         i_chapter = 1;
353     }
354
355     
356     p_input->stream.pp_areas[i_title]->i_part = i_chapter;
357
358     p_area = p_input->stream.pp_areas[i_title];
359
360     VCDSetArea( p_input, p_area );
361
362     /* Set program information. */
363
364     input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) ); 
365
366     /* No PSM to read in disc mode, we already have all information */
367     p_input->stream.pp_programs[0]->b_is_ok = 1;
368
369     p_es = input_AddES( p_input, p_input->stream.pp_programs[0], 0xe0, 0 );
370     p_es->i_stream_id = 0xe0;
371     p_es->i_type = MPEG1_VIDEO_ES;
372     p_es->i_cat = VIDEO_ES;
373     
374     if( p_main->b_video )
375     {
376         input_SelectES( p_input, p_es );
377     }
378     
379     p_es = input_AddES( p_input,
380                 p_input->stream.pp_programs[0], 0xc0, 0 );
381     p_es->i_stream_id = 0xc0;
382     p_es->i_type = MPEG1_AUDIO_ES;
383     p_es->b_audio = 1;
384     p_es->i_cat = AUDIO_ES;
385      
386     if( p_main->b_audio )
387     {
388         input_SelectES( p_input, p_es );
389     }
390     
391     vlc_mutex_unlock( &p_input->stream.stream_lock );
392
393     
394     return;
395 }
396
397
398 /*****************************************************************************
399  * VCDEnd: frees unused data
400  *****************************************************************************/
401 static void VCDEnd( input_thread_t * p_input )
402 {
403     thread_vcd_data_t *     p_vcd;
404
405     p_vcd = (thread_vcd_data_t*)p_input->p_plugin_data;
406
407     free( p_vcd );
408
409 }
410
411 /*****************************************************************************
412  * VCDSetArea: initialize input data for title x, chapter y.
413  * It should be called for each user navigation request.
414  ****************************************************************************/
415 static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
416 {
417     thread_vcd_data_t *     p_vcd;
418     
419     p_vcd = (thread_vcd_data_t*)p_input->p_plugin_data;
420     
421     /* we can't use the interface slider until initilization is complete */
422     p_input->stream.b_seekable = 0;
423     
424     if ( p_area != p_input->stream.p_selected_area ) 
425     {
426         /* Reset the Chapter position of the old title */
427         p_input->stream.p_selected_area->i_part = 0;
428         
429         /* Change the default area */
430         p_input->stream.p_selected_area =
431                     p_input->stream.pp_areas[p_area->i_id];
432
433         /* Change the current track */
434         /* The first track is not a valid one  */
435         p_vcd->current_track = p_area->i_id + 1 ;
436         p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track] ;
437     }
438     /* warn interface that something has changed */
439     p_input->stream.b_seekable = 1;
440     p_input->stream.b_changed = 1;
441     return 0 ;
442     
443 }
444
445
446
447 /*****************************************************************************
448  * VCDRead: reads from the VCD into PES packets.
449  *****************************************************************************
450  * Returns -1 in case of error, 0 if everything went well, and 1 in case of
451  * EOF.
452  *****************************************************************************/
453 static int VCDRead( input_thread_t * p_input,
454                     data_packet_t ** pp_packets )
455 {
456     thread_vcd_data_t *     p_vcd;
457     data_packet_t *         p_data;
458     int                     i_packet_size;
459     int                     i_index;
460     int                     i_packet;   
461     boolean_t               b_eof;
462     byte_t *                p_buffer;
463     boolean_t                  b_no_packet;
464     /* boolean_t               b_eoc; No chapters yet */
465     
466     p_vcd = (thread_vcd_data_t *)p_input->p_plugin_data;
467    
468
469     p_buffer = malloc ( VCD_DATA_SIZE );
470
471     if ( p_buffer == NULL )
472     {
473         intf_ErrMsg("Could not malloc the read buffer");
474         return -1;
475     }
476
477     
478     i_packet = 0;
479     b_no_packet = 0;
480
481     while( i_packet < VCD_DATA_ONCE ) 
482     {
483         i_index = 0;
484         
485         if ( VCD_sector_read( p_vcd, p_buffer ) == -1 )
486         {
487               return -1;
488         }
489         
490         while (i_index < BUFFER_SIZE - 6) 
491         {
492             
493             if( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L )
494             {
495                 /* This is not the startcode of a packet. Read the stream
496                  * until we find one. */
497     
498                 if( !U32_AT( p_buffer + i_index ) )
499                 {
500                     /* It is common for MPEG-1 streams to pad with zeros
501                      * (although it is forbidden by the recommendation), so
502                      * don't bother everybody in this case. */
503                     intf_WarnMsg( 3, "Garbage at input" );
504                 }
505     
506                 while( ( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L )
507                        && ( i_index < BUFFER_SIZE - 4 ) )
508                 {
509                     i_index ++;
510                 }
511     
512                 if ( i_index == BUFFER_SIZE - 4 )
513                 {
514                     b_no_packet = 1;
515                 }
516                 /* Packet found. */
517             }
518             
519             if (b_no_packet)
520             {
521                 b_no_packet = 0;
522                 intf_WarnMsg(3, "No packet found on sector %d\n", 
523                             p_vcd->current_sector -1 );
524                 break; /* go to the next sector */
525             }
526             
527 #ifdef DEBUG
528             intf_DbgMsg("packet start code : %X\n", 
529                         U32_AT(p_buffer + i_index));
530 #endif
531             /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
532             if( U32_AT(p_buffer + i_index) != 0x1B9 )
533             {
534                 /* The packet is at least 6 bytes long. */
535     
536                 if( U32_AT(p_buffer + i_index) != 0x1BA )
537                 {
538                     /* That's the case for all packets, except pack header. */
539                     i_packet_size = U16_AT((p_buffer + ( i_index + 4 )));
540                 }
541                 else
542                 {
543                     /* Pack header. */
544                     if( ( *( p_buffer + ( i_index + 4 ) ) & 0xC0) == 0x40 )
545                     {
546                         /* MPEG-2 */
547                         i_packet_size = 8;
548                     }
549                     else if( (*(p_buffer + ( i_index + 4 ) ) & 0xF0) == 0x20 )
550                     {
551                         /* MPEG-1 */
552                         i_packet_size = 6;
553                     }
554                     else
555                     {
556                         intf_ErrMsg( "Unable to determine stream type" );
557                         return( -1 );
558                     }
559                 }
560             }
561             else
562             {
563                 /* System End Code */
564                 i_packet_size = -2;
565             }
566 #ifdef DEBUG
567             intf_DbgMsg("i_index : %d\n", i_index);
568             intf_DbgMsg("i_packet_size : %d\n", i_packet_size);
569 #endif
570             if ( i_index + i_packet_size > BUFFER_SIZE )
571             {
572                 intf_ErrMsg( "Too long packet");
573                 continue;
574             }
575             
576             /* Fetch a packet of the appropriate size. */
577             
578             p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 );
579             
580             if( p_data == NULL )
581             {
582                 intf_ErrMsg( "Out of memory" );
583                 return( -1 );
584             }
585     
586             if( U32_AT(p_buffer) != 0x1B9 )
587             {
588                 memcpy( p_data->p_buffer, p_buffer + i_index,
589                         6 + i_packet_size );
590                 i_index += ( 6 + i_packet_size );
591     
592             }
593             else
594             {
595                 /* Copy the small header. */
596                 memcpy( p_data->p_buffer, p_buffer + i_index, 4 );
597                 i_index += 4;
598             }
599     
600             /* Give the packet to the other input stages. */
601             pp_packets[i_packet] = p_data;
602             i_packet ++;
603         }
604         
605         if ( p_vcd->b_end_of_track )
606             break;
607     }
608
609
610
611
612
613     
614     vlc_mutex_lock( &p_input->stream.stream_lock );
615
616     p_input->stream.p_selected_area->i_tell =
617         p_vcd->current_sector -
618         p_input->stream.p_selected_area->i_start ;
619     
620     /* no chapter for the moment*/
621     /*if( b_eoc )
622     {
623         * We modify i_part only at end of chapter not to erase
624          * some modification from the interface *
625         p_input->stream.p_selected_area->i_part = p_vcd->i_chapter;
626     }*/
627
628     
629     b_eof = p_vcd->b_end_of_track && 
630             ( ( p_vcd->current_track + 1 ) >= p_vcd->nb_tracks );
631
632     if( b_eof )
633     {
634         vlc_mutex_unlock( &p_input->stream.stream_lock );
635         return 1;
636     }
637
638     if( p_vcd->b_end_of_track )
639     {
640         intf_WarnMsg( 4, "vcd info: new title" );
641         p_vcd->current_track++;
642         p_vcd->b_end_of_track = 0;
643         VCDSetArea( p_input, p_input->stream.pp_areas[p_vcd->current_track] );
644         vlc_mutex_unlock( &p_input->stream.stream_lock );
645         return 0;
646     }
647     
648     vlc_mutex_unlock( &p_input->stream.stream_lock );
649
650
651     return 0;
652 }
653
654 /*****************************************************************************
655  * VCDRewind : reads a stream backward
656  *****************************************************************************/
657 static int VCDRewind( input_thread_t * p_input )
658 {
659     return( -1 );
660 }
661
662
663 /****************************************************************************
664  * VCDSeek
665  ****************************************************************************/
666 static void VCDSeek( input_thread_t * p_input, off_t i_off )
667 {
668     thread_vcd_data_t *               p_vcd;
669
670     p_vcd = (thread_vcd_data_t *) p_input->p_plugin_data;
671
672     p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track]
673                                 + i_off;
674
675     p_input->stream.p_selected_area->i_tell = p_vcd->current_sector
676         - p_input->stream.p_selected_area->i_start;
677     
678     return ;
679 }
680
681
682
683 /*
684  * Packet management utilities
685  */
686
687
688 /*****************************************************************************
689  * NewPacket: allocates a data packet
690  *****************************************************************************/
691 static struct data_packet_s * NewPacket( void * p_packet_cache,
692                                          size_t l_size )
693
694     packet_cache_t *   p_cache;
695     data_packet_t *    p_data;
696     long               l_index;
697
698     p_cache = (packet_cache_t *)p_packet_cache;
699
700 #ifdef DEBUG
701     if ( p_cache == NULL )
702     {
703         intf_ErrMsg( "PPacket cache not initialized" );
704         return NULL;
705     }
706 #endif
707
708     /* Safety check */
709     if( l_size > INPUT_MAX_PACKET_SIZE )
710     {
711         intf_ErrMsg( "Packet too big (%d)", l_size );
712         return NULL;
713     }
714
715     vlc_mutex_lock( &p_cache->lock );
716
717     /* Checks whether the data cache is empty */
718     if( p_cache->data.l_index == 0 )
719     {
720         /* Allocates a new packet */
721         p_data = malloc( sizeof(data_packet_t) );
722         if( p_data == NULL )
723         {
724             intf_ErrMsg( "Out of memory" );
725             vlc_mutex_unlock( &p_cache->lock );
726             return NULL;
727         }
728 #ifdef TRACE_INPUT
729         intf_DbgMsg( "PS input: data packet allocated" );
730 #endif
731     }
732     else
733     {
734         /* Takes the packet out from the cache */
735         if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ]) 
736             == NULL )
737         {
738             intf_ErrMsg( "NULL packet in the data cache" );
739             vlc_mutex_unlock( &p_cache->lock );
740             return NULL;
741         }
742     }
743     
744     if( l_size < MAX_SMALL_SIZE )
745     {
746         /* Small buffer */  
747    
748         /* Checks whether the buffer cache is empty */
749         if( p_cache->smallbuffer.l_index == 0 )
750         {
751             /* Allocates a new packet */
752             p_data->p_buffer = malloc( l_size );
753             if( p_data->p_buffer == NULL )
754             {
755                 intf_DbgMsg( "Out of memory" );
756                 free( p_data );
757                 vlc_mutex_unlock( &p_cache->lock );
758                 return NULL;
759             }
760 #ifdef TRACE_INPUT
761             intf_DbgMsg( "PS input: small buffer allocated" );
762 #endif
763             p_data->l_size = l_size;
764         }
765         else
766         {
767             /* Takes the packet out from the cache */
768             l_index = -- p_cache->smallbuffer.l_index;    
769             if( (p_data->p_buffer = p_cache->smallbuffer.p_stack[l_index].p_data)
770                 == NULL )
771             {
772                 intf_ErrMsg( "NULL packet in the small buffer cache" );
773                 free( p_data );
774                 vlc_mutex_unlock( &p_cache->lock );
775                 return NULL;
776             }
777             /* Reallocates the packet if it is too small or too large */
778             if( p_cache->smallbuffer.p_stack[l_index].l_size < l_size ||
779                 p_cache->smallbuffer.p_stack[l_index].l_size > 2*l_size )
780             {
781                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
782                 p_data->l_size = l_size;
783             }
784             else
785             {
786                 p_data->l_size = p_cache->smallbuffer.p_stack[l_index].l_size;
787             }
788         }
789     }
790     else
791     {
792         /* Large buffer */  
793    
794         /* Checks whether the buffer cache is empty */
795         if( p_cache->largebuffer.l_index == 0 )
796         {
797             /* Allocates a new packet */
798             p_data->p_buffer = malloc( l_size );
799             if ( p_data->p_buffer == NULL )
800             {
801                 intf_ErrMsg( "Out of memory" );
802                 free( p_data );
803                 vlc_mutex_unlock( &p_cache->lock );
804                 return NULL;
805             }
806 #ifdef TRACE_INPUT
807             intf_DbgMsg( "PS input: large buffer allocated" );
808 #endif
809             p_data->l_size = l_size;
810         }
811         else
812         {
813             /* Takes the packet out from the cache */
814             l_index = -- p_cache->largebuffer.l_index;    
815             p_data->p_buffer = p_cache->largebuffer.p_stack[l_index].p_data;
816             if( p_data->p_buffer == NULL )
817             {
818                 intf_ErrMsg( "NULL packet in the small buffer cache" );
819                 free( p_data );
820                 vlc_mutex_unlock( &p_cache->lock );
821                 return NULL;
822             }
823             /* Reallocates the packet if it is too small or too large */
824             if( p_cache->largebuffer.p_stack[l_index].l_size < l_size ||
825                 p_cache->largebuffer.p_stack[l_index].l_size > 2*l_size )
826             {
827                 p_data->p_buffer = realloc( p_data->p_buffer, l_size );
828                 p_data->l_size = l_size;
829             }
830             else
831             {
832                 p_data->l_size = p_cache->largebuffer.p_stack[l_index].l_size;
833             }
834         }
835     }
836
837     vlc_mutex_unlock( &p_cache->lock );
838
839     /* Initialize data */
840     p_data->p_next = NULL;
841     p_data->b_discard_payload = 0;
842     p_data->p_payload_start = p_data->p_buffer;
843     p_data->p_payload_end = p_data->p_buffer + l_size;
844
845     return( p_data );
846
847 }
848
849
850 /*****************************************************************************
851  * NewPES: allocates a pes packet
852  *****************************************************************************/
853 static pes_packet_t * NewPES( void * p_packet_cache )
854 {
855     packet_cache_t *   p_cache;
856     pes_packet_t *     p_pes;
857
858     p_cache = (packet_cache_t *)p_packet_cache;
859
860 #ifdef DEBUG
861     if ( p_cache == NULL )
862     {
863         intf_ErrMsg( "Packet cache not initialized" );
864         return NULL;
865     }
866 #endif
867
868     vlc_mutex_lock( &p_cache->lock );
869
870     /* Checks whether the PES cache is empty */
871     if( p_cache->pes.l_index == 0 )
872     {
873         /* Allocates a new packet */
874         p_pes = malloc( sizeof(pes_packet_t) );
875         if( p_pes == NULL )
876         {
877             intf_DbgMsg( "Out of memory" );
878             vlc_mutex_unlock( &p_cache->lock );
879             return NULL;
880         }
881 #ifdef TRACE_INPUT
882         intf_DbgMsg( "PS input: PES packet allocated" );
883 #endif
884     }
885     else
886     {
887         /* Takes the packet out from the cache */
888         p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ];
889         if( p_pes == NULL )
890         {
891             intf_ErrMsg( "NULL packet in the data cache" );
892             vlc_mutex_unlock( &p_cache->lock );
893             return NULL;
894         }
895     }
896
897     vlc_mutex_unlock( &p_cache->lock );
898
899     p_pes->b_data_alignment = p_pes->b_discontinuity =
900         p_pes->i_pts = p_pes->i_dts = 0;
901     p_pes->i_pes_size = 0;
902     p_pes->p_first = NULL;
903
904     return( p_pes );
905     
906 }
907
908 /*****************************************************************************
909  * DeletePacket: deletes a data packet
910  *****************************************************************************/
911 static void DeletePacket( void * p_packet_cache,
912                           data_packet_t * p_data )
913 {
914     packet_cache_t *   p_cache;
915
916     p_cache = (packet_cache_t *)p_packet_cache;
917
918 #ifdef DEBUG
919     if ( p_cache == NULL )
920     {
921         intf_ErrMsg( "Packet cache not initialized" );
922         return;
923     }
924 #endif
925
926     ASSERT( p_data );
927
928     vlc_mutex_lock( &p_cache->lock );
929
930     /* Checks whether the data cache is full */
931     if ( p_cache->data.l_index < DATA_CACHE_SIZE )
932     {
933         /* Cache not full: store the packet in it */
934         p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data;
935         /* Small buffer or large buffer? */
936         if ( p_data->l_size < MAX_SMALL_SIZE )
937         {
938             /* Checks whether the small buffer cache is full */
939             if ( p_cache->smallbuffer.l_index < SMALL_CACHE_SIZE )
940             {
941                 p_cache->smallbuffer.p_stack[
942                     p_cache->smallbuffer.l_index ].l_size = p_data->l_size;
943                 p_cache->smallbuffer.p_stack[
944                     p_cache->smallbuffer.l_index++ ].p_data = p_data->p_buffer;
945             }
946             else
947             {
948                 ASSERT( p_data->p_buffer );
949                 free( p_data->p_buffer );
950 #ifdef TRACE_INPUT
951                 intf_DbgMsg( "PS input: small buffer freed" );
952 #endif
953             }
954         }
955         else
956         {
957             /* Checks whether the large buffer cache is full */
958             if ( p_cache->largebuffer.l_index < LARGE_CACHE_SIZE )
959             {
960                 p_cache->largebuffer.p_stack[
961                     p_cache->largebuffer.l_index ].l_size = p_data->l_size;
962                 p_cache->largebuffer.p_stack[
963                     p_cache->largebuffer.l_index++ ].p_data = p_data->p_buffer;
964             }
965             else
966             {
967                 ASSERT( p_data->p_buffer );
968                 free( p_data->p_buffer );
969 #ifdef TRACE_INPUT
970                 intf_DbgMsg( "PS input: large buffer freed" );
971 #endif
972             }
973         }
974     }
975     else
976     {
977         /* Cache full: the packet must be freed */
978         free( p_data->p_buffer );
979         free( p_data );
980 #ifdef TRACE_INPUT
981         intf_DbgMsg( "PS input: data packet freed" );
982 #endif
983     }
984
985     vlc_mutex_unlock( &p_cache->lock );
986 }
987
988 /*****************************************************************************
989  * DeletePES: deletes a PES packet and associated data packets
990  *****************************************************************************/
991 static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
992 {
993     packet_cache_t *    p_cache;
994     data_packet_t *     p_data;
995     data_packet_t *     p_next;
996
997     p_cache = (packet_cache_t *)p_packet_cache;
998
999 #ifdef DEBUG
1000     if ( p_cache == NULL )
1001     {
1002         intf_ErrMsg( "Packet cache not initialized" );
1003         return;
1004     }
1005 #endif
1006
1007     ASSERT( p_pes);
1008
1009     p_data = p_pes->p_first;
1010
1011     while( p_data != NULL )
1012     {
1013         p_next = p_data->p_next;
1014         DeletePacket( p_cache, p_data );
1015         p_data = p_next;
1016     }
1017
1018     vlc_mutex_lock( &p_cache->lock );
1019
1020     /* Checks whether the PES cache is full */
1021     if ( p_cache->pes.l_index < PES_CACHE_SIZE )
1022     {
1023         /* Cache not full: store the packet in it */
1024         p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
1025     }
1026     else
1027     {
1028         /* Cache full: the packet must be freed */
1029         free( p_pes );
1030 #ifdef TRACE_INPUT
1031         intf_DbgMsg( "PS input: PES packet freed" );
1032 #endif
1033     }
1034
1035     vlc_mutex_unlock( &p_cache->lock );
1036 }