[vlc-devel] commit: Added es_out_ControlModifyPcrSystem to synchronize the input clock on an external source . (Laurent Aimar )

git version control git at videolan.org
Thu Jan 28 22:02:19 CET 2010


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Thu Jan 28 21:53:58 2010 +0100| [d147f145510bb7c1f07cd95a050a0e709223f6ec] | committer: Laurent Aimar 

Added es_out_ControlModifyPcrSystem to synchronize the input clock on an external source.

It could be used to update the netsynch module or to lock the input
clock on the audio one.

Partially based on a patch by Jean-Paul Saman.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d147f145510bb7c1f07cd95a050a0e709223f6ec
---

 include/vlc_es_out.h         |    5 +++++
 src/input/clock.c            |   24 ++++++++++++++++++++++--
 src/input/clock.h            |    9 +++++----
 src/input/es_out.c           |   18 +++++++++++++++++-
 src/input/es_out_timeshift.c |   10 ++++++++++
 5 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
index 357b0ad..78d3168 100644
--- a/include/vlc_es_out.h
+++ b/include/vlc_es_out.h
@@ -87,6 +87,7 @@ enum es_out_query_e
 
     /* PCR system clock manipulation for external clock synchronization */
     ES_OUT_GET_PCR_SYSTEM, /* arg1=mtime_t * res=can fail */
+    ES_OUT_MODIFY_PCR_SYSTEM, /* arg1=int is_absolute, arg2=mtime_t, res=can fail */
 
     /* First value usable for private control */
     ES_OUT_PRIVATE_START = 0x10000,
@@ -152,6 +153,10 @@ static inline int es_out_ControlGetPcrSystem( es_out_t *out, mtime_t *pi_system
 {
     return es_out_Control( out, ES_OUT_GET_PCR_SYSTEM, pi_system );
 }
+static inline int es_out_ControlModifyPcrSystem( es_out_t *out, bool b_absolute, mtime_t i_system )
+{
+    return es_out_Control( out, ES_OUT_MODIFY_PCR_SYSTEM, b_absolute, i_system );
+}
 
 /**
  * @}
diff --git a/src/input/clock.c b/src/input/clock.c
index 2902949..9b87b4b 100644
--- a/src/input/clock.c
+++ b/src/input/clock.c
@@ -169,6 +169,10 @@ struct input_clock_t
     clock_point_t ref;
     bool          b_has_reference;
 
+    /* External clock drift */
+    mtime_t       i_external_clock;
+    bool          b_has_external_clock;
+
     /* Current modifiers */
     bool    b_paused;
     int     i_rate;
@@ -193,6 +197,7 @@ input_clock_t *input_clock_New( int i_rate )
     vlc_mutex_init( &cl->lock );
     cl->b_has_reference = false;
     cl->ref = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
+    cl->b_has_external_clock = false;
 
     cl->last = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
 
@@ -272,6 +277,7 @@ void input_clock_Update( input_clock_t *cl, vlc_object_t *p_log,
         cl->b_has_reference = true;
         cl->ref = clock_point_Create( i_ck_stream,
                                       __MAX( cl->i_ts_max + CR_MEAN_PTS_GAP, i_ck_system ) );
+        cl->b_has_external_clock = false;
     }
 
     /* Compute the drift between the stream clock and the system clock
@@ -329,6 +335,7 @@ void input_clock_Reset( input_clock_t *cl )
 
     cl->b_has_reference = false;
     cl->ref = clock_point_Create( VLC_TS_INVALID, VLC_TS_INVALID );
+    cl->b_has_external_clock = false;
     cl->i_ts_max = VLC_TS_INVALID;
 
     vlc_mutex_unlock( &cl->lock );
@@ -482,12 +489,25 @@ int input_clock_GetState( input_clock_t *cl,
     return VLC_SUCCESS;
 }
 
-void input_clock_ChangeSystemOrigin( input_clock_t *cl, mtime_t i_system )
+void input_clock_ChangeSystemOrigin( input_clock_t *cl, bool b_absolute, mtime_t i_system )
 {
     vlc_mutex_lock( &cl->lock );
 
     assert( cl->b_has_reference );
-    const mtime_t i_offset = i_system - cl->ref.i_system - ClockGetTsOffset( cl );
+    mtime_t i_offset;
+    if( b_absolute )
+    {
+        i_offset = i_system - cl->ref.i_system - ClockGetTsOffset( cl );
+    }
+    else
+    {
+        if( !cl->b_has_external_clock )
+        {
+            cl->b_has_external_clock = true;
+            cl->i_external_clock     = i_system;
+        }
+        i_offset = i_system - cl->i_external_clock;
+    }
 
     cl->ref.i_system += i_offset;
     cl->last.i_system += i_offset;
diff --git a/src/input/clock.h b/src/input/clock.h
index ab3509e..688b56f 100644
--- a/src/input/clock.h
+++ b/src/input/clock.h
@@ -90,11 +90,12 @@ void    input_clock_ChangePause( input_clock_t *, bool b_paused, mtime_t i_date
 mtime_t input_clock_GetSystemOrigin( input_clock_t * );
 
 /**
- * This function allows to rebase the original system value date.
- * It can be called only imediatly after a input_clock_Update call.
- * FIXME ugly
+ * This function allows to rebase the original system value date (a valid
+ * reference point must have been set).
+ * When using the absolute mode, it will create a discontinuity unless
+ * called imediatly after a input_clock_Update.
  */
-void    input_clock_ChangeSystemOrigin( input_clock_t *, mtime_t i_system );
+void    input_clock_ChangeSystemOrigin( input_clock_t *, bool b_absolute, mtime_t i_system );
 
 /**
  * This function converts a pair of timestamp from stream clock to system clock.
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 0762690..f2546b5 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -679,7 +679,8 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
     const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/
     const mtime_t i_current_date = p_sys->b_paused ? p_sys->i_pause_date : mdate();
 
-    input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, i_current_date + i_wakeup_delay - i_buffering_duration );
+    input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, true,
+                                    i_current_date + i_wakeup_delay - i_buffering_duration );
 
     for( int i = 0; i < p_sys->i_es; i++ )
     {
@@ -2580,6 +2581,21 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
             return VLC_SUCCESS;
         }
 
+        case ES_OUT_MODIFY_PCR_SYSTEM:
+        {
+            if( p_sys->b_buffering )
+                return VLC_EGENERIC;
+
+            es_out_pgrm_t *p_pgrm = p_sys->p_pgrm;
+            if( !p_pgrm )
+                return VLC_EGENERIC;
+
+            const bool    b_absolute = va_arg( args, int );
+            const mtime_t i_system   = va_arg( args, mtime_t );
+            input_clock_ChangeSystemOrigin( p_pgrm->p_clock, b_absolute, i_system );
+            return VLC_SUCCESS;
+        }
+
         default:
             msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
             return VLC_EGENERIC;
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 5118936..032b854 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -681,6 +681,16 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         mtime_t *pi_system = (mtime_t*)va_arg( args, mtime_t * );
         return es_out_ControlGetPcrSystem( p_sys->p_out, pi_system );
     }
+    case ES_OUT_MODIFY_PCR_SYSTEM:
+    {
+        const bool    b_absolute = va_arg( args, int );
+        const mtime_t i_system   = va_arg( args, mtime_t );
+
+        if( b_absolute && p_sys->b_delayed )
+            return VLC_EGENERIC;
+
+        return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system );
+    }
     default:
         msg_Err( p_sys->p_input, "Unknown es_out_Control query !" );
         assert(0);




More information about the vlc-devel mailing list