Commit ff85edc6 authored by Christophe Massiot's avatar Christophe Massiot

* Centralized clock management, preparing for stream navigation ;

* Fixed a bug in the management of the first video PTS.
parent 422bd79f
...@@ -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.11 2001/01/30 05:48:23 sam Exp $ * $Id: input_ext-intf.h,v 1.12 2001/02/07 15:32:25 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -110,7 +110,8 @@ typedef struct pgrm_descriptor_s ...@@ -110,7 +110,8 @@ typedef struct pgrm_descriptor_s
/* Synchronization information */ /* Synchronization information */
mtime_t delta_cr; mtime_t delta_cr;
mtime_t cr_ref, sysdate_ref; mtime_t cr_ref, sysdate_ref;
mtime_t last_cr; mtime_t last_cr; /* reference to detect unexpected stream
* discontinuities */
count_t c_average_count; count_t c_average_count;
/* counter used to compute dynamic average values */ /* counter used to compute dynamic average values */
int i_synchro_state; int i_synchro_state;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input.h: structures of the input not exported to other modules * input.h: structures of the input not exported to other modules
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input.h,v 1.12 2001/01/24 19:05:55 massiot Exp $ * $Id: input.h,v 1.13 2001/02/07 15:32:25 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* Ethernet MTU is 1500 bytes, so in a UDP * * Ethernet MTU is 1500 bytes, so in a UDP *
* packet we can put : 1500/188 = 7 TS * * packet we can put : 1500/188 = 7 TS *
* packets. Have a nice day and merry Xmas. */ * packets. Have a nice day and merry Xmas. */
#define PADDING_PACKET_SIZE 100 /* Size of the NULL packet inserted in case #define PADDING_PACKET_SIZE 188 /* Size of the NULL packet inserted in case
* of data loss (this should be < 188). */ * of data loss (this should be < 188). */
/***************************************************************************** /*****************************************************************************
...@@ -78,7 +78,7 @@ void NextDataPacket ( struct bit_stream_s * ); ...@@ -78,7 +78,7 @@ void NextDataPacket ( struct bit_stream_s * );
/***************************************************************************** /*****************************************************************************
* Prototypes from input_programs.c * Prototypes from input_programs.c
*****************************************************************************/ *****************************************************************************/
void input_InitStream( struct input_thread_s *, size_t ); int input_InitStream( struct input_thread_s *, size_t );
void input_EndStream( struct input_thread_s * ); void input_EndStream( struct input_thread_s * );
struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 ); struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *, struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *,
...@@ -103,10 +103,15 @@ void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * ); ...@@ -103,10 +103,15 @@ void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * );
/***************************************************************************** /*****************************************************************************
* Prototypes from input_clock.c * Prototypes from input_clock.c
*****************************************************************************/ *****************************************************************************/
mtime_t input_ClockToSysdate( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t );
void input_ClockNewRef( struct input_thread_s *, void input_ClockNewRef( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t ); struct pgrm_descriptor_s *, mtime_t );
void input_EscapeDiscontinuity( struct input_thread_s *,
struct pgrm_descriptor_s * );
void input_ClockInit( struct pgrm_descriptor_s * );
void input_ClockManageRef( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t );
mtime_t input_ClockGetTS( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t );
/***************************************************************************** /*****************************************************************************
* Create a NULL packet for padding in case of a data loss * Create a NULL packet for padding in case of a data loss
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_clock.c: Clock/System date conversions, stream management * input_clock.c: Clock/System date conversions, stream management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_clock.c,v 1.1 2001/01/24 19:05:55 massiot Exp $ * $Id: input_clock.c,v 1.2 2001/02/07 15:32:26 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -38,11 +38,51 @@ ...@@ -38,11 +38,51 @@
#include "input.h" #include "input.h"
/*
* DISCUSSION : SYNCHRONIZATION METHOD
*
* In some cases we can impose the pace of reading (when reading from a
* file or a pipe), and for the synchronization we simply sleep() until
* it is time to deliver the packet to the decoders. When reading from
* the network, we must be read at the same pace as the server writes,
* otherwise the kernel's buffer will trash packets. The risk is now to
* overflow the input buffers in case the server goes too fast, that is
* why we do these calculations :
*
* We compute a mean for the pcr because we want to eliminate the
* network jitter and keep the low frequency variations. The mean is
* in fact a low pass filter and the jitter is a high frequency signal
* that is why it is eliminated by the filter/average.
*
* The low frequency variations enable us to synchronize the client clock
* with the server clock because they represent the time variation between
* the 2 clocks. Those variations (ie the filtered pcr) are used to compute
* the presentation dates for the audio and video frames. With those dates
* we can decode (or trash) the MPEG2 stream at "exactly" the same rate
* as it is sent by the server and so we keep the synchronization between
* the server and the client.
*
* It is a very important matter if you want to avoid underflow or overflow
* in all the FIFOs, but it may be not enough.
*/
/***************************************************************************** /*****************************************************************************
* input_ClockToSysdate: converts a movie clock to system date * Constants
*****************************************************************************/ *****************************************************************************/
mtime_t input_ClockToSysdate( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm, mtime_t i_clock ) /* Maximum number of samples used to compute the dynamic average value.
* We use the following formula :
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
#define CR_MAX_AVERAGE_COUNTER 40
/* Maximum gap allowed between two CRs. */
#define CR_MAX_GAP 1000000
/*****************************************************************************
* ClockToSysdate: converts a movie clock to system date
*****************************************************************************/
static mtime_t ClockToSysdate( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm, mtime_t i_clock )
{ {
mtime_t i_sysdate = 0; mtime_t i_sysdate = 0;
...@@ -59,6 +99,19 @@ mtime_t input_ClockToSysdate( input_thread_t * p_input, ...@@ -59,6 +99,19 @@ mtime_t input_ClockToSysdate( input_thread_t * p_input,
return( i_sysdate ); return( i_sysdate );
} }
/*****************************************************************************
* ClockCurrent: converts current system date to clock units
*****************************************************************************
* Caution : the synchro state must be SYNCHRO_OK for this to operate.
*****************************************************************************/
static mtime_t ClockCurrent( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm )
{
return( (mdate() - p_pgrm->sysdate_ref) * 27 * DEFAULT_RATE
/ p_input->stream.control.i_rate / 300
+ p_pgrm->cr_ref );
}
/***************************************************************************** /*****************************************************************************
* input_ClockNewRef: writes a new clock reference * input_ClockNewRef: writes a new clock reference
*****************************************************************************/ *****************************************************************************/
...@@ -69,3 +122,114 @@ void input_ClockNewRef( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm, ...@@ -69,3 +122,114 @@ void input_ClockNewRef( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm,
p_pgrm->sysdate_ref = mdate(); p_pgrm->sysdate_ref = mdate();
} }
/*****************************************************************************
* input_EscapeDiscontinuity: send a NULL packet to the decoders
*****************************************************************************/
void input_EscapeDiscontinuity( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm )
{
int i_es;
for( i_es = 0; i_es < p_pgrm->i_es_number; i_es++ )
{
es_descriptor_t * p_es = p_pgrm->pp_es[i_es];
if( p_es->p_decoder_fifo != NULL )
{
input_NullPacket( p_input, p_es );
}
}
}
/*****************************************************************************
* input_ClockInit: reinitializes the clock reference after a stream
* discontinuity
*****************************************************************************/
void input_ClockInit( pgrm_descriptor_t * p_pgrm )
{
p_pgrm->last_cr = 0;
p_pgrm->cr_ref = 0;
p_pgrm->sysdate_ref = 0;
p_pgrm->delta_cr = 0;
p_pgrm->c_average_count = 0;
}
/*****************************************************************************
* input_ClockManageRef: manages a clock reference
*****************************************************************************/
void input_ClockManageRef( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm, mtime_t i_clock )
{
if( p_pgrm->i_synchro_state != SYNCHRO_OK )
{
/* Feed synchro with a new reference point. */
input_ClockNewRef( p_input, p_pgrm, i_clock );
p_pgrm->i_synchro_state = SYNCHRO_OK;
}
else
{
if ( p_pgrm->last_cr != 0 &&
( (p_pgrm->last_cr - i_clock) > CR_MAX_GAP
|| (p_pgrm->last_cr - i_clock) < - CR_MAX_GAP ) )
{
/* Stream discontinuity, for which we haven't received a
* warning from the stream control facilities (dd-edited
* stream ?). */
intf_WarnMsg( 3, "Clock gap, unexpected stream discontinuity" );
input_ClockInit( p_pgrm );
p_pgrm->i_synchro_state = SYNCHRO_START;
input_EscapeDiscontinuity( p_input, p_pgrm );
}
p_pgrm->last_cr = i_clock;
if( p_input->stream.b_pace_control
&& p_input->stream.pp_programs[0] == p_pgrm )
{
/* Wait a while before delivering the packets to the decoder.
* In case of multiple programs, we arbitrarily follow the
* clock of the first program. */
mwait( ClockToSysdate( p_input, p_pgrm, i_clock ) );
}
else
{
/* Smooth clock reference variations. */
mtime_t i_extrapoled_clock = ClockCurrent( p_input, p_pgrm );
/* Bresenham algorithm to smooth variations. */
if( p_pgrm->c_average_count == CR_MAX_AVERAGE_COUNTER )
{
p_pgrm->delta_cr = ( p_pgrm->delta_cr
* (CR_MAX_AVERAGE_COUNTER - 1)
+ i_extrapoled_clock )
/ CR_MAX_AVERAGE_COUNTER;
}
else
{
p_pgrm->delta_cr = ( p_pgrm->delta_cr
* p_pgrm->c_average_count
+ i_extrapoled_clock )
/ (p_pgrm->c_average_count + 1);
p_pgrm->c_average_count++;
}
}
}
}
/*****************************************************************************
* input_ClockGetTS: manages a PTS or DTS
*****************************************************************************/
mtime_t input_ClockGetTS( input_thread_t * p_input,
pgrm_descriptor_t * p_pgrm, mtime_t i_ts )
{
if( p_pgrm->i_synchro_state == SYNCHRO_OK )
{
return( ClockToSysdate( p_input, p_pgrm, i_ts + p_pgrm->delta_cr )
+ DEFAULT_PTS_DELAY );
}
else
{
return 0;
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_programs.c,v 1.27 2001/01/24 19:05:55 massiot Exp $ * $Id: input_programs.c,v 1.28 2001/02/07 15:32:26 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
/***************************************************************************** /*****************************************************************************
* input_InitStream: init the stream descriptor of the given input * input_InitStream: init the stream descriptor of the given input
*****************************************************************************/ *****************************************************************************/
void input_InitStream( input_thread_t * p_input, size_t i_data_len ) int input_InitStream( input_thread_t * p_input, size_t i_data_len )
{ {
p_input->stream.i_stream_id = 0; p_input->stream.i_stream_id = 0;
p_input->stream.pp_es = NULL; p_input->stream.pp_es = NULL;
...@@ -63,11 +63,12 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len ) ...@@ -63,11 +63,12 @@ void input_InitStream( input_thread_t * p_input, size_t i_data_len )
if ( (p_input->stream.p_demux_data = malloc( i_data_len )) == NULL ) if ( (p_input->stream.p_demux_data = malloc( i_data_len )) == NULL )
{ {
intf_ErrMsg( "Unable to allocate memory in input_InitStream"); intf_ErrMsg( "Unable to allocate memory in input_InitStream");
/* FIXME : find a way to tell if failed */ return 1;
return;
} }
memset( p_input->stream.p_demux_data, 0, i_data_len ); memset( p_input->stream.p_demux_data, 0, i_data_len );
} }
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -147,11 +148,8 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input, ...@@ -147,11 +148,8 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
p_input->stream.pp_programs[i_pgrm_index]->i_es_number = 0; p_input->stream.pp_programs[i_pgrm_index]->i_es_number = 0;
p_input->stream.pp_programs[i_pgrm_index]->pp_es = NULL; p_input->stream.pp_programs[i_pgrm_index]->pp_es = NULL;
p_input->stream.pp_programs[i_pgrm_index]->delta_cr = 0; input_ClockInit( p_input->stream.pp_programs[i_pgrm_index] );
p_input->stream.pp_programs[i_pgrm_index]->cr_ref = 0;
p_input->stream.pp_programs[i_pgrm_index]->sysdate_ref = 0;
p_input->stream.pp_programs[i_pgrm_index]->last_cr = 0;
p_input->stream.pp_programs[i_pgrm_index]->c_average_count = 0;
p_input->stream.pp_programs[i_pgrm_index]->i_synchro_state p_input->stream.pp_programs[i_pgrm_index]->i_synchro_state
= SYNCHRO_START; = SYNCHRO_START;
p_input->stream.pp_programs[i_pgrm_index]->b_discontinuity = 0; p_input->stream.pp_programs[i_pgrm_index]->b_discontinuity = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ps.c: PS demux and packet management * input_ps.c: PS demux and packet management
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input_ps.c,v 1.21 2001/01/30 05:48:23 sam Exp $ * $Id: input_ps.c,v 1.22 2001/02/07 15:32:26 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -103,6 +103,7 @@ static void PSInit( input_thread_t * p_input ) ...@@ -103,6 +103,7 @@ static void PSInit( input_thread_t * p_input )
} }
fseek( p_method->stream, 0, SEEK_SET ); fseek( p_method->stream, 0, SEEK_SET );
/* FIXME : detect if InitStream failed */
input_InitStream( p_input, sizeof( stream_ps_data_t ) ); input_InitStream( p_input, sizeof( stream_ps_data_t ) );
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) ); input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
......
...@@ -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, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: mpeg_system.c,v 1.28 2001/01/30 05:48:23 sam Exp $ * $Id: mpeg_system.c,v 1.29 2001/02/07 15:32:26 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -217,11 +217,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -217,11 +217,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
p_pes = NULL; p_pes = NULL;
return; return;
} }
p_pes->i_pts = input_ClockToSysdate( p_input, p_es->p_pgrm, p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
( ((mtime_t)(p_full_header[2] & 0x0E) << 29) | ( ((mtime_t)(p_full_header[2] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_full_header + 3) << 14) - (1 << 14)) | (((mtime_t)U16_AT(p_full_header + 3) << 14) - (1 << 14)) |
((mtime_t)U16_AT(p_full_header + 5) >> 1) ) ) ((mtime_t)U16_AT(p_full_header + 5) >> 1) ) );
+ DEFAULT_PTS_DELAY;
if( b_has_dts ) if( b_has_dts )
{ {
...@@ -235,13 +234,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -235,13 +234,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
p_pes = NULL; p_pes = NULL;
return; return;
} }
p_pes->i_dts = input_ClockToSysdate( p_input, p_pes->i_dts = input_ClockGetTS( p_input, p_es->p_pgrm,
p_es->p_pgrm,
( ((mtime_t)(p_full_header[7] & 0x0E) << 29) | ( ((mtime_t)(p_full_header[7] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_full_header + 8) << 14) (((mtime_t)U16_AT(p_full_header + 8) << 14)
- (1 << 14)) | - (1 << 14)) |
((mtime_t)U16_AT(p_full_header + 10) >> 1) ) ) ((mtime_t)U16_AT(p_full_header + 10) >> 1) ) );
+ DEFAULT_PTS_DELAY;
} }
} }
} }
...@@ -313,11 +310,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -313,11 +310,10 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
return; return;
} }
p_pes->i_pts = input_ClockToSysdate( p_input, p_es->p_pgrm, p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
( ((mtime_t)(p_ts[0] & 0x0E) << 29) | ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_ts + 1) << 14) - (1 << 14)) | (((mtime_t)U16_AT(p_ts + 1) << 14) - (1 << 14)) |
((mtime_t)U16_AT(p_ts + 3) >> 1) ) ) ((mtime_t)U16_AT(p_ts + 3) >> 1) ) );
+ DEFAULT_PTS_DELAY;
if( b_has_dts ) if( b_has_dts )
{ {
...@@ -332,12 +328,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) ...@@ -332,12 +328,11 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
return; return;
} }
p_pes->i_dts = input_ClockToSysdate( p_input, p_pes->i_dts = input_ClockGetTS( p_input,
p_es->p_pgrm, p_es->p_pgrm,
( ((mtime_t)(p_ts[0] & 0x0E) << 29) | ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_ts + 1) << 14) - (1 << 14)) | (((mtime_t)U16_AT(p_ts + 1) << 14) - (1 << 14)) |
((mtime_t)U16_AT(p_ts + 3) >> 1) ) ) ((mtime_t)U16_AT(p_ts + 3) >> 1) ) );
+ DEFAULT_PTS_DELAY;
} }
} }
} }
...@@ -491,132 +486,6 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, ...@@ -491,132 +486,6 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
} }
/*
* Pace control
*/
/*
* DISCUSSION : SYNCHRONIZATION METHOD
*
* In some cases we can impose the pace of reading (when reading from a
* file or a pipe), and for the synchronization we simply sleep() until
* it is time to deliver the packet to the decoders. When reading from
* the network, we must be read at the same pace as the server writes,
* otherwise the kernel's buffer will trash packets. The risk is now to
* overflow the input buffers in case the server goes too fast, that is
* why we do these calculations :
*
* We compute an average for the pcr because we want to eliminate the
* network jitter and keep the low frequency variations. The average is
* in fact a low pass filter and the jitter is a high frequency signal
* that is why it is eliminated by the filter/average.
*
* The low frequency variations enable us to synchronize the client clock
* with the server clock because they represent the time variation between
* the 2 clocks. Those variations (ie the filtered pcr) are used to compute
* the presentation dates for the audio and video frames. With those dates
* we can decode (or trash) the MPEG2 stream at "exactly" the same rate
* as it is sent by the server and so we keep the synchronization between
* the server and the client.
*
* It is a very important matter if you want to avoid underflow or overflow
* in all the FIFOs, but it may be not enough.
*/
/*****************************************************************************
* Constants
*****************************************************************************/
/* Maximum number of samples used to compute the dynamic average value,
* it is also the maximum of c_average_count in pgrm_ts_data_t.
* We use the following formula :
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) */
#define CR_MAX_AVERAGE_COUNTER 40
/* Maximum gap allowed between two CRs. */
#define CR_MAX_GAP 1000000
/*****************************************************************************
* CRReInit : Reinitialize the clock reference
*****************************************************************************/
static void CRReInit( pgrm_descriptor_t * p_pgrm )
{
p_pgrm->delta_cr = 0;
p_pgrm->last_cr = 0;
p_pgrm->c_average_count = 0;
}
/* FIXME: find a better name */
/*****************************************************************************
* CRDecode : Decode a clock reference
*****************************************************************************/
static void CRDecode( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm,
mtime_t cr_time )
{
if( p_pgrm->i_synchro_state != SYNCHRO_OK )
{
input_ClockNewRef( p_input, p_pgrm, cr_time );
p_pgrm->i_synchro_state = SYNCHRO_OK;
}
else
{
if( p_pgrm->b_discontinuity ||
( p_pgrm->last_cr != 0 &&
( (p_pgrm->last_cr - cr_time) > CR_MAX_GAP
|| (p_pgrm->last_cr - cr_time) < - CR_MAX_GAP ) ) )
{
#if 0
/* This code is deprecated */
int i_es;
/* Stream discontinuity. */
intf_WarnMsg( 3, "CR re-initialiazed" );
CRReInit( p_pgrm );
p_pgrm->i_synchro_state = SYNCHRO_REINIT;
p_pgrm->b_discontinuity = 0;
/* Warn all the elementary streams */
for( i_es = 0; i_es < p_pgrm->i_es_number; i_es++ )
{
p_pgrm->pp_es[i_es]->b_discontinuity = 1;
}
#endif
}
p_pgrm->last_cr = cr_time;
if( p_input->stream.b_pace_control )
{
/* Wait a while before delivering the packets to the decoder. */
mwait( input_ClockToSysdate( p_input, p_pgrm, cr_time ) );
}
else
{
#if 0
/* This code is deprecated, too */
mtime_t sys_time, delta_cr;
sys_time = mdate();
delta_cr = sys_time - cr_time;
if( p_pgrm->c_average_count == CR_MAX_AVERAGE_COUNTER )
{
p_pgrm->delta_cr = ( delta_cr + (p_pgrm->delta_cr
* (CR_MAX_AVERAGE_COUNTER - 1)) )
/ CR_MAX_AVERAGE_COUNTER;
}
else
{
p_pgrm->delta_cr = ( delta_cr + (p_pgrm->delta_cr
* p_pgrm->c_average_count) )
/ ( p_pgrm->c_average_count + 1 );
p_pgrm->c_average_count++;
}
#endif
}
}
}
/* /*
* PS Demultiplexing * PS Demultiplexing
*/ */
...@@ -939,8 +808,8 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -939,8 +808,8 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
} }
/* Call the pace control. */ /* Call the pace control. */
//intf_Msg("+%lld", scr_time); //intf_Msg("+%lld", scr_time);
CRDecode( p_input, p_input->stream.pp_programs[0], input_ClockManageRef( p_input, p_input->stream.pp_programs[0],
scr_time ); scr_time );
b_trash = 1; b_trash = 1;
} }
break; break;
...@@ -1111,7 +980,8 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1111,7 +980,8 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
( (mtime_t)U32_AT((u32*)&p[6]) << 1 ) ( (mtime_t)U32_AT((u32*)&p[6]) << 1 )
| ( p[10] >> 7 ); | ( p[10] >> 7 );
/* Call the pace control. */ /* Call the pace control. */
CRDecode( p_input, p_es->p_pgrm, pcr_time ); input_ClockManageRef( p_input, p_es->p_pgrm,
pcr_time );
} }
} /* PCR ? */ } /* PCR ? */
} /* valid TS adaptation field ? */ } /* valid TS adaptation field ? */
...@@ -1184,6 +1054,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1184,6 +1054,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
{ {
/* The payload contains PSI tables */ /* The payload contains PSI tables */
#if 0 #if 0
/* FIXME ! write the PSI decoder :p */
input_DemuxPSI( p_input, p_data, p_es, input_DemuxPSI( p_input, p_data, p_es,
b_unit_start, b_lost ); b_unit_start, b_lost );
#endif #endif
......
...@@ -224,8 +224,8 @@ void module_ManageBank( module_bank_t * p_bank ) ...@@ -224,8 +224,8 @@ void module_ManageBank( module_bank_t * p_bank )
} }
else else
{ {
intf_DbgMsg( "module: hiding unused module `%s'", intf_WarnMsg( 1, "module: hiding unused module `%s'",
p_module->psz_name ); p_module->psz_name );
HideModule( p_module ); HideModule( p_module );
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video_parser.c : video parser thread * video_parser.c : video parser thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: video_parser.c,v 1.70 2001/01/24 19:05:55 massiot Exp $ * $Id: video_parser.c,v 1.71 2001/02/07 15:32:26 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>
...@@ -225,6 +225,13 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -225,6 +225,13 @@ static int InitThread( vpar_thread_t *p_vpar )
p_vpar->bit_stream.pf_bitstream_callback = BitstreamCallback; p_vpar->bit_stream.pf_bitstream_callback = BitstreamCallback;
p_vpar->bit_stream.p_callback_arg = (void *)p_vpar; p_vpar->bit_stream.p_callback_arg = (void *)p_vpar;
/* InitBitstream has normally begun to read a PES packet, get its
* PTS/DTS */
if( !p_vpar->p_fifo->b_die )
{
BitstreamCallback( &p_vpar->bit_stream, 1 );
}
/* Initialize parsing data */ /* Initialize parsing data */
p_vpar->sequence.p_forward = NULL; p_vpar->sequence.p_forward = NULL;
p_vpar->sequence.p_backward = NULL; p_vpar->sequence.p_backward = NULL;
......
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