[vlc-devel] [PATCHv3 13/13] libvlc: media: add slaves API

Thomas Guillem thomas at gllm.fr
Tue May 17 18:24:47 CEST 2016


---
 include/vlc/libvlc_media.h |  87 +++++++++++++++++++++++++++
 lib/libvlc.sym             |   4 ++
 lib/media.c                | 144 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 235 insertions(+)

diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index ed5090d..9cedfec 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -272,6 +272,26 @@ typedef enum libvlc_media_parsed_status_t
 } libvlc_media_parsed_status_t;
 
 /**
+ * Type of a media slave: subtitle or audio.
+ */
+typedef enum
+{
+    libvlc_media_slave_type_subtitle,
+    libvlc_media_slave_type_audio,
+} libvlc_media_slave_type_t;
+
+/**
+ * A slave of a libvlc_media_t
+ * \see libvlc_media_slaves_get
+ */
+typedef struct
+{
+    libvlc_media_slave_type_t       i_type;
+    unsigned int                    i_priority;
+    char                            psz_uri[];
+} libvlc_media_slave_t;
+
+/**
  * Callback prototype to open a custom bitstream input media.
  *
  * The same media item can be opened multiple times. Each time, this callback
@@ -753,6 +773,73 @@ void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks,
 LIBVLC_API
 libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md );
 
+/**
+ * Add a slave to the current media.
+ *
+ * A slave is an external input source that may contains an additional subtitle
+ * track (like a .srt) or an additional audio track (like a .ac3).
+ *
+ * \note This function must be called before the media is parsed (via
+ * libvlc_media_parse_with_options()) or before the media is played (via
+ * libvlc_media_player_play())
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_md media descriptor object
+ * \param psz_uri Uri of the slave (should contain a valid scheme).
+ * \param i_type subtitle or audio
+ * \param i_priority from 0 (low priority) to 4 (high priority)
+ */
+LIBVLC_API
+int libvlc_media_slaves_add( libvlc_media_t *p_md,
+                             const char *psz_uri,
+                             libvlc_media_slave_type_t i_type,
+                             unsigned int i_priority );
+
+/**
+ * Clear all slaves previously added by libvlc_media_slaves_add() or
+ * internally.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_md media descriptor object
+ */
+LIBVLC_API
+void libvlc_media_slaves_clear( libvlc_media_t *p_md );
+
+/**
+ * Get a media descriptor's slave list
+ *
+ * The list will contain slaves parsed by VLC or previously added by
+ * libvlc_media_slaves_add(). The typical use case of this function is to save
+ * a list of slave in a database for a later use.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_slaves_add
+ *
+ * \param p_md media descriptor object
+ * \param ppp_slaves address to store an allocated array of slaves (must be
+ * freed with libvlc_media_slaves_release()) [OUT]
+ *
+ * \return the number of slaves (zero on error)
+ */
+LIBVLC_API
+unsigned int libvlc_media_slaves_get( libvlc_media_t *p_md,
+                                      libvlc_media_slave_t ***ppp_slaves );
+
+/**
+ * Release a media descriptor's slave list
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param pp_slaves slave array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API
+void libvlc_media_slaves_release( libvlc_media_slave_t **pp_slaves,
+                                  unsigned int i_count );
+
 /** @}*/
 
 # ifdef __cplusplus
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index c134fef..816025d 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -202,6 +202,10 @@ libvlc_media_player_set_video_title_display
 libvlc_media_release
 libvlc_media_retain
 libvlc_media_save_meta
+libvlc_media_slaves_add
+libvlc_media_slaves_clear
+libvlc_media_slaves_get
+libvlc_media_slaves_release
 libvlc_media_set_meta
 libvlc_media_set_state
 libvlc_media_set_user_data
diff --git a/lib/media.c b/lib/media.c
index 32379a1..6412f10 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -1096,3 +1096,147 @@ libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md )
         return libvlc_media_type_unknown;
     }
 }
+
+int libvlc_media_slaves_add( libvlc_media_t *p_md,
+                             const char *psz_uri,
+                             libvlc_media_slave_type_t i_type,
+                             unsigned int i_priority )
+{
+    assert( p_md && psz_uri );
+    input_item_t *p_input_item = p_md->p_input_item;
+
+    enum slave_type i_input_slave_type;
+    switch( i_type )
+    {
+    case libvlc_media_slave_type_subtitle:
+        i_input_slave_type = SLAVE_TYPE_SPU;
+        break;
+    case libvlc_media_slave_type_audio:
+        i_input_slave_type = SLAVE_TYPE_AUDIO;
+    default:
+        vlc_assert_unreachable();
+        return -1;
+    }
+
+    enum slave_priority i_input_slave_priority;
+    switch( i_priority )
+    {
+    case 0:
+        i_input_slave_priority = SLAVE_PRIORITY_MATCH_NONE;
+        break;
+    case 1:
+        i_input_slave_priority = SLAVE_PRIORITY_MATCH_RIGHT;
+        break;
+    case 2:
+        i_input_slave_priority = SLAVE_PRIORITY_MATCH_LEFT;
+        break;
+    case 3:
+        i_input_slave_priority = SLAVE_PRIORITY_MATCH_ALL;
+        break;
+    default:
+    case 4:
+        i_input_slave_priority = SLAVE_PRIORITY_USER;
+        break;
+    }
+
+    input_item_slave *p_slave = input_item_slave_New( psz_uri,
+                                                      i_input_slave_type,
+                                                      i_input_slave_priority );
+    if( p_slave == NULL )
+        return -1;
+    return input_item_AddSlave( p_input_item, p_slave ) == VLC_SUCCESS ? 0 : -1;
+}
+
+void libvlc_media_slaves_clear( libvlc_media_t *p_md )
+{
+    assert( p_md );
+    input_item_t *p_input_item = p_md->p_input_item;
+
+    vlc_mutex_lock( &p_input_item->lock );
+    for( int i = 0; i < p_input_item->i_slaves; i++ )
+        input_item_slave_Delete( p_input_item->pp_slaves[i] );
+    TAB_CLEAN( p_input_item->i_slaves, p_input_item->pp_slaves );
+    vlc_mutex_unlock( &p_input_item->lock );
+}
+
+unsigned int libvlc_media_slaves_get( libvlc_media_t *p_md,
+                                      libvlc_media_slave_t ***ppp_slaves )
+{
+    assert( p_md && ppp_slaves );
+    input_item_t *p_input_item = p_md->p_input_item;
+
+    vlc_mutex_lock( &p_input_item->lock );
+
+    int i_count = p_input_item->i_slaves;
+    if( i_count <= 0 )
+        return vlc_mutex_unlock( &p_input_item->lock ), 0;
+
+    libvlc_media_slave_t **pp_slaves = calloc( i_count, sizeof(*pp_slaves) );
+    if( pp_slaves == NULL )
+        return vlc_mutex_unlock( &p_input_item->lock ), 0;
+
+    for( int i = 0; i < i_count; ++i )
+    {
+        input_item_slave *p_item_slave = p_input_item->pp_slaves[i];
+        if( p_item_slave->i_priority == 0 )
+            continue;
+
+        libvlc_media_slave_t *p_slave = malloc( sizeof(*p_slave) +
+                                                strlen( p_item_slave->psz_uri )
+                                                + 1 );
+
+        if( p_slave == NULL )
+        {
+            libvlc_media_slaves_release(pp_slaves, i);
+            return vlc_mutex_unlock( &p_input_item->lock ), 0;
+        }
+        strcpy( p_slave->psz_uri, p_item_slave->psz_uri );
+
+        switch( p_item_slave->i_type )
+        {
+        case SLAVE_TYPE_SPU:
+            p_slave->i_type = libvlc_media_slave_type_subtitle;
+            break;
+        case SLAVE_TYPE_AUDIO:
+            p_slave->i_type = libvlc_media_slave_type_audio;
+            break;
+        default:
+            vlc_assert_unreachable();
+        }
+
+        switch( p_item_slave->i_priority )
+        {
+        case SLAVE_PRIORITY_MATCH_NONE:
+            p_slave->i_priority = 0;
+            break;
+        case SLAVE_PRIORITY_MATCH_RIGHT:
+            p_slave->i_priority = 1;
+            break;
+        case SLAVE_PRIORITY_MATCH_LEFT:
+            p_slave->i_priority = 2;
+            break;
+        case SLAVE_PRIORITY_MATCH_ALL:
+            p_slave->i_priority = 3;
+            break;
+        case SLAVE_PRIORITY_USER:
+            p_slave->i_priority = 4;
+            break;
+        default:
+            vlc_assert_unreachable();
+        }
+        pp_slaves[i] = p_slave;
+    }
+    vlc_mutex_unlock( &p_input_item->lock );
+
+    *ppp_slaves = pp_slaves;
+    return i_count;
+}
+
+void libvlc_media_slaves_release( libvlc_media_slave_t **pp_slaves,
+                                  unsigned int i_count )
+{
+    assert( pp_slaves );
+    for( unsigned int i = 0; i < i_count; ++i )
+        free(pp_slaves[i]);
+    free(pp_slaves);
+}
-- 
2.8.1



More information about the vlc-devel mailing list