예제 #1
0
/**************************************************************************
 * Tell media player to start playing.
 **************************************************************************/
int libvlc_media_player_play( libvlc_media_player_t *p_mi )
{
    lock_input( p_mi );

    input_thread_t *p_input_thread = p_mi->input.p_thread;
    if( p_input_thread )
    {
        /* A thread already exists, send it a play message */
        input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
        unlock_input( p_mi );
        return 0;
    }

    /* Ignore previous exception */
    lock(p_mi);

    if( !p_mi->p_md )
    {
        unlock(p_mi);
        unlock_input( p_mi );
        libvlc_printerr( "No associated media descriptor" );
        return -1;
    }

    p_input_thread = input_Create( p_mi, p_mi->p_md->p_input_item, NULL,
                                   p_mi->input.p_resource );
    unlock(p_mi);
    if( !p_input_thread )
    {
        unlock_input(p_mi);
        libvlc_printerr( "Not enough memory" );
        return -1;
    }

    var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
    var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
    var_AddCallback( p_input_thread, "program-scrambled", input_scrambled_changed, p_mi );
    var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );

    if( input_Start( p_input_thread ) )
    {
        unlock_input(p_mi);
        var_DelCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
        var_DelCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
        var_DelCallback( p_input_thread, "program-scrambled", input_scrambled_changed, p_mi );
        var_DelCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
        vlc_object_release( p_input_thread );
        libvlc_printerr( "Input initialization failure" );
        return -1;
    }
    p_mi->input.p_thread = p_input_thread;
    unlock_input(p_mi);
    return 0;
}
예제 #2
0
파일: thread.c 프로젝트: Kubink/vlc
/**
 * Start the input for an item
 *
 * \param p_playlist the playlist object
 * \param p_item the item to play
 * \return nothing
 */
static void PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_item_t *p_input = p_item->p_input;

    PL_ASSERT_LOCKED;

    msg_Dbg( p_playlist, "creating new input thread" );

    p_item->i_nb_played++;
    set_current_status_item( p_playlist, p_item );

    p_sys->status.i_status = PLAYLIST_RUNNING;

    assert( p_sys->p_input == NULL );
    PL_UNLOCK;

    input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL,
                                                   p_sys->p_input_resource );
    if( likely(p_input_thread != NULL) )
    {
        var_AddCallback( p_input_thread, "intf-event",
                         InputEvent, p_playlist );

        if( input_Start( p_input_thread ) )
        {
            var_DelCallback( p_input_thread, "intf-event",
                             InputEvent, p_playlist );
            vlc_object_release( p_input_thread );
            p_input_thread = NULL;
        }
    }

    var_SetAddress( p_playlist, "input-current", p_input_thread );

    /* TODO store art policy in playlist private data */
    char *psz_arturl = input_item_GetArtURL( p_input );
    /* p_input->p_meta should not be null after a successful CreateThread */
    bool b_has_art = !EMPTY_STR( psz_arturl );

    if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) )
    {
        PL_DEBUG( "requesting art for new input thread" );
        libvlc_ArtRequest( p_playlist->p_libvlc, p_input, META_REQUEST_OPTION_NONE );
    }
    free( psz_arturl );

    var_TriggerCallback( p_playlist, "activity" );

    PL_LOCK;
    p_sys->p_input = p_input_thread;
}
예제 #3
0
/**
 * 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 );
}
예제 #4
0
파일: preparser.c 프로젝트: mstorsjo/vlc
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;
}
예제 #5
0
/**
 * Start the input for an item
 *
 * \param p_playlist the playlist object
 * \param p_item the item to play
 * \return nothing
 */
static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_item_t *p_input = p_item->p_input;

    PL_ASSERT_LOCKED;

    msg_Dbg( p_playlist, "creating new input thread" );

    p_input->i_nb_played++;
    set_current_status_item( p_playlist, p_item );

    p_sys->status.i_status = PLAYLIST_RUNNING;

    UpdateActivity( p_playlist, DEFAULT_INPUT_ACTIVITY );

    assert( p_sys->p_input == NULL );

    if( !p_sys->p_input_resource )
        p_sys->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) );
    input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource );
    if( p_input_thread )
    {
        p_sys->p_input = p_input_thread;
        var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist );

        var_SetAddress( p_playlist, "input-current", p_input_thread );

        if( input_Start( p_sys->p_input ) )
        {
            vlc_object_release( p_input_thread );
            p_sys->p_input = p_input_thread = NULL;
        }
    }

    char *psz_uri = input_item_GetURI( p_item->p_input );
    if( psz_uri && ( !strncmp( psz_uri, "directory:", 10 ) ||
                     !strncmp( psz_uri, "vlc:", 4 ) ) )
    {
        free( psz_uri );
        return VLC_SUCCESS;
    }
    free( psz_uri );

    /* TODO store art policy in playlist private data */
    if( var_GetInteger( p_playlist, "album-art" ) == ALBUM_ART_WHEN_PLAYED )
    {
        bool b_has_art;

        char *psz_arturl, *psz_name;
        psz_arturl = input_item_GetArtURL( p_input );
        psz_name = input_item_GetName( p_input );

        /* p_input->p_meta should not be null after a successfull CreateThread */
        b_has_art = !EMPTY_STR( psz_arturl );

        if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) )
        {
            PL_DEBUG( "requesting art for %s", psz_name );
            playlist_AskForArtEnqueue( p_playlist, p_input );
        }
        free( psz_arturl );
        free( psz_name );
    }
    /* FIXME: this is not safe !!*/
    PL_UNLOCK;
    var_SetAddress( p_playlist, "item-current", p_input );
    PL_LOCK;

    return VLC_SUCCESS;
}
예제 #6
0
파일: thread.c 프로젝트: 371816210/vlc_vlc
/**
 * Start the input for an item
 *
 * \param p_playlist the playlist object
 * \param p_item the item to play
 * \return nothing
 */
static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_item_t *p_input = p_item->p_input;

    PL_ASSERT_LOCKED;

    msg_Dbg( p_playlist, "creating new input thread" );

    p_input->i_nb_played++;
    set_current_status_item( p_playlist, p_item );

    p_sys->status.i_status = PLAYLIST_RUNNING;

    assert( p_sys->p_input == NULL );

    input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource );
    if( p_input_thread )
    {
        p_sys->p_input = p_input_thread;
        var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist );

        var_SetAddress( p_playlist, "input-current", p_input_thread );

        if( input_Start( p_sys->p_input ) )
        {
            vlc_object_release( p_input_thread );
            p_sys->p_input = p_input_thread = NULL;
        }
    }

    bool b_find_art = var_GetInteger( p_playlist, "album-art" )
                                                      == ALBUM_ART_WHEN_PLAYED;
    if( b_find_art )
    {
        char *psz_uri = input_item_GetURI( p_item->p_input );
        if( psz_uri != NULL && (!strncmp( psz_uri, "directory:", 10 ) ||
                                !strncmp( psz_uri, "vlc:", 4 )) )
            b_find_art = false;
        free( psz_uri );
    }

    /* TODO store art policy in playlist private data */
    if( b_find_art )
    {
        char *psz_arturl = input_item_GetArtURL( p_input );
        char *psz_name = input_item_GetName( p_input );
        /* p_input->p_meta should not be null after a successful CreateThread */
        bool b_has_art = !EMPTY_STR( psz_arturl );

        if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) )
        {
            PL_DEBUG( "requesting art for %s", psz_name );
            libvlc_ArtRequest( p_playlist->p_libvlc, p_input );
        }
        free( psz_arturl );
        free( psz_name );
    }
    PL_UNLOCK;
    var_TriggerCallback( p_playlist, "activity" );
    PL_LOCK;

    return VLC_SUCCESS;
}
예제 #7
0
파일: fingerprinter.c 프로젝트: IAPark/vlc
static void DoFingerprint( fingerprinter_thread_t *p_fingerprinter,
                           acoustid_fingerprint_t *fp,
                           const char *psz_uri )
{
    input_item_t *p_item = input_item_New( NULL, NULL );
    if ( unlikely(p_item == NULL) )
         return;

    char *psz_sout_option;
    /* Note: need at -max- 2 channels, but we can't guess it before playing */
    /* the stereo upmix could make the mono tracks fingerprint to differ :/ */
    if ( asprintf( &psz_sout_option,
                   "sout=#transcode{acodec=%s,channels=2}:chromaprint",
                   ( VLC_CODEC_S16L == VLC_CODEC_S16N ) ? "s16l" : "s16b" )
         == -1 )
    {
        input_item_Release( p_item );
        return;
    }

    input_item_AddOption( p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED );
    free( psz_sout_option );
    input_item_AddOption( p_item, "vout=dummy", VLC_INPUT_OPTION_TRUSTED );
    input_item_AddOption( p_item, "aout=dummy", VLC_INPUT_OPTION_TRUSTED );
    if ( fp->i_duration )
    {
        if ( asprintf( &psz_sout_option, "stop-time=%u", fp->i_duration ) == -1 )
        {
            input_item_Release( p_item );
            return;
        }
        input_item_AddOption( p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED );
        free( psz_sout_option );
    }
    input_item_SetURI( p_item, psz_uri ) ;

    input_thread_t *p_input = input_Create( p_fingerprinter, p_item, "fingerprinter", NULL, NULL );
    input_item_Release( p_item );

    if( p_input == NULL )
        return;

    chromaprint_fingerprint_t chroma_fingerprint;

    chroma_fingerprint.psz_fingerprint = NULL;
    chroma_fingerprint.i_duration = fp->i_duration;

    var_Create( p_input, "fingerprint-data", VLC_VAR_ADDRESS );
    var_SetAddress( p_input, "fingerprint-data", &chroma_fingerprint );

    var_AddCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys );

    if( input_Start( p_input ) != VLC_SUCCESS )
    {
        var_DelCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys );
        input_Close( p_input );
    }
    else
    {
        p_fingerprinter->p_sys->processing.b_working = true;
        while( p_fingerprinter->p_sys->processing.b_working )
        {
            vlc_cond_wait( &p_fingerprinter->p_sys->processing.cond,
                           &p_fingerprinter->p_sys->processing.lock );
        }
        var_DelCallback( p_input, "intf-event", InputEventHandler, p_fingerprinter->p_sys );
        input_Stop( p_input );
        input_Close( p_input );

        fp->psz_fingerprint = chroma_fingerprint.psz_fingerprint;
        if( !fp->i_duration ) /* had not given hint */
            fp->i_duration = chroma_fingerprint.i_duration;
    }
}
예제 #8
0
파일: fingerprinter.c 프로젝트: Kubink/vlc
static void DoFingerprint( vlc_object_t *p_this, fingerprinter_sys_t *p_sys, acoustid_fingerprint_t *fp )
{
    p_sys->p_input = NULL;
    p_sys->p_item = NULL;
    p_sys->chroma_fingerprint.psz_fingerprint = NULL;
    vlc_cleanup_push( cancelDoFingerprint, p_sys );

    p_sys->p_item = input_item_New( NULL, NULL );
    if ( ! p_sys->p_item ) goto end;

    char *psz_sout_option;
    /* Note: need at -max- 2 channels, but we can't guess it before playing */
    /* the stereo upmix could make the mono tracks fingerprint to differ :/ */
    if ( asprintf( &psz_sout_option,
                   "sout=#transcode{acodec=%s,channels=2}:chromaprint",
                   ( VLC_CODEC_S16L == VLC_CODEC_S16N ) ? "s16l" : "s16b" )
         == -1 ) goto end;
    input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED );
    free( psz_sout_option );
    input_item_AddOption( p_sys->p_item, "vout=dummy", VLC_INPUT_OPTION_TRUSTED );
    input_item_AddOption( p_sys->p_item, "aout=dummy", VLC_INPUT_OPTION_TRUSTED );
    if ( fp->i_duration )
    {
        if ( asprintf( &psz_sout_option, "stop-time=%u", fp->i_duration ) == -1 ) goto end;
        input_item_AddOption( p_sys->p_item, psz_sout_option, VLC_INPUT_OPTION_TRUSTED );
        free( psz_sout_option );
    }
    input_item_SetURI( p_sys->p_item, p_sys->psz_uri ) ;

    p_sys->p_input = input_Create( p_this, p_sys->p_item, "fingerprinter", NULL );
    if ( p_sys->p_input )
    {
        p_sys->chroma_fingerprint.i_duration = fp->i_duration;
        var_Create( p_sys->p_input, "fingerprint-data", VLC_VAR_ADDRESS );
        var_SetAddress( p_sys->p_input, "fingerprint-data", & p_sys->chroma_fingerprint );

        input_Start( p_sys->p_input );

        /* Wait for input to start && end */
        p_sys->condwait.i_input_state = var_GetInteger( p_sys->p_input, "state" );

        if ( likely( var_AddCallback( p_sys->p_input, "intf-event",
                            inputStateCallback, p_sys ) == VLC_SUCCESS ) )
        {
            while( p_sys->condwait.i_input_state <= PAUSE_S )
            {
                vlc_mutex_lock( &p_sys->condwait.lock );
                mutex_cleanup_push( &p_sys->condwait.lock );
                vlc_cond_wait( &p_sys->condwait.wait, &p_sys->condwait.lock );
                vlc_cleanup_run();
            }
            var_DelCallback( p_sys->p_input, "intf-event", inputStateCallback, p_sys );
        }
        input_Stop( p_sys->p_input, true );
        input_Close( p_sys->p_input );
        p_sys->p_input = NULL;

        if ( p_sys->chroma_fingerprint.psz_fingerprint )
        {
            fp->psz_fingerprint = strdup( p_sys->chroma_fingerprint.psz_fingerprint );
            if ( ! fp->i_duration ) /* had not given hint */
                fp->i_duration = p_sys->chroma_fingerprint.i_duration;
        }
    }
end:
    vlc_cleanup_run( );
}