Commit d5b04453 authored by Christophe Massiot's avatar Christophe Massiot

STABLE/HEAD merge ; backported the Next Generation Buffer Manager.

parent f6b7894d
......@@ -110,7 +110,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
# C Objects
#
INTERFACE := main interface intf_msg intf_playlist intf_channels
INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_netlist input_clock mpeg_system
INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
VIDEO_OUTPUT := video_output video_text video_spu video_yuv
AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
MISC := mtime tests modules netutils iso_lang
......
......@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: common.h,v 1.53.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: common.h,v 1.53.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -347,18 +347,6 @@ typedef struct module_symbols_s
struct pgrm_descriptor_s *,
mtime_t );
int ( * input_NetlistInit ) ( struct input_thread_s *,
int, int, int, size_t, int );
struct iovec * ( * input_NetlistGetiovec ) ( void * p_method_data );
void ( * input_NetlistMviovec ) ( void * , int,
struct data_packet_s **);
struct data_packet_s * ( * input_NetlistNewPacket ) ( void *, size_t );
struct data_packet_s * ( * input_NetlistNewPtr ) ( void * );
struct pes_packet_s * ( * input_NetlistNewPES ) ( void * );
void ( * input_NetlistDeletePacket ) ( void *, struct data_packet_s * );
void ( * input_NetlistDeletePES ) ( void *, struct pes_packet_s * );
void ( * input_NetlistEnd ) ( struct input_thread_s * );
struct aout_fifo_s * ( * aout_CreateFifo )
( int, int, long, long, long, void * );
void ( * aout_DestroyFifo ) ( struct aout_fifo_s * );
......
......@@ -97,13 +97,6 @@
/* Environment variable containing the memcpy method */
#define MEMCPY_METHOD_VAR "vlc_memcpy"
/*
* Decoders FIFO configuration
*/
/* Size of the FIFO. FIFO_SIZE+1 must be a power of 2 */
#define FIFO_SIZE 1023
/*
* Paths
*/
......@@ -175,6 +168,9 @@
/* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100
/* Maximum memory the input is allowed to use (20 MB) */
#define INPUT_MAX_ALLOCATION 20971520
/* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
......
......@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.41.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: input_ext-dec.h,v 1.41.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
......@@ -40,22 +40,25 @@
*****************************************************************************
* Describe a data packet.
*****************************************************************************/
#define DATA_PACKET \
/* start of the PS or TS packet */ \
byte_t * p_demux_start; \
/* start of the PES payload in this packet */ \
byte_t * p_payload_start; \
byte_t * p_payload_end; /* guess ? :-) */ \
/* is the packet messed up ? */ \
boolean_t b_discard_payload;
typedef struct data_packet_s
{
/* Nothing before this line, the code relies on that */
byte_t * p_buffer; /* raw data packet */
long l_size; /* buffer size */
/* Decoders information */
byte_t * p_payload_start;
/* start of the PES payload in this packet */
byte_t * p_payload_end; /* guess ? :-) */
boolean_t b_discard_payload; /* is the packet messed up ? */
/* Used to chain the packets that carry data for a same PES or PSI */
struct data_packet_s * p_next;
int * pi_refcount;
DATA_PACKET
/* Used to chain the TS packets that carry data for a same PES or PSI */
struct data_packet_s * p_next;
/* Please note that at least one buffer allocator (in particular, the
* Next Generation Buffer Allocator) extends this structure with
* private data after DATA_PACKET. */
} data_packet_t;
/*****************************************************************************
......@@ -66,6 +69,9 @@ typedef struct data_packet_s
*****************************************************************************/
typedef struct pes_packet_s
{
/* Chained list to the next PES packet (depending on the context) */
struct pes_packet_s * p_next;
/* PES properties */
boolean_t b_data_alignment; /* used to find the beginning of
* a video or audio unit */
......@@ -77,12 +83,15 @@ typedef struct pes_packet_s
int i_rate; /* current pace of reading
* (see stream_control.h) */
int i_pes_size; /* size of the current PES packet */
unsigned int i_pes_size; /* size of the current PES packet */
/* Pointers to packets (packets are then linked by the p_prev and
p_next fields of the data_packet_t struct) */
/* Chained list to packets */
data_packet_t * p_first; /* The first packet contained by this
* PES (used by decoders). */
data_packet_t * p_last; /* The last packet contained by this
PES (used by the buffer allocator) */
unsigned int i_nb_data; /* Number of data packets in the chained
list */
} pes_packet_t;
/*****************************************************************************
......@@ -97,9 +106,9 @@ typedef struct decoder_fifo_s
vlc_cond_t data_wait; /* fifo data conditional variable */
/* Data */
pes_packet_t * buffer[FIFO_SIZE + 1];
int i_start;
int i_end;
pes_packet_t * p_first;
pes_packet_t ** pp_last;
int i_depth; /* number of PES packets in the stack */
/* Communication interface between input and decoders */
boolean_t b_die; /* the decoder should return now */
......@@ -110,18 +119,6 @@ typedef struct decoder_fifo_s
/* function to use when releasing a PES */
} decoder_fifo_t;
/* Macros to manage a decoder_fifo_t structure. Please remember to take
* data_lock before using them. */
#define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
#define DECODER_FIFO_ISFULL( fifo ) ( ( ((fifo).i_end + 1 - (fifo).i_start)\
& FIFO_SIZE ) == 0 )
#define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
& FIFO_SIZE )
#define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
#define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
& FIFO_SIZE )
/*****************************************************************************
* bit_fifo_t : bit fifo descriptor
*****************************************************************************
......
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.51 2001/12/07 16:47:47 jobi Exp $
* $Id: input_ext-intf.h,v 1.51.2.1 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -26,7 +26,6 @@
/*
* Communication input -> interface
*/
#define INPUT_MAX_PLUGINS 1
/* FIXME ! */
#define REQUESTED_MPEG 1
#define REQUESTED_AC3 2
......@@ -66,7 +65,6 @@ typedef struct es_descriptor_s
/* PES parser information */
struct pes_packet_s * p_pes; /* Current PES */
struct data_packet_s * p_last; /* The last packet gathered at present */
int i_pes_real_size; /* as indicated by the header */
/* Decoder information */
......@@ -95,6 +93,7 @@ typedef struct es_descriptor_s
#define SPU_ES 0x02
#define NAV_ES 0x03
#define UNKNOWN_ES 0xFF
/*****************************************************************************
* pgrm_descriptor_t
*****************************************************************************
......@@ -263,7 +262,7 @@ typedef struct input_thread_s
/* Read & Demultiplex */
int (* pf_read)( struct input_thread_s *,
struct data_packet_s * pp_packets[] );
struct data_packet_s ** );
void (* pf_demux)( struct input_thread_s *,
struct data_packet_s * );
......@@ -289,8 +288,6 @@ typedef struct input_thread_s
int i_handle; /* socket or file descriptor */
FILE * p_stream; /* if applicable */
void * p_handle; /* if i_handle isn't suitable */
int i_read_once; /* number of packet read by
* pf_read once */
void * p_method_data; /* data of the packet manager */
void * p_plugin_data; /* data of the plugin */
......
This diff is collapsed.
......@@ -77,15 +77,6 @@
(p_symbols)->input_DemuxTS = input_DemuxTS; \
(p_symbols)->input_DemuxPSI = input_DemuxPSI; \
(p_symbols)->input_ClockManageControl = input_ClockManageControl; \
(p_symbols)->input_NetlistInit = input_NetlistInit; \
(p_symbols)->input_NetlistGetiovec = input_NetlistGetiovec; \
(p_symbols)->input_NetlistMviovec = input_NetlistMviovec; \
(p_symbols)->input_NetlistNewPacket = input_NetlistNewPacket; \
(p_symbols)->input_NetlistNewPtr = input_NetlistNewPtr; \
(p_symbols)->input_NetlistNewPES = input_NetlistNewPES; \
(p_symbols)->input_NetlistDeletePacket = input_NetlistDeletePacket; \
(p_symbols)->input_NetlistDeletePES = input_NetlistDeletePES; \
(p_symbols)->input_NetlistEnd = input_NetlistEnd; \
(p_symbols)->aout_CreateFifo = aout_CreateFifo; \
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
(p_symbols)->vout_CreateThread = vout_CreateThread; \
......
......@@ -2,7 +2,7 @@
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_adec.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: ac3_adec.c,v 1.5.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
......@@ -171,12 +171,12 @@ static int decoder_Run ( decoder_config_t * p_config )
sync = 1;
}
if (DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts)
if (p_ac3thread->p_fifo->p_first->i_pts)
{
p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts;
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts = 0;
p_ac3thread->p_fifo->p_first->i_pts;
p_ac3thread->p_fifo->p_first->i_pts = 0;
} else {
p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] =
......
......@@ -2,7 +2,7 @@
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: ac3_spdif.c,v 1.5.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
......@@ -347,7 +347,7 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
p_bit_stream->p_byte += 3;
p_spdif->i_pts =
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts;
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts = 0;
p_bit_stream->p_decoder_fifo->p_first->i_pts;
p_bit_stream->p_decoder_fifo->p_first->i_pts = 0;
}
}
This diff is collapsed.
This diff is collapsed.
......@@ -2,7 +2,7 @@
* lpcm_decoder_thread.c: lpcm decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: lpcm_adec.c,v 1.3.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: lpcm_adec.c,v 1.3.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
......@@ -187,11 +187,11 @@ void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
int i_loop;
byte_t byte1, byte2;
if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
if( p_lpcmdec->p_fifo->p_first->i_pts )
{
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
p_lpcmdec->p_fifo->p_first->i_pts;
p_lpcmdec->p_fifo->p_first->i_pts = 0;
}
else
{
......
......@@ -62,9 +62,9 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
byte_t buffer[ADEC_FRAME_SIZE];
/* Store time stamp of current frame */
if ( DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts ) {
p_mad_adec->i_pts_save = DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts;
DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts = 0;
if ( p_mad_adec->p_fifo->p_first->i_pts ) {
p_mad_adec->i_pts_save = p_mad_adec->p_fifo->p_first->i_pts;
p_mad_adec->p_fifo->p_first->i_pts = 0;
}
else {
p_mad_adec->i_pts_save = LAST_MDATE;
......
......@@ -2,7 +2,7 @@
* input_es.c: Elementary Stream demux and packet management
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: input_es.c,v 1.16.2.1 2001/12/10 15:56:57 massiot Exp $
* $Id: input_es.c,v 1.16.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Author: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -75,7 +75,7 @@
*****************************************************************************/
static int ESProbe ( probedata_t * );
static int ESRead ( struct input_thread_s *,
data_packet_t * p_packets[INPUT_READ_ONCE] );
data_packet_t ** );
static void ESInit ( struct input_thread_s * );
static void ESEnd ( struct input_thread_s * );
static void ESSeek ( struct input_thread_s *, off_t );
......@@ -89,6 +89,20 @@ static void ESInitBitstream( struct bit_stream_s *, struct decoder_fifo_s *,
void * );
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
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 );
DECLARE_BUFFERS_TOIO( FLAGS, ES_PACKET_SIZE );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
......@@ -106,10 +120,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input.pf_set_program = ESSetProgram;
input.pf_read = ESRead;
input.pf_demux = ESDemux;
input.pf_new_packet = input_NetlistNewPacket;
input.pf_new_pes = input_NetlistNewPES;
input.pf_delete_packet = input_NetlistDeletePacket;
input.pf_delete_pes = input_NetlistDeletePES;
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 = NULL;
input.pf_seek = ESSeek;
#undef input
......@@ -141,27 +155,24 @@ static void ESInit( input_thread_t * p_input )
{
es_descriptor_t * p_es;
p_input->p_method_data = NULL;
/* Initialize netlist */
if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, ES_PACKET_SIZE,
INPUT_READ_ONCE ) )
if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
intf_ErrMsg( "ES input : Could not initialize netlist" );
p_input->b_error = 1;
return;
}
/* FIXME : detect if InitStream failed */
input_InitStream( p_input, 0 );
input_AddProgram( p_input, 0, 0 );
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
vlc_mutex_lock( &p_input->stream.stream_lock );
p_es = input_AddES( p_input, p_input->stream.pp_programs[0], 0xE0, 0 );
p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xE0, 0 );
p_es->i_stream_id = 0xE0;
p_es->i_type = MPEG1_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
input_SelectES( p_input, p_es );
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.pp_programs[0]->b_is_ok = 1;
p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
......@@ -170,49 +181,57 @@ static void ESInit( input_thread_t * p_input )
*****************************************************************************/
static void ESEnd( input_thread_t * p_input )
{
input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
* ESRead: 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 ESRead( input_thread_t * p_input,
data_packet_t * pp_packets[INPUT_READ_ONCE] )
data_packet_t ** pp_data )
{
int i_read;
struct iovec * p_iovec;
struct iovec p_iovec[ES_READ_ONCE];
data_packet_t * p_data;
/* Get iovecs */
p_iovec = input_NetlistGetiovec( p_input->p_method_data );
*pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
ES_READ_ONCE );
if ( p_iovec == NULL )
if ( p_data == NULL )
{
return( -1 ); /* empty netlist */
return( -1 );
}
memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
i_read = readv( p_input->i_handle, p_iovec, ES_READ_ONCE );
if( i_read == -1 )
{
intf_ErrMsg( "input error: ES 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 /= ES_PACKET_SIZE;
/* EOF */
if( i_read == 0 && p_input->stream.b_seekable )
if( i_read != ES_READ_ONCE )
{
return( 1 );
}
/* We got fewer packets than wanted. Give remaining packets
* back to the buffer allocator. */
int i_loop;
input_NetlistMviovec( p_input->p_method_data,
(int)(i_read/ES_PACKET_SIZE), pp_packets );
for( i_loop = 0; i_loop < i_read; i_loop++ )
{
pp_data = &(*pp_data)->p_next;
}
p_input->stream.p_selected_area->i_tell += i_read;
p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
*pp_data = NULL;
}
return( 0 );
return( i_read );
}
/*****************************************************************************
......@@ -241,7 +260,7 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
{
pes_packet_t * p_pes = p_input->pf_new_pes( p_input->p_method_data );
decoder_fifo_t * p_fifo =
p_input->stream.pp_programs[0]->pp_es[0]->p_decoder_fifo;
p_input->stream.p_selected_program->pp_es[0]->p_decoder_fifo;
if( p_pes == NULL )
{
......@@ -251,22 +270,23 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
}
p_pes->i_rate = p_input->stream.control.i_rate;
p_pes->p_first = p_data;
p_pes->p_first = p_pes->p_last = p_data;
p_pes->i_nb_data = 1;
if( (p_input->stream.pp_programs[0]->i_synchro_state == SYNCHRO_REINIT)
| (input_ClockManageControl( p_input, p_input->stream.pp_programs[0],
if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
| (input_ClockManageControl( p_input,
p_input->stream.p_selected_program,
(mtime_t)0 ) == PAUSE_S) )
{
intf_WarnMsg( 2, "synchro reinit" );
p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY;
p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_OK;
p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
}
input_DecodePES( p_fifo, p_pes );
vlc_mutex_lock( &p_fifo->data_lock );
if( ( (DECODER_FIFO_END( *p_fifo ) - DECODER_FIFO_START( *p_fifo ))
& FIFO_SIZE ) >= MAX_PACKETS_IN_FIFO )
if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
......@@ -290,18 +310,23 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL )
{
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
pes_packet_t * p_next;
vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */
p_next = p_fifo->p_first->p_next;
p_fifo->p_first->p_next = NULL;
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_fifo ) );
DECODER_FIFO_INCSTART( *p_fifo );
p_fifo->p_first );
p_fifo->p_first = p_next;
p_fifo->i_depth--;
if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
if( p_fifo->p_first == NULL )
{
/* No PES in the FIFO. p_last is no longer valid. */
p_fifo->pp_last = &p_fifo->p_first;
/* Signal the input thread we're waiting. */
vlc_cond_signal( &p_fifo->data_wait );
......@@ -310,7 +335,7 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
}
/* The next byte could be found in the next PES packet */
p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
p_bit_stream->p_data = p_fifo->p_first->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
......
......@@ -2,7 +2,7 @@
* input_es.h: thread structure of the ES plugin
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: input_es.h,v 1.2 2001/06/27 09:53:56 massiot Exp $
* $Id: input_es.h,v 1.2.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors:
*
......@@ -20,8 +20,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NB_DATA 8192
#define NB_PES 4096
#define ES_PACKET_SIZE 2048
#define MAX_PACKETS_IN_FIFO 14
#define ES_READ_ONCE 50
#define MAX_PACKETS_IN_FIFO 50
This diff is collapsed.
......@@ -2,7 +2,7 @@
* input_ps.h: thread structure of the PS plugin
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ps.h,v 1.9 2001/10/02 16:46:59 massiot Exp $
* $Id: input_ps.h,v 1.9.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
......@@ -22,54 +22,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define DATA_CACHE_SIZE 150
#define PES_CACHE_SIZE 150
#define SMALL_CACHE_SIZE 150
#define LARGE_CACHE_SIZE 150
#define MAX_SMALL_SIZE 50 // frontier between small and large packets
typedef struct
{
data_packet_t ** p_stack;
long l_index;
} data_packet_cache_t;
typedef struct
{
pes_packet_t ** p_stack;
long l_index;
} pes_packet_cache_t;
typedef struct
{
byte_t * p_data;
long l_size;
} packet_buffer_t;
typedef struct
{
packet_buffer_t * p_stack;
long l_index;
} small_buffer_cache_t;
typedef struct
{
packet_buffer_t * p_stack;
long l_index;
} large_buffer_cache_t;
typedef struct
{
vlc_mutex_t lock;
data_packet_cache_t data;
pes_packet_cache_t pes;
small_buffer_cache_t smallbuffer;
large_buffer_cache_t largebuffer;
} packet_cache_t;
#define PS_READ_ONCE 50
......@@ -2,7 +2,7 @@
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ts.c,v 1.42 2001/12/07 18:33:07 sam Exp $
* $Id: input_ts.c,v 1.42.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
*
......@@ -89,7 +89,21 @@ 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] );
data_packet_t ** );
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
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, 1000 );
DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
DECLARE_BUFFERS_TOIO( FLAGS, TS_PACKET_SIZE );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
......@@ -108,10 +122,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input.pf_set_program = input_SetProgram;
input.pf_read = TSRead;
input.pf_demux = input_DemuxTS;
input.pf_new_packet = input_NetlistNewPacket;
input.pf_new_pes = input_NetlistNewPES;
input.pf_delete_packet = input_NetlistDeletePacket;
input.pf_delete_pes = input_NetlistDeletePES;
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 = NULL;
input.pf_seek = NULL;
#undef input
......@@ -160,7 +174,6 @@ static int TSProbe( probedata_t * p_data )
*****************************************************************************/
static void TSInit( input_thread_t * p_input )
{
/* Initialize netlist and TS structures */
thread_ts_data_t * p_method;
es_descriptor_t * p_pat_es;
es_ts_data_t * p_demux_data;
......@@ -184,11 +197,9 @@ static void TSInit( input_thread_t * p_input )
p_input->p_method_data = NULL;
/* Initialize netlist */
if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, TS_PACKET_SIZE,
INPUT_READ_ONCE ) )
if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
intf_ErrMsg( "TS input : Could not initialize netlist" );
p_input->b_error = 1;
return;
}
......@@ -227,23 +238,23 @@ static void TSEnd( input_thread_t * p_input )
input_DelES( p_input, p_pat_es );
free(p_input->p_plugin_data);
input_NetlistEnd( p_input );
input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
* 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;
struct iovec p_iovec[TS_READ_ONCE];
data_packet_t * p_data;
struct timeval timeout;
/* Init */
......@@ -257,9 +268,6 @@ static int TSRead( input_thread_t * p_input,
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 )
......@@ -278,25 +286,26 @@ static int TSRead( input_thread_t * p_input,
if( i_data )
{
/* Get iovecs */
p_iovec = input_NetlistGetiovec( p_input->p_method_data );
*pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
TS_READ_ONCE );
if ( p_iovec == NULL )
if ( p_data == NULL )
{
return( -1 ); /* empty netlist */
return( -1 );
}
#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) ) )
......@@ -306,36 +315,35 @@ static int TSRead( input_thread_t * p_input,
i_read = 0;
}
#endif
/* 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 < i_read; i_loop++ )
{
return( 1 );
}
input_NetlistMviovec( p_input->p_method_data,
(int)(((i_read-1)/TS_PACKET_SIZE)+1) , pp_packets );
/* check correct TS header */
for( i_loop=0; i_loop * TS_PACKET_SIZE < i_read; i_loop++ )
if( (*pp_data)->p_demux_start[0] != 0x47 )
{
if( pp_packets[i_loop]->p_buffer[0] != 0x47 )
intf_ErrMsg( "input error: bad TS packet (starts with "
"0x%.2x, should be 0x47)",
pp_packets[i_loop]->p_buffer[0] );
p_data->p_demux_start[0] );
}
for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
{
pp_packets[i_loop] = NULL;
pp_data = &(*pp_data)->p_next;
}
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, *pp_data );
*pp_data = NULL;
}
}
return 0;
return( i_read );
}
......@@ -2,7 +2,7 @@
* input_ts.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ts.h,v 1.12.2.1 2001/12/09 21:14:19 sam Exp $
* $Id: input_ts.h,v 1.12.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
* Boris Dors <babal@via.ecp.fr>
......@@ -22,10 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NB_DATA 16384
#define NB_PES 8192
/* UDP packets contain 1500 bytes, that is 7 TS packets */
#define TS_READ_ONCE 7
#define BUFFER_SIZE (7 * TS_PACKET_SIZE)
#ifdef WIN32
# define BUFFER_SIZE (7 * TS_PACKET_SIZE)
#endif
/*****************************************************************************
* thread_ts_data_t: private input data
......
......@@ -2,7 +2,7 @@
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: mpeg_adec.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: mpeg_adec.c,v 1.5.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
......@@ -203,11 +203,11 @@ static void DecodeThread( adec_thread_t * p_adec )
buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+ (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
if( p_adec->p_fifo->p_first->i_pts )
{
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
p_adec->p_fifo->p_first->i_pts;
p_adec->p_fifo->p_first->i_pts = 0;
}
else
{
......
......@@ -2,7 +2,7 @@
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: video_parser.c,v 1.6.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: video_parser.c,v 1.6.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
......@@ -281,38 +281,6 @@ static int InitThread( vpar_thread_t *p_vpar )
return( 0 );
}
/*****************************************************************************
* mpeg_vdec_ErrorThread: RunThread() error loop
*****************************************************************************
* This function is called when an error occured during thread main's loop. The
* thread can still receive feed, but must be ready to terminate as soon as
* possible.
*****************************************************************************/
static void mpeg_vdec_ErrorThread( vpar_thread_t *p_vpar )
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
vlc_mutex_lock( &p_vpar->p_fifo->data_lock );
/* Wait until a `die' order is sent */
while( !p_vpar->p_fifo->b_die )
{
/* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(*p_vpar->p_fifo) )
{
p_vpar->p_fifo->pf_delete_pes( p_vpar->p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_vpar->p_fifo) );
DECODER_FIFO_INCSTART( *p_vpar->p_fifo );
}
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_vpar->p_fifo->data_wait, &p_vpar->p_fifo->data_lock );
}
/* We can release the lock before leaving */
vlc_mutex_unlock( &p_vpar->p_fifo->data_lock );
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
......@@ -428,13 +396,13 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
if( b_new_pes )
{
p_vpar->sequence.next_pts =
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts;
p_bit_stream->p_decoder_fifo->p_first->i_pts;
p_vpar->sequence.next_dts =
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_dts;
p_bit_stream->p_decoder_fifo->p_first->i_dts;
p_vpar->sequence.i_current_rate =
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_rate;
p_bit_stream->p_decoder_fifo->p_first->i_rate;
if( DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->b_discontinuity )
if( p_bit_stream->p_decoder_fifo->p_first->b_discontinuity )
{
#ifdef TRACE_VPAR
intf_DbgMsg( "Discontinuity in BitstreamCallback" );
......
......@@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: spu_decoder.c,v 1.5.2.2 2001/12/30 06:06:00 sam Exp $
* $Id: spu_decoder.c,v 1.5.2.3 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -275,7 +275,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
p_spudec->i_spu_size );
/* We cannot display a subpicture with no date */
if( DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts == 0 )
if( p_spudec->p_fifo->p_first->i_pts == 0 )
{
intf_WarnMsg( 3, "spudec error: subtitle without a date" );
return;
......@@ -295,7 +295,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
}
/* Get display time now. If we do it later, we may miss the PTS. */
p_spudec->i_pts = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
p_spudec->i_pts = p_spudec->p_fifo->p_first->i_pts;
/* Allocate the temporary buffer we will parse */
p_src = malloc( p_spudec->i_rle_size );
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* input_vcd.h: thread structure of the VCD plugin
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_vcd.h,v 1.1 2001/10/23 03:17:49 jobi Exp $
* $Id: input_vcd.h,v 1.1.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Author: Johan Bilien <jobi@via.ecp.fr>
*
......@@ -21,25 +21,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
/*****************************************************************************
* thread_vcd_data_t: VCD information
*****************************************************************************/
typedef struct thread_vcd_data_s
{
int vcdhandle; // File descriptor
int nb_tracks; // Nb of tracks (titles)
int current_track; // Current track
int current_sector; // Current Sector
int * tracks_sector; // index of tracks
boolean_t b_end_of_track; // if the end of track is
// reached
} thread_vcd_data_t ;
int i_handle; /* File descriptor */
int nb_tracks; /* Nb of tracks (titles) */
int i_track; /* Current track */
int i_sector; /* Current Sector */
int * p_sectors; /* Track sectors */
boolean_t b_end_of_track; /* If the end of track was reached */
} thread_vcd_data_t;
......@@ -71,129 +71,97 @@
#include "modules.h"
#include "modules_export.h"
#include "input_vcd.h"
#include "linux_cdrom_tools.h"
/*****************************************************************************
* read_toc : Reads the Table of Content of a CD-ROM and fills p_vcd with *
* the read information *
*****************************************************************************/
int read_toc ( thread_vcd_data_t * p_vcd )
* ioctl_ReadTocHeader: Read the TOC header and return the track number.
*****************************************************************************/
int ioctl_GetTrackCount( int i_fd )
{
int i ;
struct cdrom_tochdr tochdr ;
struct cdrom_tocentry tocent ;
int fd = p_vcd->vcdhandle ;
struct cdrom_tochdr tochdr;
/* first we read the TOC header */
if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1)
/* First we read the TOC header */
if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
{
intf_ErrMsg("problem occured when reading CD's TOCHDR\n") ;
return -1 ;
}
p_vcd->nb_tracks = tochdr.cdth_trk1;
/* nb_tracks + 1 because we put the lead_out tracks for computing last
track's size */
p_vcd->tracks_sector = malloc( ( p_vcd->nb_tracks + 1 )
* sizeof( int ) );
if ( p_vcd->tracks_sector == NULL )
{
intf_ErrMsg("could not malloc tracks_sector");
intf_ErrMsg( "vcd error: could not read TOCHDR" );
return -1;
}
/* then for each track we read its TOC entry */
return tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
}
for( i=tochdr.cdth_trk0 ; i <= tochdr.cdth_trk1 ; i++ )
{
tocent.cdte_track = i;
tocent.cdte_format = CDROM_LBA;
if (ioctl( fd, CDROMREADTOCENTRY, &tocent) == -1 )
/*****************************************************************************
* ioctl_GetSectors: Read the Table of Contents and fill p_vcd.
*****************************************************************************/
int * ioctl_GetSectors( int i_fd )
{
int i, i_tracks;
int *p_sectors;
struct cdrom_tochdr tochdr;
struct cdrom_tocentry tocent;
/* First we read the TOC header */
if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
{
intf_ErrMsg( "problem occured when reading CD's TOCENTRY\n" );
free ( p_vcd->tracks_sector );
return -1;
intf_ErrMsg( "vcd error: could not read TOCHDR" );
return NULL;
}
p_vcd->tracks_sector[i-1] = tocent.cdte_addr.lba ;
i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
p_sectors = malloc( (i_tracks + 1) * sizeof(int) );
if( p_sectors == NULL )
{
intf_ErrMsg( "vcd error: could not allocate p_sectors" );
return NULL;
}
/* finally we read the lead-out track toc entry */
/* Fill the p_sectors structure with the track/sector matches */
for( i = 0 ; i <= i_tracks ; i++ )
{
tocent.cdte_format = CDROM_LBA;
tocent.cdte_track =
( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
tocent.cdte_track = CDROM_LEADOUT ;
tocent.cdte_format = CDROM_LBA ;
if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1)
if( ioctl( i_fd, CDROMREADTOCENTRY, &tocent ) == -1 )
{
intf_ErrMsg("problem occured when readind CD's
lead-out track TOC entry") ;
free (p_vcd->tracks_sector) ;
return -1 ;
intf_ErrMsg( "vcd error: could not read TOCENTRY" );
free( p_sectors );
return NULL;
}
p_vcd->tracks_sector[p_vcd->nb_tracks] = tocent.cdte_addr.lba ;
return 1 ;
p_sectors[ i ] = tocent.cdte_addr.lba;
}
return p_sectors;
}
/****************************************************************************
* VCD_sector_read : Function that reads a sector (2324 bytes) from VCD
* ioctl_ReadSector: Read a sector (2324 bytes)
****************************************************************************/
int VCD_sector_read ( struct thread_vcd_data_s * p_vcd, byte_t * p_buffer )
int ioctl_ReadSector( int i_fd, int i_sector, byte_t * p_buffer )
{
byte_t p_read_block[VCD_SECTOR_SIZE] ;
struct cdrom_msf0 msf_cursor ;
msf_cursor = lba2msf( p_vcd->current_sector ) ;
#ifdef DEBUG
intf_DbgMsg("Playing frame %d:%d-%d\n", msf_cursor.minute,
msf_cursor.second, msf_cursor.frame) ;
#endif
memcpy(p_read_block, &msf_cursor, sizeof(struct cdrom_msf0)) ;
if (ioctl(p_vcd->vcdhandle, CDROMREADRAW, p_read_block) == -1)
{
intf_ErrMsg("problem occured when reading CD") ;
free (p_read_block) ;
return -1 ;
}
/* we don't want to keep the header of the read sector */
memcpy( p_buffer, &p_read_block[VCD_DATA_START],
VCD_DATA_SIZE );
byte_t p_block[ VCD_SECTOR_SIZE ];
int i_dummy = i_sector + 2 * CD_FRAMES;
#define p_msf ((struct cdrom_msf0 *)p_block)
p_msf->minute = i_dummy / (CD_FRAMES * CD_SECS);
p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
p_msf->frame = ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
p_vcd->current_sector ++;
intf_DbgMsg( "vcd debug: playing frame %d:%d-%d",
p_msf->minute, p_msf->second, p_msf->frame);
#undef p_msf
if ( p_vcd->current_sector ==
p_vcd->tracks_sector[p_vcd->current_track + 1] )
if( ioctl(i_fd, CDROMREADRAW, p_block) == -1 )
{
p_vcd->b_end_of_track = 1;
intf_ErrMsg( "vcd error: could not read block %i from disc",
i_sector );
return -1;
}
return 1;
}
/*****************************************************************************
* lba2msf : converts a logical block address into a minute/second/frame
* address.
*****************************************************************************/
struct cdrom_msf0 lba2msf( int lba)
{
struct cdrom_msf0 msf_result ;
/* we add 2*CD_FRAMES since the 2 first seconds are not played*/
/* We don't want to keep the header of the read sector */
p_main->fast_memcpy( p_buffer, p_block + VCD_DATA_START, VCD_DATA_SIZE );
msf_result.minute = (lba+2*CD_FRAMES) / ( CD_FRAMES * CD_SECS ) ;
msf_result.second = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )
/ CD_FRAMES ;
msf_result.frame = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )
% CD_FRAMES ;
return msf_result ;
return 0;
}
......@@ -36,7 +36,6 @@
/******************************************************************************
* Prototypes *
******************************************************************************/
int read_toc ( struct thread_vcd_data_s *);
int VCD_sector_read ( struct thread_vcd_data_s *, byte_t *) ;
struct cdrom_msf0 lba2msf ( int ) ;
int ioctl_GetTrackCount ( int );
int * ioctl_GetSectors ( int );
int ioctl_ReadSector ( int, int, byte_t * );
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input.c,v 1.163.2.2 2001/12/12 02:13:20 sam Exp $
* $Id: input.c,v 1.163.2.3 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -120,9 +120,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
return( NULL );
}
/* Packets read once */
p_input->i_read_once = INPUT_READ_ONCE;
/* Initialize thread properties */
p_input->b_die = 0;
p_input->b_error = 0;
......@@ -206,7 +203,7 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
/* Request thread destruction */
p_input->b_die = 1;
/* Make the thread exit of an eventual vlc_cond_wait() */
/* Make the thread exit from an eventual vlc_cond_wait() */
vlc_mutex_lock( &p_input->stream.stream_lock );
vlc_cond_signal( &p_input->stream.stream_wait );
vlc_mutex_unlock( &p_input->stream.stream_lock );
......@@ -229,9 +226,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
*****************************************************************************/
static void RunThread( input_thread_t *p_input )
{
int i_error, i;
data_packet_t ** pp_packets;
if( InitThread( p_input ) )
{
/* If we failed, wait before we are killed, and exit */
......@@ -242,22 +236,16 @@ static void RunThread( input_thread_t *p_input )
return;
}
/* initialization is completed */
/* initialization is complete */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_changed = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
pp_packets = (data_packet_t **) malloc( p_input->i_read_once *
sizeof( data_packet_t * ) );
if( pp_packets == NULL )
{
intf_ErrMsg( "input error: out of memory" );
free( pp_packets );
p_input->b_error = 1;
}
while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
{
data_packet_t * p_data;
int i_count, i;
p_input->c_loops++;
vlc_mutex_lock( &p_input->stream.stream_lock );
......@@ -357,32 +345,32 @@ static void RunThread( input_thread_t *p_input )
vlc_mutex_unlock( &p_input->stream.stream_lock );
i_error = p_input->pf_read( p_input, pp_packets );
i_count = p_input->pf_read( p_input, &p_data );
/* Demultiplex read packets. */
for( i = 0; i < p_input->i_read_once && pp_packets[i] != NULL; i++ )
while( p_data != NULL )
{
data_packet_t * p_next = p_data->p_next;
p_data->p_next = NULL;
p_input->stream.c_packets_read++;
p_input->pf_demux( p_input, pp_packets[i] );
p_input->pf_demux( p_input, p_data );
p_data = p_next;
}
if( i_error )
{
if( i_error == 1 )
if( i_count == 0 && p_input->stream.b_seekable )
{
/* End of file - we do not set b_die because only the
* interface is allowed to do so. */
intf_WarnMsg( 3, "input: EOF reached" );
p_input->b_eof = 1;
}
else
else if( i_count < 0 )
{
p_input->b_error = 1;
}
}
}
free( pp_packets );
if( p_input->b_error || p_input->b_eof )
{
......@@ -401,7 +389,6 @@ static void RunThread( input_thread_t *p_input )
*****************************************************************************/
static int InitThread( input_thread_t * p_input )
{
/* Initialize statistics */
p_input->c_loops = 0;
p_input->stream.c_packets_read = 0;
......
......@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_dec.c,v 1.19 2001/12/03 16:18:37 sam Exp $
* $Id: input_dec.c,v 1.19.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -144,21 +144,13 @@ void input_DecodePES( decoder_fifo_t * p_decoder_fifo, pes_packet_t * p_pes )
{
vlc_mutex_lock( &p_decoder_fifo->data_lock );
if( !DECODER_FIFO_ISFULL( *p_decoder_fifo ) )
{
p_decoder_fifo->buffer[p_decoder_fifo->i_end] = p_pes;
DECODER_FIFO_INCEND( *p_decoder_fifo );
p_pes->p_next = NULL;
*p_decoder_fifo->pp_last = p_pes;
p_decoder_fifo->pp_last = &p_pes->p_next;
p_decoder_fifo->i_depth++;
/* Warn the decoder that it's got work to do. */
vlc_cond_signal( &p_decoder_fifo->data_wait );
}
else
{
/* The FIFO is full !!! This should not happen. */
p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
p_pes );
intf_ErrMsg( "PES trashed - decoder fifo full !" );
}
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
}
......@@ -261,7 +253,9 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
p_config->i_type = p_es->i_type;
p_config->p_stream_ctrl = &p_input->stream.control;
p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0;
p_config->p_decoder_fifo->p_first = NULL;
p_config->p_decoder_fifo->pp_last = &p_config->p_decoder_fifo->p_first;
p_config->p_decoder_fifo->i_depth = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
......@@ -274,14 +268,13 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
*****************************************************************************/
static void DeleteDecoderConfig( decoder_config_t * p_config )
{
intf_StatMsg( "input stats: killing decoder for 0x%x, type 0x%x, %d PES in FIFO",
p_config->i_id, p_config->i_type,
p_config->p_decoder_fifo->i_depth );
/* Free all packets still in the decoder fifo. */
while( !DECODER_FIFO_ISEMPTY( *p_config->p_decoder_fifo ) )
{
p_config->p_decoder_fifo->pf_delete_pes(
p_config->p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_config->p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_config->p_decoder_fifo );
}
p_config->p_decoder_fifo->p_first );
/* Destroy the lock and cond */
vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait );
......
......@@ -2,7 +2,7 @@
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ext-dec.c,v 1.21.2.1 2001/12/30 06:06:00 sam Exp $
* $Id: input_ext-dec.c,v 1.21.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -55,7 +55,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
/* Get the first data packet. */
vlc_mutex_lock( &p_fifo->data_lock );
while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
while ( p_fifo->p_first == NULL )
{
if ( p_fifo->b_die )
{
......@@ -64,7 +64,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
}
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
p_bit_stream->p_data = p_fifo->p_first->p_first;
p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
p_bit_stream->fifo.buffer = 0;
......@@ -100,12 +100,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
while( !p_fifo->b_die )
{
/* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(*p_fifo) )
{
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_fifo) );
DECODER_FIFO_INCSTART( *p_fifo );
}
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
......@@ -131,24 +126,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL )
{
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
pes_packet_t * p_next;
vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */
p_next = p_fifo->p_first->p_next;
p_fifo->p_first->p_next = NULL;
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_fifo ) );
DECODER_FIFO_INCSTART( *p_fifo );
p_fifo->p_first );
p_fifo->p_first = p_next;
p_fifo->i_depth--;
if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
if( p_fifo->p_first == NULL )
{
/* No PES in the FIFO. p_last is no longer valid. */
p_fifo->pp_last = &p_fifo->p_first;
/* Wait for the input to tell us when we receive a packet. */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
/* The next byte could be found in the next PES packet */
p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
p_bit_stream->p_data = p_fifo->p_first->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: mpeg_system.c,v 1.69.2.4 2001/12/17 16:37:25 sam Exp $
* $Id: mpeg_system.c,v 1.69.2.5 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
......@@ -136,7 +136,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
!= PES_HEADER_SIZE )
{
intf_WarnMsg( 1, "PES packet too short to have a header" );
intf_WarnMsg( 1, "input: PES packet too short to have a header" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
......@@ -154,7 +154,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
{
/* packet_start_code_prefix != 0x000001 */
intf_ErrMsg( "PES packet doesn't start with 0x000001 : data loss" );
intf_ErrMsg( "input error: data loss, "
"PES packet doesn't start with 0x000001" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
}
......@@ -167,7 +168,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
{
/* PES_packet_length is set and != total received payload */
/* Warn the decoder that the data may be corrupt. */
intf_WarnMsg( 1, "PES sizes do not match : packet corrupted" );
intf_WarnMsg( 1, "input: packet corrupted, "
"PES sizes do not match" );
}
switch( p_es->i_stream_id )
......@@ -273,7 +275,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
}
if( i_pes_header_size == 23 )
{
intf_ErrMsg( "Too much MPEG-1 stuffing" );
intf_ErrMsg( "input error: too much MPEG-1 stuffing" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
......@@ -474,10 +476,11 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
else
{
/* Update the relations between the data packets */
p_es->p_last->p_next = p_data;
p_pes->p_last->p_next = p_data;
}
p_es->p_last = p_data;
p_pes->p_last = p_data;
p_pes->i_nb_data++;
/* Size of the payload carried in the data packet */
p_pes->i_pes_size += (p_data->p_payload_end
......@@ -505,13 +508,13 @@ static u16 GetID( data_packet_t * p_data )
{
u16 i_id;
i_id = p_data->p_payload_start[3]; /* stream_id */
i_id = p_data->p_demux_start[3]; /* stream_id */
if( i_id == 0xBD )
{
/* FIXME : this is not valid if the header is split in multiple
* packets */
/* stream_private_id */
i_id |= p_data->p_payload_start[ 9 + p_data->p_payload_start[8] ] << 8;
i_id |= p_data->p_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
}
return( i_id );
}
......@@ -530,14 +533,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
int i;
int i_new_es_number = 0;
if( p_data->p_payload_start + 10 > p_data->p_payload_end )
if( p_data->p_demux_start + 10 > p_data->p_payload_end )
{
intf_ErrMsg( "PSM too short : packet corrupt" );
return;
}
if( p_demux->b_has_PSM
&& p_demux->i_PSM_version == (p_data->p_payload_start[6] & 0x1F) )
&& p_demux->i_PSM_version == (p_data->p_demux_start[6] & 0x1F) )
{
/* Already got that one. */
return;
......@@ -545,12 +548,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
intf_DbgMsg( "Building PSM" );
p_demux->b_has_PSM = 1;
p_demux->i_PSM_version = p_data->p_payload_start[6] & 0x1F;
p_demux->i_PSM_version = p_data->p_demux_start[6] & 0x1F;
/* Go to elementary_stream_map_length, jumping over
* program_stream_info. */
p_byte = p_data->p_payload_start + 10
+ U16_AT(&p_data->p_payload_start[8]);
p_byte = p_data->p_demux_start + 10
+ U16_AT(&p_data->p_demux_start[8]);
if( p_byte > p_data->p_payload_end )
{
intf_ErrMsg( "PSM too short : packet corrupt" );
......@@ -655,7 +658,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
u32 i_code;
es_descriptor_t * p_es = NULL;
i_code = p_data->p_payload_start[3];
i_code = p_data->p_demux_start[3];
if( i_code > 0xBC ) /* ES start code */
{
......@@ -694,7 +697,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
i_id, 0 );
if( p_es != NULL )
{
p_es->i_stream_id = p_data->p_payload_start[3];
p_es->i_stream_id = p_data->p_demux_start[3];
/* Set stream type and auto-spawn. */
if( (i_id & 0xF0) == 0xE0 )
......@@ -794,7 +797,10 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
boolean_t b_trash = 0;
es_descriptor_t * p_es = NULL;
i_code = U32_AT( p_data->p_payload_start );
i_code = ((u32)p_data->p_demux_start[0] << 24)
| ((u32)p_data->p_demux_start[1] << 16)
| ((u32)p_data->p_demux_start[2] << 8)
| p_data->p_demux_start[3];
if( i_code <= 0x1BC )
{
switch( i_code )
......@@ -805,12 +811,12 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
mtime_t scr_time;
u32 i_mux_rate;
if( (p_data->p_payload_start[4] & 0xC0) == 0x40 )
if( (p_data->p_demux_start[4] & 0xC0) == 0x40 )
{
/* MPEG-2 */
byte_t p_header[14];
byte_t * p_byte;
p_byte = p_data->p_payload_start;
p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 14 ) != 14 )
{
......@@ -841,7 +847,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
/* MPEG-1 SCR is like PTS. */
byte_t p_header[12];
byte_t * p_byte;
p_byte = p_data->p_payload_start;
p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 12 ) != 12 )
{
......@@ -943,7 +949,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
es_ts_data_t * p_es_demux = NULL;
pgrm_ts_data_t * p_pgrm_demux = NULL;
#define p (p_data->p_buffer)
#define p (p_data->p_demux_start)
/* Extract flags values from TS common header. */
i_pid = ((p[1] & 0x1F) << 8) | p[2];
b_unit_start = (p[1] & 0x40);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment