[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