Android AudioFlinger回顧

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<IServiceManager> 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<IAudioPolicyService>& 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     sp<AudioPolicyEffects>audioPolicyEffects = 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<DeviceHalInterface> 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<AudioHwDevice::Flags>(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<AudioHwDevice::Flags>(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<AudioHwDevice::Flags>(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::ThreadBase> 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<MmapPlaybackThread> 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<PlaybackThread> 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<IAudioTrack> track = audioFlinger->createTrack(...){


} 
653  sp<IAudioTrack> 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<IMemory>& 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<PlaybackThread::Track> track;
670      sp<TrackHandle> trackHandle;
671      sp<Client> 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<PlaybackThread> 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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章