vlc | branch: master | Hugo Beauzée-Luyssen <[email protected]> | Fri Oct 5 13:23:00 2018 +0200| [a9014afdac8bf102718f153d5d161f69cf87d53f] | committer: Hugo Beauzée-Luyssen
lib: Add thumbnailing support Fix #17368 > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a9014afdac8bf102718f153d5d161f69cf87d53f --- include/vlc/libvlc_events.h | 9 ++++ include/vlc/libvlc_media.h | 82 +++++++++++++++++++++++++++++++++ include/vlc/vlc.h | 1 + lib/audio.c | 1 + lib/libvlc.sym | 3 ++ lib/libvlc_internal.h | 1 + lib/media.c | 110 ++++++++++++++++++++++++++++++++++++++++++++ lib/media_discoverer.c | 1 + lib/media_list.c | 1 + lib/media_list_player.c | 1 + lib/media_player.c | 1 + lib/video.c | 1 + src/libvlc.c | 3 ++ src/libvlc.h | 1 + 14 files changed, 216 insertions(+) diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h index 18a1513d8e..1339639272 100644 --- a/include/vlc/libvlc_events.h +++ b/include/vlc/libvlc_events.h @@ -84,6 +84,11 @@ enum libvlc_event_e { * Subitem tree was added to a \link #libvlc_media_t media item\endlink */ libvlc_MediaSubItemTreeAdded, + /** + * A thumbnail generation for this \link #libvlc_media_t media \endlink completed. + * \see libvlc_media_get_thumbnail() + */ + libvlc_MediaThumbnailGenerated, libvlc_MediaPlayerMediaChanged=0x100, libvlc_MediaPlayerNothingSpecial, @@ -235,6 +240,10 @@ typedef struct libvlc_event_t } media_state_changed; struct { + libvlc_picture_t* p_thumbnail; + } media_thumbnail_generated; + struct + { libvlc_media_t * item; } media_subitemtree_added; diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h index 314d5c20b8..9475019b92 100644 --- a/include/vlc/libvlc_media.h +++ b/include/vlc/libvlc_media.h @@ -28,6 +28,8 @@ # ifdef __cplusplus extern "C" { +# else +# include <stdbool.h> # endif /** \defgroup libvlc_media LibVLC media @@ -801,6 +803,86 @@ LIBVLC_API libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md ); /** + * \brief libvlc_media_thumbnail_request_t An opaque thumbnail request object + */ +typedef struct libvlc_media_thumbnail_request_t libvlc_media_thumbnail_request_t; + +enum libvlc_thumbnailer_seek_speed +{ + libvlc_media_thumbnail_seek_precise, + libvlc_media_thumbnail_seek_fast, +}; + +/** + * \brief libvlc_media_get_thumbnail_by_time Start an asynchronous thumbnail generation + * + * If the request is successfuly queued, the libvlc_MediaThumbnailGenerated + * is guaranteed to be emited. + * + * \param md media descriptor object + * \param time The time at which the thumbnail should be generated + * \param speed The seeking speed \sa{enum libvlc_thumbnailer_seek_speed} + * \param width The thumbnail width + * \param height the thumbnail height + * \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t} + * \param timeout A timeout value in ms, or 0 to disable timeout + * + * \return A valid opaque request object, or NULL in case of failure. + * + * \version libvlc 4.0 or later + * + * \see libvlc_picture_t + * \see libvlc_picture_type_t + */ +LIBVLC_API libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request_by_time( libvlc_media_t *md, + libvlc_time_t time, + enum libvlc_thumbnailer_seek_speed speed, + unsigned int width, unsigned int height, + libvlc_picture_type_t picture_type, + libvlc_time_t timeout ); + +/** + * \brief libvlc_media_get_thumbnail_by_pos Start an asynchronous thumbnail generation + * + * If the request is successfuly queued, the libvlc_MediaThumbnailGenerated + * is guaranteed to be emited. + * + * \param md media descriptor object + * \param pos The position at which the thumbnail should be generated + * \param speed The seeking speed \sa{enum libvlc_thumbnailer_seek_speed} + * \param width The thumbnail width + * \param height the thumbnail height + * \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t} + * \param timeout A timeout value in ms, or 0 to disable timeout + * + * \return A valid opaque request object, or NULL in case of failure. + * + * \version libvlc 4.0 or later + * + * \see libvlc_picture_t + * \see libvlc_picture_type_t + */ +LIBVLC_API libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request_by_pos( libvlc_media_t *md, + float pos, + enum libvlc_thumbnailer_seek_speed speed, + unsigned int width, unsigned int height, + libvlc_picture_type_t picture_type, + libvlc_time_t timeout ); + +/** + * @brief libvlc_media_thumbnail_cancel cancels a thumbnailing request + * @param p_req An opaque thumbnail request object. + * + * Cancelling the request will still cause libvlc_MediaThumbnailGenerated event + * to be emited, with a NULL libvlc_picture_t + * If the request is cancelled after its completion, the behavior is undefined. + */ +LIBVLC_API void +libvlc_media_thumbnail_cancel( libvlc_media_thumbnail_request_t *p_req ); + +/** * Add a slave to the current media. * * A slave is an external input source that may contains an additional subtitle diff --git a/include/vlc/vlc.h b/include/vlc/vlc.h index 1c53fdb73f..d2d1b4ec9d 100644 --- a/include/vlc/vlc.h +++ b/include/vlc/vlc.h @@ -39,6 +39,7 @@ extern "C" { #include <vlc/libvlc.h> #include <vlc/libvlc_renderer_discoverer.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_player.h> #include <vlc/libvlc_media_list.h> diff --git a/lib/audio.c b/lib/audio.c index a77a8b7002..7aec6b1c50 100644 --- a/lib/audio.c +++ b/lib/audio.c @@ -31,6 +31,7 @@ #include <vlc/libvlc.h> #include <vlc/libvlc_renderer_discoverer.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_player.h> diff --git a/lib/libvlc.sym b/lib/libvlc.sym index 67cd40b69c..0b4d3fd74a 100644 --- a/lib/libvlc.sym +++ b/lib/libvlc.sym @@ -82,6 +82,9 @@ libvlc_media_get_type libvlc_media_get_user_data libvlc_media_is_parsed libvlc_media_get_parsed_status +libvlc_media_thumbnail_request_by_time +libvlc_media_thumbnail_request_by_pos +libvlc_media_thumbnail_cancel libvlc_media_library_load libvlc_media_library_media_list libvlc_media_library_new diff --git a/lib/libvlc_internal.h b/lib/libvlc_internal.h index 44df3cfd6f..d76cd3d21f 100644 --- a/lib/libvlc_internal.h +++ b/lib/libvlc_internal.h @@ -31,6 +31,7 @@ #include <vlc/libvlc.h> #include <vlc/libvlc_dialog.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_events.h> diff --git a/lib/media.c b/lib/media.c index 17deae436e..b4970c847b 100644 --- a/lib/media.c +++ b/lib/media.c @@ -29,6 +29,7 @@ #include <errno.h> #include <vlc/libvlc.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_list.h> // For the subitems, here for convenience #include <vlc/libvlc_events.h> @@ -38,12 +39,14 @@ #include <vlc_meta.h> #include <vlc_playlist.h> /* For the preparser */ #include <vlc_url.h> +#include <vlc_thumbnailer.h> #include "../src/libvlc.h" #include "libvlc_internal.h" #include "media_internal.h" #include "media_list_internal.h" +#include "picture_internal.h" static const vlc_meta_type_t libvlc_to_vlc_meta[] = { @@ -1092,6 +1095,113 @@ libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md ) } } +struct libvlc_media_thumbnail_request_t +{ + libvlc_media_t *md; + unsigned int width; + unsigned int height; + libvlc_picture_type_t type; + vlc_thumbnailer_request_t* req; +}; + +static void media_on_thumbnail_ready( void* data, picture_t* thumbnail ) +{ + libvlc_media_thumbnail_request_t *req = data; + libvlc_media_t *p_media = req->md; + libvlc_event_t event; + event.type = libvlc_MediaThumbnailGenerated; + libvlc_picture_t* pic = NULL; + if ( thumbnail != NULL ) + pic = libvlc_picture_new( VLC_OBJECT(p_media->p_libvlc_instance->p_libvlc_int), + thumbnail, req->type, req->width, req->height ); + event.u.media_thumbnail_generated.p_thumbnail = pic; + libvlc_event_send( &p_media->event_manager, &event ); + if ( pic != NULL ) + libvlc_picture_release( pic ); + libvlc_media_release( p_media ); + free( req ); +} + +libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request_by_time( libvlc_media_t *md, libvlc_time_t time, + enum libvlc_thumbnailer_seek_speed speed, + unsigned int width, unsigned int height, + libvlc_picture_type_t picture_type, + libvlc_time_t timeout ) +{ + assert( md ); + libvlc_priv_t *p_priv = libvlc_priv(md->p_libvlc_instance->p_libvlc_int); + if( unlikely( p_priv->p_thumbnailer == NULL ) ) + return NULL; + libvlc_media_thumbnail_request_t *req = malloc( sizeof( *req ) ); + if ( unlikely( req == NULL ) ) + return NULL; + + req->md = md; + req->width = width; + req->height = height; + req->type = picture_type; + libvlc_media_retain( md ); + req->req = vlc_thumbnailer_RequestByTime( p_priv->p_thumbnailer, + VLC_TICK_FROM_MS( time ), + speed == libvlc_media_thumbnail_seek_fast ? + VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, + md->p_input_item, + timeout > 0 ? VLC_TICK_FROM_MS( timeout ) : VLC_TICK_INVALID, + media_on_thumbnail_ready, req ); + if ( req->req == NULL ) + { + free( req ); + libvlc_media_release( md ); + return NULL; + } + return req; +} + +libvlc_media_thumbnail_request_t* +libvlc_media_thumbnail_request_by_pos( libvlc_media_t *md, float pos, + enum libvlc_thumbnailer_seek_speed speed, + unsigned int width, unsigned int height, + libvlc_picture_type_t picture_type, + libvlc_time_t timeout ) +{ + assert( md ); + libvlc_priv_t *priv = libvlc_priv(md->p_libvlc_instance->p_libvlc_int); + if( unlikely( priv->p_thumbnailer == NULL ) ) + return NULL; + libvlc_media_thumbnail_request_t *req = malloc( sizeof( *req ) ); + if ( unlikely( req == NULL ) ) + return NULL; + + req->md = md; + req->width = width; + req->height = height; + req->type = picture_type; + libvlc_media_retain( md ); + req->req = vlc_thumbnailer_RequestByPos( priv->p_thumbnailer, pos, + speed == libvlc_media_thumbnail_seek_fast ? + VLC_THUMBNAILER_SEEK_FAST : VLC_THUMBNAILER_SEEK_PRECISE, + md->p_input_item, + timeout > 0 ? VLC_TICK_FROM_MS( timeout ) : VLC_TICK_INVALID, + media_on_thumbnail_ready, req ); + if ( req->req == NULL ) + { + free( req ); + libvlc_media_release( md ); + return NULL; + } + return req; +} + +void libvlc_media_thumbnail_cancel( libvlc_media_thumbnail_request_t *req ) +{ + libvlc_priv_t *p_priv = libvlc_priv(req->md->p_libvlc_instance->p_libvlc_int); + assert( p_priv->p_thumbnailer != NULL ); + vlc_thumbnailer_Cancel( p_priv->p_thumbnailer, req->req ); + libvlc_media_release( req->md ); + free( req ); +} + int libvlc_media_slaves_add( libvlc_media_t *p_md, libvlc_media_slave_type_t i_type, unsigned int i_priority, diff --git a/lib/media_discoverer.c b/lib/media_discoverer.c index f3a13a7717..f3840e7ace 100644 --- a/lib/media_discoverer.c +++ b/lib/media_discoverer.c @@ -28,6 +28,7 @@ #include <assert.h> #include <vlc/libvlc.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_list.h> #include <vlc/libvlc_media_discoverer.h> diff --git a/lib/media_list.c b/lib/media_list.c index 720c7d522f..37c7586b0e 100644 --- a/lib/media_list.c +++ b/lib/media_list.c @@ -28,6 +28,7 @@ #include <assert.h> #include <vlc/libvlc.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_list.h> #include <vlc/libvlc_events.h> diff --git a/lib/media_list_player.c b/lib/media_list_player.c index 114da9c680..d4ea676172 100644 --- a/lib/media_list_player.c +++ b/lib/media_list_player.c @@ -29,6 +29,7 @@ #include <vlc/libvlc.h> #include <vlc/libvlc_renderer_discoverer.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_list.h> #include <vlc/libvlc_media_player.h> diff --git a/lib/media_player.c b/lib/media_player.c index 4f4cb70291..9cb826934a 100644 --- a/lib/media_player.c +++ b/lib/media_player.c @@ -28,6 +28,7 @@ #include <vlc/libvlc.h> #include <vlc/libvlc_renderer_discoverer.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_events.h> diff --git a/lib/video.c b/lib/video.c index e5796ec2c8..fc964955b4 100644 --- a/lib/video.c +++ b/lib/video.c @@ -31,6 +31,7 @@ #include <vlc/libvlc.h> #include <vlc/libvlc_renderer_discoverer.h> +#include <vlc/libvlc_picture.h> #include <vlc/libvlc_media.h> #include <vlc/libvlc_media_player.h> diff --git a/src/libvlc.c b/src/libvlc.c index 18d55004d1..b715cbcf29 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -376,6 +376,9 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) msg_Dbg( p_libvlc, "removing all interfaces" ); intf_DestroyAll( p_libvlc ); + if ( priv->p_thumbnailer ) + vlc_thumbnailer_Release( priv->p_thumbnailer ); + if ( priv->p_media_library ) libvlc_MlRelease( priv->p_media_library ); diff --git a/src/libvlc.h b/src/libvlc.h index afe075d62c..6b585807e4 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -197,6 +197,7 @@ typedef struct libvlc_priv_t struct input_preparser_t *parser; ///< Input item meta data handler vlc_actions_t *actions; ///< Hotkeys handler struct vlc_medialibrary_t *p_media_library; ///< Media library instance + struct vlc_thumbnailer_t *p_thumbnailer; ///< Lazily instantiated media thumbnailer /* Exit callback */ vlc_exit_t exit; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
