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

📄 coreaudio.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * coreaudio.c: CoreAudio output plugin ***************************************************************************** * Copyright (C) 2002-2004 VideoLAN * $Id: coreaudio.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Colin Delacroix <colin@zoy.org> *          Jon Lech Johansen <jon-vl@nanocrew.net> *          Christophe Massiot <massiot@via.ecp.fr> *          Heiko Panther <heiko.panther@web.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <string.h>#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/aout.h>#include "aout_internal.h"#include <CoreAudio/CoreAudio.h>#define STREAM_FORMAT_MSG( pre, sfm ) \    pre ": [%ld][%4.4s][%ld][%ld][%ld][%ld][%ld][%ld]", \    (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \    sfm.mFormatFlags, sfm.mBytesPerPacket, \    sfm.mFramesPerPacket, sfm.mBytesPerFrame, \    sfm.mChannelsPerFrame, sfm.mBitsPerChannel/***************************************************************************** * aout_class_t  ****************************************************************************/enum AudioDeviceClass{    AudioDeviceClassA52     = 1 << 0,    AudioDeviceClassPCM     = 1 << 1};static struct aout_class_t{    UInt32 mFormatID;    UInt32 mChannelsPerFrame;    enum AudioDeviceClass class;    const char * psz_class;}aout_classes[] ={    { /* old A/52 format type */        'IAC3',         2,         AudioDeviceClassA52,         "Digital A/52"     },    { /* new A/52 format type */        kAudioFormat60958AC3,         2,         AudioDeviceClassA52,         "Digital A/52"    },    {        kAudioFormatLinearPCM,         2,         AudioDeviceClassPCM,         "Stereo PCM"    },    {        kAudioFormatLinearPCM,         1,         AudioDeviceClassPCM,         "Mono PCM"    },    {        kAudioFormatLinearPCM,        4,        AudioDeviceClassPCM,        "4 Channel PCM"    },    {        kAudioFormatLinearPCM,         6,         AudioDeviceClassPCM,         "6 Channel PCM"    },    {        kAudioFormatLinearPCM,        8,        AudioDeviceClassPCM,        "8 Channel PCM"    }}; #define N_AOUT_CLASSES (sizeof(aout_classes)/sizeof(aout_classes[0]))/***************************************************************************** * aout_option_t ****************************************************************************/struct aout_option_t{    char sz_option[64];    UInt32 i_dev, i_idx;    UInt32 i_sdx, i_cdx;    AudioStreamID i_sid;};/***************************************************************************** * aout_dev_t ****************************************************************************/struct aout_dev_t{    AudioDeviceID devid;    char * psz_device_name;    UInt32 i_streams;    UInt32 * pi_streams;    AudioStreamBasicDescription ** pp_streams;};/***************************************************************************** * aout_sys_t: private audio output method descriptor ***************************************************************************** * This structure is part of the audio output thread descriptor. * It describes the CoreAudio specific properties of an output thread. *****************************************************************************/struct aout_sys_t{    vlc_mutex_t                 lock;    vlc_bool_t                  b_hwinfo;    UInt32                      i_def_dev;    UInt32                      i_devices;    struct aout_dev_t *         p_devices;    UInt32                      i_sel_opt;    UInt32                      i_options;    struct aout_option_t *      p_options;    AudioDeviceID               devid;    UInt32                      i_stream_index;    AudioStreamBasicDescription stream_format;    UInt32                      b_dev_alive;    vlc_bool_t                  b_revert_sfmt;    AudioStreamBasicDescription sfmt_revert;    UInt32                      i_bufframe_size;    mtime_t                     clock_diff;};/***************************************************************************** * Local prototypes. *****************************************************************************/static int      InitHardwareInfo ( aout_instance_t * p_aout );static int      InitDeviceInfo   ( UInt32 i_dev, aout_instance_t * p_aout ); static void     FreeDeviceInfo   ( UInt32 i_dev, aout_instance_t * p_aout ); static void     FreeHardwareInfo ( aout_instance_t * p_aout );static int      InitDevice       ( aout_instance_t * p_aout );static void     FreeDevice       ( aout_instance_t * p_aout );static int      GetStreamID      ( AudioDeviceID devid, UInt32 i_idx,                                   AudioStreamID * p_sid );static int      InitStreamInfo   ( UInt32 i_dev, aout_instance_t * p_aout,                                   UInt32 i_idx );static void     FreeStreamInfo   ( UInt32 i_dev, aout_instance_t * p_aout,                                   UInt32 i_idx );static void     InitDeviceVar    ( aout_instance_t * p_aout, int i_option,                                   vlc_bool_t b_change );static int      Open             ( vlc_object_t * );static void     Close            ( vlc_object_t * );static void     Play             ( aout_instance_t * p_aout );static OSStatus IOCallback       ( AudioDeviceID inDevice,                                   const AudioTimeStamp * inNow,                                    const void * inInputData,                                    const AudioTimeStamp * inInputTime,                                   AudioBufferList * outOutputData,                                    const AudioTimeStamp * inOutputTime,                                    void * threadGlobals );static OSStatus HardwareListener ( AudioHardwarePropertyID inPropertyID,                                   void * inClientData );static OSStatus DeviceListener   ( AudioDeviceID inDevice,                                   UInt32 inChannel,                                   Boolean isInput,                                   AudioDevicePropertyID inPropertyID,                                   void * inClientData );static OSStatus StreamListener   ( AudioStreamID inStream,                                   UInt32 inChannel,                                   AudioDevicePropertyID inPropertyID,                                   void * inClientData );/***************************************************************************** * Module descriptor *****************************************************************************/#define ADEV_TEXT N_("Audio Device")#define ADEV_LONGTEXT N_("Choose a number corresponding to the number of an " \    "audio device, as listed in your 'Audio Device' menu. This device will " \    "then be used by default for audio playback.")vlc_module_begin();    set_shortname( "CoreAudio" );    set_description( _("CoreAudio output") );    set_capability( "audio output", 100 );    set_category( CAT_AUDIO );    set_subcategory( SUBCAT_AUDIO_AOUT );    set_callbacks( Open, Close );    add_integer( "coreaudio-dev", -1, NULL, ADEV_TEXT, ADEV_LONGTEXT, VLC_FALSE ); vlc_module_end();/***************************************************************************** * Open: open a CoreAudio HAL device *****************************************************************************/static int Open( vlc_object_t * p_this ){    OSStatus err;    UInt32 i_param_size;    struct aout_sys_t * p_sys;    aout_instance_t * p_aout = (aout_instance_t *)p_this;    struct aout_option_t * p_option;    UInt32 i_startingChannel;    /* Allocate structure */    p_sys = (struct aout_sys_t *)malloc( sizeof( struct aout_sys_t ) );    if( p_sys == NULL )    {        msg_Err( p_aout, "out of memory" );        return( VLC_ENOMEM );    }    memset( p_sys, 0, sizeof( struct aout_sys_t ) );    p_aout->output.p_sys = p_sys;    p_aout->output.pf_play = Play;    vlc_mutex_init( p_aout, &p_sys->lock );    if( InitHardwareInfo( p_aout ) )    {        msg_Err( p_aout, "InitHardwareInfo failed" );        vlc_mutex_destroy( &p_sys->lock );        free( (void *)p_sys );        return( VLC_EGENERIC );    }     if( var_Type( p_aout, "audio-device" ) == 0 )    {        InitDeviceVar( p_aout, config_GetInt( p_aout, "coreaudio-dev" ),                       VLC_FALSE );    }    if( InitDevice( p_aout ) )    {        msg_Err( p_aout, "InitDevice failed" );        FreeHardwareInfo( p_aout );        vlc_mutex_destroy( &p_sys->lock );        free( (void *)p_sys );        return( VLC_EGENERIC );    }     /* get starting channel for the selected stream */    p_option = &p_sys->p_options[p_sys->i_sel_opt];    i_param_size = sizeof( UInt32 );     err = AudioStreamGetProperty( p_option->i_sid, 0,                                   kAudioStreamPropertyStartingChannel,                                  &i_param_size, &i_startingChannel );    if( err != noErr )    {        msg_Err( p_aout, "failed to get channel number: [%4.4s]",                  (char *)&err );        FreeDevice( p_aout );        FreeHardwareInfo( p_aout );        vlc_mutex_destroy( &p_sys->lock );        free( (void *)p_sys );        return( VLC_EGENERIC );    }        msg_Dbg( p_aout, "starting channel: [%ld]", i_startingChannel );    /* Get a description of the stream format */    i_param_size = sizeof( AudioStreamBasicDescription );     err = AudioDeviceGetProperty( p_sys->devid, i_startingChannel, FALSE,                                   kAudioDevicePropertyStreamFormat,                                  &i_param_size, &p_sys->stream_format );    if( err != noErr )    {        msg_Err( p_aout, "failed to get stream format: [%4.4s]",                  (char *)&err );        FreeDevice( p_aout );        FreeHardwareInfo( p_aout );        vlc_mutex_destroy( &p_sys->lock );        free( (void *)p_sys );        return( VLC_EGENERIC );    }    /* Set the output sample rate */    p_aout->output.output.i_rate =         (unsigned int)p_sys->stream_format.mSampleRate;    msg_Dbg( p_aout, STREAM_FORMAT_MSG( "using format",                                        p_sys->stream_format ) );    /* Get the bufframe size */    i_param_size = sizeof( p_sys->i_bufframe_size );    err = AudioDeviceGetProperty( p_sys->devid, i_startingChannel, FALSE,                                   kAudioDevicePropertyBufferFrameSize,                                   &i_param_size, &p_sys->i_bufframe_size );    if( err != noErr )    {        msg_Err( p_aout, "failed to get bufframe size: [%4.4s]",                  (char *)&err );        FreeDevice( p_aout );        FreeHardwareInfo( p_aout );        vlc_mutex_destroy( &p_sys->lock );        free( (void *)p_sys );        return( VLC_EGENERIC );    }    msg_Dbg( p_aout, "device bufframe size: [%ld]", p_sys->i_bufframe_size );    msg_Dbg( p_aout, "device buffer index: [%ld]", p_sys->i_stream_index );    /* If we do AC3 over SPDIF, set buffer size to one AC3 frame */    if( ( p_sys->stream_format.mFormatID == kAudioFormat60958AC3 ||          p_sys->stream_format.mFormatID == 'IAC3' ) &&        p_sys->i_bufframe_size != A52_FRAME_NB )    {        p_sys->i_bufframe_size = A52_FRAME_NB;        i_param_size = sizeof( p_sys->i_bufframe_size );        err = AudioDeviceSetProperty( p_sys->devid, 0, 0, FALSE,                                      kAudioDevicePropertyBufferFrameSize,                                      i_param_size, &p_sys->i_bufframe_size );        if( err != noErr )        {            msg_Err( p_aout, "failed to set bufframe size (%ld): [%4.4s]",                      p_sys->i_bufframe_size, (char *)&err );            FreeDevice( p_aout );            FreeHardwareInfo( p_aout );            vlc_mutex_destroy( &p_sys->lock );            free( (void *)p_sys );            return( VLC_EGENERIC );        }        msg_Dbg( p_aout, "device bufframe size set to: [%ld]",                  p_sys->i_bufframe_size );    }    switch( p_sys->stream_format.mFormatID )    {    case kAudioFormatLinearPCM:        p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');        switch( p_sys->stream_format.mChannelsPerFrame )        {        case 1:            p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;            break;

⌨️ 快捷键说明

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