コード例 #1
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 );
}
コード例 #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
ファイル: sap.c プロジェクト: forthyen/SDesk
/**
 * Create the SAP handler
 *
 * \param p_announce the parent announce_handler
 * \return the newly created SAP handler or NULL on error
 */
sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce )
{
    sap_handler_t *p_sap;

    p_sap = vlc_object_create( p_announce, sizeof( sap_handler_t ) );

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

    vlc_mutex_init( p_sap, &p_sap->object_lock );

    p_sap->pf_add = announce_SAPAnnounceAdd;
    p_sap->pf_del = announce_SAPAnnounceDel;

    p_sap->i_sessions = 0;
    p_sap->i_addresses = 0;
    p_sap->i_current_session = 0;

    p_sap->b_control = config_GetInt( p_sap, "sap-flow-control");

    if( vlc_thread_create( p_sap, "sap handler", RunThread,
                       VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
    {
        msg_Dbg( p_announce, "Unable to spawn SAP handler thread");
        free( p_sap );
        return NULL;
    };
    msg_Dbg( p_announce, "thread created, %i sessions", p_sap->i_sessions);
    return p_sap;
}
コード例 #4
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;
}
コード例 #5
0
/***********************************************************************
 * Start
 ***********************************************************************/
int services_discovery_Start ( services_discovery_t * p_sd )
{
    if ((p_sd->pf_run != NULL)
        && vlc_thread_create( p_sd, "services_discovery", RunSD,
                              VLC_THREAD_PRIORITY_LOW, false))
    {
        msg_Err( p_sd, "cannot create services discovery thread" );
        vlc_object_release( p_sd );
        return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}
コード例 #6
0
ファイル: interface.c プロジェクト: mahaserver/MHSVLC
/**
 * 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;
}
コード例 #7
0
/*****************************************************************************
 * Open: initialize and create window
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    vlc_value_t lockval;

    /* FIXME: put this in the module (de)initialization ASAP */
    var_Create( p_this->p_libvlc, "gtk", VLC_VAR_MUTEX );

    var_Get( p_this->p_libvlc, "gtk", &lockval );
    vlc_mutex_lock( lockval.p_address );

    if( i_refcount > 0 )
    {
        i_refcount++;
        vlc_mutex_unlock( lockval.p_address );

        return VLC_SUCCESS;
    }

    p_gtk_main = vlc_object_create( p_this, VLC_OBJECT_GENERIC );

    /* Only initialize gthreads if it's the first time we do it */
    if( !g_thread_supported() )
    {
        g_thread_init( NULL );
    }

    /* Launch the gtk_main() thread. It will not return until it has
     * called gdk_threads_enter(), which ensures us thread safety. */
    if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain,
                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
    {
        vlc_object_destroy( p_gtk_main );
        i_refcount--;
        vlc_mutex_unlock( lockval.p_address );
        var_Destroy( p_this->p_libvlc, "gtk" );
        return VLC_ETHREAD;
    }

    i_refcount++;
    vlc_mutex_unlock( lockval.p_address );

    return VLC_SUCCESS;
}
コード例 #8
0
/*****************************************************************************
 * Run: main loop
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
    if( p_intf->pf_show_dialog )
    {
        /* The module is used in dialog provider mode */

        /* Create a new thread for the dialogs provider */
        if( vlc_thread_create( p_intf, "Skins Dialogs Thread",
                               MainLoop, 0, VLC_TRUE ) )
        {
            msg_Err( p_intf, "cannot create Skins Dialogs Thread" );
            p_intf->pf_show_dialog = NULL;
        }
    }
    else
    {
        /* The module is used in interface mode */
        MainLoop( p_intf );
    }
}
コード例 #9
0
ファイル: AtmoThread.cpp プロジェクト: cmassiot/vlc-broadcast
void CThread::Run()
{
   m_bTerminated = ATMO_FALSE;

#if defined(_ATMO_VLC_PLUGIN_)
   m_pAtmoThread->b_die = false;
   if(vlc_thread_create( m_pAtmoThread,
                         "Atmo-CThread-Class",
                         CThread::ThreadProc,
                         VLC_THREAD_PRIORITY_LOW ))
   {
      msg_Err( m_pOwner, "cannot launch one of the AtmoLight threads");
   }

#else

   ResetEvent(m_hTerminateEvent);
   ResumeThread(m_hThread);

#endif
}
コード例 #10
0
ファイル: remoteosd.c プロジェクト: iamnpc/myfaplayer
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;
}
コード例 #11
0
ファイル: oss.c プロジェクト: iamnpc/myfaplayer
/*****************************************************************************
 * Open: open the audio device (the digital sound processor)
 *****************************************************************************
 * This function opens the DSP as a usual non-blocking write-only file, and
 * modifies the p_aout->p_sys->i_fd with the file's descriptor.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    char * psz_device;
    vlc_value_t val;

    /* Allocate structure */
    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    /* Get device name */
    if( (psz_device = var_InheritString( p_aout, "oss-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device specified (maybe /dev/dsp?)" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Open the sound device in non-blocking mode, because ALSA's OSS
     * emulation and some broken OSS drivers would make a blocking call
     * wait forever until the device is available. Since this breaks the
     * OSS spec, we immediately put it back to blocking mode if the
     * operation was successful. */
    p_sys->i_fd = vlc_open( psz_device, O_WRONLY | O_NDELAY );
    if( p_sys->i_fd < 0 )
    {
        msg_Err( p_aout, "cannot open audio device (%s)", psz_device );
        free( psz_device );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* if the opening was ok, put the device back in blocking mode */
    fcntl( p_sys->i_fd, F_SETFL,
            fcntl( p_sys->i_fd, F_GETFL ) &~ FNDELAY );

    free( psz_device );

    p_aout->output.pf_play = Play;

    if ( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout );
    }

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        /* Probe() has failed. */
        close( p_sys->i_fd );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        p_aout->output.output.i_format = VLC_CODEC_SPDIFL;
    }
    else if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_format = VLC_CODEC_S16N;
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_format = VLC_CODEC_S16N;
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->output.output.i_format = VLC_CODEC_S16N;
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_format = VLC_CODEC_S16N;
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%"PRId64")",
                 val.i_int );
        close( p_sys->i_fd );
        free( p_sys );
        return VLC_EGENERIC;
    }

    var_TriggerCallback( p_aout, "intf-change" );

    /* Reset the DSP device */
    if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
    {
        msg_Err( p_aout, "cannot reset OSS audio device" );
        close( p_sys->i_fd );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Set the output format */
    if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        int i_format = AFMT_AC3;

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
             || i_format != AFMT_AC3 )
        {
            msg_Err( p_aout, "cannot reset OSS audio device" );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }

        p_aout->output.output.i_format = VLC_CODEC_SPDIFL;
        p_aout->output.i_nb_samples = A52_FRAME_NB;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;

        aout_VolumeNoneInit( p_aout );
    }

    if ( !AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        unsigned int i_format = AFMT_S16_NE;
        unsigned int i_frame_size, i_fragments;
        unsigned int i_rate;
        unsigned int i_nb_channels;
        audio_buf_info audio_buf;

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
        {
            msg_Err( p_aout, "cannot set audio output format" );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }

        switch ( i_format )
        {
        case AFMT_U8:
            p_aout->output.output.i_format = VLC_CODEC_U8;
            break;
        case AFMT_S8:
            p_aout->output.output.i_format = VLC_CODEC_S8;
            break;
        case AFMT_U16_LE:
            p_aout->output.output.i_format = VLC_CODEC_U16L;
            break;
        case AFMT_S16_LE:
            p_aout->output.output.i_format = VLC_CODEC_S16L;
            break;
        case AFMT_U16_BE:
            p_aout->output.output.i_format = VLC_CODEC_U16B;
            break;
        case AFMT_S16_BE:
            p_aout->output.output.i_format = VLC_CODEC_S16B;
            break;
        default:
            msg_Err( p_aout, "OSS fell back to an unknown format (%d)",
                     i_format );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }

        i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );

        /* Set the number of channels */
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) < 0 ||
            i_nb_channels != aout_FormatNbChannels( &p_aout->output.output ) )
        {
            msg_Err( p_aout, "cannot set number of audio channels (%s)",
                     aout_FormatPrintChannels( &p_aout->output.output) );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }

        /* Set the output rate */
        i_rate = p_aout->output.output.i_rate;
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SPEED, &i_rate ) < 0 )
        {
            msg_Err( p_aout, "cannot set audio output rate (%i)",
                             p_aout->output.output.i_rate );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }

        if( i_rate != p_aout->output.output.i_rate )
        {
            p_aout->output.output.i_rate = i_rate;
        }

        /* Set the fragment size */
        aout_FormatPrepare( &p_aout->output.output );

        /* i_fragment = xxxxyyyy where: xxxx        is fragtotal
         *                              1 << yyyy   is fragsize */
        i_frame_size = ((uint64_t)p_aout->output.output.i_bytes_per_frame * p_aout->output.output.i_rate * 65536) / (48000 * 2 * 2) / FRAME_COUNT;
        i_fragments = 4;
        while( i_fragments < 12 && (1U << i_fragments) < i_frame_size )
        {
            ++i_fragments;
        }
        i_fragments |= FRAME_COUNT << 16;
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFRAGMENT, &i_fragments ) < 0 )
        {
            msg_Warn( p_aout, "cannot set fragment size (%.8x)", i_fragments );
        }

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_GETOSPACE, &audio_buf ) < 0 )
        {
            msg_Err( p_aout, "cannot get fragment size" );
            close( p_sys->i_fd );
            free( p_sys );
            return VLC_EGENERIC;
        }
        else
        {
            /* Number of fragments actually allocated */
            p_aout->output.p_sys->i_fragstotal = audio_buf.fragstotal;

            /* Maximum duration the soundcard's buffer can hold */
            p_aout->output.p_sys->max_buffer_duration =
                (mtime_t)audio_buf.fragstotal * audio_buf.fragsize * 1000000
                / p_aout->output.output.i_bytes_per_frame
                / p_aout->output.output.i_rate
                * p_aout->output.output.i_frame_length;

            p_aout->output.i_nb_samples = audio_buf.fragsize /
                p_aout->output.output.i_bytes_per_frame;
        }

        aout_VolumeSoftInit( p_aout );
    }

    /* Create OSS thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, OSSThread,
                           VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create OSS thread (%m)" );
        close( p_sys->i_fd );
        free( p_sys );
        return VLC_ENOMEM;
    }

    return VLC_SUCCESS;
}
コード例 #12
0
ファイル: dv.c プロジェクト: skoruga/vlc-shaders
/*****************************************************************************
 * Open: open the file
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys;

    struct raw1394_portinfo port_inf[ 16 ];

    msg_Dbg( p_access, "opening device" );

    /* Set up p_access */
    access_InitFields( p_access );
    ACCESS_SET_CALLBACKS( NULL, Block, Control, NULL );

    p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) );
    if( !p_sys )
        return VLC_EGENERIC;

    p_sys->i_cards = 0;
    p_sys->i_node = 0;
    p_sys->i_port = 0;
    p_sys->i_guid = 0;
    p_sys->i_channel = 63;
    p_sys->p_raw1394 = NULL;
    p_sys->p_avc1394 = NULL;
    p_sys->p_frame = NULL;
    p_sys->p_ev = NULL;

    vlc_mutex_init( &p_sys->lock );

    p_sys->i_node = DiscoverAVC( p_access, &p_sys->i_port, p_sys->i_guid );
    if( p_sys->i_node < 0 )
    {
        msg_Err( p_access, "failed to open a Firewire (IEEE1394) connection" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    p_sys->p_avc1394 = AVCOpen( p_access, p_sys->i_port );
    if( !p_sys->p_avc1394 )
    {
        msg_Err( p_access, "no Digital Video Control device found" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    p_sys->p_raw1394 = raw1394_new_handle();
    if( !p_sys->p_raw1394 )
    {
        msg_Err( p_access, "no Digital Video device found" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    p_sys->i_cards = raw1394_get_port_info( p_sys->p_raw1394, port_inf, 16 );
    if( p_sys->i_cards < 0 )
    {
        msg_Err( p_access, "failed to get port info" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( raw1394_set_port( p_sys->p_raw1394, p_sys->i_port ) < 0 )
    {
        msg_Err( p_access, "failed to set port info" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    if ( raw1394_iso_recv_init( p_sys->p_raw1394, Raw1394Handler,
                ISOCHRONOUS_QUEUE_LENGTH, ISOCHRONOUS_MAX_PACKET_SIZE,
                p_sys->i_channel, RAW1394_DMA_PACKET_PER_BUFFER, -1 ) < 0 )
    {
        msg_Err( p_access, "failed to init isochronous recv" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    raw1394_set_userdata( p_sys->p_raw1394, p_access );
    raw1394_iso_recv_start( p_sys->p_raw1394, -1, -1, 0 );

    p_sys->raw1394_poll.fd = raw1394_get_fd( p_sys->p_raw1394 );
    p_sys->raw1394_poll.events = POLLIN | POLLPRI;

    /* Update default_pts to a suitable value for udp access */
    var_Create( p_access, "dv-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );

    /* Now create our event thread catcher */
    p_sys->p_ev = vlc_object_create( p_access, sizeof( event_thread_t ) );
    if( !p_sys->p_ev )
    {
        msg_Err( p_access, "failed to create event thread" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    p_sys->p_ev->p_frame = NULL;
    p_sys->p_ev->pp_last = &p_sys->p_ev->p_frame;
    p_sys->p_ev->p_access = p_access;
    vlc_mutex_init( &p_sys->p_ev->lock );
    vlc_thread_create( p_sys->p_ev, "dv event thread handler",
                       Raw1394EventThread, VLC_THREAD_PRIORITY_OUTPUT );

    return VLC_SUCCESS;
}
コード例 #13
0
/*****************************************************************************
 * Open : creates a handle and opens an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API
 *****************************************************************************/
int E_(OpenAudio)( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    int i_ret;
    int i_bytes_per_sample;
    int i_nb_channels;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_params_t pp;
    aout_instance_t *p_aout = (aout_instance_t *)p_this;

    /* allocate structure */
    p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_aout->output.p_sys == NULL )
    {
        msg_Err( p_aout, "out of memory" );
        return -1;
    }

    /* open audio device */
    if( ( i_ret = snd_pcm_open_preferred( &p_aout->output.p_sys->p_pcm_handle,
                                          &p_aout->output.p_sys->i_card,
                                          &p_aout->output.p_sys->i_device,
                                          SND_PCM_OPEN_PLAYBACK ) ) < 0 )
    {
        msg_Err( p_aout, "unable to open audio device (%s)",
                         snd_strerror( i_ret ) );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* disable mmap */
    if( ( i_ret = snd_pcm_plugin_set_disable( p_aout->output.p_sys->p_pcm_handle,
                                              PLUGIN_DISABLE_MMAP ) ) < 0 )
    {
        msg_Err( p_aout, "unable to disable mmap (%s)", snd_strerror(i_ret) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    p_aout->output.p_sys->p_silent_buffer = malloc( DEFAULT_FRAME_SIZE * 4 );
    p_aout->output.pf_play = Play;
    aout_VolumeSoftInit( p_aout );

    memset( &pi, 0, sizeof(pi) );
    memset( &pp, 0, sizeof(pp) );

    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if( ( i_ret = snd_pcm_plugin_info( p_aout->output.p_sys->p_pcm_handle,
                                       &pi ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get plugin info (%s)",
                         snd_strerror( i_ret ) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    pp.mode       = SND_PCM_MODE_BLOCK;
    pp.channel    = SND_PCM_CHANNEL_PLAYBACK;
    pp.start_mode = SND_PCM_START_FULL;
    pp.stop_mode  = SND_PCM_STOP_STOP;

    pp.buf.block.frags_max   = 3;
    pp.buf.block.frags_min   = 1;

    pp.format.interleave     = 1;
    pp.format.rate           = p_aout->output.output.i_rate;

    i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
    if ( i_nb_channels > 2 )
    {
        /* I don't know if QNX supports more than two channels. */
        i_nb_channels = 2;
        p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
    }
    pp.format.voices         = i_nb_channels;

    p_aout->output.output.i_format = AOUT_FMT_S16_NE;
    p_aout->output.i_nb_samples = DEFAULT_FRAME_SIZE;
    pp.format.format = SND_PCM_SFMT_S16;
    i_bytes_per_sample = 2;

    pp.buf.block.frag_size = p_aout->output.i_nb_samples *
                            p_aout->output.output.i_channels *
                            i_bytes_per_sample;

    /* set parameters */
    if( ( i_ret = snd_pcm_plugin_params( p_aout->output.p_sys->p_pcm_handle,
                                         &pp ) ) < 0 )
    {
        msg_Err( p_aout, "unable to set parameters (%s)", snd_strerror(i_ret) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* prepare channel */
    if( ( i_ret = snd_pcm_plugin_prepare( p_aout->output.p_sys->p_pcm_handle,
                                          SND_PCM_CHANNEL_PLAYBACK ) ) < 0 )
    {
        msg_Err( p_aout, "unable to prepare channel (%s)",
                         snd_strerror( i_ret ) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* Create audio thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, "aout", QNXaoutThread,
                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
    {
        msg_Err( p_aout, "cannot create QNX audio thread (%s)", strerror(errno) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    return( 0 );
}
コード例 #14
0
ファイル: portaudio.c プロジェクト: Kafay/vlc
/*****************************************************************************
 * Open: open the audio device
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    int i_err;

    msg_Dbg( p_aout, "entering Open()");

    /* Allocate p_sys structure */
    p_sys = malloc( sizeof(aout_sys_t) );
    if( p_sys == NULL )
        return VLC_ENOMEM;
    p_sys->p_aout = p_aout;
    p_sys->p_stream = 0;
    p_aout->output.p_sys = p_sys;
    p_aout->output.pf_play = Play;

    /* Retrieve output device id from config */
    p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" );

#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN
    if( !b_init )
    {
        /* Test device */
        if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open portaudio device" );
            free( p_sys );
            return VLC_EGENERIC;
        }

        /* Close device for now. We'll re-open it later on */
        if( ( i_err = Pa_Terminate() ) != paNoError )
        {
            msg_Err( p_aout, "closing the device returned %d", i_err );
        }

        b_init = true;

        /* Now we need to setup our DirectSound play notification structure */
        pa_thread = vlc_object_create( p_aout, sizeof(pa_thread_t) );
        pa_thread->p_aout = p_aout;
        pa_thread->b_error = false;
        vlc_mutex_init( &pa_thread->lock_wait );
        vlc_cond_init( &pa_thread->wait );
        pa_thread->b_wait = false;
        vlc_mutex_init( &pa_thread->lock_signal );
        vlc_cond_init( &pa_thread->signal );
        pa_thread->b_signal = false;

        /* Create PORTAUDIOThread */
        if( vlc_thread_create( pa_thread, "aout", PORTAUDIOThread,
                               VLC_THREAD_PRIORITY_OUTPUT ) )
        {
            msg_Err( p_aout, "cannot create PORTAUDIO thread" );
            return VLC_EGENERIC;
        }
    }
    else
    {
        pa_thread->p_aout = p_aout;
        pa_thread->b_wait = false;
        pa_thread->b_signal = false;
        pa_thread->b_error = false;
    }

    /* Signal start of stream */
    vlc_mutex_lock( &pa_thread->lock_signal );
    pa_thread->b_signal = true;
    vlc_cond_signal( &pa_thread->signal );
    vlc_mutex_unlock( &pa_thread->lock_signal );

    /* Wait until thread is ready */
    vlc_mutex_lock( &pa_thread->lock_wait );
    if( !pa_thread->b_wait )
        vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
    vlc_mutex_unlock( &pa_thread->lock_wait );
    pa_thread->b_wait = false;

    if( pa_thread->b_error )
    {
        msg_Err( p_aout, "PORTAUDIO thread failed" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;

#else

    if( PAOpenDevice( p_aout ) != VLC_SUCCESS )
    {
        msg_Err( p_aout, "cannot open portaudio device" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( PAOpenStream( p_aout ) != VLC_SUCCESS )
    {
        msg_Err( p_aout, "cannot open portaudio device" );
    }

    return VLC_SUCCESS;

#endif
}
コード例 #15
0
ファイル: waveout.c プロジェクト: forthyen/SDesk
/*****************************************************************************
 * Open: open the audio device
 *****************************************************************************
 * This function opens and setups Win32 waveOut
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    vlc_value_t val;
    int i;

    /* Allocate structure */
    p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) );

    if( p_aout->output.p_sys == NULL )
    {
        msg_Err( p_aout, "out of memory" );
        return VLC_EGENERIC;
    }

    p_aout->output.pf_play = Play;
    p_aout->b_die = VLC_FALSE;

    if( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout );
    }

    if( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        /* Probe() has failed. */
        free( p_aout->output.p_sys );
        return VLC_EGENERIC;
    }

    var_Create( p_aout, "waveout-float32", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );

    /* Open the device */
    if( val.i_int == AOUT_VAR_SPDIF )
    {
        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');

        if( OpenWaveOut( p_aout, VLC_FOURCC('s','p','d','i'),
                         p_aout->output.output.i_physical_channels,
                         aout_FormatNbChannels( &p_aout->output.output ),
                         p_aout->output.output.i_rate, VLC_FALSE )
            != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open waveout audio device" );
            free( p_aout->output.p_sys );
            return VLC_EGENERIC;
        }

        /* Calculate the frame size in bytes */
        p_aout->output.i_nb_samples = A52_FRAME_NB;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;
        p_aout->output.p_sys->i_buffer_size =
            p_aout->output.output.i_bytes_per_frame;

        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        if( val.i_int == AOUT_VAR_5_1 )
        {
            p_aout->output.output.i_physical_channels
                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
                   | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
                   | AOUT_CHAN_LFE;
        }
        else if( val.i_int == AOUT_VAR_2F2R )
        {
            p_aout->output.output.i_physical_channels
                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
                   | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
        }
        else if( val.i_int == AOUT_VAR_MONO )
        {
            p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
        }
        else
        {
            p_aout->output.output.i_physical_channels
                = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
        }

        if( OpenWaveOutPCM( p_aout, &p_aout->output.output.i_format,
                            p_aout->output.output.i_physical_channels,
                            aout_FormatNbChannels( &p_aout->output.output ),
                            p_aout->output.output.i_rate, VLC_FALSE )
            != VLC_SUCCESS )
        {
            msg_Err( p_aout, "cannot open waveout audio device" );
            free( p_aout->output.p_sys );
            return VLC_EGENERIC;
        }

        /* Calculate the frame size in bytes */
        p_aout->output.i_nb_samples = FRAME_SIZE;
        aout_FormatPrepare( &p_aout->output.output );
        p_aout->output.p_sys->i_buffer_size = FRAME_SIZE *
            p_aout->output.output.i_bytes_per_frame;

        aout_VolumeSoftInit( p_aout );
    }


    waveOutReset( p_aout->output.p_sys->h_waveout );

    /* Allocate silence buffer */
    p_aout->output.p_sys->p_silence_buffer =
        malloc( p_aout->output.p_sys->i_buffer_size );
    if( p_aout->output.p_sys->p_silence_buffer == NULL )
    {
        free( p_aout->output.p_sys );
        msg_Err( p_aout, "out of memory" );
        return 1;
    }

    /* Zero the buffer. WinCE doesn't have calloc(). */
    memset( p_aout->output.p_sys->p_silence_buffer, 0,
            p_aout->output.p_sys->i_buffer_size );

    /* Now we need to setup our waveOut play notification structure */
    p_aout->output.p_sys->p_notif =
        vlc_object_create( p_aout, sizeof(notification_thread_t) );
    p_aout->output.p_sys->p_notif->p_aout = p_aout;
    p_aout->output.p_sys->event = CreateEvent( NULL, FALSE, FALSE, NULL );

    /* Then launch the notification thread */
    if( vlc_thread_create( p_aout->output.p_sys->p_notif,
                           "waveOut Notification Thread", WaveOutThread,
                           VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )
    {
        msg_Err( p_aout, "cannot create WaveOutThread" );
    }

    /* We need to kick off the playback in order to have the callback properly
     * working */
    for( i = 0; i < FRAMES_NUM; i++ )
    {
        p_aout->output.p_sys->waveheader[i].dwFlags = WHDR_DONE;
        p_aout->output.p_sys->waveheader[i].dwUser = 0;
    }
    PlayWaveOut( p_aout, p_aout->output.p_sys->h_waveout,
                 &p_aout->output.p_sys->waveheader[0], NULL );

    return 0;
}
コード例 #16
0
ファイル: alsa.c プロジェクト: FLYKingdom/vlc
/*****************************************************************************
 * Open: create a handle and open an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API.
 *
 * Note: the only heap-allocated string is psz_device. All the other pointers
 * are references to psz_device or to stack-allocated data.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    vlc_value_t val;

    char psz_default_iec_device[128]; /* Buffer used to store the default
                                         S/PDIF device */
    char * psz_device, * psz_iec_device; /* device names for PCM and S/PDIF
                                            output */

    int i_vlc_pcm_format; /* Audio format for VLC's data */
    int i_snd_pcm_format; /* Audio format for ALSA's data */

    snd_pcm_uframes_t i_buffer_size = 0;
    snd_pcm_uframes_t i_period_size = 0;
    int i_channels = 0;

    snd_pcm_hw_params_t *p_hw;
    snd_pcm_sw_params_t *p_sw;

    int i_snd_rc = -1;
    unsigned int i_old_rate;
    bool b_retry = true;

    /* Allocate structures */
    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;
    p_sys->b_playing = false;
    p_sys->start_date = 0;
    vlc_cond_init( &p_sys->wait );
    vlc_mutex_init( &p_sys->lock );

    /* Get device name */
    if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
        dialog_Fatal( p_aout, _("No Audio Device"), "%s",
                        _("No audio device name was given. You might want to " \
                          "enter \"default\".") );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Choose the IEC device for S/PDIF output:
       if the device is overriden by the user then it will be the one
       otherwise we compute the default device based on the output format. */
    if( AOUT_FMT_NON_LINEAR( &p_aout->output.output )
        && !strcmp( psz_device, DEFAULT_ALSA_DEVICE ) )
    {
        snprintf( psz_default_iec_device, sizeof(psz_default_iec_device),
                  "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
                  IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO,
                  IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
                  0,
                  ( p_aout->output.output.i_rate == 48000 ?
                    IEC958_AES3_CON_FS_48000 :
                    ( p_aout->output.output.i_rate == 44100 ?
                      IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000 ) ) );
        psz_iec_device = psz_default_iec_device;
    }
    else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        psz_iec_device = psz_device;
    }
    else
    {
        psz_iec_device = NULL;
    }

    /* Choose the linear PCM format (read the comment above about FPU
       and float32) */
    if( vlc_CPU() & CPU_CAPABILITY_FPU )
    {
        i_vlc_pcm_format = VLC_CODEC_FL32;
        i_snd_pcm_format = SND_PCM_FORMAT_FLOAT;
    }
    else
    {
        i_vlc_pcm_format = VLC_CODEC_S16N;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
    }

    /* If the variable doesn't exist then it's the first time we're called
       and we have to probe the available audio formats and channels */
    if ( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout, psz_device, psz_iec_device, &i_snd_pcm_format );
    }

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

    p_aout->output.output.i_format = i_vlc_pcm_format;
    if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
        free( psz_device );
        psz_device = strdup( "surround51" );
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
        free( psz_device );
        psz_device = strdup( "surround40" );
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else if( val.i_int != AOUT_VAR_SPDIF )
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int );
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

#ifdef ALSA_DEBUG
    snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 );
#endif

    /* Open the device */
    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iec_device,
                            SND_PCM_STREAM_PLAYBACK, 0 ) ) < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_iec_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_iec_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }
        i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
        i_channels = 2;

        i_vlc_pcm_format = VLC_CODEC_SPDIFL;
        p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;

        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        int i;

        msg_Dbg( p_aout, "opening ALSA device `%s'", psz_device );

        /* Since it seems snd_pcm_close hasn't really released the device at
          the time it returns, probe if the device is available in loop for 1s.
          We cannot use blocking mode since the we would wait indefinitely when
          switching from a dmx device to surround51. */

        for( i = 10; i >= 0; i-- )
        {
            if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device,
                   SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY )
            {
                if( i ) msleep( 100000 /* 100ms */ );
                else
                {
                    msg_Err( p_aout, "audio device: %s is already in use",
                              psz_device );
                    dialog_Fatal( p_aout, _("Audio output failed"),
                                    _("The audio device \"%s\" is already in use."),
                                    psz_device );
                }
                continue;
            }
            break;
        }
        if( i_snd_rc < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }

        /* We want blocking mode */
        snd_pcm_nonblock( p_sys->p_snd_pcm, 0 );

        i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE;
        i_channels = aout_FormatNbChannels( &p_aout->output.output );

        p_aout->output.i_nb_samples = i_period_size = ALSA_DEFAULT_PERIOD_SIZE;

        aout_VolumeSoftInit( p_aout );
    }

    /* Free psz_device so that all the remaining data is stack-allocated */
    free( psz_device );

    p_aout->output.pf_play = Play;

    snd_pcm_hw_params_alloca(&p_hw);
    snd_pcm_sw_params_alloca(&p_sw);

    /* Due to some bugs in alsa with some drivers, we need to retry in s16l
       if snd_pcm_hw_params fails in fl32 */
    while ( b_retry )
    {
        b_retry = false;

        /* Get Initial hardware parameters */
        if ( ( i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            msg_Err( p_aout, "unable to retrieve initial hardware parameters (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set format. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
                                                    i_snd_pcm_format ) ) < 0 )
        {
            if( i_snd_pcm_format != SND_PCM_FORMAT_S16 )
            {
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
                                                     p_hw, i_snd_pcm_format );
            }
            if ( i_snd_rc < 0 )
            {
                msg_Err( p_aout, "unable to set stream sample size and "
                     "word order (%s)", snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
        if( i_vlc_pcm_format != VLC_CODEC_SPDIFL )
        switch( i_snd_pcm_format )
        {
        case SND_PCM_FORMAT_FLOAT:
            i_vlc_pcm_format = VLC_CODEC_FL32;
            break;
        case SND_PCM_FORMAT_S16:
            i_vlc_pcm_format = VLC_CODEC_S16N;
            break;
        }
        p_aout->output.output.i_format = i_vlc_pcm_format;

        if ( ( i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw,
                                    SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set interleaved stream format (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set channels. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw,
                                                      i_channels ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set number of output channels (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set rate. */
        i_old_rate = p_aout->output.output.i_rate;
        i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw,
                                                &p_aout->output.output.i_rate,
                                                NULL );
        if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate )
        {
            msg_Warn( p_aout, "The rate %d Hz is not supported by your " \
                "hardware. Using %d Hz instead.\n", i_old_rate, \
                p_aout->output.output.i_rate );
        }

        /* Set period size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_period_size, NULL ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set period size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }
        p_aout->output.i_nb_samples = i_period_size;

/* Set buffer size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_buffer_size ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set buffer size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Commit hardware parameters. */
        if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            if ( b_retry == false &&
                                i_snd_pcm_format == SND_PCM_FORMAT_FLOAT)
            {
                b_retry = true;
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                p_aout->output.output.i_format = VLC_CODEC_S16N;
                msg_Warn( p_aout, "unable to commit hardware configuration "
                                  "with fl32 samples. Retrying with s16l (%s)",                                     snd_strerror( i_snd_rc ) );
            }
            else
            {
                msg_Err( p_aout, "unable to commit hardware configuration (%s)",
                         snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
    }

    if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw,
                                    &p_sys->i_period_time, NULL ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get period time (%s)",
                         snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Get Initial software parameters */
    snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw );

    i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 );

    i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw,
                                                p_aout->output.i_nb_samples );
    /* start playing when one period has been written */
    i_snd_rc = snd_pcm_sw_params_set_start_threshold( p_sys->p_snd_pcm, p_sw,
                                                      ALSA_DEFAULT_PERIOD_SIZE);
    if( i_snd_rc < 0 )
    {
        msg_Err( p_aout, "unable to set start threshold (%s)",
                          snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Commit software parameters. */
    if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 )
    {
        msg_Err( p_aout, "unable to set software configuration" );
        goto error;
    }

#ifdef ALSA_DEBUG
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA hardware setup:\n\n" );
    snd_pcm_dump_hw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA software setup:\n\n" );
    snd_pcm_dump_sw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\n" );
#endif

    /* Create ALSA thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, "aout", ALSAThread,
                           VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create ALSA thread (%m)" );
        goto error;
    }

    return 0;

error:
    snd_pcm_close( p_sys->p_snd_pcm );
#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif
    free( p_sys );
    return VLC_EGENERIC;
}
コード例 #17
0
ファイル: hd1000a.cpp プロジェクト: cmassiot/vlc-broadcast
/*****************************************************************************
 * Open: open a dummy audio device
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    PCMAudioPlayer * pPlayer;
    int i_volume;

    /* Allocate structure */
    p_aout->output.p_sys = p_sys =
        (aout_sys_t *)malloc( sizeof( aout_sys_t ) );
    if( p_aout->output.p_sys == NULL )
        return VLC_ENOMEM;

    /* New PCMAudioPlayer */
    p_sys->pPlayer = pPlayer = new PCMAudioPlayer();
    if( p_sys->pPlayer == NULL )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    /* Get Buffer Requirements */
    if( !pPlayer->GetBufferRequirements( p_sys->nAlignment,
                                         p_sys->nSizeMultiple,
                                         p_sys->nBuffers ) )
    {
        msg_Err( p_aout, "GetBufferRequirements failed" );
        delete pPlayer;
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->nBuffers = __MIN( p_sys->nBuffers, 4 );

    p_sys->ppBuffers = (void **)malloc( p_sys->nBuffers * sizeof( void * ) );
    if( p_sys->ppBuffers == NULL )
    {
        delete pPlayer;
        free( p_sys );
        return VLC_ENOMEM;
    }

    /* Open PCMAudioPlayer */
    p_sys->nBufferSize = FRAME_SIZE * 4;
    if( !pPlayer->Open( p_sys->nBuffers, p_sys->nBufferSize,
                        p_sys->ppBuffers ) )
    {
        msg_Err( p_aout, "Open failed" );
        delete pPlayer;
        free( p_sys->ppBuffers );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->nNextBufferIndex = 0;

    if( !pPlayer->SetSampleRate( p_aout->output.output.i_rate ) )
    {
        p_aout->output.output.i_rate = 44100;
        if( !pPlayer->SetSampleRate( p_aout->output.output.i_rate ) )
        {
            msg_Err( p_aout, "SetSampleRate failed" );
            pPlayer->Close();
            delete pPlayer;
            free( p_sys->ppBuffers );
            free( p_sys );
            return VLC_EGENERIC;
        }
    }

    p_aout->output.output.i_format = VLC_CODEC_S16N;
    p_aout->output.i_nb_samples = FRAME_SIZE;
    p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    p_aout->output.pf_play = Play;
    aout_VolumeSoftInit( p_aout );

    i_volume = config_GetInt( p_aout->p_libvlc, "volume" );
    pPlayer->SetVolume( (u32)__MIN( i_volume * 64, 0xFFFF ) );

    /* Create thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, "aout", Thread,
                           VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create OSS thread (%m)" );
        pPlayer->Close();
        delete pPlayer;
        free( p_sys->ppBuffers );
        free( p_sys );
        return VLC_ENOMEM;
    }

    return VLC_SUCCESS;
}
コード例 #18
0
/*****************************************************************************
 * Callback: test callback functions
 *****************************************************************************/
static int Callback( vlc_object_t *p_this, char const *psz_cmd,
                     vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    int i;
    char psz_var[20];
    vlc_object_t *pp_objects[10];
    vlc_value_t val;

    /* Allocate a few variables */
    for( i = 0; i < 1000; i++ )
    {
        sprintf( psz_var, "blork-%i", i );
        var_Create( p_this, psz_var, VLC_VAR_INTEGER );
        var_AddCallback( p_this, psz_var, MyCallback, NULL );
    }

    /*
     *  Test #1: callback loop detection
     */
    printf( "Test #1: callback loop detection\n" );

    printf( " - without boundary check (vlc should print an error)\n" );
    val.i_int = 1234567;
    var_Set( p_this, "blork-12", val );

    printf( " - with boundary check\n" );
    val.i_int = 12;
    var_Set( p_this, "blork-12", val );

    /*
     *  Test #2: concurrent access
     */
    printf( "Test #2: concurrent access\n" );

    printf( " - launch worker threads\n" );

    for( i = 0; i < 10; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
        vlc_object_attach( pp_objects[i], p_this );
        vlc_thread_create( pp_objects[i], "foo", MyThread, 0, VLC_TRUE );
    }

    msleep( 3000000 );

    printf( " - kill worker threads\n" );

    for( i = 0; i < 10; i++ )
    {
        pp_objects[i]->b_die = VLC_TRUE;
        vlc_thread_join( pp_objects[i] );
        vlc_object_detach( pp_objects[i] );
        vlc_object_destroy( pp_objects[i] );
    }

    /* Clean our mess */
    for( i = 0; i < 1000; i++ )
    {
        sprintf( psz_var, "blork-%i", i );
        var_DelCallback( p_this, psz_var, MyCallback, NULL );
        var_Destroy( p_this, psz_var );
    }

    return VLC_SUCCESS;
}
コード例 #19
0
ファイル: remoteosd.c プロジェクト: iamnpc/myfaplayer
/*****************************************************************************
 * CreateFilter: Create the filter and open the definition file
 *****************************************************************************/
static int CreateFilter ( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = NULL;

    msg_Dbg( p_filter, "Creating vnc osd filter..." );

    p_filter->p_sys = p_sys = calloc( 1, sizeof(*p_sys) );
    if( !p_filter->p_sys )
        return VLC_ENOMEM;

    /* Populating struct */
    vlc_mutex_init( &p_sys->lock );
    p_sys->b_continue = true;
    p_sys->i_socket = -1;
    p_sys->p_pic = NULL;

    p_sys->psz_host = var_CreateGetString( p_this, RMTOSD_CFG "host" );
    if( EMPTY_STR(p_sys->psz_host) )
    {
        msg_Err( p_filter, "unable to get vnc host" );
        goto error;
    }

    p_sys->psz_passwd = var_CreateGetString( p_this, RMTOSD_CFG "password" );
    if( !p_sys->psz_passwd )
    {
        msg_Err( p_filter, "unable to get vnc password" );
        goto error;
    }

    p_sys->i_port = var_CreateGetIntegerCommand( p_this, RMTOSD_CFG "port" );

    p_sys->i_alpha = var_CreateGetIntegerCommand( p_this, RMTOSD_CFG "alpha" );

    /* in milliseconds, 0 disables polling, should not be lower than 100 */
    p_sys->i_vnc_poll_interval  = var_CreateGetIntegerCommand( p_this,
                                                       RMTOSD_CFG "update" );
    if ( p_sys->i_vnc_poll_interval < 100)
    {
       p_sys->i_vnc_poll_interval = 100;
    }

    for ( int i = 0; i < 256; i++ )
    {
        p_sys->ar_color_table_yuv[i][0] = 255;
        p_sys->ar_color_table_yuv[i][1] = 255;
        p_sys->ar_color_table_yuv[i][2] = 255;
        p_sys->ar_color_table_yuv[i][3] = 255;
    }

    p_sys->b_vnc_poll = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "vnc-polling" );
    p_sys->b_vnc_mouse_events = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "mouse-events" );
    p_sys->b_vnc_key_events = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "key-events" );

    /* Keep track of OSD Events */
    p_sys->b_need_update  = false;

    /* Attach subpicture source callback */
    p_filter->pf_sub_source = Filter;
    p_filter->pf_sub_mouse  = MouseEvent;

    var_AddCallback( p_filter->p_libvlc, "key-pressed", KeyEvent, p_this );

    es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_CODEC_SPU );
    p_filter->fmt_out.i_priority = 0;

    vlc_gcrypt_init();

    /* create the vnc worker thread */
    p_sys->p_worker_thread = vlc_object_create( p_this,
                                                sizeof( vlc_object_t ) );
    vlc_object_attach( p_sys->p_worker_thread, p_this );
    if( vlc_thread_create( p_sys->p_worker_thread,
                           vnc_worker_thread, VLC_THREAD_PRIORITY_LOW ) )
    {
        vlc_object_release( p_sys->p_worker_thread );
        msg_Err( p_filter, "cannot spawn vnc message reader thread" );
        goto error;
    }

    msg_Dbg( p_filter, "osdvnc filter started" );

    return VLC_SUCCESS;

error:
    msg_Err( p_filter, "osdvnc filter discarded" );

    stop_osdvnc( p_filter );

    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys->psz_host );
    free( p_sys->psz_passwd );
    free( p_sys );

    return VLC_EGENERIC;
}
コード例 #20
0
/*****************************************************************************
 * Stress: perform various stress tests
 *****************************************************************************/
static int Stress( vlc_object_t *p_this, char const *psz_cmd,
                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    vlc_object_t **pp_objects;
    mtime_t start;
    char ** ppsz_name;
    char *  psz_blob;
    int     i, i_level;

    if( *newval.psz_string )
    {
        i_level = atoi( newval.psz_string );
        if( i_level <= 0 )
        {
            i_level = 1;
        }
        else if( i_level > 200 )
        {
            /* It becomes quite dangerous above 150 */
            i_level = 200;
        }
    }
    else
    {
        i_level = 10;
    }

    /* Allocate required data */
    ppsz_name = malloc( MAXVAR * i_level * sizeof(char*) );
    psz_blob = malloc( 20 * MAXVAR * i_level * sizeof(char) );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        ppsz_name[i] = psz_blob + 20 * i;
    }

    pp_objects = malloc( MAXOBJ * i_level * sizeof(void*) );

    /*
     *  Test #1: objects
     */
    printf( "Test #1: objects\n" );

    printf( " - creating %i objects\n", MAXOBJ * i_level );
    start = mdate();
    for( i = 0; i < MAXOBJ * i_level; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
    }

    printf( " - randomly looking up %i objects\n", MAXLOOK * i_level );
    for( i = MAXLOOK * i_level; i--; )
    {
        int id = (int) (MAXOBJ * i_level * 1.0 * rand() / (RAND_MAX));
        vlc_object_get( p_this, pp_objects[id]->i_object_id );
        vlc_object_release( p_this );
    }

    printf( " - destroying the objects (LIFO)\n" );
    for( i = MAXOBJ * i_level; i--; )
    {
        vlc_object_destroy( pp_objects[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #2: integer variables
     */
    printf( "Test #2: integer variables\n" );

    printf( " - creating %i integer variables\n", MAXVAR * i_level );
    start = mdate();
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
        var_Create( p_this, ppsz_name[i], VLC_VAR_INTEGER );
    }

    printf( " - randomly assigning %i values\n", MAXSET * i_level );
    for( i = 0; i < MAXSET * i_level; i++ )
    {
        int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
        var_Set( p_this, ppsz_name[v], (vlc_value_t)i );
    }

    printf( " - destroying the variables\n" );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        var_Destroy( p_this, ppsz_name[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #3: string variables
     */
    printf( "Test #3: string variables\n" );

    printf( " - creating %i string variables\n", MAXVAR * i_level );
    start = mdate();
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
        var_Create( p_this, ppsz_name[i], VLC_VAR_STRING );
    }

    printf( " - randomly assigning %i values\n", MAXSET * i_level );
    for( i = 0; i < MAXSET * i_level; i++ )
    {
        int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
        var_Set( p_this, ppsz_name[v], (vlc_value_t)ppsz_name[v] );
    }

    printf( " - destroying the variables\n" );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        var_Destroy( p_this, ppsz_name[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #4: threads
     */
    printf( "Test #4: threads\n" );
    start = mdate();

    printf( " - spawning %i threads that will each create %i objects\n",
            MAXTH * i_level, MAXOBJ/MAXTH );
    for( i = 0; i < MAXTH * i_level; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
        vlc_thread_create( pp_objects[i], "foo", Dummy, 0, VLC_TRUE );
    }

    printf( " - killing the threads (LIFO)\n" );
    for( i = MAXTH * i_level; i--; )
    {
        pp_objects[i]->b_die = VLC_TRUE;
        vlc_thread_join( pp_objects[i] );
        vlc_object_destroy( pp_objects[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /* Free required data */
    free( pp_objects );
    free( psz_blob );
    free( ppsz_name );

    return VLC_SUCCESS;
}
コード例 #21
0
ファイル: video.c プロジェクト: iamnpc/myfaplayer
int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_t *id )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    /* Open decoder
     * Initialization of decoder structures
     */
    id->p_decoder->fmt_out = id->p_decoder->fmt_in;
    id->p_decoder->fmt_out.i_extra = 0;
    id->p_decoder->fmt_out.p_extra = 0;
    id->p_decoder->pf_decode_video = NULL;
    id->p_decoder->pf_get_cc = NULL;
    id->p_decoder->pf_get_cc = 0;
    id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
    id->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder;
    id->p_decoder->pf_picture_link    = video_link_picture_decoder;
    id->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder;
    id->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
    if( !id->p_decoder->p_owner )
        return VLC_EGENERIC;

    id->p_decoder->p_owner->p_sys = p_sys;
    /* id->p_decoder->p_cfg = p_sys->p_video_cfg; */

    id->p_decoder->p_module =
        module_need( id->p_decoder, "decoder", "$codec", false );

    if( !id->p_decoder->p_module )
    {
        msg_Err( p_stream, "cannot find video decoder" );
        free( id->p_decoder->p_owner );
        return VLC_EGENERIC;
    }

    /*
     * Open encoder.
     * Because some info about the decoded input will only be available
     * once the first frame is decoded, we actually only test the availability
     * of the encoder here.
     */

    /* Initialization of encoder format structures */
    es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
                    id->p_decoder->fmt_out.i_codec );
    id->p_encoder->fmt_in.video.i_chroma = id->p_decoder->fmt_out.i_codec;

    /* The dimensions will be set properly later on.
     * Just put sensible values so we can test an encoder is available. */
    id->p_encoder->fmt_in.video.i_width =
        id->p_encoder->fmt_out.video.i_width
          ? id->p_encoder->fmt_out.video.i_width
          : id->p_decoder->fmt_in.video.i_width
            ? id->p_decoder->fmt_in.video.i_width : 16;
    id->p_encoder->fmt_in.video.i_height =
        id->p_encoder->fmt_out.video.i_height
          ? id->p_encoder->fmt_out.video.i_height
          : id->p_decoder->fmt_in.video.i_height
            ? id->p_decoder->fmt_in.video.i_height : 16;
    id->p_encoder->fmt_in.video.i_frame_rate = ENC_FRAMERATE;
    id->p_encoder->fmt_in.video.i_frame_rate_base = ENC_FRAMERATE_BASE;

    id->p_encoder->i_threads = p_sys->i_threads;
    id->p_encoder->p_cfg = p_sys->p_video_cfg;

    id->p_encoder->p_module =
        module_need( id->p_encoder, "encoder", p_sys->psz_venc, true );
    if( !id->p_encoder->p_module )
    {
        msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.",
                 p_sys->psz_venc ? p_sys->psz_venc : "any",
                 (char *)&p_sys->i_vcodec );
        module_unneed( id->p_decoder, id->p_decoder->p_module );
        id->p_decoder->p_module = 0;
        free( id->p_decoder->p_owner );
        return VLC_EGENERIC;
    }

    /* Close the encoder.
     * We'll open it only when we have the first frame. */
    module_unneed( id->p_encoder, id->p_encoder->p_module );
    if( id->p_encoder->fmt_out.p_extra )
    {
        free( id->p_encoder->fmt_out.p_extra );
        id->p_encoder->fmt_out.p_extra = NULL;
        id->p_encoder->fmt_out.i_extra = 0;
    }
    id->p_encoder->p_module = NULL;

    if( p_sys->i_threads >= 1 )
    {
        int i_priority = p_sys->b_high_priority ? VLC_THREAD_PRIORITY_OUTPUT :
                           VLC_THREAD_PRIORITY_VIDEO;
        p_sys->id_video = id;
        vlc_mutex_init( &p_sys->lock_out );
        vlc_cond_init( &p_sys->cond );
        memset( p_sys->pp_pics, 0, sizeof(p_sys->pp_pics) );
        p_sys->i_first_pic = 0;
        p_sys->i_last_pic = 0;
        p_sys->p_buffers = NULL;
        p_sys->b_die = p_sys->b_error = 0;
        if( vlc_thread_create( p_sys, EncoderThread, i_priority ) )
        {
            msg_Err( p_stream, "cannot spawn encoder thread" );
            module_unneed( id->p_decoder, id->p_decoder->p_module );
            id->p_decoder->p_module = 0;
            free( id->p_decoder->p_owner );
            return VLC_EGENERIC;
        }
    }
    return VLC_SUCCESS;
}
コード例 #22
0
ファイル: thread.c プロジェクト: mahaserver/MHSVLC
/**
 * Create the main playlist thread
 * Additionally to the playlist, this thread controls :
 *    - Statistics
 *    - VLM
 * \param p_parent
 * \return an object with a started thread
 */
void __playlist_ThreadCreate( vlc_object_t *p_parent )
{
    playlist_t *p_playlist = playlist_Create( p_parent );
    if( !p_playlist ) return;

    // Preparse
    static const char ppname[] = "preparser";
    p_playlist->p_preparse =
        vlc_custom_create( p_playlist, sizeof( playlist_preparse_t ),
                           VLC_OBJECT_GENERIC, ppname );
    if( !p_playlist->p_preparse )
    {
        msg_Err( p_playlist, "unable to create preparser" );
        vlc_object_release( p_playlist );
        return;
    }
    p_playlist->p_preparse->i_waiting = 0;
    p_playlist->p_preparse->pp_waiting = NULL;

    vlc_object_set_destructor( p_playlist->p_preparse, PreparseDestructor );

    vlc_object_attach( p_playlist->p_preparse, p_playlist );
    if( vlc_thread_create( p_playlist->p_preparse, "preparser",
                           RunPreparse, VLC_THREAD_PRIORITY_LOW, true ) )
    {
        msg_Err( p_playlist, "cannot spawn preparse thread" );
        vlc_object_release( p_playlist->p_preparse );
        return;
    }

    // Secondary Preparse
    static const char fname[] = "fetcher";
    p_playlist->p_fetcher =
        vlc_custom_create( p_playlist, sizeof( playlist_fetcher_t ),
                           VLC_OBJECT_GENERIC, fname );
    if( !p_playlist->p_fetcher )
    {
        msg_Err( p_playlist, "unable to create secondary preparser" );
        vlc_object_release( p_playlist );
        return;
    }
    p_playlist->p_fetcher->i_waiting = 0;
    p_playlist->p_fetcher->pp_waiting = NULL;
    p_playlist->p_fetcher->i_art_policy = var_CreateGetInteger( p_playlist,
                                                                "album-art" );

    vlc_object_set_destructor( p_playlist->p_fetcher, FetcherDestructor );

    vlc_object_attach( p_playlist->p_fetcher, p_playlist );
    if( vlc_thread_create( p_playlist->p_fetcher,
                           "fetcher",
                           RunFetcher,
                           VLC_THREAD_PRIORITY_LOW, true ) )
    {
        msg_Err( p_playlist, "cannot spawn secondary preparse thread" );
        vlc_object_release( p_playlist->p_fetcher );
        return;
    }

    // Start the thread
    if( vlc_thread_create( p_playlist, "playlist", RunControlThread,
                           VLC_THREAD_PRIORITY_LOW, true ) )
    {
        msg_Err( p_playlist, "cannot spawn playlist thread" );
        vlc_object_release( p_playlist );
        return;
    }

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

    return;
}
コード例 #23
0
ファイル: encoder.c プロジェクト: forthyen/SDesk
/****************************************************************************
 * EncodeVideo: the whole thing
 ****************************************************************************/
static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    AVFrame frame;
    int i_out, i_plane;

#if LIBAVCODEC_BUILD >= 4702
    if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
    {
        struct thread_context_t ** pp_contexts;
        int i;

        p_sys->b_inited = 1;
        pp_contexts = malloc( sizeof(struct thread_context_t *)
                                 * p_enc->i_threads );
        p_sys->p_context->thread_opaque = (void *)pp_contexts;

        for ( i = 0; i < p_enc->i_threads; i++ )
        {
            pp_contexts[i] = vlc_object_create( p_enc,
                                     sizeof(struct thread_context_t) );
            pp_contexts[i]->p_context = p_sys->p_context;
            vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
            vlc_cond_init( p_enc, &pp_contexts[i]->cond );
            pp_contexts[i]->b_work = 0;
            pp_contexts[i]->b_done = 0;
            if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
                                    VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
            {
                msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
                return NULL;
            }
        }

        p_sys->p_context->execute = FfmpegExecute;
    }
#endif

    memset( &frame, 0, sizeof( AVFrame ) );
    for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
    {
        frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
        frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
    }

    /* Let ffmpeg select the frame type */
    frame.pict_type = 0;

    frame.repeat_pict = 2 - p_pict->i_nb_fields;

#if LIBAVCODEC_BUILD >= 4685
    frame.interlaced_frame = !p_pict->b_progressive;
    frame.top_field_first = !!p_pict->b_top_field_first;
#endif

#if LIBAVCODEC_BUILD < 4702
    /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
    if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) )
#else
    if( 1 )
#endif
    {
        frame.pts = p_pict->date ? p_pict->date : AV_NOPTS_VALUE;

        if ( p_sys->b_hurry_up && frame.pts != AV_NOPTS_VALUE )
        {
            mtime_t current_date = mdate();

            if ( current_date + HURRY_UP_GUARD3 > frame.pts )
            {
                p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
                p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
                msg_Dbg( p_enc, "hurry up mode 3" );
            }
            else
            {
                p_sys->p_context->mb_decision = p_sys->i_hq;

                if ( current_date + HURRY_UP_GUARD2 > frame.pts )
                {
                    p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
#if LIBAVCODEC_BUILD >= 4690
                    p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
                         + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
#endif
                    msg_Dbg( p_enc, "hurry up mode 2" );
                }
                else
                {
                    if ( p_sys->b_trellis )
                        p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
#if LIBAVCODEC_BUILD >= 4690
                    p_sys->p_context->noise_reduction =
                        p_sys->i_noise_reduction;
#endif
                }
            }

            if ( current_date + HURRY_UP_GUARD1 > frame.pts )
            {
                frame.pict_type = FF_P_TYPE;
                /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
            }
        }
    }
    else
    {
        frame.pts = AV_NOPTS_VALUE;
    }

    if ( frame.pts != AV_NOPTS_VALUE && frame.pts != 0 )
    {
        if ( p_sys->i_last_pts == frame.pts )
        {
            msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
                      "same PTS (" I64Fd ")", frame.pts );
            return NULL;
        }
        else if ( p_sys->i_last_pts > frame.pts )
        {
            msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
                      "past (current: " I64Fd ", last: "I64Fd")",
                      frame.pts, p_sys->i_last_pts );
            return NULL;
        }
        else
        {
            p_sys->i_last_pts = frame.pts;
        }
    }

    frame.quality = p_sys->i_quality;

    /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
    p_sys->i_framenum++;
    p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
    frame.pts = p_sys->i_framenum * AV_TIME_BASE *
        p_enc->fmt_in.video.i_frame_rate_base;
    frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
    frame.pts /= p_enc->fmt_in.video.i_frame_rate;
#endif
    /* End work-around */

    i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
                                  AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );

    if( i_out > 0 )
    {
        block_t *p_block = block_New( p_enc, i_out );
        memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );

        /* FIXME, 3-2 pulldown is not handled correctly */
        p_block->i_length = I64C(1000000) *
            p_enc->fmt_in.video.i_frame_rate_base /
                p_enc->fmt_in.video.i_frame_rate;

        if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
        {
            /* No delay -> output pts == input pts */
            p_block->i_pts = p_block->i_dts = p_pict->date;
        }
        else if( p_sys->p_context->coded_frame->pts != AV_NOPTS_VALUE &&
            p_sys->p_context->coded_frame->pts != 0 &&
            p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
        {
            p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
            p_block->i_pts = p_sys->p_context->coded_frame->pts;

            /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
            {
            int64_t i_framenum = p_block->i_pts *
                p_enc->fmt_in.video.i_frame_rate /
                p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;

            p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
            }
#endif
            /* End work-around */

            if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
                p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
            {
                p_block->i_dts = p_block->i_pts;
            }
            else
            {
                if( p_sys->i_last_ref_pts )
                {
                    p_block->i_dts = p_sys->i_last_ref_pts;
                }
                else
                {
                    /* Let's put something sensible */
                    p_block->i_dts = p_block->i_pts;
                }

                p_sys->i_last_ref_pts = p_block->i_pts;
            }
        }
        else
        {
            /* Buggy libavcodec which doesn't update coded_frame->pts
             * correctly */
            p_block->i_dts = p_block->i_pts = p_pict->date;
        }

        switch ( p_sys->p_context->coded_frame->pict_type )
        {
        case FF_I_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_I;
            break;
        case FF_P_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_P;
            break;
        case FF_B_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_B;
            break;
        }

        return p_block;
    }

    return NULL;
}
コード例 #24
0
ファイル: goom.c プロジェクト: banketree/faplayer
/*****************************************************************************
 * Open: open a scope effect plugin
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    filter_t       *p_filter = (filter_t *)p_this;
    filter_sys_t   *p_sys;
    goom_thread_t  *p_thread;
    int             width, height;
    video_format_t fmt;


    if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ||
         p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 )
    {
        msg_Warn( p_filter, "bad input or output format" );
        return VLC_EGENERIC;
    }
    if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) )
    {
        msg_Warn( p_filter, "input and output formats are not similar" );
        return VLC_EGENERIC;
    }

    p_filter->pf_audio_filter = DoWork;

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

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

    width = var_CreateGetInteger( p_thread, "goom-width" );
    height = var_CreateGetInteger( p_thread, "goom-height" );

    memset( &fmt, 0, sizeof(video_format_t) );

    fmt.i_width = fmt.i_visible_width = width;
    fmt.i_height = fmt.i_visible_height = height;
    fmt.i_chroma = VLC_CODEC_RGB32;
    fmt.i_sar_num = fmt.i_sar_den = 1;

    p_thread->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt );
    if( p_thread->p_vout == NULL )
    {
        msg_Err( p_filter, "no suitable vout module" );
        vlc_object_release( p_thread );
        free( p_sys );
        return VLC_EGENERIC;
    }
    vlc_mutex_init( &p_thread->lock );
    vlc_cond_init( &p_thread->wait );

    p_thread->i_blocks = 0;
    date_Init( &p_thread->date, p_filter->fmt_out.audio.i_rate, 1 );
    date_Set( &p_thread->date, 0 );
    p_thread->i_channels = aout_FormatNbChannels( &p_filter->fmt_in.audio );

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

    if( vlc_thread_create( p_thread, Thread,
                           VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot lauch goom thread" );
        vlc_object_release( p_thread->p_vout );
        vlc_mutex_destroy( &p_thread->lock );
        vlc_cond_destroy( &p_thread->wait );
        free( p_thread->psz_title );
        vlc_object_release( p_thread );
        free( p_sys );
        return VLC_EGENERIC;
    }

    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
ファイル: goom.c プロジェクト: forthyen/SDesk
/*****************************************************************************
 * 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;
    goom_thread_t     *p_thread;
    vlc_value_t       width, height;

    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 goom thread */
    p_sys->p_thread = p_thread =
        vlc_object_create( p_filter, sizeof( goom_thread_t ) );
    vlc_object_attach( p_thread, p_this );

    var_Create( p_thread, "goom-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "goom-width", &width );
    var_Create( p_thread, "goom-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "goom-height", &height );

    p_thread->p_vout =
        vout_Request( p_filter, NULL, width.i_int, height.i_int,
                      VLC_FOURCC('R','V','3','2'),
                      VOUT_ASPECT_FACTOR * width.i_int/height.i_int );
    if( p_thread->p_vout == NULL )
    {
        msg_Err( p_filter, "no suitable vout module" );
        vlc_object_detach( p_thread );
        vlc_object_destroy( p_thread );
        free( p_sys );
        return VLC_EGENERIC;
    }
    vlc_mutex_init( p_filter, &p_thread->lock );
    vlc_cond_init( p_filter, &p_thread->wait );

    p_thread->i_blocks = 0;
    aout_DateInit( &p_thread->date, p_filter->output.i_rate );
    aout_DateSet( &p_thread->date, 0 );
    p_thread->i_channels = aout_FormatNbChannels( &p_filter->input );

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

    if( vlc_thread_create( p_thread, "Goom Update Thread", Thread,
                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
    {
        msg_Err( p_filter, "cannot lauch goom thread" );
        vout_Destroy( p_thread->p_vout );
        vlc_mutex_destroy( &p_thread->lock );
        vlc_cond_destroy( &p_thread->wait );
        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;
}