From: Martin Storsjö Date: Tue, 12 Feb 2013 20:45:25 +0000 (+0200) Subject: libvlc: Add a new more extensible struct libvlc_media_track_t X-Git-Tag: 2.1.0-git~1289 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=cd5345a00009f2fc571c23509a025331ad24fc87;p=vlc libvlc: Add a new more extensible struct libvlc_media_track_t Due to the way this struct is allocated, it can be extended later without breaking ABI. Signed-off-by: Rémi Denis-Courmont --- diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h index 7e610396db..92016b7502 100644 --- a/include/vlc/libvlc_media.h +++ b/include/vlc/libvlc_media.h @@ -170,6 +170,52 @@ typedef struct libvlc_media_track_info_t } libvlc_media_track_info_t; +typedef struct libvlc_audio_track_t +{ + unsigned i_channels; + unsigned i_rate; +} libvlc_audio_track_t; + +typedef struct libvlc_video_track_t +{ + unsigned i_height; + unsigned i_width; + unsigned i_sar_num; + unsigned i_sar_den; + unsigned i_frame_rate_num; + unsigned i_frame_rate_den; +} libvlc_video_track_t; + +typedef struct libvlc_subtitle_track_t +{ + char *psz_encoding; +} libvlc_subtitle_track_t; + +typedef struct libvlc_media_track_t +{ + /* Codec fourcc */ + uint32_t i_codec; + uint32_t i_original_fourcc; + int i_id; + libvlc_track_type_t i_type; + + /* Codec specific */ + int i_profile; + int i_level; + + union { + libvlc_audio_track_t *audio; + libvlc_video_track_t *video; + libvlc_subtitle_track_t *subtitle; + }; + + unsigned int i_bitrate; + char *psz_language; + char *psz_description; + +} libvlc_media_track_t; + + /** * Create a media with a certain given media resource location, * for instance a valid URL. @@ -503,16 +549,51 @@ LIBVLC_API void *libvlc_media_get_user_data( libvlc_media_t *p_md ); * before calling this function. * Not doing this will result in an empty array. * + * \deprecated Use libvlc_media_tracks_get instead + * * \param p_md media descriptor object * \param tracks address to store an allocated array of Elementary Streams * descriptions (must be freed by the caller) [OUT] * * \return the number of Elementary Streams */ -LIBVLC_API +LIBVLC_DEPRECATED LIBVLC_API int libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t **tracks ); +/** + * Get media descriptor's elementary streams description + * + * Note, you need to call libvlc_media_parse() or play the media at least once + * before calling this function. + * Not doing this will result in an empty array. + * + * \version LibVLC 2.1.0 and later. + * + * \param p_md media descriptor object + * \param tracks address to store an allocated array of Elementary Streams + * descriptions (must be freed with libvlc_media_tracks_release + by the caller) [OUT] + * + * \return the number of Elementary Streams + */ +LIBVLC_API +int libvlc_media_tracks_get( libvlc_media_t *p_md, + libvlc_media_track_t ***tracks ); + + +/** + * Release media descriptor's elementary streams description array + * + * \version LibVLC 2.1.0 and later. + * + * \param p_tracks tracks info array to release + * \param i_count number of elements in the array + */ +LIBVLC_API +void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks, + int i_count ); + /** @}*/ # ifdef __cplusplus diff --git a/lib/libvlc.sym b/lib/libvlc.sym index 42dad5cf9f..c3cc58041a 100644 --- a/lib/libvlc.sym +++ b/lib/libvlc.sym @@ -168,6 +168,8 @@ libvlc_media_set_meta libvlc_media_set_state libvlc_media_set_user_data libvlc_media_subitems +libvlc_media_tracks_get +libvlc_media_tracks_release libvlc_new libvlc_playlist_play libvlc_release diff --git a/lib/media.c b/lib/media.c index 600e10a01e..d7d087231b 100644 --- a/lib/media.c +++ b/lib/media.c @@ -734,3 +734,116 @@ libvlc_media_get_tracks_info( libvlc_media_t *p_md, libvlc_media_track_info_t ** vlc_mutex_unlock( &p_input_item->lock ); return i_es; } + +int +libvlc_media_tracks_get( libvlc_media_t *p_md, libvlc_media_track_t *** pp_es ) +{ + assert( p_md ); + + input_item_t *p_input_item = p_md->p_input_item; + vlc_mutex_lock( &p_input_item->lock ); + + const int i_es = p_input_item->i_es; + *pp_es = (i_es > 0) ? calloc( i_es, sizeof(**pp_es) ) : NULL; + + if( !*pp_es ) /* no ES, or OOM */ + { + vlc_mutex_unlock( &p_input_item->lock ); + return 0; + } + + /* Fill array */ + for( int i = 0; i < i_es; i++ ) + { + libvlc_media_track_t *p_mes = calloc( 1, sizeof(*p_mes) ); + if ( p_mes ) + { + p_mes->audio = malloc( __MAX(__MAX(sizeof(*p_mes->audio), + sizeof(*p_mes->video)), + sizeof(*p_mes->subtitle)) ); + } + if ( !p_mes || !p_mes->audio ) + { + libvlc_media_tracks_release( *pp_es, i_es ); + *pp_es = NULL; + return 0; + } + (*pp_es)[i] = p_mes; + + const es_format_t *p_es = p_input_item->es[i]; + + p_mes->i_codec = p_es->i_codec; + p_mes->i_original_fourcc = p_es->i_original_fourcc; + p_mes->i_id = p_es->i_id; + + p_mes->i_profile = p_es->i_profile; + p_mes->i_level = p_es->i_level; + + p_mes->i_bitrate = p_es->i_bitrate; + p_mes->psz_language = p_es->psz_language != NULL ? strdup(p_es->psz_language) : NULL; + p_mes->psz_description = p_es->psz_description != NULL ? strdup(p_es->psz_description) : NULL; + + switch(p_es->i_cat) + { + case UNKNOWN_ES: + default: + p_mes->i_type = libvlc_track_unknown; + break; + case VIDEO_ES: + p_mes->i_type = libvlc_track_video; + p_mes->video->i_height = p_es->video.i_height; + p_mes->video->i_width = p_es->video.i_width; + p_mes->video->i_sar_num = p_es->video.i_sar_num; + p_mes->video->i_sar_den = p_es->video.i_sar_den; + p_mes->video->i_frame_rate_num = p_es->video.i_frame_rate; + p_mes->video->i_frame_rate_den = p_es->video.i_frame_rate_base; + break; + case AUDIO_ES: + p_mes->i_type = libvlc_track_audio; + p_mes->audio->i_channels = p_es->audio.i_channels; + p_mes->audio->i_rate = p_es->audio.i_rate; + break; + case SPU_ES: + p_mes->i_type = libvlc_track_text; + p_mes->subtitle->psz_encoding = p_es->subs.psz_encoding != NULL ? + strdup(p_es->subs.psz_encoding) : NULL; + break; + } + } + + vlc_mutex_unlock( &p_input_item->lock ); + return i_es; +} + + +/************************************************************************** + * Release media descriptor's elementary streams description array + **************************************************************************/ +void libvlc_media_tracks_release( libvlc_media_track_t **p_tracks, int i_count ) +{ + if( !p_tracks ) + return; + for( int i = 0; i < i_count; ++i ) + { + if ( !p_tracks[i] ) + continue; + free( p_tracks[i]->psz_language ); + free( p_tracks[i]->psz_description ); + switch( p_tracks[i]->i_type ) + { + case libvlc_track_audio: + break; + case libvlc_track_video: + break; + case libvlc_track_text: + free( p_tracks[i]->subtitle->psz_encoding ); + break; + case libvlc_track_unknown: + default: + break; + } + free( p_tracks[i]->audio ); + free( p_tracks[i] ); + } + free( p_tracks ); +}