[vlc-devel] Clock synchro problems - proposed solution

Marian Durkovic md at bts.sk
Wed Nov 9 09:20:17 CET 2005


Hi all,

   after various tests with different streams seems I've found the reasons
why the synchro has stability problems:

1) the interval for computing clock drift is too small. Clock drift is
currently computed at every PCR - and PCR interval for various streams I have
here is typically between 14 and 39 msec. This is sometimes much less than
network jitter and for small audio streams it means that e.g. 3 different PCRs 
included in the same RTP/UDP packet corrupt the clock drift computation.
Also for streams with variable bitrate, the computation is not accurate, since
due to prebuffering, clock drift is computed from data upto 100 msec in the 
past. Also, due to relatively small time differences I suspect this
calculation suffers also from rounding problems.

2) sometimes the OS on either sender or receiver machine randomly delays the
RTP/UDP packet and this delay is in the order of hundreds of miliseconds.
If this is included in the clock drift calculation, it moves the reference
clock that much, that VLC immediately starts audio resampling and/or drops
the buffer due to PTS being out of range. 


  Please have a look at the attached patch, which tries to solve the above
problems by:

- extending the clock drift computation interval to 1 second,
- using 100 as hardcoded value into smoothing alg. to avoid rounding problems
- ignoring extreme clock difference values ( > 80 msec )

   Any comments are of course welcome.


	With kind regards,


		M.

--------------------------------------------------------------------------
----                                                                  ----
----   Marian Durkovic                       network  manager         ----
----                                                                  ----
----   Slovak Technical University           Tel: +421 2 524 51 301   ----
----   Computer Centre, Nam. Slobody 17      Fax: +421 2 524 94 351   ----
----   812 43 Bratislava, Slovak Republic    E-mail/sip: md at bts.sk    ----
----                                                                  ----
--------------------------------------------------------------------------
-------------- next part --------------
Index: src/input/input_internal.h
===================================================================
--- src/input/input_internal.h	(revision 13150)
+++ src/input/input_internal.h	(working copy)
@@ -133,6 +133,7 @@
     /* Synchronization information */
     mtime_t                 delta_cr;
     mtime_t                 cr_ref, sysdate_ref;
+    mtime_t                 cr_last, cr_pcr_last;
     mtime_t                 last_cr; /* reference to detect unexpected stream
                                       * discontinuities                      */
     mtime_t                 last_pts;
Index: src/input/clock.c
===================================================================
--- src/input/clock.c	(revision 13150)
+++ src/input/clock.c	(working copy)
@@ -136,6 +136,8 @@
     cl->cr_ref = 0;
     cl->sysdate_ref = 0;
     cl->delta_cr = 0;
+    cl->cr_last = 0;
+    cl->cr_pcr_last = 0;
     cl->c_average_count = 0;
 
     cl->i_cr_average = i_cr_average;
@@ -265,6 +267,8 @@
         {
             cl->last_cr = 0;
             cl->delta_cr = 0;
+            cl->cr_last = 0;
+            cl->cr_pcr_last = 0;
             cl->c_average_count = 0;
         }
     }
@@ -310,13 +314,32 @@
         }
         else
         {
-            /* Smooth clock reference variations. */
-            mtime_t i_extrapoled_clock = ClockCurrent( p_input, cl );
+            mtime_t curdate = mdate();
+            mtime_t diff;
 
-            /* Bresenham algorithm to smooth variations. */
-            cl->delta_cr = ( cl->delta_cr * (cl->i_cr_average - 1)
-                               + ( i_extrapoled_clock - i_clock ) )
-                           / cl->i_cr_average;
+            if (!cl->cr_last && !cl->cr_pcr_last)
+            {
+                cl->cr_last = curdate;
+                cl->cr_pcr_last = i_clock;
+            }
+            else if ( curdate - cl->cr_last > 1000000 )
+            {
+               diff = curdate - cl->cr_last - ( (i_clock - cl->cr_pcr_last) *
+                      (mtime_t)p_input->i_rate / 90 );
+               if( diff < -80000 | diff > 80000 )
+               {
+                   msg_Warn( p_input, "diff "I64Fd" too big, ignoring", diff );
+               }
+               else
+               {
+                   /* Bresenham algorithm to smooth variations. */
+                   cl->delta_cr = ( cl->delta_cr * 99 + diff ) / 100;
+                   msg_Dbg (p_input, "delta_cr="I64Fd" diff="I64Fd, cl->delta_cr
+, diff);
+               }
+               cl->cr_last = curdate;
+               cl->cr_pcr_last = i_clock;
+           }
         }
     }
 }


More information about the vlc-devel mailing list