* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.12 2001/04/05 14:00:28 asmax Exp $
+ * $Id: input_ps.c,v 1.25 2001/05/30 17:03:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
#include <stdlib.h>
#include <string.h>
+#ifdef STRNCASECMP_IN_STRINGS_H
+# include <strings.h>
+#endif
#include <errno.h>
#include <sys/types.h>
#define input p_function_list->functions.input
p_function_list->pf_probe = PSProbe;
input.pf_init = PSInit;
- input.pf_open = input_FileOpen;
- input.pf_close = input_FileClose;
+ input.pf_open = NULL; /* Set in PSInit */
+ input.pf_close = NULL;
input.pf_end = PSEnd;
input.pf_set_area = NULL;
input.pf_read = PSRead;
static void PSInit( input_thread_t * p_input )
{
thread_ps_data_t * p_method;
- packet_cache_t * p_packet_cache;
+ packet_cache_t * p_packet_cache;
if( (p_method =
(thread_ps_data_t *)malloc( sizeof(thread_ps_data_t) )) == NULL )
return;
}
p_input->p_method_data = (void *)p_packet_cache;
+
+ /* Set callback */
+ p_input->pf_open = p_input->pf_file_open;
+ p_input->pf_close = p_input->pf_file_close;
+
+ /* 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 *
if ( p_packet_cache->data.p_stack == NULL )
{
intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
+ p_input->b_error = 1;
+ return;
}
p_packet_cache->data.l_index = 0;
}
rewind( p_method->stream );
vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ p_input->stream.i_method = INPUT_METHOD_FILE;
p_input->stream.p_selected_area->i_tell = 0;
+
if( p_demux_data->b_has_PSM )
{
/* (The PSM decoder will care about spawning the decoders) */
break;
case LPCM_AUDIO_ES:
- /* FIXME ! */
+ if( main_GetIntVariable( INPUT_CHANNEL_VAR, 0 )
+ == ((p_es->i_id & 0x1F00) >> 8) )
+ switch( main_GetIntVariable( INPUT_AUDIO_VAR, 0 ) )
+ {
+ case 0:
+ main_PutIntVariable( INPUT_AUDIO_VAR,
+ REQUESTED_LPCM );
+ case REQUESTED_LPCM:
+ input_SelectES( p_input, p_es );
+ }
break;
}
}
{
/* The programs will be added when we read them. */
vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.i_method = INPUT_METHOD_FILE;
p_input->stream.pp_programs[0]->b_is_ok = 0;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
*****************************************************************************/
static void PSEnd( input_thread_t * p_input )
{
+ vlc_mutex_destroy( &((packet_cache_t *)p_input->p_plugin_data)->lock );
free( p_input->p_plugin_data );
}
/* 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( 1, "Garbage at input (%.8x)", i_startcode );
+ intf_WarnMsg( 3, "Garbage at input (%.8x)", i_startcode );
}
while( (i_startcode & 0xFFFFFF00) != 0x100L )
/* Give the packet to the other input stages. */
pp_packets[i_packet] = p_data;
-//fprintf(stderr, "read2 %li %li\n", p_data, p_data->l_size);
}
return( 0 );
p_method = (thread_ps_data_t *)p_input->p_plugin_data;
/* A little bourrin but should work for a while --Meuuh */
+#ifndef WIN32
fseeko( p_method->stream, i_position, SEEK_SET );
+#else
+ fseek( p_method->stream, (long)i_position, SEEK_SET );
+#endif
p_input->stream.p_selected_area->i_tell = i_position;
}
data_packet_t * p_data;
long l_index;
- if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+ 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 )
{
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 */
if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL )
{
- intf_DbgMsg( "Out of memory" );
+ 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
{
if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ])
== NULL )
{
- intf_DbgMsg( "NULL packet in the data cache" );
+ intf_ErrMsg( "NULL packet in the data cache" );
+ vlc_mutex_unlock( &p_cache->lock );
return NULL;
}
}
/* Checks whether the buffer cache is empty */
if( p_cache->small.l_index == 0 )
{
- /* Allocates a new packet */
+ /* Allocates a new packet */
if ( (p_data->p_buffer = malloc( l_size )) == 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
if( (p_data->p_buffer = p_cache->small.p_stack[l_index].p_data)
== NULL )
{
- intf_DbgMsg( "NULL packet in the small buffer cache" );
+ 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 */
+ /* Reallocates the packet if it is too small or too large */
if( p_cache->small.p_stack[l_index].l_size < l_size ||
p_cache->small.p_stack[l_index].l_size > 2*l_size )
{
/* Checks whether the buffer cache is empty */
if( p_cache->large.l_index == 0 )
{
- /* Allocates a new packet */
+ /* Allocates a new packet */
if ( (p_data->p_buffer = malloc( l_size )) == NULL )
{
- intf_DbgMsg( "Out of memory" );
+ 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
if( (p_data->p_buffer = p_cache->large.p_stack[l_index].p_data)
== NULL )
{
- intf_DbgMsg( "NULL packet in the small buffer cache" );
+ 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 */
+ /* Reallocates the packet if it is too small or too large */
if( p_cache->large.p_stack[l_index].l_size < l_size ||
p_cache->large.p_stack[l_index].l_size > 2*l_size )
{
{
p_data->l_size = p_cache->large.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;
-//fprintf(stderr, "addr: %li %li buf %li\n", p_data, p_data->l_size, p_data->p_buffer);
return( p_data );
-
+
}
packet_cache_t * p_cache;
pes_packet_t * p_pes;
- if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+ 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 )
{
if ( (p_pes = malloc( sizeof(pes_packet_t) )) == 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
{
if( (p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ])
== NULL )
{
- intf_DbgMsg( "NULL packet in the data cache" );
+ 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;
data_packet_t * p_data )
{
packet_cache_t * p_cache;
-
- if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+
+ 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 );
- 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 )
{
ASSERT( p_data->p_buffer );
free( p_data->p_buffer );
+#ifdef TRACE_INPUT
+ intf_DbgMsg( "PS input: small buffer freed" );
+#endif
}
}
- else
+ else
{
/* Checks whether the large buffer cache is full */
if ( p_cache->large.l_index < LARGE_CACHE_SIZE )
{
ASSERT( p_data->p_buffer );
free( p_data->p_buffer );
+#ifdef TRACE_INPUT
+ intf_DbgMsg( "PS input: large buffer freed" );
+#endif
}
}
}
{
/* Cache full: the packet must be freed */
free( p_data->p_buffer );
- free( p_data );
+ free( p_data );
+#ifdef TRACE_INPUT
+ intf_DbgMsg( "PS input: data packet freed" );
+#endif
}
+ vlc_mutex_unlock( &p_cache->lock );
}
/*****************************************************************************
data_packet_t * p_data;
data_packet_t * p_next;
- if ( (p_cache = (packet_cache_t *)p_packet_cache) == NULL )
+ 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_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 */
+ /* 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 );
}