Android音頻系統之AudioFlinger(一)

1.1 AudioFlinger

在上面的框架圖中,咱們能夠看到AudioFlinger(下面簡稱AF)是整個音頻系統的核心與難點。做爲Android系統中的音頻中樞,它同時也是一個系統服務,啓到承上(爲上層提供訪問接口)啓下(經過HAL來管理音頻設備)的做用。只有理解了AudioFlinger,才能以此爲基礎更好地深刻到其它模塊,於是咱們把它放在前面進行分析。java

 

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)ui

{指針

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

    sp<IServiceManager>sm = defaultServiceManager();繼承

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

   AudioFlinger::instantiate();進程

   MediaPlayerService::instantiate();rpc

   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的構造函數,發現它只是簡單地爲內部一些變量作了初始化,除此以外就沒有任何代碼了:

(frameworks/av/services/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執行音頻處理操做,咱們在後面章節會陸續講解到。

相關文章
相關標籤/搜索