Beispiel #1
0
/**
 * Delete an update_t struct
 *
 * \param p_update update_t* pointer
 * \return nothing
 */
void update_Delete( update_t *p_update )
{
    assert( p_update );

    if( p_update->p_check )
    {
        vlc_object_kill( p_update->p_check );
        vlc_thread_join( p_update->p_check );
        vlc_object_release( p_update->p_check );
    }

    if( p_update->p_download )
    {
        vlc_object_kill( p_update->p_download );
        vlc_thread_join( p_update->p_download );
        vlc_object_release( p_update->p_download );
    }

    vlc_mutex_destroy( &p_update->lock );

    free( p_update->release.psz_url );
    free( p_update->release.psz_desc );
    free( p_update->p_pkey );

    free( p_update );
}
Beispiel #2
0
/**
 * Stops and destroys all interfaces
 * @param p_libvlc the LibVLC instance
 */
void intf_DestroyAll( libvlc_int_t *p_libvlc )
{
    intf_thread_t *p_first;

    vlc_mutex_lock( &lock );
    p_first = libvlc_priv( p_libvlc )->p_intf;
#ifndef NDEBUG
    libvlc_priv( p_libvlc )->p_intf = NULL;
#endif
    vlc_mutex_unlock( &lock );

    /* Tell the interfaces to die */
    for( intf_thread_t *p_intf = p_first; p_intf; p_intf = p_intf->p_next )
        vlc_object_kill( p_intf );

    /* Cleanup the interfaces */
    for( intf_thread_t *p_intf = p_first; p_intf != NULL; )
    {
        intf_thread_t *p_next = p_intf->p_next;

        if( p_intf->pf_run )
        {
            vlc_cancel( p_intf->thread );
            vlc_join( p_intf->thread, NULL );
        }
        module_unneed( p_intf, p_intf->p_module );
        config_ChainDestroy( p_intf->p_cfg );
        vlc_object_release( p_intf );

        p_intf = p_next;
    }
}
Beispiel #3
0
void transcode_video_close( sout_stream_t *p_stream,
                                   sout_stream_id_t *id )
{
    if( p_stream->p_sys->i_threads >= 1 )
    {
        vlc_mutex_lock( &p_stream->p_sys->lock_out );
        vlc_object_kill( p_stream->p_sys );
        vlc_cond_signal( &p_stream->p_sys->cond );
        vlc_mutex_unlock( &p_stream->p_sys->lock_out );
        vlc_thread_join( p_stream->p_sys );
        vlc_mutex_destroy( &p_stream->p_sys->lock_out );
        vlc_cond_destroy( &p_stream->p_sys->cond );
    }

    video_timer_close( id->p_encoder );

    /* Close decoder */
    if( id->p_decoder->p_module )
        module_unneed( id->p_decoder, id->p_decoder->p_module );
    if( id->p_decoder->p_description )
        vlc_meta_Delete( id->p_decoder->p_description );

    free( id->p_decoder->p_owner );

    /* Close encoder */
    if( id->p_encoder->p_module )
        module_unneed( id->p_encoder, id->p_encoder->p_module );

    /* Close filters */
    if( id->p_f_chain )
        filter_chain_Delete( id->p_f_chain );
    if( id->p_uf_chain )
        filter_chain_Delete( id->p_uf_chain );
}
Beispiel #4
0
/*****************************************************************************
 * Close: close the plugin
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    filter_t     *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = p_filter->p_sys;

    /* Stop Goom Thread */
    vlc_object_kill( p_sys->p_thread );

    vlc_mutex_lock( &p_sys->p_thread->lock );
    vlc_cond_signal( &p_sys->p_thread->wait );
    vlc_mutex_unlock( &p_sys->p_thread->lock );

    vlc_thread_join( p_sys->p_thread );

    /* Free data */
    aout_filter_RequestVout( p_filter, p_sys->p_thread->p_vout, 0 );
    vlc_mutex_destroy( &p_sys->p_thread->lock );
    vlc_cond_destroy( &p_sys->p_thread->wait );

    while( p_sys->p_thread->i_blocks-- )
    {
        block_Release( p_sys->p_thread->pp_blocks[p_sys->p_thread->i_blocks] );
    }

    vlc_object_release( p_sys->p_thread );

    free( p_sys );
}
Beispiel #5
0
/**
 ****************************************************************************
 * Destroy a vlc object (Internal)
 *
 * This function destroys an object that has been previously allocated with
 * vlc_object_create. The object's refcount must be zero and it must not be
 * attached to other objects in any way.
 *
 * This function must be called with cancellation disabled (currently).
 *****************************************************************************/
static void vlc_object_destroy( vlc_object_t *p_this )
{
    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    /* Send a kill to the object's thread if applicable */
    vlc_object_kill( p_this );

    /* Call the custom "subclass" destructor */
    if( p_priv->pf_destructor )
        p_priv->pf_destructor( p_this );

    /* Any thread must have been cleaned up at this point. */
    assert( !p_priv->b_thread );

    /* Destroy the associated variables. */
    var_DestroyAll( p_this );

    vlc_cond_destroy( &p_priv->var_wait );
    vlc_mutex_destroy( &p_priv->var_lock );

    free( p_this->psz_header );

    free( p_priv->psz_name );

    vlc_spin_destroy( &p_priv->ref_spin );
    if( p_priv->pipes[1] != -1 && p_priv->pipes[1] != p_priv->pipes[0] )
        close( p_priv->pipes[1] );
    if( p_priv->pipes[0] != -1 )
        close( p_priv->pipes[0] );
    if( VLC_OBJECT(p_this->p_libvlc) == p_this )
        vlc_mutex_destroy (&(libvlc_priv ((libvlc_int_t *)p_this)->structure_lock));

    free( p_priv );
}
Beispiel #6
0
/*****************************************************************************
 * MonitorLibVLCDeath: Used when b_should_run_on_first_thread is set.
 *****************************************************************************/
static void * MonitorLibVLCDeath( vlc_object_t * p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    libvlc_int_t * p_libvlc = p_intf->p_libvlc;
    vlc_object_lock( p_libvlc );
    while(vlc_object_alive( p_libvlc ) )
    {
        if(p_intf->b_die)
        {
            vlc_object_unlock( p_libvlc );
            return NULL;
        }
        vlc_object_wait( p_libvlc );
    }
    vlc_object_unlock( p_libvlc );

    /* Someone killed libvlc */

    /* Make sure we kill all interface objects, especially
     * those that are blocking libvlc (running on main thread) */
    vlc_list_t * p_list = vlc_list_find( p_libvlc, VLC_OBJECT_INTF, FIND_CHILD );
    for( int i = 0; i < p_list->i_count; i++ )
    {
        vlc_object_t * p_intf = p_list->p_values[i].p_object;
        vlc_object_kill( p_intf );
    }
    vlc_list_release( p_list );
    return NULL;
}
Beispiel #7
0
/*****************************************************************************
 * Close: close the ALSA device
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;
    int i_snd_rc;

    /* Make sure that the thread will stop once it is waken up */
    vlc_object_kill( p_aout );

    /* make sure the audio output thread is waken up */
    vlc_mutex_lock( &p_aout->output.p_sys->lock );
    vlc_cond_signal( &p_aout->output.p_sys->wait );
    vlc_mutex_unlock( &p_aout->output.p_sys->lock );

    /* */
    vlc_thread_join( p_aout );
    p_aout->b_die = false;

    i_snd_rc = snd_pcm_close( p_sys->p_snd_pcm );

    if( i_snd_rc > 0 )
    {
        msg_Err( p_aout, "failed closing ALSA device (%s)",
                         snd_strerror( i_snd_rc ) );
    }

#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif

    free( p_sys );
}
Beispiel #8
0
/**
 * Check for updates
 *
 * \param p_update pointer to update struct
 * \param pf_callback pointer to a function to call when the update_check is finished
 * \param p_data pointer to some datas to give to the callback
 * \returns nothing
 */
void update_Check( update_t *p_update, void (*pf_callback)( void*, bool ), void *p_data )
{
    assert( p_update );

    // If the object already exist, destroy it
    if( p_update->p_check )
    {
        vlc_object_kill( p_update->p_check );
        vlc_thread_join( p_update->p_check );
        vlc_object_release( p_update->p_check );
    }

    update_check_thread_t *p_uct =
        vlc_custom_create( p_update->p_libvlc, sizeof( *p_uct ),
                           VLC_OBJECT_GENERIC, "update check" );
    if( !p_uct ) return;

    p_uct->p_update = p_update;
    p_update->p_check = p_uct;
    p_uct->pf_callback = pf_callback;
    p_uct->p_data = p_data;

    vlc_thread_create( p_uct, "check for update", update_CheckReal,
                       VLC_THREAD_PRIORITY_LOW );
}
Beispiel #9
0
Datei: qte.cpp Projekt: Kafay/vlc
/*****************************************************************************
 * CloseVideo: destroy Sys video thread output method
 *****************************************************************************
 * Terminate an output method created by Open
 *****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
    vout_thread_t * p_vout = (vout_thread_t *)p_this;

    msg_Dbg( p_vout, "close" );
    if( p_vout->p_sys->p_event )
    {
        vlc_object_detach( p_vout->p_sys->p_event );

        /* Kill RunQtThread */
        vlc_object_kill( p_vout->p_sys->p_event );
        CloseDisplay(p_vout);

        vlc_thread_join( p_vout->p_sys->p_event );
        vlc_object_release( p_vout->p_sys->p_event );
    }

#ifdef NEED_QTE_MAIN
    msg_Dbg( p_vout, "releasing gui-helper" );
    module_unneed( p_vout, p_vout->p_sys->p_qte_main );
#endif

    if( p_vout->p_sys )
    {
        free( p_vout->p_sys );
        p_vout->p_sys = NULL;
    }
}
Beispiel #10
0
static void stop_osdvnc ( filter_t *p_filter )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    /* It will unlock socket reading */
    vlc_object_kill( p_filter );

    /* */
    if( p_sys->p_worker_thread )
    {
        msg_Dbg( p_filter, "joining worker_thread" );
        vlc_object_kill( p_sys->p_worker_thread );
        vlc_thread_join( p_sys->p_worker_thread );
        vlc_object_release( p_sys->p_worker_thread );
        msg_Dbg( p_filter, "released worker_thread" );
    }

    msg_Dbg( p_filter, "osdvnc stopped" );
}
Beispiel #11
0
/***********************************************************************
 * Stop
 ***********************************************************************/
static void ObjectKillChildrens( vlc_object_t *p_obj )
{
    vlc_list_t *p_list;
    int i;
    vlc_object_kill( p_obj );

    p_list = vlc_list_children( p_obj );
    for( i = 0; i < p_list->i_count; i++ )
        ObjectKillChildrens( p_list->p_values[i].p_object );
    vlc_list_release( p_list );
}
Beispiel #12
0
/**
 * MonitorLibVLCDeath: Used when b_should_run_on_first_thread is set.
 *
 * @param p_this: the interface object
 */
static void * MonitorLibVLCDeath( vlc_object_t * p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    libvlc_int_t * p_libvlc = p_intf->p_libvlc;
    int canc = vlc_savecancel ();

    libvlc_InternalWait( p_libvlc );

    vlc_object_kill( p_intf ); /* Kill the stupid first thread interface */
    vlc_restorecancel (canc);
    return NULL;
}
Beispiel #13
0
/*****************************************************************************
 * InterfaceWindow::QuitRequested
 *****************************************************************************/
bool InterfaceWindow::QuitRequested()
{
    if( p_playlist )
    {
        playlist_Stop( p_playlist );
    }
    p_mediaControl->SetStatus(-1, INPUT_RATE_DEFAULT);

     _StoreSettings();

    vlc_object_kill( p_intf );

    return( true );
}
Beispiel #14
0
/*****************************************************************************
 * Close: close the DSP audio device
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;

    vlc_object_kill( p_aout );
    vlc_thread_join( p_aout );
    p_aout->b_die = false;

    ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL );
    close( p_sys->i_fd );

    free( p_sys );
}
Beispiel #15
0
/*****************************************************************************
 * CloseAudio: close the audio device
 *****************************************************************************/
void CloseAudio ( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    int i_ret;

    vlc_object_kill( p_aout );
    vlc_thread_join( p_aout );

    if( ( i_ret = snd_pcm_close( p_aout->output.p_sys->p_pcm_handle ) ) < 0 )
    {
        msg_Err( p_aout, "unable to close audio device (%s)",
                         snd_strerror( i_ret ) );
    }

    free( p_aout->output.p_sys->p_silent_buffer );
    free( p_aout->output.p_sys );
}
Beispiel #16
0
/*****************************************************************************
 * Close: close our file
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
    u32 i;
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;

    vlc_object_kill( p_aout );
    vlc_thread_join( p_aout );
    p_aout->b_die = false;

    do
    {
        i = p_sys->pPlayer->WaitForBuffer();
    } while( i != 0 && i != p_sys->nBuffers );

    p_sys->pPlayer->Close();
    delete p_sys->pPlayer;

    free( p_sys->ppBuffers );
    free( p_sys );
}
Beispiel #17
0
void CThread::Terminate(void)
{
   // Set Termination Flag and EventObject!
   // and wait for Termination

#if defined(_ATMO_VLC_PLUGIN_)
   if(m_pAtmoThread)
   {
      vlc_mutex_lock( &m_TerminateLock );
      m_bTerminated = ATMO_TRUE;
      vlc_cond_signal( &m_TerminateCond  );
      vlc_mutex_unlock( &m_TerminateLock );

      vlc_object_kill( m_pAtmoThread );
      vlc_thread_join( m_pAtmoThread );
   }
#else
   m_bTerminated = ATMO_TRUE;
   SetEvent(m_hTerminateEvent);
   WaitForSingleObject(m_hThread,INFINITE);
#endif
}
Beispiel #18
0
void playlist_Deactivate( playlist_t *p_playlist )
{
    /* */
    playlist_private_t *p_sys = pl_priv(p_playlist);

    msg_Dbg( p_playlist, "deactivating the playlist" );

    PL_LOCK;
    vlc_object_kill( p_playlist );
    vlc_cond_signal( &p_sys->signal );
    PL_UNLOCK;

    vlc_join( p_sys->thread, NULL );
    assert( !p_sys->p_input );

    /* release input resources */
    if( p_sys->p_input_resource )
    {
        input_resource_Terminate( p_sys->p_input_resource );
        input_resource_Release( p_sys->p_input_resource );
    }
    p_sys->p_input_resource = NULL;

    if( var_InheritBool( p_playlist, "media-library" ) )
        playlist_MLDump( p_playlist );

    PL_LOCK;

    /* Release the current node */
    set_current_status_node( p_playlist, NULL );

    /* Release the current item */
    set_current_status_item( p_playlist, NULL );

    PL_UNLOCK;

    msg_Dbg( p_playlist, "playlist correctly deactivated" );
}
Beispiel #19
0
/**
 * Starts and runs the interface thread.
 *
 * \param p_intf the interface thread
 * \return VLC_SUCCESS on success, an error number else
 */
int intf_RunThread( intf_thread_t *p_intf )
{
#if defined( __APPLE__ ) || defined( WIN32 )
    /* Hack to get Mac OS X Cocoa runtime running
     * (it needs access to the main thread) */
    if( p_intf->b_should_run_on_first_thread )
    {
        if( vlc_thread_create( p_intf, "interface", MonitorLibVLCDeath,
                               VLC_THREAD_PRIORITY_LOW, false ) )
        {
            msg_Err( p_intf, "cannot spawn libvlc death monitoring thread" );
            return VLC_EGENERIC;
        }
        RunInterface( VLC_OBJECT(p_intf) );

        /* Make sure our MonitorLibVLCDeath thread exit */
        vlc_object_kill( p_intf );
        /* It is monitoring libvlc, not the p_intf */
        vlc_object_signal( p_intf->p_libvlc );
        vlc_thread_join( p_intf );

        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
        return VLC_SUCCESS;
    }
#endif
    /* Run the interface in a separate thread */
    if( vlc_thread_create( p_intf, "interface", RunInterface,
                           VLC_THREAD_PRIORITY_LOW, false ) )
    {
        msg_Err( p_intf, "cannot spawn interface thread" );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Beispiel #20
0
/*****************************************************************************
 * Close: free unused data structures
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys = p_access->p_sys;

    if( p_sys->p_ev )
    {
        /* stop the event handler */
        vlc_object_kill( p_sys->p_ev );

        if( p_sys->p_raw1394 )
            raw1394_iso_shutdown( p_sys->p_raw1394 );

        vlc_thread_join( p_sys->p_ev );
        vlc_mutex_destroy( &p_sys->p_ev->lock );

        /* Cleanup frame data */
        if( p_sys->p_ev->p_frame )
        {
            block_ChainRelease( p_sys->p_ev->p_frame );
            p_sys->p_ev->p_frame = NULL;
            p_sys->p_ev->pp_last = &p_sys->p_frame;
        }
        vlc_object_release( p_sys->p_ev );
    }

    if( p_sys->p_frame )
        block_ChainRelease( p_sys->p_frame );
    if( p_sys->p_raw1394 )
        raw1394_destroy_handle( p_sys->p_raw1394 );

    AVCClose( p_access );

    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys );
}
Beispiel #21
0
static void* vnc_worker_thread( vlc_object_t *p_thread_obj )
{
    filter_t* p_filter = (filter_t*)(p_thread_obj->p_parent);
    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_object_t *p_update_request_thread;
    int canc = vlc_savecancel ();

    msg_Dbg( p_filter, "VNC worker thread started" );

    if( !open_vnc_connection ( p_filter ) )
    {
        msg_Err( p_filter, "Could not connect to vnc host" );
        goto exit;
    }

    if( !handshaking ( p_filter ) )
    {
        msg_Err( p_filter, "Error occured while handshaking vnc host" );
        goto exit;
    }

    p_sys->b_connection_active = true; /* to enable sending key
                                            * and mouse events to host */

    /* Create an empty picture for VNC the data */
    vlc_mutex_lock( &p_sys->lock );
    p_sys->p_pic = picture_New( VLC_CODEC_YUVA,
                                p_sys->i_vnc_width, p_sys->i_vnc_height, 1, 1 );
    if( !p_sys->p_pic )
    {
        vlc_mutex_unlock( &p_sys->lock );
        goto exit;
    }
	p_sys->i_vnc_pixels = p_sys->i_vnc_width * p_sys->i_vnc_height;

    vlc_mutex_unlock( &p_sys->lock );

    /* create the update request thread */
    p_update_request_thread = vlc_object_create( p_filter,
                                                 sizeof( vlc_object_t ) );
    vlc_object_attach( p_update_request_thread, p_filter );
    if( vlc_thread_create( p_update_request_thread,
                           update_request_thread, VLC_THREAD_PRIORITY_LOW ) )
    {
        vlc_object_release( p_update_request_thread );
        msg_Err( p_filter, "cannot spawn vnc update request thread" );
        goto exit;
    }

    /* connection is initialized, now read and handle server messages */
    while( vlc_object_alive( p_thread_obj ) )
    {
        rfbServerToClientMsg msg;
        int i_msgSize;

        memset( &msg, 0, sizeof(msg) );

        if( !read_exact(p_filter, p_sys->i_socket, (char*)&msg, 1 ) )
        {
            msg_Err( p_filter, "Error while waiting for next server message");
            break;
        }
        switch (msg.type)
        {
        case rfbFramebufferUpdate:
            i_msgSize = sz_rfbFramebufferUpdateMsg;
            break;
        case rfbSetColourMapEntries:
            i_msgSize = sz_rfbSetColourMapEntriesMsg;
            break;
        case rfbBell:
            i_msgSize = sz_rfbBellMsg;
            break;
        case rfbServerCutText:
            i_msgSize = sz_rfbServerCutTextMsg;
            break;
        case rfbReSizeFrameBuffer:
            i_msgSize = sz_rfbReSizeFrameBufferMsg;
            break;
        default:
            i_msgSize = 0;
            msg_Err( p_filter, "Invalid message %u received", msg.type );
            break;
        }

        if( i_msgSize <= 0 )
            break;

        if( --i_msgSize > 0 )
        {
            if ( !read_exact( p_filter, p_sys->i_socket,
                              ((char*)&msg)+1, i_msgSize ) )
            {
                msg_Err( p_filter, "Error while reading message of type %u",
                         msg.type );
                break;
            }
        }
        process_server_message( p_filter, &msg);
    }

    msg_Dbg( p_filter, "joining update_request_thread" );
    vlc_object_kill( p_update_request_thread );
    vlc_thread_join( p_update_request_thread );
    vlc_object_release( p_update_request_thread );
    msg_Dbg( p_filter, "released update_request_thread" );

exit:

    vlc_mutex_lock( &p_sys->lock );
    p_sys->b_connection_active = false;

    if (p_sys->i_socket >= 0)
        net_Close(p_sys->i_socket);

    if( p_sys->p_pic )
        picture_Release( p_sys->p_pic );

    /* It will hide the subtitle */
    p_sys->b_continue = false;
    p_sys->b_need_update = true;
    vlc_mutex_unlock( &p_sys->lock );

    msg_Dbg( p_filter, "VNC message reader thread ended" );
    vlc_restorecancel (canc);
    return NULL;
}
Beispiel #22
0
/**
 * Stops the interface thread
 *
 * This function asks the interface thread to stop
 * \param p_intf the interface thread
 * \return nothing
 */
void intf_StopThread( intf_thread_t *p_intf )
{
    /* Tell the interface to die */
    vlc_object_kill( p_intf );
    vlc_thread_join( p_intf );
}
Beispiel #23
0
/**
 * Create and start an interface.
 *
 * @param p_this the calling vlc_object_t
 * @param psz_module a preferred interface module
 * @return VLC_SUCCESS or an error code
 */
int intf_Create( vlc_object_t *p_this, const char *psz_module )
{
    libvlc_int_t *p_libvlc = p_this->p_libvlc;
    intf_thread_t * p_intf;

    /* Allocate structure */
    p_intf = vlc_custom_create( p_libvlc, sizeof( *p_intf ), "interface" );
    if( !p_intf )
        return VLC_ENOMEM;

    /* Variable used for interface spawning */
    vlc_value_t val, text;
    var_Create( p_intf, "intf-add", VLC_VAR_STRING |
                VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
    text.psz_string = _("Add Interface");
    var_Change( p_intf, "intf-add", VLC_VAR_SETTEXT, &text, NULL );
#if !defined(WIN32) && defined(HAVE_ISATTY)
    if( isatty( 0 ) )
#endif
    {
        val.psz_string = (char *)"rc";
        text.psz_string = (char *)_("Console");
        var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
    }
    val.psz_string = (char *)"telnet";
    text.psz_string = (char *)_("Telnet");
    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
    val.psz_string = (char *)"http";
    text.psz_string = (char *)_("Web");
    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
    val.psz_string = (char *)"logger";
    text.psz_string = (char *)_("Debug logging");
    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );
    val.psz_string = (char *)"gestures";
    text.psz_string = (char *)_("Mouse Gestures");
    var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text );

    var_AddCallback( p_intf, "intf-add", AddIntfCallback, NULL );

    /* Attach interface to LibVLC */
#if defined( __APPLE__ )
    p_intf->b_should_run_on_first_thread = false;
#endif

    /* Choose the best module */
    p_intf->p_cfg = NULL;
    char *psz_parser = *psz_module == '$'
                     ? var_CreateGetString(p_intf,psz_module+1)
                     : strdup( psz_module );
    char *psz_tmp = config_ChainCreate( &p_intf->psz_intf, &p_intf->p_cfg,
                                        psz_parser );
    free( psz_tmp );
    free( psz_parser );
    p_intf->p_module = module_need( p_intf, "interface", p_intf->psz_intf, true );
    if( p_intf->p_module == NULL )
    {
        msg_Err( p_intf, "no suitable interface module" );
        goto error;
    }

#if defined( __APPLE__ )
    /* Hack to get Mac OS X Cocoa runtime running
     * (it needs access to the main thread) */
    if( p_intf->b_should_run_on_first_thread )
    {
        if( vlc_clone( &p_intf->thread,
                       MonitorLibVLCDeath, p_intf, VLC_THREAD_PRIORITY_LOW ) )
        {
            msg_Err( p_intf, "cannot spawn libvlc death monitoring thread" );
            goto error;
        }
        assert( p_intf->pf_run );
        p_intf->pf_run( p_intf );

        /* It is monitoring libvlc, not the p_intf */
        vlc_object_kill( p_intf->p_libvlc );

        vlc_join( p_intf->thread, NULL );
    }
    else
#endif
    /* Run the interface in a separate thread */
    if( p_intf->pf_run
     && vlc_clone( &p_intf->thread,
                   RunInterface, p_intf, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_intf, "cannot spawn interface thread" );
        goto error;
    }

    vlc_mutex_lock( &lock );
    p_intf->p_next = libvlc_priv( p_libvlc )->p_intf;
    libvlc_priv( p_libvlc )->p_intf = p_intf;
    vlc_mutex_unlock( &lock );

    return VLC_SUCCESS;

error:
    if( p_intf->p_module )
        module_unneed( p_intf, p_intf->p_module );
    config_ChainDestroy( p_intf->p_cfg );
    free( p_intf->psz_intf );
    vlc_object_release( p_intf );
    return VLC_EGENERIC;
}
Beispiel #24
0
static void Run(intf_thread_t *p_intf) {
    intf_sys_t *p_sys = p_intf->p_sys;
    input_thread_t *p_input = NULL;
    playlist_t *p_playlist = pl_Get(p_intf);
    int *pi_fd, i_listen = 0, i_err;

    p_intf->p_sys->p_playlist = p_playlist;

    for (pi_fd = p_sys->pi_socket; *pi_fd != -1; pi_fd++)
        i_listen++;
    for (; vlc_object_alive(p_intf);) {
        vlc_value_t val;
        struct pollfd fd[i_listen + 2];

        vlc_testcancel();

        if (p_input == NULL) {
            p_input = playlist_CurrentInput(p_playlist);
            if (p_input) {
                var_AddCallback(p_input, "intf-event", InputEvent, p_intf);
            }
        }
        else {
            if (p_input->b_dead || !vlc_object_alive(p_input)) {
                var_DelCallback(p_input, "intf-event", InputEvent, p_intf);
                vlc_object_release(p_input);
                p_input = NULL;
            }
        }
        memset(&fd, 0, sizeof(fd[0]) * (i_listen + 1));
        if (p_sys->i_socket == -1) {
            for (int i = 0; i < i_listen; i++) {
                fd[i].fd = p_sys->pi_socket[i];
                fd[i].events = POLLIN;
                fd[i].revents = 0;
            }
        }
        else {
            fd[0].fd = p_sys->i_wakeup[0];
            fd[0].events = POLLIN;
            fd[0].revents = 0;
            fd[1].fd = p_sys->i_socket;
            fd[1].events = POLLIN | (p_sys->i_write_length > 0 ? POLLOUT : 0);
            fd[1].revents = 0;
        }
        i_err = poll(fd, (p_sys->i_socket != -1) ? 2 : i_listen, -1);
        if (i_err < 0) {
            msg_Dbg(p_intf, "poll() failed");
            vlc_object_kill(p_intf);
            break;
        }
        if (i_err == 0)
            continue;
        if (p_sys->i_socket == -1) {
            for (int i = 0; i < i_listen; i++) {
                if (fd[i].revents & POLLIN) {
                    int client = net_AcceptSingle(VLC_OBJECT(p_intf), fd[i].fd);
                    if (client == -1)
                        continue;
                    p_sys->i_socket = client;
                    break;
                }
            }
        }
        else {
            if (fd[0].revents & POLLIN) {
                char ch;

                read(fd[0].fd, &ch, 1);
            }
            if (fd[1].revents & (POLLERR|POLLHUP|POLLNVAL)) {
                net_Close(fd[0].fd);
                p_sys->i_socket = -1;
                msg_Dbg(VLC_OBJECT(p_intf), "connection error");
                continue;
            }
            ssize_t i_len, i_test;
            if (fd[1].revents & POLLIN) {
                //msg_Dbg(VLC_OBJECT(p_intf), "poll in");
                bool b_line = false;
                while ((i_len = recv(fd[1].fd, p_sys->p_read_buffer + p_sys->i_read_offset, 1, 0)) > 0) {
                    char ch;

                    ch = p_sys->p_read_buffer[p_sys->i_read_offset];
                    switch (ch) {
                    case '\r':
                    case '\n':
                        p_sys->p_read_buffer[p_sys->i_read_offset] = '\0';
                        b_line = true;
                        break;
                    case '\0':
                        b_line = true;
                        break;
                    default:
                        break;
                    }
                    p_sys->i_read_offset++;
                    if (p_sys->i_read_offset == sizeof(p_sys->p_read_buffer) && !b_line) {
                        net_Close(p_sys->i_socket);
                        p_sys->i_socket = -1;
                        msg_Dbg(VLC_OBJECT(p_intf), "input is too long, close connection");
                        break;
                    }
                }
                if (b_line && strlen(p_sys->p_read_buffer)) {
                    p_sys->i_read_offset = 0;
                    //msg_Dbg(VLC_OBJECT(p_intf), "%s\n", p_sys->p_read_buffer);
                    ProcessCommand(p_intf, p_sys->p_read_buffer);
                }
                if(i_len == 0) {
                    net_Close(p_sys->i_socket);
                    p_sys->i_socket = -1;
                    msg_Dbg(VLC_OBJECT(p_intf), "connection is closed by client");
                }
            }
            if (fd[1].revents & POLLOUT) {
                vlc_mutex_lock(&p_sys->o_write_lock);
                if (p_sys->i_write_length) {
                    int i_first, i_second;

                    i_first = sizeof(p_sys->p_write_buffer) - p_sys->i_write_offset;
                    i_second = (p_sys->i_write_offset + p_sys->i_write_length) % sizeof(p_sys->p_write_buffer);
                    i_test = 0;
                    if (i_first >= p_sys->i_write_length)
                        i_len = send(fd[1].fd, p_sys->p_write_buffer + p_sys->i_write_offset, p_sys->i_write_length, 0);
                    else {
                        i_len = send(fd[1].fd, p_sys->p_write_buffer + p_sys->i_write_offset, i_first, 0);
                        if (i_len == i_first)
                            i_test = send(fd[1].fd, p_sys->p_write_buffer, i_second, 0);
                        if (i_test > 0)
                            i_len += i_test;
                    }
                    if (i_len > 0) {
                        p_sys->i_write_offset += i_len;
                        p_sys->i_write_offset %= sizeof(p_sys->p_write_buffer);
                        p_sys->i_write_length -= i_len;
                        if (p_sys->i_write_length == 0)
                            p_sys->i_write_offset = 0;
                    }
                }
                vlc_mutex_unlock(&p_sys->o_write_lock);
            }
        }
    }
}