我是靠谱客的博主 平常小土豆,最近开发中收集的这篇文章主要介绍AndroidO audio系统之audioflinger启动分析(二),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. audioflinger创建过程

在Android8.0的音频系统中,AudioFlinger是一个C++的Binder服务,运行在HAL进程中,它是在audioserver.c

//frameworks/av/media/audioserver/audioserver.rc
service audioserver /system/bin/audioserver
    class main
    user audioserver
    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct oem_2901
    ioprio rt 4
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
    onrestart restart audio-hal-2-0

on property:vts.native_server.on=1
    stop audioserver
on property:vts.native_server.on=0
    start audioserver

audioserver的入口函数是main(),代码如下:

int main(int argc __unused, char **argv)
{
	......
	sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();   //创建AudioFlinger服务
        AudioPolicyService::instantiate(); //创建AudioPolicyService服务
        AAudioService::instantiate();  //创建AAudioService服务
        RadioService::instantiate();   //创建RadioService服务
        SoundTriggerHwService::instantiate();
#ifdef VRAUDIOSERVICE_ENABLE
        VRAudioServiceNative::instantiate();
#endif
        ProcessState::self()->startThreadPool();
// FIXME: remove when BUG 31748996 is fixed
        android::hardware::ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
}

AudioFlinger::instantiate()并不属于AudioFlinger的内部类,而是BinderService类的一个实现包括AudioFlinger,AudioPolicy等在内的几个服务都继承自这个统一的Binder的服务类,具体实现在BinderService.h中

// frameworks/native/include/binder/BinderService.h
    static status_t publish(bool allowIsolated = false) {
        sp<IServiceManager> sm(defaultServiceManager());
        //SERVICE是文件中定义的一个模板,AudioFlinger调用了instantiate()函数,
        //所以当前的SERVICE为AudioFlinger
        return sm->addService(
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);
    }

    static void instantiate() { publish(); }

可以看出publish()函数所做的事获取到ServiceManager的代理,然后new一个调用instantiate的那个service的对象并把它添加到ServiceManager中。
所以下一步就是去分析AudioFlinger的构造函数了

AudioFlinger::AudioFlinger()
    : BnAudioFlinger(),
      mMediaLogNotifier(new AudioFlinger::MediaLogNotifier()),
      mPrimaryHardwareDev(NULL),
      mAudioHwDevs(NULL),
      mHardwareStatus(AUDIO_HW_IDLE),
      mMasterVolume(1.0f),
      mMasterMute(false),
      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
      mIsDeviceTypeKnown(false),
      mGlobalEffectEnableTime(0),
      mSystemReady(false)
{
    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
    for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
        // zero ID has a special meaning, so unavailable
        mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
    }

    getpid_cached = getpid();
    const bool doLog = property_get_bool("ro.test_harness", false);
    if (doLog) {
        mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters",
                MemoryHeapBase::READ_ONLY);
        (void) pthread_once(&sMediaLogOnce, sMediaLogInit);
    }

    // reset battery stats.
    // if the audio service has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    //重置电池统计信息。 如果音频服务崩溃,电池状态可能会处于不良状态,在服务启动时重置状态
    BatteryNotifier::getInstance().noteResetAudio();

	//创建设备HAL层接口,用于hidl绑定
    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
   	//创建效果HAL层接口,用于hidl绑定
    mEffectsFactoryHal = EffectsFactoryHalInterface::create();

    mMediaLogNotifier->run("MediaLogNotifier");
}

1.1 DevicesFactoryHalInterface

sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
    return new DevicesFactoryHalHybrid();
}

DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
        : mLocalFactory(new DevicesFactoryHalLocal()),
          mHidlFactory(
#ifdef USE_LEGACY_LOCAL_AUDIO_HAL
                  nullptr
#else
                  new DevicesFactoryHalHidl()
#endif
                       ) {
}

DevicesFactoryHalHybrid::~DevicesFactoryHalHybrid() {
}

1.2 EffectsFactoryHalInterface

sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
    return new EffectsFactoryHalHidl();
}

EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
    mEffectsFactory = IEffectsFactory::getService();
    if (mEffectsFactory == 0) {
        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
        exit(1);
    }
}

接下来再看看它的onFirstRef()函数。

void AudioFlinger::onFirstRef()
{
    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;

    gAudioFlinger = this;
}

onFirstRef()函数也很简单,仅仅读取属性"ro.audio.flinger_standbytime_ms"的值并赋给变量mStandbyTimeInNsecs ,若这个属性没有设置,则使用默认值kDefaultStandbyTimeInNsecs。

2. audioflinger中的线程关系图

线程结构图
    PlaybackThread和RecordThread分别用于播放与录音。PlaybackThread中派生出DirectOutputThread与MixerThread。AudioFlinger中创建的播放线程大都是MixerThread,用于混合多路声音输出,而DirectOutputThread用于将声音直接发送给底层播放,不需要混音处理。
  DuplicatingThread用于将声音同时输出到蓝牙设备和其他设备,因为蓝牙设备和其他设备的连接是分开的,所以输出蓝牙音频数据需要一条单独的通道,而输出到DSP的数据也需要一条单独的通道。

3.小结

    本文旨在介绍一下audioflinger的启动过程及它包含线程之间的关系。具体audioflinger是如何工作的?后面会深入的一步步分析。下一篇将会先介绍audiopolicyservice以及它如何关联audioflinger等等,未完待续。。。

最后

以上就是平常小土豆为你收集整理的AndroidO audio系统之audioflinger启动分析(二)的全部内容,希望文章能够帮你解决AndroidO audio系统之audioflinger启动分析(二)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部