vlc | branch: master | Thomas Guillem <[email protected]> | Thu Oct 1 11:25:07 2020 +0200| [2d9504539027b42728a47b94826808b2c1da41a7] | committer: Thomas Guillem
libvlc: media_player: add program API Add events, selection, and list API. Like the for the media track list, this API use an opaque structure libvlc_player_programlist_t to iterate through all programs. This avoid the usage of *** from a public API. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2d9504539027b42728a47b94826808b2c1da41a7 --- include/vlc/libvlc_events.h | 17 ++++ include/vlc/libvlc_media_player.h | 131 +++++++++++++++++++++++++ lib/libvlc.sym | 8 ++ lib/media_player.c | 196 +++++++++++++++++++++++++++++++++----- 4 files changed, 329 insertions(+), 23 deletions(-) diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h index 5cd545097e..073e06893e 100644 --- a/include/vlc/libvlc_events.h +++ b/include/vlc/libvlc_events.h @@ -129,6 +129,10 @@ enum libvlc_event_e { /** A track was updated, cf. media_player_es_changed in \ref * libvlc_event_t.u to get the id of the updated track. */ libvlc_MediaPlayerESUpdated, + libvlc_MediaPlayerProgramAdded, + libvlc_MediaPlayerProgramDeleted, + libvlc_MediaPlayerProgramSelected, + libvlc_MediaPlayerProgramUpdated, /** * The title list changed, call * libvlc_media_player_get_full_title_descriptions() to get the new list. @@ -370,6 +374,19 @@ typedef struct libvlc_event_t const char *psz_selected_id; } media_player_es_selection_changed; + /* ProgramAdded, ProgramDeleted, ProgramUpdated */ + struct + { + int i_id; + } media_player_program_changed; + + /* ProgramSelected */ + struct + { + int i_unselected_id; + int i_selected_id; + } media_player_program_selection_changed; + struct { float volume; diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h index 8f6447574c..c6056c76ef 100644 --- a/include/vlc/libvlc_media_player.h +++ b/include/vlc/libvlc_media_player.h @@ -1461,6 +1461,137 @@ int libvlc_media_player_add_slave( libvlc_media_player_t *p_mi, libvlc_media_slave_type_t i_type, const char *psz_uri, bool b_select ); +typedef struct libvlc_player_program_t +{ + /** Id used for libvlc_media_player_select_program() */ + int i_group_id; + /** Program name, always valid */ + char *psz_name; + /** True if the program is selected */ + bool b_selected; + /** True if the program is scrambled */ + bool b_scrambled; +} libvlc_player_program_t; + +/** + * Opaque struct containing a list of program + */ +typedef struct libvlc_player_programlist_t libvlc_player_programlist_t; + +/** + * Delete a program struct + * + * \version LibVLC 4.0.0 and later. + * + * \param program returned by libvlc_media_player_get_selected_program() or + * libvlc_media_player_get_program_from_id() + * + */ +LIBVLC_API void +libvlc_player_program_delete( libvlc_player_program_t *program ); + +/** + * Get the number of programs in a programlist + * + * \version LibVLC 4.0.0 and later. + * + * \param list valid programlist + * + * \return number of programs, or 0 if the list is empty + */ +LIBVLC_API size_t +libvlc_player_programlist_count( const libvlc_player_programlist_t *list ); + +/** + * Get a program at a specific index + * + * \warning The behaviour is undefined if the index is not valid. + * + * \version LibVLC 4.0.0 and later. + * + * \param list valid programlist + * \param index valid index in the range [0; count[ + * + * \return a valid program (can't be NULL if libvlc_player_programlist_count() + * returned a valid count) + */ +LIBVLC_API libvlc_player_program_t * +libvlc_player_programlist_at( libvlc_player_programlist_t *list, size_t index ); + +/** + * Release a programlist + * + * \version LibVLC 4.0.0 and later. + * + * \see libvlc_media_get_programlist + * \see libvlc_media_player_get_programlist + * + * \param list valid programlist + */ +LIBVLC_API void +libvlc_player_programlist_delete( libvlc_player_programlist_t *list ); + +/** + * Select program with a given program id. + * + * \note program ids are sent via the libvlc_MediaPlayerProgramAdded event or + * can be fetch via libvlc_media_player_get_programlist() + * + * \version LibVLC 4.0.0 or later + * + * \param p_mi opaque media player handle + * \param program_id + */ +LIBVLC_API void libvlc_media_player_select_program_id( libvlc_media_player_t *p_mi, int program_id); + +/** + * Get the selected program + * + * \version LibVLC 4.0.0 or later + * + * \param p_mi opaque media player handle + * + * \return a valid program struct or NULL if no programs are selected. The + * program need to be freed with libvlc_player_program_delete(). + */ +LIBVLC_API libvlc_player_program_t * +libvlc_media_player_get_selected_program( libvlc_media_player_t *p_mi); + +/** + * Get a program struct from a program id + * + * \version LibVLC 4.0.0 or later + * + * \param p_mi opaque media player handle + * \param i_group_id program id + * + * \return a valid program struct or NULL if the group_id is not found. The + * program need to be freed with libvlc_player_program_delete(). + */ +LIBVLC_API libvlc_player_program_t * +libvlc_media_player_get_program_from_id( libvlc_media_player_t *p_mi, int i_group_id ); + +/** + * Get the program list + * + * \version LibVLC 4.0.0 and later. + * \note This program list is a snapshot of the current programs when this + * function is called. If a program is updated after this call, the user will + * need to call this function again to get the updated program. + * + * The program list can be used to get program informations and to select + * specific programs. + * + * \param p_mi the media player + * \param type type of the program list to request + * + * \return a valid libvlc_media_programlist_t or NULL in case of error or empty + * list, delete with libvlc_media_programlist_delete() + */ +LIBVLC_API libvlc_player_programlist_t * +libvlc_media_player_get_programlist( libvlc_media_player_t *p_mi ); + + /** \defgroup libvlc_video LibVLC video controls * @{ */ diff --git a/lib/libvlc.sym b/lib/libvlc.sym index ea3e886dbb..ebdd2db629 100644 --- a/lib/libvlc.sym +++ b/lib/libvlc.sym @@ -190,6 +190,14 @@ libvlc_media_player_select_track libvlc_media_player_unselect_track_type libvlc_media_player_select_tracks libvlc_media_player_select_tracks_by_ids +libvlc_player_program_delete +libvlc_player_programlist_count +libvlc_player_programlist_at +libvlc_player_programlist_delete +libvlc_media_player_select_program_id +libvlc_media_player_get_selected_program +libvlc_media_player_get_program_from_id +libvlc_media_player_get_programlist libvlc_media_release libvlc_media_retain libvlc_media_save_meta diff --git a/lib/media_player.c b/lib/media_player.c index 7fcb8ba483..d74f3be3de 100644 --- a/lib/media_player.c +++ b/lib/media_player.c @@ -290,20 +290,24 @@ on_program_list_changed(vlc_player_t *player, enum vlc_player_list_action action, const struct vlc_player_program *prgm, void* data) { - (void) action; - (void) prgm; - + (void) player; libvlc_media_player_t *mp = data; - const struct vlc_player_program *selected = - vlc_player_GetSelectedProgram(player); - if (!selected) - return; - libvlc_event_t event; - event.type = libvlc_MediaPlayerScrambledChanged; - event.u.media_player_scrambled_changed.new_scrambled = selected->scrambled; + switch (action) + { + case VLC_PLAYER_LIST_ADDED: + event.type = libvlc_MediaPlayerProgramAdded; + break; + case VLC_PLAYER_LIST_REMOVED: + event.type = libvlc_MediaPlayerProgramDeleted; + break; + case VLC_PLAYER_LIST_UPDATED: + event.type = libvlc_MediaPlayerProgramUpdated; + break; + } + event.u.media_player_program_changed.i_id = prgm->group_id; libvlc_event_send(&mp->event_manager, &event); } @@ -311,22 +315,13 @@ static void on_program_selection_changed(vlc_player_t *player, int unselected_id, int selected_id, void *data) { - (void) unselected_id; - + (void) player; libvlc_media_player_t *mp = data; - if (selected_id == -1) - return; - - const struct vlc_player_program *program = - vlc_player_GetSelectedProgram(player); - - if (unlikely(program == NULL)) /* can happen when the player is stopping */ - return; - libvlc_event_t event; - event.type = libvlc_MediaPlayerScrambledChanged; - event.u.media_player_scrambled_changed.new_scrambled = program->scrambled; + event.type = libvlc_MediaPlayerProgramSelected; + event.u.media_player_program_selection_changed.i_unselected_id = unselected_id; + event.u.media_player_program_selection_changed.i_selected_id = selected_id; libvlc_event_send(&mp->event_manager, &event); } @@ -2023,6 +2018,161 @@ int libvlc_media_player_set_equalizer( libvlc_media_player_t *p_mi, libvlc_equal return 0; } + +static libvlc_player_program_t * +libvlc_player_program_new(const struct vlc_player_program *program) +{ + libvlc_player_program_t *libprogram = malloc(sizeof(*libprogram)); + if (libprogram == NULL) + return NULL; + + libprogram->i_group_id = program->group_id; + libprogram->psz_name = strdup(program->name); + libprogram->b_selected = program->selected; + libprogram->b_scrambled = program->scrambled; + + return libprogram; +} + +void +libvlc_player_program_delete( libvlc_player_program_t *program ) +{ + free( program->psz_name ); + free( program ); +} + +void libvlc_media_player_select_program_id( libvlc_media_player_t *p_mi, + int program_id) +{ + vlc_player_t *player = p_mi->player; + + vlc_player_Lock(player); + + vlc_player_SelectProgram(player, program_id); + + vlc_player_Unlock(player); +} + +libvlc_player_program_t * +libvlc_media_player_get_selected_program( libvlc_media_player_t *p_mi) +{ + vlc_player_t *player = p_mi->player; + + vlc_player_Lock(player); + + const struct vlc_player_program *program = vlc_player_GetSelectedProgram( player ); + if( program == NULL ) + { + vlc_player_Unlock(player); + return NULL; + } + libvlc_player_program_t *libprogram = libvlc_player_program_new(program); + + vlc_player_Unlock(player); + + return libprogram; +} + +libvlc_player_program_t * +libvlc_media_player_get_program_from_id( libvlc_media_player_t *p_mi, int i_group_id ) +{ + vlc_player_t *player = p_mi->player; + + vlc_player_Lock(player); + + libvlc_player_program_t *libprogram = NULL; + + size_t count = vlc_player_GetProgramCount(player); + for (size_t i = 0; i < count; ++i) + { + const struct vlc_player_program *program = + vlc_player_GetProgramAt(player, i); + assert(program); + if (program->group_id == i_group_id) + { + libprogram = libvlc_player_program_new(program); + break; + } + } + + vlc_player_Unlock(player); + + return libprogram; +} + +struct libvlc_player_programlist_t +{ + size_t count; + libvlc_player_program_t *programs[]; +}; + +size_t +libvlc_player_programlist_count( const libvlc_player_programlist_t *list ) +{ + return list->count; +} + +libvlc_player_program_t * +libvlc_player_programlist_at( libvlc_player_programlist_t *list, size_t index ) +{ + assert(index < list->count); + return list->programs[index]; +} + +void +libvlc_player_programlist_delete( libvlc_player_programlist_t *list ) +{ + for (size_t i = 0; i < list->count; ++i) + libvlc_player_program_delete(list->programs[i]); + free(list); +} + +libvlc_player_programlist_t * +libvlc_media_player_get_programlist( libvlc_media_player_t *p_mi ) +{ + vlc_player_t *player = p_mi->player; + + vlc_player_Lock(player); + + size_t count = vlc_player_GetProgramCount(player); + if (count == 0) + goto error; + + size_t size; + if( mul_overflow( count, sizeof(libvlc_player_program_t *), &size) ) + goto error; + if( add_overflow( size, sizeof(libvlc_player_programlist_t), &size) ) + goto error; + + libvlc_player_programlist_t *list = malloc( size ); + if( list == NULL ) + goto error; + + list->count = 0; + for (size_t i = 0; i < count; ++i) + { + const struct vlc_player_program *program = + vlc_player_GetProgramAt(player, i); + assert(program); + list->programs[i] = libvlc_player_program_new(program); + if (list->programs[i] == NULL) + { + libvlc_player_programlist_delete(list); + goto error; + } + + list->count++; + } + + vlc_player_Unlock(player); + + return list; + +error: + vlc_player_Unlock(player); + return NULL; +} + static const char roles[][16] = { [libvlc_role_Music] = "music", _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
