static void media_list_subitem_added( const libvlc_event_t * p_event, void * p_user_data ) { libvlc_media_list_t * p_mlist; libvlc_event_t added_event; libvlc_media_list_view_t * p_mlv = p_user_data; libvlc_media_t * p_submd = p_event->u.media_subitem_added.new_child; libvlc_media_t * p_md = p_event->p_obj; if((p_mlist = libvlc_media_subitems( p_md ))) { /* We have a mlist to which we're going to listen to events * thus, no need to wait for SubItemAdded events */ libvlc_event_detach( p_md->p_event_manager, libvlc_MediaSubItemAdded, media_list_subitem_added, p_mlv, NULL ); libvlc_media_list_lock( p_mlist ); libvlc_event_attach( p_mlist->p_event_manager, libvlc_MediaListItemAdded, media_list_item_added, p_mlv, NULL ); libvlc_event_attach( p_mlist->p_event_manager, libvlc_MediaListItemDeleted, media_list_item_removed, p_mlv, NULL ); libvlc_media_list_unlock( p_mlist ); libvlc_media_list_release( p_mlist ); } install_md_listener( p_mlv, p_submd ); added_event.u.media_list_item_added.item = p_submd; added_event.u.media_list_item_added.index = 0; if( p_mlv->pf_ml_item_added ) p_mlv->pf_ml_item_added( &added_event, p_mlv ); }
/* Little helper */ static void import_mlist_rec( libvlc_media_list_view_t * p_mlv, libvlc_media_list_t * p_mlist, libvlc_exception_t * p_e ) { int i, count; count = libvlc_media_list_count( p_mlist, p_e ); for( i = 0; i < count; i++ ) { libvlc_media_t * p_md; libvlc_media_list_t * p_submlist; p_md = libvlc_media_list_item_at_index( p_mlist, i, p_e ); vlc_array_append( &p_mlv->p_this_view_data->array, p_md ); p_submlist = libvlc_media_subitems( p_md ); if( p_submlist ) { libvlc_media_list_lock( p_submlist ); import_mlist_rec( p_mlv, p_submlist, p_e ); libvlc_media_list_unlock( p_submlist ); libvlc_media_list_release( p_submlist ); } /* No need to release the md, as we want to retain it, as it is * stored in our array */ } }
/************************************************************************** * flat_media_list_view_item_at_index (private) * (called by flat_media_list_view_item_at_index) **************************************************************************/ static libvlc_media_t * hierarch_node_media_list_view_item_at_index( libvlc_media_list_view_t * p_mlv, int index, libvlc_exception_t * p_e ) { /* FIXME: we may want to cache that */ libvlc_media_t * p_md; libvlc_media_list_t * p_submlist; trace("%d\n", index); int i, current_index, count = libvlc_media_list_count( p_mlv->p_mlist, p_e ); current_index = -1; for( i = 0; i < count; i++ ) { p_md = libvlc_media_list_item_at_index( p_mlv->p_mlist, i, p_e ); if( !p_md ) continue; p_submlist = libvlc_media_subitems( p_md ); if( !p_submlist ) continue; libvlc_media_list_release( p_submlist ); current_index++; if( current_index == index ) return p_md; libvlc_media_release( p_md ); } libvlc_exception_raise( p_e ); libvlc_printerr( "Index out of bound in Media List View" ); return NULL; }
static void uninstall_md_listener( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_md) { libvlc_media_list_t * p_mlist; libvlc_exception_t ignored_exception; libvlc_exception_init( &ignored_exception ); libvlc_event_detach( p_md->p_event_manager, libvlc_MediaSubItemAdded, media_list_subitem_added, p_mlv, &ignored_exception ); if( libvlc_exception_raised( &ignored_exception ) ) libvlc_exception_clear( &ignored_exception ); /* We don't care if we encounter an exception */ if((p_mlist = libvlc_media_subitems( p_md ))) { libvlc_media_list_lock( p_mlist ); libvlc_event_detach( p_mlist->p_event_manager, libvlc_MediaListItemAdded, media_list_item_added, p_mlv, NULL ); libvlc_event_detach( p_mlist->p_event_manager, libvlc_MediaListItemDeleted, media_list_item_removed, p_mlv, NULL ); int i, count = libvlc_media_list_count( p_mlist, NULL ); for( i = 0; i < count; i++) { libvlc_media_t * p_submd; p_submd = libvlc_media_list_item_at_index( p_mlist,i, NULL ); uninstall_md_listener( p_mlv, p_submd ); libvlc_media_release( p_submd ); } libvlc_media_list_unlock( p_mlist ); libvlc_media_list_release( p_mlist ); } }
static int expand_media_internal(JNIEnv *env, libvlc_instance_t* p_instance, jobject arrayList, libvlc_media_t* p_md) { if(!p_md) { return -1; } libvlc_media_list_t* p_subitems = libvlc_media_subitems(p_md); libvlc_media_release(p_md); if(p_subitems) { // Expand any subitems if needed int subitem_count = libvlc_media_list_count(p_subitems); if(subitem_count > 0) { LOGD("Found %d subitems, expanding", subitem_count); jclass arrayListClass; jmethodID methodAdd; arrayListGetIDs(env, &arrayListClass, &methodAdd, NULL); for(int i = subitem_count - 1; i >= 0; i--) { libvlc_media_t* p_subitem = libvlc_media_list_item_at_index(p_subitems, i); char* p_subitem_uri = libvlc_media_get_mrl(p_subitem); arrayListStringAdd(env, arrayListClass, methodAdd, arrayList, p_subitem_uri); free(p_subitem_uri); } } libvlc_media_list_release(p_subitems); if(subitem_count > 0) { return 0; } else { return -1; } } else { return -1; } }
static bool item_is_already_added( libvlc_media_t * p_md ) { libvlc_media_list_t * p_submlist; p_submlist = libvlc_media_subitems( p_md ); if( !p_submlist ) return false; int count = libvlc_media_list_count( p_submlist, NULL ); libvlc_media_list_release( p_submlist ); return count > 1; }
static void services_discovery_item_added( services_discovery_t *sd, input_item_t *parent, input_item_t *p_item, const char *psz_cat ) { libvlc_media_t * p_md; libvlc_media_discoverer_t *p_mdis = sd->owner.sys; libvlc_media_list_t * p_mlist = p_mdis->p_mlist; p_md = libvlc_media_new_from_input_item( p_mdis->p_libvlc_instance, p_item ); if( parent != NULL ) { /* Flatten items list for now. TODO: tree support. */ } else /* If we have a category, that mean we have to group the items having * that category in a media_list. */ if( psz_cat ) { p_mlist = vlc_dictionary_value_for_key( &p_mdis->catname_to_submedialist, psz_cat ); if( p_mlist == kVLCDictionaryNotFound ) { libvlc_media_t * p_catmd; p_catmd = libvlc_media_new_as_node( p_mdis->p_libvlc_instance, psz_cat ); p_mlist = libvlc_media_subitems( p_catmd ); p_mlist->b_read_only = true; /* Insert the newly created mlist in our dictionary */ vlc_dictionary_insert( &p_mdis->catname_to_submedialist, psz_cat, p_mlist ); /* Insert the md into the root list */ libvlc_media_list_lock( p_mdis->p_mlist ); libvlc_media_list_internal_add_media( p_mdis->p_mlist, p_catmd ); libvlc_media_list_unlock( p_mdis->p_mlist ); /* We don't release the mlist cause the dictionary * doesn't retain the object. But we release the md. */ libvlc_media_release( p_catmd ); } } libvlc_media_list_lock( p_mlist ); libvlc_media_list_internal_add_media( p_mlist, p_md ); libvlc_media_list_unlock( p_mlist ); libvlc_media_release( p_md ); }
static void test_media_has_slaves_from_parent(libvlc_instance_t *p_vlc, libvlc_media_slave_t *p_expected_slaves, unsigned i_expected_slaves) { libvlc_media_t *p_m = libvlc_media_new_path(p_vlc, SLAVES_DIR); assert(p_m != NULL); printf("Parse media dir to get subitems\n"); media_parse_sync(p_m); char *psz_main_media_mrl = path_to_mrl(p_vlc, MAIN_MEDIA_PATH); assert(psz_main_media_mrl != NULL); printf("Main media mrl: '%s'\n", psz_main_media_mrl); printf("Fetch main media from subitems\n"); libvlc_media_list_t *p_ml = libvlc_media_subitems(p_m); assert(p_ml != NULL); libvlc_media_list_lock(p_ml); int i_count = libvlc_media_list_count(p_ml); assert(i_count > 0); libvlc_media_t *p_subm = NULL; for (int i = 0; i < i_count; ++i) { p_subm = libvlc_media_list_item_at_index(p_ml, i); assert(p_subm != NULL); char *psz_mrl = libvlc_media_get_mrl(p_subm); assert(psz_mrl != NULL); if (strcmp(psz_main_media_mrl, psz_mrl) == 0) { printf("Found main media\n"); free(psz_mrl); break; } free(psz_mrl); libvlc_media_release(p_subm); p_subm = NULL; } free(psz_main_media_mrl); libvlc_media_list_unlock(p_ml); libvlc_media_list_release(p_ml); assert(p_subm != NULL); test_expected_slaves(p_subm, p_expected_slaves, i_expected_slaves); libvlc_media_release(p_subm); libvlc_media_release(p_m); }
/************************************************************************** * libvlc_media_list_view_children_for_item (Public) **************************************************************************/ libvlc_media_list_view_t * libvlc_media_list_view_children_for_item( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_md, libvlc_exception_t * p_e) { (void)p_e; libvlc_media_list_t * p_mlist; libvlc_media_list_view_t * ret; p_mlist = libvlc_media_subitems(p_md); if(!p_mlist) return NULL; ret = p_mlv->pf_constructor( p_mlist, p_e ); libvlc_media_list_release( p_mlist ); return ret; }
static void services_discovery_item_added( const vlc_event_t * p_event, void * user_data ) { input_item_t * p_item = p_event->u.services_discovery_item_added.p_new_item; const char * psz_cat = p_event->u.services_discovery_item_added.psz_category; libvlc_media_t * p_md; libvlc_media_discoverer_t * p_mdis = user_data; libvlc_media_list_t * p_mlist = p_mdis->p_mlist; p_md = libvlc_media_new_from_input_item( p_mdis->p_libvlc_instance, p_item, NULL ); /* If we have a category, that mean we have to group the items having * that category in a media_list. */ if( psz_cat ) { p_mlist = vlc_dictionary_value_for_key( &p_mdis->catname_to_submedialist, psz_cat ); if( p_mlist == kVLCDictionaryNotFound ) { libvlc_media_t * p_catmd; p_catmd = libvlc_media_new_as_node( p_mdis->p_libvlc_instance, psz_cat, NULL ); p_mlist = libvlc_media_subitems( p_catmd, NULL ); p_mlist->b_read_only = true; /* Insert the newly created mlist in our dictionary */ vlc_dictionary_insert( &p_mdis->catname_to_submedialist, psz_cat, p_mlist ); /* Insert the md into the root list */ libvlc_media_list_lock( p_mdis->p_mlist ); _libvlc_media_list_add_media( p_mdis->p_mlist, p_catmd, NULL ); libvlc_media_list_unlock( p_mdis->p_mlist ); /* We don't release the mlist cause the dictionary * doesn't retain the object. But we release the md. */ libvlc_media_release( p_catmd ); } } else { libvlc_media_list_lock( p_mlist ); _libvlc_media_list_add_media( p_mlist, p_md, NULL ); libvlc_media_list_unlock( p_mlist ); } }
/************************************************************************** * flat_media_list_view_item_at_index (private) * (called by flat_media_list_view_item_at_index) **************************************************************************/ static libvlc_media_list_view_t * hierarch_media_list_view_children_at_index( libvlc_media_list_view_t * p_mlv, int index, libvlc_exception_t * p_e ) { libvlc_media_t * p_md; libvlc_media_list_t * p_submlist; libvlc_media_list_view_t * p_ret; p_md = libvlc_media_list_item_at_index( p_mlv->p_mlist, index, p_e ); if( !p_md ) return NULL; p_submlist = libvlc_media_subitems( p_md, p_e ); libvlc_media_release( p_md ); if( !p_submlist ) return NULL; p_ret = libvlc_media_list_hierarchical_view( p_submlist, p_e ); libvlc_media_list_release( p_submlist ); return p_ret; }
static void install_md_listener( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_md) { libvlc_media_list_t * p_mlist; if((p_mlist = libvlc_media_subitems( p_md ))) { libvlc_media_list_lock( p_mlist ); int i, count = libvlc_media_list_count( p_mlist, NULL ); for( i = 0; i < count; i++) { libvlc_event_t added_event; libvlc_media_t * p_submd; p_submd = libvlc_media_list_item_at_index( p_mlist, i, NULL ); /* Install our listeners */ install_md_listener( p_mlv, p_submd ); /* For each item, send a notification to the mlv subclasses */ added_event.u.media_list_item_added.item = p_submd; added_event.u.media_list_item_added.index = 0; if( p_mlv->pf_ml_item_added ) p_mlv->pf_ml_item_added( &added_event, p_mlv ); libvlc_media_release( p_submd ); } libvlc_event_attach( p_mlist->p_event_manager, libvlc_MediaListItemAdded, media_list_item_added, p_mlv, NULL ); libvlc_event_attach( p_mlist->p_event_manager, libvlc_MediaListItemDeleted, media_list_item_removed, p_mlv, NULL ); libvlc_media_list_unlock( p_mlist ); libvlc_media_list_release( p_mlist ); } else { /* No mlist, wait for a subitem added event */ libvlc_event_attach( p_md->p_event_manager, libvlc_MediaSubItemAdded, media_list_subitem_added, p_mlv, NULL ); } }
/************************************************************************** * flat_media_list_view_count (private) * (called by media_list_view_count) **************************************************************************/ static int hierarch_node_media_list_view_count( libvlc_media_list_view_t * p_mlv, libvlc_exception_t * p_e ) { /* FIXME: we may want to cache that */ int i, ret, count = libvlc_media_list_count( p_mlv->p_mlist, p_e ); libvlc_media_t * p_md; libvlc_media_list_t * p_submlist; ret = 0; trace("\n"); for( i = 0; i < count; i++ ) { p_md = libvlc_media_list_item_at_index( p_mlv->p_mlist, i, p_e ); if( !p_md ) continue; p_submlist = libvlc_media_subitems( p_md ); if( !p_submlist ) continue; libvlc_media_release( p_md ); libvlc_media_list_release( p_submlist ); ret++; } return ret; }
/* Helper */ static int index_of_item( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_md ) { libvlc_media_t * p_iter_md; libvlc_media_list_t * p_submlist; int i, current_index, count = libvlc_media_list_count( p_mlv->p_mlist, NULL ); current_index = -1; for( i = 0; i < count; i++ ) { p_iter_md = libvlc_media_list_item_at_index( p_mlv->p_mlist, i, NULL ); if( !p_iter_md ) continue; p_submlist = libvlc_media_subitems( p_iter_md ); if( !p_submlist ) continue; libvlc_media_list_release( p_submlist ); libvlc_media_release( p_iter_md ); current_index++; if( p_md == p_iter_md ) return current_index; } return -1; }