[vlc-devel] [PATCH] libvlc: expand media player API to retrieve information about all available titles of the currently playing media item

Rémi Denis-Courmont remi at remlab.net
Tue Feb 3 19:48:48 CET 2015


Le 2015-02-03 21:32, Felix Paul Kühne a écrit :
> @@ -61,6 +61,17 @@ typedef struct libvlc_track_description_t
>  } libvlc_track_description_t;
>
>  /**
> + * Description for titles. It contains name (description string),
> and duration,
> + * and information if it is a menu.
> + */
> +typedef struct libvlc_title_description_t
> +{
> +    bool b_menu;

I'm still not convinced that there is any unintrinsically buggy usage 
of b_menu here.

> +    char *psz_name;
> +    int64_t i_duration;

Unit not documented.

> +} libvlc_title_description_t;
> +
> +/**
>   * Description for audio output. It contains
>   * name, description and pointer to next record.
>   */
> @@ -1129,6 +1140,32 @@ LIBVLC_API libvlc_track_description_t *
>          libvlc_video_get_title_description( libvlc_media_player_t 
> *p_mi );
>
>  /**
> + * Get the full description of a title
> + *
> + * \param p_mi the media player
> + * \param title address to store an allocated array of title 
> descriptions
> + *        (must be freed by the caller) [OUT]
> + *
> + * \return the number of titles
> + * \version LibVLC 3.0.0 and later.
> + */
> +LIBVLC_API unsigned
> +        libvlc_media_player_get_title_descriptions(
> libvlc_media_player_t *p_mi,
> +
> libvlc_title_description_t *** pp_titles );

Intuitively, I would think that error is not the same as zero titles, 
and there is no way to distinguish those cases.

> +
> +/**
> + * Release a title description
> + *
> + * \param p_titles title array to release
> + * \param i_count number of elements in the array
> + *
> + * \version LibVLC 3.0.0 and later
> + */
> +LIBVLC_API
> +    void libvlc_title_descriptions_release(
> libvlc_title_description_t **p_titles,
> +                                            unsigned i_count );

Urg. No. NULL-terminate the table and don't require that i_count 
parameter.

> +
> +/**
>   * Get the description of available chapters for specific title.
>   *
>   * \param p_mi the media player
> diff --git a/lib/libvlc.sym b/lib/libvlc.sym
> index 7810ed7..1ee5888 100644
> --- a/lib/libvlc.sym
> +++ b/lib/libvlc.sym
> @@ -151,6 +151,7 @@ libvlc_media_player_get_state
>  libvlc_media_player_get_time
>  libvlc_media_player_get_title
>  libvlc_media_player_get_title_count
> +libvlc_media_player_get_title_descriptions
>  libvlc_media_player_get_xwindow
>  libvlc_media_player_has_vout
>  libvlc_media_player_is_seekable
> @@ -196,6 +197,7 @@ libvlc_set_fullscreen
>  libvlc_set_log_verbosity
>  libvlc_set_user_agent
>  libvlc_set_app_id
> +libvlc_title_descriptions_release
>  libvlc_toggle_fullscreen
>  libvlc_toggle_teletext
>  libvlc_track_description_release
> diff --git a/lib/media_player.c b/lib/media_player.c
> index 3ca1e10..7bc0889 100644
> --- a/lib/media_player.c
> +++ b/lib/media_player.c
> @@ -1,7 +1,7 @@
>
> 
> /*****************************************************************************
>   * media_player.c: Libvlc API Media Instance management functions
>
> 
> *****************************************************************************
> - * Copyright (C) 2005-2011 VLC authors and VideoLAN
> + * Copyright (C) 2005-2015 VLC authors and VideoLAN
>   *
>   * Authors: Clément Stenac <zorglub at videolan.org>
>   *
> @@ -1223,6 +1223,83 @@ int libvlc_media_player_get_title_count(
> libvlc_media_player_t *p_mi )
>      return i_ret == VLC_SUCCESS ? val.i_int : -1;
>  }
>
> +unsigned libvlc_media_player_get_title_descriptions(
> libvlc_media_player_t *p_mi,
> +
> libvlc_title_description_t *** pp_titles )
> +{
> +    assert( p_mi );
> +
> +    input_thread_t *p_input = libvlc_get_input_thread( p_mi );
> +
> +    if( !p_input )
> +        return 0;
> +
> +    const int i_titles = libvlc_media_player_get_title_count( p_mi 
> );
> +
> +    *pp_titles = (i_titles > 0) ? calloc( i_titles,
> sizeof(**pp_titles) ) : NULL;
> +
> +    if( !*pp_titles ) // no titles or out of memory
> +    {
> +        vlc_object_release( p_input );
> +        return 0;
> +    }
> +
> +    /* fill array */
> +    libvlc_title_description_t *p_title;
> +    for( int i = 0; i < i_titles; i++ )
> +    {
> +        p_title = calloc( 1, sizeof(*pp_titles) );

Why calloc?

> +        if( !p_title )
> +        {
> +            goto bailout;
> +        }
> +        (*pp_titles)[i] = p_title;
> +
> +        input_title_t *p_input_title = NULL;
> +        if( input_Control(p_input, INPUT_GET_TITLE_INFO,
> &p_input_title, &i) != VLC_SUCCESS )

This is racy. Titles might have changed since get_title_count().

> +        {
> +            goto bailout;
> +        }
> +
> +        if( !p_title )
> +        {
> +            goto bailout;
> +        }
> +
> +        p_title->i_duration = p_input_title->i_length;
> +        p_title->b_menu = p_input_title->b_menu;
> +        if( p_input_title->psz_name )
> +        {
> +            p_title->psz_name = strdup( p_input_title->psz_name );
> +        }
> +
> +        vlc_input_title_Delete( p_input_title );
> +    }
> +
> +    vlc_object_release( p_input );
> +
> +    return i_titles;
> +
> +bailout:
> +    libvlc_title_descriptions_release( *pp_titles, i_titles );
> +    *pp_titles = NULL;
> +    free( p_title );
> +    vlc_object_release( p_input );
> +    return 0;
> +}
> +
> +void libvlc_title_descriptions_release( libvlc_title_description_t
> **p_titles,
> +                                        unsigned i_count )
> +{
> +    for( unsigned i = 0; i < i_count; ++i )
> +    {
> +        if( !p_titles[i] )
> +            continue;
> +        free( p_titles[i]->psz_name );
> +        free( p_titles[i] );
> +    }
> +    free( p_titles );
> +}
> +
>  void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi )
>  {
>      input_thread_t *p_input_thread;

-- 
Rémi Denis-Courmont



More information about the vlc-devel mailing list