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

📄 auhal.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * auhal.c: AUHAL output plugin ***************************************************************************** * Copyright (C) 2005 VideoLAN * $Id$ * * Authors: Derk-Jan Hartman <hartman at videolan dot org> * * 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>#include <CoreAudio/CoreAudioTypes.h>#include <AudioUnit/AudioUnitProperties.h>#include <AudioUnit/AudioUnitParameters.h>#include <AudioUnit/AudioOutputUnit.h>#include <AudioToolbox/AudioFormat.h>#define STREAM_FORMAT_MSG( pre, sfm ) \    pre ":\nsamplerate: [%ld]\nFormatID: [%4.4s]\nFormatFlags: [%ld]\nBypesPerPacket: [%ld]\nFramesPerPacket: [%ld]\nBytesPerFrame: [%ld]\nChannelsPerFrame: [%ld]\nBitsPerChannel[%ld]", \    (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \    sfm.mFormatFlags, sfm.mBytesPerPacket, \    sfm.mFramesPerPacket, sfm.mBytesPerFrame, \    sfm.mChannelsPerFrame, sfm.mBitsPerChannel#define BUFSIZE 0xffffff/***************************************************************************** * 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{    AudioDeviceID               i_default_dev;  /* Keeps DeviceID of defaultOutputDevice */    AudioDeviceID               i_selected_dev; /* Keeps DeviceID of the selected device */    UInt32                      i_devices;      /* Number of CoreAudio Devices */    vlc_bool_t                  b_supports_digital;/* Does the currently selected device support digital mode? */    vlc_bool_t                  b_digital;      /* Are we running in digital mode? */    Component                   au_component;   /* The Audiocomponent we use */    AudioUnit                   au_unit;        /* The AudioUnit we use */    mtime_t                     clock_diff;    uint8_t                      p_remainder_buffer[BUFSIZE];    uint32_t                    i_read_bytes;    uint32_t                    i_total_bytes;    audio_date_t                end_date_t;        };/***************************************************************************** * Local prototypes. *****************************************************************************/static int      Open                    ( vlc_object_t * );static void     Close                   ( vlc_object_t * );static void     Play                    ( aout_instance_t *);static int      Probe                   ( aout_instance_t * );static int      DeviceDigitalMode       ( aout_instance_t *, AudioDeviceID );int             AudioDeviceHasOutput    ( AudioDeviceID );static int      DigitalInit             ( aout_instance_t * );static OSStatus RenderCallbackAnalog    ( vlc_object_t *, AudioUnitRenderActionFlags *, const AudioTimeStamp *,                                          unsigned int, unsigned int, AudioBufferList *);static OSStatus HardwareListener        ( AudioHardwarePropertyID, void *);/***************************************************************************** * 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( "auhal" );    set_description( _("HAL AudioUnit output") );    set_capability( "audio output", 101 );    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 HAL AudioUnit *****************************************************************************/static int Open( vlc_object_t * p_this ){    OSStatus                err = noErr;    ComponentDescription    desc;    UInt32                  i_param_size,i;    struct aout_sys_t       *p_sys;    vlc_value_t             val;    aout_instance_t         *p_aout = (aout_instance_t *)p_this;    /* 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_sys->b_digital = VLC_FALSE; /* We assume we are not digital */    p_aout->output.p_sys = p_sys;    p_aout->output.pf_play = Play;        aout_FormatPrint( p_aout, "VLC is looking for:\n", (audio_sample_format_t *)&p_aout->output.output );        /* Build a list of devices */    if( var_Type( p_aout, "audio-device" ) == 0 )    {        Probe( p_aout );        /*if( Probe( p_aout ) != VLC_SUCCESS );        {            msg_Err( p_aout, "Probe failed" );            free( p_sys );            return VLC_EGENERIC;        }*/    }        /* What device do we want? */    if( var_Get( p_aout, "audio-device", &val ) < 0 )    {        msg_Err( p_aout, "audio-device var does not exist" );        free( p_sys );        return( VLC_ENOVAR );    }    p_sys->i_selected_dev = val.i_int;    /* what is vlc format? if digital, take digital route else AUHAL route */    DeviceDigitalMode( p_aout, p_sys->i_selected_dev );    /*if( DeviceDigitalMode( p_aout, p_sys->i_selected_dev ) != VLC_SUCCESS );    {        msg_Err( p_aout, "DeviceDigitalMode failed" );        free( p_sys );        return VLC_EGENERIC;    }    */        if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) && p_sys->b_supports_digital )    {        p_sys->b_digital = VLC_TRUE;        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');        msg_Dbg( p_aout, "we found a digital stream, and we WANT a digital stream" );    }    else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) && !p_sys->b_supports_digital )    {        msg_Dbg( p_aout, "we had requested a digital stream, but it's not possible for this device" );    }     /* If analog only start setting up AUHAL */    /* Lets go find our Component */    desc.componentType = kAudioUnitType_Output;    desc.componentSubType = kAudioUnitSubType_HALOutput;    desc.componentManufacturer = kAudioUnitManufacturer_Apple;    desc.componentFlags = 0;    desc.componentFlagsMask = 0;    p_sys->au_component = FindNextComponent( NULL, &desc );    if( p_sys->au_component == NULL )    {        msg_Err( p_aout, "we cannot find our HAL component" );        free( p_sys );        return VLC_EGENERIC;    }    err = OpenAComponent( p_sys->au_component, &p_sys->au_unit );    if( err )    {                msg_Err( p_aout, "we cannot find our HAL component" );        free( p_sys );        return VLC_EGENERIC;    }        /* Enable IO for the component */        /* Set the device */    verify_noerr( AudioUnitSetProperty( p_sys->au_unit,                         kAudioOutputUnitProperty_CurrentDevice,                         kAudioUnitScope_Global,                         0,                         &p_sys->i_selected_dev,                         sizeof(p_sys->i_selected_dev)));                             /* Get the current format */    AudioStreamBasicDescription DeviceFormat;        i_param_size = sizeof(AudioStreamBasicDescription);    verify_noerr( AudioUnitGetProperty( p_sys->au_unit,                                   kAudioUnitProperty_StreamFormat,                                   kAudioUnitScope_Input,                                   0,                                   &DeviceFormat,                                   &i_param_size ));                                       msg_Dbg( p_aout, STREAM_FORMAT_MSG( "current format is " , DeviceFormat ) );    /* Get the channel layout */    AudioChannelLayout *layout;    verify_noerr( AudioUnitGetPropertyInfo( p_sys->au_unit,                                   kAudioDevicePropertyPreferredChannelLayout,                                   kAudioUnitScope_Output,                                   0,                                   &i_param_size,                                   NULL ));    layout = (AudioChannelLayout *)malloc( i_param_size);    verify_noerr( AudioUnitGetProperty( p_sys->au_unit,                                   kAudioDevicePropertyPreferredChannelLayout,                                   kAudioUnitScope_Output,                                   0,                                   layout,                                   &i_param_size ));                                       /* Lets fill out the ChannelLayout */    if( layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)    {        msg_Dbg( p_aout, "bitmap defined channellayout" );        verify_noerr( AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForBitmap,                                sizeof( UInt32), &layout->mChannelBitmap,                                &i_param_size,                                layout ));    }    else if( layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions )    {        msg_Dbg( p_aout, "layouttags defined channellayout" );        verify_noerr( AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForTag,                                sizeof( AudioChannelLayoutTag ), &layout->mChannelLayoutTag,                                &i_param_size,                                layout ));    }    msg_Dbg( p_aout, "Layout of AUHAL has %d channels" , (int)layout->mNumberChannelDescriptions );        p_aout->output.output.i_physical_channels = 0;    for( i = 0; i < layout->mNumberChannelDescriptions; i++ )    {        msg_Dbg( p_aout, "This is channel: %d", (int)layout->mChannelDescriptions[i].mChannelLabel );        switch( layout->mChannelDescriptions[i].mChannelLabel )        {            case kAudioChannelLabel_Left:

⌨️ 快捷键说明

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