コード例 #1
0
ファイル: dec.c プロジェクト: forthyen/SDesk
aout_input_t * __aout_DecNew( vlc_object_t * p_this,
                              aout_instance_t ** pp_aout,
                              audio_sample_format_t * p_format )
{
    if ( *pp_aout == NULL )
    {
        /* Create an audio output if there is none. */
        *pp_aout = vlc_object_find( p_this, VLC_OBJECT_AOUT, FIND_ANYWHERE );

        if( *pp_aout == NULL )
        {
            msg_Dbg( p_this, "no aout present, spawning one" );

            *pp_aout = aout_New( p_this );
            /* Everything failed, I'm a loser, I just wanna die */
            if( *pp_aout == NULL )
            {
                return NULL;
            }
            vlc_object_attach( *pp_aout, p_this->p_vlc );
        }
        else
        {
            vlc_object_release( *pp_aout );
        }
    }

    return DecNew( p_this, *pp_aout, p_format );
}
コード例 #2
0
/*****************************************************************************
 * Open: open a scope effect plugin
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_filter_t     *p_filter = (aout_filter_t *)p_this;
    aout_filter_sys_t *p_sys;
    galaktos_thread_t *p_thread;

    if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' )
         || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
    {
        msg_Warn( p_filter, "bad input or output format" );
        return VLC_EGENERIC;
    }
    if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
    {
        msg_Warn( p_filter, "input and output formats are not similar" );
        return VLC_EGENERIC;
    }

    p_filter->pf_do_work = DoWork;
    p_filter->b_in_place = 1;

    /* Allocate structure */
    p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) );

    /* Create galaktos thread */
    p_sys->p_thread = p_thread =
        vlc_object_create( p_filter, sizeof( galaktos_thread_t ) );
    vlc_object_attach( p_thread, p_this );

/*
    var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "galaktos-width", &width );
    var_Create( p_thread, "galaktos-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "galaktos-height", &height );
*/
    p_thread->i_cur_sample = 0;
    bzero( p_thread->p_data, 2*2*512 );

    p_thread->i_width = 600;
    p_thread->i_height = 600;
    p_thread->b_fullscreen = 0;
    galaktos_init( p_thread );

    p_thread->i_channels = aout_FormatNbChannels( &p_filter->input );

    p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) );

    if( vlc_thread_create( p_thread, "galaktos update thread", Thread,
                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
    {
        msg_Err( p_filter, "cannot lauch galaktos thread" );
        if( p_thread->psz_title ) free( p_thread->psz_title );
        vlc_object_detach( p_thread );
        vlc_object_destroy( p_thread );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
コード例 #3
0
ファイル: filters.c プロジェクト: forthyen/SDesk
/*****************************************************************************
 * FindFilter: find an audio filter for a specific transformation
 *****************************************************************************/
static aout_filter_t * FindFilter( aout_instance_t * p_aout,
                             const audio_sample_format_t * p_input_format,
                             const audio_sample_format_t * p_output_format )
{
    aout_filter_t * p_filter = vlc_object_create( p_aout,
                                                  sizeof(aout_filter_t) );

    if ( p_filter == NULL ) return NULL;
    vlc_object_attach( p_filter, p_aout );

    memcpy( &p_filter->input, p_input_format, sizeof(audio_sample_format_t) );
    memcpy( &p_filter->output, p_output_format,
            sizeof(audio_sample_format_t) );
    p_filter->p_module = module_Need( p_filter, "audio filter", NULL, 0 );
    if ( p_filter->p_module == NULL )
    {
        vlc_object_detach( p_filter );
        vlc_object_destroy( p_filter );
        return NULL;
    }

    p_filter->b_continuity = VLC_FALSE;

    return p_filter;
}
コード例 #4
0
ファイル: dialogs.cpp プロジェクト: banketree/faplayer
bool Dialogs::init()
{
    // Allocate descriptor
    m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(),
                                                    sizeof( intf_thread_t ) );
    if( m_pProvider == NULL )
        return false;

    // Attach the dialogs provider to its parent interface
    vlc_object_attach( m_pProvider, getIntf() );

    m_pModule = module_need( m_pProvider, "dialogs provider", NULL, false );
    if( m_pModule == NULL )
    {
        msg_Err( getIntf(), "no suitable dialogs provider found (hint: compile the qt4 plugin, and make sure it is loaded properly)" );
        vlc_object_release( m_pProvider );
        m_pProvider = NULL;
        return false;
    }

    /* Register callback for the intf-popupmenu variable */
    var_AddCallback( getIntf()->p_libvlc, "intf-popupmenu",
                     PopupMenuCB, this );

    return true;
}
コード例 #5
0
ファイル: sql.c プロジェクト: paa/vlc
sql_t *sql_Create( vlc_object_t *p_this, const char *psz_name,
        const char* psz_host, int i_port,
        const char* psz_user, const char* psz_pass )
{
    sql_t *p_sql;

    p_sql = ( sql_t * ) vlc_custom_create( p_this, sizeof( sql_t ),
                                           VLC_OBJECT_GENERIC, "sql" );
    if( !p_sql )
    {
        msg_Err( p_this, "unable to create sql object" );
        return NULL;
    }
    vlc_object_attach( p_sql, p_this );

    p_sql->psz_host = strdup( psz_host );
    p_sql->psz_user = strdup( psz_user );
    p_sql->psz_pass = strdup( psz_pass );
    p_sql->i_port = i_port;

    p_sql->p_module = module_need( p_sql, "sql", psz_name,
                                   psz_name && *psz_name );
    if( !p_sql->p_module )
    {
        free( p_sql->psz_host );
        free( p_sql->psz_user );
        free( p_sql->psz_pass );
        vlc_object_release( p_sql );
        msg_Err( p_this, "SQL provider not found" );
        return NULL;
    }

    return p_sql;
}
コード例 #6
0
ファイル: common.c プロジェクト: iamnpc/myfaplayer
/*****************************************************************************
 * aout_New: initialize aout structure
 *****************************************************************************/
aout_instance_t * __aout_New( vlc_object_t * p_parent )
{
    aout_instance_t * p_aout;

    /* Allocate descriptor. */
    p_aout = vlc_custom_create( p_parent, sizeof( *p_aout ), VLC_OBJECT_AOUT,
                                "audio output" );
    if( p_aout == NULL )
    {
        return NULL;
    }

    /* Initialize members. */
    vlc_mutex_init( &p_aout->input_fifos_lock );
    vlc_mutex_init( &p_aout->mixer_lock );
    vlc_mutex_init( &p_aout->volume_vars_lock );
    vlc_mutex_init( &p_aout->output_fifo_lock );
    p_aout->i_nb_inputs = 0;
    p_aout->mixer_multiplier = 1.0;
    p_aout->p_mixer = NULL;
    p_aout->output.b_error = 1;
    p_aout->output.b_starving = 1;

    var_Create( p_aout, "intf-change", VLC_VAR_VOID );

    vlc_object_set_destructor( p_aout, aout_Destructor );

    vlc_object_attach( p_aout, p_parent );

    return p_aout;
}
コード例 #7
0
ファイル: filter.c プロジェクト: paa/vlc
filter_t *filter_NewBlend( vlc_object_t *p_this,
                           const video_format_t *p_dst_chroma )
{
    filter_t *p_blend = vlc_custom_create( p_this, sizeof(*p_blend),
                                           VLC_OBJECT_GENERIC, "blend" );
    if( !p_blend )
        return NULL;

    es_format_Init( &p_blend->fmt_in, VIDEO_ES, 0 );

    es_format_Init( &p_blend->fmt_out, VIDEO_ES, 0 );

    p_blend->fmt_out.i_codec        = 
    p_blend->fmt_out.video.i_chroma = p_dst_chroma->i_chroma;
    p_blend->fmt_out.video.i_rmask  = p_dst_chroma->i_rmask;
    p_blend->fmt_out.video.i_gmask  = p_dst_chroma->i_gmask;
    p_blend->fmt_out.video.i_bmask  = p_dst_chroma->i_bmask;
    p_blend->fmt_out.video.i_rrshift= p_dst_chroma->i_rrshift;
    p_blend->fmt_out.video.i_rgshift= p_dst_chroma->i_rgshift;
    p_blend->fmt_out.video.i_rbshift= p_dst_chroma->i_rbshift;
    p_blend->fmt_out.video.i_lrshift= p_dst_chroma->i_lrshift;
    p_blend->fmt_out.video.i_lgshift= p_dst_chroma->i_lgshift;
    p_blend->fmt_out.video.i_lbshift= p_dst_chroma->i_lbshift;

    /* The blend module will be loaded when needed with the real
    * input format */
    p_blend->p_module = NULL;

    /* */
    vlc_object_attach( p_blend, p_this );

    return p_blend;
}
コード例 #8
0
ファイル: qte.cpp プロジェクト: Kafay/vlc
/*****************************************************************************
 * OpenDisplay: create qte applicaton / window
 *****************************************************************************
 * Create a window according to video output given size, and set other
 * properties according to the display properties.
 *****************************************************************************/
static int OpenDisplay( vout_thread_t *p_vout )
{
    /* for displaying the vout in a qt window we need the QtApplication */
    p_vout->p_sys->p_QApplication = NULL;
    p_vout->p_sys->p_VideoWidget = NULL;

    p_vout->p_sys->p_event = (event_thread_t*) vlc_object_create( p_vout, sizeof(event_thread_t) );
    p_vout->p_sys->p_event->p_vout = p_vout;

    /* Initializations */
#if 1 /* FIXME: I need an event queue to handle video output size changes. */
    p_vout->b_fullscreen = true;
#endif

    /* Set main window's size */
    QWidget *desktop = p_vout->p_sys->p_QApplication->desktop();
    p_vout->p_sys->i_width = p_vout->b_fullscreen ? desktop->height() :
                                                    p_vout->i_window_width;
    p_vout->p_sys->i_height = p_vout->b_fullscreen ? desktop->width() :
                                                     p_vout->i_window_height;

#if 0 /* FIXME: I need an event queue to handle video output size changes. */
    /* Update dimensions */
    p_vout->i_changes |= VOUT_SIZE_CHANGE;
    p_vout->i_window_width = p_vout->p_sys->i_width;
    p_vout->i_window_height = p_vout->p_sys->i_height;
#endif

    msg_Dbg( p_vout, "opening display (h=%d,w=%d)",p_vout->p_sys->i_height,p_vout->p_sys->i_width);

    /* create thread to exec the qpe application */
    if ( vlc_thread_create( p_vout->p_sys->p_event, "QT Embedded Thread",
                            RunQtThread,
                            VLC_THREAD_PRIORITY_OUTPUT, true) )
    {
        msg_Err( p_vout, "cannot create QT Embedded Thread" );
        vlc_object_release( p_vout->p_sys->p_event );
        p_vout->p_sys->p_event = NULL;
        return -1;
    }

    if( p_vout->p_sys->p_event->b_error )
    {
        msg_Err( p_vout, "RunQtThread failed" );
        return -1;
    }

    vlc_object_attach( p_vout->p_sys->p_event, p_vout );
    msg_Dbg( p_vout, "RunQtThread running" );

    // just wait until the crew is complete...
    while(p_vout->p_sys->p_VideoWidget == NULL)
    {
        msleep(1);
    }
    return VLC_SUCCESS;
}
コード例 #9
0
ファイル: tls.c プロジェクト: banketree/faplayer
tls_session_t *tls_ServerSessionPrepare (tls_server_t *srv)
{
    tls_session_t *ses;

    ses = srv->pf_open (srv);
    if (ses == NULL)
        return NULL;

    vlc_object_attach (ses, srv);
    return ses;
}
コード例 #10
0
ファイル: sap.c プロジェクト: banketree/faplayer
/**
 * Create the SAP handler
 *
 * \param p_announce a VLC object
 * \return the newly created SAP handler or NULL on error
 */
sap_handler_t *SAP_Create (vlc_object_t *p_announce)
{
    sap_handler_t *p_sap;

    p_sap = vlc_custom_create (p_announce, sizeof (*p_sap),
                               VLC_OBJECT_GENERIC, "sap sender");
    if (p_sap == NULL)
        return NULL;

    vlc_object_attach( p_sap, p_announce );
    vlc_mutex_init (&p_sap->lock);
    p_sap->first = NULL;
    return p_sap;
}
コード例 #11
0
ファイル: AtmoThread.cpp プロジェクト: cmassiot/vlc-broadcast
CThread::CThread(vlc_object_t *pOwner)
{
    m_bTerminated  = ATMO_FALSE;
    m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner,
                                                        sizeof(atmo_thread_t) );
    if(m_pAtmoThread)
    {
        m_pAtmoThread->p_thread = this;
        this->m_pOwner = pOwner;

        vlc_object_attach( m_pAtmoThread, m_pOwner);

        vlc_mutex_init( &m_TerminateLock );
        vlc_cond_init( &m_TerminateCond );
    }
}
コード例 #12
0
ファイル: tls.c プロジェクト: banketree/faplayer
/**
 * Allocates a client's TLS credentials and shakes hands through the network.
 * This is a blocking network operation.
 *
 * @param fd stream socket through which to establish the secure communication
 * layer.
 * @param psz_hostname Server Name Indication to pass to the server, or NULL.
 *
 * @return NULL on error.
 **/
tls_session_t *
tls_ClientCreate (vlc_object_t *obj, int fd, const char *psz_hostname)
{
    tls_session_t *cl;
    int val;

    cl = (tls_session_t *)vlc_custom_create (obj, sizeof (*cl),
                                             VLC_OBJECT_GENERIC,
                                             "tls client");
    if (cl == NULL)
        return NULL;

    var_Create (cl, "tls-server-name", VLC_VAR_STRING);
    if (psz_hostname != NULL)
    {
        msg_Dbg (cl, "requested server name: %s", psz_hostname);
        var_SetString (cl, "tls-server-name", psz_hostname);
    }
    else
        msg_Dbg (cl, "requested anonymous server");

    vlc_object_attach (cl, obj);
    cl->p_module = module_need (cl, "tls client", NULL, false );
    if (cl->p_module == NULL)
    {
        msg_Err (cl, "TLS client plugin not available");
        vlc_object_release (cl);
        return NULL;
    }

    cl->pf_set_fd (cl, fd);

    do
        val = cl->pf_handshake (cl);
    while (val > 0);

    if (val == 0)
    {
        msg_Dbg (cl, "TLS client session initialized");
        return cl;
    }
    msg_Err (cl, "TLS client session handshake error");

    module_unneed (cl, cl->p_module);
    vlc_object_release (cl);
    return NULL;
}
コード例 #13
0
ファイル: window.c プロジェクト: shanewfx/vlc-arib
vout_window_t *vout_window_New(vlc_object_t *obj,
                               const char *module,
                               const vout_window_cfg_t *cfg)
{
    static char const name[] = "window";
    window_t *w = vlc_custom_create(obj, sizeof(*w), VLC_OBJECT_GENERIC, name);
    vout_window_t *window = &w->wnd;

    window->cfg = cfg;
    memset(&window->handle, 0, sizeof(window->handle));
    window->control = NULL;
    window->sys = NULL;

    vlc_object_attach(window, obj);

    const char *type;
    switch (cfg->type) {
    case VOUT_WINDOW_TYPE_HWND:
        type = "vout window hwnd";
        break;
    case VOUT_WINDOW_TYPE_XID:
        type = "vout window xid";
        break;
    default:
        assert(0);
    }

    w->module = module_need(window, type, module, module && *module != '\0');
    if (!w->module) {
        vlc_object_detach(window);
        vlc_object_release(window);
        return NULL;
    }

    /* Hook for screensaver inhibition */
    if (cfg->type == VOUT_WINDOW_TYPE_XID) {
        w->inhibit = vlc_inhibit_Create (VLC_OBJECT (window),
                                         window->handle.xid);
        if (w->inhibit != NULL)
            vlc_inhibit_Set (w->inhibit, true);
            /* FIXME: ^ wait for vout activation, pause */
    }
    else
        w->inhibit = NULL;
    return window;
}
コード例 #14
0
int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
                     playlist_item_t *p_export_root, const char *psz_type )
{
    if( p_export_root == NULL ) return VLC_EGENERIC;

    playlist_export_t *p_export =
        vlc_custom_create( p_playlist, sizeof( *p_export ), VLC_OBJECT_GENERIC,
                           "playlist export" );
    if( !p_export )
        return VLC_ENOMEM;

    vlc_object_attach( p_export, p_playlist );
    msg_Dbg( p_export, "saving %s to file %s",
             p_export_root->p_input->psz_name, psz_filename );

    int ret = VLC_EGENERIC;

    /* Prepare the playlist_export_t structure */
    p_export->p_root = p_export_root;
    p_export->psz_filename = psz_filename;
    p_export->p_file = vlc_fopen( psz_filename, "wt" );
    if( p_export->p_file == NULL )
        msg_Err( p_export, "could not create playlist file %s (%m)",
                 psz_filename );
    else
    {
        module_t *p_module;

        /* And call the module ! All work is done now */
        playlist_Lock( p_playlist );
        p_module = module_need( p_export, "playlist export", psz_type, true );
        playlist_Unlock( p_playlist );

        if( p_module == NULL )
            msg_Err( p_playlist, "could not export playlist" );
        else
        {
            module_unneed( p_export, p_module );
            ret = VLC_SUCCESS;
        }
        fclose( p_export->p_file );
    }
    vlc_object_release( p_export );
    return ret;
}
コード例 #15
0
ファイル: vout_intf.c プロジェクト: mahaserver/MHSVLC
/*****************************************************************************
 * vout_RequestWindow: Create/Get a video window if possible.
 *****************************************************************************
 * This function looks for the main interface and tries to request
 * a new video window. If it fails then the vout will still need to create the
 * window by itself.
 *****************************************************************************/
void *vout_RequestWindow( vout_thread_t *p_vout,
                          int *pi_x_hint, int *pi_y_hint,
                          unsigned int *pi_width_hint,
                          unsigned int *pi_height_hint )
{
    /* Small kludge */
    if( !var_Type( p_vout, "aspect-ratio" ) ) vout_IntfInit( p_vout );

    /* Get requested coordinates */
    *pi_x_hint = var_GetInteger( p_vout, "video-x" );
    *pi_y_hint = var_GetInteger( p_vout, "video-y" );

    *pi_width_hint = p_vout->i_window_width;
    *pi_height_hint = p_vout->i_window_height;

    /* Check whether someone provided us with a window ID */
    int drawable = var_CreateGetInteger( p_vout, "drawable" );
    if( drawable ) return (void *)(intptr_t)drawable;

    vout_window_t *wnd = vlc_custom_create (VLC_OBJECT(p_vout), sizeof (*wnd),
                                            VLC_OBJECT_GENERIC, "window");
    if (wnd == NULL)
        return NULL;

    wnd->vout = p_vout;
    wnd->width = *pi_width_hint;
    wnd->height = *pi_height_hint;
    wnd->pos_x = *pi_x_hint;
    wnd->pos_y = *pi_y_hint;
    vlc_object_attach (wnd, p_vout);

    wnd->module = module_Need (wnd, "vout window", 0, 0);
    if (wnd->module == NULL)
    {
        msg_Dbg (wnd, "no window provider available");
        vlc_object_release (wnd);
        return NULL;
    }
    p_vout->p_window = wnd;
    *pi_width_hint = wnd->width;
    *pi_height_hint = wnd->height;
    *pi_x_hint = wnd->pos_x;
    *pi_y_hint = wnd->pos_y;
    return wnd->handle;
}
コード例 #16
0
/**
 * Create the announce handler object
 *
 * \param p_this a vlc_object structure
 * \return the new announce handler or NULL on error
 */
announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
{
    announce_handler_t *p_announce;

    p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE );

    if( !p_announce )
    {
        msg_Err( p_this, "out of memory" );
        return NULL;
    }

    p_announce->p_sap = NULL;

    vlc_object_attach( p_announce, p_this->p_vlc);


    return p_announce;
}
コード例 #17
0
ファイル: interface.c プロジェクト: mahaserver/MHSVLC
/**
 * Create the interface, and prepare it for main loop.
 *
 * \param p_this the calling vlc_object_t
 * \param psz_module a preferred interface module
 * \return a pointer to the created interface thread, NULL on error
 */
intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
{
    intf_thread_t * p_intf;

    /* Allocate structure */
    p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
    if( !p_intf )
        return NULL;
    p_intf->b_interaction = false;
#if defined( __APPLE__ ) || defined( WIN32 )
    p_intf->b_should_run_on_first_thread = false;
#endif

    /* Choose the best module */
    p_intf->psz_intf = strdup( psz_module );
    p_intf->p_module = module_Need( p_intf, "interface", psz_module, false );

    if( p_intf->p_module == NULL )
    {
        msg_Err( p_intf, "no suitable interface module" );
        free( p_intf->psz_intf );
        vlc_object_release( p_intf );
        return NULL;
    }

    /* Initialize structure */
    p_intf->b_menu        = false;
    p_intf->b_menu_change = false;

    /* Initialize mutexes */
    vlc_mutex_init( &p_intf->change_lock );

    /* Attach interface to its parent object */
    vlc_object_attach( p_intf, p_this );
    vlc_object_set_destructor( p_intf, intf_Destroy );

    return p_intf;
}
コード例 #18
0
ファイル: filter.c プロジェクト: paa/vlc
video_splitter_t *video_splitter_New( vlc_object_t *p_this,
                                      const char *psz_name,
                                      const video_format_t *p_fmt )
{
    video_splitter_t *p_splitter = vlc_custom_create( p_this, sizeof(*p_splitter),
                                           VLC_OBJECT_GENERIC, "video splitter" );
    if( !p_splitter )
        return NULL;

    video_format_Copy( &p_splitter->fmt, p_fmt );

    /* */
    vlc_object_attach( p_splitter, p_this );

    p_splitter->p_module = module_need( p_splitter, "video splitter", psz_name, true );
    if( ! p_splitter->p_module )
    {
        video_splitter_Delete( p_splitter );
        return NULL;
    }

    return p_splitter;
}
コード例 #19
0
ファイル: vout_intf.c プロジェクト: MisTelochka/vlc
/**
 * Creates a video output window.
 * On Unix systems, this is an X11 drawable (handle).
 * On Windows, this is a Win32 window (handle).
 * Video output plugins are supposed to called this function and display the
 * video within the resulting window, while in windowed mode.
 *
 * @param p_vout video output thread to create a window for
 * @param psz_cap VLC module capability (window system type)
 * @param pi_x_hint pointer to store the recommended horizontal position [OUT]
 * @param pi_y_hint pointer to store the recommended vertical position [OUT]
 * @param pi_width_hint pointer to store the recommended width [OUT]
 * @param pi_height_hint pointer to store the recommended height [OUT]
 *
 * @return a vout_window_t object, or NULL in case of failure.
 * The window is released with vout_ReleaseWindow().
 */
vout_window_t *vout_RequestWindow( vout_thread_t *p_vout, const char *psz_cap,
                          int *pi_x_hint, int *pi_y_hint,
                          unsigned int *pi_width_hint,
                          unsigned int *pi_height_hint )
{
    /* Get requested coordinates */
    *pi_x_hint = var_GetInteger( p_vout, "video-x" );
    *pi_y_hint = var_GetInteger( p_vout, "video-y" );

    *pi_width_hint = p_vout->i_window_width;
    *pi_height_hint = p_vout->i_window_height;

    vout_window_t *wnd = vlc_custom_create (VLC_OBJECT(p_vout), sizeof (*wnd),
                                            VLC_OBJECT_GENERIC, "window");
    if (wnd == NULL)
        return NULL;

    wnd->vout = p_vout;
    wnd->width = *pi_width_hint;
    wnd->height = *pi_height_hint;
    wnd->pos_x = *pi_x_hint;
    wnd->pos_y = *pi_y_hint;
    vlc_object_attach (wnd, p_vout);

    wnd->module = module_need (wnd, psz_cap, NULL, false);
    if (wnd->module == NULL)
    {
        msg_Dbg (wnd, "no \"%s\" window provider available", psz_cap);
        vlc_object_release (wnd);
        return NULL;
    }
    *pi_width_hint = wnd->width;
    *pi_height_hint = wnd->height;
    *pi_x_hint = wnd->pos_x;
    *pi_y_hint = wnd->pos_y;
    return wnd;
}
コード例 #20
0
ファイル: tls.c プロジェクト: banketree/faplayer
/**
 * Allocates a whole server's TLS credentials.
 *
 * @param cert_path required (Unicode) path to an x509 certificate,
 *                  if NULL, anonymous key exchange will be used.
 * @param key_path (UTF-8) path to the PKCS private key for the certificate,
 *                 if NULL; cert_path will be used.
 *
 * @return NULL on error.
 */
tls_server_t *
tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
                  const char *key_path)
{
    tls_server_t *srv;

    srv = (tls_server_t *)vlc_custom_create (obj, sizeof (*srv),
                                             VLC_OBJECT_GENERIC,
                                             "tls server");
    if (srv == NULL)
        return NULL;

    var_Create (srv, "tls-x509-cert", VLC_VAR_STRING);
    var_Create (srv, "tls-x509-key", VLC_VAR_STRING);

    if (cert_path != NULL)
    {
        var_SetString (srv, "tls-x509-cert", cert_path);

        if (key_path == NULL)
            key_path = cert_path;
        var_SetString (srv, "tls-x509-key", key_path);
    }

    vlc_object_attach (srv, obj);
    srv->p_module = module_need (srv, "tls server", NULL, false );
    if (srv->p_module == NULL)
    {
        msg_Err (srv, "TLS server plugin not available");
        vlc_object_release (srv);
        return NULL;
    }

    msg_Dbg (srv, "TLS server plugin initialized");
    return srv;
}
コード例 #21
0
/***********************************************************************
 * Create
 ***********************************************************************/
services_discovery_t *
services_discovery_Create ( vlc_object_t * p_super, const char * psz_module_name )
{
    services_discovery_t *p_sd;
    p_sd = vlc_custom_create( p_super, sizeof( *p_sd ), VLC_OBJECT_GENERIC,
                              "services discovery" );
    if( !p_sd )
        return NULL;

    p_sd->pf_run = NULL;
    p_sd->psz_localized_name = NULL;

    vlc_event_manager_init( &p_sd->event_manager, p_sd, (vlc_object_t *)p_sd );
    vlc_event_manager_register_event_type( &p_sd->event_manager,
            vlc_ServicesDiscoveryItemAdded );
    vlc_event_manager_register_event_type( &p_sd->event_manager,
            vlc_ServicesDiscoveryItemRemoved );
    vlc_event_manager_register_event_type( &p_sd->event_manager,
            vlc_ServicesDiscoveryStarted );
    vlc_event_manager_register_event_type( &p_sd->event_manager,
            vlc_ServicesDiscoveryEnded );

    p_sd->p_module = module_Need( p_sd, "services_discovery", psz_module_name, true );

    if( p_sd->p_module == NULL )
    {
        msg_Err( p_super, "no suitable services discovery module" );
        vlc_object_release( p_sd );
        return NULL;
    }
    p_sd->psz_module = strdup( psz_module_name );
    p_sd->b_die = false; /* FIXME */

    vlc_object_attach( p_sd, p_super );
    return p_sd;
}
コード例 #22
0
/*****************************************************************************
 * Thread:
 *****************************************************************************/
static void Thread( vlc_object_t *p_this )
{
    galaktos_thread_t *p_thread = (galaktos_thread_t*)p_this;

    int count=0;
    double realfps=0,fpsstart=0;
    int timed=0;
    int timestart=0;
    int mspf=0;

    /* Get on OpenGL provider */
    p_thread->p_opengl =
        (vout_thread_t *)vlc_object_create( p_this, VLC_OBJECT_OPENGL );
    if( p_thread->p_opengl == NULL )
    {
        msg_Err( p_thread, "out of memory" );
        return;
    }
    vlc_object_attach( p_thread->p_opengl, p_this );

    /* Initialize vout parameters */
    vout_InitFormat( &p_thread->p_opengl->fmt_in,
                     VLC_FOURCC('R','V','3','2'),
                     p_thread->i_width, p_thread->i_height, 1 );
    p_thread->p_opengl->i_window_width = p_thread->i_width;
    p_thread->p_opengl->i_window_height = p_thread->i_height;
    p_thread->p_opengl->render.i_width = p_thread->i_width;
    p_thread->p_opengl->render.i_height = p_thread->i_width;
    p_thread->p_opengl->render.i_aspect = VOUT_ASPECT_FACTOR;
    p_thread->p_opengl->b_scale = VLC_TRUE;
    p_thread->p_opengl->b_fullscreen = VLC_FALSE;
    p_thread->p_opengl->i_alignment = 0;
    p_thread->p_opengl->fmt_in.i_sar_num = 1;
    p_thread->p_opengl->fmt_in.i_sar_den = 1;
    p_thread->p_opengl->fmt_render = p_thread->p_opengl->fmt_in;

    p_thread->p_module =
        module_Need( p_thread->p_opengl, "opengl provider", NULL, 0 );
    if( p_thread->p_module == NULL )
    {
        msg_Err( p_thread, "unable to initialize OpenGL" );
        vlc_object_detach( p_thread->p_opengl );
        vlc_object_destroy( p_thread->p_opengl );
        return;
    }

    p_thread->p_opengl->pf_init( p_thread->p_opengl );

    setup_opengl( p_thread->i_width, p_thread->i_height );
    CreateRenderTarget(512, &RenderTargetTextureID, NULL);

    timestart=mdate()/1000;

    while( !p_thread->b_die )
    {
        mspf = 1000 / 60;
        if( galaktos_update( p_thread ) == 1 )
        {
            p_thread->b_die = 1;
        }
        if( p_thread->psz_title )
        {
            free( p_thread->psz_title );
            p_thread->psz_title = NULL;
        }

        if (++count%100==0)
        {
            realfps=100/((mdate()/1000-fpsstart)/1000);
 //           printf("%f\n",realfps);
            fpsstart=mdate()/1000;
        }
        //framerate limiter
        timed=mspf-(mdate()/1000-timestart);
      //   printf("%d,%d\n",time,mspf);
        if (timed>0) msleep(1000*timed);
    //     printf("Limiter %d\n",(mdate()/1000-timestart));
        timestart=mdate()/1000;
    }

    /* Free the openGL provider */
    module_Unneed( p_thread->p_opengl, p_thread->p_module );
    vlc_object_detach( p_thread->p_opengl );
    vlc_object_destroy( p_thread->p_opengl );
}
コード例 #23
0
static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;
    sout_stream_id_t *id;

    id = calloc( 1, sizeof( sout_stream_id_t ) );
    if( !id )
        goto error;

    id->id = NULL;
    id->p_decoder = NULL;
    id->p_encoder = NULL;

    /* Create decoder object */
    id->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) );
    if( !id->p_decoder )
        goto error;
    vlc_object_attach( id->p_decoder, p_stream );
    id->p_decoder->p_module = NULL;
    id->p_decoder->fmt_in = *p_fmt;
    id->p_decoder->b_pace_control = true;

    /* Create encoder object */
    id->p_encoder = sout_EncoderCreate( p_stream );
    if( !id->p_encoder )
        goto error;
    vlc_object_attach( id->p_encoder, p_stream );
    id->p_encoder->p_module = NULL;

    /* Create destination format */
    es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );
    id->p_encoder->fmt_out.i_id    = p_fmt->i_id;
    id->p_encoder->fmt_out.i_group = p_fmt->i_group;

    if( p_sys->psz_alang )
        id->p_encoder->fmt_out.psz_language = strdup( p_sys->psz_alang );
    else if( p_fmt->psz_language )
        id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );

    bool success;

    if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )
        success = transcode_audio_add(p_stream, p_fmt, id);
    else if( p_fmt->i_cat == VIDEO_ES && (p_sys->i_vcodec || p_sys->psz_venc) )
        success = transcode_video_add(p_stream, p_fmt, id);
    else if( ( p_fmt->i_cat == SPU_ES ) &&
             ( p_sys->i_scodec || p_sys->psz_senc || p_sys->b_soverlay ) )
        success = transcode_spu_add(p_stream, p_fmt, id);
    else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )
        success = transcode_osd_add(p_stream, p_fmt, id);
    else
    {
        msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",
                 (char*)&p_fmt->i_codec );
        id->id = sout_StreamIdAdd( p_stream->p_next, p_fmt );
        id->b_transcode = false;

        success = id->id;
    }

    if(!success)
        goto error;

    return id;

error:
    if( id )
    {
        if( id->p_decoder )
        {
            vlc_object_release( id->p_decoder );
            id->p_decoder = NULL;
        }

        if( id->p_encoder )
        {
            es_format_Clean( &id->p_encoder->fmt_out );
            vlc_object_release( id->p_encoder );
            id->p_encoder = NULL;
        }

        free( id );
    }
    return NULL;
}
コード例 #24
0
ファイル: logo.c プロジェクト: forthyen/SDesk
/*****************************************************************************
 * Init: initialize logo video thread output method
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    vout_sys_t *p_sys = p_vout->p_sys;
    picture_t *p_pic;
    int i_index;

    I_OUTPUTPICTURES = 0;

    /* Initialize the output structure */
    p_vout->output.i_chroma = p_vout->render.i_chroma;
    p_vout->output.i_width  = p_vout->render.i_width;
    p_vout->output.i_height = p_vout->render.i_height;
    p_vout->output.i_aspect = p_vout->render.i_aspect;

    /* Load the video blending filter */
    p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) );
    vlc_object_attach( p_sys->p_blend, p_vout );
    p_sys->p_blend->fmt_out.video.i_x_offset =
        p_sys->p_blend->fmt_out.video.i_y_offset = 0;
    p_sys->p_blend->fmt_in.video.i_x_offset =
        p_sys->p_blend->fmt_in.video.i_y_offset = 0;
    p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect;
    p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma;
    p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A');
    p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR;
    p_sys->p_blend->fmt_in.video.i_width =
        p_sys->p_blend->fmt_in.video.i_visible_width =
            p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
    p_sys->p_blend->fmt_in.video.i_height =
        p_sys->p_blend->fmt_in.video.i_visible_height =
            p_sys->p_pic->p[Y_PLANE].i_visible_lines;
    p_sys->p_blend->fmt_out.video.i_width =
        p_sys->p_blend->fmt_out.video.i_visible_width =
           p_vout->output.i_width;
    p_sys->p_blend->fmt_out.video.i_height =
        p_sys->p_blend->fmt_out.video.i_visible_height =
            p_vout->output.i_height;

    p_sys->p_blend->p_module =
        module_Need( p_sys->p_blend, "video blending", 0, 0 );
    if( !p_sys->p_blend->p_module )
    {
        msg_Err( p_vout, "can't open blending filter, aborting" );
        vlc_object_detach( p_sys->p_blend );
        vlc_object_destroy( p_sys->p_blend );
        return VLC_EGENERIC;
    }

    if( p_sys->posx < 0 || p_sys->posy < 0 )
    {
        p_sys->posx = 0; p_sys->posy = 0;

        if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM )
        {
            p_sys->posy = p_vout->render.i_height - p_sys->i_height;
        }
        else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) )
        {
            p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2;
        }

        if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT )
        {
            p_sys->posx = p_vout->render.i_width - p_sys->i_width;
        }
        else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) )
        {
            p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2;
        }
    }

    /* Try to open the real video output */
    msg_Dbg( p_vout, "spawning the real video output" );

    p_sys->p_vout =
        vout_Create( p_vout, p_vout->render.i_width, p_vout->render.i_height,
                     p_vout->render.i_chroma, p_vout->render.i_aspect );

    /* Everything failed */
    if( p_sys->p_vout == NULL )
    {
        msg_Err( p_vout, "can't open vout, aborting" );
        return VLC_EGENERIC;
    }

    var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
    var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);

    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
    ADD_CALLBACKS( p_sys->p_vout, SendEvents );
    ADD_PARENT_CALLBACKS( SendEventsToChild );

    return VLC_SUCCESS;
}
コード例 #25
0
ファイル: playlist.c プロジェクト: forthyen/SDesk
/**
 * 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;
    vlc_value_t     val;

    /* Allocate structure */
    p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
    if( !p_playlist )
    {
        msg_Err( p_parent, "out of memory" );
        return NULL;
    }

    var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
    val.b_bool = VLC_TRUE;
    var_Set( p_playlist, "intf-change", val );

    var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
    val.i_int = -1;
    var_Set( p_playlist, "item-change", val );

    var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
    val.i_int = -1;
    var_Set( p_playlist, "playlist-current", val );

    var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );

    var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
    val.b_bool = VLC_TRUE;
    var_Set( p_playlist, "intf-show", val );


    var_Create( p_playlist, "prevent-skip", VLC_VAR_BOOL );
    val.b_bool = VLC_FALSE;
    var_Set( p_playlist, "prevent-skip", val );

    var_Create( p_playlist, "play-and-stop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "random", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );

    p_playlist->p_input = NULL;
    p_playlist->i_status = PLAYLIST_STOPPED;
    p_playlist->i_index = -1;
    p_playlist->i_size = 0;
    p_playlist->pp_items = NULL;

    p_playlist->i_groups = 0;
    p_playlist->pp_groups = NULL;
    p_playlist->i_last_group = 0;
    p_playlist->i_last_id = 0;
    p_playlist->i_sort = SORT_ID;
    p_playlist->i_order = ORDER_NORMAL;

    playlist_CreateGroup( p_playlist, _("Normal") );

    if( vlc_thread_create( p_playlist, "playlist", RunThread,
                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
    {
        msg_Err( p_playlist, "cannot spawn playlist thread" );
        vlc_object_destroy( p_playlist );
        return NULL;
    }

    /* The object has been initialized, now attach it */
    vlc_object_attach( p_playlist, p_parent );

    return p_playlist;
}
コード例 #26
0
ファイル: rtmp.c プロジェクト: banketree/faplayer
/*****************************************************************************
 * Open: open the rtmp connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t *) p_this;
    sout_access_out_sys_t *p_sys;
    char *psz, *p;
    int length_path, length_media_name;
    int i;

    if( !( p_sys = calloc ( 1, sizeof( sout_access_out_sys_t ) ) ) )
        return VLC_ENOMEM;
    p_access->p_sys = p_sys;

    p_sys->p_thread =
        vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) );
    if( !p_sys->p_thread )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }
    vlc_object_attach( p_sys->p_thread, p_access );

    /* Parse URI - remove spaces */
    p = psz = strdup( p_access->psz_path );
    while( ( p = strchr( p, ' ' ) ) != NULL )
        *p = '+';
    vlc_UrlParse( &p_sys->p_thread->url, psz, 0 );
    free( psz );

    if( p_sys->p_thread->url.psz_host == NULL
        || *p_sys->p_thread->url.psz_host == '\0' )
    {
         msg_Warn( p_access, "invalid host" );
         goto error;
    }

    if( p_sys->p_thread->url.i_port <= 0 )
        p_sys->p_thread->url.i_port = 1935;

    if ( p_sys->p_thread->url.psz_path == NULL )
    {
        msg_Warn( p_access, "invalid path" );
        goto error;
    }

    length_path = strlen( p_sys->p_thread->url.psz_path );
    char* psz_tmp = strrchr( p_sys->p_thread->url.psz_path, '/' );
    if( !psz_tmp )
        goto error;
    length_media_name = strlen( psz_tmp ) - 1;

    p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 );
    p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) );

    msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'",
             p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path );

    if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username )
    {
        msg_Dbg( p_access, "      user='******'", p_sys->p_thread->url.psz_username );
    }

    /* Initialize thread variables */
    p_sys->p_thread->b_error= 0;
    p_sys->p_thread->p_fifo_input = block_FifoNew();
    p_sys->p_thread->p_empty_blocks = block_FifoNew();
    p_sys->p_thread->has_audio = 0;
    p_sys->p_thread->has_video = 0;
    p_sys->p_thread->metadata_received = 0;
    p_sys->p_thread->first_media_packet = 1;
    p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */

    p_sys->p_thread->flv_body = rtmp_body_new( -1 );
    p_sys->p_thread->flv_length_body = 0;

    p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    for(i = 0; i < 64; i++)
    {
        memset( &p_sys->p_thread->rtmp_headers_recv[i], 0, sizeof( rtmp_packet_t ) );
        p_sys->p_thread->rtmp_headers_send[i].length_header = -1;
        p_sys->p_thread->rtmp_headers_send[i].stream_index = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp_relative = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_encoded = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_body = -1;
        p_sys->p_thread->rtmp_headers_send[i].content_type = -1;
        p_sys->p_thread->rtmp_headers_send[i].src_dst = -1;
        p_sys->p_thread->rtmp_headers_send[i].body = NULL;
    }

    vlc_cond_init( &p_sys->p_thread->wait );
    vlc_mutex_init( &p_sys->p_thread->lock );

    p_sys->p_thread->result_connect = 1;
    /* p_sys->p_thread->result_publish = only used on access */
    p_sys->p_thread->result_play = 1;
    p_sys->p_thread->result_stop = 0;
    p_sys->p_thread->fd = -1;

    /* Open connection */
    if( var_CreateGetBool( p_access, "rtmp-connect" ) > 0 )
    {
#if 0
        p_sys->p_thread->fd = net_ConnectTCP( p_access,
                                              p_sys->p_thread->url.psz_host,
                                              p_sys->p_thread->url.i_port );
#endif
        msg_Err( p_access, "to be implemented" );
        goto error2;
    }
    else
    {
        int *p_fd_listen;

        p_sys->active = 0;
        p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host,
                                     p_sys->p_thread->url.i_port );
        if( p_fd_listen == NULL )
        {
            msg_Warn( p_access, "cannot listen to %s port %i",
                      p_sys->p_thread->url.psz_host,
                      p_sys->p_thread->url.i_port );
            goto error2;
        }

        do
            p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen );
        while( p_sys->p_thread->fd == -1 );
        net_ListenClose( p_fd_listen );

        if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 )
        {
            msg_Err( p_access, "handshake passive failed");
            goto error2;
        }
    }

    if( vlc_clone( &p_sys->p_thread->thread, ThreadControl, p_sys->p_thread,
                   VLC_THREAD_PRIORITY_INPUT ) )
    {
        msg_Err( p_access, "cannot spawn rtmp control thread" );
        goto error2;
    }

    if( !p_sys->active )
    {
        if( rtmp_connect_passive( p_sys->p_thread ) < 0 )
        {
            msg_Err( p_access, "connect passive failed");
            vlc_cancel( p_sys->p_thread->thread );
            vlc_join( p_sys->p_thread->thread, NULL );
            goto error2;
        }
    }

    p_access->pf_write = Write;
    p_access->pf_seek = Seek;

    return VLC_SUCCESS;

error2:
    vlc_cond_destroy( &p_sys->p_thread->wait );
    vlc_mutex_destroy( &p_sys->p_thread->lock );

    free( p_sys->p_thread->psz_application );
    free( p_sys->p_thread->psz_media );

    if( p_sys->p_thread->fd != -1 )
        net_Close( p_sys->p_thread->fd );
error:
    vlc_UrlClean( &p_sys->p_thread->url );
    vlc_object_release( p_sys->p_thread );
    free( p_sys );

    return VLC_EGENERIC;
}
コード例 #27
0
ファイル: opengl.c プロジェクト: paa/vlc
/*****************************************************************************
 * CreateVout: This function allocates and initializes the OpenGL vout method.
 *****************************************************************************/
static int CreateVout( vlc_object_t *p_this )
{
    vout_thread_t *p_vout = (vout_thread_t *)p_this;
    vout_sys_t *p_sys;
    char * psz;

    /* Allocate structure */
    p_vout->p_sys = p_sys = malloc( sizeof( vout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    /* Get window */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create( p_this, sizeof( vout_thread_t ) );
    if( p_sys->p_vout == NULL )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }
    vlc_object_attach( p_sys->p_vout, p_this );

    p_sys->p_vout->i_window_width = p_vout->i_window_width;
    p_sys->p_vout->i_window_height = p_vout->i_window_height;
    p_sys->p_vout->b_fullscreen = p_vout->b_fullscreen;
    p_sys->p_vout->render.i_width = p_vout->render.i_width;
    p_sys->p_vout->render.i_height = p_vout->render.i_height;
    p_sys->p_vout->render.i_aspect = p_vout->render.i_aspect;
    p_sys->p_vout->fmt_render = p_vout->fmt_render;
    p_sys->p_vout->fmt_in = p_vout->fmt_in;
    p_sys->p_vout->b_autoscale = p_vout->b_autoscale;
    p_sys->p_vout->i_zoom = p_vout->i_zoom;
    p_sys->p_vout->i_alignment = p_vout->i_alignment;
    var_Create( p_sys->p_vout, "video-deco",
                VLC_VAR_BOOL | VLC_VAR_DOINHERIT );

    /* Forward events from the opengl provider */
    var_Create( p_sys->p_vout, "mouse-moved", VLC_VAR_COORDS );
    var_Create( p_sys->p_vout, "mouse-clicked", VLC_VAR_COORDS );
    var_Create( p_sys->p_vout, "mouse-button-down", VLC_VAR_INTEGER );
    var_Create( p_sys->p_vout, "video-on-top",
                VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_sys->p_vout, "autoscale",
                VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_sys->p_vout, "scale",
                VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );

    var_AddCallback( p_sys->p_vout, "mouse-moved", SendEvents, p_vout );
    var_AddCallback( p_sys->p_vout, "mouse-clicked", SendEvents, p_vout );
    var_AddCallback( p_sys->p_vout, "mouse-button-down", SendEvents, p_vout );
    var_AddCallback( p_sys->p_vout, "video-on-top", SendEvents, p_vout );
    var_AddCallback( p_vout, "autoscale", SendEvents, p_sys->p_vout );
    var_AddCallback( p_vout, "scale", SendEvents, p_sys->p_vout );

    psz = var_CreateGetString( p_vout, "opengl-provider" );
    p_sys->p_vout->p_module =
        module_need( p_sys->p_vout, "opengl provider", psz, false );
    free( psz );
    if( p_sys->p_vout->p_module == NULL )
    {
        msg_Warn( p_vout, "No OpenGL provider found" );
        /* no need for var_DelCallback here :-) */
        vlc_object_release( p_sys->p_vout );
        free( p_sys );
        return VLC_ENOOBJ;
    }

    p_vout->pf_init = Init;
    p_vout->pf_end = End;
    p_vout->pf_manage = Manage;
    p_vout->pf_render = Render;
    p_vout->pf_display = DisplayVideo;
    p_vout->pf_control = Control;

    return VLC_SUCCESS;
}
コード例 #28
0
ファイル: osd.c プロジェクト: paa/vlc
/*****************************************************************************
 * OSD menu Funtions
 *****************************************************************************/
osd_menu_t *osd_MenuCreate( vlc_object_t *p_this, const char *psz_file )
{
    osd_menu_t  *p_osd = NULL;
    vlc_value_t val;
    vlc_mutex_t *p_lock;
    int         i_volume = 0;
    int         i_steps = 0;

    /* to be sure to avoid multiple creation */
    p_lock = osd_GetMutex( p_this );
    vlc_mutex_lock( p_lock );

    var_Create( p_this->p_libvlc, "osd", VLC_VAR_ADDRESS );
    var_Get( p_this->p_libvlc, "osd", &val );
    if( val.p_address == NULL )
    {
        static const char osdmenu_name[] = "osd menu";

        p_osd = vlc_custom_create( p_this, sizeof( *p_osd ),
                                   VLC_OBJECT_GENERIC, osdmenu_name );
        if( !p_osd )
            return NULL;

        p_osd->p_parser = NULL;
        vlc_object_attach( p_osd, p_this->p_libvlc );

        /* Parse configuration file */
        if ( !osd_ParserLoad( p_osd, psz_file ) )
            goto error;
        if( !p_osd->p_state )
            goto error;

        /* Setup default button (first button) */
        p_osd->p_state->p_visible = p_osd->p_button;
        p_osd->p_state->p_visible->p_current_state =
            osd_StateChange( p_osd->p_state->p_visible, OSD_BUTTON_SELECT );
        p_osd->i_width  = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch;
        p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines;

        if( p_osd->p_state->p_volume )
        {
            /* Update the volume state images to match the current volume */
            i_volume = config_GetInt( p_this, "volume" );
            i_steps = osd_VolumeStep( p_this, i_volume, p_osd->p_state->p_volume->i_ranges );
            p_osd->p_state->p_volume->p_current_state = osd_VolumeStateChange(
                                    p_osd->p_state->p_volume->p_states, i_steps );
        }
        /* Initialize OSD state */
        osd_UpdateState( p_osd->p_state, p_osd->i_x, p_osd->i_y,
                         p_osd->i_width, p_osd->i_height, NULL );

        /* Signal when an update of OSD menu is needed */
        var_Create( p_osd, "osd-menu-update", VLC_VAR_BOOL );
        var_Create( p_osd, "osd-menu-visible", VLC_VAR_BOOL );

        var_SetBool( p_osd, "osd-menu-update", false );
        var_SetBool( p_osd, "osd-menu-visible", false );

        val.p_address = p_osd;
        var_Set( p_this->p_libvlc, "osd", val );
    }
    else
        p_osd = val.p_address;
    vlc_object_hold( p_osd );
    vlc_mutex_unlock( p_lock );
    return p_osd;

error:
    vlc_mutex_unlock( p_lock );
    osd_MenuDelete( p_this, p_osd );
    return NULL;
}
コード例 #29
0
/*****************************************************************************
 * aout_InputNew : allocate a new input and rework the filter pipeline
 *****************************************************************************/
int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_request_vout_t *p_request_vout )
{
    audio_sample_format_t chain_input_format;
    audio_sample_format_t chain_output_format;
    vlc_value_t val, text;
    char *psz_filters, *psz_visual, *psz_scaletempo;
    int i_visual;

    aout_FormatPrint( p_aout, "input", &p_input->input );

    p_input->i_nb_resamplers = p_input->i_nb_filters = 0;

    /* Prepare FIFO. */
    aout_FifoInit( p_aout, &p_input->mixer.fifo, p_aout->mixer_format.i_rate );
    p_input->mixer.begin = NULL;

    /* */
    if( p_request_vout )
    {
        p_input->request_vout = *p_request_vout;
    }
    else
    {
        p_input->request_vout.pf_request_vout = RequestVout;
        p_input->request_vout.p_private = p_aout;
    }

    /* Prepare format structure */
    chain_input_format  = p_input->input;
    chain_output_format = p_aout->mixer_format;
    chain_output_format.i_rate = p_input->input.i_rate;
    aout_FormatPrepare( &chain_output_format );

    /* Now add user filters */
    if( var_Type( p_aout, "visual" ) == 0 )
    {
        var_Create( p_aout, "visual", VLC_VAR_STRING | VLC_VAR_HASCHOICE );
        text.psz_string = _("Visualizations");
        var_Change( p_aout, "visual", VLC_VAR_SETTEXT, &text, NULL );
        val.psz_string = (char*)""; text.psz_string = _("Disable");
        var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        val.psz_string = (char*)"spectrometer"; text.psz_string = _("Spectrometer");
        var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        val.psz_string = (char*)"scope"; text.psz_string = _("Scope");
        var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        val.psz_string = (char*)"spectrum"; text.psz_string = _("Spectrum");
        var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        val.psz_string = (char*)"vuMeter"; text.psz_string = _("Vu meter");
        var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );

        /* Look for goom plugin */
        if( module_exists( "goom" ) )
        {
            val.psz_string = (char*)"goom"; text.psz_string = (char*)"Goom";
            var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        }

        /* Look for libprojectM plugin */
        if( module_exists( "projectm" ) )
        {
            val.psz_string = (char*)"projectm"; text.psz_string = (char*)"projectM";
            var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text );
        }

        if( var_Get( p_aout, "effect-list", &val ) == VLC_SUCCESS )
        {
            var_SetString( p_aout, "visual", val.psz_string );
            free( val.psz_string );
        }
        var_AddCallback( p_aout, "visual", VisualizationCallback, NULL );
    }

    if( var_Type( p_aout, "equalizer" ) == 0 )
    {
        module_config_t *p_config;
        int i;

        p_config = config_FindConfig( VLC_OBJECT(p_aout), "equalizer-preset" );
        if( p_config && p_config->i_list )
        {
               var_Create( p_aout, "equalizer",
                           VLC_VAR_STRING | VLC_VAR_HASCHOICE );
            text.psz_string = _("Equalizer");
            var_Change( p_aout, "equalizer", VLC_VAR_SETTEXT, &text, NULL );

            val.psz_string = (char*)""; text.psz_string = _("Disable");
            var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text );

            for( i = 0; i < p_config->i_list; i++ )
            {
                val.psz_string = (char *)p_config->ppsz_list[i];
                text.psz_string = (char *)p_config->ppsz_list_text[i];
                var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE,
                            &val, &text );
            }

            var_AddCallback( p_aout, "equalizer", EqualizerCallback, NULL );
        }
    }

    if( var_Type( p_aout, "audio-filter" ) == 0 )
    {
        var_Create( p_aout, "audio-filter",
                    VLC_VAR_STRING | VLC_VAR_DOINHERIT );
        text.psz_string = _("Audio filters");
        var_Change( p_aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL );
    }
    if( var_Type( p_aout, "audio-visual" ) == 0 )
    {
        var_Create( p_aout, "audio-visual",
                    VLC_VAR_STRING | VLC_VAR_DOINHERIT );
        text.psz_string = _("Audio visualizations");
        var_Change( p_aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL );
    }

    if( var_Type( p_aout, "audio-replay-gain-mode" ) == 0 )
    {
        module_config_t *p_config;
        int i;

        p_config = config_FindConfig( VLC_OBJECT(p_aout), "audio-replay-gain-mode" );
        if( p_config && p_config->i_list )
        {
            var_Create( p_aout, "audio-replay-gain-mode",
                        VLC_VAR_STRING | VLC_VAR_DOINHERIT );

            text.psz_string = _("Replay gain");
            var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_SETTEXT, &text, NULL );

            for( i = 0; i < p_config->i_list; i++ )
            {
                val.psz_string = (char *)p_config->ppsz_list[i];
                text.psz_string = (char *)p_config->ppsz_list_text[i];
                var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_ADDCHOICE,
                            &val, &text );
            }

            var_AddCallback( p_aout, "audio-replay-gain-mode", ReplayGainCallback, NULL );
        }
    }
    if( var_Type( p_aout, "audio-replay-gain-preamp" ) == 0 )
    {
        var_Create( p_aout, "audio-replay-gain-preamp",
                    VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
    }
    if( var_Type( p_aout, "audio-replay-gain-default" ) == 0 )
    {
        var_Create( p_aout, "audio-replay-gain-default",
                    VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
    }
    if( var_Type( p_aout, "audio-replay-gain-peak-protection" ) == 0 )
    {
        var_Create( p_aout, "audio-replay-gain-peak-protection",
                    VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    }
    if( var_Type( p_aout, "audio-time-stretch" ) == 0 )
    {
        var_Create( p_aout, "audio-time-stretch",
                    VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    }

    psz_filters = var_GetString( p_aout, "audio-filter" );
    psz_visual = var_GetString( p_aout, "audio-visual");
    psz_scaletempo = var_GetBool( p_aout, "audio-time-stretch" ) ? strdup( "scaletempo" ) : NULL;

    p_input->b_recycle_vout = psz_visual && *psz_visual;

    /* parse user filter lists */
    char *const ppsz_array[] = { psz_scaletempo, psz_filters, psz_visual };
    p_input->p_playback_rate_filter = NULL;

    for( i_visual = 0; i_visual < 3 && !AOUT_FMT_NON_LINEAR(&chain_output_format); i_visual++ )
    {
        char *psz_next = NULL;
        char *psz_parser = ppsz_array[i_visual];

        if( psz_parser == NULL || !*psz_parser )
            continue;

        while( psz_parser && *psz_parser )
        {
            filter_t * p_filter = NULL;

            if( p_input->i_nb_filters >= AOUT_MAX_FILTERS )
            {
                msg_Dbg( p_aout, "max filters reached (%d)", AOUT_MAX_FILTERS );
                break;
            }

            while( *psz_parser == ' ' && *psz_parser == ':' )
            {
                psz_parser++;
            }
            if( ( psz_next = strchr( psz_parser , ':'  ) ) )
            {
                *psz_next++ = '\0';
            }
            if( *psz_parser =='\0' )
            {
                break;
            }

            /* Create a VLC object */
            static const char typename[] = "audio filter";
            p_filter = vlc_custom_create( p_aout, sizeof(*p_filter),
                                          VLC_OBJECT_GENERIC, typename );
            if( p_filter == NULL )
            {
                msg_Err( p_aout, "cannot add user filter %s (skipped)",
                         psz_parser );
                psz_parser = psz_next;
                continue;
            }

            vlc_object_attach( p_filter , p_aout );

            p_filter->p_owner = malloc( sizeof(*p_filter->p_owner) );
            p_filter->p_owner->p_aout  = p_aout;
            p_filter->p_owner->p_input = p_input;

            /* request format */
            memcpy( &p_filter->fmt_in.audio, &chain_output_format,
                    sizeof(audio_sample_format_t) );
            p_filter->fmt_in.i_codec = chain_output_format.i_format;
            memcpy( &p_filter->fmt_out.audio, &chain_output_format,
                    sizeof(audio_sample_format_t) );
            p_filter->fmt_out.i_codec = chain_output_format.i_format;
            p_filter->pf_audio_buffer_new = aout_FilterBufferNew;

            /* try to find the requested filter */
            if( i_visual == 2 ) /* this can only be a visualization module */
            {
                p_filter->p_module = module_need( p_filter, "visualization2",
                                                  psz_parser, true );
            }
            else /* this can be a audio filter module as well as a visualization module */
            {
                p_filter->p_module = module_need( p_filter, "audio filter",
                                              psz_parser, true );

                if ( p_filter->p_module == NULL )
                {
                    /* if the filter requested a special format, retry */
                    if ( !( AOUT_FMTS_IDENTICAL( &p_filter->fmt_in.audio,
                                                 &chain_input_format )
                            && AOUT_FMTS_IDENTICAL( &p_filter->fmt_out.audio,
                                                    &chain_output_format ) ) )
                    {
                        aout_FormatPrepare( &p_filter->fmt_in.audio );
                        aout_FormatPrepare( &p_filter->fmt_out.audio );
                        p_filter->p_module = module_need( p_filter,
                                                          "audio filter",
                                                          psz_parser, true );
                    }
                    /* try visual filters */
                    else
                    {
                        memcpy( &p_filter->fmt_in.audio, &chain_output_format,
                                sizeof(audio_sample_format_t) );
                        memcpy( &p_filter->fmt_out.audio, &chain_output_format,
                                sizeof(audio_sample_format_t) );
                        p_filter->p_module = module_need( p_filter,
                                                          "visualization2",
                                                          psz_parser, true );
                    }
                }
            }

            /* failure */
            if ( p_filter->p_module == NULL )
            {
                msg_Err( p_aout, "cannot add user filter %s (skipped)",
                         psz_parser );

                free( p_filter->p_owner );
                vlc_object_release( p_filter );

                psz_parser = psz_next;
                continue;
            }

            /* complete the filter chain if necessary */
            if ( !AOUT_FMTS_IDENTICAL( &chain_input_format,
                                       &p_filter->fmt_in.audio ) )
            {
                if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
                                                 &p_input->i_nb_filters,
                                                 &chain_input_format,
                                                 &p_filter->fmt_in.audio ) < 0 )
                {
                    msg_Err( p_aout, "cannot add user filter %s (skipped)",
                             psz_parser );

                    module_unneed( p_filter, p_filter->p_module );
                    free( p_filter->p_owner );
                    vlc_object_release( p_filter );

                    psz_parser = psz_next;
                    continue;
                }
            }

            /* success */
            p_input->pp_filters[p_input->i_nb_filters++] = p_filter;
            memcpy( &chain_input_format, &p_filter->fmt_out.audio,
                    sizeof( audio_sample_format_t ) );

            if( i_visual == 0 ) /* scaletempo */
                p_input->p_playback_rate_filter = p_filter;

            /* next filter if any */
            psz_parser = psz_next;
        }
    }
    free( psz_visual );
    free( psz_filters );
    free( psz_scaletempo );

    /* complete the filter chain if necessary */
    if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &chain_output_format ) )
    {
        if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
                                         &p_input->i_nb_filters,
                                         &chain_input_format,
                                         &chain_output_format ) < 0 )
        {
            inputFailure( p_aout, p_input, "couldn't set an input pipeline" );
            return -1;
        }
    }

    /* Prepare hints for the buffer allocator. */
    p_input->input_alloc.b_alloc = true;
    p_input->input_alloc.i_bytes_per_sec = -1;

    /* Create resamplers. */
    if ( !AOUT_FMT_NON_LINEAR( &p_aout->mixer_format ) )
    {
        chain_output_format.i_rate = (__MAX(p_input->input.i_rate,
                                            p_aout->mixer_format.i_rate)
                                 * (100 + AOUT_MAX_RESAMPLING)) / 100;
        if ( chain_output_format.i_rate == p_aout->mixer_format.i_rate )
        {
            /* Just in case... */
            chain_output_format.i_rate++;
        }
        if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers,
                                         &p_input->i_nb_resamplers,
                                         &chain_output_format,
                                         &p_aout->mixer_format ) < 0 )
        {
            inputFailure( p_aout, p_input, "couldn't set a resampler pipeline");
            return -1;
        }

        aout_FiltersHintBuffers( p_aout, p_input->pp_resamplers,
                                 p_input->i_nb_resamplers,
                                 &p_input->input_alloc );
        p_input->input_alloc.b_alloc = true;

        /* Setup the initial rate of the resampler */
        p_input->pp_resamplers[0]->fmt_in.audio.i_rate = p_input->input.i_rate;
    }
    p_input->i_resampling_type = AOUT_RESAMPLING_NONE;

    if( ! p_input->p_playback_rate_filter && p_input->i_nb_resamplers > 0 )
    {
        p_input->p_playback_rate_filter = p_input->pp_resamplers[0];
    }

    aout_FiltersHintBuffers( p_aout, p_input->pp_filters,
                             p_input->i_nb_filters,
                             &p_input->input_alloc );
    p_input->input_alloc.b_alloc = true;

    /* i_bytes_per_sec is still == -1 if no filters */
    p_input->input_alloc.i_bytes_per_sec = __MAX(
                                    p_input->input_alloc.i_bytes_per_sec,
                                    (int)(p_input->input.i_bytes_per_frame
                                     * p_input->input.i_rate
                                     / p_input->input.i_frame_length) );

    ReplayGainSelect( p_aout, p_input );

    /* Success */
    p_input->b_error = false;
    p_input->i_last_input_rate = INPUT_RATE_DEFAULT;

    return 0;
}
コード例 #30
0
/**
 * ProjectM update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t     *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;
    int cancel = vlc_savecancel();
    video_format_t fmt;
    vout_opengl_t *gl;
    int i_last_width  = 0;
    int i_last_height = 0;
#ifdef HAVE_PROJECTM2
    projectM::Settings settings;
#endif

    /* Create the openGL provider */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) );
    if( !p_sys->p_vout )
        goto error;

    vlc_object_attach( p_sys->p_vout, p_filter );

    /* */
    video_format_Init( &fmt, 0 );
    video_format_Setup( &fmt, VLC_CODEC_RGB32,
                        p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    vout_display_state_t state;
    memset( &state, 0, sizeof(state) );
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl",
                                   300000, 1000000 );
    if( !p_sys->p_vd )
    {
        vlc_object_release( p_sys->p_vout );
        goto error;
    }
    var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL );
    var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd );

    gl = vout_GetDisplayOpengl( p_sys->p_vd );
    if( !gl )
    {
        vout_DeleteDisplay( p_sys->p_vd, NULL );
        vlc_object_release( p_sys->p_vout );
        goto error;
    }

    /* Create the projectM object */
#ifndef HAVE_PROJECTM2
    p_sys->p_projectm = new projectM( p_sys->psz_config );
#else
    settings.meshX = 32;
    settings.meshY = 24;
    settings.fps = 35;
    settings.textureSize = 1024;
    settings.windowWidth = p_sys->i_width;
    settings.windowHeight = p_sys->i_height;
    settings.presetURL = p_sys->psz_preset_path;
    settings.titleFontURL =  p_sys->psz_title_font;
    settings.menuFontURL = p_sys->psz_menu_font;
    settings.smoothPresetDuration = 5;
    settings.presetDuration = 30;
    settings.beatSensitivity = 10;
    settings.aspectCorrection = 1;
    settings.easterEgg = 1;
    settings.shuffleEnabled = 1;
    p_sys->p_projectm = new projectM( settings );
#endif
    p_sys->i_buffer_size = p_sys->p_projectm->pcm()->maxsamples;
    p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size,
                                      sizeof( float ) );

    vlc_sem_post( &p_sys->ready );

    /* TODO: Give to projectm the name of the input
    p_sys->p_projectm->projectM_setTitle( "" ); */

    /* */
    for( ;; )
    {
        const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */
        /* Manage the events */
        vout_ManageDisplay( p_sys->p_vd, true );
        if( p_sys->p_vd->cfg->display.width  != i_last_width ||
            p_sys->p_vd->cfg->display.height != i_last_height )
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false );
            p_sys->p_projectm->projectM_resetGL( place.width, place.height );

            i_last_width  = p_sys->p_vd->cfg->display.width;
            i_last_height = p_sys->p_vd->cfg->display.height;
        }

        /* Render the image and swap the buffers */
        vlc_mutex_lock( &p_sys->lock );
        if( p_sys->i_nb_samples > 0 )
        {
            p_sys->p_projectm->pcm()->addPCMfloat( p_sys->p_buffer,
                                                   p_sys->i_nb_samples );
            p_sys->i_nb_samples = 0;
        }
        if( p_sys->b_quit )
        {
            vlc_mutex_unlock( &p_sys->lock );

            delete p_sys->p_projectm;
            vout_DeleteDisplay( p_sys->p_vd, NULL );
            vlc_object_release( p_sys->p_vout );
            return NULL;
        }
        vlc_mutex_unlock( &p_sys->lock );

        p_sys->p_projectm->renderFrame();

        /* */
        mwait( i_deadline );

        if( !vout_opengl_Lock(gl) )
        {
            vout_opengl_Swap( gl );
            vout_opengl_Unlock( gl );
        }
    }
    abort();

error:
    p_sys->b_error = true;
    vlc_sem_post( &p_sys->ready );
    return NULL;
}