国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android13音頻子系統(tǒng)分析(一)---整體架構(gòu)

這篇具有很好參考價值的文章主要介紹了Android13音頻子系統(tǒng)分析(一)---整體架構(gòu)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

????????

目錄

一、應(yīng)用API層

二、Java框架層

三、Native核心層

3.1 AudioFlinger模塊

3.2 AudioPolicyService模塊

四、HAL層

????????本文基于AOSP13源碼進(jìn)行分析解讀。所以與各個SoC平臺廠商提供的運行在真實設(shè)備上的源碼會有細(xì)微差異,但核心原理區(qū)別不大。

????????音頻子系統(tǒng)在Android中是一個較為復(fù)雜的子系統(tǒng),橫跨應(yīng)用API層,框架層,Native層和HAL層。使用Java、C++、C語言進(jìn)行編寫。運行在Linux用戶空間的4個進(jìn)程中:APP應(yīng)用進(jìn)程(API層的代碼)、SystemServer進(jìn)程(框架層的代碼)、AudioServer進(jìn)程(Native層的代碼)、AudioHAL進(jìn)程(HAL層的代碼)。其中運行在AudioServer進(jìn)程中的AudioFlinger和AudioPolicyService,以及運行在SystemServer進(jìn)程中的AudioService這三個模塊是Android音頻子系統(tǒng)的核心,也是我后續(xù)分析的重點。而AudioHAL模塊是由各個SoC廠商自行根據(jù)芯片特點實現(xiàn)的,每種平臺的代碼都不一樣,AOSP中只定義了標(biāo)準(zhǔn)接口,并沒有具體的實現(xiàn)代碼。以下是音頻子系統(tǒng)的整體架構(gòu)圖:

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

一、應(yīng)用API層

? ? ? ? 應(yīng)用API層的源碼位置:/frameworks/base/media/java/android/media/

? ? ? ? 這部分代碼是運行在調(diào)用其代碼的APP進(jìn)程中的,圖中用淺藍(lán)色標(biāo)注的模塊。其中主要的接口模塊有三個:

  • AudioTrack.java:為APP提供播放音頻數(shù)據(jù)的接口。
  • AudioRecord.java:為APP提供錄制音頻數(shù)據(jù)的接口。
  • AudioManager.java:為APP提供管理音頻路由、音量控制、音頻焦點獲取的接口。

? ? ? ? 從上面的整體架構(gòu)圖中可以看出,AudioTrack.java和AudioRecord.java會分別調(diào)用其對應(yīng)的JNI文件:android_media_AudioTrack.cpp、android_media_AudioRecord.cpp(它們位于/frameworks/base/core/jni/目錄中)。而這兩個JNI層的代碼又會調(diào)用Native的客戶端代碼AudioTrack.cpp和AudioRecord.cpp(它們位于/frameworks/av/media/libaudioclient/目錄中)。所以,我們可以看出音頻播放和錄制數(shù)據(jù)的應(yīng)用接口代碼的真正實現(xiàn)是在libaudioclient中的。

? ? ? ? AudioManger.java是AudioService.java的客戶端代理類,它里面的大多數(shù)函數(shù)都是通過Binder方式遠(yuǎn)程調(diào)用AudioService.java來實現(xiàn)的。當(dāng)然一小部分簡單的函數(shù)也會直接調(diào)用AudioSystem.java來實現(xiàn)。而大多數(shù)情況下AudioSystem.java都是被AudioService.java調(diào)用使用的。

????????在上面的整體架構(gòu)圖中,我把AudioSystem.java放在了APP進(jìn)程和SystemServer進(jìn)程這兩個進(jìn)程框線之間,意思是這個java文件會分別運行在兩個不同的進(jìn)程中。我們知道Java的特性是同一個java文件在不同的進(jìn)程中會有不同對象和數(shù)據(jù),不過當(dāng)我們讀一下AudioSystem.java的源碼我們就會發(fā)現(xiàn),它是一個全部通過靜態(tài)方法實現(xiàn)的代碼文件,只有靜態(tài)數(shù)據(jù),比如注冊的一些Callback函數(shù)。所以,APP進(jìn)程中注冊的Callback對象和SystemServer進(jìn)程中注冊的Callback對象并不是同一個。AudioSystem.java文件也位于/frameworks/base/media/java/android/media/目錄中,但是它是一個hide class,所以普通的APP程序是無法直接調(diào)用它的接口的,當(dāng)然Java反射除外。AudioSystem.java和AudioTrack.java類似,它也會通過JNI調(diào)用android_media_AudioSystem.cpp文件,然后JNI文件又會調(diào)用libaudioclient的AudioSystem.cpp文件。所以AudioSystem.cpp才是真正實現(xiàn)代碼邏輯的地方。

????????/frameworks/av/media/libaudioclient/這個目錄中的源碼會被編譯打包成libaudioclient.so,它包含了三個重要客戶端接口類AudioTrack.cpp、AudioRecord.cpp和AudioSystem.cpp。所以,如果我們寫一個native APP,完全可以直接加載libaudioclient這個so庫,調(diào)用它們提供的接口API。? ? ? ? ? ? ? ?前面我們提到AudioManager.java會直接調(diào)用AudioSystem.java的部分函數(shù),而AudioManager.java是運行在APP進(jìn)程中的,AudioSystem.java最終又會調(diào)用libaudioclient.so的AudioSystem.cpp,所以我們可以推斷APP進(jìn)程在初始化時,已經(jīng)加載過了libaudioclient.so庫。我們可以直接使用C++代碼調(diào)用AudioTrack.cpp和AudioRecord.cpp中的接口函數(shù)。

? ? ? ? AudioSystem.cpp也是一個由靜態(tài)函數(shù)實現(xiàn)的類。它的作用是和AudioFilnger、AudioPolicyService通信,通過Binder方式調(diào)用這兩個模塊提供的接口函數(shù)。同時,它提供了直接獲取這兩個模塊的Binder代理接口類的方法:get_audio_flinger()、get_audio_policy_service()。

????????當(dāng)我們查看AudioPolicyService模塊中的源碼時,我們就會看到,AudioPolicyService也是通過AudioSystem.cpp的get_audio_flinger()接口函數(shù),來獲取到AudioFlinger的Binder代理類,然后和AudioFilnger模塊進(jìn)行通信的,雖然AudioPolicyService模塊和AudioFlinger這兩個模塊都是運行在同一進(jìn)程AudioServer中。Binder的機(jī)制是跨進(jìn)程調(diào)用時,被調(diào)用的Server端函數(shù)會運行在Server端的15個Binder線程中的一個,而同一進(jìn)程內(nèi)調(diào)用時,被調(diào)用的Server端函數(shù)就直接運行在客戶端調(diào)用方運行的線程中。所以,AudioPolicyService所調(diào)用的任何AudioFlinger函數(shù),都不是運行在AudioServer進(jìn)程的15個Binder線程中的。順便說一下,基于這個發(fā)現(xiàn),我們可以知道AudioServer進(jìn)程中已經(jīng)加載了libaudioclient.so庫,因為它使用了AudioSystem.cpp文件。所以,在AudioServer進(jìn)程中的模塊代碼是可以直接使用AudioTrack.cpp和AudioRecord.cpp文件的。正是基于這個發(fā)現(xiàn),我之前在解決一個手機(jī)通過藍(lán)牙連接到寶馬車機(jī)播放聲音延遲很大的問題時,就想到了在AudioFlinger模塊中直接通過AudioTrack.cpp和AudioRecord.cpp創(chuàng)建一個超聲播放回路,用于監(jiān)測車內(nèi)的聲音播放延遲大小,實踐證明是可行的。

? ? ? ? 通過上面的分析我們可以發(fā)現(xiàn),Android音頻子系統(tǒng)提供了兩套API接口給客戶端使用,一套是Java代碼實現(xiàn)的,位于/frameworks/base/media/java/android/media/目錄中。一套是C++代碼實現(xiàn)的,位于/frameworks/av/media/libaudioclient/目錄中。
? ? ? ? 應(yīng)用API層除了提供核心的AudioTrack.java、AudioRecord.java和AudioManager.java接口之外,還提供了AudioPatch.java和AudioMix.java這兩類接口,用于客戶端定制音頻路由策略。但是它們兩都是hide class,所以普通應(yīng)用不能使用。我看目前主要是CarAudioService在使用,用于車機(jī)場景。后續(xù)有機(jī)會我會單獨寫一篇文章來介紹這兩個類的作用,因為是和AudioPolicyService模塊強相關(guān),所以要在深入分析完AudioPolicyService模塊后再介紹更為合適。

二、Java框架層

? ? ? ? Java框架層的源碼位置:/frameworks/base/services/core/java/com/android/server/audio/

? ? ? ? 這部分代碼是運行在SystemServer進(jìn)程中的,整體架構(gòu)圖中用綠色標(biāo)注的模塊。

? ? ? ? AudioService.java是音頻設(shè)備路由管理、音量控制、焦點控制的具體實現(xiàn)模塊。它主要包含4個子模塊。具體模塊架構(gòu)圖如下:

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

? ? ? ? 基本上從文件名稱上我們就可以看出這幾個模塊的用途:

  • AudioDeviceBroker.java:用于管理音頻設(shè)備路由策略。它包含兩個子模塊AudioDeviceInventory.java和BtHelper.java。BtHelper用于和藍(lán)牙Java層模塊交互(源碼位于/packages/modules/Bluetooth/目錄),監(jiān)聽藍(lán)牙設(shè)備的連接狀態(tài)和codec配置變更信息等。
  • MediaFocusControl.java:音頻焦點控制模塊。
  • PlaybackActivityMonitor.java:音頻播放事件監(jiān)聽模塊。
  • RecordingActivityMonitor.java:音頻錄制事件監(jiān)聽模塊。

? ? ? ? 在/frameworks/base/services/core/java/com/android/server/audio/這個目錄中,我并沒有看到音量控制相關(guān)的類,因為它是由AudioService.java自己實現(xiàn)的。還有一個類,雖然不在這個目錄中,但需要在這里提一下:

/frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java

它是監(jiān)聽有線耳機(jī)設(shè)備插拔狀態(tài)的入口。

? ? ? ? 我之前看到這里的代碼,曾產(chǎn)生一個疑問,既然AudioService是用于管理音頻設(shè)備路由策略的,那還要AudioPolicyService干嘛?或者說直接在AudioPolicyService里面實現(xiàn)不就行了,還要AudioService干嘛?我的理解是AudioService是運行在SystemServer進(jìn)程的,它可以直接和ActivityManagerService等其它Android核心服務(wù)交互,可以知道客戶端是哪個package name在播放、在設(shè)置設(shè)備路由等。輔助AudioPolicyService更好的管理。所以,我認(rèn)為基于Android系統(tǒng)結(jié)合當(dāng)?shù)赜脩魬?yīng)用場景來進(jìn)行音頻模塊定制化時,應(yīng)該優(yōu)先考慮修改AudioService模塊,因為它更接近用戶場景,AudioService模塊實現(xiàn)不了的,再考慮修改AudioPolicyService模塊。

三、Native核心層

? ? ? ? 音頻Native核心層分為兩大模塊:AudioFlinger和AudioPolicyService。它們都是注冊在ServiceManager中的Binder服務(wù)。運行在AudioServer進(jìn)程中,整體架構(gòu)圖中橙色部分。下面分開進(jìn)行介紹。

3.1 AudioFlinger模塊

? ? ? ? AudioFlinger模塊的源碼位置:/frameworks/av/services/audioflinger/?

? ? ? ? 我認(rèn)為AudioFlinger主要分為三個遞進(jìn)關(guān)系的子模塊:AudioHwDevice、PlaybackThread/RecordThread、PlaybackTrack/RecordTrack。當(dāng)然我沒有提到音效相關(guān)的類,是因為我認(rèn)為不介紹音效相關(guān)類并不影響整體架構(gòu)的梳理和理解,后續(xù)講到播放時再來介紹也沒關(guān)系。

????????這里的AudioHwDevice并不是指喇叭、聽筒、耳機(jī)這種真實的物理設(shè)備,而是指不同的Audio HAL module,比如primary module、a2dp module等,也可以理解成是音頻框架層定義的一種虛擬設(shè)備。它和Audio HAL層的DeviceHal是對應(yīng)的關(guān)系。

????????PlaybackThread/RecordThread是由AudioFlinger啟動的負(fù)責(zé)音頻數(shù)據(jù)傳輸?shù)木€程。播放和錄制的核心流程都在這里面實現(xiàn)。它和Audio HAL層的StreamHal是對應(yīng)的關(guān)系。

????????PlaybackTrack/RecordTrack對應(yīng)的是API層的AudioTrack/RecordTrack,它相當(dāng)于是服務(wù)端。

????????我還想提一個模塊是PatchPanel.cpp,它是用于管理音頻設(shè)備切換的類。使用AudioPatch類來表示stream和device的連接關(guān)系。之所以在這里提及一下,是因為這個文件中包含了一些AudioFlinger類的實現(xiàn)函數(shù),大家在查看AudioFlinger.h申明的函數(shù)具體實現(xiàn)時,如果在AudioFlinger.cpp中找不到,就可以在PatchPanel.cpp找一下,主要是和音頻設(shè)備切換相關(guān)的,比如createAudioPatch()函數(shù)。

? ? ? ? 以下是AudioFlinger核心子模塊的類圖:

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

? ? ? ? 從類圖中可以看出,應(yīng)用層libaudioclient中的AudioTrack.cpp有一個成員變量mAudioTrack(BpAudioTrack),它是IAudioTrack.aidl接口的代理端,通過Binder方式與BnAudioTrack進(jìn)行交互。BpAudioTrack和BnAudioTrack都是Android基于IAudioTrack.aidl文件編譯時自動生成的,所以找不到源碼。IAudioTrack.aidl服務(wù)端的實現(xiàn)就是繼承了BnAudioTrack的AudioFlinger.TrackHandle這個內(nèi)部類。所以,AudioTrack.cpp實際上就是和它在進(jìn)行通信交互。AudioTrack.cpp獲取IAudioTrack代理端的方法是調(diào)用AudioFlinger的createTrack()函數(shù)。

????????查看AudioFlinger.TrackHandle的源碼會發(fā)現(xiàn),在AudioFlinger內(nèi)部,TrackHandle只是一個代理,負(fù)責(zé)與客戶端交互,真正的實現(xiàn)邏輯是在AudioFlinger.PlaybackThread.Track這個內(nèi)部類中。

? ? ? ? AudioFlinger模塊的源碼文件個數(shù)不多,但是一個文件中定義了好幾個內(nèi)部類,以下是各種內(nèi)部類所在的源碼文件位置,方法大家查找閱讀:

  • 所有Track相關(guān)的源碼都定義在TrackBase.h、PlaybackTacks.h、RecordTracks.h這三個頭文件中,統(tǒng)一在Tracks.cpp文件中實現(xiàn)。但是TrackHandle類和RecordHandle類是定義在AudioFlinger.h頭文件中,實現(xiàn)卻是在Tracks.cpp文件中。
  • 所有Thread相關(guān)的源碼都定義在Threads.h文件中,實現(xiàn)是在Threads.cpp文件中。比如PlaybackThread和RecordThread類。
  • AudioStreamIn這個類因為比較簡單,它的定義和實現(xiàn)都是在AudioFlinger.h頭文件中。

????????DeviceHalInterface、StreamOutHalInterface和StreamInHalInterface這三個接口類是AudioHAL定義的HAL客戶端接口類,源碼位于/frameworks/av/media/libaudiohal/目錄中,在HAL層架構(gòu)分析時我會進(jìn)一步講。

? ? ? ? 由于Thread和Track這兩種類的繼承關(guān)系較多,所以我畫了兩個類圖來說明它們的結(jié)構(gòu),如下:????????安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

? ? ? ? 從這個類圖中可以看出,所有的播放和錄制Thread類都是繼承的ThreadBase,而ThreadBase又繼承了Android標(biāo)準(zhǔn)的循環(huán)線程類Thread,所以它們都是可以單獨循環(huán)運行的普通線程。以下是各種Thread的作用介紹:

  • MixerThread:包含將上層多個track數(shù)據(jù)進(jìn)行混音操作的播放線程。當(dāng)AudioPolicySerivce請求openOutput時設(shè)置了這些flag,AudioFlinger就會創(chuàng)建此種線程:AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER。它也是AudioFlinger使用頻次最多、默認(rèn)創(chuàng)建的Thread類型。
  • DirectOutputThread:不經(jīng)過混音等上層音效處理的直傳播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_DIRECT flag時,會被創(chuàng)建使用。
  • OffloadThread:要求通過底層DSP硬件進(jìn)行解碼的播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD flag時,會被創(chuàng)建使用。
  • DuplicatingThread:多路輸出播放線程,比如手機(jī)連上藍(lán)牙耳機(jī)后來電時,聲音會從喇叭和耳機(jī)同時輸出。
  • SpatializerThread:Android13新增加的空間音頻播放線程。當(dāng)設(shè)置了AUDIO_OUTPUT_FLAG_SPATIALIZER flag時,會被創(chuàng)建使用。

? ? ? ? 所有的Thread類都是AudioFlinger的內(nèi)部類,但是如果我們查看Threads.h源文件,并沒有看到這些類是定義在class AudioFlinger中的?原因是在AudioFlinger.h文件中,定義的AudioFlinger class包含了這句代碼:#include "Threads.h"。Track類的定義也是采用相同的方法,以下是Track的類圖,從這個類圖中可以看到,所有的Track都是Thread的內(nèi)部類。

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

3.2 AudioPolicyService模塊

????????AudioPolicyService模塊的源碼位置:/frameworks/av/services/audiopolicy/

????????AudioPolicyService模塊的源碼目錄結(jié)構(gòu)比較多,源文件也比較多。但是我認(rèn)為核心的就3個子模塊:AudioPolicyService、AudioPolicyManager和Engine。Engine負(fù)責(zé)存儲設(shè)備路由策略和音量大小配置。AudioPolicyManager負(fù)責(zé)設(shè)備路由和音量控制的具體實現(xiàn)。AudioPolicyService負(fù)責(zé)對外提供Binder接口和其它模塊進(jìn)行交互。它們?nèi)叩恼{(diào)用可以從以下類圖中看出:

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

? ? ? ? 簡化一下,就可以看出這三者的調(diào)用關(guān)系是:

AudioPolicyService<-->AudioPolicyManager<-->Engine

? ? ? ? 當(dāng)然,在AudioPolicyService模塊中,也會存在device、stream、track的概念,只是它們的命名方式不一樣。這也是我認(rèn)為整個Android音頻子系統(tǒng)代碼實現(xiàn)不好的地方,我猜可能是各個模塊由不同的人編寫的原因吧。比如說streamOutput,AudioFlinger里面叫PlaybackThread,AudioPolicyService里面又叫AudioOutputDescriptor,還有一個叫IOProfile,IOProfile對象保存封裝的是config配置文件中針對stream流的配置,而在配置文件中,又定義成叫mixPort,而mix這個名稱,讓我一開始想到的是AudioFlinger里面的AudioMixer(用于執(zhí)行多個track混音的模塊)。device也是,AudioFlinger里面叫AudioHwDevice,到了AudioPolicyService里面又叫HwModule。在剛開始看這些代碼時,真的是能把人繞暈。下面我就來介紹一下AudioPolicyService模塊里面的核心數(shù)據(jù)結(jié)構(gòu)。

? ? ? ? AudioPolicyService模塊的四個核心數(shù)據(jù)類:HwModule、AudioIODescriptorInterface、DeviceDescriptor、ClientDescriptor。

  • HwModule:它代表的是HAL層的虛擬設(shè)備Device,與AudioFlinger中的AudioHwDevice對應(yīng)。在audio_policy_configuration.xml配置文件中對應(yīng)的是<module>節(jié)點。
  • AudioIODescriptorInterface:它包含兩個子類,AudioOutputDescriptor和AudioInputDescriptor。代表的是音頻輸入輸出流,對應(yīng)的是AudioFlinger中的Thread,以及HAL層的Stream。同時它還有一個成員變量IOProfile對象,IOProfile對應(yīng)的是audio_policy_configuration.xml配置文件中的<mixPort>節(jié)點。
  • DeviceDescriptor:它代表的是真實的物理設(shè)備,比如喇叭、聽筒、Mic等。對應(yīng)的是audio_policy_configuration.xml配置文件中<devicePort>節(jié)點。
  • ClientDescriptor:它包含兩個子類,TrackClientDescriptor和RecordClientDescriptor。分別對應(yīng)的是上層的Track和Record對象。

? ? ? ? 下圖是以音頻播放場景舉例,來說明這四種數(shù)據(jù)類型在各個層級中的定義,顏色相同的代表同一種數(shù)據(jù)類型。以及它們四者之間的包含關(guān)系。

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

????????從這個圖中可以看出,四者之間的關(guān)系是:Module包含多個OutputStream,OutputStream作為中間連接器,包含上層的多個track,也包含底層的多個device。其中AudioPolicyService模塊的關(guān)系定義是最標(biāo)準(zhǔn)的,也最能說明它們四者之間的關(guān)系。

? ? ? ? 同時可以看出,Track是只在上層和框架層存在的概念。到了HAL層就沒有Track這個概念了。HAL層只有outputStream和真實物理設(shè)備Device的概念。

? ? ? ? 下面分別說明一下這四個數(shù)據(jù)結(jié)構(gòu)在各個層級中的定義名稱:

  • Module:只存在于框架層和HAL層的概念。代表的是一個HAL模塊,也可以理解成是一個虛擬設(shè)備。它在AudioPolicyService中的定義是HwModule。在AudioFlinger中的定義是AudioHwDevice。在HAL向上接口層的定義是IDevice.aidl。在HAL向下接口層的定義是audio_hw_device。
  • OutputStream:代表的是一個音頻輸出流。用于連接上層的track和底層真實的device設(shè)備。它在AudioPolicyService中的定義是AudioOutputDescriptor、OutputProfile。在AudioFlinger中的定義是PlaybackThread、AudioStreamOut。在HAL向上接口層的定義是IStreamOut.aidl。在HAL向下接口層的定義是audio_stream_out。
  • Track:代表的是應(yīng)用層的一個播放對象,一個應(yīng)用進(jìn)程中可以創(chuàng)建多個Track。它在應(yīng)用層的定義是AudioTrack.java。在AudioPolicyService中的定義是TrackClientDescriptor。在AudioFlinger中的定義是AudioFlinger.TrackHandle、AudioFlinger.PlaybackThread.Track。
  • Device:代表的是一個真實的物理設(shè)備。它在應(yīng)用層的定義是AudioDeviceInfo.java。在AudioPolicyService中的定義是DeviceDescriptor。在AudioFlinger中的定義是AudioDeviceTypeAddr。在HAL層的定義是audio_devices_t。

? ? ? ? 如果我們在/system/media/audio/include/system/audio-hal-enums.h源文件中看一下audio_devices_t的定義,就會發(fā)現(xiàn)它只是一個定義多種常量的枚舉。并沒有包含物理設(shè)備的配置信息:比如支持的samplingRates、format等。原因是Android音頻子系統(tǒng)中還定義了一個叫AudioPort的概念。它代表的是一個音頻流中的節(jié)點,可以是真實物理設(shè)備、也可以是outputstream、還可以是session。AudioPort有兩種角色,一種是sink,比如說代表喇叭設(shè)備時。一種是source,比如說代表PlaybackThread時,或者代表mic設(shè)備時。

? ? ? ? AudioPort是橫跨整個音頻子系統(tǒng)的數(shù)據(jù)類型,它在應(yīng)用層、框架層、HAL層中都有使用。它的定義是在/system/media/audio/include/system/audio.h源文件中,定義了兩個結(jié)構(gòu)體:audio_port和audio_port_config。各個層級也會基于此定義自己的數(shù)據(jù)類型,比如Native層的AudioPort和AudioPortConfig類,它們位于/frameworks/av/media/libaudiofoundation/include/media/AudioPort.h源文件中,供C++世界的代碼使用,比如AudioPolicyService模塊。在Java世界中的定義是:AudioPort.java和AudioPortConfig.java,位于/frameworks/base/media/java/android/media/目錄中。

? ? ? ? 下面我會畫一個AudioPolicyService模塊中的DeviceDescriptor和OutputProfile的繼承關(guān)系類圖,從而更直觀看出AudioPort的定義。

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

????????這張類圖中,可以直觀的看到DeviceDescriptor和OutputProfile都是繼承了AudioPort類的。其中PolicyAudioPort類和PolicyAudioPortConfig類是AudioPoicyService模塊自己擴(kuò)展定義的AudioPort。位于/frameworks/av/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h源文件中。

? ? ? ? 最后,介紹一下AudioPolicyService模塊的源碼目錄結(jié)構(gòu):

  • /frameworks/av/services/audiopolicy/根目錄下,只有一個源文件:AudioPolicyInterface.h,它定義了AudioPolicyService和AudioPolicyManager需要遵循的接口。
  • ./service/目錄:定義了AudioPolicyService模塊的代碼實現(xiàn)。
  • ./managerdefault/目錄:定義了AudioPolicyManager模塊的代碼實現(xiàn)。這個目錄中的代碼會被編譯打包到libaudiopolicymanagerdefault.so庫中。廠商也可以根據(jù)自己需要完全重寫。
  • ./enginedefault/目錄:定義了engine模塊的代碼實現(xiàn)。這個目錄會被編譯打包到libaudiopolicyenginedefault.so庫中。
  • ./engineconfigurable/目錄,定義了engine模塊的另外一種實現(xiàn),目前沒有使用,而是用的./enginedefault/目錄中的源碼。
  • ./engine/目錄:定義了engine模塊的基礎(chǔ)代碼實現(xiàn),EngineBase類就在其中定義。
  • ./config/目錄:定義了audio_policy_configuration.xml文件的參考模版。
  • ./common/目錄:定義了AudioPolicyManager模塊所使用的一些數(shù)據(jù)結(jié)構(gòu),比如HwModule、DeviceDescriptor、AudioOutputDescriptor等。會被編譯打包到libaudiopolicycomponents.so庫中。

四、HAL層

? ? ? ? 我認(rèn)為AudioHAL層可以分為三大部分:

  • 第一部分是HIDL代理端的實現(xiàn)。源碼位于:/frameworks/av/media/libaudiohal/目錄。它供AudioFlinger來調(diào)用,運行在調(diào)用方AudioServer進(jìn)程中。通過Binder方式與HIDL服務(wù)端通信。
  • 第二部分是HIDL服務(wù)端的實現(xiàn)。源碼位于:/hardware/interfaces/audio/目錄。包含了音頻HIDL接口文件的定義和服務(wù)端的實現(xiàn)代碼。
  • 第三部分是提供給SoC廠商的實現(xiàn)接口定義。由SoC廠商根據(jù)自己芯片的特點進(jìn)行實現(xiàn)。AOSP不提供實現(xiàn)源碼。接口定義的源碼位于:/hardware/libhardware/include/hardware/audio.h

安卓音頻子系統(tǒng),Android13音頻系統(tǒng),架構(gòu),android,音頻

? ? ? ? 以上是HIDL代理端libaudiohal的代碼實現(xiàn)類圖。從類圖中可以看出,由DevicesFactoryHalHidl負(fù)責(zé)創(chuàng)建Device對象,再由DeviceHalHidl來創(chuàng)建Stream對象。

device的真正實現(xiàn)是在DeviceHalHidl.cpp文件中。stream的真正實現(xiàn)是在StreamHalHidl.cpp文件中。

? ? ? ?HIDL服務(wù)端的啟動代碼是在/hardware/interfaces/audio/common/all-versions/default/service/目錄中,它是Audio HAL進(jìn)程的啟動總?cè)肟?。有對?yīng)的rc文件。

????????HIDL服務(wù)端的實現(xiàn)代碼是在/hardware/interfaces/audio/core/all-versions/default/目錄中,包含了DevicesFactory、Device和Stream的實現(xiàn)。正如前面所說,它們其實也是一個代理,只是調(diào)用audio.h中定義的接口。真正的實現(xiàn)還是由SoC廠商完成的。文章來源地址http://www.zghlxwxcb.cn/news/detail-724723.html

到了這里,關(guān)于Android13音頻子系統(tǒng)分析(一)---整體架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • win10安裝安卓子系統(tǒng)android13肯定成功補充說明Win1022H2安裝WSA安卓子系統(tǒng)部署失敗0x80073CF3無法進(jìn)行更新、相關(guān)性或沖突驗證Xaml.2.8解決方案

    win10安裝安卓子系統(tǒng)android13肯定成功補充說明Win1022H2安裝WSA安卓子系統(tǒng)部署失敗0x80073CF3無法進(jìn)行更新、相關(guān)性或沖突驗證Xaml.2.8解決方案

    說明:該文章為我之前的文章的一個補充說明,也是由于最近系統(tǒng)出了問題后,進(jìn)行了更新到Win10最新系統(tǒng)后,出現(xiàn)的一些問題,并做了以下的一些記錄: 這里呢,我是昨天重新下載并更新了系統(tǒng)為22H2,所以,我還在用之前的安卓子系統(tǒng)時,出現(xiàn)了問題,無法部署成功,“部

    2024年02月20日
    瀏覽(24)
  • 1.內(nèi)核驅(qū)動中,驅(qū)動注冊,阻塞IO,gpio子系統(tǒng),中斷處理的整體結(jié)合示例

    1.內(nèi)核驅(qū)動中,驅(qū)動注冊,阻塞IO,gpio子系統(tǒng),中斷處理的整體結(jié)合示例

    /*功能實現(xiàn) 在stm32開發(fā)板上實現(xiàn)功能 ? ? ? ? ? ?1.使用阻塞IO讀取number變量的值,當(dāng)number的值改變時打印number的值 ? ? ? ? ? ?2.注冊KEY1按鍵的驅(qū)動和LED1的驅(qū)動以及對應(yīng)的設(shè)備文件, ? ? ? ? ? ?3.按鍵和指示燈設(shè)備信息放在同一個設(shè)備樹的節(jié)點中 ? ? ? ? ? ?4.當(dāng)KEY1按下時

    2024年02月15日
    瀏覽(18)
  • 【W(wǎng)indows 11】安裝 Android子系統(tǒng) 和 Linux子系統(tǒng)

    【W(wǎng)indows 11】安裝 Android子系統(tǒng) 和 Linux子系統(tǒng)

    本文使用電腦系統(tǒng): 主要就是安裝一個名為: 適用于Android的Windows子系統(tǒng) (WSA)的軟件。 首先在電腦的設(shè)置里面:時間和語言——語言和地區(qū)里面把地區(qū)改為美國。 然后到微軟商店搜索: Amazon AppStore 。 安裝亞馬遜應(yīng)用商店的時候,會首先提示你安裝前面說的WSA。如此,我

    2024年02月09日
    瀏覽(31)
  • Android相機(jī)-HAL子系統(tǒng)

    Android相機(jī)-HAL子系統(tǒng)

    應(yīng)用框架要通過拍照預(yù)覽攝像獲得照片或者視頻,就需要向相機(jī)子系統(tǒng)發(fā)出請求, 一個請求對應(yīng)一組結(jié)果 一次可發(fā)起多個請求,并且提交請求是非阻塞的,始終按照接收的順序以隊列的形式先進(jìn)先出地進(jìn)行順序處理 一個請求包含了拍攝和拍照配置的所有信息,以及處理這些的

    2024年02月11日
    瀏覽(17)
  • 一、LED子系統(tǒng)框架分析

    個人主頁:董哥聊技術(shù) 我是董哥,嵌入式領(lǐng)域新星創(chuàng)作者 創(chuàng)作理念:專注分享高質(zhì)量嵌入式文章,讓大家讀有所得!

    2023年04月09日
    瀏覽(20)
  • OpenHarmony3.1安全子系統(tǒng)-簽名系統(tǒng)分析

    OpenHarmony3.1安全子系統(tǒng)-簽名系統(tǒng)分析

    應(yīng)用簽名系統(tǒng)主要負(fù)責(zé)鴻蒙hap應(yīng)用包的簽名完整性校驗,以及應(yīng)用來源識別等功能。 子系統(tǒng)間接口: 應(yīng)用完整性校驗?zāi)K給其他模塊提供的接口; 完整性校驗: 通過驗簽,保障應(yīng)用包完整性,防篡改; 應(yīng)用來源識別: 通過匹配簽名證書鏈與可信源列表,識別應(yīng)用來源。

    2024年02月05日
    瀏覽(20)
  • 【分析筆記】Linux 4.9 backlight 子系統(tǒng)分析

    【分析筆記】Linux 4.9 backlight 子系統(tǒng)分析

    內(nèi)核版本:Linux version 4.9.56 驅(qū)動文件:licheelinux-4.9driversvideobacklightbacklight.c 對上,面對應(yīng)用層提供統(tǒng)一的設(shè)備節(jié)點入口 同級,面對驅(qū)動層提供設(shè)備驅(qū)動加載卸載通知事件,以及背光控制接口。 對下,面對硬件層提供背光控制調(diào)節(jié)的回調(diào)接口 監(jiān)聽 frambuffer 事件, 實現(xiàn)清屏聯(lián)

    2024年02月11日
    瀏覽(17)
  • 五分鐘Win11安裝安卓(Android)子系統(tǒng)

    五分鐘Win11安裝安卓(Android)子系統(tǒng)

    十分鐘,完成win11安裝安卓子系統(tǒng) Win+i 進(jìn)入設(shè)置頁面,選擇 時間和語言 - 語言和區(qū)域 - 區(qū)域-美國 訪問如下連接,install即可 安卓子系統(tǒng) 在開始菜單找到子系統(tǒng),點開,做如下配置: 打開應(yīng)用商店,安卓APK安裝程序 下載應(yīng)用寶手機(jī)版,APK文件,雙擊,有什么點什么,即可

    2024年02月02日
    瀏覽(29)
  • windows11安裝Android子系統(tǒng),安裝apk教程。

    windows11安裝Android子系統(tǒng),安裝apk教程。

    系統(tǒng):windows11TPM2.0 硬件:內(nèi)存大于8GB 瀏覽器地址欄輸入:“https://store.rg-adguard.net/” 搜索框輸入:“https://www.microsoft.com/store/productId/9P3395VX91NR” 然后在右邊下拉列表選擇“Slow” ,然后點擊最后面的“√”。注:不要翻譯界面! 找到MicrosoftCorporationII.WindowsSubsystemForAndroid_1

    2024年02月06日
    瀏覽(24)
  • 【W(wǎng)indows優(yōu)化系列】Windows11安裝Android子系統(tǒng)

    【W(wǎng)indows優(yōu)化系列】Windows11安裝Android子系統(tǒng)

    Q:為什么要在Windows安裝Android系統(tǒng)?直接在手機(jī)使用不好嗎? A:在電腦刷酷安不比拿著手機(jī)刷酷安爽嗎?在電腦版的酷安碼字不比手機(jī)上碼字爽嗎?不用打開手機(jī)也可以在電腦上點餓了么外賣不方便嗎?手機(jī)上似乎不能使用tiktok,電腦上就可以使用tiktok。 并且,使用微軟的

    2024年02月07日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包