audio 核心服務AudioPolicyService 和AudioFlinger啟動流程

目錄

1、audioserver啟動

2、AudioPolicyService啟動

3、AudioFlinger啟動


audio的核心服務有兩個,AudioPolicyService 和AudioFlinger他們到在audioserver一個進程中


1、audioserver啟動


設備開機,系統啟動時將執行 /system/etc/init/audioserver.rc ,運行 /system/bin/ 目錄下的 audioserver 服務。
機器上路徑
console:/ # ls /system/etc/init/audioserver.rc?
/system/etc/init/audioserver.rc
源碼上路徑
frameworks/av/media/audioserver/audioserver.rc
內容如下:

1 service audioserver /system/bin/audioserver
2     class core
3     user audioserver
4     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
5     group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
6     capabilities BLOCK_SUSPEND
7     ioprio rt 4
8     task_profiles ProcessCapacityHigh HighPerformance
9 
10     onrestart setprop sys.audio.restart.hal 1

audioserver 進程會依次對 AudioFlinger、AudioPolicyService、RadioService、SoundTriggerHwService 進行實例化。如果設備集成了杜比音效,杜比音效的內存管理服務 DolbyMemoryService 也會在這里進行實例化。


2、AudioPolicyService啟動

AudioPolicyService服務運行在audioserver進程中, 隨著audioserver進程啟動而啟動。
frameworks/av/media/audioserver/main_audioserver.cpp

int main(int argc __unused, char **argv){……sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();ALOGI("ServiceManager: %p", sm.get());AudioFlinger::instantiate();//實例化AudioFlinger服務,AudioFlinger 的實例化先于AudioPolicyServiceAudioPolicyService::instantiate();//實例化AudioPlicyService服務
}

????????其中,AudioPolicyService::instantiate()并不由AudioPolicyService實現,而是BinderService類的一個實現包括AudioFlinger,AudioPolicyservice等在內的幾個服務都繼承自這個統一的Binder的服務類,具體實現在BinderService.h中。如果后續我們需要自己開發一個基于binder的服務那么也可以繼承binderservice來實現。

    static void instantiate() { publish(); }static status_t publish(bool allowIsolated = false,int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {sp<IServiceManager> sm(defaultServiceManager());return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,dumpFlags);//注冊服務到servicemanager中}

publish()函數獲取到ServiceManager的代理,然后new一個調用instantiate的service對象并把它添加到ServiceManager中。AudioPolicyService 開始構造并調用 AudioPolicyService::onFirstRef() 方法進行初始化,這個過程中會創建 AudioPolicyManager 對象
frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp


void AudioPolicyService::onFirstRef()
{{Mutex::Autolock _l(mLock);// start audio commands threadmAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);//創建ApmAudio線程用于執行audio命令// start output activity command threadmOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);//創建ApmOutpur線程用于執行輸出命令mAudioPolicyClient = new AudioPolicyClient(this);//創建AudioPolicyClient對象ALOGE("czhaudio AudioPolicyService createAudioPolicyManager");mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);// 創建 AudioPolicyManager 對象}// load audio processing modules//解析audio_effects.conf 文件,得到并加載系統支持的音效庫。初始化各個音效對應的參數,將各音效和對應的輸入和輸出//流綁定在一起,這樣,當上層要使用音效時,就會在對應的threadloop中調用process_l音效處理函數。sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();//創建音效相關對象sp<UidPolicy> uidPolicy = new UidPolicy(this);sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);{Mutex::Autolock _l(mLock);mAudioPolicyEffects = audioPolicyEffects;mUidPolicy = uidPolicy;mSensorPrivacyPolicy = sensorPrivacyPolicy;}uidPolicy->registerSelf();sensorPrivacyPolicy->registerSelf();
}

這里audiopolicyservice為什么要起兩個commandthread?audioflinger和audiopoliyservice是在同一個進程。如果audiopolicymanager直接調用audioflinger的接口就會阻塞住。(也就是同步的)。
而通過線程去調用audioflinger的話或者處理一些耗時的任務,audiopolicymanager就可以很快返回不需要阻塞住createAudioPolicyManager() 函數的實現位于 frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp文件中。
查看源碼后我們會發現它實際上是直接調用了 AudioPolicyManager 的構造函數

extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);  // 調用 AudioPolicyManager 的構造函數創建對象status_t status = apm->initialize(); //進行初始化硬件各個模塊if (status != NO_ERROR) {delete apm;apm = nullptr;}return apm;
}

????????AudioPolicyManager 的構造函數將解析音頻策略配置文件,從而獲取到設備所支持的音頻設備信息(包括設備是否支持 Offload、Direct 模式輸出,各輸入輸出 profile 所支持的采樣率、通道數、數據格式等),加載全部 HwModule,為之創建所有非 direct 輸出類型的 outputStream 和所有 inputStream,并創建相應的 playbackThread 或 recordThread 線程。需要注意的是,Android 7.0上的音頻策略配置文件開始使用 XML 格式,其文件名為 audio_policy_configuration.xml,而在之前的版本上音頻策略配置文件為 audio_policy.conf
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 中 AudioPolicyManager 構造函數的關鍵代碼如下

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface): AudioPolicyManager(clientInterface, false /*forTesting*/)
{loadConfig();
}

loadConfig:下片介紹 https://blog.csdn.net/niaohaoge/article/details/147394152

3、AudioFlinger啟動


接1 節的publish,直接分析構造函數
AudioFlinger::instantiate();//實例化AudioFlinger服務,AudioFlinger 的實例化先于AudioPolicyService
?

AudioFlinger::AudioFlinger(): BnAudioFlinger(),mPrimaryHardwareDev(NULL),//...mGlobalEffectEnableTime(0),mPrimaryOutputSampleRate(0)
{getpid_cached = getpid();char value[PROPERTY_VALUE_MAX];//...
}

主要是一些變量的初始化,之后主要看onFirstRef的實現,代碼如下:

void AudioFlinger::onFirstRef()
{int rc = 0;Mutex::Autolock _l(mLock);/* TODO: move all this work into an Init() function */char val_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);} else {mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;}}//這里將AudioFlinger傳遞給PatchPanel,其他并沒有做什么mPatchPanel = new PatchPanel(this);mMode = AUDIO_MODE_NORMAL;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78245.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78245.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78245.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

反爬蟲機制中的驗證碼識別:類型、技術難點與應對策略

在互聯網數據抓取領域&#xff0c;驗證碼識別是爬蟲過程中的關鍵環節之一。下面對常見驗證碼類型、技術難點及應對策略進行詳細解析&#xff0c;并提供多種場景下的代碼實現示例。 一、驗證碼類型與技術難點 &#xff08;一&#xff09;圖形驗證碼 1. 字符驗證碼 特征&#…

vue element使用el-table時,切換tab,table表格列項發生錯位問題

展示問題 問題描述&#xff1a;使用el-table的fixed"right"屬性后&#xff0c;如果切換tab時&#xff0c;回出現最后一列錯誤的問題 官網提供解決方法&#xff1a;doLayout 需要注意的事項&#xff1a;我這里是通過組件使用的table組件&#xff0c;涉及多層組件封裝…

示例:Spring JDBC 聲明式事務(xml配置形式)

聲明式事務是指在不修改源代碼的情況下通過配置applicationContext.xml自動實現事務控制&#xff0c;其本質是AOP環繞通知。它的觸發時機為&#xff1a;1、當目標方法執行成功時自動提交事務&#xff0c;2、當目標方法拋出運行時異常時&#xff0c;自動事務回滾 核心步驟示例&a…

在vmware中ubuntu系統因為安裝了docker查不到ip地址

問題截圖&#xff1a; 根據提供的截圖信息&#xff0c;可以明確看到ens33網卡處于**物理連接斷開&#xff08;NO-CARRIER&#xff09;且接口關閉&#xff08;DOWN&#xff09;**的狀態&#xff0c;這是導致無法獲取IP地址的直接原因。以下是針對VMware虛擬機的具體解決方案&am…

51c大模型~合集121

我自己的原文哦~ https://blog.51cto.com/whaosoft/13869815 #大模型何以擅長小樣本學習&#xff1f; 這項研究給出詳細分析 近年來&#xff0c;大語言模型&#xff08;LLM&#xff09;在人工智能領域取得了突破性進展&#xff0c;成為推動自然語言處理技術發展與通用人…

Babylon.js 材質統一轉換指南:將 AssetContainer 中的所有材質轉換為 PBRMetallicRoughnessMaterial

在現代 3D 開發中&#xff0c;基于物理的渲染(PBR)已成為行業標準。本文將詳細介紹如何在 Babylon.js 中將 AssetContainer 加載的各種材質統一轉換為 PBRMetallicRoughnessMaterial&#xff0c;實現項目材質的標準化。 為什么需要材質轉換&#xff1f; PBRMetallicRoughness…

Go slice切片使用教程,一次通關!

簡介 Go 中的 切片&#xff08;slice&#xff09; 是 Go 最強大、最常用的數據結構之一。它是對數組的輕量封裝&#xff0c;比數組更靈活&#xff0c;幾乎所有的集合處理都用切片來完成。 什么是切片&#xff08;slice&#xff09; 切片是一個擁有 長度&#xff08;len&…

nodejs的包管理工具介紹,npm的介紹和安裝,npm的初始化包 ,搜索包,下載安裝包

nodejs的包管理工具介紹&#xff0c;npm的介紹和安裝&#xff0c;npm的初始化包 &#xff0c;搜索包&#xff0c;下載安裝包 &#x1f9f0; 一、Node.js 的包管理工具有哪些&#xff1f; 工具簡介是否默認特點npmNode.js 官方的包管理工具&#xff08;Node Package Manager&am…

FPGA設計 時空變換

1、時空變換基本概念 1.1、時空概念簡介 時鐘速度決定完成任務需要的時間&#xff0c;規模的大小決定完成任務所需要的空間&#xff08;資源&#xff09;&#xff0c;因此速度和規模就是FPGA中時間和空間的體現。 如果要提高FPGA的時鐘&#xff0c;每個clk內組合邏輯所能做的事…

增加首屏圖片

增加首屏圖片&#xff08;bg.jpg&#xff09; web-mobile類型打包 //index.html腳本 <div id"myDiv_1111"style"background: url(./bg.jpg) 50% 50%/ 100% auto no-repeat ; width:100%;height:100%;position:absolute;"></div> //游戲內腳本…

貪心算法~~

目錄 一、理論基礎 二、題目練習 &#xff08;1&#xff09;455. 分發餅干 &#xff08;2&#xff09;53. 最大子數組和 - 力扣 &#xff08;3&#xff09;122. 買賣股票的最佳時機 II - 力扣&#xff08;LeetCode&#xff09; &#xff08;4&#xff09;860. 檸檬水找零…

形象解釋 HTTP 的四種常見請求方式及其中的區別聯系

HTTP 的常見請求方式常見的有四種&#xff1a;GET、POST、PUT、DELETE&#xff0c;它們各自的功能不一樣。 &#x1f35c; 場景比喻&#xff1a;HTTP 請求像“去餐廳點菜” 請求方式行為餐廳比喻說明GET獲取數據看菜單/問服務員&#xff1a;你們有什么菜&#xff1f;不帶食材、…

string的基本使用

string的模擬實現 string的基本用法string的遍歷&#xff08;三種方式&#xff09;&#xff1a;關于auto&#xff08;自動推導&#xff09;:范圍for: 迭代器普通迭代器(可讀可改&#xff09;const迭代器&#xff08;可讀不可改&#xff09; string細小知識點string的常見接口引…

kubernetes》》k8s》》證書有效期

cd /etc/kubernetes/pki openssl x509 -in apiserver.crt -text -noount通常&#xff0c;Kubernetes的證書是由kubeadm生成的&#xff0c;所以可能需要修改kubeadm的源碼或者配置 登錄Master節點 》》》默認延續1年 # 查看證書 檢查證書有效期 # 該命令顯示 /etc/kubernetes…

LangChain LCEL表達式語言簡介

LangChain表達式語言&#xff08;LCEL&#xff09;是專為構建AI應用鏈設計的聲明式編程框架&#xff0c;通過管道符|實現組件無縫銜接&#xff0c;支持流式處理、異步調用等生產級特性。其核心優勢在于零代碼改動實現原型到生產的過渡&#xff0c;同時保持代碼簡潔性和可維護性…

【計算機視覺】CV實踐項目- 基于PaddleSeg的遙感建筑變化檢測全解析:從U-Net 3+原理到工程實踐

基于PaddleSeg的遙感建筑變化檢測全解析&#xff1a;從U-Net 3原理到工程實踐 技術背景與項目意義傳統方法的局限性深度學習的優勢 核心技術與算法原理U-Net 3架構創新全尺度跳躍連接深度監督機制 變化檢測技術路線 實戰指南&#xff1a;從環境搭建到模型部署環境配置數據準備與…

萬字長文 | Apache SeaTunnel 分離集群模式部署 K8s 集群實踐

文章作者&#xff1a;雷寶鑫 整理排版&#xff1a;白鯨開源 曾輝 Apache SeaTunnel官網鏈接: https://seatunnel.apache.org/ Apache SeaTunnel(以下簡稱SeaTunnel&#xff09;是一款新一代高性能、分布式的數據集成同步工具&#xff0c;正受到業界廣泛關注和應用。SeaTunnel支…

深入解析YOLO v1:實時目標檢測的開山之作

目錄 YOLO v1 算法詳解? ?1. 核心思想? ?2. 算法優勢? ?3. 網絡結構&#xff08;Unified Detection&#xff09;?? ?4. 關鍵創新? ?5. 結構示意圖&#xff08;Fig1&#xff09;? Confidence Score 的計算? 類別概率與 Bounding Box 的關系? 后處理&…

信令與流程分析

WebRTC是h5支持的重要特征之一&#xff0c;有了它&#xff0c;不再需要借助音視頻相關的客戶端&#xff0c;直接通過瀏覽器的Web頁面就可以實現音視頻聊天功能。 WebRTC項目是開源的&#xff0c;我們可以借助WebRTC&#xff0c;構建自己的音視頻聊緹娜功能。無論是前端JS的Web…

BIOS主板(非UEFI)安裝fedora42的方法

BIOS主板(非UEFI)安裝fedora42的方法 現實困難&#xff1a;將Fedora-Workstation-Live-42-1.1.x86_64.iso寫入U盤制作成可啟動U盤啟動fedora42&#xff0c;按照向導將fedora42安裝到真機的sda7分區中得到報錯如下內容&#xff1a; /boot/efi 必需的 /boot/efi必須位于格式化為e…