標籤:
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(一)【轉】