clock: require the lock for all functions

Instead of wondering if a specific function need to be called locked or
not.

This allows few optimizations where 2 clock functions were called in a
row.
This commit is contained in:
Thomas Guillem 2024-03-15 14:33:29 +01:00 committed by Felix Paul Kühne
parent 9af0658668
commit b61be68d6a
9 changed files with 162 additions and 81 deletions

View File

@ -183,7 +183,9 @@ static void stream_Reset(vlc_aout_stream *stream)
if (stream->filters)
aout_FiltersFlush (stream->filters);
vlc_clock_Lock(stream->sync.clock);
vlc_clock_Reset(stream->sync.clock);
vlc_clock_Unlock(stream->sync.clock);
if (stream->filters)
aout_FiltersResetClock(stream->filters);
@ -195,7 +197,9 @@ static void stream_Reset(vlc_aout_stream *stream)
* dejitter. This will allow the aout to update the master clock
* sooner.
*/
vlc_clock_Lock(stream->sync.clock);
vlc_clock_SetDelay(stream->sync.clock, 0);
vlc_clock_Unlock(stream->sync.clock);
if (stream->filters)
aout_FiltersSetClockDelay(stream->filters, 0);
stream->sync.request_delay = stream->sync.delay;
@ -456,9 +460,11 @@ static void stream_Silence (vlc_aout_stream *stream, vlc_tick_t length, vlc_tick
block->i_length = length;
const vlc_tick_t system_now = vlc_tick_now();
vlc_clock_Lock(stream->sync.clock);
const vlc_tick_t system_pts =
vlc_clock_ConvertToSystem(stream->sync.clock, system_now, pts,
stream->sync.rate);
vlc_clock_Unlock(stream->sync.clock);
stream->timing.played_samples += block->i_nb_samples;
aout->play(aout, block, system_pts);
}
@ -657,8 +663,10 @@ static void stream_Synchronize(vlc_aout_stream *stream, vlc_tick_t system_now,
}
}
vlc_clock_Lock(stream->sync.clock);
drift = vlc_clock_Update(stream->sync.clock, system_now + delay,
dec_pts, stream->sync.rate);
vlc_clock_Unlock(stream->sync.clock);
}
stream_HandleDrift(stream, drift, dec_pts);
@ -699,9 +707,11 @@ void vlc_aout_stream_NotifyTiming(vlc_aout_stream *stream, vlc_tick_t system_ts,
stream->timing.system_ts = system_ts;
stream->timing.audio_ts = audio_ts;
vlc_clock_Lock(stream->sync.clock);
stream->timing.last_drift =
vlc_clock_Update(stream->sync.clock, system_ts,
audio_ts, stream->timing.rate);
vlc_clock_Unlock(stream->sync.clock);
vlc_mutex_unlock(&stream->timing.lock);
}
@ -760,7 +770,9 @@ int vlc_aout_stream_Play(vlc_aout_stream *stream, block_t *block)
if (stream->sync.request_delay != stream->sync.delay)
{
stream->sync.delay = stream->sync.request_delay;
vlc_clock_Lock(stream->sync.clock);
vlc_tick_t delta = vlc_clock_SetDelay(stream->sync.clock, stream->sync.delay);
vlc_clock_Unlock(stream->sync.clock);
if (stream->filters)
aout_FiltersSetClockDelay(stream->filters, stream->sync.delay);
if (delta > 0)
@ -770,9 +782,11 @@ int vlc_aout_stream_Play(vlc_aout_stream *stream, block_t *block)
/* Drift correction */
vlc_tick_t system_now = vlc_tick_now();
vlc_clock_Lock(stream->sync.clock);
vlc_tick_t play_date =
vlc_clock_ConvertToSystem(stream->sync.clock, system_now, original_pts,
stream->sync.rate);
vlc_clock_Unlock(stream->sync.clock);
stream_Synchronize(stream, system_now, play_date, original_pts);
vlc_audio_meter_Process(&owner->meter, block, play_date);
@ -788,9 +802,11 @@ int vlc_aout_stream_Play(vlc_aout_stream *stream, block_t *block)
/* Update the clock immediately with the new rate, instead of waiting
* for a timing update that could come too late (after 1second). */
vlc_clock_Lock(stream->sync.clock);
stream->timing.last_drift =
vlc_clock_Update(stream->sync.clock, play_date, original_pts,
stream->sync.rate);
vlc_clock_Unlock(stream->sync.clock);
vlc_mutex_unlock(&stream->timing.lock);
}
@ -861,10 +877,12 @@ void vlc_aout_stream_ChangePause(vlc_aout_stream *stream, bool paused, vlc_tick_
if (aout->time_get == NULL && !paused
&& stream->timing.rate_audio_ts != VLC_TICK_INVALID)
{
vlc_clock_Lock(stream->sync.clock);
vlc_tick_t play_date =
vlc_clock_ConvertToSystem(stream->sync.clock, date,
stream->timing.rate_audio_ts,
stream->sync.rate);
vlc_clock_Unlock(stream->sync.clock);
stream->timing.rate_system_ts = play_date;
}
}

View File

@ -418,7 +418,9 @@ vout_thread_t *aout_filter_GetVout(filter_t *filter, const video_format_t *fmt)
assert(owner_sys->clock == NULL);
assert(owner_sys->vout == NULL);
vlc_clock_Lock(owner_sys->clock_source);
vlc_clock_t *clock = vlc_clock_CreateSlave(owner_sys->clock_source, AUDIO_ES);
vlc_clock_Unlock(owner_sys->clock_source);
if (clock == NULL)
return NULL;
@ -700,7 +702,11 @@ static void aout_FiltersPipelineResetClock(const struct aout_filter *tab,
{
vlc_clock_t *clock = tab[i].clock;
if (clock != NULL)
{
vlc_clock_Lock(clock);
vlc_clock_Reset(clock);
vlc_clock_Unlock(clock);
}
}
}
@ -717,7 +723,11 @@ static void aout_FiltersPipelineSetClockDelay(const struct aout_filter *tab,
{
vlc_clock_t *clock = tab[i].clock;
if (clock != NULL)
{
vlc_clock_Lock(clock);
vlc_clock_SetDelay(clock, delay);
vlc_clock_Unlock(clock);
}
}
}

View File

@ -80,8 +80,8 @@ struct vlc_clock_ops
unsigned frame_rate, unsigned frame_rate_base);
void (*reset)(vlc_clock_t *clock);
vlc_tick_t (*set_delay)(vlc_clock_t *clock, vlc_tick_t delay);
vlc_tick_t (*to_system_locked)(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate);
vlc_tick_t (*to_system)(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate);
};
struct vlc_clock_t
@ -103,6 +103,7 @@ vlc_clock_AddListener(vlc_clock_t *clock,
{
vlc_clock_main_t *main_clock = clock->owner;
assert(cbs != NULL);
vlc_mutex_assert(&main_clock->lock);
vlc_clock_listener_id *listener_id = malloc(sizeof(*listener_id));
if (listener_id == NULL)
@ -112,10 +113,7 @@ vlc_clock_AddListener(vlc_clock_t *clock,
listener_id->cbs = cbs;
listener_id->data = data;
vlc_mutex_lock(&main_clock->lock);
bool success = vlc_vector_push(&main_clock->listeners, listener_id);
vlc_mutex_unlock(&main_clock->lock);
if (!success)
{
free(listener_id);
@ -128,8 +126,7 @@ void
vlc_clock_RemoveListener(vlc_clock_t *clock, vlc_clock_listener_id *listener_id)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
vlc_mutex_assert(&main_clock->lock);
const vlc_clock_listener_id *it;
vlc_vector_foreach(it, &main_clock->listeners)
@ -137,8 +134,6 @@ vlc_clock_RemoveListener(vlc_clock_t *clock, vlc_clock_listener_id *listener_id)
{
vlc_vector_remove(&main_clock->listeners, vlc_vector_idx_it);
free(listener_id);
vlc_mutex_unlock(&main_clock->lock);
return;
}
@ -232,8 +227,6 @@ static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
if (unlikely(ts == VLC_TICK_INVALID || system_now == VLC_TICK_INVALID))
return VLC_TICK_INVALID;
vlc_mutex_lock(&main_clock->lock);
/* If system_now is VLC_TICK_MAX, the update is forced, don't modify
* anything but only notify the new clock point. */
if (system_now != VLC_TICK_MAX)
@ -312,8 +305,6 @@ static vlc_tick_t vlc_clock_master_update(vlc_clock_t *clock,
vlc_cond_broadcast(&main_clock->cond);
}
vlc_mutex_unlock(&main_clock->lock);
/* Fix the reported ts if both master and slaves source are delayed. This
* happens if we apply a positive delay to the master, and then lower it. */
if (clock->delay > 0 && main_clock->delay < 0 && ts > -main_clock->delay)
@ -329,7 +320,6 @@ static void vlc_clock_master_reset(vlc_clock_t *clock)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
if (main_clock->tracer != NULL && clock->track_str_id != NULL)
vlc_tracer_TraceEvent(main_clock->tracer, "RENDER", clock->track_str_id,
"reset_user");
@ -353,15 +343,12 @@ static void vlc_clock_master_reset(vlc_clock_t *clock)
}
}
vlc_mutex_unlock(&main_clock->lock);
vlc_clock_on_update(clock, VLC_TICK_INVALID, VLC_TICK_INVALID, VLC_TICK_INVALID, 1.f, 0, 0);
}
static vlc_tick_t vlc_clock_master_set_delay(vlc_clock_t *clock, vlc_tick_t delay)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
vlc_tick_t delta = delay - clock->delay;
@ -381,13 +368,12 @@ static vlc_tick_t vlc_clock_master_set_delay(vlc_clock_t *clock, vlc_tick_t dela
assert(clock->delay >= 0);
vlc_cond_broadcast(&main_clock->cond);
vlc_mutex_unlock(&main_clock->lock);
return delta;
}
static vlc_tick_t
vlc_clock_monotonic_to_system_locked(vlc_clock_t *clock, vlc_tick_t now,
vlc_tick_t ts, double rate)
vlc_clock_monotonic_to_system(vlc_clock_t *clock, vlc_tick_t now,
vlc_tick_t ts, double rate)
{
vlc_clock_main_t *main_clock = clock->owner;
@ -421,9 +407,9 @@ vlc_clock_monotonic_to_system_locked(vlc_clock_t *clock, vlc_tick_t now,
+ main_clock->wait_sync_ref.system;
}
static vlc_tick_t vlc_clock_slave_to_system_locked(vlc_clock_t *clock,
vlc_tick_t now,
vlc_tick_t ts, double rate)
static vlc_tick_t vlc_clock_slave_to_system(vlc_clock_t *clock,
vlc_tick_t now, vlc_tick_t ts,
double rate)
{
vlc_clock_main_t *main_clock = clock->owner;
@ -432,15 +418,15 @@ static vlc_tick_t vlc_clock_slave_to_system_locked(vlc_clock_t *clock,
{
/* We don't have a master sync point, let's fallback to a monotonic ref
* point */
system = vlc_clock_monotonic_to_system_locked(clock, now, ts, rate);
system = vlc_clock_monotonic_to_system(clock, now, ts, rate);
}
return system + (clock->delay - main_clock->delay) * rate;
}
static vlc_tick_t vlc_clock_master_to_system_locked(vlc_clock_t *clock,
vlc_tick_t now,
vlc_tick_t ts, double rate)
static vlc_tick_t vlc_clock_master_to_system(vlc_clock_t *clock,
vlc_tick_t now, vlc_tick_t ts,
double rate)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_tick_t system = main_stream_to_system(main_clock, ts);
@ -448,7 +434,7 @@ static vlc_tick_t vlc_clock_master_to_system_locked(vlc_clock_t *clock,
{
/* We don't have a master sync point, let's fallback to a monotonic ref
* point */
system = vlc_clock_monotonic_to_system_locked(clock, now, ts, rate);
system = vlc_clock_monotonic_to_system(clock, now, ts, rate);
}
return system;
@ -460,8 +446,6 @@ static vlc_tick_t vlc_clock_slave_update(vlc_clock_t *clock,
unsigned frame_rate,
unsigned frame_rate_base)
{
vlc_clock_main_t *main_clock = clock->owner;
if (system_now == VLC_TICK_MAX)
{
/* If system_now is VLC_TICK_MAX, the update is forced, don't modify
@ -471,11 +455,7 @@ static vlc_tick_t vlc_clock_slave_update(vlc_clock_t *clock,
return VLC_TICK_MAX;
}
vlc_mutex_lock(&main_clock->lock);
vlc_tick_t computed = clock->ops->to_system_locked(clock, system_now, ts, rate);
vlc_mutex_unlock(&main_clock->lock);
vlc_tick_t computed = clock->ops->to_system(clock, system_now, ts, rate);
vlc_tick_t drift = computed - system_now;
vlc_clock_on_update(clock, computed, ts, drift, rate,
@ -486,13 +466,10 @@ static vlc_tick_t vlc_clock_slave_update(vlc_clock_t *clock,
static void vlc_clock_slave_reset(vlc_clock_t *clock)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
main_clock->wait_sync_ref_priority = UINT_MAX;
main_clock->wait_sync_ref =
clock_point_Create(VLC_TICK_INVALID, VLC_TICK_INVALID);
vlc_mutex_unlock(&main_clock->lock);
vlc_clock_on_update(clock, VLC_TICK_INVALID, VLC_TICK_INVALID,
VLC_TICK_INVALID, 1.0f, 0, 0);
}
@ -500,12 +477,10 @@ static void vlc_clock_slave_reset(vlc_clock_t *clock)
static vlc_tick_t vlc_clock_slave_set_delay(vlc_clock_t *clock, vlc_tick_t delay)
{
vlc_clock_main_t *main_clock = clock->owner;
vlc_mutex_lock(&main_clock->lock);
clock->delay = delay;
vlc_cond_broadcast(&main_clock->cond);
vlc_mutex_unlock(&main_clock->lock);
return 0;
}
@ -545,6 +520,8 @@ int vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t deadline)
void vlc_clock_Wake(vlc_clock_t *clock)
{
AssertLocked(clock);
vlc_clock_main_t *main_clock = clock->owner;
vlc_cond_broadcast(&main_clock->cond);
}
@ -682,6 +659,7 @@ void vlc_clock_main_Unlock(vlc_clock_main_t *main_clock)
vlc_tick_t vlc_clock_Update(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate)
{
AssertLocked(clock);
return clock->ops->update(clock, system_now, ts, rate, 0, 0);
}
@ -689,38 +667,42 @@ vlc_tick_t vlc_clock_UpdateVideo(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate,
unsigned frame_rate, unsigned frame_rate_base)
{
AssertLocked(clock);
return clock->ops->update(clock, system_now, ts, rate, frame_rate, frame_rate_base);
}
void vlc_clock_Reset(vlc_clock_t *clock)
{
AssertLocked(clock);
clock->ops->reset(clock);
}
vlc_tick_t vlc_clock_SetDelay(vlc_clock_t *clock, vlc_tick_t delay)
{
AssertLocked(clock);
return clock->ops->set_delay(clock, delay);
}
vlc_tick_t vlc_clock_ConvertToSystemLocked(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate)
vlc_tick_t vlc_clock_ConvertToSystem(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate)
{
return clock->ops->to_system_locked(clock, system_now, ts, rate);
AssertLocked(clock);
return clock->ops->to_system(clock, system_now, ts, rate);
}
static const struct vlc_clock_ops master_ops = {
.update = vlc_clock_master_update,
.reset = vlc_clock_master_reset,
.set_delay = vlc_clock_master_set_delay,
.to_system_locked = vlc_clock_master_to_system_locked,
.to_system = vlc_clock_master_to_system,
};
static const struct vlc_clock_ops slave_ops = {
.update = vlc_clock_slave_update,
.reset = vlc_clock_slave_reset,
.set_delay = vlc_clock_slave_set_delay,
.to_system_locked = vlc_clock_slave_to_system_locked,
.to_system = vlc_clock_slave_to_system,
};
static vlc_clock_t *vlc_clock_main_Create(vlc_clock_main_t *main_clock,
@ -806,7 +788,7 @@ vlc_clock_t *vlc_clock_main_CreateSlave(vlc_clock_main_t *main_clock,
/* 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.
* vlc_clock_monotonic_to_system_locked */
* vlc_clock_monotonic_to_system */
unsigned priority;
switch (cat)
{

View File

@ -195,13 +195,15 @@ vlc_clock_t *vlc_clock_CreateSlave(const vlc_clock_t *clock,
/**
* This function free the resources allocated by vlc_clock*Create*()
*
* @param clock the unlocked clock used by the source
*/
void vlc_clock_Delete(vlc_clock_t *clock);
/**
* This function will update the clock drift and returns the drift
*
* @param clock the clock setter to update
* @param clock the locked clock used by the source
* @param system_now valid system time or VLC_TICK_MAX is the updated point is
* forced (when paused for example)
* @param ts the timestamp in media time for the updated point
@ -225,6 +227,8 @@ vlc_tick_t vlc_clock_UpdateVideo(vlc_clock_t *clock, vlc_tick_t system_now,
/**
* This function resets the clock drift
*
* @param clock the locked clock used by the source
*/
void vlc_clock_Reset(vlc_clock_t *clock);
@ -233,16 +237,22 @@ void vlc_clock_Reset(vlc_clock_t *clock);
*
* It returns the amount of time the clock owner need to wait in order to reach
* the time introduced by the new positive delay.
*
* @param clock the locked clock used by the source
*/
vlc_tick_t vlc_clock_SetDelay(vlc_clock_t *clock, vlc_tick_t ts_delay);
/**
* Lock the clock mutex
*
* @param clock the unlocked clock used by the source
*/
void vlc_clock_Lock(vlc_clock_t *clock);
/**
* Unlock the clock mutex
*
* @param clock the locked clock used by the source
*/
void vlc_clock_Unlock(vlc_clock_t *clock);
@ -251,6 +261,7 @@ void vlc_clock_Unlock(vlc_clock_t *clock);
*
* The clock mutex must be locked.
*
* @param clock the locked clock used by the source
* @retval true if the clock is paused
* @retval false if the clock is not paused
*/
@ -263,8 +274,7 @@ bool vlc_clock_IsPaused(vlc_clock_t *clock);
* invalidate the computed deadline. In that case, the caller must recompute
* the new deadline and call it again.
*
* The clock mutex must be locked.
*
* @param clock the locked clock used by the source
* @return 0 if the condition was signaled, an error code in case of timeout
*/
int vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_deadline);
@ -272,14 +282,14 @@ int vlc_clock_Wait(vlc_clock_t *clock, vlc_tick_t system_deadline);
/**
* Wake up any vlc_clock_Wait()
*
* The clock mutex must be locked.
* @param clock the locked clock used by the source
*/
void vlc_clock_Wake(vlc_clock_t *clock);
/**
* Add a listener for events
*
* @param clock the clock used by the source
* @param clock the locked clock used by the source
* @param cbs valid pointer to register events
* @param data opaque data used by cbs
* @return a valid listener id, or NULL in case of allocation error
@ -292,7 +302,7 @@ vlc_clock_AddListener(vlc_clock_t *clock,
/**
* Remove a event listener callback
*
* @param clock the clock used by the source
* @param clock the locked clock used by the source
* @param listener_id listener id returned by vlc_clock_AddListener()
*/
void
@ -301,23 +311,11 @@ vlc_clock_RemoveListener(vlc_clock_t *clock, vlc_clock_listener_id *listener_id)
/**
* This function converts a timestamp from stream to system
*
* The clock mutex must be locked.
*
* @param clock the locked clock used by the source
* @return the valid system time
*/
vlc_tick_t vlc_clock_ConvertToSystemLocked(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate);
static inline vlc_tick_t
vlc_clock_ConvertToSystem(vlc_clock_t *clock, vlc_tick_t system_now,
vlc_tick_t ts, double rate)
{
vlc_clock_Lock(clock);
vlc_tick_t system =
vlc_clock_ConvertToSystemLocked(clock, system_now, ts, rate);
vlc_clock_Unlock(clock);
return system;
}
vlc_tick_t vlc_clock_ConvertToSystem(vlc_clock_t *clock,
vlc_tick_t system_now, vlc_tick_t ts,
double rate);
#endif /*CLOCK_H*/

View File

@ -989,7 +989,11 @@ static vlc_tick_t ModuleThread_GetDisplayDate( decoder_t *p_dec,
if( !p_owner->p_clock || i_ts == VLC_TICK_INVALID )
return i_ts;
return vlc_clock_ConvertToSystem( p_owner->p_clock, system_now, i_ts, rate );
vlc_clock_Lock( p_owner->p_clock );
vlc_tick_t conv_ts =
vlc_clock_ConvertToSystem( p_owner->p_clock, system_now, i_ts, rate );
vlc_clock_Unlock( p_owner->p_clock );
return conv_ts;
}
static float ModuleThread_GetDisplayRate( decoder_t *p_dec )

View File

@ -1261,14 +1261,20 @@ ClockListenerUpdate(void *opaque, vlc_tick_t ck_system,
vlc_tick_t ck_stream, double rate)
{
es_out_pgrm_t *pgrm = opaque;
return vlc_clock_Update(pgrm->clocks.input, ck_system, ck_stream, rate);
vlc_clock_Lock(pgrm->clocks.input);
vlc_tick_t drift =
vlc_clock_Update(pgrm->clocks.input, ck_system, ck_stream, rate);
vlc_clock_Unlock(pgrm->clocks.input);
return drift;
}
static void
ClockListenerReset(void *opaque)
{
es_out_pgrm_t *pgrm = opaque;
vlc_clock_Lock(pgrm->clocks.input);
vlc_clock_Reset(pgrm->clocks.input);
vlc_clock_Unlock(pgrm->clocks.input);
}

View File

@ -984,9 +984,11 @@ static picture_t *PreparePicture(vout_thread_sys_t *vout, bool reuse_decoded,
if (is_late_dropped && !decoded->b_force)
{
const vlc_tick_t system_now = vlc_tick_now();
vlc_clock_Lock(sys->clock);
const vlc_tick_t system_pts =
vlc_clock_ConvertToSystem(sys->clock, system_now,
decoded->date, sys->rate);
vlc_clock_Unlock(sys->clock);
if (IsPictureLate(vout, decoded, system_now, system_pts))
{
@ -1145,9 +1147,11 @@ static int PrerenderPicture(vout_thread_sys_t *sys, picture_t *filtered,
render_subtitle_date = sys->pause.date;
else
{
vlc_clock_Lock(sys->clock);
render_subtitle_date = filtered->date <= VLC_TICK_0 ? system_now :
vlc_clock_ConvertToSystem(sys->clock, system_now, filtered->date,
sys->rate);
vlc_clock_Unlock(sys->clock);
}
/*
@ -1313,8 +1317,10 @@ static int RenderPicture(vout_thread_sys_t *sys, bool render_now)
vlc_tick_t system_now = vlc_tick_now();
const vlc_tick_t pts = todisplay->date;
vlc_clock_Lock(sys->clock);
vlc_tick_t system_pts = render_now ? system_now :
vlc_clock_ConvertToSystem(sys->clock, system_now, pts, sys->rate);
vlc_clock_Unlock(sys->clock);
const unsigned frame_rate = todisplay->format.i_frame_rate;
const unsigned frame_rate_base = todisplay->format.i_frame_rate_base;
@ -1357,8 +1363,9 @@ static int RenderPicture(vout_thread_sys_t *sys, bool render_now)
deadline = max_deadline;
else
{
deadline = vlc_clock_ConvertToSystemLocked(sys->clock,
vlc_tick_now(), pts, sys->rate);
deadline = vlc_clock_ConvertToSystem(sys->clock,
vlc_tick_now(), pts,
sys->rate);
if (deadline > max_deadline)
deadline = max_deadline;
}
@ -1385,10 +1392,12 @@ static int RenderPicture(vout_thread_sys_t *sys, bool render_now)
/* Display the direct buffer returned by vout_RenderPicture */
vout_display_Display(vd, todisplay);
vlc_clock_Lock(sys->clock);
vlc_tick_t drift = vlc_clock_UpdateVideo(sys->clock,
vlc_tick_now(),
pts, sys->rate,
frame_rate, frame_rate_base);
vlc_clock_Unlock(sys->clock);
vlc_queuedmutex_unlock(&sys->display_lock);
@ -1461,9 +1470,11 @@ static bool UpdateCurrentPicture(vout_thread_sys_t *sys)
return false;
const vlc_tick_t system_now = vlc_tick_now();
vlc_clock_Lock(sys->clock);
const vlc_tick_t system_swap_current =
vlc_clock_ConvertToSystem(sys->clock, system_now,
sys->displayed.current->date, sys->rate);
vlc_clock_Unlock(sys->clock);
const vlc_tick_t render_delay = vout_chrono_GetHigh(&sys->chrono.render) + VOUT_MWAIT_TOLERANCE;
vlc_tick_t system_prepare_current = system_swap_current - render_delay;
@ -1598,8 +1609,10 @@ static void vout_FlushUnlocked(vout_thread_sys_t *vout, bool below,
if (sys->clock != NULL)
{
vlc_clock_Lock(sys->clock);
vlc_clock_Reset(sys->clock);
vlc_clock_SetDelay(sys->clock, sys->delay);
vlc_clock_Unlock(sys->clock);
}
}
@ -1636,7 +1649,9 @@ void vout_ChangeDelay(vout_thread_t *vout, vlc_tick_t delay)
assert(sys->display);
vout_control_Hold(&sys->control);
vlc_clock_Lock(sys->clock);
vlc_clock_SetDelay(sys->clock, delay);
vlc_clock_Unlock(sys->clock);
sys->delay = delay;
vout_control_Release(&sys->control);
}
@ -1901,7 +1916,9 @@ static void vout_ReleaseDisplay(vout_thread_sys_t *vout)
if (sys->clock_listener_id != NULL)
{
vlc_clock_Lock(sys->clock);
vlc_clock_RemoveListener(sys->clock, sys->clock_listener_id);
vlc_clock_Unlock(sys->clock);
sys->clock_listener_id = NULL;
}
@ -2254,8 +2271,10 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
static const struct vlc_clock_event_cbs clock_event_cbs = {
.on_discontinuity = clock_event_OnDiscontinuity,
};
vlc_clock_Lock(sys->clock);
sys->clock_listener_id =
vlc_clock_AddListener(sys->clock, &clock_event_cbs, vout);
vlc_clock_Unlock(sys->clock);
sys->delay = 0;
@ -2278,7 +2297,11 @@ error_thread:
error_display:
vout_DisableWindow(vout);
if (sys->clock_listener_id != NULL)
{
vlc_clock_Lock(sys->clock);
vlc_clock_RemoveListener(sys->clock, sys->clock_listener_id);
vlc_clock_Unlock(sys->clock);
}
sys->clock_listener_id = NULL;
vlc_mutex_lock(&sys->clock_lock);
sys->clock = NULL;

View File

@ -696,12 +696,12 @@ static size_t spu_channel_UpdateDates(struct spu_channel *channel,
{
assert(entry);
entry->start = vlc_clock_ConvertToSystemLocked(channel->clock, system_now,
entry->orgstart, channel->rate);
entry->start = vlc_clock_ConvertToSystem(channel->clock, system_now,
entry->orgstart, channel->rate);
entry->stop =
vlc_clock_ConvertToSystemLocked(channel->clock, system_now,
entry->orgstop, channel->rate);
vlc_clock_ConvertToSystem(channel->clock, system_now,
entry->orgstop, channel->rate);
}
vlc_clock_Unlock(channel->clock);
@ -1857,7 +1857,9 @@ void spu_SetClockDelay(spu_t *spu, size_t channel_id, vlc_tick_t delay)
vlc_mutex_lock(&sys->lock);
struct spu_channel *channel = spu_GetChannel(spu, channel_id, NULL);
assert(channel->clock);
vlc_clock_Lock(channel->clock);
vlc_clock_SetDelay(channel->clock, delay);
vlc_clock_Unlock(channel->clock);
channel->delay = delay;
vlc_mutex_unlock(&sys->lock);
}
@ -1979,11 +1981,11 @@ void spu_PutSubpicture(spu_t *spu, subpicture_t *subpic)
vlc_clock_Lock(channel->clock);
subpic->i_start =
vlc_clock_ConvertToSystemLocked(channel->clock, system_now,
orgstart, channel->rate);
vlc_clock_ConvertToSystem(channel->clock, system_now,
orgstart, channel->rate);
subpic->i_stop =
vlc_clock_ConvertToSystemLocked(channel->clock, system_now,
orgstop, channel->rate);
vlc_clock_ConvertToSystem(channel->clock, system_now,
orgstop, channel->rate);
vlc_clock_Unlock(channel->clock);
spu_channel_EarlyRemoveLate(sys, channel, system_now);
@ -2187,8 +2189,10 @@ void spu_ClearChannel(spu_t *spu, size_t channel_id)
spu_channel_Clean(sys, channel);
if (channel->clock)
{
vlc_clock_Lock(channel->clock);
vlc_clock_Reset(channel->clock);
vlc_clock_SetDelay(channel->clock, channel->delay);
vlc_clock_Unlock(channel->clock);
}
vlc_mutex_unlock(&sys->lock);
}

View File

@ -315,6 +315,7 @@ static void play_scenario(libvlc_int_t *vlc, struct vlc_tracer *tracer,
vlc_clock_main_t *mainclk = vlc_clock_main_New(logger, tracer);
assert(mainclk != NULL);
vlc_clock_main_Lock(mainclk);
vlc_clock_t *master = vlc_clock_main_CreateMaster(mainclk, scenario->name,
NULL, NULL);
assert(master != NULL);
@ -325,6 +326,7 @@ static void play_scenario(libvlc_int_t *vlc, struct vlc_tracer *tracer,
vlc_clock_t *slave = vlc_clock_main_CreateSlave(mainclk, slave_name, VIDEO_ES,
NULL, NULL);
assert(slave != NULL);
vlc_clock_main_Unlock(mainclk);
const struct clock_ctx ctx = {
.mainclk = mainclk,
@ -365,10 +367,12 @@ static void play_scenario(libvlc_int_t *vlc, struct vlc_tracer *tracer,
{
while (video_system < expected_system + scenario->stream_increment)
{
vlc_clock_Lock(ctx.slave);
vlc_tick_t play_date =
vlc_clock_ConvertToSystem(ctx.slave, video_system, video_ts,
1.0f);
vlc_clock_Update(ctx.slave, play_date, video_ts, 1.0f);
vlc_clock_Unlock(ctx.slave);
video_system += video_increment;
video_ts += video_increment;
}
@ -454,8 +458,10 @@ static void normal_update(const struct clock_ctx *ctx, size_t index,
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_clock_Lock(ctx->master);
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
vlc_clock_Unlock(ctx->master);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
@ -524,9 +530,11 @@ static void normal_check(const struct clock_ctx *ctx, size_t update_count,
}
}
vlc_clock_Lock(ctx->slave);
vlc_tick_t converted =
vlc_clock_ConvertToSystem(ctx->slave, expected_system_end,
stream_end, 1.0f);
vlc_clock_Unlock(ctx->slave);
assert(converted == expected_system_end);
}
@ -543,8 +551,10 @@ static void lowprecision_update(const struct clock_ctx *ctx, size_t index,
vlc_tick_t imprecision = rand() % VLC_TICK_FROM_MS(5);
*system = base_system + imprecision;
vlc_clock_Lock(ctx->master);
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
vlc_clock_Unlock(ctx->master);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
}
@ -578,8 +588,10 @@ static void drift_update(const struct clock_ctx *ctx, size_t index,
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_clock_Lock(ctx->master);
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
vlc_clock_Unlock(ctx->master);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
@ -600,9 +612,11 @@ static void drift_check(const struct clock_ctx *ctx, size_t update_count,
check_no_event_error(update_count);
vlc_clock_Lock(ctx->slave);
vlc_tick_t converted =
vlc_clock_ConvertToSystem(ctx->slave, expected_system_end,
stream_end, 1.0f);
vlc_clock_Unlock(ctx->slave);
assert(converted - expected_system_end == scenario->total_drift_duration);
}
@ -613,8 +627,10 @@ static void drift_sudden_update(const struct clock_ctx *ctx, size_t index,
(void) index;
const struct clock_scenario *scenario = ctx->scenario;
vlc_clock_Lock(ctx->slave);
vlc_tick_t drift =
vlc_clock_Update(ctx->master, *system, stream, 1.0f);
vlc_clock_Unlock(ctx->slave);
/* The master can't drift */
assert(drift == VLC_TICK_INVALID);
@ -633,16 +649,26 @@ static void pause_common(const struct clock_ctx *ctx, vlc_clock_t *updater)
const vlc_tick_t pause_duration = VLC_TICK_FROM_MS(20);
vlc_tick_t system = system_start;
vlc_clock_Lock(updater);
vlc_clock_Update(updater, system, 1, 1.0f);
vlc_clock_Unlock(updater);
system += VLC_TICK_FROM_MS(10);
vlc_clock_main_Lock(ctx->mainclk);
vlc_clock_main_ChangePause(ctx->mainclk, system, true);
vlc_clock_main_Unlock(ctx->mainclk);
system += pause_duration;
vlc_clock_main_Lock(ctx->mainclk);
vlc_clock_main_ChangePause(ctx->mainclk, system, false);
vlc_clock_main_Unlock(ctx->mainclk);
system += 1;
vlc_clock_Lock(ctx->slave);
vlc_tick_t converted = vlc_clock_ConvertToSystem(ctx->slave, system, 1, 1.0f);
vlc_clock_Unlock(ctx->slave);
assert(converted == system_start + pause_duration);
}
@ -654,8 +680,10 @@ static void master_pause_run(const struct clock_ctx *ctx)
static void monotonic_pause_run(const struct clock_ctx *ctx)
{
/* Don't add any delay for the first monotonic ref point */
vlc_clock_main_Lock(ctx->mainclk);
vlc_clock_main_SetInputDejitter(ctx->mainclk, 0);
vlc_clock_main_SetDejitter(ctx->mainclk, 0);
vlc_clock_main_Unlock(ctx->mainclk);
pause_common(ctx, ctx->slave);
}
@ -665,14 +693,20 @@ static void convert_paused_common(const struct clock_ctx *ctx, vlc_clock_t *upda
const vlc_tick_t system_start = vlc_tick_now();
vlc_tick_t system = system_start;
vlc_clock_Lock(updater);
vlc_clock_Update(updater, system_start, 1, 1.0f);
vlc_clock_Unlock(updater);
system += VLC_TICK_FROM_MS(10);
vlc_clock_main_Lock(ctx->mainclk);
vlc_clock_main_ChangePause(ctx->mainclk, system, true);
vlc_clock_main_Unlock(ctx->mainclk);
system += 1;
vlc_clock_Lock(ctx->slave);
vlc_tick_t converted = vlc_clock_ConvertToSystem(ctx->slave, system, 1, 1.0f);
vlc_clock_Unlock(ctx->slave);
assert(converted == system_start);
}
@ -684,8 +718,10 @@ static void master_convert_paused_run(const struct clock_ctx *ctx)
static void monotonic_convert_paused_run(const struct clock_ctx *ctx)
{
/* Don't add any delay for the first monotonic ref point */
vlc_clock_main_Lock(ctx->mainclk);
vlc_clock_main_SetInputDejitter(ctx->mainclk, 0);
vlc_clock_main_SetDejitter(ctx->mainclk, 0);
vlc_clock_main_Unlock(ctx->mainclk);
convert_paused_common(ctx, ctx->slave);
}