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", &params);
+
+    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

Reply via email to