[vlc-commits] lib: Add thumbnailing support

Hugo Beauzée-Luyssen git at videolan.org
Mon Nov 12 17:12:20 CET 2018


vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | 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;



More information about the vlc-commits mailing list