[vlc-commits] [Git][videolan/vlc][master] 3 commits: clock: expose and require lock for vlc_clock_main_t
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sun Mar 17 09:06:43 UTC 2024
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
81a594b2 by Thomas Guillem at 2024-03-17T08:37:18+00:00
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.
- - - - -
9af06586 by Thomas Guillem at 2024-03-17T08:37:18+00:00
aout: filters: clock_source is mutable
Even if the clock is only used for functions that are not modifying the
clock, it locks the clock->main_clock mutex.
This change is necessary as all vlc_clock_t will need to be called with
the lock held.
- - - - -
b61be68d by Thomas Guillem at 2024-03-17T08:37:18+00:00
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.
- - - - -
11 changed files:
- src/audio_output/aout_internal.h
- src/audio_output/dec.c
- src/audio_output/filters.c
- src/clock/clock.c
- src/clock/clock.h
- src/input/decoder.c
- src/input/es_out.c
- src/stream_output/stream_output.c
- src/video_output/video_output.c
- src/video_output/vout_subpictures.c
- test/src/clock/clock.c
Changes:
=====================================
src/audio_output/aout_internal.h
=====================================
@@ -203,7 +203,7 @@ static inline void aout_SetWavePhysicalChannels(audio_sample_format_t *fmt)
* The clock, that is not mandatory, will be used to create a new slave clock
* for the filter visualization plugins.
*/
-aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *, const vlc_clock_t *,
+aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *, vlc_clock_t *,
const audio_sample_format_t *,
const audio_sample_format_t *,
const aout_filters_cfg_t *cfg) VLC_USED;
=====================================
src/audio_output/dec.c
=====================================
@@ -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;
}
}
=====================================
src/audio_output/filters.c
=====================================
@@ -370,7 +370,7 @@ struct aout_filters
(either the scaletempo filter or a resampler) */
struct aout_filter resampler; /**< The resampler */
int resampling; /**< Current resampling (Hz) */
- const vlc_clock_t *clock_source;
+ vlc_clock_t *clock_source;
unsigned count; /**< Number of filters */
struct aout_filter tab[AOUT_MAX_FILTERS]; /**< Configured user filters
@@ -406,7 +406,7 @@ static int VisualizationCallback (vlc_object_t *obj, const char *var,
struct filter_owner_sys
{
- const vlc_clock_t *clock_source;
+ vlc_clock_t *clock_source;
vlc_clock_t *clock;
vout_thread_t *vout;
};
@@ -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;
@@ -542,7 +544,7 @@ static int AppendRemapFilter(vlc_object_t *obj, aout_filters_t *restrict filters
return ret;
}
-aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *clock,
+aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, vlc_clock_t *clock,
const audio_sample_format_t *restrict infmt,
const audio_sample_format_t *restrict outfmt,
const aout_filters_cfg_t *cfg)
@@ -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);
+ }
}
}
=====================================
src/clock/clock.c
=====================================
@@ -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);
}
@@ -589,17 +566,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 +585,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 +631,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,9 +645,21 @@ 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)
{
+ AssertLocked(clock);
return clock->ops->update(clock, system_now, ts, rate, 0, 0);
}
@@ -678,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,
@@ -738,12 +731,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 +747,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 +773,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,10 +783,12 @@ 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.
- * vlc_clock_monotonic_to_system_locked */
+ * vlc_clock_monotonic_to_system */
unsigned priority;
switch (cat)
{
@@ -812,10 +807,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;
}
=====================================
src/clock/clock.h
=====================================
@@ -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,19 +187,23 @@ 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);
/**
* 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
@@ -181,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);
@@ -189,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);
@@ -207,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
*/
@@ -219,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);
@@ -228,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
@@ -248,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
@@ -257,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*/
=====================================
src/input/decoder.c
=====================================
@@ -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 )
=====================================
src/input/es_out.c
=====================================
@@ -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);
}
}
@@ -1256,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);
}
@@ -1304,8 +1315,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 +1345,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 +1523,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 +1532,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 +2290,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 +2309,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 +3949,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;
}
=====================================
src/stream_output/stream_output.c
=====================================
@@ -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 )
=====================================
src/video_output/video_output.c
=====================================
@@ -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;
=====================================
src/video_output/vout_subpictures.c
=====================================
@@ -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);
}
=====================================
test/src/clock/clock.c
=====================================
@@ -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);
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f1d0bb4f85b6566648efb82a5d0561a6a594673b...b61be68d6aebb657d207c51114eeb6f6592cac73
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f1d0bb4f85b6566648efb82a5d0561a6a594673b...b61be68d6aebb657d207c51114eeb6f6592cac73
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list