Commit b1d048d8 authored by Laurent Aimar's avatar Laurent Aimar

Protect input_clock_GetTS from concurrent access.

parent a18cf1de
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include <vlc_input.h> #include <vlc_input.h>
#include "input_clock.h" #include "input_clock.h"
/* TODO:
* - clean up locking once clock code is stable
*
*/
/* /*
* DISCUSSION : SYNCHRONIZATION METHOD * DISCUSSION : SYNCHRONIZATION METHOD
* *
...@@ -68,6 +73,7 @@ ...@@ -68,6 +73,7 @@
* new_average = (old_average * c_average + new_sample_value) / (c_average +1) * new_average = (old_average * c_average + new_sample_value) / (c_average +1)
*/ */
/***************************************************************************** /*****************************************************************************
* Constants * Constants
*****************************************************************************/ *****************************************************************************/
...@@ -117,6 +123,9 @@ static inline clock_point_t clock_point_Create( mtime_t i_stream, mtime_t i_syst ...@@ -117,6 +123,9 @@ static inline clock_point_t clock_point_Create( mtime_t i_stream, mtime_t i_syst
/* */ /* */
struct input_clock_t struct input_clock_t
{ {
/* */
vlc_mutex_t lock;
/* Reference point */ /* Reference point */
bool b_has_reference; bool b_has_reference;
clock_point_t ref; clock_point_t ref;
...@@ -148,6 +157,7 @@ input_clock_t *input_clock_New( int i_cr_average, int i_rate ) ...@@ -148,6 +157,7 @@ input_clock_t *input_clock_New( int i_cr_average, int i_rate )
if( !cl ) if( !cl )
return NULL; return NULL;
vlc_mutex_init( &cl->lock );
cl->b_has_reference = false; cl->b_has_reference = false;
cl->ref = clock_point_Create( 0, 0 ); cl->ref = clock_point_Create( 0, 0 );
...@@ -169,6 +179,7 @@ input_clock_t *input_clock_New( int i_cr_average, int i_rate ) ...@@ -169,6 +179,7 @@ input_clock_t *input_clock_New( int i_cr_average, int i_rate )
void input_clock_Delete( input_clock_t *cl ) void input_clock_Delete( input_clock_t *cl )
{ {
AvgClean( &cl->drift ); AvgClean( &cl->drift );
vlc_mutex_destroy( &cl->lock );
free( cl ); free( cl );
} }
...@@ -184,6 +195,7 @@ void input_clock_Update( input_clock_t *cl, ...@@ -184,6 +195,7 @@ void input_clock_Update( input_clock_t *cl,
{ {
bool b_reset_reference = false; bool b_reset_reference = false;
vlc_mutex_lock( &cl->lock );
if( ( !cl->b_has_reference ) || if( ( !cl->b_has_reference ) ||
( i_ck_stream == 0 && cl->last.i_stream != 0 ) ) ( i_ck_stream == 0 && cl->last.i_stream != 0 ) )
{ {
...@@ -224,6 +236,8 @@ void input_clock_Update( input_clock_t *cl, ...@@ -224,6 +236,8 @@ void input_clock_Update( input_clock_t *cl,
cl->i_next_drift_update = i_ck_system + CLOCK_FREQ/5; /* FIXME why that */ cl->i_next_drift_update = i_ck_system + CLOCK_FREQ/5; /* FIXME why that */
} }
cl->last = clock_point_Create( i_ck_stream, i_ck_system ); cl->last = clock_point_Create( i_ck_stream, i_ck_system );
vlc_mutex_unlock( &cl->lock );
} }
/***************************************************************************** /*****************************************************************************
...@@ -231,9 +245,13 @@ void input_clock_Update( input_clock_t *cl, ...@@ -231,9 +245,13 @@ void input_clock_Update( input_clock_t *cl,
*****************************************************************************/ *****************************************************************************/
void input_clock_Reset( input_clock_t *cl ) void input_clock_Reset( input_clock_t *cl )
{ {
vlc_mutex_lock( &cl->lock );
cl->b_has_reference = false; cl->b_has_reference = false;
cl->ref = clock_point_Create( 0, 0 ); cl->ref = clock_point_Create( 0, 0 );
cl->i_ts_max = 0; cl->i_ts_max = 0;
vlc_mutex_unlock( &cl->lock );
} }
/***************************************************************************** /*****************************************************************************
...@@ -241,11 +259,15 @@ void input_clock_Reset( input_clock_t *cl ) ...@@ -241,11 +259,15 @@ void input_clock_Reset( input_clock_t *cl )
*****************************************************************************/ *****************************************************************************/
void input_clock_ChangeRate( input_clock_t *cl, int i_rate ) void input_clock_ChangeRate( input_clock_t *cl, int i_rate )
{ {
vlc_mutex_lock( &cl->lock );
/* Move the reference point */ /* Move the reference point */
if( cl->b_has_reference ) if( cl->b_has_reference )
cl->ref = cl->last; cl->ref = cl->last;
cl->i_rate = i_rate; cl->i_rate = i_rate;
vlc_mutex_unlock( &cl->lock );
} }
/***************************************************************************** /*****************************************************************************
...@@ -253,12 +275,17 @@ void input_clock_ChangeRate( input_clock_t *cl, int i_rate ) ...@@ -253,12 +275,17 @@ void input_clock_ChangeRate( input_clock_t *cl, int i_rate )
*****************************************************************************/ *****************************************************************************/
mtime_t input_clock_GetWakeup( input_clock_t *cl ) mtime_t input_clock_GetWakeup( input_clock_t *cl )
{ {
/* Not synchronized, we cannot wait */ mtime_t i_wakeup = 0;
if( !cl->b_has_reference )
return 0;
/* */ vlc_mutex_lock( &cl->lock );
return ClockStreamToSystem( cl, cl->last.i_stream );
/* Synchronized, we can wait */
if( cl->b_has_reference )
i_wakeup = ClockStreamToSystem( cl, cl->last.i_stream );
vlc_mutex_unlock( &cl->lock );
return i_wakeup;
} }
/***************************************************************************** /*****************************************************************************
...@@ -269,14 +296,21 @@ mtime_t input_clock_GetTS( input_clock_t *cl, ...@@ -269,14 +296,21 @@ mtime_t input_clock_GetTS( input_clock_t *cl,
{ {
mtime_t i_converted_ts; mtime_t i_converted_ts;
vlc_mutex_lock( &cl->lock );
if( !cl->b_has_reference ) if( !cl->b_has_reference )
{
vlc_mutex_unlock( &cl->lock );
return 0; return 0;
}
/* */ /* */
i_converted_ts = ClockStreamToSystem( cl, i_ts + AvgGet( &cl->drift ) ); i_converted_ts = ClockStreamToSystem( cl, i_ts + AvgGet( &cl->drift ) );
if( i_converted_ts > cl->i_ts_max ) if( i_converted_ts > cl->i_ts_max )
cl->i_ts_max = i_converted_ts; cl->i_ts_max = i_converted_ts;
vlc_mutex_unlock( &cl->lock );
return i_converted_ts + i_pts_delay; return i_converted_ts + i_pts_delay;
} }
......
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
/** /**
* This structure is used to manage clock drift and reception jitters * This structure is used to manage clock drift and reception jitters
*
* XXX input_clock_GetTS can be called from any threads. All others functions
* MUST be called from one and only one thread.
*/ */
typedef struct input_clock_t input_clock_t; typedef struct input_clock_t input_clock_t;
......
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