⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directx.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    vlc_object_attach( p_aout->output.p_sys->p_notif, p_aout );    return VLC_SUCCESS; error:    CloseAudio( VLC_OBJECT(p_aout) );    return VLC_EGENERIC;}/***************************************************************************** * Probe: probe the audio device for available formats and channels *****************************************************************************/static void Probe( aout_instance_t * p_aout ){    vlc_value_t val, text;    int i_format;    unsigned int i_physical_channels;    DWORD ui_speaker_config;    var_Create( p_aout, "audio-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );    text.psz_string = _("Audio Device");    var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );    /* Test for 5.1 support */    i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |                          AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |                          AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;    if( p_aout->output.output.i_physical_channels == i_physical_channels )    {        if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 6,                               p_aout->output.output.i_rate, VLC_TRUE )            == VLC_SUCCESS )        {            val.i_int = AOUT_VAR_5_1;            text.psz_string = N_("5.1");            var_Change( p_aout, "audio-device",                        VLC_VAR_ADDCHOICE, &val, &text );            msg_Dbg( p_aout, "device supports 5.1 channels" );        }    }    /* Test for 3 Front 2 Rear support */    i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |                          AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |                          AOUT_CHAN_REARRIGHT;    if( p_aout->output.output.i_physical_channels == i_physical_channels )    {        if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 5,                               p_aout->output.output.i_rate, VLC_TRUE )            == VLC_SUCCESS )        {            val.i_int = AOUT_VAR_3F2R;            text.psz_string = N_("3 Front 2 Rear");            var_Change( p_aout, "audio-device",                        VLC_VAR_ADDCHOICE, &val, &text );            msg_Dbg( p_aout, "device supports 5 channels" );        }    }    /* Test for 2 Front 2 Rear support */    i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |                          AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;    if( ( p_aout->output.output.i_physical_channels & i_physical_channels )        == i_physical_channels )    {        if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 4,                               p_aout->output.output.i_rate, VLC_TRUE )            == VLC_SUCCESS )        {            val.i_int = AOUT_VAR_2F2R;            text.psz_string = N_("2 Front 2 Rear");            var_Change( p_aout, "audio-device",                        VLC_VAR_ADDCHOICE, &val, &text );            msg_Dbg( p_aout, "device supports 4 channels" );        }    }    /* Test for stereo support */    i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;    if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 2,                           p_aout->output.output.i_rate, VLC_TRUE )        == VLC_SUCCESS )    {        val.i_int = AOUT_VAR_STEREO;        text.psz_string = N_("Stereo");        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );        var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );        msg_Dbg( p_aout, "device supports 2 channels" );    }    /* Test for mono support */    i_physical_channels = AOUT_CHAN_CENTER;    if( CreateDSBufferPCM( p_aout, &i_format, i_physical_channels, 1,                           p_aout->output.output.i_rate, VLC_TRUE )        == VLC_SUCCESS )    {        val.i_int = AOUT_VAR_MONO;        text.psz_string = N_("Mono");        var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );        msg_Dbg( p_aout, "device supports 1 channel" );    }    /* Check the speaker configuration to determine which channel config should     * be the default */    if FAILED( IDirectSound_GetSpeakerConfig( p_aout->output.p_sys->p_dsobject,                                              &ui_speaker_config ) )    {        ui_speaker_config = DSSPEAKER_STEREO;    }    switch( DSSPEAKER_CONFIG(ui_speaker_config) )    {    case DSSPEAKER_5POINT1:        val.i_int = AOUT_VAR_5_1;        break;    case DSSPEAKER_QUAD:        val.i_int = AOUT_VAR_2F2R;        break;#if 0 /* Lots of people just get their settings wrong and complain that       * this is a problem with VLC so just don't ever set mono by default. */    case DSSPEAKER_MONO:        val.i_int = AOUT_VAR_MONO;        break;#endif    case DSSPEAKER_SURROUND:    case DSSPEAKER_STEREO:    default:        val.i_int = AOUT_VAR_STEREO;        break;    }    var_Set( p_aout, "audio-device", val );    /* Test for SPDIF support */    if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )    {        if( CreateDSBuffer( 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,                            AOUT_SPDIF_SIZE, VLC_TRUE )            == VLC_SUCCESS )        {            msg_Dbg( p_aout, "device supports A/52 over S/PDIF" );            val.i_int = AOUT_VAR_SPDIF;            text.psz_string = N_("A/52 over S/PDIF");            var_Change( p_aout, "audio-device",                        VLC_VAR_ADDCHOICE, &val, &text );            if( config_GetInt( p_aout, "spdif" ) )                var_Set( p_aout, "audio-device", val );        }    }    var_Change( p_aout, "audio-device", VLC_VAR_CHOICESCOUNT, &val, NULL );    if( val.i_int <= 0 )    {        /* Probe() has failed. */        var_Destroy( p_aout, "audio-device" );        return;    }    var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );    val.b_bool = VLC_TRUE;    var_Set( p_aout, "intf-change", val );}/***************************************************************************** * Play: we'll start playing the directsound buffer here because at least here *       we know the first buffer has been put in the aout fifo and we also *       know its date. *****************************************************************************/static void Play( aout_instance_t *p_aout ){    if( !p_aout->output.p_sys->b_playing )    {        aout_buffer_t *p_buffer;        p_aout->output.p_sys->b_playing = 1;        /* get the playing date of the first aout buffer */        p_aout->output.p_sys->p_notif->start_date =            aout_FifoFirstDate( p_aout, &p_aout->output.fifo );        /* fill in the first samples */        p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );        FillBuffer( p_aout, 0, p_buffer );        /* wake up the audio output thread */        SetEvent( p_aout->output.p_sys->p_notif->p_events[0].hEventNotify );    }}/***************************************************************************** * CloseAudio: close the audio device *****************************************************************************/static void CloseAudio( vlc_object_t *p_this ){    aout_instance_t * p_aout = (aout_instance_t *)p_this;    aout_sys_t *p_sys = p_aout->output.p_sys;    msg_Dbg( p_aout, "CloseAudio" );    /* kill the position notification thread, if any */    if( p_sys->p_notif )    {        vlc_object_detach( p_sys->p_notif );        if( p_sys->p_notif->b_thread )        {            p_sys->p_notif->b_die = 1;            if( !p_sys->b_playing )                /* wake up the audio thread */                SetEvent( p_sys->p_notif->p_events[0].hEventNotify );            vlc_thread_join( p_sys->p_notif );        }        vlc_object_destroy( p_sys->p_notif );    }    /* release the secondary buffer */    DestroyDSBuffer( p_aout );    /* finally release the DirectSound object */    if( p_sys->p_dsobject ) IDirectSound_Release( p_sys->p_dsobject );        /* free DSOUND.DLL */    if( p_sys->hdsound_dll ) FreeLibrary( p_sys->hdsound_dll );    if( p_aout->output.p_sys->p_device_guid )        free( p_aout->output.p_sys->p_device_guid );    free( p_sys );}/***************************************************************************** * CallBackDirectSoundEnum: callback to enumerate available devices *****************************************************************************/static int CALLBACK CallBackDirectSoundEnum( LPGUID p_guid, LPCSTR psz_desc,                                             LPCSTR psz_mod, LPVOID _p_aout ){    aout_instance_t *p_aout = (aout_instance_t *)_p_aout;    msg_Dbg( p_aout, "found device: %s", psz_desc );    if( p_aout->output.p_sys->i_device_id == 0 && p_guid )    {        p_aout->output.p_sys->p_device_guid = malloc( sizeof( GUID ) );        *p_aout->output.p_sys->p_device_guid = *p_guid;        msg_Dbg( p_aout, "using device: %s", psz_desc );    }    p_aout->output.p_sys->i_device_id--;    return 1;}/***************************************************************************** * InitDirectSound: handle all the gory details of DirectSound initialisation *****************************************************************************/static int InitDirectSound( aout_instance_t *p_aout ){    HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);    HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACK, LPVOID);    p_aout->output.p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL");    if( p_aout->output.p_sys->hdsound_dll == NULL )    {        msg_Warn( p_aout, "cannot open DSOUND.DLL" );        goto error;    }    OurDirectSoundCreate = (void *)        GetProcAddress( p_aout->output.p_sys->hdsound_dll,                        "DirectSoundCreate" );    if( OurDirectSoundCreate == NULL )    {        msg_Warn( p_aout, "GetProcAddress FAILED" );        goto error;    }    /* Get DirectSoundEnumerate */    OurDirectSoundEnumerate = (void *)       GetProcAddress( p_aout->output.p_sys->hdsound_dll,                       "DirectSoundEnumerateA" );    if( OurDirectSoundEnumerate )    {        /* Attempt enumeration */        if( FAILED( OurDirectSoundEnumerate( CallBackDirectSoundEnum,                                              p_aout ) ) )        {            msg_Dbg( p_aout, "enumeration of DirectSound devices failed" );        }    }    /* Create the direct sound object */    if FAILED( OurDirectSoundCreate( p_aout->output.p_sys->p_device_guid,                                      &p_aout->output.p_sys->p_dsobject,                                     NULL ) )    {        msg_Warn( p_aout, "cannot create a direct sound device" );        goto error;    }    /* Set DirectSound Cooperative level, ie what control we want over Windows     * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the     * settings of the primary buffer, but also that only the sound of our     * application will be hearable when it will have the focus.     * !!! (this is not really working as intended yet because to set the     * cooperative level you need the window handle of your application, and     * I don't know of any easy way to get it. Especially since we might play     * sound without any video, and so what window handle should we use ???     * The hack for now is to use the Desktop window handle - it seems to be     * working */    if( IDirectSound_SetCooperativeLevel( p_aout->output.p_sys->p_dsobject,                                          GetDesktopWindow(),                                          DSSCL_EXCLUSIVE) )    {        msg_Warn( p_aout, "cannot set direct sound cooperative level" );    }    return VLC_SUCCESS; error:    p_aout->output.p_sys->p_dsobject = NULL;    if( p_aout->output.p_sys->hdsound_dll )    {        FreeLibrary( p_aout->output.p_sys->hdsound_dll );        p_aout->output.p_sys->hdsound_dll = NULL;    }    return VLC_EGENERIC;}/***************************************************************************** * CreateDSBuffer: Creates a direct sound buffer of the required format. ***************************************************************************** * This function creates the buffer we'll use to play audio. * In DirectSound there are two kinds of buffers: * - the primary buffer: which is the actual buffer that the soundcard plays * - the secondary buffer(s): these buffers are the one actually used by *    applications and DirectSound takes care of mixing them into the primary. * * Once you create a secondary buffer, you cannot change its format anymore so * you have to release the current one and create another. *****************************************************************************/static int CreateDSBuffer( aout_instance_t *p_aout, int i_format,                           int i_channels, int i_nb_channels, int i_rate,                           int i_bytes_per_frame, vlc_bool_t b_probe ){    WAVEFORMATEXTENSIBLE waveformat;    DSBUFFERDESC         dsbdesc;    unsigned int         i;    /* First set the sound buffer format */    waveformat.dwChannelMask = 0;    for( i = 0; i < sizeof(pi_channels_src)/sizeof(uint32_t); i++ )    {        if( i_channels & pi_channels_src[i] )            waveformat.dwChannelMask |= pi_channels_in[i];    }    switch( i_format )    {    case VLC_FOURCC('s','p','d','i'):        i_nb_channels = 2;        /* To prevent channel re-ordering */        waveformat.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;        waveformat.Format.wBitsPerSample = 16;        waveformat.Samples.wValidBitsPerSample =            waveformat.Format.wBitsPerSample;        waveformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;        break;    case VLC_FOURCC('f','l','3','2'):        waveformat.Format.wBitsPerSample = sizeof(float) * 8;        waveformat.Samples.wValidBitsPerSample =            waveformat.Format.wBitsPerSample;        waveformat.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;        break;    case VLC_FOURCC('s','1','6','l'):        waveformat.Format.wBitsPerSample = 16;        waveformat.Samples.wValidBitsPerSample =            waveformat.Format.wBitsPerSample;        waveformat.Format.wFormatTag = WAVE_FORMAT_PCM;        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_PCM;        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -