zoukankan      html  css  js  c++  java
  • 服务、启动Android音频系统之AudioFlinger(一)by小雨

    首先声明,我是一个菜鸟。一下文章中出现技术误导情况盖不负责

        

    1.1 AudioFlinger

        在上面的框架图中,我们可以看到AudioFlinger(上面简称AF)是全部音频系统的核心与难点。作为Android系统中的音频中枢,它同时也是一个系统服务,启到承上(为下层供提拜访接口)启下(通过HAL来理管音频备设)的作用。只有理解了AudioFlinger,才能以此为基础更好地入深到其它模块,因而我们把它放在前面行进析分。

        

    1.1.1 AudioFlinger服务的启动和行运

        我们道知,Android中的系统服务分为两类,分别是Java层和Native层的System Services。其中AudioFlinger和SurfaceFlinger一样,都属于后者。Java层服务通常在SystemServer.java中启动,比如前面会看到的AudioService就是这类情况。而Native层服务则通常是各服务方按照自己的特定部署来定决何时启动、如何启动。例如AudioFlinger就是利用一个Linux序程来接间创立的,如下所示:

        

    /*frameworks/av/media/mediaserver/Main_mediaserver.cpp*/

    int main(int argc, char** argv)

    {

        sp<ProcessState>proc(ProcessState::self());

        sp<IServiceManager>sm = defaultServiceManager();

       ALOGI("ServiceManager: %p", sm.get());

       AudioFlinger::instantiate();

       MediaPlayerService::instantiate();

       CameraService::instantiate();

       AudioPolicyService::instantiate();

       ProcessState::self()->startThreadPool();

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

    }

        这个mediaserver的目录下只有一个文件,它的任务很简略,就是把有所媒体相干的native层服务(括包AudioFlinger,MediaPlayerService,CameraService和AudioPolicyService)启动起来,可以参考其Android.mk:

        

    LOCAL_SRC_FILES:= \

                    main_mediaserver.cpp

    LOCAL_SHARED_LIBRARIES := \

                    libaudioflinger\

                    libcameraservice\

                    libmediaplayerservice\

                    libutils \

                    libbinder

    LOCAL_MODULE:= mediaserver

        根据前面的析分,AudioFlinger的源码实现是放在libaudioflinger库中的,因而在编译mediaserver时要用引这个库,其它服务也是一样的做法。编译生成的mediaserver将被烧录到备设的/system/bin/mediaserver径路中,然后由系统启动时的init进程启动,其在Init.rc中的配置是:

        

    service media /system/bin/mediaserver

        class main

        user media

        group audio camera inetnet_bt net_bt_admin net_bw_acct drmrpc

        ioprio rt 4

        值得一提的是,这个AudioFlinger::instantiate()并非AudioFlinger部内的静态类,而是BinderService类的一个实现。括包AudioFlinger、AudioPolicyService等在内的几个服务都承继自这个同一的Binder服务类,比如:

        

    class AudioFlinger :

        public BinderService<AudioFlinger>,

        public BnAudioFlinger…

        从称名上看,BinderService应该是实现了binder跨进程通信相干的功能,它是一个模板类,其中的数函instantiate将把模板指定的服务创立出来,并添加到ServiceManager中:

        

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

        template<typename SERVICE> …

        static status_t  publish(bool allowIsolated = false) {

           sp<IServiceManager> sm(defaultServiceManager());

            returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE(),allowIsolated);

        }

        static void instantiate(){ publish(); } //用调publish

        头回看下AudioFlinger的构造数函,发明它只是简略地为部内一些量变做了初始化,除此之外就没有任何代码了:

        

    AudioFlinger::AudioFlinger()

    :BnAudioFlinger(),mPrimaryHardwareDev(NULL),

     mHardwareStatus(AUDIO_HW_IDLE), // see alsoonFirstRef()

          mMasterVolume(1.0f),mMasterVolumeSupportLvl(MVS_NONE), mMasterMute(false),

          mNextUniqueId(1),mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false)

    {

    }

        大家可能会得觉困惑,那么AudioFlinger在什么情况下会开始行执际实的任务呢?没错,是在onFirstRef()中。BnAudioFlinger是由RefBase层层承继而来的,并且IServiceManager::addService的第二个参数际实上是一个强指针用引(constsp<IBinder>&),因而AudioFlinger备具了强指针被第一次用引时用调onFirstRef的序程逻辑。如果大家不是很楚清这些细节的话,可以参考下本书的强指针章节,这里不再赘述。

        

    void AudioFlinger::onFirstRef()

    {

        int rc = 0;

        Mutex::Autolock _l(mLock);

        charval_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;

                …

            }

    }

    mMode = AUDIO_MODE_NORMAL;

        mMasterVolumeSW = 1.0;

        mMasterVolume   = 1.0;

        mHardwareStatus =AUDIO_HW_IDLE;

    }

        属性ro.audio.flinger_standbytime_ms为用户调整standby时间供提了一个接口,早期版本中这个时间值是固定的。接下来初始化几个重要的部内量变,和构造数函的做法不同的是,这里赋予的都是有效的值了。

        从这时开始,AudioFlinger就是一个“有意义”的实体了,因为有人使用到了它。接下来其它进程可以通过ServiceManager来拜访,并用调createTrack、openOutput等一系列接口来驱使AudioFlinger行执音频处理操作,我们在前面章节会陆续讲解到。

    文章结束给大家分享下程序员的一些笑话语录: 腾讯总舵主马化腾,有人曾经戏称如果在Z国选举总统,马化腾一定当选,因为只要QQ来一个弹窗”投马总,送Q币”即可。

  • 相关阅读:
    [高精度模板][Pascal]整数加、减、乘、除、开方等
    [poj2528]求最后未完全被其它线段覆盖的线段个数
    [POJ3468]线段树模板
    火车进出栈问题(强化版)
    手把手教上Getchu.com
    集合删数
    [SBT模板题]HNOI2002 营业额统计
    离散化Pascal模板
    hdu 4507 吉哥系列故事——恨7不成妻
    组合数学总结
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3022867.html
Copyright © 2011-2022 走看看