mirror of https://code.videolan.org/videolan/vlc
clock: expose and require lock for vlc_clock_main_t
All vlc_clock_main_t functions need to be called with this lock held. This allows optimizations where 2 vlc_clock_main_t functions were called in a row.
This commit is contained in:
parent
f1d0bb4f85
commit
81a594b206
|
@ -589,17 +589,18 @@ vlc_clock_main_t *vlc_clock_main_New(struct vlc_logger *parent_logger, struct vl
|
|||
|
||||
void vlc_clock_main_Reset(vlc_clock_main_t *main_clock)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
vlc_clock_main_reset(main_clock);
|
||||
main_clock->first_pcr =
|
||||
clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_SetFirstPcr(vlc_clock_main_t *main_clock,
|
||||
vlc_tick_t system_now, vlc_tick_t ts)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
if (main_clock->first_pcr.system == VLC_TICK_INVALID)
|
||||
{
|
||||
main_clock->first_pcr = clock_point_Create(system_now, ts);
|
||||
|
@ -607,29 +608,29 @@ void vlc_clock_main_SetFirstPcr(vlc_clock_main_t *main_clock,
|
|||
main_clock->wait_sync_ref =
|
||||
clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
|
||||
}
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_SetInputDejitter(vlc_clock_main_t *main_clock,
|
||||
vlc_tick_t delay)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
main_clock->input_dejitter = delay;
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_SetDejitter(vlc_clock_main_t *main_clock,
|
||||
vlc_tick_t dejitter)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
main_clock->output_dejitter = dejitter;
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_ChangePause(vlc_clock_main_t *main_clock, vlc_tick_t now,
|
||||
bool paused)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
assert(paused == (main_clock->pause_date == VLC_TICK_INVALID));
|
||||
|
||||
if (paused)
|
||||
|
@ -653,7 +654,6 @@ void vlc_clock_main_ChangePause(vlc_clock_main_t *main_clock, vlc_tick_t now,
|
|||
main_clock->pause_date = VLC_TICK_INVALID;
|
||||
vlc_cond_broadcast(&main_clock->cond);
|
||||
}
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_Delete(vlc_clock_main_t *main_clock)
|
||||
|
@ -668,6 +668,17 @@ void vlc_clock_main_Delete(vlc_clock_main_t *main_clock)
|
|||
free(main_clock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_Lock(vlc_clock_main_t *main_clock)
|
||||
{
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
}
|
||||
|
||||
void vlc_clock_main_Unlock(vlc_clock_main_t *main_clock)
|
||||
{
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
}
|
||||
|
||||
vlc_tick_t vlc_clock_Update(vlc_clock_t *clock, vlc_tick_t system_now,
|
||||
vlc_tick_t ts, double rate)
|
||||
{
|
||||
|
@ -738,12 +749,13 @@ vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
|
|||
const struct vlc_clock_cbs *cbs,
|
||||
void *cbs_data)
|
||||
{
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
/* The master has always the 0 priority */
|
||||
vlc_clock_t *clock = vlc_clock_main_Create(main_clock, track_str_id, 0, cbs, cbs_data);
|
||||
if (!clock)
|
||||
return NULL;
|
||||
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
assert(main_clock->master == NULL);
|
||||
|
||||
if (main_clock->input_master == NULL)
|
||||
|
@ -753,19 +765,19 @@ vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
|
|||
|
||||
main_clock->master = clock;
|
||||
main_clock->rc++;
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
vlc_clock_t *vlc_clock_main_CreateInputMaster(vlc_clock_main_t *main_clock)
|
||||
{
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
/* The master has always the 0 priority */
|
||||
vlc_clock_t *clock = vlc_clock_main_Create(main_clock, "input", 0, NULL, NULL);
|
||||
if (!clock)
|
||||
return NULL;
|
||||
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
assert(main_clock->input_master == NULL);
|
||||
|
||||
/* Even if the master ES clock has already been created, it should not
|
||||
|
@ -779,7 +791,6 @@ vlc_clock_t *vlc_clock_main_CreateInputMaster(vlc_clock_main_t *main_clock)
|
|||
clock->ops = &master_ops;
|
||||
main_clock->input_master = clock;
|
||||
main_clock->rc++;
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
@ -790,6 +801,8 @@ vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
|
|||
const struct vlc_clock_cbs *cbs,
|
||||
void *cbs_data)
|
||||
{
|
||||
vlc_mutex_assert(&main_clock->lock);
|
||||
|
||||
/* SPU outputs should have lower priority than VIDEO outputs since they
|
||||
* necessarily depend on a VIDEO output. This mean that a SPU reference
|
||||
* point will always be overridden by AUDIO or VIDEO outputs. Cf.
|
||||
|
@ -812,10 +825,8 @@ vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
|
|||
if (!clock)
|
||||
return NULL;
|
||||
|
||||
vlc_mutex_lock(&main_clock->lock);
|
||||
clock->ops = &slave_ops;
|
||||
main_clock->rc++;
|
||||
vlc_mutex_unlock(&main_clock->lock);
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
|
|
@ -79,16 +79,48 @@ vlc_clock_main_t *vlc_clock_main_New(struct vlc_logger *parent_logger, struct vl
|
|||
|
||||
/**
|
||||
* Destroy the clock main
|
||||
*
|
||||
* @param main_clock the unlocked main_clock
|
||||
*/
|
||||
void vlc_clock_main_Delete(vlc_clock_main_t *main_clock);
|
||||
|
||||
/**
|
||||
* Lock the main_clock mutex
|
||||
*
|
||||
* All vlc_clock_main_t functions must be called with the lock held, except
|
||||
* vlc_clock_main_Delete()
|
||||
*
|
||||
* @param main_clock the unlocked main_clock
|
||||
*/
|
||||
void vlc_clock_main_Lock(vlc_clock_main_t *main_clock);
|
||||
|
||||
/**
|
||||
* Unlock the main_clock mutex
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_Unlock(vlc_clock_main_t *main_clock);
|
||||
|
||||
/**
|
||||
* Reset the vlc_clock_main_t
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_Reset(vlc_clock_main_t *main_clock);
|
||||
|
||||
/**
|
||||
* Set the first PCR point
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_SetFirstPcr(vlc_clock_main_t *main_clock,
|
||||
vlc_tick_t system_now, vlc_tick_t ts);
|
||||
|
||||
/**
|
||||
* Set the input dejitter
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_SetInputDejitter(vlc_clock_main_t *main_clock,
|
||||
vlc_tick_t delay);
|
||||
|
||||
|
@ -96,12 +128,16 @@ void vlc_clock_main_SetInputDejitter(vlc_clock_main_t *main_clock,
|
|||
* This function sets the dejitter delay to absorb the clock jitter
|
||||
*
|
||||
* Also used as the maximum delay before the synchro is considered to kick in.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_SetDejitter(vlc_clock_main_t *main_clock, vlc_tick_t dejitter);
|
||||
|
||||
|
||||
/**
|
||||
* This function allows changing the pause status.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
void vlc_clock_main_ChangePause(vlc_clock_main_t *clock, vlc_tick_t system_now,
|
||||
bool paused);
|
||||
|
@ -112,6 +148,8 @@ void vlc_clock_main_ChangePause(vlc_clock_main_t *clock, vlc_tick_t system_now,
|
|||
* @warning There can be only one master at a given time.
|
||||
*
|
||||
* You must use vlc_clock_Delete to free it.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
|
||||
const char *track_str_id,
|
||||
|
@ -127,6 +165,8 @@ vlc_clock_t *vlc_clock_main_CreateMaster(vlc_clock_main_t *main_clock,
|
|||
* @warning There can be only one input master at a given time.
|
||||
*
|
||||
* You must use vlc_clock_Delete to free it.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
vlc_clock_t *vlc_clock_main_CreateInputMaster(vlc_clock_main_t *main_clock);
|
||||
|
||||
|
@ -134,6 +174,8 @@ vlc_clock_t *vlc_clock_main_CreateInputMaster(vlc_clock_main_t *main_clock);
|
|||
* This function creates a new slave vlc_clock_t interface
|
||||
*
|
||||
* You must use vlc_clock_Delete to free it.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
|
||||
const char *track_str_id,
|
||||
|
@ -145,6 +187,8 @@ vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
|
|||
* This function creates a new slave vlc_clock_t interface
|
||||
*
|
||||
* You must use vlc_clock_Delete to free it.
|
||||
*
|
||||
* @param main_clock the locked main_clock
|
||||
*/
|
||||
vlc_clock_t *vlc_clock_CreateSlave(const vlc_clock_t *clock,
|
||||
enum es_format_category_e cat);
|
||||
|
|
|
@ -1038,6 +1038,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
|
|||
|
||||
input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_input_clock, true, update );
|
||||
|
||||
vlc_clock_main_Lock(p_sys->p_pgrm->clocks.main);
|
||||
/* Resetting the main_clock here will drop all points that were sent during
|
||||
* the buffering step. Only points coming from the input_clock are dropped
|
||||
* here. Indeed, decoders should not send any output frames while buffering
|
||||
|
@ -1053,6 +1054,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
|
|||
* point for the sync point. */
|
||||
vlc_clock_main_SetFirstPcr(p_sys->p_pgrm->clocks.main, update,
|
||||
i_stream_start);
|
||||
vlc_clock_main_Unlock(p_sys->p_pgrm->clocks.main);
|
||||
|
||||
foreach_es_then_es_slaves(p_es)
|
||||
{
|
||||
|
@ -1112,7 +1114,10 @@ static void EsOutProgramChangePause( es_out_t *out, bool b_paused, vlc_tick_t i_
|
|||
vlc_list_foreach(pgrm, &p_sys->programs, node)
|
||||
{
|
||||
input_clock_ChangePause(pgrm->p_input_clock, b_paused, i_date);
|
||||
|
||||
vlc_clock_main_Lock(pgrm->clocks.main);
|
||||
vlc_clock_main_ChangePause(pgrm->clocks.main, i_date, b_paused);
|
||||
vlc_clock_main_Unlock(pgrm->clocks.main);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1304,8 +1309,10 @@ static void EsOutProgramHandleClockSource( es_out_t *out, es_out_pgrm_t *p_pgrm
|
|||
/* Fall-through */
|
||||
case VLC_CLOCK_MASTER_INPUT:
|
||||
{
|
||||
vlc_clock_main_Lock(p_sys->p_pgrm->clocks.main);
|
||||
p_pgrm->clocks.input =
|
||||
vlc_clock_main_CreateInputMaster(p_pgrm->clocks.main);
|
||||
vlc_clock_main_Unlock(p_sys->p_pgrm->clocks.main);
|
||||
|
||||
if (p_pgrm->clocks.input == NULL)
|
||||
break;
|
||||
|
@ -1332,8 +1339,10 @@ static void EsOutProgramHandleClockSource( es_out_t *out, es_out_pgrm_t *p_pgrm
|
|||
|
||||
if (p_pgrm->active_clock_source != VLC_CLOCK_MASTER_INPUT)
|
||||
{
|
||||
vlc_clock_main_Lock(p_pgrm->clocks.main);
|
||||
p_pgrm->clocks.input = vlc_clock_main_CreateSlave(
|
||||
p_pgrm->clocks.main, "pcr", UNKNOWN_ES, NULL, NULL);
|
||||
vlc_clock_main_Unlock(p_pgrm->clocks.main);
|
||||
|
||||
if (p_pgrm->clocks.input != NULL)
|
||||
{
|
||||
|
@ -1508,6 +1517,8 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, input_source_t *source, in
|
|||
const vlc_tick_t pts_delay = p_sys->i_pts_delay + p_sys->i_pts_jitter
|
||||
+ p_sys->i_tracks_pts_delay;
|
||||
input_clock_SetJitter( p_pgrm->p_input_clock, pts_delay, p_sys->i_cr_average );
|
||||
|
||||
vlc_clock_main_Lock(p_pgrm->clocks.main);
|
||||
vlc_clock_main_SetInputDejitter(p_pgrm->clocks.main, pts_delay );
|
||||
|
||||
/* In case of low delay: don't use any output dejitter. This may result on
|
||||
|
@ -1515,6 +1526,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, input_source_t *source, in
|
|||
* than the visual quality if the user chose this option. */
|
||||
if (input_priv(p_input)->b_low_delay)
|
||||
vlc_clock_main_SetDejitter(p_pgrm->clocks.main, 0);
|
||||
vlc_clock_main_Unlock(p_pgrm->clocks.main);
|
||||
|
||||
/* Append it */
|
||||
vlc_list_append(&p_pgrm->node, &p_sys->programs);
|
||||
|
@ -2272,6 +2284,7 @@ static void EsOutCreateDecoder( es_out_t *out, es_out_id_t *p_es )
|
|||
vlc_assert_unreachable();
|
||||
}
|
||||
|
||||
vlc_clock_main_Lock(p_es->p_pgrm->clocks.main);
|
||||
if( p_es->fmt.i_cat != UNKNOWN_ES
|
||||
&& p_es->fmt.i_cat == clock_source_cat
|
||||
&& p_es->p_pgrm->p_master_es_clock == NULL )
|
||||
|
@ -2290,6 +2303,7 @@ static void EsOutCreateDecoder( es_out_t *out, es_out_id_t *p_es )
|
|||
p_es->fmt.i_cat,
|
||||
&clock_cbs, p_es);
|
||||
}
|
||||
vlc_clock_main_Unlock(p_es->p_pgrm->clocks.main);
|
||||
|
||||
if( !p_es->p_clock )
|
||||
{
|
||||
|
@ -3929,7 +3943,9 @@ static int EsOutVaPrivControlLocked( es_out_t *out, input_source_t *source,
|
|||
{
|
||||
input_clock_SetJitter(pgrm->p_input_clock,
|
||||
i_pts_delay, i_cr_average);
|
||||
vlc_clock_main_Lock(pgrm->clocks.main);
|
||||
vlc_clock_main_SetInputDejitter(pgrm->clocks.main, i_pts_delay);
|
||||
vlc_clock_main_Unlock(pgrm->clocks.main);
|
||||
}
|
||||
return VLC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -792,15 +792,21 @@ void sout_ClockMainDelete( vlc_clock_main_t *main_clock )
|
|||
|
||||
void sout_ClockMainSetFirstPcr( vlc_clock_main_t *main_clock, vlc_tick_t pcr )
|
||||
{
|
||||
vlc_clock_main_Lock( main_clock );
|
||||
vlc_clock_main_Reset( main_clock );
|
||||
vlc_clock_main_SetFirstPcr( main_clock, vlc_tick_now(), pcr );
|
||||
vlc_clock_main_Unlock( main_clock );
|
||||
}
|
||||
|
||||
vlc_clock_t *sout_ClockCreate( vlc_clock_main_t *main_clock,
|
||||
const es_format_t *fmt )
|
||||
{
|
||||
return vlc_clock_main_CreateSlave( main_clock, NULL, fmt->i_cat,
|
||||
NULL, NULL );
|
||||
vlc_clock_main_Lock( main_clock );
|
||||
vlc_clock_t *clock =
|
||||
vlc_clock_main_CreateSlave( main_clock, NULL, fmt->i_cat,
|
||||
NULL, NULL );
|
||||
vlc_clock_main_Unlock( main_clock );
|
||||
return clock;
|
||||
}
|
||||
|
||||
void sout_ClockDelete( vlc_clock_t *clock )
|
||||
|
|
Loading…
Reference in New Issue