vlc | branch: master | Thomas Guillem <[email protected]> | Tue May 17 17:33:32 2016 +0200| [b7ea52605bac816993743f41b281d502b0a52953] | committer: Thomas Guillem
libvlc: media: add slaves API > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b7ea52605bac816993743f41b281d502b0a52953 --- include/vlc/libvlc_media.h | 89 +++++++++++++++++++++++++++ lib/libvlc.sym | 4 ++ lib/media.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h index ed5090d..d05f642 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,75 @@ 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) + * + * \return 0 on success, -1 on error. + */ +LIBVLC_API +int libvlc_media_slaves_add( libvlc_media_t *p_md, + libvlc_media_slave_type_t i_type, + unsigned int i_priority, + const char *psz_uri ); + +/** + * 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..5a52cb1 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, + libvlc_media_slave_type_t i_type, + unsigned int i_priority, + const char *psz_uri ) +{ + 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_t *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_t *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); +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
