* src/input/input_clock.c: Fixed two long-standing (> 2 years) bugs
authorChristophe Massiot <massiot@videolan.org>
Sun, 27 Jul 2003 14:10:02 +0000 (14:10 +0000)
committerChristophe Massiot <massiot@videolan.org>
Sun, 27 Jul 2003 14:10:02 +0000 (14:10 +0000)
- 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.

NEWS
include/input_ext-intf.h
modules/gui/macosx/controls.m
modules/gui/macosx/intf.m
src/input/input_clock.c

diff --git a/NEWS b/NEWS
index 1a44fc2..fc30076 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,13 @@
-$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:
 ---------------------------------
 
+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:
  * Added vorbis audio support in Ogg streaming.
  * Added vorbis audio transcoding support.
index 056d383..6329f53 100644 (file)
@@ -4,7 +4,7 @@
  * control the pace of reading.
  *****************************************************************************
  * 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>
  *
@@ -112,7 +112,7 @@ struct pgrm_descriptor_t
     mtime_t                 cr_ref, sysdate_ref;
     mtime_t                 last_cr; /* reference to detect unexpected stream
                                       * discontinuities                      */
-    mtime_t                 last_syscr;
+    mtime_t                 last_pts;
     count_t                 c_average_count;
                            /* counter used to compute dynamic average values */
     int                     i_synchro_state;
index 7a21936..24b8b03 100644 (file)
@@ -2,7 +2,7 @@
  * controls.m: MacOS X interface plugin
  *****************************************************************************
  * 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>
  *          Christophe Massiot <massiot@via.ecp.fr>
         return;
     }
 
+    playlist_Play( p_playlist );
     input_Seek( p_playlist->p_input, 5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
     vlc_object_release( p_playlist );
 }
         return;
     }
 
+    playlist_Play( p_playlist );
     input_Seek( p_playlist->p_input, -5, INPUT_SEEK_SECONDS | INPUT_SEEK_CUR );
     vlc_object_release( p_playlist );
 }
index d3d609f..d632797 100644 (file)
@@ -2,7 +2,7 @@
  * intf.m: MacOS X interface plugin
  *****************************************************************************
  * 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>
  *          Christophe Massiot <massiot@via.ecp.fr>
@@ -733,7 +733,10 @@ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
 
                 /* release the lock to be able to seek */
                 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 );
+                vlc_mutex_lock( &p_playlist->object_lock );
                 vlc_mutex_lock( &p_input->stream.stream_lock );
 
                 /* update the old value */
index 7df1aa4..97ed1b0 100644 (file)
@@ -2,7 +2,7 @@
  * input_clock.c: Clock/System date convertions, stream management
  *****************************************************************************
  * 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>
  *
@@ -61,6 +61,9 @@
  * 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
  *****************************************************************************/
 /* Maximum gap allowed between two CRs. */
 #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
  *****************************************************************************/
@@ -90,6 +97,12 @@ static mtime_t ClockToSysdate( input_thread_t * p_input,
         i_sysdate /= 27;
         i_sysdate /= 1000;
         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 );
@@ -115,12 +128,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm,
                          mtime_t i_clock, mtime_t i_sysdate )
 {
     p_pgrm->cr_ref = i_clock;
-    /* this is actually a kludge, but it gives better results when scr
-    * 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 ;
+    p_pgrm->sysdate_ref = i_sysdate ;
 }
 
 /*****************************************************************************
@@ -130,7 +138,7 @@ static void ClockNewRef( pgrm_descriptor_t * p_pgrm,
 void input_ClockInit( pgrm_descriptor_t * p_pgrm )
 {
     p_pgrm->last_cr = 0;
-    p_pgrm->last_syscr = 0;
+    p_pgrm->last_pts = 0;
     p_pgrm->cr_ref = 0;
     p_pgrm->sysdate_ref = 0;
     p_pgrm->delta_cr = 0;
@@ -160,8 +168,8 @@ int input_ClockManageControl( input_thread_t * p_input,
 
         vlc_cond_wait( &p_input->stream.stream_wait,
                        &p_input->stream.stream_lock );
-        p_pgrm->last_syscr = 0;
-        ClockNewRef( p_pgrm, i_clock, mdate() );
+        ClockNewRef( p_pgrm, i_clock, p_pgrm->last_pts > mdate() ?
+                                      p_pgrm->last_pts : mdate() );
 
         if( p_input->stream.i_new_status == PAUSE_S )
         {
@@ -229,7 +237,9 @@ void input_ClockManageRef( input_thread_t * p_input,
     if( ( p_pgrm->i_synchro_state != SYNCHRO_OK ) || ( i_clock == 0 ) )
     {
         /* 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;
 
         if( p_input->stream.b_pace_control
@@ -241,7 +251,6 @@ void input_ClockManageRef( input_thread_t * p_input,
         else
         {
             p_pgrm->last_cr = 0;
-            p_pgrm->last_syscr = 0;
             p_pgrm->delta_cr = 0;
             p_pgrm->c_average_count = 0;
         }
@@ -266,15 +275,10 @@ void input_ClockManageRef( input_thread_t * p_input,
         if( p_input->stream.b_pace_control
              && 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.
              * In case of multiple programs, we arbitrarily follow the
              * clock of the first program. */
-            mwait( p_pgrm->last_syscr );
+            mwait( ClockToSysdate( p_input, p_pgrm, i_clock ) );
 
             /* Now take into account interface changes. */
             input_ClockManageControl( p_input, p_pgrm, i_clock );
@@ -318,8 +322,9 @@ mtime_t input_ClockGetTS( input_thread_t * p_input,
 
     if( p_pgrm->i_synchro_state == SYNCHRO_OK )
     {
-        return( ClockToSysdate( p_input, p_pgrm, i_ts + p_pgrm->delta_cr )
-                 + p_input->i_pts_delay );
+        p_pgrm->last_pts = ClockToSysdate( p_input, p_pgrm,
+                                           i_ts + p_pgrm->delta_cr );
+        return( p_pgrm->last_pts + p_input->i_pts_delay );
     }
     else
     {