[vlc-devel] [PATCH] libvlc: expand media player API to retrieve full information about available chapter of a given title
Rémi Denis-Courmont
remi at remlab.net
Fri Jun 12 21:29:26 CEST 2015
Summary description is too long.
Le jeudi 04 juin 2015, 14:08:38 Felix Paul Kühne a écrit :
> ---
> 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).
This is incomplete documentation (unit?), and documented the fields in Doxygen
would be better.
> + */
> +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
Missing () for Doxygen.
> + * 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) );
Why calloc?
> + 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 * );
Useless casts.
> +
> + 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 )
Wrong and missing unlikely().
> + {
> + 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 * );
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list