[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