[vlc-devel] [RFC PATCHv2 05/10] lib: add libvlc_media_get_tracklist()

Thomas Guillem thomas at gllm.fr
Thu Jun 4 23:23:20 CEST 2020


---
 include/vlc/libvlc_media.h | 23 +++++++++++++++++++
 lib/libvlc.sym             |  1 +
 lib/media.c                | 16 +++++++++++++
 lib/media_internal.h       |  5 ++++
 lib/media_track.c          | 47 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 92 insertions(+)

diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index 9ed688f935..78883d9946 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -661,6 +661,29 @@ LIBVLC_API
 unsigned libvlc_media_tracks_get( libvlc_media_t *p_md,
                                   libvlc_media_track_t ***tracks );
 
+/**
+ * Get the track list for one type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \note You need to call libvlc_media_parse_with_options() or play the media
+ * at least once before calling this function.  Not doing this will result in
+ * an empty list.
+ *
+ * \see libvlc_media_parse_with_options
+ * \see libvlc_media_tracklist_count
+ * \see libvlc_media_tracklist_at
+ *
+ * \param p_md media descriptor object
+ * \param type type of the track list to request
+ *
+ * \return a valid libvlc_media_tracklist_t or NULL in case of error, if there
+ * is no track for a category, the returned list will have a size of 0, delete
+ * with libvlc_media_tracklist_release()
+ */
+LIBVLC_API libvlc_media_tracklist_t *
+libvlc_media_get_tracklist( libvlc_media_t *p_md, libvlc_track_type_t type );
+
 /**
  * Get codec description from media elementary stream
  *
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 9ccab493a5..a3217c5750 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -77,6 +77,7 @@ libvlc_media_get_meta
 libvlc_media_get_mrl
 libvlc_media_get_state
 libvlc_media_get_stats
+libvlc_media_get_tracklist
 libvlc_media_get_type
 libvlc_media_get_user_data
 libvlc_media_is_parsed
diff --git a/lib/media.c b/lib/media.c
index 8d663bc48b..e25d439a8a 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -895,6 +895,22 @@ libvlc_media_tracks_get( libvlc_media_t *p_md, libvlc_media_track_t *** pp_es )
     return i_es;
 }
 
+libvlc_media_tracklist_t *
+libvlc_media_get_tracklist( libvlc_media_t *p_md, libvlc_track_type_t type )
+{
+    assert( p_md );
+
+    input_item_t *p_input_item = p_md->p_input_item;
+
+    vlc_mutex_lock( &p_input_item->lock );
+    libvlc_media_tracklist_t *list =
+        libvlc_media_tracklist_from_es_array( p_input_item->es,
+                                              p_input_item->i_es, type );
+    vlc_mutex_unlock( &p_input_item->lock );
+
+    return list;
+}
+
 // Get codec description from media elementary stream
 const char *
 libvlc_media_get_codec_description( libvlc_track_type_t i_type,
diff --git a/lib/media_internal.h b/lib/media_internal.h
index 2aa944806a..24bedfb405 100644
--- a/lib/media_internal.h
+++ b/lib/media_internal.h
@@ -87,6 +87,11 @@ void
 libvlc_media_trackpriv_from_es( libvlc_media_trackpriv_t *trackpriv,
                                 const es_format_t *es  );
 
+libvlc_media_tracklist_t *
+libvlc_media_tracklist_from_es_array( es_format_t **es_array,
+                                      size_t es_count,
+                                      libvlc_track_type_t type );
+
 void
 libvlc_media_track_clean( libvlc_media_track_t *track );
 
diff --git a/lib/media_track.c b/lib/media_track.c
index 3a3c4abc7e..a6c364a4e5 100644
--- a/lib/media_track.c
+++ b/lib/media_track.c
@@ -125,6 +125,53 @@ libvlc_media_track_clean( libvlc_media_track_t *track )
     }
 }
 
+static libvlc_media_tracklist_t *
+libvlc_media_tracklist_alloc( size_t count )
+{
+    size_t size;
+    if( mul_overflow( count, sizeof(libvlc_media_trackpriv_t), &size) )
+        return NULL;
+    if( add_overflow( size, sizeof(libvlc_media_tracklist_t), &size) )
+        return NULL;
+
+    libvlc_media_tracklist_t *list = malloc( size );
+    if( list == NULL )
+        return NULL;
+
+    list->count = count;
+    return list;
+}
+
+libvlc_media_tracklist_t *
+libvlc_media_tracklist_from_es_array( es_format_t **es_array,
+                                      size_t es_count,
+                                      libvlc_track_type_t type )
+{
+    size_t count = 0;
+    const enum es_format_category_e cat = libvlc_track_type_to_escat( type );
+
+    for( size_t i = 0; i < es_count; ++i )
+    {
+        if( es_array[i]->i_cat == cat )
+            count++;
+    }
+
+    libvlc_media_tracklist_t *list = libvlc_media_tracklist_alloc( count );
+
+    if( count == 0 )
+        return list;
+
+    count = 0;
+    for( size_t i = 0; i < es_count; ++i )
+    {
+        if( es_array[i]->i_cat == cat )
+            libvlc_media_trackpriv_from_es( &list->tracks[count++],
+                                            es_array[i] );
+    }
+
+    return list;
+}
+
 size_t
 libvlc_media_tracklist_count( const libvlc_media_tracklist_t *list )
 {
-- 
2.20.1



More information about the vlc-devel mailing list