* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ts.c,v 1.6 2001/12/27 01:49:34 massiot Exp $
+ * $Id: input_ts.c,v 1.7 2001/12/27 03:47:09 massiot Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
*
static int TSProbe ( probedata_t * );
static void TSInit ( struct input_thread_s * );
static void TSEnd ( struct input_thread_s * );
-static int TSRead ( struct input_thread_s *,
- data_packet_t * p_packets[INPUT_READ_ONCE] );
+static int TSRead ( struct input_thread_s *, data_packet_t ** );
/*****************************************************************************
* Declare a buffer manager
/*****************************************************************************
* TSRead: reads data packets
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
static int TSRead( input_thread_t * p_input,
- data_packet_t * pp_packets[INPUT_READ_ONCE] )
+ data_packet_t ** pp_data )
{
thread_ts_data_t * p_method;
- unsigned int i_loop;
- int i_read;
+ int i_read = 0, i_loop;
int i_data = 1;
- struct iovec p_iovec[INPUT_READ_ONCE];
+ struct iovec p_iovec[TS_READ_ONCE];
data_packet_t * p_data;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
- /* Reset pointer table */
- memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
-
/* Fill if some data is available */
#if defined( WIN32 )
if ( ! p_input->stream.b_pace_control )
if( i_data )
{
/* Get iovecs */
- p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
- INPUT_READ_ONCE );
+ *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
+ TS_READ_ONCE );
if ( p_data == NULL )
{
#if defined( WIN32 )
if( p_input->stream.b_pace_control )
{
- i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+ i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
}
else
{
i_read = readv_network( p_input->i_handle, p_iovec,
- INPUT_READ_ONCE, p_method );
+ TS_READ_ONCE, p_method );
}
#else
- i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+ i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
/* Shouldn't happen, but it does - at least under Linux */
if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) )
i_read = 0;
}
#endif
- /* check correct TS header */
- for( i_loop=0; i_loop * TS_PACKET_SIZE < i_read; i_loop++ )
- {
- pp_packets[i_loop] = p_data;
- p_data = p_data->p_next;
- pp_packets[i_loop]->p_next = NULL;
-
- if( pp_packets[i_loop]->p_demux_start[0] != 0x47 )
- intf_ErrMsg( "input error: bad TS packet (starts with "
- "0x%.2x, should be 0x47)",
- pp_packets[i_loop]->p_demux_start[0] );
- }
- /* Delete remaining packets */
- input_DeletePacket( p_input->p_method_data, p_data );
- for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
- {
- pp_packets[i_loop] = NULL;
- }
-
/* Error */
if( i_read == -1 )
{
intf_ErrMsg( "input error: TS readv error" );
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( -1 );
}
+ p_input->stream.p_selected_area->i_tell += i_read;
+ i_read /= TS_PACKET_SIZE;
- /* EOF */
- if( i_read == 0 && p_input->stream.b_seekable )
+ /* Check correct TS header */
+ for( i_loop = 0; i_loop + 1 < i_read; i_loop++ )
{
- return( 1 );
+ if( p_data->p_demux_start[0] != 0x47 )
+ {
+ intf_ErrMsg( "input error: bad TS packet (starts with "
+ "0x%.2x, should be 0x47)",
+ p_data->p_demux_start[0] );
+ }
+ p_data = p_data->p_next;
}
+ /* Last packet */
+ if( p_data->p_demux_start[0] != 0x47 )
+ {
+ intf_ErrMsg( "input error: bad TS packet (starts with "
+ "0x%.2x, should be 0x47)",
+ p_data->p_demux_start[0] );
+ }
- p_input->stream.p_selected_area->i_tell += i_read;
+ if( i_read != TS_READ_ONCE )
+ {
+ /* Delete remaining packets */
+ p_input->pf_delete_packet( p_input->p_method_data, p_data->p_next );
+ if( i_read != 0 )
+ {
+ p_data->p_next = NULL;
+ }
+ }
}
- return 0;
+ return( i_read );
}