From 7b32ae177048eb0bc36b6f7610b9e8a1fb22fead Mon Sep 17 00:00:00 2001 From: Pierre d'Herbemont Date: Sat, 20 Oct 2007 17:56:00 +0000 Subject: [PATCH] src/control: (Patch by Enrique Osuna) * Add the ability to store user data in media_descriptor. * Duration can now be retrieved from a media_instance * Can new get the preparsed state of a media_descriptor * Add callbacks for libvlc_MediaDescriptorDurationChanged/vlc_InputItemDurationChanged and libvlc_MediaDescriptorPreparsedChanged/vlc_InputItemPreparsedChanged. --- include/vlc/libvlc.h | 16 +++++ include/vlc/libvlc_structures.h | 12 +++- include/vlc_events.h | 12 +++- include/vlc_input.h | 44 +++++++++++- src/control/libvlc_internal.h | 1 + src/control/media_descriptor.c | 123 ++++++++++++++++++++++++++++++++ src/control/media_instance.c | 1 + 7 files changed, 204 insertions(+), 5 deletions(-) diff --git a/include/vlc/libvlc.h b/include/vlc/libvlc.h index 7d0f0c612e..2e06c8ff20 100644 --- a/include/vlc/libvlc.h +++ b/include/vlc/libvlc.h @@ -189,6 +189,22 @@ VLC_PUBLIC_API libvlc_event_manager_t * libvlc_media_descriptor_event_manager( libvlc_media_descriptor_t * p_md, libvlc_exception_t * p_e ); +VLC_PUBLIC_API vlc_int64_t + libvlc_media_descriptor_get_duration( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ); + +VLC_PUBLIC_API vlc_bool_t + libvlc_media_descriptor_is_preparsed( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e ); + +VLC_PUBLIC_API void + libvlc_media_descriptor_set_user_data( libvlc_media_descriptor_t * p_md, + void * p_new_user_data, + libvlc_exception_t * p_e); +VLC_PUBLIC_API void * + libvlc_media_descriptor_get_user_data( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * p_e); + /** @}*/ /***************************************************************************** diff --git a/include/vlc/libvlc_structures.h b/include/vlc/libvlc_structures.h index 34c6259b61..7ee11ec60e 100644 --- a/include/vlc/libvlc_structures.h +++ b/include/vlc/libvlc_structures.h @@ -296,6 +296,8 @@ typedef struct libvlc_log_message_t typedef enum libvlc_event_type_t { libvlc_MediaDescriptorMetaChanged, libvlc_MediaDescriptorSubItemAdded, + libvlc_MediaDescriptorDurationChanged, + libvlc_MediaDescriptorPreparsedChanged, libvlc_MediaInstancePlayed, libvlc_MediaInstancePaused, @@ -333,7 +335,15 @@ typedef struct libvlc_event_t { libvlc_media_descriptor_t * new_child; } media_descriptor_subitem_added; - + struct + { + vlc_int64_t new_duration; + } media_descriptor_duration_changed; + struct + { + int new_status; + } media_descriptor_preparsed_changed; + /* media instance */ struct { diff --git a/include/vlc_events.h b/include/vlc_events.h index b4037e7caf..4cf6599333 100644 --- a/include/vlc_events.h +++ b/include/vlc_events.h @@ -114,6 +114,8 @@ typedef enum vlc_event_type_t { /* Input item events */ vlc_InputItemMetaChanged, vlc_InputItemSubItemAdded, + vlc_InputItemDurationChanged, + vlc_InputItemPreparsedChanged, /* Service Discovery event */ vlc_ServicesDiscoveryItemAdded, @@ -136,7 +138,15 @@ typedef struct vlc_event_t { input_item_t * p_new_child; } input_item_subitem_added; - + struct vlc_input_item_duration_changed + { + mtime_t new_duration; + } input_item_duration_changed; + struct vlc_input_item_preparsed_changed + { + int new_status; + } input_item_preparsed_changed; + /* Service discovery events */ struct vlc_services_discovery_item_added { diff --git a/include/vlc_input.h b/include/vlc_input.h index 060effc410..dbef0e94b3 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -120,6 +120,10 @@ static inline void input_ItemInit( vlc_object_t *p_o, input_item_t *p_i ) vlc_InputItemMetaChanged ); vlc_event_manager_register_event_type( &p_i->event_manager, vlc_InputItemSubItemAdded ); + vlc_event_manager_register_event_type( &p_i->event_manager, + vlc_InputItemDurationChanged ); + vlc_event_manager_register_event_type( &p_i->event_manager, + vlc_InputItemPreparsedChanged ); } static inline void input_ItemCopyOptions( input_item_t *p_parent, @@ -302,21 +306,55 @@ static inline mtime_t input_item_GetDuration( input_item_t * p_i ) static inline void input_item_SetDuration( input_item_t * p_i, mtime_t i_duration ) { + vlc_bool_t send_event = VLC_FALSE; + vlc_mutex_lock( &p_i->lock ); - p_i->i_duration = i_duration; + if( p_i->i_duration != i_duration ) + { + p_i->i_duration = i_duration; + send_event = VLC_TRUE; + } vlc_mutex_unlock( &p_i->lock ); + + if ( send_event == VLC_TRUE ) + { + vlc_event_t event; + event.type = vlc_InputItemDurationChanged; + event.u.input_item_duration_changed.new_duration = i_duration; + vlc_event_send( &p_i->event_manager, &event ); + } + return; } static inline void input_item_SetPreparsed( input_item_t *p_i, vlc_bool_t preparsed ) { + vlc_bool_t send_event = VLC_FALSE; + if( !p_i->p_meta ) p_i->p_meta = vlc_meta_New(); + vlc_mutex_lock( &p_i->lock ); + int new_status; if( preparsed ) - p_i->p_meta->i_status |= ITEM_PREPARSED; + new_status = p_i->p_meta->i_status | ITEM_PREPARSED; else - p_i->p_meta->i_status &= ~ITEM_PREPARSED; + new_status = p_i->p_meta->i_status & ~ITEM_PREPARSED; + if ( p_i->p_meta->i_status != new_status ) + { + p_i->p_meta->i_status = new_status; + send_event = VLC_TRUE; + } + + vlc_mutex_unlock( &p_i->lock ); + + if ( send_event == VLC_TRUE ) + { + vlc_event_t event; + event.type = vlc_InputItemPreparsedChanged; + event.u.input_item_preparsed_changed.new_status = new_status; + vlc_event_send( &p_i->event_manager, &event ); + } } static inline vlc_bool_t input_item_IsPreparsed( input_item_t *p_i ) diff --git a/src/control/libvlc_internal.h b/src/control/libvlc_internal.h index 525afef2eb..6f07ce07d5 100644 --- a/src/control/libvlc_internal.h +++ b/src/control/libvlc_internal.h @@ -88,6 +88,7 @@ struct libvlc_media_descriptor_t vlc_dictionary_t tags; /* To be merged with core's meta soon */ struct libvlc_media_list_t *p_subitems; /* A media descriptor can have * Sub item */ + void *p_user_data; /* Allows for VLC.framework to hook into media descriptor without creating a new VLCMedia object. */ }; struct libvlc_tag_query_t diff --git a/src/control/media_descriptor.c b/src/control/media_descriptor.c index 7067cc1992..953eecb900 100644 --- a/src/control/media_descriptor.c +++ b/src/control/media_descriptor.c @@ -124,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) @@ -138,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 ); } /************************************************************************** @@ -153,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 ); } /************************************************************************** @@ -197,6 +248,7 @@ libvlc_media_descriptor_t * libvlc_media_descriptor_new_from_input_item( p_md->p_input_item = p_input_item; p_md->b_preparsed = VLC_FALSE; p_md->i_refcount = 1; + p_md->p_user_data = NULL; // VLC.framework hook /* A media descriptor can be a playlist. When you open a playlist * It can give a bunch of item to read. */ @@ -209,6 +261,8 @@ libvlc_media_descriptor_t * libvlc_media_descriptor_new_from_input_item( libvlc_MediaDescriptorMetaChanged, p_e ); 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_MediaDescriptorDurationChanged, p_e ); vlc_gc_incref( p_md->p_input_item ); @@ -462,3 +516,72 @@ libvlc_media_descriptor_event_manager( libvlc_media_descriptor_t * p_md, { 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 ) +{ + 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. + **************************************************************************/ +vlc_bool_t +libvlc_media_descriptor_is_preparsed( libvlc_media_descriptor_t * p_md, + libvlc_exception_t * 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 ) +{ + 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 ) +{ + if( p_md ) + { + return p_md->p_user_data; + } + else + { + return NULL; + } +} \ No newline at end of file diff --git a/src/control/media_instance.c b/src/control/media_instance.c index e4d999440e..178d34e342 100644 --- a/src/control/media_instance.c +++ b/src/control/media_instance.c @@ -307,6 +307,7 @@ void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi ) if( libvlc_exception_raised( &p_e ) ) { libvlc_event_manager_release( p_mi->p_event_manager ); + libvlc_exception_clear( &p_e ); free( p_mi ); return; /* no need to worry about no input thread */ } -- 2.39.2