Android音頻系統之AudioFlinger(一)【轉】

來源:互聯網
上載者:User

標籤:

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執行音頻處理操作,我們在後面章節會陸續講解到。

Android音頻系統之AudioFlinger(一)【轉】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.