#include "libvlc_internal.h"
#include "media_internal.h"
+#include "media_list_internal.h"
static const vlc_meta_type_t libvlc_to_vlc_meta[] =
{
[vlc_meta_DiscNumber] = libvlc_meta_DiscNumber
};
+static libvlc_media_list_t *media_get_subitems( libvlc_media_t * p_md,
+ bool b_create )
+{
+ libvlc_media_list_t *p_subitems = NULL;
+
+ vlc_mutex_lock( &p_md->subitems_lock );
+ if( p_md->p_subitems == NULL && b_create )
+ {
+ p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance );
+ if( p_md->p_subitems != NULL )
+ {
+ p_md->p_subitems->b_read_only = true;
+ p_md->p_subitems->p_internal_md = p_md;
+ }
+ }
+ p_subitems = p_md->p_subitems;
+ vlc_mutex_unlock( &p_md->subitems_lock );
+ return p_subitems;
+}
+
/**************************************************************************
* input_item_subitem_added (Private) (vlc event Callback)
**************************************************************************/
{
libvlc_media_t * p_md = user_data;
libvlc_media_t * p_md_child;
+ libvlc_media_list_t *p_subitems;
libvlc_event_t event;
p_md_child = libvlc_media_new_from_input_item(
p_event->u.input_item_subitem_added.p_new_child );
/* Add this to our media list */
- if( p_md->p_subitems == NULL )
+ p_subitems = media_get_subitems( p_md, true );
+ if( p_subitems != NULL )
{
- p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance );
- if( unlikely(p_md->p_subitems == NULL) )
- abort();
- libvlc_media_list_set_media( p_md->p_subitems, p_md );
+ libvlc_media_list_lock( p_subitems );
+ libvlc_media_list_internal_add_media( p_subitems, p_md_child );
+ libvlc_media_list_unlock( p_subitems );
}
- libvlc_media_list_add_media( p_md->p_subitems, p_md_child );
/* Construct the event */
event.type = libvlc_MediaSubItemAdded;
libvlc_event_send(media->p_event_manager, &event);
}
+/**************************************************************************
+ * input_item_preparse_ended (Private) (vlc event Callback)
+ **************************************************************************/
+static void input_item_preparse_ended( const vlc_event_t * p_event,
+ void * user_data )
+{
+ VLC_UNUSED( p_event );
+ libvlc_media_t * p_md = user_data;
+ libvlc_media_list_t *p_subitems = media_get_subitems( p_md, false );
+
+ if( p_subitems != NULL )
+ {
+ /* notify the media list */
+ libvlc_media_list_lock( p_subitems );
+ libvlc_media_list_internal_end_reached( p_subitems );
+ libvlc_media_list_unlock( p_subitems );
+ }
+}
+
/**************************************************************************
* Install event handler (Private)
**************************************************************************/
vlc_InputItemSubItemTreeAdded,
input_item_subitemtree_added,
p_md );
+ vlc_event_attach( &p_md->p_input_item->event_manager,
+ vlc_InputItemPreparseEnded,
+ input_item_preparse_ended,
+ p_md );
}
/**************************************************************************
vlc_InputItemSubItemTreeAdded,
input_item_subitemtree_added,
p_md );
+ vlc_event_detach( &p_md->p_input_item->event_manager,
+ vlc_InputItemPreparseEnded,
+ input_item_preparse_ended,
+ p_md );
}
/**************************************************************************
vlc_cond_init(&p_md->parsed_cond);
vlc_mutex_init(&p_md->parsed_lock);
+ vlc_mutex_init(&p_md->subitems_lock);
p_md->state = libvlc_NothingSpecial;
{
input_item_t * p_input_item;
libvlc_media_t * p_md;
+ libvlc_media_list_t * p_subitems;
p_input_item = input_item_New( "vlc://nop", psz_name );
p_md = libvlc_media_new_from_input_item( p_instance, p_input_item );
- p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance );
+ p_subitems = media_get_subitems( p_md, true );
+ if( p_subitems == NULL) {
+ libvlc_media_release( p_md );
+ return NULL;
+ }
return p_md;
}
vlc_cond_destroy( &p_md->parsed_cond );
vlc_mutex_destroy( &p_md->parsed_lock );
+ vlc_mutex_destroy( &p_md->subitems_lock );
/* Construct the event */
libvlc_event_t event;
libvlc_media_list_t *
libvlc_media_subitems( libvlc_media_t * p_md )
{
- if( p_md->p_subitems )
- libvlc_media_list_retain( p_md->p_subitems );
- return p_md->p_subitems;
+ libvlc_media_list_t *p_subitems = media_get_subitems( p_md, true );
+ if( p_subitems )
+ libvlc_media_list_retain( p_subitems );
+ return p_subitems;
}
/**************************************************************************
return from_mtime(input_item_GetDuration( p_md->p_input_item ));
}
-static int media_parse(libvlc_media_t *media)
+static int media_parse(libvlc_media_t *media, bool b_async,
+ libvlc_media_parse_flag_t parse_flag)
{
- libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int;
- input_item_t *item = media->p_input_item;
+ bool needed;
+
+ vlc_mutex_lock(&media->parsed_lock);
+ needed = !media->has_asked_preparse;
+ media->has_asked_preparse = true;
+ vlc_mutex_unlock(&media->parsed_lock);
+
+ if (needed)
+ {
+ libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int;
+ input_item_t *item = media->p_input_item;
+ input_item_meta_request_option_t art_scope = META_REQUEST_OPTION_NONE;
+ input_item_meta_request_option_t parse_scope = META_REQUEST_OPTION_SCOPE_LOCAL;
+ int ret;
+
+ if (parse_flag & libvlc_media_fetch_local)
+ art_scope |= META_REQUEST_OPTION_SCOPE_LOCAL;
+ if (parse_flag & libvlc_media_fetch_network)
+ art_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
+ if (art_scope != META_REQUEST_OPTION_NONE) {
+ ret = libvlc_ArtRequest(libvlc, item, art_scope);
+ if (ret != VLC_SUCCESS)
+ return ret;
+ }
+
+ if (parse_flag & libvlc_media_parse_network)
+ parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK;
+ ret = libvlc_MetaRequest(libvlc, item, parse_scope);
+ if (ret != VLC_SUCCESS)
+ return ret;
+ }
+ else
+ return VLC_EGENERIC;
- /* TODO: Fetch art on need basis. But how not to break compatibility? */
- libvlc_ArtRequest(libvlc, item, META_REQUEST_OPTION_NONE);
- return libvlc_MetaRequest(libvlc, item, META_REQUEST_OPTION_NONE);
+ if (!b_async)
+ {
+ vlc_mutex_lock(&media->parsed_lock);
+ while (!media->is_parsed)
+ vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
+ vlc_mutex_unlock(&media->parsed_lock);
+ }
+ return VLC_SUCCESS;
}
/**************************************************************************
void
libvlc_media_parse(libvlc_media_t *media)
{
- vlc_mutex_lock(&media->parsed_lock);
- if (!media->has_asked_preparse)
- {
- media->has_asked_preparse = true;
- vlc_mutex_unlock(&media->parsed_lock);
-
- if (media_parse(media))
- /* Parse failed: do not wait! */
- return;
- vlc_mutex_lock(&media->parsed_lock);
- }
-
- while (!media->is_parsed)
- vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
- vlc_mutex_unlock(&media->parsed_lock);
+ media_parse( media, false, libvlc_media_fetch_local );
}
/**************************************************************************
void
libvlc_media_parse_async(libvlc_media_t *media)
{
- bool needed;
-
- vlc_mutex_lock(&media->parsed_lock);
- needed = !media->has_asked_preparse;
- media->has_asked_preparse = true;
- vlc_mutex_unlock(&media->parsed_lock);
+ media_parse( media, true, libvlc_media_fetch_local );
+}
- if (needed)
- media_parse(media);
+/**************************************************************************
+ * Parse the media asynchronously with options.
+ **************************************************************************/
+int
+libvlc_media_parse_with_options( libvlc_media_t *media,
+ libvlc_media_parse_flag_t parse_flag )
+{
+ return media_parse( media, true, parse_flag ) == VLC_SUCCESS ? 0 : -1;
}
/**************************************************************************
}
free( p_tracks );
}
+
+/**************************************************************************
+ * Get the media type of the media descriptor object
+ **************************************************************************/
+libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md )
+{
+ assert( p_md );
+
+ int i_type;
+ input_item_t *p_input_item = p_md->p_input_item;
+
+ vlc_mutex_lock( &p_input_item->lock );
+ i_type = p_md->p_input_item->i_type;
+ vlc_mutex_unlock( &p_input_item->lock );
+
+ switch( i_type )
+ {
+ case ITEM_TYPE_FILE:
+ return libvlc_media_type_file;
+ case ITEM_TYPE_NODE:
+ case ITEM_TYPE_DIRECTORY:
+ return libvlc_media_type_directory;
+ case ITEM_TYPE_DISC:
+ return libvlc_media_type_disc;
+ case ITEM_TYPE_STREAM:
+ return libvlc_media_type_stream;
+ case ITEM_TYPE_PLAYLIST:
+ return libvlc_media_type_playlist;
+ default:
+ return libvlc_media_type_unknown;
+ }
+}