Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
28f62e34 by Thomas Guillem at 2026-02-13T10:29:25+00:00
player: force interpolation to pause_date when paused
This fixes vlc_player_GetTime() reporting input time when paused, that
could be more than 1 seconds behind the last polled timing.
Improve 46214fdcebb91622bd8beb7eb69c4a78b00f2cf9
Really fixes #28353
(still no problem with Qt as it use the timer API directly).
- - - - -
0705ba78 by Thomas Guillem at 2026-02-13T10:29:25+00:00
test: player: modules: implement aout->pause
Avoid discontinuity from aout flush when testing pause.
Furthermore, the fake aout behaves more like other main aout modules.
- - - - -
8f3f8383 by Thomas Guillem at 2026-02-13T10:29:25+00:00
test: player: add pause_get_time_increase
- - - - -
4 changed files:
- src/player/player.h
- src/player/timer.c
- test/src/player/modules.c
- test/src/player/pause.c
Changes:
=====================================
src/player/player.h
=====================================
@@ -236,6 +236,7 @@ struct vlc_player_timer
UPDATE_STATE_PAUSED,
UPDATE_STATE_RESUMING,
} update_state;
+ vlc_tick_t pause_date;
bool stopping;
struct vlc_player_timer_source sources[VLC_PLAYER_TIMER_TYPE_COUNT];
=====================================
src/player/timer.c
=====================================
@@ -41,6 +41,7 @@ vlc_player_ResetTimer(vlc_player_t *player)
player->timer.seek_ts = VLC_TICK_INVALID;
player->timer.seek_position = -1;
player->timer.update_state = UPDATE_STATE_RESUMED;
+ player->timer.pause_date = VLC_TICK_INVALID;
player->timer.stopping = false;
vlc_mutex_unlock(&player->timer.lock);
@@ -262,6 +263,7 @@ vlc_player_UpdateTimerEvent(vlc_player_t *player,
vlc_es_id_t *es_source,
case VLC_PLAYER_TIMER_EVENT_PAUSED:
assert(system_date != VLC_TICK_INVALID);
player->timer.update_state = UPDATE_STATE_PAUSED;
+ player->timer.pause_date = system_date;
for (size_t i = 0; i < VLC_PLAYER_TIMER_TYPE_COUNT; ++i)
{
@@ -422,7 +424,10 @@ vlc_player_UpdateTimerBestSource(vlc_player_t *player,
vlc_es_id_t *es_source,
&source->point);
if (player->timer.update_state == UPDATE_STATE_RESUMING)
+ {
player->timer.update_state = UPDATE_STATE_RESUMED;
+ player->timer.pause_date = VLC_TICK_INVALID;
+ }
}
}
}
@@ -599,10 +604,14 @@ vlc_player_GetTimerPoint(vlc_player_t *player, bool
*seeking,
if (player->timer.best_source.point.system_date == VLC_TICK_INVALID)
goto end;
- if (system_now != VLC_TICK_INVALID
- && player->timer.update_state == UPDATE_STATE_RESUMED)
+ if (system_now != VLC_TICK_INVALID) /* interpolate */
+ {
+ /* If paused, force interpolation to the paused date */
+ if (player->timer.pause_date != VLC_TICK_INVALID)
+ system_now = player->timer.pause_date;
ret =
vlc_player_timer_point_Interpolate(&player->timer.best_source.point,
system_now, out_ts, out_pos);
+ }
else
{
const struct vlc_player_timer_point *point =
=====================================
test/src/player/modules.c
=====================================
@@ -51,6 +51,13 @@ static void aout_Flush(audio_output_t *aout)
sys->first_pts = sys->first_play_date = VLC_TICK_INVALID;
}
+static void aout_Pause(audio_output_t *aout, bool pause, vlc_tick_t date)
+{
+ (void) date;
+ if (pause)
+ aout_Flush(aout);
+}
+
static void aout_InstantDrain(audio_output_t *aout)
{
aout_DrainedReport(aout);
@@ -75,7 +82,7 @@ static int aout_Open(vlc_object_t *obj)
aout->start = aout_Start;
aout->play = aout_Play;
- aout->pause = NULL;
+ aout->pause = aout_Pause;
aout->flush = aout_Flush;
aout->stop = aout_Flush;
aout->volume_set = NULL;
@@ -132,4 +139,4 @@ vlc_module_end()
VLC_EXPORT const vlc_plugin_cb vlc_static_modules[] = {
VLC_SYMBOL(vlc_entry),
NULL
-};
\ No newline at end of file
+};
=====================================
test/src/player/pause.c
=====================================
@@ -102,12 +102,66 @@ test_pause(struct ctx *ctx)
player_remove_timer(player, &timer);
}
+static void
+test_pause_get_time_increase(struct ctx *ctx)
+{
+ /* Ensure that vlc_player_GetTime() is always increasing, even when
+ * spamming pause/resume. Contrary to timers (async events), we can't
+ * control if vlc_player_GetTime() will be processed when paused or
+ * resumed (async calls), hence this "brute-force" test. */
+ test_log("pause_get_time_increase\n");
+ vlc_player_t *player = ctx->player;
+
+ struct media_params params = DEFAULT_MEDIA_PARAMS(VLC_TICK_FROM_SEC(10));
+ player_set_next_mock_media(ctx, "media1", ¶ms);
+
+ player_start(ctx);
+
+ wait_state(ctx, VLC_PLAYER_STATE_PLAYING);
+
+ {
+ vec_on_position_changed *vec = &ctx->report.on_position_changed;
+ while (vec->size == 0)
+ vlc_player_CondWait(player, &ctx->wait);
+ }
+ vlc_tick_sleep(VLC_TICK_FROM_MS(100));
+
+ vlc_tick_t prev_time = vlc_player_GetTime(player);
+ assert(prev_time >= VLC_TICK_0);
+ for (unsigned i = 0; i < 100; i++)
+ {
+ vlc_tick_t time = vlc_player_GetTime(player);
+ assert(time >= prev_time);
+ prev_time = time;
+
+ vlc_tick_sleep(VLC_TICK_FROM_MS(10));
+
+ time = vlc_player_GetTime(player);
+ assert(time >= prev_time);
+ prev_time = time;
+
+ vlc_player_Pause(player);
+
+ time = vlc_player_GetTime(player);
+ assert(time >= prev_time);
+ prev_time = time;
+
+
+ vlc_player_Resume(player);
+ }
+
+ /* Ensure we stay paused */
+
+ test_end(ctx);
+}
+
int
main(void)
{
struct ctx ctx;
ctx_init(&ctx, 0);
test_pause(&ctx);
+ test_pause_get_time_increase(&ctx);
ctx_destroy(&ctx);
return 0;
}
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/4223f1fb9077f4ad9094716a7ee87df483b8c883...8f3f83837a09241b0af91fcb8229bb1e43f48b52
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/4223f1fb9077f4ad9094716a7ee87df483b8c883...8f3f83837a09241b0af91fcb8229bb1e43f48b52
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits