Android AudioFlinger回顾

  • AudioFlinger
    • AudioFlinger的启动
    • AudioFlinger的创建
    • AF之loadHwModule 和 openOutput
      • AudioPolicyService的启动
      • AudioPolicyManager的创建
      • loadHwModule
      • openOutput
    • Track的创建
    • AudioFlinger dump

AudioFlinger

AudioTrack称为音轨,负责音频数据的传送,把数据交给AudioFlinger,AudioFlinger可以称之为混音器,同时可以进行音效的处理,然后把处理后的数据交给Audio Hal层,最终有相应的硬件播放。启到承上启下的作用

AudioFlinger的启动

作为音频系统两个最重要的服务AudioFlinger和AudioPolicyService,运行在audioserver中

Android 7.0 开始,AudioFlinger 在系统启动时由 audioserver 加载(之前版本由 mediaserver 加载)
android/frameworks/av/media/audioserver/main_audioserver.cpp

int main(int argc __unused, char **argv)
{
    ...
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        AudioPolicyService::instantiate(); //初始化 AudioPolicyService
        // AAudioService disabled because we do not support MMAP mode in OC or OC-DR1.
        // AAudioService::instantiate();
        RadioService::instantiate();
        SoundTriggerHwService::instantiate();
        ......
        //启动服务端的线程池
        ProcessState::self()->startThreadPool();

        // FIXME: remove when BUG 31748996 is fixed
        android::hardware::ProcessState::self()->startThreadPool();

        IPCThreadState::self()->joinThreadPool();
}

instantiate()并不是AudioFlinger中的静态方法,而是由他的父类BinderService继承的,BinderService是一个模板类,在方法instantiate()中主要是创建Audiolinger的实例,并将其加入到ServiceManager中。

// ---------------------------------------------------------------------------
31 namespace android {
32 
33 template<typename SERVICE>
34 class BinderService
35 {
36 public:
37     static status_t publish(bool allowIsolated = false) {
38         sp sm(defaultServiceManager());
39         return sm->addService(
40                 String16(SERVICE::getServiceName()),
41                 new SERVICE(), allowIsolated);
42     }
43 
44     static void publishAndJoinThreadPool(bool allowIsolated = false) {
45         publish(allowIsolated);
46         joinThreadPool();
47     }
48 
49     static void instantiate() { publish(); }
......

main_audioserver.cpp 编译生成的可执行文件存放在 /system/bin/audioserver,系统启动时由 init 进程运行
AudioFlinger 服务启动后,其他进程可以通过 ServiceManager 来获取其代理对象 IAudioFlinger,通过 IAudioFlinger 可以向 AudioFlinger 发出各种服务请求,从而完成自己的音频业务。

AudioFlinger的创建

构造函数:


146 AudioFlinger::AudioFlinger()
147     : BnAudioFlinger(),
148       mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
149       mPrimaryHardwareDev(NULL),
150       mAudioHwDevs(NULL),
151       mHardwareStatus(AUDIO_HW_IDLE),
152       mMasterVolume(1.0f),
153       mMasterMute(false),
154       // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
155       mMode(AUDIO_MODE_INVALID),
156       mBtNrecIsOff(false),
157       mIsLowRamDevice(true),
158       mIsDeviceTypeKnown(false),
159       mGlobalEffectEnableTime(0),
160       mSystemReady(false)
161 {
162     // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
163     for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
164         // zero ID has a special meaning, so unavailable
165         mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
166     }
167 
168     getpid_cached = getpid();
169     const bool doLog = property_get_bool("ro.test_harness", false);
170     if (doLog) {
171         mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
172                 MemoryHeapBase::READ_ONLY);
173         (void) pthread_once(&sMediaLogOnce, sMediaLogInit);
174     }
175 
176     // reset battery stats.
177     // if the audio service has crashed, battery stats could be left
178     // in bad state, reset the state upon service start.
179     BatteryNotifier::getInstance().noteResetAudio();
180 
        //创建代表Audio硬件的HAL接口对象
181     mDevicesFactoryHal = DevicesFactoryHalInterface::create();
182     mEffectsFactoryHal = EffectsFactoryHalInterface::create();
183 
184     mMediaLogNotifier->run("MediaLogNotifier");
        ......

这里并没有做过多的事情,不多说

  • AudioFlinger onFirstRef()*
    AudioFlinger继承的BnAudioFlinger是由RefBase层层继承而来的,并且IServiceManager::addService的第二个参数实际上是一个强指针引用(const sp&),
    因而AudioFlinger具备了强指针被第一次引用时调用onFirstRef的程序逻辑

208 void AudioFlinger::onFirstRef()
209 {
210     Mutex::Autolock _l(mLock);
211 
212     /* TODO: move all this work into an Init() function */
213     char val_str[PROPERTY_VALUE_MAX] = { 0 };
214     if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
215         uint32_t int_val;
216         if (1 == sscanf(val_str, "%u", &int_val)) {
217             mStandbyTimeInNsecs = milliseconds(int_val);
218             ALOGI("Using %u mSec as standby time.", int_val);
219         } else {
220             mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
221             ALOGI("Using default %u mSec as standby time.",
222                     (uint32_t)(mStandbyTimeInNsecs / 1000000));
223         }
224     }
225 
226     mPatchPanel = new PatchPanel(this);
227 
228     mMode = AUDIO_MODE_NORMAL;
229 
230     gAudioFlinger = this;
231 }

AF内部,由于和他交互的模块较多,并且维护了多个线程,这些线程实现在\frameworks\av\services\audioflinger\Threads.cpp ,主要的实现在PlaybackThread
这些Thread是什么时候创建的?带着疑问先看AudioFlinger createTrack()

AudioFlinger createTrack()之前在AudioTrack的createTrack_l()中会getOutputForAttr,所以openoutput的操作就更早了,要看Thread
是什么时候创建的,就要先看openoutput在哪里

getOutputForAttr会获取get_audio_policy_service()得到代理对象IAudioPolicyService,进而在通过Binder机制向AudioPolicyService发起请求getOutputForAttr

 status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
                                         audio_io_handle_t *output,
                                         audio_session_t session,
                                         audio_stream_type_t *stream,
                                         uid_t uid,
                                         const audio_config_t *config,
                                         audio_output_flags_t flags,
                                         audio_port_handle_t selectedDeviceId,
                                         audio_port_handle_t *portId)
 {
     const sp& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getOutputForAttr(attr, output, session, stream, uid,
                                  config,
                                  flags, selectedDeviceId, portId);
 }

那么问题是什么时候openoutput的呢?

AF之loadHwModule 和 openOutput

AudioPolicyService的启动

我们知道AudioPolicyService也是在audioserver中启动的,按照之前对AudioFlinger的分析,AudioPolicyService也会执行onFirstRef()
然后在这里创建AudioPolicyManager

void AudioPolicyService::onFirstRef()
62 {
63     {
64         Mutex::Autolock _l(mLock);
65 
66         // start tone playback thread
67         mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
68         // start audio commands thread
69         mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
70         // start output activity command thread
71         mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
72 
73         mAudioPolicyClient = new AudioPolicyClient(this);
74         mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
75     }
76     // load audio processing modules
77     spaudioPolicyEffects = new AudioPolicyEffects();
78     {
79         Mutex::Autolock _l(mLock);
80         mAudioPolicyEffects = audioPolicyEffects;
81     }
82 }

AudioPolicyManager的创建

android/frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp

21 extern "C" AudioPolicyInterface* createAudioPolicyManager(
22         AudioPolicyClientInterface *clientInterface)
23 {
24     return new AudioPolicyManager(clientInterface);
25 }

new AudioPolicyManager(clientInterface)
在构造函数AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)中做了很多事,获取了 AudioPolicyConfig的配置文件、loadHwModule、执行openOutput()、 setOutputDevice、setDeviceConnectionState等等

3460 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
3461     :
3462 #ifdef AUDIO_POLICY_TEST
3463     Thread(false),
3464 #endif //AUDIO_POLICY_TEST
3465     mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
3466     mA2dpSuspended(false),
3467     mAudioPortGeneration(1),
3468     mBeaconMuteRefCount(0),
3469     mBeaconPlayingRefCount(0),
3470     mBeaconMuted(false),
3471     mTtsOutputAvailable(false),
3472     mMasterMono(false),
3473     mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
3474 {
3475     mUidCached = getuid();
3476     mpClientInterface = clientInterface;
3477 
3478     // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
3479     // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
3480     // Note: remove also speaker_drc_enabled from global configuration of XML config file.
3481     bool speakerDrcEnabled = false;
3482 
3483 #ifdef USE_XML_AUDIO_POLICY_CONF
3484     mVolumeCurves = new VolumeCurvesCollection();
3485     AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3486                              mDefaultOutputDevice, speakerDrcEnabled,
3487                              static_cast<VolumeCurvesCollection *>(mVolumeCurves));
3488     if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
3489 #else
3490     mVolumeCurves = new StreamDescriptorCollection();
3491     AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3492                              mDefaultOutputDevice, speakerDrcEnabled);
3493     if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
3494             (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
3495 #endif
3496         ALOGE("could not load audio policy configuration file, setting defaults");
3497         config.setDefault();
3498     }
3499     // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
3500     mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
3501 
3502     // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
3503     audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
3504     if (!engineInstance) {
3505         ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
3506         return;
3507     }
3508     // Retrieve the Policy Manager Interface
3509     mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
3510     if (mEngine == NULL) {
3511         ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
3512         return;
3513     }
3514     mEngine->setObserver(this);
3515     status_t status = mEngine->initCheck();
3516     (void) status;
3517     ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
3518 
3519     // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
3520     // open all output streams needed to access attached devices
3521     audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
3522     audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
3523     for (size_t i = 0; i < mHwModules.size(); i++) {
3524         mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
3525         if (mHwModules[i]->mHandle == 0) {
3526             ALOGW("could not open HW module %s", mHwModules[i]->getName());
3527             continue;
3528         }
3529         // open all output streams needed to access attached devices
3530         // except for direct output streams that are only opened when they are actually
3531         // required by an app.
3532         // This also validates mAvailableOutputDevices list
3533         for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3534         {
3535             const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
3536 
3537             if (!outProfile->hasSupportedDevices()) {
3538                 ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
3539                 continue;
3540             }
3541             if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
3542                 mTtsOutputAvailable = true;
3543             }
3544 
3545             if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
3546                 continue;
3547             }
3548             audio_devices_t profileType = outProfile->getSupportedDevicesType();
3549             if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
3550                 profileType = mDefaultOutputDevice->type();
3551             } else {
3552                 // chose first device present in profile's SupportedDevices also part of
3553                 // outputDeviceTypes
3554                 profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
3555             }
3556             if ((profileType & outputDeviceTypes) == 0) {
3557                 continue;
3558             }
3559             sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
3560                                                                                  mpClientInterface);
3561             const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
3562             const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
3563             String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
3564                     : String8("");
3565 
3566             outputDesc->mDevice = profileType;
3567             audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3568             config.sample_rate = outputDesc->mSamplingRate;
3569             config.channel_mask = outputDesc->mChannelMask;
3570             config.format = outputDesc->mFormat;
3571             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3572             status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
3573                                                             &output,
3574                                                             &config,
3575                                                             &outputDesc->mDevice,
3576                                                             address,
3577                                                             &outputDesc->mLatency,
3578                                                             outputDesc->mFlags);
3579 
3580             if (status != NO_ERROR) {
3581                 ALOGW("Cannot open output stream for device %08x on hw module %s",
3582                       outputDesc->mDevice,
3583                       mHwModules[i]->getName());
3584             } else {
3585                 outputDesc->mSamplingRate = config.sample_rate;
3586                 outputDesc->mChannelMask = config.channel_mask;
3587                 outputDesc->mFormat = config.format;
3588 
3589                 for (size_t k = 0; k  < supportedDevices.size(); k++) {
3590                     ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
3591                     // give a valid ID to an attached device once confirmed it is reachable
3592                     if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
3593                         mAvailableOutputDevices[index]->attach(mHwModules[i]);
3594                     }
3595                 }
3596                 if (mPrimaryOutput == 0 &&
3597                         outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
3598                     mPrimaryOutput = outputDesc;
3599                 }
3600                 addOutput(output, outputDesc);
3601                 setOutputDevice(outputDesc,
3602                                 outputDesc->mDevice,
3603                                 true,
3604                                 0,
3605                                 NULL,
3606                                 address.string());
3607             }
3608         }
3609         // open input streams needed to access attached devices to validate
3610         // mAvailableInputDevices list
3611         for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
3612         {
3613             const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
3614 
3615             if (!inProfile->hasSupportedDevices()) {
3616                 ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
3617                 continue;
3618             }
3619             // chose first device present in profile's SupportedDevices also part of
3620             // inputDeviceTypes
3621             audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
3622 
3623             if ((profileType & inputDeviceTypes) == 0) {
3624                 continue;
3625             }
3626             sp<AudioInputDescriptor> inputDesc =
3627                     new AudioInputDescriptor(inProfile);
3628 
3629             inputDesc->mDevice = profileType;
3630 
3631             // find the address
3632             DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
3633             //   the inputs vector must be of size 1, but we don't want to crash here
3634             String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
3635                     : String8("");
3636             ALOGV("  for input device 0x%x using address %s", profileType, address.string());
3637             ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
3638 
3639             audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3640             config.sample_rate = inputDesc->mSamplingRate;
3641             config.channel_mask = inputDesc->mChannelMask;
3642             config.format = inputDesc->mFormat;
3643             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3644             status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
3645                                                            &input,
3646                                                            &config,
3647                                                            &inputDesc->mDevice,
3648                                                            address,
3649                                                            AUDIO_SOURCE_MIC,
3650                                                            AUDIO_INPUT_FLAG_NONE);
3651 
3652             if (status == NO_ERROR) {
3653                 const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
3654                 for (size_t k = 0; k  < supportedDevices.size(); k++) {
3655                     ssize_t index =  mAvailableInputDevices.indexOf(supportedDevices[k]);
3656                     // give a valid ID to an attached device once confirmed it is reachable
3657                     if (index >= 0) {
3658                         sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
3659                         if (!devDesc->isAttached()) {
3660                             devDesc->attach(mHwModules[i]);
3661                             devDesc->importAudioPort(inProfile, true);
3662                         }
3663                     }
3664                 }
3665                 mpClientInterface->closeInput(input);
3666             } else {
3667                 ALOGW("Cannot open input stream for device %08x on hw module %s",
3668                       inputDesc->mDevice,
3669                       mHwModules[i]->getName());
3670             }
3671         }
3672     }
3673     // make sure all attached devices have been allocated a unique ID
3674     for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
3675         if (!mAvailableOutputDevices[i]->isAttached()) {
3676             ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
3677             mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
3678             continue;
3679         }
3680         // The device is now validated and can be appended to the available devices of the engine
3681         mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
3682                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
3683         i++;
3684     }
3685     for (size_t i = 0; i  < mAvailableInputDevices.size();) {
3686         if (!mAvailableInputDevices[i]->isAttached()) {
3687             ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
3688             mAvailableInputDevices.remove(mAvailableInputDevices[i]);
3689             continue;
3690         }
3691         // The device is now validated and can be appended to the available devices of the engine
3692         mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
3693                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
3694         i++;
3695     }
3696     // make sure default device is reachable
3697     if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
3698         ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
3699     }
3700 
3701     ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
3702 
3703     updateDevicesAndOutputs();
......

而实际loadHwModule()和openOutput()的操作是由AudioFlinger完成的,这也是为什么在audioserver中AudioFlinger的初始化要在AudioPolicyService之前

/* implementation of the client interface from the policy manager */
27
28 audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
29 {
30 sp af = AudioSystem::get_audio_flinger();
31 if (af == 0) {
32 ALOGW(“%s: could not get AudioFlinger”, func);
33 return AUDIO_MODULE_HANDLE_NONE;
34 }
35
36 return af->loadHwModule(name);
37 }
38
39 status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
40 audio_io_handle_t *output,
41 audio_config_t *config,
42 audio_devices_t *devices,
43 const String8& address,
44 uint32_t *latencyMs,
45 audio_output_flags_t flags)
46 {
47 sp af = AudioSystem::get_audio_flinger();
48 if (af == 0) {
49 ALOGW(“%s: could not get AudioFlinger”, func);
50 return PERMISSION_DENIED;
51 }
52 return af->openOutput(module, output, config, devices, address, latencyMs, flags);
53 }

再来看一下loadHwModule和openOutput都干了什么
先将loadHwModule

loadHwModule

1776  // loadHwModule_l() must be called with AudioFlinger::mLock held
1777  audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
1778  {
1779      for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
1780          if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
1781              ALOGW("loadHwModule() module %s already loaded", name);
1782              return mAudioHwDevs.keyAt(i);
1783          }
1784      }
1785  
1786      sp dev;
1787  
1788      int rc = mDevicesFactoryHal->openDevice(name, &dev);
1789      if (rc) {
1790          ALOGE("loadHwModule() error %d loading module %s", rc, name);
1791          return AUDIO_MODULE_HANDLE_NONE;
1792      }
1793  
1794      mHardwareStatus = AUDIO_HW_INIT;
1795      rc = dev->initCheck();
1796      mHardwareStatus = AUDIO_HW_IDLE;
1797      if (rc) {
1798          ALOGE("loadHwModule() init check error %d for module %s", rc, name);
1799          return AUDIO_MODULE_HANDLE_NONE;
1800      }
1801  
1802      // Check and cache this HAL's level of support for master mute and master
1803      // volume.  If this is the first HAL opened, and it supports the get
1804      // methods, use the initial values provided by the HAL as the current
1805      // master mute and volume settings.
1806  
1807      AudioHwDevice::Flags flags = static_cast(0);
1808      {  // scope for auto-lock pattern
1809          AutoMutex lock(mHardwareLock);
1810  
1811          if (0 == mAudioHwDevs.size()) {
1812              mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
1813              float mv;
1814              if (OK == dev->getMasterVolume(&mv)) {
1815                  mMasterVolume = mv;
1816              }
1817  
1818              mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
1819              bool mm;
1820              if (OK == dev->getMasterMute(&mm)) {
1821                  mMasterMute = mm;
1822              }
1823          }
1824  
1825          mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
1826          if (OK == dev->setMasterVolume(mMasterVolume)) {
1827              flags = static_cast(flags |
1828                      AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
1829          }
1830  
1831          mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
1832          if (OK == dev->setMasterMute(mMasterMute)) {
1833              flags = static_cast(flags |
1834                      AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
1835          }
1836  
1837          mHardwareStatus = AUDIO_HW_IDLE;
1838      }
1839  
1840      audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
1841      mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
1842  
1843      ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
1844  
1845      return handle;
1846  
1847  }

openOutput



1973  sp AudioFlinger::openOutput_l(audio_module_handle_t module,
1974                                                              audio_io_handle_t *output,
1975                                                              audio_config_t *config,
1976                                                              audio_devices_t devices,
1977                                                              const String8& address,
1978                                                              audio_output_flags_t flags)
1979  {
1980      AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
1981      if (outHwDev == NULL) {
1982          return 0;
1983      }
1984  
1985      if (*output == AUDIO_IO_HANDLE_NONE) {
1986          *output = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
1987      } else {
1988          // Audio Policy does not currently request a specific output handle.
1989          // If this is ever needed, see openInput_l() for example code.
1990          ALOGE("openOutput_l requested output handle %d is not AUDIO_IO_HANDLE_NONE", *output);
1991          return 0;
1992      }
1993  
1994      mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
1995  
1996      // FOR TESTING ONLY:
1997      // This if statement allows overriding the audio policy settings
1998      // and forcing a specific format or channel mask to the HAL/Sink device for testing.
1999      if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) {
2000          // Check only for Normal Mixing mode
2001          if (kEnableExtendedPrecision) {
2002              // Specify format (uncomment one below to choose)
2003              //config->format = AUDIO_FORMAT_PCM_FLOAT;
2004              //config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
2005              //config->format = AUDIO_FORMAT_PCM_32_BIT;
2006              //config->format = AUDIO_FORMAT_PCM_8_24_BIT;
2007              // ALOGV("openOutput_l() upgrading format to %#08x", config->format);
2008          }
2009          if (kEnableExtendedChannels) {
2010              // Specify channel mask (uncomment one below to choose)
2011              //config->channel_mask = audio_channel_out_mask_from_count(4);  // for USB 4ch
2012              //config->channel_mask = audio_channel_mask_from_representation_and_bits(
2013              //        AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1);  // another 4ch example
2014          }
2015      }
2016  
2017      AudioStreamOut *outputStream = NULL;
2018      status_t status = outHwDev->openOutputStream(
2019              &outputStream,
2020              *output,
2021              devices,
2022              flags,
2023              config,
2024              address.string());
2025  
2026      mHardwareStatus = AUDIO_HW_IDLE;
2027  
2028      if (status == NO_ERROR) {
2029          if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
2030              sp thread =
2031                      new MmapPlaybackThread(this, *output, outHwDev, outputStream,
2032                                            devices, AUDIO_DEVICE_NONE, mSystemReady);
2033              mMmapThreads.add(*output, thread);
2034              ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p",
2035                    *output, thread.get());
2036              return thread;
2037          } else {
2038              sp thread;
2039              if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
2040                  thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
2041                  ALOGV("openOutput_l() created offload output: ID %d thread %p",
2042                        *output, thread.get());
2043              } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
2044                      || !isValidPcmSinkFormat(config->format)
2045                      || !isValidPcmSinkChannelMask(config->channel_mask)) {
2046                  thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
2047                  ALOGV("openOutput_l() created direct output: ID %d thread %p",
2048                        *output, thread.get());
2049              } else {
2050                  thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
2051                  ALOGV("openOutput_l() created mixer output: ID %d thread %p",
2052                        *output, thread.get());
2053              }
2054              mPlaybackThreads.add(*output, thread);
2055              return thread;
2056          }
2057      }
2058  
2059      return 0;
2060  }
2061  

看来AudioPolicyService在启动时回去创建AudioPolicyManager对象,并且在在AudioPolicyManager的构造函数中去做一些必要的初始化操作和准备操作包括加载配置文件audio_policy.conf、loadHwModule和openOutput等,并且loadHwModule和openOutput的完成实际是audioFlinger,而且然后由audioFliinger的openoutput中创建相应的Thread,接下来才会createTrack

Track的创建

作为客户端的AudioTrack会通过代理对象通过 IAudioFlinger,向服务端AudioFlinger发起createTrack()的请求,并且返回了IAudioTrack对象,建立了AudioTrack与AudioFlinger之间的关系,createTrack就是在AudioFlinger中创建一个Track对象,在创建Tack对象时会分配一块共享内存,stream模式下的匿名共享内存头部会创建一个audio_track_cblk_t对象,用于协调生产者AudioTrack和消费者AudioFlinger之间的步调

sp track = audioFlinger->createTrack(...){


} 
653  sp AudioFlinger::createTrack(
654          audio_stream_type_t streamType,
655          uint32_t sampleRate,
656          audio_format_t format,
657          audio_channel_mask_t channelMask,
658          size_t *frameCount,
659          audio_output_flags_t *flags,
660          const sp& sharedBuffer,
661          audio_io_handle_t output,
662          pid_t pid,
663          pid_t tid,
664          audio_session_t *sessionId,
665          int clientUid,
666          status_t *status,
667          audio_port_handle_t portId)
668  {
669      sp track;
670      sp trackHandle;
671      sp client;
672      status_t lStatus;
673      audio_session_t lSessionId;
674  
675      const uid_t callingUid = IPCThreadState::self()->getCallingUid();
676      if (pid == -1 || !isTrustedCallingUid(callingUid)) {
677          const pid_t callingPid = IPCThreadState::self()->getCallingPid();
678          ALOGW_IF(pid != -1 && pid != callingPid,
679                   "%s uid %d pid %d tried to pass itself off as pid %d",
680                   __func__, callingUid, callingPid, pid);
681          pid = callingPid;
682      }
683  
684      // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
685      // but if someone uses binder directly they could bypass that and cause us to crash
686      if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
687          ALOGE("createTrack() invalid stream type %d", streamType);
688          lStatus = BAD_VALUE;
689          goto Exit;
690      }
......

719      {
720          Mutex::Autolock _l(mLock);
721          PlaybackThread *thread = checkPlaybackThread_l(output);
722          if (thread == NULL) {
723              ALOGE("no playback thread found for output handle %d", output);
724              lStatus = BAD_VALUE;
725              goto Exit;
726          }
727  
728          client = registerPid(pid);
729  
730          PlaybackThread *effectThread = NULL;
731          if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
732              if (audio_unique_id_get_use(*sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
733                  ALOGE("createTrack() invalid session ID %d", *sessionId);
734                  lStatus = BAD_VALUE;
735                  goto Exit;
736              }
737              lSessionId = *sessionId;
738              // check if an effect chain with the same session ID is present on another
739              // output thread and move it here.
740              for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
741                  sp t = mPlaybackThreads.valueAt(i);
742                  if (mPlaybackThreads.keyAt(i) != output) {
743                      uint32_t sessions = t->hasAudioSession(lSessionId);
744                      if (sessions & ThreadBase::EFFECT_SESSION) {
745                          effectThread = t.get();
746                          break;
747                      }
748                  }
749              }
750          } else {
751              // if no audio session id is provided, create one here
752              lSessionId = (audio_session_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
753              if (sessionId != NULL) {
754                  *sessionId = lSessionId;
755              }
756          }
757          ALOGV("createTrack() lSessionId: %d", lSessionId);
758  
759          track = thread->createTrack_l(client, streamType, sampleRate, format,
760                  channelMask, frameCount, sharedBuffer, lSessionId, flags, tid,
761                  clientUid, &lStatus, portId);
...

{待续 补充}

AudioFlinger dump

通过下面的adb命令可以dump AudioFlinger的相关信息

adb shell dumpsys media.audio_flinger

dump information:

Libraries NOT loaded:
Libraries loaded:
 Library audio_pre_processing
  path: /vendor/lib/soundfx/libqcomvoiceprocessing.so
  Noise Suppression / Qualcomm Fluence
    UUID: 1d97bb0b-9e2f-4403-9ae3-58c2554306f8
    TYPE: 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
    apiVersion: 00020000
    flags: 00420203
  Acoustic Echo Canceler / Qualcomm Fluence
    UUID: 0f8d0d2a-59e5-45fe-b6e4-248c8a799109
    TYPE: 7b491460-8d4d-11e0-bd61-0002a5d5c51b
    apiVersion: 00020000
    flags: 00420203
 Library offload_bundle
  path: /vendor/lib/soundfx/libqcompostprocbundle.so
  (no effects)
  ......
 Library downmix
  path: /vendor/lib/soundfx/libdownmix.so
  Multichannel Downmix To Stereo / The Android Open Source Project
    UUID: 93f04452-e4fe-41cc-91f9-e475b6d1d69f
    TYPE: 381e49cc-a858-4aa2-87f6-e8388e7601b2
    apiVersion: 00020000
    flags: 00000008
  ......
 Library bundle
  path: /vendor/lib/soundfx/libbundlewrapper.so
  Volume / NXP Software Ltd.
    UUID: 119341a0-8469-11df-81f9-0002a5d5c51b
    TYPE: 09e8ede0-ddde-11db-b4f6-0002a5d5c51b
    apiVersion: 00020000
    flags: 00000050
Clients:
  pid: 2150
  pid: 4561
Notification Clients:
  pid: 813
......
Global session refs:
  session   pid count
       41  2150     1
       65  4561     2
       65   824     1
       89  6681     1
Hardware status: 0
Standby Time mSec: 3000

Output thread 0xef003140, name AudioOut_D, tid 1194, type 0 (MIXER):
  I/O handle: 13
  Standby: yes
  Sample rate: 48000 Hz
  HAL frame count: 192
  HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
  HAL buffer size: 768 bytes
  Channel count: 2
  Channel mask: 0x00000003 (front-left, front-right)
  Processing format: 0x5 (AUDIO_FORMAT_PCM_FLOAT)
  Processing frame size: 8 bytes
  Pending config events: none
  Output device: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
  Input device: 0 (AUDIO_DEVICE_NONE)
  Audio source: 0 (default)
  Normal frame count: 960
  Last write occurred (msecs): 57113
  Total writes: 156
  Delayed writes: 0
  Blocked in write: no
  Suspend count: 0
  Sink buffer : 0xf07f8000
  Mixer buffer: 0xf07f6000
  Effect buffer: 0xf07e4000
  Fast track availMask=0xfc
  Standby delay ns=3000000000
  AudioStreamOut: 0xf078ea60 flags 0x6 (AUDIO_OUTPUT_FLAG_PRIMARY|AUDIO_OUTPUT_FLAG_FAST)
  Frames written: 149760
  Suspended frames: 0
  PipeSink frames written: 149760
  Hal stream dump:
  Thread throttle time (msecs): 0
  AudioMixer tracks: 0x00000001
  Master mono: off
  FastMixer thread 0xeed83e40 tid=1193  FastMixer command=COLD_IDLE writeSequence=1554 framesWritten=149184
            numTracks=1 writeErrors=0 underruns=0 overruns=0
            sampleRate=48000 frameCount=192 measuredWarmup=69.6 ms, warmupCycles=5
            mixPeriod=4.00 ms
  Simple moving statistics over last 3.1 seconds:
    wall clock time in ms per mix cycle:
      mean=4.00 min=3.51 max=4.52 stddev=0.08
    raw CPU load in us per mix cycle:
      mean=95 min=0 max=339 stddev=25
  Fast tracks: sMaxFastTracks=8 activeMask=0x1
  Index Active Full Partial Empty  Recent Ready    Written
      0    yes  772       0     0    full  1728     148032
      1     no   11       0    16   empty     0       2112
      2     no    0       0     0    full     0          0
      3     no    0       0     0    full     0          0
      4     no    0       0     0    full     0          0
      5     no    0       0     0    full     0          0
      6     no    0       0     0    full     0          0
      7     no    0       0     0    full     0          0
  Stream volumes in dB: 0:-24, 1:-inf, 2:-inf, 3:-inf, 4:-inf, 5:-inf, 6:0, 7:-inf, 8:-inf, 9:0, 10:-inf, 11:0, 12:0
  Normal mixer raw underrun counters: partial=0 empty=0
  1 Tracks of which 0 are active
    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  L dB  R dB  VS dB    Server Main buf  Aux buf Flags UndFrmCnt  Flushed
    F  1     no   2150    5 00000001 00000001      41    960 S 1 48000     0     0     0   00000840 F07F8000 00000000 0x600         0        0
  0 Effect Chains

Output thread 0xeedf6000, name AudioOut_2D, tid 6146, type 4 (OFFLOAD):
  I/O handle: 45
  Standby: no
  Sample rate: 44100 Hz
  HAL frame count: 262144
  HAL format: 0x1000000 (AUDIO_FORMAT_MP3)
  HAL buffer size: 262144 bytes
  Channel count: 2
  Channel mask: 0x00000003 (front-left, front-right)
  Processing format: 0x1000000 (AUDIO_FORMAT_MP3)
  Processing frame size: 1 bytes
  Pending config events: none
  Output device: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
  Input device: 0 (AUDIO_DEVICE_NONE)
  Audio source: 0 (default)
  Normal frame count: 262144
  Last write occurred (msecs): 12052
  Total writes: 8
  Delayed writes: 0
  Blocked in write: no
  Suspend count: 0
  Sink buffer : 0xee383000
  Mixer buffer: 0xed700000
  Effect buffer: 0xed600000
  Fast track availMask=0xfe
  Standby delay ns=1000000000
  AudioStreamOut: 0xf07ca940 flags 0x31 (AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING)
  Frames written: 1048660
  Suspended frames: 0
  Hal stream dump:
  Stream volumes in dB: 0:-5.9, 1:-inf, 2:-inf, 3:-22, 4:0, 5:-inf, 6:0, 7:-inf, 8:-inf, 9:0, 10:-22, 11:0, 12:0
  Normal mixer raw underrun counters: partial=0 empty=0
  1 Tracks of which 1 are active
    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  L dB  R dB  VS dB    Server Main buf  Aux buf Flags UndFrmCnt  Flushed
    none    yes   4561    3 01000000 00000003      65 262144 A 3 44100     0     0     0   00140054 EE383000 00000000 0x000    524204        0
  0 Effect Chains

关于上面的信息有一点说明:如下 Name 为 F, 代表是fast track, 但是active 为 no,因为fasttrack最多处理8条track,但是其中有一个track是为和normal track通讯被占用,因此有效的track只有7个

  1 Tracks of which 0 are active
    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  L dB  R dB  VS dB    Server Main buf  Aux buf Flags UndFrmCnt  Flushed
    F  1     no   2150    5 00000001 00000001      41    960 S 1 48000     0     0     0   00000840 F07F8000 00000000 0x600         0        0

而第二条Output thread 0xeedf6000 ,播放的是mp3:AUDIO_FORMAT_MP3,OFFLOAD的模式播放也就是说采用硬件解码,在ADSP侧可以对解码的数据进行音效处理

上下对应关系,看dump的开始信息:

Clients:
  pid: 2150
  pid: 4561

那么在打印出来的Output thread信息中,我们只需要看pid 为2150的fast track(在 Output thread 0xef003140输出的dump 信息中)和pid 为4561的nomal track(Output thread 0xeedf6000)

你可能感兴趣的:(Audio,AudioFlinger,Android)