/** * Create a pair of nodes in the category and onelevel trees. * They share the same input item. * \param p_playlist the playlist * \param psz_name the name of the nodes * \param pp_node_cat pointer to return the node in category tree * \param pp_node_one pointer to return the node in onelevel tree * \param b_for_sd For Services Discovery ? (make node read-only and unskipping) */ void playlist_NodesPairCreate( playlist_t *p_playlist, const char *psz_name, playlist_item_t **pp_node_cat, playlist_item_t **pp_node_one, bool b_for_sd ) { PL_ASSERT_LOCKED; *pp_node_cat = playlist_NodeCreate( p_playlist, psz_name, p_playlist->p_root_category, 0, NULL ); *pp_node_one = playlist_NodeCreate( p_playlist, psz_name, p_playlist->p_root_onelevel, 0, (*pp_node_cat)->p_input ); if( b_for_sd ) { (*pp_node_cat)->i_flags |= PLAYLIST_RO_FLAG; (*pp_node_cat)->i_flags |= PLAYLIST_SKIP_FLAG; (*pp_node_one)->i_flags |= PLAYLIST_RO_FLAG; (*pp_node_one)->i_flags |= PLAYLIST_SKIP_FLAG; } }
playlist_item_t *RecentsMRL::toPlaylist(int length) { playlist_item_t *p_node_recent = playlist_NodeCreate(THEPL, _("Recently Played"), THEPL->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL); if ( p_node_recent == NULL ) return NULL; if (length == 0 || recents.count() < length) length = recents.count(); for (int i = 0; i < length; i++) { input_item_t *p_input = input_item_New(qtu(recents.at(i)), NULL); playlist_NodeAddInput(THEPL, p_input, p_node_recent, PLAYLIST_APPEND, PLAYLIST_END, false); } return p_node_recent; }
static int RecursiveInsertCopy ( playlist_t *p_playlist, playlist_item_t *p_item, playlist_item_t *p_parent, int i_pos, bool b_flat ) { PL_ASSERT_LOCKED; assert( p_parent != NULL && p_item != NULL ); if( p_item == p_parent ) return i_pos; input_item_t *p_input = p_item->p_input; if( !(p_item->i_children != -1 && b_flat) ) { input_item_t *p_new_input = input_item_Copy( p_input ); if( !p_new_input ) return i_pos; playlist_item_t *p_new_item = NULL; if( p_item->i_children == -1 ) p_new_item = playlist_NodeAddInput( p_playlist, p_new_input, p_parent, PLAYLIST_INSERT, i_pos, pl_Locked ); else p_new_item = playlist_NodeCreate( p_playlist, NULL, p_parent, i_pos, 0, p_new_input ); vlc_gc_decref( p_new_input ); if( !p_new_item ) return i_pos; i_pos++; if( p_new_item->i_children != -1 ) p_parent = p_new_item; } for( int i = 0; i < p_item->i_children; i++ ) { if( b_flat ) i_pos = RecursiveInsertCopy( p_playlist, p_item->pp_children[i], p_parent, i_pos, true ); else RecursiveInsertCopy( p_playlist, p_item->pp_children[i], p_parent, p_parent->i_children, false ); } return i_pos; }
/* A new item has been added to a certain sd */ static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_data ) { input_item_t * p_input = p_event->u.services_discovery_item_added.p_new_item; const char * psz_cat = p_event->u.services_discovery_item_added.psz_category; playlist_item_t *p_new_item, * p_parent = user_data; playlist_t * p_playlist = p_parent->p_playlist; msg_Dbg( p_playlist, "Adding %s in %s", p_input->psz_name ? p_input->psz_name : "(null)", psz_cat ? psz_cat : "(null)" ); PL_LOCK; /* If p_parent is in root category (this is clearly a hack) and we have a cat */ if( !EMPTY_STR(psz_cat) && p_parent->p_parent == p_playlist->p_root_category ) { /* */ playlist_item_t * p_cat; p_cat = playlist_ChildSearchName( p_parent, psz_cat ); if( !p_cat ) { p_cat = playlist_NodeCreate( p_playlist, psz_cat, p_parent, 0, NULL ); p_cat->i_flags &= ~PLAYLIST_SKIP_FLAG; } p_parent = p_cat; } p_new_item = playlist_NodeAddInput( p_playlist, p_input, p_parent, PLAYLIST_APPEND, PLAYLIST_END, pl_Locked ); if( p_new_item ) { p_new_item->i_flags &= ~PLAYLIST_SKIP_FLAG; p_new_item->i_flags &= ~PLAYLIST_SAVE_FLAG; } PL_UNLOCK; }
/** * Create playlist * * Create a playlist structure. * \param p_parent the vlc object that is to be the parent of this playlist * \return a pointer to the created playlist, or NULL on error */ static playlist_t *playlist_Create( vlc_object_t *p_parent ) { playlist_t *p_playlist; playlist_private_t *p; /* Allocate structure */ p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" ); if( !p ) return NULL; assert( offsetof( playlist_private_t, public_data ) == 0 ); p_playlist = &p->public_data; TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds ); VariablesInit( p_playlist ); vlc_mutex_init( &p->lock ); vlc_cond_init( &p->signal ); p->killed = false; /* Initialise data structures */ pl_priv(p_playlist)->i_last_playlist_id = 0; pl_priv(p_playlist)->p_input = NULL; ARRAY_INIT( p_playlist->items ); ARRAY_INIT( p_playlist->all_items ); ARRAY_INIT( pl_priv(p_playlist)->items_to_delete ); ARRAY_INIT( p_playlist->current ); p_playlist->i_current_index = 0; pl_priv(p_playlist)->b_reset_currently_playing = true; pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" ); pl_priv(p_playlist)->b_doing_ml = false; pl_priv(p_playlist)->b_auto_preparse = var_InheritBool( p_parent, "auto-preparse" ); /* Preparser (and meta retriever) */ p->p_preparser = playlist_preparser_New( VLC_OBJECT(p_playlist) ); if( unlikely(p->p_preparser == NULL) ) msg_Err( p_playlist, "cannot create preparser" ); /* Create the root node */ PL_LOCK; p_playlist->p_root = playlist_NodeCreate( p_playlist, NULL, NULL, PLAYLIST_END, 0, NULL ); PL_UNLOCK; if( !p_playlist->p_root ) return NULL; /* Create currently playing items node */ PL_LOCK; p_playlist->p_playing = playlist_NodeCreate( p_playlist, _( "Playlist" ), p_playlist->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); PL_UNLOCK; if( !p_playlist->p_playing ) return NULL; /* Create media library node */ const bool b_ml = var_InheritBool( p_parent, "media-library"); if( b_ml ) { PL_LOCK; p_playlist->p_media_library = playlist_NodeCreate( p_playlist, _( "Media Library" ), p_playlist->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); PL_UNLOCK; } else { p_playlist->p_media_library = NULL; } p_playlist->p_root_category = p_playlist->p_root; p_playlist->p_root_onelevel = p_playlist->p_root; p_playlist->p_local_category = p_playlist->p_playing; p_playlist->p_local_onelevel = p_playlist->p_playing; p_playlist->p_ml_category = p_playlist->p_media_library; p_playlist->p_ml_onelevel = p_playlist->p_media_library;; /* Initial status */ pl_priv(p_playlist)->status.p_item = NULL; pl_priv(p_playlist)->status.p_node = p_playlist->p_playing; pl_priv(p_playlist)->request.b_request = false; pl_priv(p_playlist)->status.i_status = PLAYLIST_STOPPED; if(b_ml) { const bool b_auto_preparse = pl_priv(p_playlist)->b_auto_preparse; pl_priv(p_playlist)->b_auto_preparse = false; playlist_MLLoad( p_playlist ); pl_priv(p_playlist)->b_auto_preparse = b_auto_preparse; } /* Input resources */ p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) ); if( unlikely(p->p_input_resource == NULL) ) abort(); /* Audio output (needed for volume and device controls). */ audio_output_t *aout = input_resource_GetAout( p->p_input_resource ); if( aout != NULL ) input_resource_PutAout( p->p_input_resource, aout ); /* Thread */ playlist_Activate (p_playlist); /* Add service discovery modules */ char *mods = var_InheritString( p_playlist, "services-discovery" ); if( mods != NULL ) { char *p = mods, *m; while( (m = strsep( &p, " :," )) != NULL ) playlist_ServicesDiscoveryAdd( p_playlist, m ); free( mods ); } return p_playlist; }
/** * Create playlist * * Create a playlist structure. * \param p_parent the vlc object that is to be the parent of this playlist * \return a pointer to the created playlist, or NULL on error */ playlist_t *playlist_Create( vlc_object_t *p_parent ) { playlist_t *p_playlist; playlist_private_t *p; /* Allocate structure */ p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" ); if( !p ) return NULL; assert( offsetof( playlist_private_t, public_data ) == 0 ); p_playlist = &p->public_data; TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds ); VariablesInit( p_playlist ); vlc_mutex_init( &p->lock ); vlc_cond_init( &p->signal ); p->killed = false; /* Initialise data structures */ pl_priv(p_playlist)->i_last_playlist_id = 0; pl_priv(p_playlist)->p_input = NULL; ARRAY_INIT( p_playlist->items ); ARRAY_INIT( p_playlist->all_items ); ARRAY_INIT( pl_priv(p_playlist)->items_to_delete ); ARRAY_INIT( p_playlist->current ); p_playlist->i_current_index = 0; pl_priv(p_playlist)->b_reset_currently_playing = true; pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" ); pl_priv(p_playlist)->b_preparse = var_InheritBool( p_parent, "auto-preparse" ); /* Create the root, playing items and meida library nodes */ playlist_item_t *root, *playing, *ml; PL_LOCK; root = playlist_NodeCreate( p_playlist, NULL, NULL, PLAYLIST_END, 0, NULL ); playing = playlist_NodeCreate( p_playlist, _( "Playlist" ), root, PLAYLIST_END, PLAYLIST_RO_FLAG | PLAYLIST_NO_INHERIT_FLAG, NULL ); if( var_InheritBool( p_parent, "media-library") ) ml = playlist_NodeCreate( p_playlist, _( "Media Library" ), root, PLAYLIST_END, PLAYLIST_RO_FLAG | PLAYLIST_NO_INHERIT_FLAG, NULL ); else ml = NULL; PL_UNLOCK; if( unlikely(root == NULL || playing == NULL) ) abort(); p_playlist->p_root = root; p_playlist->p_playing = playing; p_playlist->p_media_library = ml; p_playlist->p_root_category = p_playlist->p_root; p_playlist->p_root_onelevel = p_playlist->p_root; p_playlist->p_local_category = p_playlist->p_playing; p_playlist->p_local_onelevel = p_playlist->p_playing; p_playlist->p_ml_category = p_playlist->p_media_library; p_playlist->p_ml_onelevel = p_playlist->p_media_library;; /* Initial status */ pl_priv(p_playlist)->status.p_item = NULL; pl_priv(p_playlist)->status.p_node = p_playlist->p_playing; pl_priv(p_playlist)->request.b_request = false; if (ml != NULL) playlist_MLLoad( p_playlist ); /* Input resources */ p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) ); if( unlikely(p->p_input_resource == NULL) ) abort(); /* Audio output (needed for volume and device controls). */ audio_output_t *aout = input_resource_GetAout( p->p_input_resource ); if( aout != NULL ) input_resource_PutAout( p->p_input_resource, aout ); /* Initialize the shared HTTP cookie jar */ vlc_value_t cookies; cookies.p_address = vlc_http_cookies_new(); if ( likely(cookies.p_address) ) { var_Create( p_playlist, "http-cookies", VLC_VAR_ADDRESS ); var_SetChecked( p_playlist, "http-cookies", VLC_VAR_ADDRESS, cookies ); } /* Thread */ playlist_Activate (p_playlist); /* Add service discovery modules */ char *mods = var_InheritString( p_playlist, "services-discovery" ); if( mods != NULL ) { char *s = mods, *m; while( (m = strsep( &s, " :," )) != NULL ) playlist_ServicesDiscoveryAdd( p_playlist, m ); free( mods ); } return p_playlist; }