Commit b1bd5cc0 authored by Christophe Massiot's avatar Christophe Massiot

* src/input/input_clock.c: Fixed two long-standing (> 2 years) bugs

- there should be fewer resampling, particularly on DVD chapter changes
- when you unpause a DVD, VLC will wait for the drive to spin up, so you
won't lose several seconds of movies

* modules/gui/macosx/controls.m: Seeking in paused mode resumes the play
mode, make the interface take that into account.
parent 788c882a
$Id: NEWS,v 1.57 2003/07/19 15:25:47 sigmunau Exp $ $Id: NEWS,v 1.58 2003/07/27 14:10:02 massiot Exp $
Changes between 0.6.0 and 0.6.1: Changes between 0.6.0 and 0.6.1:
--------------------------------- ---------------------------------
Core support:
* There should be less bogus resampling, particularly on DVDs.
* VLC will now wait for the medium to wake up before starting its clock
after a pause.
Stream output: Stream output:
* Added vorbis audio support in Ogg streaming. * Added vorbis audio support in Ogg streaming.
* Added vorbis audio transcoding support. * Added vorbis audio transcoding support.
......
...@@ -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.91 2003/05/31 12:24:39 titer Exp $ * $Id: input_ext-intf.h,v 1.92 2003/07/27 14:10:02 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -112,7 +112,7 @@ struct pgrm_descriptor_t ...@@ -112,7 +112,7 @@ struct pgrm_descriptor_t
mtime_t cr_ref, sysdate_ref; mtime_t cr_ref, sysdate_ref;
mtime_t last_cr; /* reference to detect unexpected stream mtime_t last_cr; /* reference to detect unexpected stream
* discontinuities */ * discontinuities */
mtime_t last_syscr; mtime_t last_pts;
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 @@
* controls.m: MacOS X interface plugin * controls.m: MacOS X interface plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 2002-2003 VideoLAN * Copyright (C) 2002-2003 VideoLAN
* $Id: controls.m,v 1.45 2003/07/09 01:31:25 hartman Exp $ * $Id: controls.m,v 1.46 2003/07/27 14:10:02 massiot Exp $
* *
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net> * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -254,6 +254,7 @@ ...@@ -254,6 +254,7 @@
return; return;
} }
playlist_Play( p_playlist );
input_Seek( p_playlist->p_input, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); input_Seek( p_playlist->p_input, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
vlc_object_release( p_playlist ); vlc_object_release( p_playlist );
} }
...@@ -269,6 +270,7 @@ ...@@ -269,6 +270,7 @@
return; return;
} }
playlist_Play( p_playlist );
input_Seek( p_playlist->p_input, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR ); input_Seek( p_playlist->p_input, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
vlc_object_release( p_playlist ); vlc_object_release( p_playlist );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* intf.m: MacOS X interface plugin * intf.m: MacOS X interface plugin
***************************************************************************** *****************************************************************************
* Copyright (C) 2002-2003 VideoLAN * Copyright (C) 2002-2003 VideoLAN
* $Id: intf.m,v 1.91 2003/06/30 01:51:10 hartman Exp $ * $Id: intf.m,v 1.92 2003/07/27 14:10:02 massiot Exp $
* *
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net> * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -733,7 +733,10 @@ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable, ...@@ -733,7 +733,10 @@ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
/* release the lock to be able to seek */ /* release the lock to be able to seek */
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Play( p_playlist );
input_Seek( p_input, i_seek, INPUT_SEEK_SET ); input_Seek( p_input, i_seek, INPUT_SEEK_SET );
vlc_mutex_lock( &p_playlist->object_lock );
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
/* update the old value */ /* update the old value */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_clock.c: Clock/System date convertions, stream management * input_clock.c: Clock/System date convertions, stream management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_clock.c,v 1.37 2003/05/22 16:01:02 gbazin Exp $ * $Id: input_clock.c,v 1.38 2003/07/27 14:10:02 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
* in all the FIFOs, but it may be not enough. * in all the FIFOs, but it may be not enough.
*/ */
static void ClockNewRef( pgrm_descriptor_t * p_pgrm,
mtime_t i_clock, mtime_t i_sysdate );
/***************************************************************************** /*****************************************************************************
* Constants * Constants
*****************************************************************************/ *****************************************************************************/
...@@ -74,6 +77,10 @@ ...@@ -74,6 +77,10 @@
/* Maximum gap allowed between two CRs. */ /* Maximum gap allowed between two CRs. */
#define CR_MAX_GAP 1000000 #define CR_MAX_GAP 1000000
/* Latency introduced on DVDs with CR == 0 on chapter change - this is from
* my dice --Meuuh */
#define CR_MEAN_PTS_GAP 300000
/***************************************************************************** /*****************************************************************************
* ClockToSysdate: converts a movie clock to system date * ClockToSysdate: converts a movie clock to system date
*****************************************************************************/ *****************************************************************************/
...@@ -90,6 +97,12 @@ static mtime_t ClockToSysdate( input_thread_t * p_input, ...@@ -90,6 +97,12 @@ static mtime_t ClockToSysdate( input_thread_t * p_input,
i_sysdate /= 27; i_sysdate /= 27;
i_sysdate /= 1000; i_sysdate /= 1000;
i_sysdate += (mtime_t)p_pgrm->sysdate_ref; i_sysdate += (mtime_t)p_pgrm->sysdate_ref;
if ( i_sysdate < mdate() - CR_MAX_GAP )
{
msg_Warn( p_input, "Bogus clock encountered, resetting" );
ClockNewRef( p_pgrm, i_clock, i_sysdate = mdate() );
}
} }
return( i_sysdate ); return( i_sysdate );
...@@ -115,12 +128,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm, ...@@ -115,12 +128,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm,
mtime_t i_clock, mtime_t i_sysdate ) mtime_t i_clock, mtime_t i_sysdate )
{ {
p_pgrm->cr_ref = i_clock; p_pgrm->cr_ref = i_clock;
/* this is actually a kludge, but it gives better results when scr p_pgrm->sysdate_ref = i_sysdate ;
* is zero in DVDs: we are 3-4 ms in advance instead of sometimes
* 100ms late */
p_pgrm->sysdate_ref = ( p_pgrm->last_syscr && !i_clock )
? p_pgrm->last_syscr
: i_sysdate ;
} }
/***************************************************************************** /*****************************************************************************
...@@ -130,7 +138,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm, ...@@ -130,7 +138,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm,
void input_ClockInit( pgrm_descriptor_t * p_pgrm ) void input_ClockInit( pgrm_descriptor_t * p_pgrm )
{ {
p_pgrm->last_cr = 0; p_pgrm->last_cr = 0;
p_pgrm->last_syscr = 0; p_pgrm->last_pts = 0;
p_pgrm->cr_ref = 0; p_pgrm->cr_ref = 0;
p_pgrm->sysdate_ref = 0; p_pgrm->sysdate_ref = 0;
p_pgrm->delta_cr = 0; p_pgrm->delta_cr = 0;
...@@ -160,8 +168,8 @@ int input_ClockManageControl( input_thread_t * p_input, ...@@ -160,8 +168,8 @@ int input_ClockManageControl( input_thread_t * p_input,
vlc_cond_wait( &p_input->stream.stream_wait, vlc_cond_wait( &p_input->stream.stream_wait,
&p_input->stream.stream_lock ); &p_input->stream.stream_lock );
p_pgrm->last_syscr = 0; ClockNewRef( p_pgrm, i_clock, p_pgrm->last_pts > mdate() ?
ClockNewRef( p_pgrm, i_clock, mdate() ); p_pgrm->last_pts : mdate() );
if( p_input->stream.i_new_status == PAUSE_S ) if( p_input->stream.i_new_status == PAUSE_S )
{ {
...@@ -229,7 +237,9 @@ void input_ClockManageRef( input_thread_t * p_input, ...@@ -229,7 +237,9 @@ void input_ClockManageRef( input_thread_t * p_input,
if( ( p_pgrm->i_synchro_state != SYNCHRO_OK ) || ( i_clock == 0 ) ) if( ( p_pgrm->i_synchro_state != SYNCHRO_OK ) || ( i_clock == 0 ) )
{ {
/* Feed synchro with a new reference point. */ /* Feed synchro with a new reference point. */
ClockNewRef( p_pgrm, i_clock, mdate() ); ClockNewRef( p_pgrm, i_clock,
p_pgrm->last_pts + CR_MEAN_PTS_GAP > mdate() ?
p_pgrm->last_pts + CR_MEAN_PTS_GAP : mdate() );
p_pgrm->i_synchro_state = SYNCHRO_OK; p_pgrm->i_synchro_state = SYNCHRO_OK;
if( p_input->stream.b_pace_control if( p_input->stream.b_pace_control
...@@ -241,7 +251,6 @@ void input_ClockManageRef( input_thread_t * p_input, ...@@ -241,7 +251,6 @@ void input_ClockManageRef( input_thread_t * p_input,
else else
{ {
p_pgrm->last_cr = 0; p_pgrm->last_cr = 0;
p_pgrm->last_syscr = 0;
p_pgrm->delta_cr = 0; p_pgrm->delta_cr = 0;
p_pgrm->c_average_count = 0; p_pgrm->c_average_count = 0;
} }
...@@ -266,15 +275,10 @@ void input_ClockManageRef( input_thread_t * p_input, ...@@ -266,15 +275,10 @@ void input_ClockManageRef( input_thread_t * p_input,
if( p_input->stream.b_pace_control if( p_input->stream.b_pace_control
&& p_input->stream.p_selected_program == p_pgrm ) && p_input->stream.p_selected_program == p_pgrm )
{ {
/* We remember the last system date to be able to restart
* the synchro we statistically better continuity, after
* a zero scr */
p_pgrm->last_syscr = ClockToSysdate( p_input, p_pgrm, i_clock );
/* Wait a while before delivering the packets to the decoder. /* Wait a while before delivering the packets to the decoder.
* In case of multiple programs, we arbitrarily follow the * In case of multiple programs, we arbitrarily follow the
* clock of the first program. */ * clock of the first program. */
mwait( p_pgrm->last_syscr ); mwait( ClockToSysdate( p_input, p_pgrm, i_clock ) );
/* Now take into account interface changes. */ /* Now take into account interface changes. */
input_ClockManageControl( p_input, p_pgrm, i_clock ); input_ClockManageControl( p_input, p_pgrm, i_clock );
...@@ -318,8 +322,9 @@ mtime_t input_ClockGetTS( input_thread_t * p_input, ...@@ -318,8 +322,9 @@ mtime_t input_ClockGetTS( input_thread_t * p_input,
if( p_pgrm->i_synchro_state == SYNCHRO_OK ) if( p_pgrm->i_synchro_state == SYNCHRO_OK )
{ {
return( ClockToSysdate( p_input, p_pgrm, i_ts + p_pgrm->delta_cr ) p_pgrm->last_pts = ClockToSysdate( p_input, p_pgrm,
+ p_input->i_pts_delay ); i_ts + p_pgrm->delta_cr );
return( p_pgrm->last_pts + p_input->i_pts_delay );
} }
else else
{ {
......
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