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 \ ...@@ -110,7 +110,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
# C Objects # C Objects
# #
INTERFACE := main interface intf_msg intf_playlist intf_channels 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 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 AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
MISC := mtime tests modules netutils iso_lang MISC := mtime tests modules netutils iso_lang
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions * Collection of useful common types and macros definitions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * 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> * Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr> * Vincent Seguin <seguin@via.ecp.fr>
...@@ -347,18 +347,6 @@ typedef struct module_symbols_s ...@@ -347,18 +347,6 @@ typedef struct module_symbols_s
struct pgrm_descriptor_s *, struct pgrm_descriptor_s *,
mtime_t ); 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 ) struct aout_fifo_s * ( * aout_CreateFifo )
( int, int, long, long, long, void * ); ( int, int, long, long, long, void * );
void ( * aout_DestroyFifo ) ( struct aout_fifo_s * ); void ( * aout_DestroyFifo ) ( struct aout_fifo_s * );
......
...@@ -97,13 +97,6 @@ ...@@ -97,13 +97,6 @@
/* Environment variable containing the memcpy method */ /* Environment variable containing the memcpy method */
#define MEMCPY_METHOD_VAR "vlc_memcpy" #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 * Paths
*/ */
...@@ -175,6 +168,9 @@ ...@@ -175,6 +168,9 @@
/* Maximum length of a hostname or source name */ /* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100 #define INPUT_MAX_SOURCE_LENGTH 100
/* Maximum memory the input is allowed to use (20 MB) */
#define INPUT_MAX_ALLOCATION 20971520
/* Default network protocol */ /* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol" #define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts" #define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders * input_ext-dec.h: structures exported to the VideoLAN decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr> * Michel Kaempf <maxx@via.ecp.fr>
...@@ -40,22 +40,25 @@ ...@@ -40,22 +40,25 @@
***************************************************************************** *****************************************************************************
* Describe a data packet. * 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 typedef struct data_packet_s
{ {
/* Nothing before this line, the code relies on that */ /* Used to chain the packets that carry data for a same PES or PSI */
byte_t * p_buffer; /* raw data packet */ struct data_packet_s * p_next;
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 ? */
int * pi_refcount; DATA_PACKET
/* Used to chain the TS packets that carry data for a same PES or PSI */ /* Please note that at least one buffer allocator (in particular, the
struct data_packet_s * p_next; * Next Generation Buffer Allocator) extends this structure with
* private data after DATA_PACKET. */
} data_packet_t; } data_packet_t;
/***************************************************************************** /*****************************************************************************
...@@ -66,6 +69,9 @@ typedef struct data_packet_s ...@@ -66,6 +69,9 @@ typedef struct data_packet_s
*****************************************************************************/ *****************************************************************************/
typedef struct pes_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 */ /* PES properties */
boolean_t b_data_alignment; /* used to find the beginning of boolean_t b_data_alignment; /* used to find the beginning of
* a video or audio unit */ * a video or audio unit */
...@@ -77,12 +83,15 @@ typedef struct pes_packet_s ...@@ -77,12 +83,15 @@ typedef struct pes_packet_s
int i_rate; /* current pace of reading int i_rate; /* current pace of reading
* (see stream_control.h) */ * (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 /* Chained list to packets */
p_next fields of the data_packet_t struct) */
data_packet_t * p_first; /* The first packet contained by this data_packet_t * p_first; /* The first packet contained by this
* PES (used by decoders). */ * 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; } pes_packet_t;
/***************************************************************************** /*****************************************************************************
...@@ -97,9 +106,9 @@ typedef struct decoder_fifo_s ...@@ -97,9 +106,9 @@ typedef struct decoder_fifo_s
vlc_cond_t data_wait; /* fifo data conditional variable */ vlc_cond_t data_wait; /* fifo data conditional variable */
/* Data */ /* Data */
pes_packet_t * buffer[FIFO_SIZE + 1]; pes_packet_t * p_first;
int i_start; pes_packet_t ** pp_last;
int i_end; int i_depth; /* number of PES packets in the stack */
/* Communication interface between input and decoders */ /* Communication interface between input and decoders */
boolean_t b_die; /* the decoder should return now */ boolean_t b_die; /* the decoder should return now */
...@@ -110,18 +119,6 @@ typedef struct decoder_fifo_s ...@@ -110,18 +119,6 @@ typedef struct decoder_fifo_s
/* function to use when releasing a PES */ /* function to use when releasing a PES */
} decoder_fifo_t; } 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 * bit_fifo_t : bit fifo descriptor
***************************************************************************** *****************************************************************************
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* control the pace of reading. * control the pace of reading.
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
/* /*
* Communication input -> interface * Communication input -> interface
*/ */
#define INPUT_MAX_PLUGINS 1
/* FIXME ! */ /* FIXME ! */
#define REQUESTED_MPEG 1 #define REQUESTED_MPEG 1
#define REQUESTED_AC3 2 #define REQUESTED_AC3 2
...@@ -66,7 +65,6 @@ typedef struct es_descriptor_s ...@@ -66,7 +65,6 @@ typedef struct es_descriptor_s
/* PES parser information */ /* PES parser information */
struct pes_packet_s * p_pes; /* Current PES */ 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 */ int i_pes_real_size; /* as indicated by the header */
/* Decoder information */ /* Decoder information */
...@@ -95,6 +93,7 @@ typedef struct es_descriptor_s ...@@ -95,6 +93,7 @@ typedef struct es_descriptor_s
#define SPU_ES 0x02 #define SPU_ES 0x02
#define NAV_ES 0x03 #define NAV_ES 0x03
#define UNKNOWN_ES 0xFF #define UNKNOWN_ES 0xFF
/***************************************************************************** /*****************************************************************************
* pgrm_descriptor_t * pgrm_descriptor_t
***************************************************************************** *****************************************************************************
...@@ -263,7 +262,7 @@ typedef struct input_thread_s ...@@ -263,7 +262,7 @@ typedef struct input_thread_s
/* Read & Demultiplex */ /* Read & Demultiplex */
int (* pf_read)( struct input_thread_s *, int (* pf_read)( struct input_thread_s *,
struct data_packet_s * pp_packets[] ); struct data_packet_s ** );
void (* pf_demux)( struct input_thread_s *, void (* pf_demux)( struct input_thread_s *,
struct data_packet_s * ); struct data_packet_s * );
...@@ -289,8 +288,6 @@ typedef struct input_thread_s ...@@ -289,8 +288,6 @@ typedef struct input_thread_s
int i_handle; /* socket or file descriptor */ int i_handle; /* socket or file descriptor */
FILE * p_stream; /* if applicable */ FILE * p_stream; /* if applicable */
void * p_handle; /* if i_handle isn't suitable */ 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_method_data; /* data of the packet manager */
void * p_plugin_data; /* data of the plugin */ void * p_plugin_data; /* data of the plugin */
......
This diff is collapsed.
...@@ -77,15 +77,6 @@ ...@@ -77,15 +77,6 @@
(p_symbols)->input_DemuxTS = input_DemuxTS; \ (p_symbols)->input_DemuxTS = input_DemuxTS; \
(p_symbols)->input_DemuxPSI = input_DemuxPSI; \ (p_symbols)->input_DemuxPSI = input_DemuxPSI; \
(p_symbols)->input_ClockManageControl = input_ClockManageControl; \ (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_CreateFifo = aout_CreateFifo; \
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \ (p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
(p_symbols)->vout_CreateThread = vout_CreateThread; \ (p_symbols)->vout_CreateThread = vout_CreateThread; \
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_adec.c: ac3 decoder module main file * ac3_adec.c: ac3 decoder module main file
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Lespinasse <walken@zoy.org>
* *
...@@ -171,12 +171,12 @@ static int decoder_Run ( decoder_config_t * p_config ) ...@@ -171,12 +171,12 @@ static int decoder_Run ( decoder_config_t * p_config )
sync = 1; 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->date[
p_ac3thread->p_aout_fifo->l_end_frame] = p_ac3thread->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts; p_ac3thread->p_fifo->p_first->i_pts;
DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts = 0; p_ac3thread->p_fifo->p_first->i_pts = 0;
} else { } else {
p_ac3thread->p_aout_fifo->date[ p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] = p_ac3thread->p_aout_fifo->l_end_frame] =
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard * ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi> * Juha Yrjola <jyrjola@cc.hut.fi>
...@@ -347,7 +347,7 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream, ...@@ -347,7 +347,7 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
p_bit_stream->p_byte += 3; p_bit_stream->p_byte += 3;
p_spdif->i_pts = p_spdif->i_pts =
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts; p_bit_stream->p_decoder_fifo->p_first->i_pts;
DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts = 0; p_bit_stream->p_decoder_fifo->p_first->i_pts = 0;
} }
} }
This diff is collapsed.
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* lpcm_decoder_thread.c: lpcm decoder thread * lpcm_decoder_thread.c: lpcm decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -187,11 +187,11 @@ void DecodeFrame( lpcmdec_thread_t * p_lpcmdec ) ...@@ -187,11 +187,11 @@ void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
int i_loop; int i_loop;
byte_t byte1, byte2; 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] = p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts; p_lpcmdec->p_fifo->p_first->i_pts;
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0; p_lpcmdec->p_fifo->p_first->i_pts = 0;
} }
else else
{ {
......
...@@ -62,9 +62,9 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream) ...@@ -62,9 +62,9 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
byte_t buffer[ADEC_FRAME_SIZE]; byte_t buffer[ADEC_FRAME_SIZE];
/* Store time stamp of current frame */ /* Store time stamp of current frame */
if ( DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts ) { if ( p_mad_adec->p_fifo->p_first->i_pts ) {
p_mad_adec->i_pts_save = DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts; p_mad_adec->i_pts_save = p_mad_adec->p_fifo->p_first->i_pts;
DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts = 0; p_mad_adec->p_fifo->p_first->i_pts = 0;
} }
else { else {
p_mad_adec->i_pts_save = LAST_MDATE; p_mad_adec->i_pts_save = LAST_MDATE;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_es.c: Elementary Stream demux and packet management * input_es.c: Elementary Stream demux and packet management
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Author: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
*****************************************************************************/ *****************************************************************************/
static int ESProbe ( probedata_t * ); static int ESProbe ( probedata_t * );
static int ESRead ( struct input_thread_s *, 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 ESInit ( struct input_thread_s * );
static void ESEnd ( struct input_thread_s * ); static void ESEnd ( struct input_thread_s * );
static void ESSeek ( struct input_thread_s *, off_t ); static void ESSeek ( struct input_thread_s *, off_t );
...@@ -89,6 +89,20 @@ static void ESInitBitstream( struct bit_stream_s *, struct decoder_fifo_s *, ...@@ -89,6 +89,20 @@ static void ESInitBitstream( struct bit_stream_s *, struct decoder_fifo_s *,
void * ); 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 * Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much. * we don't pollute the namespace too much.
...@@ -106,10 +120,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list ) ...@@ -106,10 +120,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input.pf_set_program = ESSetProgram; input.pf_set_program = ESSetProgram;
input.pf_read = ESRead; input.pf_read = ESRead;
input.pf_demux = ESDemux; input.pf_demux = ESDemux;
input.pf_new_packet = input_NetlistNewPacket; input.pf_new_packet = input_NewPacket;
input.pf_new_pes = input_NetlistNewPES; input.pf_new_pes = input_NewPES;
input.pf_delete_packet = input_NetlistDeletePacket; input.pf_delete_packet = input_DeletePacket;
input.pf_delete_pes = input_NetlistDeletePES; input.pf_delete_pes = input_DeletePES;
input.pf_rewind = NULL; input.pf_rewind = NULL;
input.pf_seek = ESSeek; input.pf_seek = ESSeek;
#undef input #undef input
...@@ -141,27 +155,24 @@ static void ESInit( input_thread_t * p_input ) ...@@ -141,27 +155,24 @@ static void ESInit( input_thread_t * p_input )
{ {
es_descriptor_t * p_es; es_descriptor_t * p_es;
p_input->p_method_data = NULL; if( (p_input->p_method_data = input_BuffersInit()) == NULL )
/* Initialize netlist */
if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, ES_PACKET_SIZE,
INPUT_READ_ONCE ) )
{ {
intf_ErrMsg( "ES input : Could not initialize netlist" ); p_input->b_error = 1;
return; return;
} }
/* FIXME : detect if InitStream failed */ /* FIXME : detect if InitStream failed */
input_InitStream( p_input, 0 ); input_InitStream( p_input, 0 );
input_AddProgram( p_input, 0, 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 ); 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_stream_id = 0xE0;
p_es->i_type = MPEG1_VIDEO_ES; p_es->i_type = MPEG1_VIDEO_ES;
p_es->i_cat = VIDEO_ES; p_es->i_cat = VIDEO_ES;
input_SelectES( p_input, p_es ); input_SelectES( p_input, p_es );
p_input->stream.p_selected_area->i_tell = 0; 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 ); vlc_mutex_unlock( &p_input->stream.stream_lock );
} }
...@@ -170,49 +181,57 @@ static void ESInit( input_thread_t * p_input ) ...@@ -170,49 +181,57 @@ static void ESInit( input_thread_t * p_input )
*****************************************************************************/ *****************************************************************************/
static void ESEnd( input_thread_t * p_input ) static void ESEnd( input_thread_t * p_input )
{ {
input_BuffersEnd( p_input->p_method_data );
} }
/***************************************************************************** /*****************************************************************************
* ESRead: reads data packets * ESRead: reads data packets
***************************************************************************** *****************************************************************************
* Returns -1 in case of error, 0 if everything went well, and 1 in case of * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* EOF. * packets.
*****************************************************************************/ *****************************************************************************/
static int ESRead( input_thread_t * p_input, static int ESRead( input_thread_t * p_input,
data_packet_t * pp_packets[INPUT_READ_ONCE] ) data_packet_t ** pp_data )
{ {
int i_read; int i_read;
struct iovec * p_iovec; struct iovec p_iovec[ES_READ_ONCE];
data_packet_t * p_data;
/* Get iovecs */ /* 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, ES_READ_ONCE );
i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
if( i_read == -1 ) if( i_read == -1 )
{ {
intf_ErrMsg( "input error: ES readv error" ); intf_ErrMsg( "input error: ES readv error" );
p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( -1 ); return( -1 );
} }
p_input->stream.p_selected_area->i_tell += i_read;
i_read /= ES_PACKET_SIZE;
/* EOF */ if( i_read != ES_READ_ONCE )
if( i_read == 0 && p_input->stream.b_seekable )
{ {
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, for( i_loop = 0; i_loop < i_read; i_loop++ )
(int)(i_read/ES_PACKET_SIZE), pp_packets ); {
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 ) ...@@ -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 ); pes_packet_t * p_pes = p_input->pf_new_pes( p_input->p_method_data );
decoder_fifo_t * p_fifo = 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 ) if( p_pes == NULL )
{ {
...@@ -251,22 +270,23 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -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->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) if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
| (input_ClockManageControl( p_input, p_input->stream.pp_programs[0], | (input_ClockManageControl( p_input,
(mtime_t)0 ) == PAUSE_S) ) p_input->stream.p_selected_program,
(mtime_t)0 ) == PAUSE_S) )
{ {
intf_WarnMsg( 2, "synchro reinit" ); intf_WarnMsg( 2, "synchro reinit" );
p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY; 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 ); input_DecodePES( p_fifo, p_pes );
vlc_mutex_lock( &p_fifo->data_lock ); vlc_mutex_lock( &p_fifo->data_lock );
if( ( (DECODER_FIFO_END( *p_fifo ) - DECODER_FIFO_START( *p_fifo )) if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
& FIFO_SIZE ) >= MAX_PACKETS_IN_FIFO )
{ {
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
} }
...@@ -290,18 +310,23 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream ) ...@@ -290,18 +310,23 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */ * time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL ) if( p_bit_stream->p_data->p_next == NULL )
{ {
/* We are going to read/write the start and end indexes of the pes_packet_t * p_next;
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
vlc_mutex_lock( &p_fifo->data_lock ); vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */ /* 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, p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_fifo ) ); p_fifo->p_first );
DECODER_FIFO_INCSTART( *p_fifo ); 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. */ /* Signal the input thread we're waiting. */
vlc_cond_signal( &p_fifo->data_wait ); vlc_cond_signal( &p_fifo->data_wait );
...@@ -310,7 +335,7 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream ) ...@@ -310,7 +335,7 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
} }
/* The next byte could be found in the next PES packet */ /* 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 ); vlc_mutex_unlock( &p_fifo->data_lock );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_es.h: thread structure of the ES plugin * input_es.h: thread structure of the ES plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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: * Authors:
* *
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * 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 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 @@ ...@@ -2,7 +2,7 @@
* input_ps.h: thread structure of the PS plugin * input_ps.h: thread structure of the PS plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr> * Cyril Deguet <asmax@via.ecp.fr>
...@@ -22,54 +22,5 @@ ...@@ -22,54 +22,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#define DATA_CACHE_SIZE 150 #define PS_READ_ONCE 50
#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;
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ts.c: TS demux and netlist management * input_ts.c: TS demux and netlist management
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Henri Fallon <henri@videolan.org>
* *
...@@ -89,7 +89,21 @@ static int TSProbe ( probedata_t * ); ...@@ -89,7 +89,21 @@ static int TSProbe ( probedata_t * );
static void TSInit ( struct input_thread_s * ); static void TSInit ( struct input_thread_s * );
static void TSEnd ( struct input_thread_s * ); static void TSEnd ( struct input_thread_s * );
static int TSRead ( 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 * 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 ) ...@@ -108,10 +122,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input.pf_set_program = input_SetProgram; input.pf_set_program = input_SetProgram;
input.pf_read = TSRead; input.pf_read = TSRead;
input.pf_demux = input_DemuxTS; input.pf_demux = input_DemuxTS;
input.pf_new_packet = input_NetlistNewPacket; input.pf_new_packet = input_NewPacket;
input.pf_new_pes = input_NetlistNewPES; input.pf_new_pes = input_NewPES;
input.pf_delete_packet = input_NetlistDeletePacket; input.pf_delete_packet = input_DeletePacket;
input.pf_delete_pes = input_NetlistDeletePES; input.pf_delete_pes = input_DeletePES;
input.pf_rewind = NULL; input.pf_rewind = NULL;
input.pf_seek = NULL; input.pf_seek = NULL;
#undef input #undef input
...@@ -160,7 +174,6 @@ static int TSProbe( probedata_t * p_data ) ...@@ -160,7 +174,6 @@ static int TSProbe( probedata_t * p_data )
*****************************************************************************/ *****************************************************************************/
static void TSInit( input_thread_t * p_input ) static void TSInit( input_thread_t * p_input )
{ {
/* Initialize netlist and TS structures */
thread_ts_data_t * p_method; thread_ts_data_t * p_method;
es_descriptor_t * p_pat_es; es_descriptor_t * p_pat_es;
es_ts_data_t * p_demux_data; es_ts_data_t * p_demux_data;
...@@ -184,11 +197,9 @@ static void TSInit( input_thread_t * p_input ) ...@@ -184,11 +197,9 @@ static void TSInit( input_thread_t * p_input )
p_input->p_method_data = NULL; p_input->p_method_data = NULL;
/* Initialize netlist */ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, TS_PACKET_SIZE,
INPUT_READ_ONCE ) )
{ {
intf_ErrMsg( "TS input : Could not initialize netlist" ); p_input->b_error = 1;
return; return;
} }
...@@ -227,23 +238,23 @@ static void TSEnd( input_thread_t * p_input ) ...@@ -227,23 +238,23 @@ static void TSEnd( input_thread_t * p_input )
input_DelES( p_input, p_pat_es ); input_DelES( p_input, p_pat_es );
free(p_input->p_plugin_data); free(p_input->p_plugin_data);
input_NetlistEnd( p_input ); input_BuffersEnd( p_input->p_method_data );
} }
/***************************************************************************** /*****************************************************************************
* TSRead: reads data packets * TSRead: reads data packets
***************************************************************************** *****************************************************************************
* Returns -1 in case of error, 0 if everything went well, and 1 in case of * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* EOF. * packets.
*****************************************************************************/ *****************************************************************************/
static int TSRead( input_thread_t * p_input, 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; thread_ts_data_t * p_method;
unsigned int i_loop; int i_read = 0, i_loop;
int i_read;
int i_data = 1; int i_data = 1;
struct iovec * p_iovec; struct iovec p_iovec[TS_READ_ONCE];
data_packet_t * p_data;
struct timeval timeout; struct timeval timeout;
/* Init */ /* Init */
...@@ -257,9 +268,6 @@ static int TSRead( input_thread_t * p_input, ...@@ -257,9 +268,6 @@ static int TSRead( input_thread_t * p_input,
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 500000; timeout.tv_usec = 500000;
/* Reset pointer table */
memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
/* Fill if some data is available */ /* Fill if some data is available */
#if defined( WIN32 ) #if defined( WIN32 )
if ( ! p_input->stream.b_pace_control ) if ( ! p_input->stream.b_pace_control )
...@@ -278,25 +286,26 @@ static int TSRead( input_thread_t * p_input, ...@@ -278,25 +286,26 @@ static int TSRead( input_thread_t * p_input,
if( i_data ) if( i_data )
{ {
/* Get iovecs */ /* 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 defined( WIN32 )
if( p_input->stream.b_pace_control ) 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 else
{ {
i_read = readv_network( p_input->i_handle, p_iovec, i_read = readv_network( p_input->i_handle, p_iovec,
INPUT_READ_ONCE, p_method ); TS_READ_ONCE, p_method );
} }
#else #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 */ /* Shouldn't happen, but it does - at least under Linux */
if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) ) if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) )
...@@ -306,36 +315,35 @@ static int TSRead( input_thread_t * p_input, ...@@ -306,36 +315,35 @@ static int TSRead( input_thread_t * p_input,
i_read = 0; i_read = 0;
} }
#endif #endif
/* Error */
if( i_read == -1 ) if( i_read == -1 )
{ {
intf_ErrMsg( "input error: TS readv error" ); intf_ErrMsg( "input error: TS readv error" );
p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( -1 ); return( -1 );
} }
p_input->stream.p_selected_area->i_tell += i_read;
i_read /= TS_PACKET_SIZE;
/* EOF */ /* Check correct TS header */
if( i_read == 0 && p_input->stream.b_seekable ) 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_packets[i_loop]->p_buffer[0] != 0x47 ) if( (*pp_data)->p_demux_start[0] != 0x47 )
{
intf_ErrMsg( "input error: bad TS packet (starts with " intf_ErrMsg( "input error: bad TS packet (starts with "
"0x%.2x, should be 0x47)", "0x%.2x, should be 0x47)",
pp_packets[i_loop]->p_buffer[0] ); p_data->p_demux_start[0] );
}
pp_data = &(*pp_data)->p_next;
} }
for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
if( i_read != TS_READ_ONCE )
{ {
pp_packets[i_loop] = NULL; /* Delete remaining packets */
p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
*pp_data = NULL;
} }
p_input->stream.p_selected_area->i_tell += i_read;
} }
return 0; return( i_read );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ts.h: structures of the input not exported to other modules * input_ts.h: structures of the input not exported to other modules
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Henri Fallon <henri@via.ecp.fr>
* Boris Dors <babal@via.ecp.fr> * Boris Dors <babal@via.ecp.fr>
...@@ -22,10 +22,12 @@ ...@@ -22,10 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#define NB_DATA 16384 /* UDP packets contain 1500 bytes, that is 7 TS packets */
#define NB_PES 8192 #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 * thread_ts_data_t: private input data
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg_adec.c: MPEG audio decoder thread * mpeg_adec.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -203,11 +203,11 @@ static void DecodeThread( adec_thread_t * p_adec ) ...@@ -203,11 +203,11 @@ static void DecodeThread( adec_thread_t * p_adec )
buffer = ((s16 *)p_adec->p_aout_fifo->buffer) buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+ (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE); + (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] = p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START( *p_adec->p_fifo )->i_pts; p_adec->p_fifo->p_first->i_pts;
DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0; p_adec->p_fifo->p_first->i_pts = 0;
} }
else else
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video_parser.c : video parser thread * video_parser.c : video parser thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr> * Samuel Hocevar <sam@via.ecp.fr>
...@@ -281,38 +281,6 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -281,38 +281,6 @@ static int InitThread( vpar_thread_t *p_vpar )
return( 0 ); 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 * EndThread: thread destruction
***************************************************************************** *****************************************************************************
...@@ -428,13 +396,13 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream, ...@@ -428,13 +396,13 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
if( b_new_pes ) if( b_new_pes )
{ {
p_vpar->sequence.next_pts = 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 = 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 = 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 #ifdef TRACE_VPAR
intf_DbgMsg( "Discontinuity in BitstreamCallback" ); intf_DbgMsg( "Discontinuity in BitstreamCallback" );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread * spu_decoder.c : spu decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -275,7 +275,7 @@ static void ParsePacket( spudec_thread_t *p_spudec ) ...@@ -275,7 +275,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
p_spudec->i_spu_size ); p_spudec->i_spu_size );
/* We cannot display a subpicture with no date */ /* 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" ); intf_WarnMsg( 3, "spudec error: subtitle without a date" );
return; return;
...@@ -295,7 +295,7 @@ static void ParsePacket( spudec_thread_t *p_spudec ) ...@@ -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. */ /* 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 */ /* Allocate the temporary buffer we will parse */
p_src = malloc( p_spudec->i_rle_size ); p_src = malloc( p_spudec->i_rle_size );
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_vcd.h: thread structure of the VCD plugin * input_vcd.h: thread structure of the VCD plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Author: Johan Bilien <jobi@via.ecp.fr>
* *
...@@ -21,25 +21,17 @@ ...@@ -21,25 +21,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
/***************************************************************************** /*****************************************************************************
* thread_vcd_data_t: VCD information * thread_vcd_data_t: VCD information
*****************************************************************************/ *****************************************************************************/
typedef struct thread_vcd_data_s typedef struct thread_vcd_data_s
{ {
int vcdhandle; // File descriptor int i_handle; /* File descriptor */
int nb_tracks; // Nb of tracks (titles) int nb_tracks; /* Nb of tracks (titles) */
int current_track; // Current track int i_track; /* Current track */
int current_sector; // Current Sector int i_sector; /* Current Sector */
int * tracks_sector; // index of tracks int * p_sectors; /* Track sectors */
boolean_t b_end_of_track; // if the end of track is boolean_t b_end_of_track; /* If the end of track was reached */
// reached
} thread_vcd_data_t ;
} thread_vcd_data_t;
...@@ -71,129 +71,97 @@ ...@@ -71,129 +71,97 @@
#include "modules.h" #include "modules.h"
#include "modules_export.h" #include "modules_export.h"
#include "input_vcd.h"
#include "linux_cdrom_tools.h" #include "linux_cdrom_tools.h"
/***************************************************************************** /*****************************************************************************
* read_toc : Reads the Table of Content of a CD-ROM and fills p_vcd with * * ioctl_ReadTocHeader: Read the TOC header and return the track number.
* the read information * *****************************************************************************/
*****************************************************************************/ int ioctl_GetTrackCount( int i_fd )
int read_toc ( thread_vcd_data_t * p_vcd ) {
{ struct cdrom_tochdr tochdr;
int i ;
struct cdrom_tochdr tochdr ; /* First we read the TOC header */
struct cdrom_tocentry tocent ; if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
int fd = p_vcd->vcdhandle ;
/* first we read the TOC header */
if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1)
{ {
intf_ErrMsg("problem occured when reading CD's TOCHDR\n") ; intf_ErrMsg( "vcd error: could not read TOCHDR" );
return -1 ; return -1;
} }
p_vcd->nb_tracks = tochdr.cdth_trk1; return tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
/* 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 ) ); * ioctl_GetSectors: Read the Table of Contents and fill p_vcd.
if ( p_vcd->tracks_sector == NULL ) *****************************************************************************/
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("could not malloc tracks_sector"); intf_ErrMsg( "vcd error: could not read TOCHDR" );
return -1; return NULL;
} }
/* then for each track we read its TOC entry */ i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
for( i=tochdr.cdth_trk0 ; i <= tochdr.cdth_trk1 ; i++ ) p_sectors = malloc( (i_tracks + 1) * sizeof(int) );
if( p_sectors == NULL )
{
intf_ErrMsg( "vcd error: could not allocate p_sectors" );
return NULL;
}
/* Fill the p_sectors structure with the track/sector matches */
for( i = 0 ; i <= i_tracks ; i++ )
{ {
tocent.cdte_track = i;
tocent.cdte_format = CDROM_LBA; tocent.cdte_format = CDROM_LBA;
if (ioctl( fd, CDROMREADTOCENTRY, &tocent) == -1 ) tocent.cdte_track =
( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
if( ioctl( i_fd, CDROMREADTOCENTRY, &tocent ) == -1 )
{ {
intf_ErrMsg( "problem occured when reading CD's TOCENTRY\n" ); intf_ErrMsg( "vcd error: could not read TOCENTRY" );
free ( p_vcd->tracks_sector ); free( p_sectors );
return -1; return NULL;
} }
p_vcd->tracks_sector[i-1] = tocent.cdte_addr.lba ;
p_sectors[ i ] = tocent.cdte_addr.lba;
} }
/* finally we read the lead-out track toc entry */
tocent.cdte_track = CDROM_LEADOUT ;
tocent.cdte_format = CDROM_LBA ;
if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1)
{
intf_ErrMsg("problem occured when readind CD's
lead-out track TOC entry") ;
free (p_vcd->tracks_sector) ;
return -1 ;
}
p_vcd->tracks_sector[p_vcd->nb_tracks] = tocent.cdte_addr.lba ;
return 1 ;
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] ; byte_t p_block[ VCD_SECTOR_SIZE ];
struct cdrom_msf0 msf_cursor ; int i_dummy = i_sector + 2 * CD_FRAMES;
msf_cursor = lba2msf( p_vcd->current_sector ) ; #define p_msf ((struct cdrom_msf0 *)p_block)
p_msf->minute = i_dummy / (CD_FRAMES * CD_SECS);
#ifdef DEBUG p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
intf_DbgMsg("Playing frame %d:%d-%d\n", msf_cursor.minute, p_msf->frame = ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
msf_cursor.second, msf_cursor.frame) ;
#endif intf_DbgMsg( "vcd debug: playing frame %d:%d-%d",
p_msf->minute, p_msf->second, p_msf->frame);
memcpy(p_read_block, &msf_cursor, sizeof(struct cdrom_msf0)) ; #undef p_msf
if (ioctl(p_vcd->vcdhandle, CDROMREADRAW, p_read_block) == -1) if( ioctl(i_fd, CDROMREADRAW, p_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 );
p_vcd->current_sector ++;
if ( p_vcd->current_sector ==
p_vcd->tracks_sector[p_vcd->current_track + 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;
}
/* 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 );
/***************************************************************************** return 0;
* 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*/
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 ;
} }
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
/****************************************************************************** /******************************************************************************
* Prototypes * * Prototypes *
******************************************************************************/ ******************************************************************************/
int ioctl_GetTrackCount ( int );
int read_toc ( struct thread_vcd_data_s *); int * ioctl_GetSectors ( int );
int VCD_sector_read ( struct thread_vcd_data_s *, byte_t *) ; int ioctl_ReadSector ( int, int, byte_t * );
struct cdrom_msf0 lba2msf ( int ) ;
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* decoders. * decoders.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -120,9 +120,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) ...@@ -120,9 +120,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
return( NULL ); return( NULL );
} }
/* Packets read once */
p_input->i_read_once = INPUT_READ_ONCE;
/* Initialize thread properties */ /* Initialize thread properties */
p_input->b_die = 0; p_input->b_die = 0;
p_input->b_error = 0; p_input->b_error = 0;
...@@ -206,7 +203,7 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) ...@@ -206,7 +203,7 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
/* Request thread destruction */ /* Request thread destruction */
p_input->b_die = 1; 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_mutex_lock( &p_input->stream.stream_lock );
vlc_cond_signal( &p_input->stream.stream_wait ); vlc_cond_signal( &p_input->stream.stream_wait );
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -229,9 +226,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) ...@@ -229,9 +226,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
*****************************************************************************/ *****************************************************************************/
static void RunThread( input_thread_t *p_input ) static void RunThread( input_thread_t *p_input )
{ {
int i_error, i;
data_packet_t ** pp_packets;
if( InitThread( p_input ) ) if( InitThread( p_input ) )
{ {
/* If we failed, wait before we are killed, and exit */ /* If we failed, wait before we are killed, and exit */
...@@ -242,22 +236,16 @@ static void RunThread( input_thread_t *p_input ) ...@@ -242,22 +236,16 @@ static void RunThread( input_thread_t *p_input )
return; return;
} }
/* initialization is completed */ /* initialization is complete */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_changed = 1; p_input->stream.b_changed = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock ); 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 ) 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++; p_input->c_loops++;
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
...@@ -357,33 +345,33 @@ static void RunThread( input_thread_t *p_input ) ...@@ -357,33 +345,33 @@ static void RunThread( input_thread_t *p_input )
vlc_mutex_unlock( &p_input->stream.stream_lock ); 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. */ /* 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->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_count == 0 && p_input->stream.b_seekable )
{ {
if( i_error == 1 ) /* End of file - we do not set b_die because only the
{ * interface is allowed to do so. */
/* End of file - we do not set b_die because only the intf_WarnMsg( 3, "input: EOF reached" );
* interface is allowed to do so. */ p_input->b_eof = 1;
intf_WarnMsg( 3, "input: EOF reached" ); }
p_input->b_eof = 1; else if( i_count < 0 )
} {
else p_input->b_error = 1;
{
p_input->b_error = 1;
}
} }
} }
free( pp_packets );
if( p_input->b_error || p_input->b_eof ) if( p_input->b_error || p_input->b_eof )
{ {
ErrorThread( p_input ); ErrorThread( p_input );
...@@ -401,7 +389,6 @@ static void RunThread( input_thread_t *p_input ) ...@@ -401,7 +389,6 @@ static void RunThread( input_thread_t *p_input )
*****************************************************************************/ *****************************************************************************/
static int InitThread( input_thread_t * p_input ) static int InitThread( input_thread_t * p_input )
{ {
/* Initialize statistics */ /* Initialize statistics */
p_input->c_loops = 0; p_input->c_loops = 0;
p_input->stream.c_packets_read = 0; p_input->stream.c_packets_read = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders * input_dec.c: Functions for the management of decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * 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 ) ...@@ -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 ); vlc_mutex_lock( &p_decoder_fifo->data_lock );
if( !DECODER_FIFO_ISFULL( *p_decoder_fifo ) ) p_pes->p_next = NULL;
{ *p_decoder_fifo->pp_last = p_pes;
p_decoder_fifo->buffer[p_decoder_fifo->i_end] = p_pes; p_decoder_fifo->pp_last = &p_pes->p_next;
DECODER_FIFO_INCEND( *p_decoder_fifo ); p_decoder_fifo->i_depth++;
/* Warn the decoder that it's got work to do. */ /* Warn the decoder that it's got work to do. */
vlc_cond_signal( &p_decoder_fifo->data_wait ); 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 ); vlc_mutex_unlock( &p_decoder_fifo->data_lock );
} }
...@@ -261,7 +253,9 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input, ...@@ -261,7 +253,9 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
p_config->i_type = p_es->i_type; p_config->i_type = p_es->i_type;
p_config->p_stream_ctrl = &p_input->stream.control; 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->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->p_packets_mgt = p_input->p_method_data;
p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes; 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, ...@@ -274,14 +268,13 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
*****************************************************************************/ *****************************************************************************/
static void DeleteDecoderConfig( decoder_config_t * p_config ) 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. */ /* 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,
p_config->p_decoder_fifo->pf_delete_pes( p_config->p_decoder_fifo->p_first );
p_config->p_decoder_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_config->p_decoder_fifo ) );
DECODER_FIFO_INCSTART( *p_config->p_decoder_fifo );
}
/* Destroy the lock and cond */ /* Destroy the lock and cond */
vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait ); vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ext-dec.c: services to the decoders * input_ext-dec.c: services to the decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -55,7 +55,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo, ...@@ -55,7 +55,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
/* Get the first data packet. */ /* Get the first data packet. */
vlc_mutex_lock( &p_fifo->data_lock ); vlc_mutex_lock( &p_fifo->data_lock );
while ( DECODER_FIFO_ISEMPTY( *p_fifo ) ) while ( p_fifo->p_first == NULL )
{ {
if ( p_fifo->b_die ) if ( p_fifo->b_die )
{ {
...@@ -64,7 +64,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo, ...@@ -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 ); 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_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->p_end = p_bit_stream->p_data->p_payload_end;
p_bit_stream->fifo.buffer = 0; p_bit_stream->fifo.buffer = 0;
...@@ -100,12 +100,7 @@ void DecoderError( decoder_fifo_t * p_fifo ) ...@@ -100,12 +100,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
while( !p_fifo->b_die ) while( !p_fifo->b_die )
{ {
/* Trash all received PES packets */ /* Trash all received PES packets */
while( !DECODER_FIFO_ISEMPTY(*p_fifo) ) p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
{
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_fifo) );
DECODER_FIFO_INCSTART( *p_fifo );
}
/* Waiting for the input thread to put new PES packets in the fifo */ /* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
...@@ -131,24 +126,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream ) ...@@ -131,24 +126,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */ * time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL ) if( p_bit_stream->p_data->p_next == NULL )
{ {
/* We are going to read/write the start and end indexes of the pes_packet_t * p_next;
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
vlc_mutex_lock( &p_fifo->data_lock ); vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */ /* 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, p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
DECODER_FIFO_START( *p_fifo ) ); p_fifo->p_first );
DECODER_FIFO_INCSTART( *p_fifo ); 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. */ /* Wait for the input to tell us when we receive a packet. */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
} }
/* The next byte could be found in the next PES packet */ /* 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 ); vlc_mutex_unlock( &p_fifo->data_lock );
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management * mpeg_system.c: TS, PS and PES management
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@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 ) ...@@ -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 ) if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
!= 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_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL; p_pes = NULL;
return; return;
...@@ -154,7 +154,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -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)) ) if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
{ {
/* packet_start_code_prefix != 0x000001 */ /* 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_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL; p_pes = NULL;
} }
...@@ -167,7 +168,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -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 */ /* PES_packet_length is set and != total received payload */
/* Warn the decoder that the data may be corrupt. */ /* 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 ) switch( p_es->i_stream_id )
...@@ -273,7 +275,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -273,7 +275,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
} }
if( i_pes_header_size == 23 ) 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_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL; p_pes = NULL;
return; return;
...@@ -474,10 +476,11 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, ...@@ -474,10 +476,11 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
else else
{ {
/* Update the relations between the data packets */ /* 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 */ /* Size of the payload carried in the data packet */
p_pes->i_pes_size += (p_data->p_payload_end p_pes->i_pes_size += (p_data->p_payload_end
...@@ -505,13 +508,13 @@ static u16 GetID( data_packet_t * p_data ) ...@@ -505,13 +508,13 @@ static u16 GetID( data_packet_t * p_data )
{ {
u16 i_id; 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 ) if( i_id == 0xBD )
{ {
/* FIXME : this is not valid if the header is split in multiple /* FIXME : this is not valid if the header is split in multiple
* packets */ * packets */
/* stream_private_id */ /* 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 ); return( i_id );
} }
...@@ -530,14 +533,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -530,14 +533,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
int i; int i;
int i_new_es_number = 0; 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" ); intf_ErrMsg( "PSM too short : packet corrupt" );
return; return;
} }
if( p_demux->b_has_PSM 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. */ /* Already got that one. */
return; return;
...@@ -545,12 +548,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -545,12 +548,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
intf_DbgMsg( "Building PSM" ); intf_DbgMsg( "Building PSM" );
p_demux->b_has_PSM = 1; 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 /* Go to elementary_stream_map_length, jumping over
* program_stream_info. */ * program_stream_info. */
p_byte = p_data->p_payload_start + 10 p_byte = p_data->p_demux_start + 10
+ U16_AT(&p_data->p_payload_start[8]); + U16_AT(&p_data->p_demux_start[8]);
if( p_byte > p_data->p_payload_end ) if( p_byte > p_data->p_payload_end )
{ {
intf_ErrMsg( "PSM too short : packet corrupt" ); intf_ErrMsg( "PSM too short : packet corrupt" );
...@@ -655,7 +658,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input, ...@@ -655,7 +658,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
u32 i_code; u32 i_code;
es_descriptor_t * p_es = NULL; 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 */ if( i_code > 0xBC ) /* ES start code */
{ {
...@@ -694,7 +697,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input, ...@@ -694,7 +697,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
i_id, 0 ); i_id, 0 );
if( p_es != NULL ) 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. */ /* Set stream type and auto-spawn. */
if( (i_id & 0xF0) == 0xE0 ) if( (i_id & 0xF0) == 0xE0 )
...@@ -794,7 +797,10 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -794,7 +797,10 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
boolean_t b_trash = 0; boolean_t b_trash = 0;
es_descriptor_t * p_es = NULL; 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 ) if( i_code <= 0x1BC )
{ {
switch( i_code ) switch( i_code )
...@@ -805,12 +811,12 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -805,12 +811,12 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
mtime_t scr_time; mtime_t scr_time;
u32 i_mux_rate; u32 i_mux_rate;
if( (p_data->p_payload_start[4] & 0xC0) == 0x40 ) if( (p_data->p_demux_start[4] & 0xC0) == 0x40 )
{ {
/* MPEG-2 */ /* MPEG-2 */
byte_t p_header[14]; byte_t p_header[14];
byte_t * p_byte; 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 ) 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 ) ...@@ -841,7 +847,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
/* MPEG-1 SCR is like PTS. */ /* MPEG-1 SCR is like PTS. */
byte_t p_header[12]; byte_t p_header[12];
byte_t * p_byte; 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 ) 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 ) ...@@ -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; es_ts_data_t * p_es_demux = NULL;
pgrm_ts_data_t * p_pgrm_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. */ /* Extract flags values from TS common header. */
i_pid = ((p[1] & 0x1F) << 8) | p[2]; i_pid = ((p[1] & 0x1F) << 8) | p[2];
b_unit_start = (p[1] & 0x40); 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