/** * This function preparses an item when needed. */ static void Preparse( playlist_preparser_t *preparser, input_item_t *p_item, input_item_meta_request_option_t i_options ) { vlc_mutex_lock( &p_item->lock ); int i_type = p_item->i_type; bool b_net = p_item->b_net; vlc_mutex_unlock( &p_item->lock ); bool b_preparse = false; switch (i_type) { case ITEM_TYPE_FILE: case ITEM_TYPE_DIRECTORY: case ITEM_TYPE_PLAYLIST: case ITEM_TYPE_NODE: if (!b_net || i_options & META_REQUEST_OPTION_SCOPE_NETWORK) b_preparse = true; break; } /* Do not preparse if it is already done (like by playing it) */ if( b_preparse && !input_item_IsPreparsed( p_item ) ) { input_thread_t *input = input_CreatePreparser( preparser->object, p_item ); if( input == NULL ) return; var_AddCallback( input, "intf-event", InputEvent, &preparser->item_done ); if( input_Start( input ) == VLC_SUCCESS ) vlc_sem_wait( &preparser->item_done ); var_DelCallback( input, "intf-event", InputEvent, &preparser->item_done ); /* Normally, the input is already stopped since we waited for it. But * if the playlist preparser is being deleted, then the input might * still be running. Force it to stop. */ input_Stop( input ); input_Close( input ); var_SetAddress( preparser->object, "item-change", p_item ); } input_item_SetPreparsed( p_item, true ); input_item_SignalPreparseEnded( p_item ); }
static int PreparserOpenInput( void* preparser_, void* req_, void** out ) { input_preparser_t* preparser = preparser_; input_preparser_req_t *req = req_; input_preparser_task_t* task = malloc( sizeof *task ); if( unlikely( !task ) ) goto error; atomic_init( &task->state, INIT_S ); atomic_init( &task->done, false ); task->preparser = preparser_; task->input = input_CreatePreparser( preparser->owner, InputEvent, task, req->item ); if( !task->input ) goto error; task->req = req; task->preparse_status = -1; if( input_Start( task->input ) ) { input_Close( task->input ); goto error; } *out = task; return VLC_SUCCESS; error: free( task ); if (req->cbs && req->cbs->on_preparse_ended) req->cbs->on_preparse_ended(req->item, ITEM_PREPARSE_FAILED, req->userdata); return VLC_EGENERIC; }