X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=plugins%2Fvcd%2Finput_vcd.c;h=cb084c1c5f37fed9afb18d792823d0e4f3bf5534;hb=abde4bbfb7419e164d60d7eb71bfa2cbfcc6b434;hp=7f644ed7f36983dc433538c2f4376abd18e5a379;hpb=7917d2ef3f36d47ad90509812755facc07bec9d7;p=vlc diff --git a/plugins/vcd/input_vcd.c b/plugins/vcd/input_vcd.c index 7f644ed7f3..cb084c1c5f 100644 --- a/plugins/vcd/input_vcd.c +++ b/plugins/vcd/input_vcd.c @@ -50,8 +50,6 @@ # include /* struct iovec */ #endif - -#include "config.h" #include "common.h" #include "intf_msg.h" #include "threads.h" @@ -62,8 +60,6 @@ # include "input_iovec.h" #endif -#include "main.h" - #include "stream_control.h" #include "input_ext-intf.h" #include "input_ext-dec.h" @@ -74,17 +70,14 @@ #include "modules.h" #include "modules_export.h" -#include "../mpeg/input_ps.h" #include "input_vcd.h" #include "linux_cdrom_tools.h" /* how many blocks VCDRead will read in each loop */ -#define VCD_BLOCKS_ONCE 64 -#define VCD_DATA_ONCE (2 * VCD_BLOCKS_ONCE) +#define VCD_BLOCKS_ONCE 4 +#define VCD_DATA_ONCE (2 * VCD_BLOCKS_ONCE) #define BUFFER_SIZE VCD_DATA_SIZE - - /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -92,18 +85,26 @@ static int VCDProbe ( probedata_t *p_data ); static void VCDInit ( struct input_thread_s * ); static int VCDRead ( struct input_thread_s *, data_packet_t ** ); -static int VCDSetArea ( struct input_thread_s *, struct input_area_s * ); -static int VCDSetProgram ( struct input_thread_s *, pgrm_descriptor_t * ); +static int VCDSetArea ( struct input_thread_s *, struct input_area_s * ); +static int VCDSetProgram ( struct input_thread_s *, pgrm_descriptor_t * ); static void VCDOpen ( struct input_thread_s *); -static void VCDClose ( struct input_thread_s *); +static void VCDClose ( struct input_thread_s *); static void VCDEnd ( struct input_thread_s *); static void VCDSeek ( struct input_thread_s *, off_t ); static int VCDRewind ( struct input_thread_s * ); -static struct data_packet_s * NewPacket( void *, size_t ); -static pes_packet_t * NewPES ( void * ); -static void DeletePacket ( void *, data_packet_t * ); -static void DeletePES ( void *, pes_packet_t *); +/***************************************************************************** + * Declare a buffer manager + *****************************************************************************/ +#define FLAGS BUFFERS_NOFLAGS +#define NB_LIFO 2 +DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ); +DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ); +DECLARE_BUFFERS_END( FLAGS, NB_LIFO ); +DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ); +DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, 150 ); +DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ); +DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150, 150 ); /***************************************************************************** @@ -123,10 +124,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list ) input.pf_set_area = VCDSetArea; input.pf_set_program = VCDSetProgram; input.pf_demux = input_DemuxPS; - input.pf_new_packet = NewPacket; - input.pf_new_pes = NewPES; - input.pf_delete_packet = DeletePacket; - input.pf_delete_pes = DeletePES; + input.pf_new_packet = input_NewPacket; + input.pf_new_pes = input_NewPES; + input.pf_delete_packet = input_DeletePacket; + input.pf_delete_pes = input_DeletePES; input.pf_rewind = VCDRewind; input.pf_seek = VCDSeek; #undef input @@ -141,7 +142,6 @@ void _M( input_getfunctions )( function_list_t * p_function_list ) *****************************************************************************/ static int VCDProbe( probedata_t *p_data ) { - input_thread_t * p_input = (input_thread_t *)p_data; char * psz_name = p_input->p_source; @@ -158,6 +158,7 @@ static int VCDProbe( probedata_t *p_data ) i_score = 100; psz_name += 4; } + return( i_score ); } @@ -166,8 +167,6 @@ static int VCDProbe( probedata_t *p_data ) *****************************************************************************/ static void VCDOpen( struct input_thread_s *p_input ) { - int vcdhandle; - vlc_mutex_lock( &p_input->stream.stream_lock ); /* If we are here we can control the pace... */ @@ -175,30 +174,27 @@ static void VCDOpen( struct input_thread_s *p_input ) p_input->stream.b_seekable = 1; p_input->stream.p_selected_area->i_size = 0; - p_input->stream.p_selected_area->i_tell = 0; vlc_mutex_unlock( &p_input->stream.stream_lock ); - - + /* XXX: put this shit in an access plugin */ if( strlen( p_input->p_source ) > 4 && !strncasecmp( p_input->p_source, "vcd:", 4 ) ) { - vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK ); + p_input->i_handle + = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK ); } else { - vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK ); + p_input->i_handle + = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK ); } - if( vcdhandle == -1 ) + if( p_input->i_handle == -1 ) { p_input->b_error = 1; - return; } - - p_input->i_handle = (int) vcdhandle; } /***************************************************************************** @@ -220,10 +216,9 @@ static void VCDInit( input_thread_t * p_input ) int i; input_area_t * p_area; es_descriptor_t * p_es; - packet_cache_t * p_packet_cache; - + p_vcd = malloc( sizeof(thread_vcd_data_t) ); - + if( p_vcd == NULL ) { intf_ErrMsg( "vcd error: out of memory" ); @@ -231,78 +226,24 @@ static void VCDInit( input_thread_t * p_input ) return; } - - p_input->p_plugin_data = (void *)p_vcd; - p_input->p_method_data = NULL; - - p_vcd->vcdhandle = p_input->i_handle; - p_vcd->b_end_of_track = 0; - /* we read the Table Of Content information */ - if ( read_toc(p_vcd) == -1 ) + if( (p_input->p_method_data = input_BuffersInit()) == NULL ) { - intf_ErrMsg("An error occured when reading vcd's TOC"); - } - - p_input->i_read_once = VCD_DATA_ONCE; - - p_packet_cache = malloc( sizeof(packet_cache_t) ); - - if ( p_packet_cache == NULL ) - { - intf_ErrMsg( "vcd error: out of memory" ); p_input->b_error = 1; return; } - - p_input->p_method_data = (void *)p_packet_cache; - /* Initialize packet cache mutex */ - vlc_mutex_init( &p_packet_cache->lock ); - - /* allocates the data cache */ - p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE * - sizeof(data_packet_t*) ); - if ( p_packet_cache->data.p_stack == NULL ) - { - intf_ErrMsg( "Out of memory" ); - p_input->b_error = 1; - return; - } - p_packet_cache->data.l_index = 0; - - /* allocates the PES cache */ - p_packet_cache->pes.p_stack = malloc( PES_CACHE_SIZE * - sizeof(pes_packet_t*) ); - if ( p_packet_cache->pes.p_stack == NULL ) - { - intf_ErrMsg( "Out of memory" ); - p_input->b_error = 1; - return; - } - p_packet_cache->pes.l_index = 0; - - /* allocates the small buffer cache */ - p_packet_cache->smallbuffer.p_stack = malloc( SMALL_CACHE_SIZE * - sizeof(packet_buffer_t) ); - if ( p_packet_cache->smallbuffer.p_stack == NULL ) - { - intf_ErrMsg( "Out of memory" ); - p_input->b_error = 1; - return; - } - p_packet_cache->smallbuffer.l_index = 0; - - /* allocates the large buffer cache */ - p_packet_cache->largebuffer.p_stack = malloc( LARGE_CACHE_SIZE * - sizeof(packet_buffer_t) ); - if ( p_packet_cache->largebuffer.p_stack == NULL ) + + p_vcd->i_handle = p_input->i_handle; + p_vcd->b_end_of_track = 0; + + /* we read the Table Of Content information */ + if ( VCDReadToc( p_vcd ) == -1 ) { - intf_ErrMsg( "Out of memory" ); - p_input->b_error = 1; - return; + intf_ErrMsg( "vcd error: could not read TOC" ); } - p_packet_cache->largebuffer.l_index = 0; + + p_input->i_read_once = VCD_DATA_ONCE; /* Set stream and area data */ vlc_mutex_lock( &p_input->stream.stream_lock ); @@ -323,8 +264,8 @@ static void VCDInit( input_thread_t * p_input ) area[i]->i_id = i; /* Absolute start offset and size */ - area[i]->i_start = p_vcd->tracks_sector[i+1]; - area[i]->i_size = p_vcd->tracks_sector[i+2] - p_vcd->tracks_sector[i+1]; + area[i]->i_start = p_vcd->p_sectors[i]; + area[i]->i_size = p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i]; /* Number of chapters */ area[i]->i_part_nb = 0; // will be the entry points @@ -334,19 +275,19 @@ static void VCDInit( input_thread_t * p_input ) area[i]->i_angle_nb = 1; // no angle support in VCDs area[i]->i_angle = 1; - area[i]->i_plugin_data = p_vcd->tracks_sector[i+1]; - } + area[i]->i_plugin_data = p_vcd->p_sectors[i]; + } #undef area /* Get requested title - if none try the first title */ i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 ); - if( i_title <= 0) + if( i_title <= 0 ) { - i_title = 2; + i_title = 1; } - - // p_vcd->current_track = i_title-1 ; - + + // p_vcd->i_track = i_title-1; + /* Get requested chapter - if none defaults to first one */ i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 ); if( i_chapter <= 0 ) @@ -354,7 +295,6 @@ static void VCDInit( input_thread_t * p_input ) i_chapter = 1; } - p_input->stream.pp_areas[i_title]->i_part = i_chapter; p_area = p_input->stream.pp_areas[i_title]; @@ -373,31 +313,27 @@ static void VCDInit( input_thread_t * p_input ) p_es->i_stream_id = 0xe0; p_es->i_type = MPEG1_VIDEO_ES; p_es->i_cat = VIDEO_ES; - + if( p_main->b_video ) { input_SelectES( p_input, p_es ); } - + p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xc0, 0 ); p_es->i_stream_id = 0xc0; p_es->i_type = MPEG1_AUDIO_ES; p_es->b_audio = 1; p_es->i_cat = AUDIO_ES; - + if( p_main->b_audio ) { input_SelectES( p_input, p_es ); } - - vlc_mutex_unlock( &p_input->stream.stream_lock ); - - return; + vlc_mutex_unlock( &p_input->stream.stream_lock ); } - /***************************************************************************** * VCDEnd: frees unused data *****************************************************************************/ @@ -409,13 +345,14 @@ static void VCDEnd( input_thread_t * p_input ) free( p_vcd ); + input_BuffersEnd( p_input->p_method_data ); } /***************************************************************************** * VCDSetProgram: Does nothing since a VCD is mono_program *****************************************************************************/ -static int VCDSetProgram( input_thread_t * p_input, - pgrm_descriptor_t * p_program) +static int VCDSetProgram( input_thread_t * p_input, + pgrm_descriptor_t * p_program) { return 0; } @@ -428,34 +365,33 @@ static int VCDSetProgram( input_thread_t * p_input, static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area ) { thread_vcd_data_t * p_vcd; - + p_vcd = (thread_vcd_data_t*)p_input->p_plugin_data; - + /* we can't use the interface slider until initilization is complete */ p_input->stream.b_seekable = 0; - - if ( p_area != p_input->stream.p_selected_area ) + + if( p_area != p_input->stream.p_selected_area ) { - /* Reset the Chapter position of the old title */ - p_input->stream.p_selected_area->i_part = 0; - + /* Reset the Chapter position of the current title */ + p_input->stream.p_selected_area->i_part = 1; + p_input->stream.p_selected_area->i_tell = 0; + /* Change the default area */ - p_input->stream.p_selected_area = - p_input->stream.pp_areas[p_area->i_id]; + p_input->stream.p_selected_area = p_area; /* Change the current track */ /* The first track is not a valid one */ - p_vcd->current_track = p_area->i_id + 1 ; - p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track] ; + p_vcd->i_track = p_area->i_id; + p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track]; } + /* warn interface that something has changed */ p_input->stream.b_seekable = 1; p_input->stream.b_changed = 1; - return 0 ; - -} - + return 0; +} /***************************************************************************** * VCDRead: reads from the VCD into PES packets. @@ -463,97 +399,72 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area ) * Returns -1 in case of error, 0 if everything went well, and 1 in case of * EOF. *****************************************************************************/ -static int VCDRead( input_thread_t * p_input, - data_packet_t ** pp_packets ) +static int VCDRead( input_thread_t * p_input, data_packet_t ** pp_packets ) { thread_vcd_data_t * p_vcd; data_packet_t * p_data; int i_packet_size; int i_index; - int i_packet; - boolean_t b_eof; - byte_t * p_buffer; - boolean_t b_no_packet; + int i_packet; + u32 i_header; + byte_t p_buffer[ VCD_DATA_SIZE ]; /* boolean_t b_eoc; No chapters yet */ - - p_vcd = (thread_vcd_data_t *)p_input->p_plugin_data; - - - p_buffer = malloc ( VCD_DATA_SIZE ); - if ( p_buffer == NULL ) - { - intf_ErrMsg("Could not malloc the read buffer"); - return -1; - } + p_vcd = (thread_vcd_data_t *)p_input->p_plugin_data; - i_packet = 0; - b_no_packet = 0; - while( i_packet < VCD_DATA_ONCE ) + while( i_packet < VCD_DATA_ONCE + && !p_vcd->b_end_of_track ) { - i_index = 0; - - if ( VCD_sector_read( p_vcd, p_buffer ) == -1 ) + if ( VCDReadSector( p_vcd, p_buffer ) == -1 ) { - return -1; + return -1; } - - while (i_index < BUFFER_SIZE - 6) + + i_index = 0; + + while( i_index < BUFFER_SIZE - 6 + && !p_vcd->b_end_of_track + && i_packet < VCD_DATA_ONCE ) { - - if( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L ) + i_header = U32_AT(p_buffer + i_index); + + /* This is not the startcode of a packet. Read the stream + * until we find one. */ + if( !i_header ) { - /* This is not the startcode of a packet. Read the stream - * until we find one. */ - - if( !U32_AT( p_buffer + i_index ) ) - { - /* It is common for MPEG-1 streams to pad with zeros - * (although it is forbidden by the recommendation), so - * don't bother everybody in this case. */ - intf_WarnMsg( 3, "Garbage at input" ); - } - - while( ( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L ) - && ( i_index < BUFFER_SIZE - 4 ) ) - { - i_index ++; - } - - if ( i_index == BUFFER_SIZE - 4 ) - { - b_no_packet = 1; - } - /* Packet found. */ + /* It is common for MPEG-1 streams to pad with zeros + * (although it is forbidden by the recommendation), so + * don't bother everybody in this case. */ + intf_WarnMsg( 3, "vcd warning: garbage at input" ); } - - if (b_no_packet) + + while( (i_header & 0xFFFFFF00) != 0x100L + && (++i_index < BUFFER_SIZE - 4) ) { - b_no_packet = 0; - intf_WarnMsg(3, "No packet found on sector %d\n", - p_vcd->current_sector -1 ); + i_header = U32_AT(p_buffer + i_index); + } + + if( (i_header & 0xFFFFFF00) != 0x100L ) + { + intf_WarnMsg( 3, "vcd warning: no packet at sector %d\n", + p_vcd->i_sector - 1 ); break; /* go to the next sector */ } - #ifdef DEBUG - intf_DbgMsg("packet start code : %X\n", - U32_AT(p_buffer + i_index)); + intf_DbgMsg( "packet start code : %X\n", i_header ); #endif - /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */ - if( U32_AT(p_buffer + i_index) != 0x1B9 ) + + switch( i_header ) { - /* The packet is at least 6 bytes long. */ - - if( U32_AT(p_buffer + i_index) != 0x1BA ) - { - /* That's the case for all packets, except pack header. */ - i_packet_size = U16_AT((p_buffer + ( i_index + 4 ))); - } - else - { - /* Pack header. */ + /* 0x1b9 == SYSTEM_END_CODE, it is only 4 bytes long. */ + case 0x1b9: + i_packet_size = -2; + break; + + /* Pack header */ + case 0x1ba: if( ( *( p_buffer + ( i_index + 4 ) ) & 0xC0) == 0x40 ) { /* MPEG-2 */ @@ -569,67 +480,63 @@ static int VCDRead( input_thread_t * p_input, intf_ErrMsg( "Unable to determine stream type" ); return( -1 ); } - } - } - else - { - /* System End Code */ - i_packet_size = -2; + break; + + /* The packet is at least 6 bytes long. */ + default: + /* That's the case for all packets, except pack header. */ + i_packet_size = U16_AT((p_buffer + ( i_index + 4 ))); + break; } + #ifdef DEBUG intf_DbgMsg("i_index : %d\n", i_index); intf_DbgMsg("i_packet_size : %d\n", i_packet_size); #endif + if ( i_index + i_packet_size > BUFFER_SIZE ) { - intf_ErrMsg( "Too long packet"); + intf_ErrMsg( "vcd error: packet too long (%i)", + i_index + i_packet_size ); continue; } - + /* Fetch a packet of the appropriate size. */ - - p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 ); - + p_data = p_input->pf_new_packet( p_input->p_method_data, + i_packet_size + 6 ); + if( p_data == NULL ) { - intf_ErrMsg( "Out of memory" ); + intf_ErrMsg( "vcd error: out of memory" ); return( -1 ); } - + if( U32_AT(p_buffer) != 0x1B9 ) { - pf_fast_memcpy( p_data->p_buffer, p_buffer + i_index, - 6 + i_packet_size ); + p_main->fast_memcpy( p_data->p_demux_start, p_buffer + i_index, + 6 + i_packet_size ); i_index += ( 6 + i_packet_size ); - } else { /* Copy the small header. */ - memcpy( p_data->p_buffer, p_buffer + i_index, 4 ); + memcpy( p_data->p_demux_start, p_buffer + i_index, 4 ); i_index += 4; } - + /* Give the packet to the other input stages. */ pp_packets[i_packet] = p_data; - i_packet ++; + i_packet++; } - - if ( p_vcd->b_end_of_track ) - break; } + pp_packets[i_packet] = NULL; - - - - vlc_mutex_lock( &p_input->stream.stream_lock ); p_input->stream.p_selected_area->i_tell = - p_vcd->current_sector - - p_input->stream.p_selected_area->i_start ; - + p_vcd->i_sector - p_input->stream.p_selected_area->i_start; + /* no chapter for the moment*/ /*if( b_eoc ) { @@ -638,28 +545,29 @@ static int VCDRead( input_thread_t * p_input, p_input->stream.p_selected_area->i_part = p_vcd->i_chapter; }*/ - - b_eof = p_vcd->b_end_of_track && - ( ( p_vcd->current_track + 1 ) >= p_vcd->nb_tracks ); - - if( b_eof ) - { - vlc_mutex_unlock( &p_input->stream.stream_lock ); - return 1; - } - if( p_vcd->b_end_of_track ) { + input_area_t *p_area; + + /* EOF ? */ + if( p_vcd->i_track >= p_vcd->nb_tracks - 1 ) + { + vlc_mutex_unlock( &p_input->stream.stream_lock ); + return 1; + } + intf_WarnMsg( 4, "vcd info: new title" ); - p_vcd->current_track++; + p_vcd->b_end_of_track = 0; - VCDSetArea( p_input, p_input->stream.pp_areas[p_vcd->current_track] ); - vlc_mutex_unlock( &p_input->stream.stream_lock ); - return 0; + + p_area = p_input->stream.pp_areas[ + p_input->stream.p_selected_area->i_id + 1 ]; + + p_area->i_part = 1; + VCDSetArea( p_input, p_area ); } - - vlc_mutex_unlock( &p_input->stream.stream_lock ); + vlc_mutex_unlock( &p_input->stream.stream_lock ); return 0; } @@ -672,7 +580,6 @@ static int VCDRewind( input_thread_t * p_input ) return( -1 ); } - /**************************************************************************** * VCDSeek ****************************************************************************/ @@ -682,368 +589,9 @@ static void VCDSeek( input_thread_t * p_input, off_t i_off ) p_vcd = (thread_vcd_data_t *) p_input->p_plugin_data; - p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track] - + i_off; + p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track] + i_off; - p_input->stream.p_selected_area->i_tell = p_vcd->current_sector + p_input->stream.p_selected_area->i_tell = p_vcd->i_sector - p_input->stream.p_selected_area->i_start; - - return ; } - - -/* - * Packet management utilities - */ - - -/***************************************************************************** - * NewPacket: allocates a data packet - *****************************************************************************/ -static struct data_packet_s * NewPacket( void * p_packet_cache, - size_t l_size ) -{ - packet_cache_t * p_cache; - data_packet_t * p_data; - long l_index; - - p_cache = (packet_cache_t *)p_packet_cache; - -#ifdef DEBUG - if ( p_cache == NULL ) - { - intf_ErrMsg( "PPacket cache not initialized" ); - return NULL; - } -#endif - - /* Safety check */ - if( l_size > INPUT_MAX_PACKET_SIZE ) - { - intf_ErrMsg( "Packet too big (%d)", l_size ); - return NULL; - } - - vlc_mutex_lock( &p_cache->lock ); - - /* Checks whether the data cache is empty */ - if( p_cache->data.l_index == 0 ) - { - /* Allocates a new packet */ - p_data = malloc( sizeof(data_packet_t) ); - if( p_data == NULL ) - { - intf_ErrMsg( "Out of memory" ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: data packet allocated" ); -#endif - } - else - { - /* Takes the packet out from the cache */ - if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ]) - == NULL ) - { - intf_ErrMsg( "NULL packet in the data cache" ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } - } - - if( l_size < MAX_SMALL_SIZE ) - { - /* Small buffer */ - - /* Checks whether the buffer cache is empty */ - if( p_cache->smallbuffer.l_index == 0 ) - { - /* Allocates a new packet */ - p_data->p_buffer = malloc( l_size ); - if( p_data->p_buffer == NULL ) - { - intf_DbgMsg( "Out of memory" ); - free( p_data ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: small buffer allocated" ); -#endif - p_data->l_size = l_size; - } - else - { - /* Takes the packet out from the cache */ - l_index = -- p_cache->smallbuffer.l_index; - if( (p_data->p_buffer = p_cache->smallbuffer.p_stack[l_index].p_data) - == NULL ) - { - intf_ErrMsg( "NULL packet in the small buffer cache" ); - free( p_data ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } - /* Reallocates the packet if it is too small or too large */ - if( p_cache->smallbuffer.p_stack[l_index].l_size < l_size || - p_cache->smallbuffer.p_stack[l_index].l_size > 2*l_size ) - { - p_data->p_buffer = realloc( p_data->p_buffer, l_size ); - p_data->l_size = l_size; - } - else - { - p_data->l_size = p_cache->smallbuffer.p_stack[l_index].l_size; - } - } - } - else - { - /* Large buffer */ - - /* Checks whether the buffer cache is empty */ - if( p_cache->largebuffer.l_index == 0 ) - { - /* Allocates a new packet */ - p_data->p_buffer = malloc( l_size ); - if ( p_data->p_buffer == NULL ) - { - intf_ErrMsg( "Out of memory" ); - free( p_data ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: large buffer allocated" ); -#endif - p_data->l_size = l_size; - } - else - { - /* Takes the packet out from the cache */ - l_index = -- p_cache->largebuffer.l_index; - p_data->p_buffer = p_cache->largebuffer.p_stack[l_index].p_data; - if( p_data->p_buffer == NULL ) - { - intf_ErrMsg( "NULL packet in the small buffer cache" ); - free( p_data ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } - /* Reallocates the packet if it is too small or too large */ - if( p_cache->largebuffer.p_stack[l_index].l_size < l_size || - p_cache->largebuffer.p_stack[l_index].l_size > 2*l_size ) - { - p_data->p_buffer = realloc( p_data->p_buffer, l_size ); - p_data->l_size = l_size; - } - else - { - p_data->l_size = p_cache->largebuffer.p_stack[l_index].l_size; - } - } - } - - vlc_mutex_unlock( &p_cache->lock ); - - /* Initialize data */ - p_data->p_next = NULL; - p_data->b_discard_payload = 0; - p_data->p_payload_start = p_data->p_buffer; - p_data->p_payload_end = p_data->p_buffer + l_size; - - return( p_data ); - -} - - -/***************************************************************************** - * NewPES: allocates a pes packet - *****************************************************************************/ -static pes_packet_t * NewPES( void * p_packet_cache ) -{ - packet_cache_t * p_cache; - pes_packet_t * p_pes; - - p_cache = (packet_cache_t *)p_packet_cache; - -#ifdef DEBUG - if ( p_cache == NULL ) - { - intf_ErrMsg( "Packet cache not initialized" ); - return NULL; - } -#endif - - vlc_mutex_lock( &p_cache->lock ); - - /* Checks whether the PES cache is empty */ - if( p_cache->pes.l_index == 0 ) - { - /* Allocates a new packet */ - p_pes = malloc( sizeof(pes_packet_t) ); - if( p_pes == NULL ) - { - intf_DbgMsg( "Out of memory" ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: PES packet allocated" ); -#endif - } - else - { - /* Takes the packet out from the cache */ - p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ]; - if( p_pes == NULL ) - { - intf_ErrMsg( "NULL packet in the data cache" ); - vlc_mutex_unlock( &p_cache->lock ); - return NULL; - } - } - - vlc_mutex_unlock( &p_cache->lock ); - - p_pes->b_data_alignment = p_pes->b_discontinuity = - p_pes->i_pts = p_pes->i_dts = 0; - p_pes->i_pes_size = 0; - p_pes->p_first = NULL; - - return( p_pes ); - -} - -/***************************************************************************** - * DeletePacket: deletes a data packet - *****************************************************************************/ -static void DeletePacket( void * p_packet_cache, - data_packet_t * p_data ) -{ - packet_cache_t * p_cache; - - p_cache = (packet_cache_t *)p_packet_cache; - -#ifdef DEBUG - if ( p_cache == NULL ) - { - intf_ErrMsg( "Packet cache not initialized" ); - return; - } -#endif - - ASSERT( p_data ); - - vlc_mutex_lock( &p_cache->lock ); - - /* Checks whether the data cache is full */ - if ( p_cache->data.l_index < DATA_CACHE_SIZE ) - { - /* Cache not full: store the packet in it */ - p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data; - /* Small buffer or large buffer? */ - if ( p_data->l_size < MAX_SMALL_SIZE ) - { - /* Checks whether the small buffer cache is full */ - if ( p_cache->smallbuffer.l_index < SMALL_CACHE_SIZE ) - { - p_cache->smallbuffer.p_stack[ - p_cache->smallbuffer.l_index ].l_size = p_data->l_size; - p_cache->smallbuffer.p_stack[ - p_cache->smallbuffer.l_index++ ].p_data = p_data->p_buffer; - } - else - { - ASSERT( p_data->p_buffer ); - free( p_data->p_buffer ); -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: small buffer freed" ); -#endif - } - } - else - { - /* Checks whether the large buffer cache is full */ - if ( p_cache->largebuffer.l_index < LARGE_CACHE_SIZE ) - { - p_cache->largebuffer.p_stack[ - p_cache->largebuffer.l_index ].l_size = p_data->l_size; - p_cache->largebuffer.p_stack[ - p_cache->largebuffer.l_index++ ].p_data = p_data->p_buffer; - } - else - { - ASSERT( p_data->p_buffer ); - free( p_data->p_buffer ); -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: large buffer freed" ); -#endif - } - } - } - else - { - /* Cache full: the packet must be freed */ - free( p_data->p_buffer ); - free( p_data ); -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: data packet freed" ); -#endif - } - - vlc_mutex_unlock( &p_cache->lock ); -} - -/***************************************************************************** - * DeletePES: deletes a PES packet and associated data packets - *****************************************************************************/ -static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes ) -{ - packet_cache_t * p_cache; - data_packet_t * p_data; - data_packet_t * p_next; - - p_cache = (packet_cache_t *)p_packet_cache; - -#ifdef DEBUG - if ( p_cache == NULL ) - { - intf_ErrMsg( "Packet cache not initialized" ); - return; - } -#endif - - ASSERT( p_pes); - - p_data = p_pes->p_first; - - while( p_data != NULL ) - { - p_next = p_data->p_next; - DeletePacket( p_cache, p_data ); - p_data = p_next; - } - - vlc_mutex_lock( &p_cache->lock ); - - /* Checks whether the PES cache is full */ - if ( p_cache->pes.l_index < PES_CACHE_SIZE ) - { - /* Cache not full: store the packet in it */ - p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes; - } - else - { - /* Cache full: the packet must be freed */ - free( p_pes ); -#ifdef TRACE_INPUT - intf_DbgMsg( "PS input: PES packet freed" ); -#endif - } - - vlc_mutex_unlock( &p_cache->lock ); -}