Ejemplo n.º 1
0
static int LoopInput( playlist_t *p_playlist )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_thread_t *p_input = p_sys->p_input;

    if( !p_input )
        return VLC_EGENERIC;

    if( ( p_sys->request.b_request || !vlc_object_alive( p_playlist ) ) && !p_input->b_die )
    {
        PL_DEBUG( "incoming request - stopping current input" );
        input_Stop( p_input, true );
    }

    /* This input is dead. Remove it ! */
    if( p_input->b_dead )
    {
        PL_DEBUG( "dead input" );

        PL_UNLOCK;
        /* We can unlock as we return VLC_EGENERIC (no event will be lost) */

        /* input_resource_t must be manipulated without playlist lock */
        if( !var_CreateGetBool( p_input, "sout-keep" ) )
            input_resource_TerminateSout( p_sys->p_input_resource );

        /* The DelCallback must be issued without playlist lock */
        var_DelCallback( p_input, "intf-event", InputEvent, p_playlist );

        PL_LOCK;

        p_sys->p_input = NULL;
        input_Close( p_input );

        UpdateActivity( p_playlist, -DEFAULT_INPUT_ACTIVITY );

        return VLC_EGENERIC;
    }
    /* This input is dying, let it do */
    else if( p_input->b_die )
    {
        PL_DEBUG( "dying input" );
    }
    /* This input has finished, ask it to die ! */
    else if( p_input->b_error || p_input->b_eof )
    {
        PL_DEBUG( "finished input" );
        input_Stop( p_input, false );
    }
    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
Archivo: item.c Proyecto: BossKing/vlc
/* Enqueue an item for preparsing, and play it, if needed */
static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
                           playlist_item_t *p_item )
{
    playlist_private_t *sys = pl_priv(p_playlist);

    PL_ASSERT_LOCKED;
    if( (i_mode & PLAYLIST_GO ) )
    {
        sys->request.b_request = true;
        sys->request.i_skip = 0;
        sys->request.p_item = p_item;
        if( sys->p_input != NULL )
            input_Stop( sys->p_input );
        vlc_cond_signal( &sys->signal );
    }
    /* Preparse if no artist/album info, and hasn't been preparsed already
       and if user has some preparsing option (auto-preparse variable)
       enabled*/
    char *psz_artist = input_item_GetArtist( p_item->p_input );
    char *psz_album = input_item_GetAlbum( p_item->p_input );

    if( sys->b_preparse && !input_item_IsPreparsed( p_item->p_input )
     && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) )
        libvlc_MetadataRequest( p_playlist->obj.libvlc, p_item->p_input, 0, -1,
                                NULL );
    free( psz_artist );
    free( psz_album );
}
Ejemplo n.º 3
0
/*
 * Release the associated input thread.
 *
 * Object lock is NOT held.
 * Input lock is held or instance is being destroyed.
 */
static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abort )
{
    assert( p_mi );

    input_thread_t *p_input_thread = p_mi->input.p_thread;
    if( !p_input_thread )
        return;

    var_DelCallback( p_input_thread, "can-seek",
                     input_seekable_changed, p_mi );
    var_DelCallback( p_input_thread, "can-pause",
                    input_pausable_changed, p_mi );
    var_DelCallback( p_input_thread, "intf-event",
                     input_event_changed, p_mi );

    /* We owned this one */
    input_Stop( p_input_thread, b_input_abort );

    vlc_thread_join( p_input_thread );

    assert( p_input_thread->b_dead );

    p_mi->input.p_thread = NULL;
    vlc_object_release( p_input_thread );
}
Ejemplo n.º 4
0
void libvlc_media_player_set_pause( libvlc_media_player_t *p_mi, int paused )
{
    input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi );
    if( !p_input_thread )
        return;

    libvlc_state_t state = libvlc_media_player_get_state( p_mi );
    if( state == libvlc_Playing || state == libvlc_Buffering )
    {
        if( paused )
        {
            if( libvlc_media_player_can_pause( p_mi ) )
                input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
            else
                input_Stop( p_input_thread, true );
        }
    }
    else
    {
        if( !paused )
            input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
    }

    vlc_object_release( p_input_thread );
}
Ejemplo n.º 5
0
/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    services_discovery_t *p_sd = ( services_discovery_t* )p_this;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;
    int i;

    vlc_cancel (p_sys->thread);
    vlc_join (p_sys->thread, NULL);

    var_DelCallback( p_sd, "podcast-urls", UrlsChange, p_sys );
    var_DelCallback( p_sd, "podcast-request", Request, p_sys );
    vlc_cond_destroy( &p_sys->wait );
    vlc_mutex_destroy( &p_sys->lock );

    for( i = 0; i < p_sys->i_input; i++ )
    {
        input_thread_t *p_input = p_sd->p_sys->pp_input[i];
        if( !p_input )
            continue;

        input_Stop( p_input, true );
        vlc_thread_join( p_input );
        vlc_object_release( p_input );

        p_sd->p_sys->pp_input[i] = NULL;
    }
    free( p_sd->p_sys->pp_input );
    for( i = 0; i < p_sys->i_urls; i++ ) free( p_sys->ppsz_urls[i] );
    free( p_sys->ppsz_urls );
    for( i = 0; i < p_sys->i_items; i++ ) vlc_gc_decref( p_sys->pp_items[i] );
    free( p_sys->pp_items );
    free( p_sys->psz_request );
    free( p_sys );
}
Ejemplo n.º 6
0
Archivo: item.c Proyecto: Annovae/vlc
/* Enqueue an item for preparsing, and play it, if needed */
static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
                           playlist_item_t *p_item )
{
    PL_ASSERT_LOCKED;
    if( (i_mode & PLAYLIST_GO ) )
    {
        pl_priv(p_playlist)->request.b_request = true;
        pl_priv(p_playlist)->request.i_skip = 0;
        pl_priv(p_playlist)->request.p_item = p_item;
        if( pl_priv(p_playlist)->p_input )
            input_Stop( pl_priv(p_playlist)->p_input, true );
        pl_priv(p_playlist)->request.i_status = PLAYLIST_RUNNING;
        vlc_cond_signal( &pl_priv(p_playlist)->signal );
    }
    /* Preparse if no artist/album info, and hasn't been preparsed allready
       and if user has some preparsing option (auto-preparse variable)
       enabled*/
    char *psz_artist = input_item_GetArtist( p_item->p_input );
    char *psz_album = input_item_GetAlbum( p_item->p_input );
    if( pl_priv(p_playlist)->b_auto_preparse &&
        input_item_IsPreparsed( p_item->p_input ) == false &&
            ( EMPTY_STR( psz_artist ) || ( EMPTY_STR( psz_album ) ) )
          )
        libvlc_MetaRequest( p_playlist->p_libvlc, p_item->p_input );
    free( psz_artist );
    free( psz_album );
}
Ejemplo n.º 7
0
Archivo: thread.c Proyecto: Kubink/vlc
static void LoopInput( playlist_t *p_playlist )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_thread_t *p_input = p_sys->p_input;

    assert( p_input != NULL );

    if( p_sys->request.b_request || p_sys->killed )
    {
        PL_DEBUG( "incoming request - stopping current input" );
        input_Stop( p_input, true );
    }

#warning Unsynchronized access to *p_input flags...
    /* This input is dead. Remove it ! */
    if( p_input->b_dead )
    {
        p_sys->p_input = NULL;
        PL_DEBUG( "dead input" );
        PL_UNLOCK;

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

        /* WARNING: Input resource manipulation and callback deletion are
         * incompatible with the playlist lock. */
        if( !var_InheritBool( p_input, "sout-keep" ) )
            input_resource_TerminateSout( p_sys->p_input_resource );
        var_DelCallback( p_input, "intf-event", InputEvent, p_playlist );

        input_Close( p_input );
        var_TriggerCallback( p_playlist, "activity" );
        PL_LOCK;
        return;
    }
    /* This input has finished, ask it to die ! */
    else if( p_input->b_error || p_input->b_eof )
    {
        PL_DEBUG( "finished input" );
        input_Stop( p_input, false );
    }

    vlc_cond_wait( &p_sys->signal, &p_sys->lock );
}
Ejemplo n.º 8
0
static void cancelDoFingerprint( void *p_arg )
{
    fingerprinter_sys_t *p_sys = ( fingerprinter_sys_t * ) p_arg;
    if ( p_sys->p_input )
    {
        input_Stop( p_sys->p_input, true );
        input_Close( p_sys->p_input );
    }
    /* cleanup temporary result */
    if ( p_sys->chroma_fingerprint.psz_fingerprint )
        FREENULL( p_sys->chroma_fingerprint.psz_fingerprint );
    if ( p_sys->p_item )
        input_item_Release( p_sys->p_item );
}
Ejemplo n.º 9
0
/*****************************************************************************
 * Run: main thread
 *****************************************************************************/
static void *Run( void *data )
{
    services_discovery_t *p_sd = data;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        while( !p_sys->b_update )
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );

        int canc = vlc_savecancel ();
        msg_Dbg( p_sd, "Update required" );

        if( p_sys->update_type == UPDATE_URLS )
        {
          char* psz_urls = var_GetNonEmptyString( p_sd, "podcast-urls" );
          ParseUrls( p_sd, psz_urls );
          free( psz_urls );
        }
        else if( p_sys->update_type == UPDATE_REQUEST )
        {
          ParseRequest( p_sd );
        }

        p_sys->b_update = false;

        for( int i = 0; i < p_sd->p_sys->i_input; i++ )
        {
            input_thread_t *p_input = p_sd->p_sys->pp_input[i];

            if( p_input->b_eof || p_input->b_error )
            {
                input_Stop( p_input, false );
                vlc_thread_join( p_input );
                vlc_object_release( p_input );

                p_sd->p_sys->pp_input[i] = NULL;
                REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                i--;
            }
        }
        vlc_restorecancel (canc);
    }
    vlc_cleanup_pop();
    assert(0); /* dead code */
}
Ejemplo n.º 10
0
/*****************************************************************************
 * Run: main thread
 *****************************************************************************/
VLC_NORETURN
static void *Run( void *data )
{
    services_discovery_t *p_sd = data;
    services_discovery_sys_t *p_sys  = p_sd->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    mutex_cleanup_push( &p_sys->lock );
    for( ;; )
    {
        while( !p_sys->b_update )
            vlc_cond_wait( &p_sys->wait, &p_sys->lock );

        int canc = vlc_savecancel ();
        msg_Dbg( p_sd, "Update required" );

        if( p_sys->update_type == UPDATE_URLS )
        {
            char *psz_urls = var_GetNonEmptyString( p_sd->p_parent,
                                                    "podcast-urls" );
            ParseUrls( p_sd, psz_urls );
            free( psz_urls );
        }
        else if( p_sys->update_type == UPDATE_REQUEST )
            ParseRequest( p_sd );

        p_sys->b_update = false;

        for( int i = 0; i < p_sd->p_sys->i_input; i++ )
        {
            input_thread_t *p_input = p_sd->p_sys->pp_input[i];
            int state = var_GetInteger( p_input, "state" );

            if( state == END_S || state == ERROR_S )
            {
                input_Stop( p_input );
                input_Close( p_input );

                p_sd->p_sys->pp_input[i] = NULL;
                REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                i--;
            }
        }
        vlc_restorecancel (canc);
    }
    vlc_cleanup_pop();
    vlc_assert_unreachable(); /* dead code */
}
Ejemplo n.º 11
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 );
}
Ejemplo n.º 12
0
static void PreparserCloseInput( void* preparser_, void* task_ )
{
    input_preparser_task_t* task = task_;
    input_preparser_req_t *req = task->req;

    input_preparser_t* preparser = preparser_;
    input_thread_t* input = task->input;
    input_item_t* item = input_priv(task->input)->p_item;

    int status;
    switch( atomic_load( &task->state ) )
    {
        case END_S:
            status = ITEM_PREPARSE_DONE;
            break;
        case ERROR_S:
            status = ITEM_PREPARSE_FAILED;
            break;
        default:
            status = ITEM_PREPARSE_TIMEOUT;
    }

    input_Stop( input );
    input_Close( input );

    if( preparser->fetcher )
    {
        task->preparse_status = status;
        if (!input_fetcher_Push(preparser->fetcher, item, 0,
                               &input_fetcher_callbacks, task))
        {
            ReqHold(task->req);
            return;
        }
    }

    free(task);

    input_item_SetPreparsed( item, true );
    if (req->cbs && req->cbs->on_preparse_ended)
        req->cbs->on_preparse_ended(req->item, status, req->userdata);
}
Ejemplo n.º 13
0
static void LoopInput( playlist_t *p_playlist )
{
    playlist_private_t *p_sys = pl_priv(p_playlist);
    input_thread_t *p_input = p_sys->p_input;

    assert( p_input != NULL );

    if( p_sys->request.b_request || p_sys->killed )
    {
        PL_DEBUG( "incoming request - stopping current input" );
        input_Stop( p_input );
    }

    switch( var_GetInteger( p_input, "state" ) )
    {
    case END_S:
    case ERROR_S:
    /* This input is dead. Remove it ! */
        p_sys->p_input = NULL;
        PL_DEBUG( "dead input" );
        PL_UNLOCK;

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

        /* WARNING: Input resource manipulation and callback deletion are
         * incompatible with the playlist lock. */
        if( !var_InheritBool( p_input, "sout-keep" ) )
            input_resource_TerminateSout( p_sys->p_input_resource );
        var_DelCallback( p_input, "intf-event", InputEvent, p_playlist );

        input_Close( p_input );
        PL_LOCK;
        break;
    default:
        vlc_cond_wait( &p_sys->signal, &p_sys->lock );
    }
}
Ejemplo n.º 14
0
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;
    }
}
Ejemplo n.º 15
0
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( );
}