Commit 3b26eefc authored by Thomas Guillem's avatar Thomas Guillem Committed by Steve Lhomme
Browse files

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.
parent b02ea71c
......@@ -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,7 +168,7 @@ 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);
......@@ -209,22 +212,28 @@ RunnableRun(void *userdata)
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)
while (task->status == RUNNING && !timeout)
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);
if (notify)
NotifyThumbnail(task, pic);
if (pic != NULL)
picture_Release(pic);
input_Stop(input);
input_Close(input);
......@@ -239,7 +248,7 @@ Interrupt(task_t *task)
{
/* Wake up RunnableRun() which will call input_Stop() */
vlc_mutex_lock(&task->lock);
task->ended = true;
task->status = INTERRUPTED;
vlc_mutex_unlock(&task->lock);
vlc_cond_signal(&task->cond_ended);
}
......
......@@ -162,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_cond_signal( &p_ctx->cond );
vlc_mutex_unlock( &p_ctx->lock );
(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 );
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment