[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