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

Hugo Beauzée-Luyssen hugo at beauzee.fr
Thu Mar 26 14:16:06 CET 2015


Hi,

On Thu, Mar 26, 2015, at 02:07 PM, Felix Paul Kühne wrote:
> ---
>  include/vlc/libvlc_media_player.h | 33 ++++++++++++++++-
>  include/vlc_input.h               | 11 +++++-
>  lib/libvlc.sym                    |  2 +
>  lib/media_player.c                | 77
>  ++++++++++++++++++++++++++++++++++++++-
>  src/input/control.c               | 32 +++++++++++++++-
>  5 files changed, 151 insertions(+), 4 deletions(-)
> 
> diff --git a/include/vlc/libvlc_media_player.h
> b/include/vlc/libvlc_media_player.h
> index c55e85d..07b64c6 100644
> --- a/include/vlc/libvlc_media_player.h
> +++ b/include/vlc/libvlc_media_player.h
> @@ -1,7 +1,7 @@
>  /*****************************************************************************
>   * libvlc_media_player.h:  libvlc_media_player external API
>   *****************************************************************************
> - * Copyright (C) 1998-2010 VLC authors and VideoLAN
> + * Copyright (C) 1998-2015 VLC authors and VideoLAN
>   * $Id$
>   *
>   * Authors: Clément Stenac <zorglub at videolan.org>
> @@ -61,6 +61,18 @@ typedef struct libvlc_track_description_t
>  } libvlc_track_description_t;
>  
>  /**
> + * Description for titles. It contains name (description string), and
> duration in microseconds if known,
> + * and information if it was determined as a menu by the demuxer.
> + */
> +typedef struct libvlc_title_description_t
> +{
> +    int64_t i_duration;
> +    struct libvlc_title_description_t *p_next;
> +    char *psz_name;
> +    bool b_menu;
> +} libvlc_title_description_t;
> +
> +/**
>   * Description for audio output. It contains
>   * name, description and pointer to next record.
>   */
> @@ -1129,6 +1141,25 @@ LIBVLC_API libvlc_track_description_t *
>          libvlc_video_get_title_description( libvlc_media_player_t *p_mi
>          );
>  
>  /**
> + * Get the full description of available titles
> + *
> + * \param p_mi the media player *
> + * \return list containing full description of available titles
> + * \version LibVLC 3.0.0 and later.
> + */
> +LIBVLC_API libvlc_title_description_t *
> +        libvlc_media_player_get_title_descriptions(
> libvlc_media_player_t *p_mi );
> +
> +/**
> + * Release a title description
> + *
> + * \param p_titles title list to release
> + * \version LibVLC 3.0.0 and later
> + */
> +LIBVLC_API
> +    void libvlc_title_descriptions_release( libvlc_title_description_t
> *p_titles );
> +
> +/**
>   * 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 6ec305b..ae62eed 100644
> --- a/include/vlc_input.h
> +++ b/include/vlc_input.h
> @@ -1,7 +1,7 @@
>  /*****************************************************************************
>   * vlc_input.h: Core input structures
>   *****************************************************************************
> - * Copyright (C) 1999-2006 VLC authors and VideoLAN
> + * Copyright (C) 1999-2015 VLC authors and VideoLAN
>   * $Id$
>   *
>   * Authors: Christophe Massiot <massiot at via.ecp.fr>
> @@ -91,6 +91,7 @@ typedef struct input_title_t
>      int         i_seekpoint;
>      seekpoint_t **seekpoint;
>  
> +    struct input_title_t *p_next;  /* set when retrieving the full list
> of titles */
>  } input_title_t;
>  
>  static inline input_title_t *vlc_input_title_New(void)
> @@ -103,6 +104,7 @@ static inline input_title_t
> *vlc_input_title_New(void)
>      t->i_size   = 0;
>      t->i_seekpoint = 0;
>      t->seekpoint = NULL;
> +    t->p_next = NULL;
>  
>      return t;
>  }
> @@ -120,6 +122,12 @@ static inline void vlc_input_title_Delete(
> input_title_t *t )
>          free( t->seekpoint[i] );
>      }
>      free( t->seekpoint );
> +
> +    if ( t->p_next )
> +    {
> +        vlc_input_title_Delete( t->p_next );
> +    }
> +
>      free( t );
>  }
>  
> @@ -455,6 +463,7 @@ enum input_query_e
>  
>      /* titles */
>      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 */
>  
>      /* Attachments */
>      INPUT_GET_ATTACHMENTS, /* arg1=input_attachment_t***, arg2=int* 
>      res=can fail */
> 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..ce1e7a4 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,81 @@ int libvlc_media_player_get_title_count(
> libvlc_media_player_t *p_mi )
>      return i_ret == VLC_SUCCESS ? val.i_int : -1;
>  }
>  
> +libvlc_title_description_t * libvlc_media_player_get_title_descriptions(
> libvlc_media_player_t *p_mi )
> +{
> +    assert( p_mi );
> +
> +    input_thread_t *p_input = libvlc_get_input_thread( p_mi );
> +
> +    if( !p_input )
> +        return NULL;
> +
> +    input_title_t *p_input_title = NULL;
> +    int *i_titles = 0;
> +
> +    /* fetch data */
> +    if( input_Control(p_input, INPUT_GET_FULL_TITLE_INFO,
> &p_input_title, &i_titles) != VLC_SUCCESS )
> +        return NULL;
> +
> +    if( p_input_title == NULL )
> +        return NULL;
> +
> +    /* fill array */
> +    libvlc_title_description_t *list = NULL;
> +
> +    for( int i = 0; i < i_titles; i++)
> +    {
> +        libvlc_title_description_t *p_title = malloc(
> sizeof(libvlc_title_description_t) );
> +        if( unlikely(p_title == NULL) )
> +            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 );
> +        }

You are not setting psz_name to NULL when p_input_title is NULL

> +
> +        p_title->p_next = list;
> +        list = p_title;
> +
> +        if( p_input_title->p_next != NULL )
> +        {
> +            p_input_title = p_input_title->p_next;
> +        }
> +        else
> +        {
> +            break;
> +        }
> +    }
> +
> +    vlc_input_title_Delete( p_input_title );
> +
> +    vlc_object_release( p_input );
> +
> +    return list;
> +
> +bailout:
> +    if( p_input_title )
> +    {
> +        vlc_input_title_Delete( p_input_title );
> +    }
> +    libvlc_title_descriptions_release( list );
> +    vlc_object_release( p_input );
> +    return NULL;
> +}
> +
> +void libvlc_title_descriptions_release( libvlc_title_description_t
> *p_titles )
> +{
> +    while( p_titles != NULL )
> +    {
> +        libvlc_title_description_t *next = p_titles->p_next;
> +        free( p_titles->psz_name );
> +        free( p_titles );
> +        p_titles = next;
> +    }
> +}
> +
>  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 2e4633f..8c85abb 100644
> --- a/src/input/control.c
> +++ b/src/input/control.c
> @@ -1,7 +1,7 @@
>  /*****************************************************************************
>   * control.c
>   *****************************************************************************
> - * Copyright (C) 1999-2004 VLC authors and VideoLAN
> + * Copyright (C) 1999-2015 VLC authors and VideoLAN
>   * $Id$
>   *
>   * Authors: Gildas Bazin <gbazin at videolan.org>
> @@ -358,6 +358,36 @@ int input_vaControl( input_thread_t *p_input, int
> i_query, va_list args )
>              }
>          }
>  
> +        case INPUT_GET_FULL_TITLE_INFO:
> +        {
> +            input_title_t **list = (input_title_t **)va_arg( args,
> input_title_t ** );
> +            int *count = (int *) va_arg( args, int * );
> +
> +            vlc_mutex_lock( &p_input->p->p_item->lock );
> +
> +            const int i_titles = p_input->p->i_title;
> +            *count = i_titles;
> +
> +            if( i_titles == 0 )
> +            {

Mutex is still locked here

> +                return VLC_EGENERIC;
> +            }
> +
> +            for( int i = 0; i < i_titles; i++ )
> +            {
> +                input_title_t *p_title = vlc_input_title_Duplicate(
> p_input->p->title[i] );
> +                if( unlikely(p_title == NULL) )
> +                    break;
> +
> +                p_title->p_next = *list;
> +                *list = p_title;
> +            }
> +
> +            vlc_mutex_unlock( &p_input->p->p_item->lock );
> +
> +            return VLC_SUCCESS;
> +        }
> +
>          case INPUT_GET_VIDEO_FPS:
>              pf = (double*)va_arg( args, double * );
>  
> -- 
> 2.3.2
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel

Regards,

-- 
  Hugo Beauzée-Luyssen
  hugo at beauzee.fr



More information about the vlc-devel mailing list