[vlc-commits] [Git][videolan/vlc][master] 9 commits: mock: simulate live input if !can_control_pace

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Jan 21 11:51:13 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
46bea823 by Thomas Guillem at 2023-01-21T11:34:37+00:00
mock: simulate live input if !can_control_pace

- - - - -
3ec5e967 by Thomas Guillem at 2023-01-21T11:34:37+00:00
test: thumbnail: signal locked

- - - - -
3c383cfc by Thomas Guillem at 2023-01-21T11:34:37+00:00
test: thumbnail: remove unused variable

- - - - -
b02ea71c by Thomas Guillem at 2023-01-21T11:34:37+00:00
test: thumbnail: set can_control_pace if the test should timeout

Otherwise, nothing prevent the input thread to parse the whole file
before a test timeout value (here, 100ms).

- - - - -
3b26eefc by Thomas Guillem at 2023-01-21T11:34:37+00:00
thumbnailer: don't send cb if interrupted

It is now safe to release media just after cancelling a thumbnail
request (before this commit, the called had to wait for the cb).

Change the test_cancel_thumbnail to make sure that no cb is sent after
a cancel.

- - - - -
a3bd2361 by Thomas Guillem at 2023-01-21T11:34:37+00:00
libvlc: media: cancel request on destroy

If the media is released, the thumbnail request must be interrupted
(since the thumbnail cb will access the media event manager).

- - - - -
962e1153 by Thomas Guillem at 2023-01-21T11:34:37+00:00
thumbnailer: remove task before notifying it

This fixes a task that could be notified 2 times (valid pic +
cancelled) if libvlc is released just after a thumbnail request.

- - - - -
4ad9af98 by Thomas Guillem at 2023-01-21T11:34:37+00:00
thumbnailer: use the correct type

- - - - -
2dee0f7a by Thomas Guillem at 2023-01-21T11:34:37+00:00
thumbnailer: signal locked

- - - - -


4 changed files:

- lib/media.c
- modules/demux/mock.c
- src/input/thumbnailer.c
- test/src/input/thumbnail.c


Changes:

=====================================
lib/media.c
=====================================
@@ -1084,6 +1084,7 @@ void libvlc_media_thumbnail_request_cancel( libvlc_media_thumbnail_request_t *re
 // Destroy a thumbnail request
 void libvlc_media_thumbnail_request_destroy( libvlc_media_thumbnail_request_t *req )
 {
+    libvlc_media_thumbnail_request_cancel( req );
     libvlc_media_release( req->md );
     libvlc_release(req->instance);
     free( req );


=====================================
modules/demux/mock.c
=====================================
@@ -906,6 +906,7 @@ Demux(demux_t *demux)
     if (ret != VLC_SUCCESS)
         return VLC_DEMUXER_EGENERIC;
 
+    vlc_tick_t prev_pts = sys->pts;
     if (sys->audio_track_count > 0
      && (sys->video_track_count > 0 || sys->sub_track_count > 0))
         sys->pts = __MIN(sys->audio_pts, sys->video_pts);
@@ -916,6 +917,15 @@ Demux(demux_t *demux)
 
     if (sys->pts > sys->length)
         sys->pts = sys->length;
+
+    if (!sys->can_control_pace)
+    {
+        /* Simulate a live input */
+        vlc_tick_t delay = sys->pts - prev_pts;
+        delay = delay - delay / 1000 /* Sleep a little less */;
+        vlc_tick_sleep(delay);
+    }
+
     es_out_SetPCR(demux->out, sys->pts);
 
     const vlc_tick_t video_step_length =


=====================================
src/input/thumbnailer.c
=====================================
@@ -72,7 +72,12 @@ struct vlc_thumbnailer_request_t
 
     vlc_mutex_t lock;
     vlc_cond_t cond_ended;
-    bool ended;
+    enum
+    {
+        RUNNING,
+        INTERRUPTED,
+        ENDED,
+    } status;
     picture_t *pic;
 
     struct vlc_runnable runnable; /**< to be passed to the executor */
@@ -101,7 +106,7 @@ TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item,
 
     vlc_mutex_init(&task->lock);
     vlc_cond_init(&task->cond_ended);
-    task->ended = false;
+    task->status = RUNNING;
     task->pic = NULL;
 
     task->runnable.run = RunnableRun;
@@ -139,8 +144,6 @@ static void NotifyThumbnail(task_t *task, picture_t *pic)
 {
     assert(task->cb);
     task->cb(task->userdata, pic);
-    if (pic)
-        picture_Release(pic);
 }
 
 static void
@@ -156,7 +159,7 @@ on_thumbnailer_input_event( input_thread_t *input,
     task_t *task = userdata;
 
     vlc_mutex_lock(&task->lock);
-    if (task->ended)
+    if (task->status != RUNNING)
     {
         /* We may receive a THUMBNAIL_READY event followed by an
          * INPUT_EVENT_STATE (end of stream), we must only consider the first
@@ -165,14 +168,13 @@ on_thumbnailer_input_event( input_thread_t *input,
         return;
     }
 
-    task->ended = true;
+    task->status = ENDED;
 
     if (event->type == INPUT_EVENT_THUMBNAIL_READY)
         task->pic = picture_Hold(event->thumbnail);
 
-    vlc_mutex_unlock(&task->lock);
-
     vlc_cond_signal(&task->cond_ended);
+    vlc_mutex_unlock(&task->lock);
 }
 
 static void
@@ -189,7 +191,7 @@ RunnableRun(void *userdata)
             input_Create( thumbnailer->parent, on_thumbnailer_input_event, task,
                           task->item, INPUT_TYPE_THUMBNAILING, NULL, NULL );
     if (!input)
-        goto end;
+        goto error;
 
     if (task->seek_target.type == VLC_THUMBNAILER_SEEK_TIME)
         input_SetTime(input, task->seek_target.time, task->fast_seek);
@@ -203,33 +205,44 @@ RunnableRun(void *userdata)
     if (ret != VLC_SUCCESS)
     {
         input_Close(input);
-        goto end;
+        goto error;
     }
 
     vlc_mutex_lock(&task->lock);
     if (task->timeout == VLC_TICK_INVALID)
     {
-        while (!task->ended)
+        while (task->status == RUNNING)
             vlc_cond_wait(&task->cond_ended, &task->lock);
     }
     else
     {
         vlc_tick_t deadline = now + task->timeout;
-        bool timeout = false;
-        while (!task->ended && !timeout)
+        int timeout = 0;
+        while (task->status == RUNNING && timeout == 0)
             timeout =
                 vlc_cond_timedwait(&task->cond_ended, &task->lock, deadline);
     }
     picture_t* pic = task->pic;
     task->pic = NULL;
+
+    bool notify = task->status != INTERRUPTED;
     vlc_mutex_unlock(&task->lock);
 
-    NotifyThumbnail(task, pic);
+    ThumbnailerRemoveTask(thumbnailer, task);
+
+    if (notify)
+        NotifyThumbnail(task, pic);
+
+    if (pic != NULL)
+        picture_Release(pic);
 
     input_Stop(input);
     input_Close(input);
 
-end:
+    TaskDelete(task);
+    return;
+
+error:
     ThumbnailerRemoveTask(thumbnailer, task);
     TaskDelete(task);
 }
@@ -239,9 +252,9 @@ Interrupt(task_t *task)
 {
     /* Wake up RunnableRun() which will call input_Stop() */
     vlc_mutex_lock(&task->lock);
-    task->ended = true;
-    vlc_mutex_unlock(&task->lock);
+    task->status = INTERRUPTED;
     vlc_cond_signal(&task->cond_ended);
+    vlc_mutex_unlock(&task->lock);
 }
 
 static task_t *


=====================================
test/src/input/thumbnail.c
=====================================
@@ -39,23 +39,24 @@ const struct
     float f_pos;
     bool b_use_pos;
     bool b_fast_seek;
+    bool b_can_control_pace;
     vlc_tick_t i_timeout;
     bool b_expected_success;
 } test_params[] = {
     /* Simple test with a thumbnail at 60s, with a video track */
-    { 1, 0, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, true,
+    { 1, 0, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, true, true,
         VLC_TICK_FROM_SEC( 1 ), true },
     /* Test without fast-seek */
-    { 1, 0, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, false,
+    { 1, 0, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, false, true,
         VLC_TICK_FROM_SEC( 1 ), true },
     /* Seek by position test */
-    { 1, 0, VLC_TICK_INVALID, 0, .3f, true, true, VLC_TICK_FROM_SEC( 1 ), true },
+    { 1, 0, VLC_TICK_INVALID, 0, .3f, true, true, true, VLC_TICK_FROM_SEC( 1 ), true },
     /* Seek at a negative position */
-    { 1, 0, VLC_TICK_INVALID, -12345, .0f, false, true, VLC_TICK_FROM_SEC( 1 ), true },
+    { 1, 0, VLC_TICK_INVALID, -12345, .0f, false, true, true, VLC_TICK_FROM_SEC( 1 ), true },
     /* Take a thumbnail of a file without video, which should timeout. */
-    { 0, 1, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, true, VLC_TICK_FROM_MS( 100 ), false },
+    { 0, 1, VLC_TICK_INVALID, VLC_TICK_FROM_SEC( 60 ), .0f, false, true, false, VLC_TICK_FROM_MS( 100 ), false },
     /* Take a thumbnail of a file with a video track starting later */
-    { 1, 1, VLC_TICK_FROM_SEC( 60 ), VLC_TICK_FROM_SEC( 30 ), .0f, false, true,
+    { 1, 1, VLC_TICK_FROM_SEC( 60 ), VLC_TICK_FROM_SEC( 30 ), .0f, false, true, true,
         VLC_TICK_FROM_SEC( 2 ), true },
 };
 
@@ -123,16 +124,16 @@ static void test_thumbnails( libvlc_instance_t* p_vlc )
         ctx.b_done = false;
 
         if ( asprintf( &psz_mrl, "mock://video_track_count=%u;audio_track_count=%u"
-                       ";length=%" PRId64 ";video_chroma=ARGB;video_add_track_at=%" PRId64,
+                       ";length=%" PRId64 ";can_control_pace=%s;video_chroma=ARGB;video_add_track_at=%" PRId64,
                        test_params[i].i_nb_video_tracks,
                        test_params[i].i_nb_audio_tracks, MOCK_DURATION,
+                       test_params[i].b_can_control_pace ? "true" : "false",
                        test_params[i].i_add_video_track_at ) < 0 )
             assert( !"Failed to allocate mock mrl" );
         input_item_t* p_item = input_item_New( psz_mrl, "mock item" );
         assert( p_item != NULL );
 
         vlc_mutex_lock( &ctx.lock );
-        int res = 0;
 
         if ( test_params[i].b_use_pos )
         {
@@ -161,43 +162,33 @@ static void test_thumbnails( libvlc_instance_t* p_vlc )
 
 static void thumbnailer_callback_cancel( void* data, picture_t* p_thumbnail )
 {
-    struct test_ctx* p_ctx = data;
-    assert( p_thumbnail == NULL );
-    vlc_mutex_lock( &p_ctx->lock );
-    p_ctx->b_done = true;
-    vlc_mutex_unlock( &p_ctx->lock );
-    vlc_cond_signal( &p_ctx->cond );
+    (void) data; (void) p_thumbnail;
+    /* This callback should not be called since the request is cancelled */
+    vlc_assert_unreachable();
 }
 
-
 static void test_cancel_thumbnail( libvlc_instance_t* p_vlc )
 {
     vlc_thumbnailer_t* p_thumbnailer = vlc_thumbnailer_Create(
                 VLC_OBJECT( p_vlc->p_libvlc_int ) );
     assert( p_thumbnailer != NULL );
 
-    struct test_ctx ctx;
-    ctx.b_done = false;
-    vlc_cond_init( &ctx.cond );
-    vlc_mutex_init( &ctx.lock );
-
-    const char* psz_mrl = "mock://video_track_count=1;audio_track_count=1";
+    const char* psz_mrl = "mock://video_track_count=0;audio_track_count=1;"
+                          /* force timeout: parsing will take the same time as length */
+                          "can_control_pace=false;"
+                          "length=200";
     input_item_t* p_item = input_item_New( psz_mrl, "mock item" );
     assert( p_item != NULL );
 
-    vlc_mutex_lock( &ctx.lock );
-    int res = 0;
     vlc_thumbnailer_request_t* p_req = vlc_thumbnailer_RequestByTime( p_thumbnailer,
-        VLC_TICK_FROM_SEC( 1 ), VLC_THUMBNAILER_SEEK_PRECISE, p_item,
-        VLC_TICK_INVALID, thumbnailer_callback_cancel, &ctx );
+        VLC_TICK_INVALID, VLC_THUMBNAILER_SEEK_PRECISE, p_item,
+        VLC_TICK_INVALID, thumbnailer_callback_cancel, NULL );
+
     vlc_thumbnailer_Cancel( p_thumbnailer, p_req );
-    while ( ctx.b_done == false )
-    {
-        vlc_tick_t timeout = vlc_tick_now() + VLC_TICK_FROM_SEC( 1 );
-        res = vlc_cond_timedwait( &ctx.cond, &ctx.lock, timeout );
-        assert( res != ETIMEDOUT );
-    }
-    vlc_mutex_unlock( &ctx.lock );
+
+    /* Check that thumbnailer_callback_cancel is not called, even after the
+     * normal termination of the parsing. */
+    (vlc_tick_sleep)(VLC_TICK_FROM_MS(250));
 
     input_item_Release( p_item );
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9d840d906feb903a6b9142302d9c9caca40eed7b...2dee0f7a2b8028bb46633e0217666276f1d6b41c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9d840d906feb903a6b9142302d9c9caca40eed7b...2dee0f7a2b8028bb46633e0217666276f1d6b41c
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