mirror of https://code.videolan.org/videolan/vlc
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:
parent
9af0658668
commit
b61be68d6a
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue