android audio flinger

    xiaoxiao2021-03-26  28

    我的书:

    购买链接:

    京东购买链接

    淘宝购买链接

    当当购买链接

     

    AudioFlinger创建

     

    ./frameworks/av/media/mediaserver/main_mediaserver.cpp:  47 int main(int argc __unused, char** argv)  48 { ...   135: AudioFlinger::instantiate();   139         AudioPolicyService::instantiate();   140         SoundTriggerHwService::instantiate();   147         ProcessState::self()->startThreadPool();   148         IPCThreadState::self()->joinThreadPool(); }

    该文件所在目录的Android.mk文件将其编译成一个可执行程序mediaserver,该程序在/system/bin/mediaserver。

     

     

    59 LOCAL_MODULE:= mediaserver 60 LOCAL_32_BIT_ONLY := true 61 62 include $(BUILD_EXECUTABLE)

    同时在init.rc文件有如下内容:

     

     

    724 service media /system/bin/mediaserver 725 class main 726 user media 727 group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm qcom_diag 728 ioprio rt 4

    也就是将mediaserver执行,即执行其中的main函数。

     

    AudioFlinger的静态初始化

     

    AudioFlinger::instantiate()并不是AudioFlinger的内部静态类,而是BinderService类的一个实现。

     

    class AudioFlinger : public BinderService<AudioFlinger>, public BnAudioFlinger

    /frameworks/native/include/binder/BinderService.h

     

     

    33template<typename SERVICE> 34class BinderService 35{ 36public: 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(); }//调用的是这里的instantiate 50 51 static status_t shutdown() { return NO_ERROR; } 52

    instantiate时,首先将AudioFlinger作为一个服务添加到ServiceManager中,此间会调用AudioFlinger的构造函数。

     

     

    AudioFlinger::AudioFlinger() : BnAudioFlinger(), mPrimaryHardwareDev(NULL), mAudioHwDevs(NULL), mHardwareStatus(AUDIO_HW_IDLE), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false), mIsLowRamDevice(true), mIsDeviceTypeKnown(false), mGlobalEffectEnableTime(0), mSystemReady(false) {}

    这个构造函数基本上就是对以上变量的初始化。其实际的工作放在了onFirstRef方法中完成了。 BnAudioFlinger类由虚基类RefBase层层继承而来,并且IserviceManager::addService的第二个参数是个强指针引用,所以在AudioFlinger被引用时,onFirstRef将被调用。

     

     

    void AudioFlinger::onFirstRef() { int rc = 0; Mutex::Autolock _l(mLock); /* TODO: move all this work into an Init() function */ char val_str[PROPERTY_VALUE_MAX] = { 0 }; if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) { uint32_t int_val; if (1 == sscanf(val_str, "%u", &int_val)) { mStandbyTimeInNsecs = milliseconds(int_val); ALOGI("Using %u mSec as standby time.", int_val); } else { mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs; ALOGI("Using default %u mSec as standby time.", (uint32_t)(mStandbyTimeInNsecs / 1000000)); } } mPatchPanel = new PatchPanel(this); mMode = AUDIO_MODE_NORMAL; }

    ro.audio.flinger_standbytime_ms属性给用户调节stand_by时间,接下来其它进程可以通过servicemanager来访问,并通过createtrack以及openOutput等接口来驱使Audioflinger为其服务。

     

    AudioFlinger和HAL的交互

     

    <AudioFlinger.cpp> static const char * const audio_interfaces[] = { AUDIO_HARDWARE_MODULE_ID_PRIMARY, AUDIO_HARDWARE_MODULE_ID_A2DP, AUDIO_HARDWARE_MODULE_ID_USB, }; #define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))

    在编译的时候,这三种设备分别被编译成audio.primary.xxx.so,audio.a2dp.xxx.so的形式,xxx表示具体的硬件平台,AP会调用AF的函数AudioFlinger::loadHwModule完成对应SO的加载。

    audio_module_handle_t AudioFlinger::loadHwModule(const char *name) { if (name == NULL) { return 0; } if (!settingsAllowed()) { return 0; } Mutex::Autolock _l(mLock); return loadHwModule_l(name);//调用loadHwModule_l完成功能 }

    loadHwModule_l的实现如下:

     

     

    audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name) { audio_hw_device_t *dev; //加载对应的so库文件,通过dlsym的形式打开so文件,加载路径/system/lib/hw或者/vendor/lib/hw

    //最终会调用audio_hw_hal.cpp里面的legacy_adev_open来挂载一些钩子函数, int rc = load_audio_interface(name, &dev); mHardwareStatus = AUDIO_HW_INIT; rc = dev->init_check(dev); mHardwareStatus = AUDIO_HW_IDLE; audio_module_handle_t handle = nextUniqueId();     mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags)); //将设备添加到AF的键值对里 }

     

     

     

     

     

    在打开so对应的音频库之后,最终调用HAL层的open函数。

     

     

    static inline int audio_hw_device_open(const struct hw_module_t* module, struct audio_hw_device** device) { return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, (struct hw_device_t**)device); }

    open函数里会将若干需要的钩子函数添加到audio_hw_device_t表示的结构体里。

     

    AudioFlinger在播放流程中的行为

    status_t AudioFlinger::openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, audio_devices_t *devices, const String8& address, uint32_t *latencyMs, audio_output_flags_t flags) { //判断要打开的设备参数是否合法 if (*devices == AUDIO_DEVICE_NONE) { return BAD_VALUE; } Mutex::Autolock _l(mLock); //创建playback线程 sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags); if (thread != 0) { *latencyMs = thread->latency(); // notify client processes of the new output creation thread->ioConfigChanged(AUDIO_OUTPUT_OPENED); // the first primary output opened designates the primary hw device if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) { ALOGI("Using module %d has the primary audio interface", module); mPrimaryHardwareDev = thread->getOutput()->audioHwDev; AutoMutex lock(mHardwareLock); mHardwareStatus = AUDIO_HW_SET_MODE; mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode); mHardwareStatus = AUDIO_HW_IDLE; } return NO_ERROR; } return NO_INIT; }

     

     

     

    sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, audio_devices_t devices, const String8& address, audio_output_flags_t flags) { //根据key-value找到相应的audio interface  AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); if (outHwDev == NULL) { return 0; } audio_hw_device_t *hwDevHal = outHwDev->hwDevice(); if (*output == AUDIO_IO_HANDLE_NONE) { *output = nextUniqueId(); } mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; // FOR TESTING ONLY: // This if statement allows overriding the audio policy settings // and forcing a specific format or channel mask to the HAL/Sink device for testing. if (!(flags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT))) { // Check only for Normal Mixing mode if (kEnableExtendedPrecision) { // Specify format (uncomment one below to choose) //config->format = AUDIO_FORMAT_PCM_FLOAT; //config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED; //config->format = AUDIO_FORMAT_PCM_32_BIT; //config->format = AUDIO_FORMAT_PCM_8_24_BIT; // ALOGV("openOutput_l() upgrading format to %#08x", config->format); } if (kEnableExtendedChannels) { // Specify channel mask (uncomment one below to choose) //config->channel_mask = audio_channel_out_mask_from_count(4); // for USB 4ch //config->channel_mask = audio_channel_mask_from_representation_and_bits( // AUDIO_CHANNEL_REPRESENTATION_INDEX, (1 << 4) - 1); // another 4ch example } } AudioStreamOut *outputStream = NULL; status_t status = outHwDev->openOutputStream( &outputStream, *output, devices, flags, config, address.string()); mHardwareStatus = AUDIO_HW_IDLE; if (status == NO_ERROR) { PlaybackThread *thread; if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady); ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread); } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || !isValidPcmSinkFormat(config->format) || !isValidPcmSinkChannelMask(config->channel_mask)) { thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady); ALOGV("openOutput_l() created direct output: ID %d thread %p ", *output, thread); //Check if this is DirectPCM, if so if (flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) { thread->mIsDirectPcm = true; } } else { thread = new MixerThread(this, outputStream, *output, devices, mSystemReady); ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread); } mPlaybackThreads.add(*output, thread); return thread; } return 0; }

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-662520.html

    最新回复(0)