[vlc-devel] [PATCH 12/13] test: player: test the timer API

Thomas Guillem thomas at gllm.fr
Wed Aug 21 16:14:03 CEST 2019


---
 test/src/player/player.c | 172 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 172 insertions(+)

diff --git a/test/src/player/player.c b/test/src/player/player.c
index ba9eba57bf..ca4370e9c7 100644
--- a/test/src/player/player.c
+++ b/test/src/player/player.c
@@ -120,6 +120,21 @@ struct report_media_subitems
     X(input_item_t *, on_media_epg_changed) \
     X(struct report_media_subitems, on_media_subitems_changed) \
 
+struct report_timer
+{
+    enum vlc_player_timer_state state;
+    struct vlc_player_timer_value value;
+};
+typedef struct VLC_VECTOR(struct report_timer) vec_report_timer;
+
+struct timer_state
+{
+    vlc_player_timer_id *id;
+    enum vlc_player_timer_type type;
+    vlc_tick_t delay;
+    vec_report_timer vec;
+};
+
 #define X(type, name) typedef struct VLC_VECTOR(type) vec_##name;
 REPORT_LIST
 #undef X
@@ -1839,6 +1854,162 @@ REPORT_LIST
     assert(ctx->listener);
 }
 
+static void
+timers_on_update(enum vlc_player_timer_state state,
+                 const struct vlc_player_timer_value *value, void *data)
+{
+    struct timer_state *timer = data;
+    struct report_timer report =
+    {
+        .state = state,
+        .value = *value,
+    };
+    bool success = vlc_vector_push(&timer->vec, report);
+    assert(success);
+}
+
+static void
+test_timers(struct ctx *ctx)
+{
+    test_log("timers\n");
+
+#define MEDIA_DURATION VLC_TICK_FROM_MS(100)
+#define STEP_DURATION VLC_TICK_FROM_MS(1)
+#define MAX_UPDATE_COUNT (MEDIA_DURATION / STEP_DURATION)
+
+#define SOURCE_TIMER_IDX 0
+#define SOURCE_DELAY_TIMER_IDX 1
+#define REGULAR_TIMER_IDX 2
+#define TIMER_COUNT 3
+
+#define SOURCE_DELAY_TIMER_VALUE (VLC_TICK_FROM_MS(2))
+#define REGULAR_DELAY_TIMER_VALUE (VLC_TICK_FROM_MS(10))
+
+    vlc_player_t *player = ctx->player;
+    struct media_params params = DEFAULT_MEDIA_PARAMS(VLC_TICK_FROM_MS(100));
+
+    /* Enable only audio with a specific audio buffer length. That way, we can
+     * know in advance the output of the clock. Indeed, writting an audio
+     * sample every 1ms means a clock update every 1ms. */
+    params.track_count[VIDEO_ES] = 0;
+    params.track_count[AUDIO_ES] = 1;
+    params.audio_block_length = STEP_DURATION;
+
+    static const struct vlc_player_timer_cbs cbs =
+    {
+        .on_update = timers_on_update,
+    };
+
+    /* Configure timers */
+    struct timer_state timers[TIMER_COUNT];
+
+    /* Receive all clock update points */
+    timers[SOURCE_TIMER_IDX].type = VLC_PLAYER_TIMER_TYPE_SOURCE;
+    timers[SOURCE_TIMER_IDX].delay = VLC_TICK_INVALID;
+
+    /* Filter some points in order to not be flooded */
+    timers[SOURCE_DELAY_TIMER_IDX].type = VLC_PLAYER_TIMER_TYPE_SOURCE;
+    timers[SOURCE_DELAY_TIMER_IDX].delay = SOURCE_DELAY_TIMER_VALUE;
+
+    /* Spawn a timer that will send update regularly */
+    timers[REGULAR_TIMER_IDX].type = VLC_PLAYER_TIMER_TYPE_REGULAR;
+    timers[REGULAR_TIMER_IDX].delay = REGULAR_DELAY_TIMER_VALUE;
+
+    /* Create all timers */
+    for (size_t i = 0; i < ARRAY_SIZE(timers); ++i)
+    {
+        vlc_vector_init(&timers[i].vec);
+        timers[i].id = vlc_player_AddTimer(player, timers[i].type,
+                                           timers[i].delay, &cbs, &timers[i]);
+        assert(timers[i].id);
+    }
+
+    player_set_current_mock_media(ctx, "media1", &params, false);
+    player_start(ctx);
+
+    wait_state(ctx, VLC_PLAYER_STATE_STARTED);
+    wait_state(ctx, VLC_PLAYER_STATE_STOPPED);
+
+    /* Common for every timers */
+    for (size_t timer_idx = 0; timer_idx < ARRAY_SIZE(timers); ++timer_idx)
+    {
+        struct timer_state *timer = &timers[timer_idx];
+        vec_report_timer *vec = &timer->vec;
+
+        vlc_player_RemoveTimer(player, timer->id);
+
+        for (size_t i = 1; i < vec->size; ++i)
+        {
+            struct report_timer *prev_report = &vec->data[i - 1];
+            struct report_timer *report = &vec->data[i];
+
+            /* ts/position should increase, rate should stay to 1.f */
+            assert(report->value.ts >= prev_report->value.ts);
+            assert(report->value.position >= prev_report->value.position);
+            assert(report->value.rate == 1.f);
+
+            /* Only the last event should be a discontinuity. We can assume
+             * that since we are not seeking and playing a fake content */
+            if (i < vec->size -1)
+                assert(report->state == VLC_PLAYER_TIMER_STATE_PLAYING);
+            else
+                assert(report->state == VLC_PLAYER_TIMER_STATE_DISCONTINUITY);
+        }
+
+        /* The last point should be the media duration */
+        assert(VEC_LAST(vec).value.ts == MEDIA_DURATION);
+    }
+
+    /* Assertions for the timer that receive all update points */
+    {
+        struct timer_state *timer = &timers[SOURCE_TIMER_IDX];
+        vec_report_timer *vec = &timer->vec;
+
+        /* Check that we didn't miss any update points */
+        assert(vec->size == MAX_UPDATE_COUNT + 1);
+    }
+
+    /* Assertions for the timer that is filtered */
+    {
+        struct timer_state *timer = &timers[SOURCE_DELAY_TIMER_IDX];
+        vec_report_timer *vec = &timer->vec;
+
+        /* It should not receive all update points */
+        assert(vec->size < MAX_UPDATE_COUNT);
+
+        for (size_t i = 1; i < vec->size; ++i)
+        {
+            struct report_timer *prev_report = &vec->data[i - 1];
+            struct report_timer *report = &vec->data[i];
+            assert(report->value.system_date - prev_report->value.system_date
+                   >= timer->delay);
+        }
+    }
+
+    /* Assertions for the regular timer */
+    {
+        struct timer_state *timer = &timers[REGULAR_TIMER_IDX];
+        vec_report_timer *vec = &timer->vec;
+
+        /* It should not receive all update points */
+        assert(vec->size < MAX_UPDATE_COUNT);
+
+        /* cf. vlc_player_RegularTimerCallback() */
+        static const vlc_tick_t internal_player_epsilon = VLC_TICK_FROM_MS(20);
+
+        for (size_t i = 1; i < vec->size; ++i)
+        {
+            struct report_timer *prev_report = &vec->data[i - 1];
+            struct report_timer *report = &vec->data[i];
+            const vlc_tick_t diff = report->value.system_date
+                                  - prev_report->value.system_date;
+            assert(diff >= timer->delay - internal_player_epsilon
+                && diff <= timer->delay + internal_player_epsilon);
+        }
+    }
+
+    test_end(ctx);
+}
 
 int
 main(void)
@@ -1869,6 +2040,7 @@ main(void)
     test_tracks(&ctx, true);
     test_tracks(&ctx, false);
     test_programs(&ctx);
+    test_timers(&ctx);
 
     test_delete_while_playback(VLC_OBJECT(ctx.vlc->p_libvlc_int), true);
     test_delete_while_playback(VLC_OBJECT(ctx.vlc->p_libvlc_int), false);
-- 
2.20.1



More information about the vlc-devel mailing list