[vlc-devel] [PATCH 3/3] lib: Add thumbnailing support

Thomas Guillem thomas at gllm.fr
Mon Oct 8 08:12:35 CEST 2018



On Sat, Oct 6, 2018, at 06:03, Zhao Zhili wrote:
> On 10/5/18 10:37 PM, Hugo Beauzée-Luyssen wrote:
> > Fix #17368
> > ---
> >   include/vlc/libvlc_events.h |  9 +++++
> >   include/vlc/libvlc_media.h  | 39 ++++++++++++++++++++
> >   include/vlc/vlc.h           |  1 +
> >   lib/audio.c                 |  1 +
> >   lib/libvlc.sym              |  3 ++
> >   lib/libvlc_internal.h       |  1 +
> >   lib/media.c                 | 73 +++++++++++++++++++++++++++++++++++++
> >   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                |  6 +++
> >   src/libvlc.h                |  1 +
> >   14 files changed, 139 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,
> > @@ -234,6 +239,10 @@ typedef struct libvlc_event_t
> >               int new_state; /**< see @ref libvlc_state_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..a0b8d79405 100644
> > --- a/include/vlc/libvlc_media.h
> > +++ b/include/vlc/libvlc_media.h
> > @@ -800,6 +800,45 @@ void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks,
> >   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;
> > +
> > +/**
> > + * \brief libvlc_media_get_thumbnail Start an asynchronous thumbnail generation
> > + *
> > + * If the request is successfuly queued, the libvlc_MediaThumbnailGenerated
> > + * is guaranteed to be emited.
> > + *
> > + * \param p_md media descriptor object
> > + * \param i_time the time to generate a thumbail at
> > + * \param i_width thumbnail's width
> > + * \param i_height thumbnail's height
> > + * \param i_type the image type
> > + * \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( libvlc_media_t *p_md, libvlc_time_t i_time,
> > +                                unsigned int i_width, unsigned int i_height,
> > +                                libvlc_picture_type_t i_type );
> 
> In my opinion it would be useful to support setting the position, in 
> case of the duration is unknown or the user don't care about the time.
> 
> By the way, "start-time" use precise seeking. I think most of the time 
> we don't want preroll to generate thumbnail.

Just seek between input creation and start instead of using this variable.
Indeed, you should do a fast seek, and propose a seek by position.

> 
> > +
> > +/**
> > + * @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.
> >    *
> > 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 41c6dd63f5..ddd8cbda12 100644
> > --- a/lib/libvlc.sym
> > +++ b/lib/libvlc.sym
> > @@ -82,6 +82,8 @@ libvlc_media_get_type
> >   libvlc_media_get_user_data
> >   libvlc_media_is_parsed
> >   libvlc_media_get_parsed_status
> > +libvlc_media_thumbnail_request
> > +libvlc_media_thumbnail_cancel
> >   libvlc_media_library_load
> >   libvlc_media_library_media_list
> >   libvlc_media_library_new
> > @@ -262,6 +264,7 @@ libvlc_set_exit_handler
> >   libvlc_audio_filter_list_get
> >   libvlc_video_filter_list_get
> >   libvlc_module_description_list_release
> > +libvlc_picture_retain
> >   libvlc_picture_release
> >   libvlc_picture_save
> >   libvlc_picture_get_buffer
> > 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..894a407172 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,76 @@ libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md )
> >       }
> >   }
> >   
> > +struct libvlc_media_thumbnail_request_t
> > +{
> > +    libvlc_media_t *p_md;
> > +    unsigned int i_width;
> > +    unsigned int i_height;
> > +    libvlc_picture_type_t i_type;
> > +    vlc_thumbnailer_request_t* p_req;
> > +};
> > +
> > +static void media_on_thumbnail_ready( void* data, picture_t* p_thumbnail )
> > +{
> > +    libvlc_media_thumbnail_request_t *req = data;
> > +    libvlc_media_t *p_media = req->p_md;
> > +    libvlc_event_t event;
> > +    event.type = libvlc_MediaThumbnailGenerated;
> > +    libvlc_picture_t* p_pic = NULL;
> > +    if ( p_thumbnail != NULL )
> > +        p_pic = libvlc_picture_new( VLC_OBJECT(p_media->p_libvlc_instance->p_libvlc_int),
> > +                                    p_thumbnail, req->i_type, req->i_width, req->i_height );
> > +    event.u.media_thumbnail_generated.p_thumbnail = p_pic;
> > +    libvlc_event_send( &p_media->event_manager, &event );
> > +    if ( p_pic != NULL )
> > +        libvlc_picture_release( p_pic );
> > +    libvlc_media_release( p_media );
> > +    free( req );
> > +}
> > +
> > +libvlc_media_thumbnail_request_t*
> > +libvlc_media_thumbnail_request( libvlc_media_t *p_md, libvlc_time_t i_time,
> > +                                unsigned int i_width, unsigned int i_height,
> > +                                libvlc_picture_type_t i_type )
> > +{
> > +    assert( p_md );
> > +    libvlc_priv_t *p_priv = libvlc_priv(p_md->p_libvlc_instance->p_libvlc_int);
> > +    if( p_priv->p_thumbnailer == NULL )
> > +    {
> > +        p_priv->p_thumbnailer = vlc_thumbnailer_Create(
> > +                    VLC_OBJECT(p_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->p_md = p_md;
> > +    req->i_width = i_width;
> > +    req->i_height = i_height;
> > +    req->i_type = i_type;
> > +    libvlc_media_retain( p_md );
> > +    req->p_req = vlc_thumbnailer_Request( p_priv->p_thumbnailer, p_md->p_input_item,
> > +                            VLC_TICK_FROM_MS( i_time ),media_on_thumbnail_ready,
> > +                            req );
> > +    if ( req->p_req == NULL )
> > +    {
> > +        free( req );
> > +        libvlc_media_release( p_md );
> > +        return NULL;
> > +    }
> > +    return req;
> > +}
> > +
> > +void libvlc_media_thumbnail_cancel( libvlc_media_thumbnail_request_t *p_req )
> > +{
> > +    libvlc_priv_t *p_priv = libvlc_priv(p_req->p_md->p_libvlc_instance->p_libvlc_int);
> > +    assert( p_priv->p_thumbnailer != NULL );
> > +    vlc_thumbnailer_Cancel( p_priv->p_thumbnailer, p_req->p_req );
> > +    libvlc_media_release( p_req->p_md );
> > +    free( p_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 7f4d427f63..17ff97eae3 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 9bf9ef983e..28b5de32e0 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 f12f980936..79c42b74b4 100644
> > --- a/src/libvlc.c
> > +++ b/src/libvlc.c
> > @@ -63,6 +63,7 @@
> >   #include <vlc_url.h>
> >   #include <vlc_modules.h>
> >   #include <vlc_media_library.h>
> > +#include <vlc_thumbnailer.h>
> >   
> >   #include "libvlc.h"
> >   #include "playlist/playlist_internal.h"
> > @@ -225,6 +226,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
> >               msg_Warn( p_libvlc, "Media library initialization failed" );
> >       }
> >   
> > +    priv->p_thumbnailer = NULL;
> > +
> >       /*
> >        * Initialize hotkey handling
> >        */
> > @@ -371,6 +374,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 97faa1d4d8..b41f095850 100644
> > --- a/src/libvlc.h
> > +++ b/src/libvlc.h
> > @@ -188,6 +188,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-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list