Commit b7ea5260 authored by Thomas Guillem's avatar Thomas Guillem

libvlc: media: add slaves API

parent d12a46f3
......@@ -271,6 +271,26 @@ typedef enum libvlc_media_parsed_status_t
libvlc_media_parse_done,
} 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.
*
......@@ -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
......
......@@ -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
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment