X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcontrol%2Fmedia_descriptor.c;h=aef2b7ddd99f53f64364ecc637e7b05df9ca180c;hb=9e96ce01733f21e24b8b357dfd9096c92480edf9;hp=310ebaf97096db13e3529824e3933fc93c79d845;hpb=18f877f56271bbc0059aa39f5296cde96449362b;p=vlc diff --git a/src/control/media_descriptor.c b/src/control/media_descriptor.c index 310ebaf970..aef2b7ddd9 100644 --- a/src/control/media_descriptor.c +++ b/src/control/media_descriptor.c @@ -21,11 +21,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#include "libvlc_internal.h" + #include #include #include -#include "libvlc_internal.h" +/* For the preparser */ +#include static const vlc_meta_type_t libvlc_to_vlc_meta[] = { @@ -80,13 +83,16 @@ static void input_item_subitem_added( const vlc_event_t *p_event, libvlc_event_t event; p_md_child = libvlc_media_descriptor_new_from_input_item( - p_md->p_libvlc_instance, + p_md->p_libvlc_instance, p_event->u.input_item_subitem_added.p_new_child, NULL ); /* Add this to our media list */ if( !p_md->p_subitems ) + { p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance, NULL ); - if( !p_md->p_subitems ) + libvlc_media_list_set_media_descriptor( p_md->p_subitems, p_md, NULL ); + } + if( p_md->p_subitems ) { libvlc_media_list_add_media_descriptor( p_md->p_subitems, p_md_child, NULL ); } @@ -118,6 +124,41 @@ static void input_item_meta_changed( const vlc_event_t *p_event, libvlc_event_send( p_md->p_event_manager, &event ); } +/************************************************************************** + * input_item_duration_changed (Private) (vlc event Callback) + **************************************************************************/ +static void input_item_duration_changed( const vlc_event_t *p_event, + void * user_data ) +{ + libvlc_media_descriptor_t * p_md = user_data; + libvlc_event_t event; + + /* Construct the event */ + event.type = libvlc_MediaDescriptorDurationChanged; + event.u.media_descriptor_duration_changed.new_duration = + p_event->u.input_item_duration_changed.new_duration; + + /* Send the event */ + libvlc_event_send( p_md->p_event_manager, &event ); +} + +/************************************************************************** + * input_item_preparsed_changed (Private) (vlc event Callback) + **************************************************************************/ +static void input_item_preparsed_changed( const vlc_event_t *p_event, + void * user_data ) +{ + libvlc_media_descriptor_t * p_md = user_data; + libvlc_event_t event; + + /* Construct the event */ + event.type = libvlc_MediaDescriptorPreparsedChanged; + event.u.media_descriptor_preparsed_changed.new_status = + p_event->u.input_item_preparsed_changed.new_status; + + /* Send the event */ + libvlc_event_send( p_md->p_event_manager, &event ); +} /************************************************************************** * Install event handler (Private) @@ -132,6 +173,14 @@ static void install_input_item_observer( libvlc_media_descriptor_t *p_md ) vlc_InputItemMetaChanged, input_item_meta_changed, p_md ); + vlc_event_attach( &p_md->p_input_item->event_manager, + vlc_InputItemDurationChanged, + input_item_duration_changed, + p_md ); + vlc_event_attach( &p_md->p_input_item->event_manager, + vlc_InputItemPreparsedChanged, + input_item_preparsed_changed, + p_md ); } /************************************************************************** @@ -147,6 +196,14 @@ static void uninstall_input_item_observer( libvlc_media_descriptor_t *p_md ) vlc_InputItemMetaChanged, input_item_meta_changed, p_md ); + vlc_event_detach( &p_md->p_input_item->event_manager, + vlc_InputItemDurationChanged, + input_item_duration_changed, + p_md ); + vlc_event_detach( &p_md->p_input_item->event_manager, + vlc_InputItemPreparsedChanged, + input_item_preparsed_changed, + p_md ); } /************************************************************************** @@ -160,10 +217,6 @@ static void preparse_if_needed( libvlc_media_descriptor_t *p_md ) playlist_PreparseEnqueue( p_md->p_libvlc_instance->p_libvlc_int->p_playlist, p_md->p_input_item ); - playlist_AskForArtEnqueue( - p_md->p_libvlc_instance->p_libvlc_int->p_playlist, - p_md->p_input_item ); - p_md->b_preparsed = VLC_TRUE; } } @@ -189,8 +242,11 @@ libvlc_media_descriptor_t * libvlc_media_descriptor_new_from_input_item( p_md = malloc( sizeof(libvlc_media_descriptor_t) ); p_md->p_libvlc_instance = p_instance; p_md->p_input_item = p_input_item; - p_md->b_preparsed = VLC_TRUE; + p_md->b_preparsed = VLC_FALSE; p_md->i_refcount = 1; + p_md->p_user_data = NULL; + + p_md->state = libvlc_NothingSpecial; /* A media descriptor can be a playlist. When you open a playlist * It can give a bunch of item to read. */ @@ -199,10 +255,16 @@ libvlc_media_descriptor_t * libvlc_media_descriptor_new_from_input_item( vlc_dictionary_init( &p_md->tags, 1 ); p_md->p_event_manager = libvlc_event_manager_new( p_md, p_instance, p_e ); - libvlc_event_manager_register_event_type( p_md->p_event_manager, + libvlc_event_manager_register_event_type( p_md->p_event_manager, libvlc_MediaDescriptorMetaChanged, p_e ); - libvlc_event_manager_register_event_type( p_md->p_event_manager, + libvlc_event_manager_register_event_type( p_md->p_event_manager, libvlc_MediaDescriptorSubItemAdded, p_e ); + libvlc_event_manager_register_event_type( p_md->p_event_manager, + libvlc_MediaDescriptorFreed, p_e ); + libvlc_event_manager_register_event_type( p_md->p_event_manager, + libvlc_MediaDescriptorDurationChanged, p_e ); + libvlc_event_manager_register_event_type( p_md->p_event_manager, + libvlc_MediaDescriptorStateChanged, p_e ); vlc_gc_incref( p_md->p_input_item ); @@ -233,9 +295,57 @@ libvlc_media_descriptor_t * libvlc_media_descriptor_new( p_md = libvlc_media_descriptor_new_from_input_item( p_instance, p_input_item, p_e ); + /* The p_input_item is retained in libvlc_media_descriptor_new_from_input_item */ + vlc_gc_decref( p_input_item ); + return p_md; } +/************************************************************************** + * Create a new media descriptor object + **************************************************************************/ +libvlc_media_descriptor_t * libvlc_media_descriptor_new_as_node( + libvlc_instance_t *p_instance, + const char * psz_name, + libvlc_exception_t *p_e ) +{ + input_item_t * p_input_item; + libvlc_media_descriptor_t * p_md; + + p_input_item = input_ItemNew( p_instance->p_libvlc_int, "vlc://nop", psz_name ); + + if (!p_input_item) + { + libvlc_exception_raise( p_e, "Can't create md's input_item" ); + return NULL; + } + + p_md = libvlc_media_descriptor_new_from_input_item( p_instance, + p_input_item, p_e ); + + p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance, NULL ); + + return p_md; +} + +/************************************************************************** + * Add an option to the media descriptor, + * that will be used to determine how the media_instance will read the + * media_descriptor. This allow to use VLC advanced reading/streaming + * options in a per-media basis + * + * The options are detailled in vlc --long-help, for instance "--sout-all" + **************************************************************************/ +void libvlc_media_descriptor_add_option( + libvlc_media_descriptor_t * p_md, + const char * ppsz_option, + libvlc_exception_t *p_e ) +{ + (void)p_e; + input_ItemAddOpt( p_md->p_input_item, ppsz_option, + VLC_INPUT_OPTION_UNIQUE|VLC_INPUT_OPTION_TRUSTED ); +} + /************************************************************************** * Delete a media descriptor object **************************************************************************/ @@ -250,11 +360,22 @@ void libvlc_media_descriptor_release( libvlc_media_descriptor_t *p_md ) if( p_md->i_refcount > 0 ) return; - libvlc_media_list_release( p_md->p_subitems ); + if( p_md->p_subitems ) + libvlc_media_list_release( p_md->p_subitems ); uninstall_input_item_observer( p_md ); vlc_gc_decref( p_md->p_input_item ); + /* Construct the event */ + libvlc_event_t event; + event.type = libvlc_MediaDescriptorFreed; + event.u.media_descriptor_freed.md = p_md; + + /* Send the event */ + libvlc_event_send( p_md->p_event_manager, &event ); + + libvlc_event_manager_release( p_md->p_event_manager ); + char ** all_keys = vlc_dictionary_all_keys( &p_md->tags ); for( i = 0; all_keys[i]; i++ ) { @@ -300,7 +421,7 @@ libvlc_media_descriptor_get_mrl( libvlc_media_descriptor_t * p_md, libvlc_exception_t * p_e ) { (void)p_e; - return strdup( p_md->p_input_item->psz_uri ); + return input_item_GetURI( p_md->p_input_item ); } /************************************************************************** @@ -311,6 +432,8 @@ char * libvlc_media_descriptor_get_meta( libvlc_media_descriptor_t *p_md, libvlc_meta_t e_meta, libvlc_exception_t *p_e ) { + VLC_UNUSED(p_e); + char * psz_meta; /* XXX: locking */ @@ -319,6 +442,13 @@ char * libvlc_media_descriptor_get_meta( libvlc_media_descriptor_t *p_md, psz_meta = input_item_GetMeta( p_md->p_input_item, libvlc_to_vlc_meta[e_meta] ); + + if( e_meta == libvlc_meta_ArtworkURL && !psz_meta ) + { + playlist_AskForArtEnqueue( + p_md->p_libvlc_instance->p_libvlc_int->p_playlist, + p_md->p_input_item ); + } /* Should be integrated in core */ if( !psz_meta && e_meta == libvlc_meta_Title && p_md->p_input_item->psz_name ) @@ -330,6 +460,41 @@ char * libvlc_media_descriptor_get_meta( libvlc_media_descriptor_t *p_md, return psz_meta; } +/************************************************************************** + * Getter for state information + * Can be error, playing, buffering, NothingSpecial. + **************************************************************************/ + +libvlc_state_t +libvlc_media_descriptor_get_state( libvlc_media_descriptor_t *p_md, + libvlc_exception_t *p_e ) +{ + (void)p_e; + return p_md->state; +} + +/************************************************************************** + * Setter for state information (LibVLC Internal) + **************************************************************************/ + +void +libvlc_media_descriptor_set_state( libvlc_media_descriptor_t *p_md, + libvlc_state_t state, + libvlc_exception_t *p_e ) +{ + (void)p_e; + libvlc_event_t event; + + p_md->state = state; + + /* Construct the event */ + event.type = libvlc_MediaDescriptorStateChanged; + event.u.media_descriptor_state_changed.new_state = state; + + /* Send the event */ + libvlc_event_send( p_md->p_event_manager, &event ); +} + /************************************************************************** * Add a tag **************************************************************************/ @@ -338,11 +503,13 @@ void libvlc_media_descriptor_add_tag( libvlc_media_descriptor_t *p_md, const libvlc_tag_t tag, libvlc_exception_t *p_e ) { + VLC_UNUSED(p_e); + struct libvlc_tags_storage_t * p_ts; if( !tag || !key ) return; - + p_ts = vlc_dictionary_value_for_key( &p_md->tags, key ); if( !p_ts ) @@ -356,7 +523,7 @@ void libvlc_media_descriptor_add_tag( libvlc_media_descriptor_t *p_md, p_ts->ppsz_tags = malloc(sizeof(char*)*(p_ts->i_count)); else p_ts->ppsz_tags = realloc(p_ts->ppsz_tags, sizeof(char*)*(p_ts->i_count)); - + p_ts->ppsz_tags[p_ts->i_count-1] = strdup( tag ); } @@ -369,12 +536,14 @@ void libvlc_media_descriptor_remove_tag( libvlc_media_descriptor_t *p_md, const libvlc_tag_t tag, libvlc_exception_t *p_e ) { + VLC_UNUSED(p_e); + struct libvlc_tags_storage_t * p_ts; int i; if( !tag || !key ) return; - + p_ts = vlc_dictionary_value_for_key( &p_md->tags, key ); if( !p_ts ) @@ -400,11 +569,13 @@ int libvlc_media_descriptor_tags_count_for_key( libvlc_media_descriptor_t *p_md, const char * key, libvlc_exception_t *p_e ) { + VLC_UNUSED(p_e); + struct libvlc_tags_storage_t * p_ts; if( !key ) return 0; - + p_ts = vlc_dictionary_value_for_key( &p_md->tags, key ); if( !p_ts ) @@ -421,16 +592,121 @@ libvlc_media_descriptor_tag_at_index_for_key( libvlc_media_descriptor_t *p_md, const char * key, libvlc_exception_t *p_e ) { + VLC_UNUSED(p_e); + struct libvlc_tags_storage_t * p_ts; if( !key ) return NULL; - + p_ts = vlc_dictionary_value_for_key( &p_md->tags, key ); if( !p_ts ) return NULL; - + return strdup( p_ts->ppsz_tags[i] ); } +/************************************************************************** + * subitems + **************************************************************************/ +libvlc_media_list_t * +libvlc_media_descriptor_subitems( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + if( p_md->p_subitems ) + libvlc_media_list_retain( p_md->p_subitems ); + return p_md->p_subitems; +} + +/************************************************************************** + * event_manager + **************************************************************************/ +libvlc_event_manager_t * +libvlc_media_descriptor_event_manager( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + return p_md->p_event_manager; +} + +/************************************************************************** + * Get duration of media_descriptor object. + **************************************************************************/ +vlc_int64_t +libvlc_media_descriptor_get_duration( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + if( p_md && p_md->p_input_item) + { + return input_item_GetDuration( p_md->p_input_item ); + } + else + { + return -1; + } +} + +/************************************************************************** + * Get preparsed status for media_descriptor object. + **************************************************************************/ +int +libvlc_media_descriptor_is_preparsed( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + if( p_md && p_md->p_input_item) + { + return input_item_IsPreparsed( p_md->p_input_item ); + } + else + { + return VLC_FALSE; + } +} + +/************************************************************************** + * Sets media descriptor's user_data. user_data is specialized data + * accessed by the host application, VLC.framework uses it as a pointer to + * an native object that references a libvlc_media_descriptor_t pointer + **************************************************************************/ +void +libvlc_media_descriptor_set_user_data( libvlc_media_descriptor_t * p_md, + void * p_new_user_data, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + if( p_md ) + { + p_md->p_user_data = p_new_user_data; + } +} + +/************************************************************************** + * Get media descriptor's user_data. user_data is specialized data + * accessed by the host application, VLC.framework uses it as a pointer to + * an native object that references a libvlc_media_descriptor_t pointer + **************************************************************************/ +void * +libvlc_media_descriptor_get_user_data( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ) +{ + VLC_UNUSED(p_e); + + if( p_md ) + { + return p_md->p_user_data; + } + else + { + return NULL; + } +} +