vlc | branch: master | Felix Paul Kühne <[email protected]> | Thu Jun 4 14:02:44 2015 +0200| [b0ba9c4cc8559924119714c060129d71d0a9f29c] | committer: Felix Paul Kühne
libvlc: expand media player API to retrieve full information about available chapter of a given title > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b0ba9c4cc8559924119714c060129d71d0a9f29c --- NEWS | 3 +- include/vlc/libvlc_media_player.h | 43 ++++++++++++++++++- include/vlc_input.h | 3 ++ lib/libvlc.sym | 2 + lib/media_player.c | 86 +++++++++++++++++++++++++++++++++++++ src/input/control.c | 44 +++++++++++++++++++ 6 files changed, 179 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index fadc7e6..4b87f6e 100644 --- a/NEWS +++ b/NEWS @@ -120,7 +120,8 @@ libVLC: identifier (if there is one available) * Add libvlc_media_get_type to get the type of the media * Add libvlc_media_player_get_full_title_descriptions to get full title info of the media - * Deprecate libvlc_video_get_title_description + * Add libvlc_media_player_get_full_chapter_descriptions to get full chapter info of the media + * Deprecate libvlc_video_get_title_description, libvlc_video_get_chapter_description Logging * Support for the SystemD Journal diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h index d0c2120..5f96b1b 100644 --- a/include/vlc/libvlc_media_player.h +++ b/include/vlc/libvlc_media_player.h @@ -73,6 +73,18 @@ typedef struct libvlc_title_description_t } libvlc_title_description_t; /** + * Description for chapters. + * It contains information about time offset, duration + * (both in milliseconds) as well as name (description string). + */ +typedef struct libvlc_chapter_description_t +{ + int64_t i_time_offset; + int64_t i_duration; + char *psz_name; +} libvlc_chapter_description_t; + +/** * Description for audio output. It contains * name, description and pointer to next record. */ @@ -1170,6 +1182,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 @@ -1177,7 +1218,7 @@ LIBVLC_API * \return list containing description of available chapter for title i_title. * It must be freed with libvlc_track_description_list_release() */ -LIBVLC_API libvlc_track_description_t * +LIBVLC_DEPRECATED LIBVLC_API libvlc_track_description_t * libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi, int i_title ); /** diff --git a/include/vlc_input.h b/include/vlc_input.h index 4a397fc..7ae07b1 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -455,6 +455,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 4e17b19..9c88996 100644 --- a/lib/media_player.c +++ b/lib/media_player.c @@ -1408,6 +1408,92 @@ 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; + + /* 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 / 1000; + + if( i > 0 ) + { + p_chapter->i_duration = p_chapter->i_time_offset - (*pp_chapters)[i-1]->i_time_offset; + } + else + { + p_chapter->i_duration = p_chapter->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 * ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
