[vlc-devel] [PATCH 4/6] lib: media_track: add a refcount

Thomas Guillem thomas at gllm.fr
Mon Jun 15 23:10:05 CEST 2020


libvlc_media_track_hold() can be used in order to have a track outliving the
tracklist.
---
 include/vlc/libvlc_media_track.h | 26 +++++++++++++++++++++-----
 lib/libvlc.sym                   |  1 +
 lib/media_internal.h             |  2 ++
 lib/media_track.c                | 29 +++++++++++++++++++----------
 4 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/include/vlc/libvlc_media_track.h b/include/vlc/libvlc_media_track.h
index 46bbbaf4bd6..f1da2478714 100644
--- a/include/vlc/libvlc_media_track.h
+++ b/include/vlc/libvlc_media_track.h
@@ -202,17 +202,33 @@ libvlc_media_tracklist_at( libvlc_media_tracklist_t *list, size_t index );
 LIBVLC_API void
 libvlc_media_tracklist_delete( libvlc_media_tracklist_t *list );
 
+
+/**
+ * Hold a single track reference
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * This function can be used to hold a track from a tracklist. In that case,
+ * the track can outlive its tracklist.
+ *
+ * \param track valid track
+ * \return the same track, need to be released with libvlc_media_track_release()
+ */
+LIBVLC_API libvlc_media_track_t *
+libvlc_media_track_hold( libvlc_media_track_t * );
+
 /**
  * Release a single track
  *
  * \version LibVLC 4.0.0 and later.
  *
- * \warning Don't release tracks from a tracklist with this function. Tracks
- * from a tracklist are released alongside the list with
- * libvlc_media_tracklist_delete()
+ * \warning Tracks from a tracklist are released alongside the list with
+ * libvlc_media_tracklist_delete().
  *
- * \see libvlc_media_player_get_selected_track
- * \see libvlc_media_player_get_track_from_id
+ * \note You only need to release tracks previously held with
+ * libvlc_media_track_hold() or returned by
+ * libvlc_media_player_get_selected_track() and
+ * libvlc_media_player_get_track_from_id()
  *
  * \param track valid track
  */
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 739f7d444e8..3753ddb89be 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -86,6 +86,7 @@ libvlc_media_thumbnail_request_by_time
 libvlc_media_thumbnail_request_by_pos
 libvlc_media_thumbnail_request_cancel
 libvlc_media_thumbnail_request_destroy
+libvlc_media_track_hold
 libvlc_media_track_release
 libvlc_media_tracklist_at
 libvlc_media_tracklist_count
diff --git a/lib/media_internal.h b/lib/media_internal.h
index 8acb116e8fe..5f43a2b3de4 100644
--- a/lib/media_internal.h
+++ b/lib/media_internal.h
@@ -30,6 +30,7 @@
 #include <vlc_common.h>
 #include <vlc_input.h>
 #include <vlc_player.h>
+#include <vlc_atomic.h>
 
 struct libvlc_media_t
 {
@@ -83,6 +84,7 @@ typedef struct libvlc_media_trackpriv_t
         libvlc_subtitle_track_t subtitle;
     };
     vlc_es_id_t *es_id;
+    vlc_atomic_rc_t rc;
 } libvlc_media_trackpriv_t;
 
 static inline const libvlc_media_trackpriv_t *
diff --git a/lib/media_track.c b/lib/media_track.c
index 515970a5319..bca82f384b6 100644
--- a/lib/media_track.c
+++ b/lib/media_track.c
@@ -119,6 +119,7 @@ libvlc_media_trackpriv_new( void )
         return NULL;
 
     trackpriv->es_id = NULL;
+    vlc_atomic_rc_init( &trackpriv->rc );
     return trackpriv;
 }
 
@@ -143,15 +144,28 @@ libvlc_media_track_clean( libvlc_media_track_t *track )
     }
 }
 
+libvlc_media_track_t *
+libvlc_media_track_hold( libvlc_media_track_t *track )
+{
+    libvlc_media_trackpriv_t *trackpriv =
+        container_of( track, libvlc_media_trackpriv_t, t );
+    vlc_atomic_rc_inc( &trackpriv->rc );
+    return track;
+}
+
 void
 libvlc_media_track_release( libvlc_media_track_t *track )
 {
     libvlc_media_trackpriv_t *trackpriv =
         container_of( track, libvlc_media_trackpriv_t, t );
-    libvlc_media_track_clean( track );
-    if( trackpriv->es_id )
-        vlc_es_id_Release( trackpriv->es_id );
-    free( trackpriv );
+
+    if( vlc_atomic_rc_dec( &trackpriv->rc ) )
+    {
+        libvlc_media_track_clean( track );
+        if( trackpriv->es_id )
+            vlc_es_id_Release( trackpriv->es_id );
+        free( trackpriv );
+    }
 }
 
 static libvlc_media_tracklist_t *
@@ -282,12 +296,7 @@ libvlc_media_tracklist_delete( libvlc_media_tracklist_t *list )
     for( size_t i = 0; i < list->count; ++i )
     {
         libvlc_media_trackpriv_t *trackpriv = list->tracks[i];
-        libvlc_media_track_clean( &trackpriv->t );
-
-        if( trackpriv->es_id != NULL )
-            vlc_es_id_Release( trackpriv->es_id );
-
-        free( trackpriv );
+        libvlc_media_track_release( &trackpriv->t );
     }
     free( list );
 }
-- 
2.20.1



More information about the vlc-devel mailing list