[vlc-commits] libvlc: media_player: add program API
Thomas Guillem
git at videolan.org
Fri Oct 30 13:37:32 CET 2020
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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",
More information about the vlc-commits
mailing list