[vlc-devel] [PATCH] libvlc: expand media player API to retrieve full information about available chapter of a given title

Felix Paul Kühne fkuehne at videolan.org
Thu Jun 4 14:08:38 CEST 2015


---
 include/vlc/libvlc_media_player.h | 40 ++++++++++++++++++++
 include/vlc_input.h               |  3 ++
 lib/libvlc.sym                    |  2 +
 lib/media_player.c                | 78 +++++++++++++++++++++++++++++++++++++++
 src/input/control.c               | 44 ++++++++++++++++++++++
 5 files changed, 167 insertions(+)

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 8bb7c29..48ce461 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -73,6 +73,17 @@ typedef struct libvlc_title_description_t
 } libvlc_title_description_t;
 
 /**
+ * Description for chapters.
+ * It contains information about time set as well as
+ * name (description string).
+ */
+typedef struct libvlc_chapter_description_t
+{
+    int64_t i_time_offset;
+    char *psz_name;
+} libvlc_chapter_description_t;
+
+/**
  * Description for audio output. It contains
  * name, description and pointer to next record.
  */
@@ -1170,6 +1181,35 @@ LIBVLC_API
                                             unsigned i_count );
 
 /**
+ * Get the full description of available chapters
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_mi the media player
+ * \param index of the title to query for chapters
+ * \param address to store an allocated array of chapter descriptions
+ *        descriptions (must be freed with libvlc_chapter_descriptions_release
+ *        by the caller) [OUT]
+ *
+ * \return the number of chapters (-1 on error)
+ */
+LIBVLC_API int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t *p_mi,
+                                                                  int i_chapters_of_title,
+                                                                  libvlc_chapter_description_t *** pp_chapters );
+
+/**
+ * Release a chapter description
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param chapter description array to release
+ * \param number of chapter descriptions to release
+ */
+LIBVLC_API
+void libvlc_chapter_descriptions_release( libvlc_chapter_description_t **p_chapters,
+                                          unsigned i_count );
+
+/**
  * Get the description of available chapters for specific title.
  *
  * \param p_mi the media player
diff --git a/include/vlc_input.h b/include/vlc_input.h
index 35b4ad3..1ae76dd 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -458,6 +458,9 @@ enum input_query_e
     INPUT_GET_TITLE_INFO,     /* arg1=input_title_t** arg2= int * res=can fail */
     INPUT_GET_FULL_TITLE_INFO,     /* arg1=input_title_t*** arg2= int * res=can fail */
 
+    /* seekpoints */
+    INPUT_GET_SEEKPOINTS,  /* arg1=seekpoint_t*** arg2= int * res=can fail */
+
     /* Attachments */
     INPUT_GET_ATTACHMENTS, /* arg1=input_attachment_t***, arg2=int*  res=can fail */
     INPUT_GET_ATTACHMENT,  /* arg1=input_attachment_t**, arg2=char*  res=can fail */
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 44e0eda..03577c7 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -44,6 +44,7 @@ libvlc_audio_set_format
 libvlc_audio_set_format_callbacks
 libvlc_audio_set_callbacks
 libvlc_audio_set_volume_callback
+libvlc_chapter_descriptions_release
 libvlc_clock
 libvlc_event_attach
 libvlc_event_detach
@@ -149,6 +150,7 @@ libvlc_media_player_get_chapter
 libvlc_media_player_get_chapter_count
 libvlc_media_player_get_chapter_count_for_title
 libvlc_media_player_get_fps
+libvlc_media_player_get_full_chapter_descriptions
 libvlc_media_player_get_full_title_descriptions
 libvlc_media_player_get_hwnd
 libvlc_media_player_get_length
diff --git a/lib/media_player.c b/lib/media_player.c
index 3ae853a..de0da95 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -1407,6 +1407,84 @@ void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles,
     free( p_titles );
 }
 
+int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t *p_mi,
+                                                      int i_chapters_of_title,
+                                                      libvlc_chapter_description_t *** pp_chapters )
+{
+    assert( p_mi );
+
+    input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
+
+    if( !p_input_thread )
+        return -1;
+
+    seekpoint_t **p_seekpoint = NULL;
+    int *i_titles = 0;
+
+    /* fetch data */
+    int ret = input_Control(p_input_thread, INPUT_GET_SEEKPOINTS, &p_seekpoint, &i_chapters_of_title);
+    vlc_object_release( p_input_thread );
+
+    if( ret != VLC_SUCCESS)
+    {
+        return -1;
+    }
+
+    if (i_chapters_of_title == 0 || p_seekpoint == NULL)
+    {
+        return 0;
+    }
+
+    const int ci_chapter_count = (const int)i_chapters_of_title;
+
+    *pp_chapters = calloc( ci_chapter_count, sizeof(**pp_chapters) );
+    if( !*pp_chapters )
+    {
+        return -1;
+    }
+
+    /* fill array */
+    for( int i = 0; i < ci_chapter_count; i++)
+    {
+        libvlc_chapter_description_t *p_chapter = calloc( 1, sizeof(*p_chapter) );
+        if( unlikely(p_chapter == NULL) )
+        {
+            libvlc_chapter_descriptions_release( *pp_chapters, ci_chapter_count );
+            free( p_chapter );
+            return -1;
+        }
+        (*pp_chapters)[i] = p_chapter;
+
+        p_chapter->i_time_offset = p_seekpoint[i]->i_time_offset;
+
+        if( p_seekpoint[i]->psz_name )
+        {
+            p_chapter->psz_name = strdup( p_seekpoint[i]->psz_name );
+        }
+        else
+        {
+            p_chapter->psz_name = NULL;
+        }
+        vlc_seekpoint_Delete( p_seekpoint[i] );
+    }
+
+    return ci_chapter_count;
+}
+
+void libvlc_chapter_descriptions_release( libvlc_chapter_description_t **p_chapters,
+                                          unsigned i_count )
+{
+    for (unsigned i = 0; i < i_count; i++ )
+    {
+        if ( !p_chapters[i] )
+            continue;
+
+        free( p_chapters[i]->psz_name );
+        free( p_chapters[i] );
+    }
+    free( p_chapters );
+}
+
 void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi )
 {
     input_thread_t *p_input_thread;
diff --git a/src/input/control.c b/src/input/control.c
index 72656f4..dc33492 100644
--- a/src/input/control.c
+++ b/src/input/control.c
@@ -391,6 +391,50 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
             return VLC_SUCCESS;
         }
 
+        case INPUT_GET_SEEKPOINTS:
+        {
+            seekpoint_t ***array = (seekpoint_t ***)va_arg( args, seekpoint_t *** );
+            int *pi_title_to_fetch = (int *) va_arg( args, int * );
+
+            vlc_mutex_lock( &p_input->p->p_item->lock );
+
+            if ( *pi_title_to_fetch < 0 ) /* query current title if -1 */
+                *pi_title_to_fetch = var_GetInteger( p_input, "title" );
+
+            if( !p_input->p->i_title || p_input->p->i_title < *pi_title_to_fetch )
+            {
+                vlc_mutex_unlock( &p_input->p->p_item->lock );
+                return VLC_EGENERIC;
+            }
+
+            input_title_t *p_title = vlc_input_title_Duplicate( p_input->p->title[*pi_title_to_fetch] );
+
+            /* set arg2 to the number of seekpoints we found */
+            const int i_chapters = p_title->i_seekpoint;
+            *pi_title_to_fetch = i_chapters;
+
+            if ( i_chapters == 0 )
+            {
+                vlc_mutex_unlock( &p_input->p->p_item->lock );
+                return VLC_SUCCESS;
+            }
+
+            *array = calloc( p_title->i_seekpoint, sizeof(**array) );
+            if( !array )
+            {
+                vlc_mutex_unlock( &p_input->p->p_item->lock );
+                return VLC_ENOMEM;
+            }
+            for( int i = 0; i < i_chapters; i++ )
+            {
+                (*array)[i] = vlc_seekpoint_Duplicate( p_title->seekpoint[i] );
+            }
+
+            vlc_mutex_unlock( &p_input->p->p_item->lock );
+
+            return VLC_SUCCESS;
+        }
+
         case INPUT_GET_VIDEO_FPS:
             pf = (double*)va_arg( args, double * );
 
-- 
2.4.2




More information about the vlc-devel mailing list