diff --git a/include/vlc_thumbnailer.h b/include/vlc_thumbnailer.h index dcf908a9cb..bc6f44e99a 100644 --- a/include/vlc_thumbnailer.h +++ b/include/vlc_thumbnailer.h @@ -56,20 +56,40 @@ typedef void(*vlc_thumbnailer_cb)( void* data, picture_t* thumbnail ); VLC_API vlc_thumbnailer_t* vlc_thumbnailer_Create(vlc_object_t* parent, vlc_tick_t timeout) VLC_USED; -enum vlc_thumbnailer_seek_speed +/** + * Thumbnailer seek argument + */ +struct vlc_thumbnailer_seek_arg { - /** Precise, but potentially slow */ - VLC_THUMBNAILER_SEEK_PRECISE, - /** Fast, but potentially imprecise */ - VLC_THUMBNAILER_SEEK_FAST, + enum + { + /** Seek by time */ + VLC_THUMBNAILER_SEEK_TIME, + /** Seek by position */ + VLC_THUMBNAILER_SEEK_POS, + } type; + union + { + /** Seek time if type == VLC_THUMBNAILER_SEEK_TIME */ + vlc_tick_t time; + /** Seek position if type == VLC_THUMBNAILER_SEEK_POS */ + double pos; + }; + enum + { + /** Precise, but potentially slow */ + VLC_THUMBNAILER_SEEK_PRECISE, + /** Fast, but potentially imprecise */ + VLC_THUMBNAILER_SEEK_FAST, + } speed; }; /** - * \brief vlc_thumbnailer_RequestByTime Requests a thumbnailer at a given time + * \brief vlc_thumbnailer_Request Requests a thumbnailer * \param thumbnailer A thumbnailer object - * \param time The time at which the thumbnail should be taken - * \param speed The seeking speed \sa{enum vlc_thumbnailer_seek_speed} * \param input_item The input item to generate the thumbnail for + * \param seek_arg pointer to a seek struct, that tell at which time the + * thumbnail should be taken * \param timeout A timeout value, or VLC_TICK_INVALID to disable timeout * \param cb A user callback to be called on completion (success & error) * \param user_data An opaque value, provided as pf_cb's first parameter @@ -82,34 +102,10 @@ enum vlc_thumbnailer_seek_speed * released safely after calling this function. */ VLC_API vlc_thumbnailer_req_id -vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer, - vlc_tick_t time, - enum vlc_thumbnailer_seek_speed speed, - input_item_t *input_item, - vlc_thumbnailer_cb cb, void* user_data ); -/** - * \brief vlc_thumbnailer_RequestByTime Requests a thumbnailer at a given time - * \param thumbnailer A thumbnailer object - * \param pos The position at which the thumbnail should be taken - * \param speed The seeking speed \sa{enum vlc_thumbnailer_seek_speed} - * \param input_item The input item to generate the thumbnail for - * \param timeout A timeout value, or VLC_TICK_INVALID to disable timeout - * \param cb A user callback to be called on completion (success & error) - * \param user_data An opaque value, provided as pf_cb's first parameter - - * @return VLC_THUMBNAILER_REQ_ID_INVALID in case of error, or a valid id if - * the item was scheduled for preparsing. If this function returns a valid id, - * the callback is guaranteed to be called, even in case of later failure - * (except if cancelled early by the user). - * The provided input_item will be held by the thumbnailer and can safely be - * released safely after calling this function. - */ -VLC_API vlc_thumbnailer_req_id -vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer, - double pos, - enum vlc_thumbnailer_seek_speed speed, - input_item_t *input_item, - vlc_thumbnailer_cb cb, void* user_data ); +vlc_thumbnailer_Request( vlc_thumbnailer_t *thumbnailer, + input_item_t *input_item, + const struct vlc_thumbnailer_seek_arg *seek_arg, + vlc_thumbnailer_cb cb, void* user_data ); /** * \brief vlc_thumbnailer_Camcel Cancel a thumbnail request diff --git a/lib/media.c b/lib/media.c index 1413f34af4..3e555269a7 100644 --- a/lib/media.c +++ b/lib/media.c @@ -945,13 +945,13 @@ static void media_on_thumbnail_ready( void* data, picture_t* thumbnail ) } // Start an asynchronous thumbnail generation -libvlc_media_thumbnail_request_t* -libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst, - libvlc_media_t *md, libvlc_time_t time, - libvlc_thumbnailer_seek_speed_t speed, - unsigned int width, unsigned int height, - bool crop, libvlc_picture_type_t picture_type, - libvlc_time_t timeout ) +static libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request( libvlc_instance_t *inst, + libvlc_media_t *md, + const struct vlc_thumbnailer_seek_arg *seek_arg, + unsigned int width, unsigned int height, + bool crop, libvlc_picture_type_t picture_type, + libvlc_time_t timeout ) { assert( md ); @@ -972,12 +972,8 @@ libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst, req->type = picture_type; req->crop = crop; libvlc_media_retain( md ); - req->id = vlc_thumbnailer_RequestByTime( thumb, - vlc_tick_from_libvlc_time( time ), - speed == libvlc_media_thumbnail_seek_fast ? - VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, - md->p_input_item, - media_on_thumbnail_ready, req ); + req->id = vlc_thumbnailer_Request( thumb, md->p_input_item, seek_arg, + media_on_thumbnail_ready, req ); if ( req->id == VLC_PREPARSER_REQ_ID_INVALID ) { free( req ); @@ -988,6 +984,24 @@ libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst, return req; } +libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst, + libvlc_media_t *md, libvlc_time_t time, + libvlc_thumbnailer_seek_speed_t speed, + unsigned int width, unsigned int height, + bool crop, libvlc_picture_type_t picture_type, + libvlc_time_t timeout ) +{ + const struct vlc_thumbnailer_seek_arg seek_arg = { + .type = VLC_THUMBNAILER_SEEK_TIME, + .time = vlc_tick_from_libvlc_time( time ), + .speed = speed == libvlc_media_thumbnail_seek_fast ? + VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, + }; + return libvlc_media_thumbnail_request( inst, md, &seek_arg, width, height, + crop, picture_type, timeout ); +} + // Start an asynchronous thumbnail generation libvlc_media_thumbnail_request_t* libvlc_media_thumbnail_request_by_pos( libvlc_instance_t *inst, @@ -997,38 +1011,14 @@ libvlc_media_thumbnail_request_by_pos( libvlc_instance_t *inst, bool crop, libvlc_picture_type_t picture_type, libvlc_time_t timeout ) { - assert( md ); - - vlc_thumbnailer_t *thumb = libvlc_get_thumbnailer(inst); - if (unlikely(thumb == NULL)) - return NULL; - - vlc_thumbnailer_SetTimeout( thumb, vlc_tick_from_libvlc_time( timeout ) ); - - libvlc_media_thumbnail_request_t *req = malloc( sizeof( *req ) ); - if ( unlikely( req == NULL ) ) - return NULL; - - req->instance = inst; - req->md = md; - req->width = width; - req->height = height; - req->crop = crop; - req->type = picture_type; - libvlc_media_retain( md ); - req->id = vlc_thumbnailer_RequestByPos( thumb, pos, - speed == libvlc_media_thumbnail_seek_fast ? + const struct vlc_thumbnailer_seek_arg seek_arg = { + .type = VLC_THUMBNAILER_SEEK_POS, + .pos = pos, + .speed = speed == libvlc_media_thumbnail_seek_fast ? VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, - md->p_input_item, - media_on_thumbnail_ready, req ); - if ( req->id == VLC_PREPARSER_REQ_ID_INVALID ) - { - free( req ); - libvlc_media_release( md ); - return NULL; - } - libvlc_retain(inst); - return req; + }; + return libvlc_media_thumbnail_request( inst, md, &seek_arg, width, height, + crop, picture_type, timeout ); } // Destroy a thumbnail request diff --git a/modules/misc/medialibrary/Thumbnailer.cpp b/modules/misc/medialibrary/Thumbnailer.cpp index 31862683cb..2b7d4cfc33 100644 --- a/modules/misc/medialibrary/Thumbnailer.cpp +++ b/modules/misc/medialibrary/Thumbnailer.cpp @@ -71,10 +71,14 @@ bool Thumbnailer::generate( const medialibrary::IMedia&, const std::string& mrl, { vlc::threads::mutex_locker lock( m_mutex ); m_currentContext = &ctx; + struct vlc_thumbnailer_seek_arg seek_arg = { + .type = vlc_thumbnailer_seek_arg::VLC_THUMBNAILER_SEEK_POS, + .pos = position, + .speed = vlc_thumbnailer_seek_arg::VLC_THUMBNAILER_SEEK_FAST, + }; vlc_thumbnailer_req_id requestId = - vlc_thumbnailer_RequestByPos( m_thumbnailer.get(), position, - VLC_THUMBNAILER_SEEK_FAST, item.get(), - &onThumbnailComplete, &ctx ); + vlc_thumbnailer_Request( m_thumbnailer.get(), item.get(), &seek_arg, + &onThumbnailComplete, &ctx ); if (requestId == VLC_THUMBNAILER_REQ_ID_INVALID) { diff --git a/src/input/thumbnailer.c b/src/input/thumbnailer.c index 63ee18adfc..3688fb6a77 100644 --- a/src/input/thumbnailer.c +++ b/src/input/thumbnailer.c @@ -41,26 +41,11 @@ struct vlc_thumbnailer_t struct vlc_list submitted_tasks; /**< list of struct task */ }; -struct seek_target -{ - enum - { - VLC_THUMBNAILER_SEEK_TIME, - VLC_THUMBNAILER_SEEK_POS, - } type; - union - { - vlc_tick_t time; - double pos; - }; -}; - typedef struct task { vlc_thumbnailer_t *thumbnailer; - struct seek_target seek_target; - bool fast_seek; + struct vlc_thumbnailer_seek_arg seek_arg; input_item_t *item; vlc_thumbnailer_cb cb; void* userdata; @@ -83,7 +68,7 @@ static void RunnableRun(void *); static task_t * TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item, - struct seek_target seek_target, bool fast_seek, + const struct vlc_thumbnailer_seek_arg *seek_arg, vlc_thumbnailer_cb cb, void *userdata) { task_t *task = malloc(sizeof(*task)); @@ -92,8 +77,8 @@ TaskNew(vlc_thumbnailer_t *thumbnailer, input_item_t *item, task->thumbnailer = thumbnailer; task->item = item; - task->seek_target = seek_target; - task->fast_seek = fast_seek; + task->seek_arg = *seek_arg; + task->cb = cb; task->userdata = userdata; @@ -178,12 +163,16 @@ RunnableRun(void *userdata) if (!input) goto error; - if (task->seek_target.type == VLC_THUMBNAILER_SEEK_TIME) - input_SetTime(input, task->seek_target.time, task->fast_seek); + assert(task->seek_arg.speed == VLC_THUMBNAILER_SEEK_PRECISE + || task->seek_arg.speed == VLC_THUMBNAILER_SEEK_FAST); + bool fast_seek = task->seek_arg.speed == VLC_THUMBNAILER_SEEK_FAST; + + if (task->seek_arg.type == VLC_THUMBNAILER_SEEK_TIME) + input_SetTime(input, task->seek_arg.time, fast_seek); else { - assert(task->seek_target.type == VLC_THUMBNAILER_SEEK_POS); - input_SetPosition(input, task->seek_target.pos, task->fast_seek); + assert(task->seek_arg.type == VLC_THUMBNAILER_SEEK_POS); + input_SetPosition(input, task->seek_arg.pos, fast_seek); } int ret = input_Start(input); @@ -228,14 +217,13 @@ error: TaskDestroy(task); } -static vlc_thumbnailer_req_id -RequestCommon(vlc_thumbnailer_t *thumbnailer, struct seek_target seek_target, - enum vlc_thumbnailer_seek_speed speed, input_item_t *item, - vlc_thumbnailer_cb cb, void *userdata) +vlc_thumbnailer_req_id +vlc_thumbnailer_Request( vlc_thumbnailer_t *thumbnailer, + input_item_t *item, + const struct vlc_thumbnailer_seek_arg *seek_arg, + vlc_thumbnailer_cb cb, void* userdata ) { - bool fast_seek = speed == VLC_THUMBNAILER_SEEK_FAST; - task_t *task = TaskNew(thumbnailer, item, seek_target, fast_seek, cb, - userdata); + task_t *task = TaskNew(thumbnailer, item, seek_arg, cb, userdata); if (!task) return 0; @@ -252,33 +240,6 @@ RequestCommon(vlc_thumbnailer_t *thumbnailer, struct seek_target seek_target, return id; } -vlc_thumbnailer_req_id -vlc_thumbnailer_RequestByTime( vlc_thumbnailer_t *thumbnailer, - vlc_tick_t time, - enum vlc_thumbnailer_seek_speed speed, - input_item_t *item, - vlc_thumbnailer_cb cb, void* userdata ) -{ - struct seek_target seek_target = { - .type = VLC_THUMBNAILER_SEEK_TIME, - .time = time, - }; - return RequestCommon(thumbnailer, seek_target, speed, item, cb, userdata); -} - -vlc_thumbnailer_req_id -vlc_thumbnailer_RequestByPos( vlc_thumbnailer_t *thumbnailer, - double pos, enum vlc_thumbnailer_seek_speed speed, - input_item_t *item, - vlc_thumbnailer_cb cb, void* userdata ) -{ - struct seek_target seek_target = { - .type = VLC_THUMBNAILER_SEEK_POS, - .pos = pos, - }; - return RequestCommon(thumbnailer, seek_target, speed, item, cb, userdata); -} - size_t vlc_thumbnailer_Cancel( vlc_thumbnailer_t* thumbnailer, vlc_thumbnailer_req_id id ) { vlc_mutex_lock(&thumbnailer->lock); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index ce0e89945d..cb8533dc9a 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -831,8 +831,7 @@ vlc_es_id_GetStrId vlc_es_id_IsStrIdStable vlc_encoder_Destroy vlc_thumbnailer_Create -vlc_thumbnailer_RequestByTime -vlc_thumbnailer_RequestByPos +vlc_thumbnailer_Request vlc_thumbnailer_Cancel vlc_thumbnailer_Delete vlc_thumbnailer_SetTimeout diff --git a/test/src/input/thumbnail.c b/test/src/input/thumbnail.c index ec3c5478bc..ba00c90546 100644 --- a/test/src/input/thumbnail.c +++ b/test/src/input/thumbnail.c @@ -137,20 +137,23 @@ static void test_thumbnails( libvlc_instance_t* p_vlc ) vlc_mutex_lock( &ctx.lock ); vlc_thumbnailer_req_id id; + struct vlc_thumbnailer_seek_arg seek_arg; if ( test_params[i].b_use_pos ) { - id = vlc_thumbnailer_RequestByPos( p_thumbnailer, test_params[i].f_pos, - test_params[i].b_fast_seek ? - VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, - p_item, thumbnailer_callback, &ctx ); + seek_arg.type = VLC_THUMBNAILER_SEEK_POS; + seek_arg.pos = test_params[i].f_pos; + seek_arg.speed = test_params[i].b_fast_seek ? + VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE; } else { - id = vlc_thumbnailer_RequestByTime( p_thumbnailer, test_params[i].i_time, - test_params[i].b_fast_seek ? - VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, - p_item, thumbnailer_callback, &ctx ); + seek_arg.type = VLC_THUMBNAILER_SEEK_TIME; + seek_arg.time = test_params[i].i_time; + seek_arg.speed = test_params[i].b_fast_seek ? + VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE; } + id = vlc_thumbnailer_Request( p_thumbnailer, p_item, &seek_arg, + thumbnailer_callback, &ctx ); assert( id != VLC_THUMBNAILER_REQ_ID_INVALID ); while ( ctx.b_done == false ) @@ -185,9 +188,9 @@ static void test_cancel_thumbnail( libvlc_instance_t* p_vlc ) input_item_t* p_item = input_item_New( psz_mrl, "mock item" ); assert( p_item != NULL ); - vlc_thumbnailer_req_id id = vlc_thumbnailer_RequestByTime( p_thumbnailer, - VLC_TICK_INVALID, VLC_THUMBNAILER_SEEK_PRECISE, p_item, - thumbnailer_callback_cancel, NULL ); + vlc_thumbnailer_req_id id = + vlc_thumbnailer_Request( p_thumbnailer, p_item, NULL, + thumbnailer_callback_cancel, NULL ); vlc_thumbnailer_Cancel( p_thumbnailer, id );