Day4.AndroidAudio初始化

1.AudioServer初始化

AudioServer 是 Android 音頻系統的核心服務,負責管理音頻硬件資源、音頻策略調度、跨進程音頻通信等核心功能。它由 Init 進程啟動,是系統核心服務之一,直接影響音頻播放、錄音、音效處理等功能的正常運行。

1.1AudioServer服務創建過程

Init 進程通過解析/system/bin/audioserver/audioserver.rc配置文件,完成 AudioServer 的服務定義與啟動參數配置。
請添加圖片描述

service audioserver /system/bin/audioserver  class core  user audioserver  # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)  group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock  capabilities BLOCK_SUSPEND  # match rtprio cur / max with sensor service as we handle AR/VR HID sensor data.  rlimit rtprio 10 10  ioprio rt 4  task_profiles ProcessCapacityHigh HighPerformance  onrestart restart vendor.audio-hal  onrestart restart vendor.audio-hal-aidl  onrestart restart vendor.audio-effect-hal-aidl  onrestart restart vendor.audio-hal-4-0-msd  onrestart restart audio_proxy_service  
?  
on property:vts.native_server.on=1  stop audioserver  
on property:vts.native_server.on=0  start audioserver  
?  
on property:init.svc.audioserver=stopped  stop vendor.audio-hal  stop vendor.audio-hal-aidl  stop vendor.audio-effect-hal-aidl  stop vendor.audio-hal-4-0-msd  stop audio_proxy_service  # See b/155364397. Need to have HAL service running for VTS.  # Can't use 'restart' because then HAL service would restart  # audioserver bringing it back into running state.  start vendor.audio-hal  start vendor.audio-hal-aidl  start vendor.audio-effect-hal-aidl  start vendor.audio-hal-4-0-msd  start audio_proxy_service  
?  
on property:init.svc.audioserver=running && property:vts.native_server.on=1  # See b/378773354. To ensure the audioserver disable when  # running test suite, this would cover the double start  # request from init that caused test flaky.  stop audioserver  
?  
on property:init.svc.audioserver=running  start vendor.audio-hal  start vendor.audio-hal-aidl  start vendor.audio-effect-hal-aidl  start vendor.audio-hal-4-0-msd  start audio_proxy_service  
?  
on property:sys.audio.restart.hal=1  # See b/159966243. Avoid restart loop between audioserver and HAL.  # Keep the original service names for backward compatibility  stop vendor.audio-hal  stop vendor.audio-hal-aidl  stop vendor.audio-effect-hal-aidl  stop vendor.audio-hal-4-0-msd  stop audio_proxy_service  start vendor.audio-hal  start vendor.audio-hal-aidl  start vendor.audio-effect-hal-aidl  start vendor.audio-hal-4-0-msd  start audio_proxy_service  # reset the property  setprop sys.audio.restart.hal 0  on init  mkdir /dev/socket/audioserver 0775 audioserver audioserver
  1. 服務定義

    service audioserver /system/bin/audioserver

    class core

    user audioserver

    • 定義了 audioserver 服務的啟動路徑 /system/bin/audioserver

    • class core 表示該服務屬于核心服務類。

    • user audioserver 指定該服務以 audioserver 用戶身份運行,確保權限隔離。

  2. 權限組

    group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock

    • 指定了服務所屬的權限組,允許它訪問音頻設備、攝像頭、藍牙功能、網絡帶寬計費等資源。
  3. 能力與資源限制

    capabilities BLOCK_SUSPEND

    rlimit rtprio 10 10

    ioprio rt 4

    task_profiles ProcessCapacityHigh HighPerformance

    • BLOCK_SUSPEND:允許服務阻止設備進入休眠狀態。

    • rlimit rtprioioprio rt:設置實時優先級和 I/O 優先級,確保服務在處理音頻任務時具有較高的性能。

    • task_profiles:定義任務性能配置文件,優化服務的運行效率。

  4. 重啟行為

    onrestart restart vendor.audio-hal

    onrestart restart vendor.audio-hal-aidl

    onrestart restart vendor.audio-effect-hal-aidl

    onrestart restart vendor.audio-hal-4-0-msd

    onrestart restart audio_proxy_service

    • audioserver 服務重啟時,相關的音頻 HAL(硬件抽象層)服務也會被重啟,確保音頻功能的正常運行。
  5. 屬性觸發器

    on property:vts.native_server.on=1

    stop audioserver

    on property:vts.native_server.on=0

    start audioserver

    • 根據系統屬性 vts.native_server.on 的值,控制 audioserver 的啟動或停止。這通常用于測試場景。
  6. 停止與啟動邏輯

    on property:init.svc.audioserver=stopped

    stop vendor.audio-hal

    stop vendor.audio-hal-aidl

    stop vendor.audio-effect-hal-aidl

    stop vendor.audio-hal-4-0-msd

    stop audio_proxy_service

    start vendor.audio-hal

    start vendor.audio-hal-aidl

    start vendor.audio-effect-hal-aidl

    start vendor.audio-hal-4-0-msd

    start audio_proxy_service

    • audioserver 停止時,相關 HAL 服務也會停止并重新啟動,確保系統的穩定性。
  7. 初始化行為

    on init

    mkdir /dev/socket/audioserver 0775 audioserver audioserver

    • 在系統初始化時,創建 /dev/socket/audioserver 目錄,并設置權限和所有者。

1.2.AudioServer啟動流程

  • audioserver服務通過/system/bin/audioserver可執行文件啟動,核心邏輯在main_audioserver.cppmain函數中,流程如下:

    1. 內存限制與信號處理
    • limitProcessMemory:通過audio.maxmem屬性或默認值(512MB)限制進程最大內存,避免音頻服務過度占用資源。

    • signal(SIGPIPE, SIG_IGN):忽略管道斷裂信號(避免音頻流中斷時進程異常退出)。

    2. 進程分叉
    • 父進程:運行media.log日志服務,監控子進程狀態并輸出資源使用日志。

    • 子進程:執行音頻服務初始化(核心流程),并通過prctl設置父進程死亡時自毀(避免孤兒進程)。

    3. 線程池初始化
    • configureRpcThreadpool(4, false):初始化 HIDL RPC 線程池(4 個線程),用于與音頻 HAL(硬件抽象層)進行跨進程通信(HAL 通常運行在獨立進程)。

    • ProcessState::self()->startThreadPool():啟動 Binder 線程池,處理應用層或其他服務通過 Binder IPC 發起的音頻請求(如播放、錄音)。

    4. 核心服務創建與注冊
    • 創建服務實例

      • sp<AudioFlinger>::make():創建AudioFlinger實例(負責音頻硬件管理、混音、音量控制等核心功能)。

      • sp<AudioPolicyService>::make():創建AudioPolicyService實例(負責音頻策略決策,如音量策略、設備切換邏輯)。

    • 注冊服務

      1. 本地注冊:通過AudioSystem::setLocalAudioFlingersetLocalAudioPolicyService將實例注冊到進程內(供本地調用)。

      2. 系統服務注冊:通過IServiceManager::addService將實例注冊到系統服務管理器(servicemanager),供跨進程調用(服務名稱分別為IAudioFlingerAudioPolicyService)。

    5. AAudioService 初始化(低延遲音頻)
    • 查詢系統 MMAP 策略(

      AudioSystem::getMmapPolicyInfos

      若策略為AUTO\ALWAYS(允許內存映射),則初始化AAudioService

      • AAudioService是 Android O 引入的低延遲音頻服務,基于 MMAP(內存映射)機制,支持實時音頻流(如游戲音效、樂器應用),僅在策略允許時啟動。
    6. 完成初始化并進入線程池
    • 記錄初始化耗時(startupFinished),通過IPCThreadState::self()->joinThreadPool()進入 Binder 線程池,等待并處理外部音頻請求。

frameworks/av/media/audioserver/main_audioserver.cpp

 int main(int argc __unused, char **argv)  {  const auto startTime = std::chrono::steady_clock::now();  limitProcessMemory(  "audio.maxmem", /* "ro.audio.maxmem", property that defines limit */  (size_t)512 * (1 << 20), /* SIZE_MAX, upper limit in bytes */  20 /* upper limit as percentage of physical RAM */);  ?  signal(SIGPIPE, SIG_IGN);  ?  #if 1  const bool doLog = false;  #else  bool doLog = (bool) property_get_bool("ro.test_harness", 0);  #endif  pid_t childPid;  if (doLog && (childPid = fork()) != 0) {  strcpy(argv[0], "media.log");  sp<ProcessState> proc(ProcessState::self());  MediaLogService::instantiate();  ProcessState::self()->startThreadPool();  IPCThreadState::self()->joinThreadPool();  for (;;) {  siginfo_t info;  int ret = TEMP_FAILURE_RETRY(waitid(P_PID, childPid, &info,  WEXITED | WSTOPPED | WCONTINUED));  if (ret < 0) {  break;  }  char buffer[32];  const char *code;  struct rusage usage;  getrusage(RUSAGE_CHILDREN, &usage);  ALOG(LOG_ERROR, "media.log", "pid %d status %d code %s user %ld.%03lds sys %ld.%03lds",  info.si_pid, info.si_status, code,  usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000,  usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000);  sp<IServiceManager> sm = defaultServiceManager();  sp<IBinder> binder = sm->getService(String16("media.log"));  if (binder != 0) {  Vector<String16> args;  binder->dump(-1, args);  }  switch (info.si_code) {  case CLD_EXITED:  case CLD_KILLED:  case CLD_DUMPED: {  ALOG(LOG_INFO, "media.log", "exiting");  _exit(0);  // not reached  }  default:  break;  }  }  } else {  // all other services  if (doLog) {  prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also  setpgid(0, 0);                      // but if I die first, don't kill my parent  }  android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);  ProcessState::self()->startThreadPool();  const auto af = sp<AudioFlinger>::make();  const auto afAdapter = sp<AudioFlingerServerAdapter>::make(af);  ALOGD("%s: AudioFlinger created", __func__);  ALOGW_IF(AudioSystem::setLocalAudioFlinger(af) != OK,  "%s: AudioSystem already has an AudioFlinger instance!", __func__);  const auto aps = sp<AudioPolicyService>::make();  af->initAudioPolicyLocal(aps);  ALOGD("%s: AudioPolicy created", __func__);  ALOGW_IF(AudioSystem::setLocalAudioPolicyService(aps) != OK,  "%s: AudioSystem already has an AudioPolicyService instance!", __func__);  ?  // Start initialization of internally managed audio objects such as Device Effects.  aps->onAudioSystemReady();  ?  // Add AudioFlinger and AudioPolicy to ServiceManager.  sp<IServiceManager> sm = defaultServiceManager();  sm->addService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME), afAdapter,  false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);  sm->addService(String16(AudioPolicyService::getServiceName()), aps,  false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);  std::vector<AudioMMapPolicyInfo> policyInfos;  status_t status = AudioSystem::getMmapPolicyInfos(  AudioMMapPolicyType::DEFAULT, &policyInfos);  if (status == NO_ERROR &&  std::any_of(policyInfos.begin(), policyInfos.end(), [](const auto& info) {  return info.mmapPolicy == AudioMMapPolicy::AUTO ||  info.mmapPolicy == AudioMMapPolicy::ALWAYS;  })) {  AAudioService::instantiate();  } else {  ALOGD("%s: Do not init aaudio service, status %d, policy info size %zu",  __func__, status, policyInfos.size());  }  const auto endTime = std::chrono::steady_clock::now();  af->startupFinished();  using FloatMillis = std::chrono::duration<float, std::milli>;  const float timeTaken = std::chrono::duration_cast<FloatMillis>(  endTime - startTime).count();  ALOGI("%s: initialization done in %.3f ms, joining thread pool", __func__, timeTaken);  IPCThreadState::self()->joinThreadPool();  }  }  

?

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

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

相關文章

OSPF 協議(多區域)

1. OSPF 單區域存在的問題① LSDB龐大&#xff0c;占用內存大&#xff0c;SPF計算開銷大&#xff1b;② LSA洪泛范圍大&#xff0c;拓撲變化影響范圍大&#xff1b;③ 路由不能被匯總&#xff0c;路由表龐大&#xff0c;查找路由開銷大。2. OSPF 多區域優點① 每個區域獨立存儲…

R 語言繪制六種精美熱圖:轉錄組數據可視化實踐(基于 pheatmap 包)

在轉錄組 Bulk 測序數據分析中&#xff0c;熱圖是展示基因表達模式、樣本聚類關系的核心可視化工具。一張高質量的熱圖不僅能清晰呈現數據特征&#xff0c;更能提升研究成果的展示效果。本文基于 R 語言的pheatmap包&#xff0c;整理了六種適用于不同場景的熱圖繪制方法&#x…

圖片PDF識別工具:掃描PDF文件批量OCR區域圖識別改名,識別大量PDF區域內容一次性改名

以下是使用“咕嘎批量OCR識別圖片PDF多區域內容重命名導出表格系統”進行操作的具體步驟&#xff1a;1. 打開工具并獲取區域坐標打開軟件后&#xff0c;選擇“PDF識別模式”。導入一個PDF文件作為樣本&#xff0c;框選需要提取文字的區域&#xff0c;并保存區域坐標。如果有多個…

中國汽車能源消耗量(2010-2024年)

1419中國汽車能源消耗量&#xff08;2010-2024年&#xff09;發文主題分布數據來源中華人民共和國工業和信息化部-中國汽車能源消耗量查詢中國汽車能源消耗量查詢 (miit.gov.cn)時間跨度2010-2024年數據范圍全國汽車企業數據指標本數據集包含包含傳統汽車能源消耗量數據以及新能…

Python 實現服務器自動故障處理工具:從監控到自愈的完整方案

在服務器運維過程中,80% 的故障都是重復性的簡單問題(如磁盤空間不足、內存泄漏、服務進程掛掉等)。本文將介紹如何使用 Python 開發一款輕量級自動故障處理工具,通過狀態監控、異常診斷、自動修復三個核心模塊,實現服務器常見故障的無人值守處理。 核心依賴庫 psutil:跨…

圖片上傳 el+node后端+數據庫

模版部分&#xff1a;鼠標懸浮到頭像的部分就出現下拉框顯示可以修改頭像&#xff0c;el-upload是隱藏的&#xff0c;可能只是為了實現on-change函數和before-upload函數吧這塊做的確實有點馬虎了。<div class"r-content"><el-dropdown><span class&q…

[java 常用類API] 新手小白的編程字典

目錄 1.API 1.1定義: 2.Object類 2.1 toString() 方法 2.2 equals() 方法 3. Arrays 類 3.1 equals() 方法 3.2 sort() 方法 3.2.1排序 3.2.2 自定義對象排序 3.3 binarySearch() 方法 3.4 copyOf() 方法 3.5 fill() 方法 3.6 toString() 方法 4.基本數據類型包裝類 4.…

去除視頻字幕 2, 使用 PaddleOCR 選取圖片中的字幕區域, 根據像素大小 + 形狀輪廓

有人問我在搞什么&#xff1a;就是做這里的第2步。問題描述這里誤導&#xff0c;誤判&#xff0c;太嚴重了。如果我把這個區域當做是 mask ,那么真正的目標會被去除掉還有什么建議嗎&#xff1f;比如我能否根據這個mask 的大致形狀來判斷它是不是字幕&#xff0c; 如果不是細長…

Ubuntu 連接Visual SVN

Windows服務器上的svn倉庫為&#xff1a; https://ldw_online:8443/svn/OnlineRepository/LVC IP地址為192.168.8.8 4. 從 Ubuntu 測試連通性 在 Ubuntu 上可以用&#xff1a; bash 復制編輯 curl -vk https://192.168.8.8:8443/ 如果返回 HTTP 頭或 SSL 握手成功&#xff…

JAVA:Spring Boot 集成 Protobuf 的技術指南

?? 1、簡述 在分布式服務通信中,數據序列化與反序列化的效率對系統性能影響極大。Protocol Buffers(Protobuf) 是由 Google 提出的一種高效的結構化數據序列化協議,具有: ?? 高性能(遠優于 JSON/XML) ?? 跨語言支持 ?? 較小的體積 本篇將帶你了解如何在 Spring…

SQLServer內存釋放工具介紹:一款實用的數據庫性能優化助手

SQLServer內存釋放工具介紹&#xff1a;一款實用的數據庫性能優化助手 去發現同類優質開源項目:https://gitcode.com/ 在數據庫管理中&#xff0c;內存釋放是優化服務器性能的重要環節。本文將為您詳細介紹一款名為SQLServer內存釋放工具的開源項目&#xff0c;幫助您輕松管理…

《藍耘容器全棧技術指南:企業級云原生與異構計算實戰大全》

&#x1f31f; 嗨&#xff0c;我是Lethehong&#xff01;&#x1f31f; &#x1f30d; 立志在堅不欲說&#xff0c;成功在久不在速&#x1f30d; &#x1f680; 歡迎關注&#xff1a;&#x1f44d;點贊??留言收藏&#x1f680; &#x1f340;歡迎使用&#xff1a;小智初學計…

計算器3.0:實現用戶自定義組件

前言&#xff1a; 馬總給我提出計算器3.0新需求&#xff1a;可以在頁面上輸入一個組件&#xff0c;用戶的組件庫里面就多一個組件&#xff0c;用戶就可以使用 一、解決方法&#xff1a; 1. 新增成員變量和初始化 // 新增的輸入框 private InputBox newInputBox; // 新增的組…

PIG AI 全新升級:全新 MCP 能力加持,讓企業級 AI 開發效率翻倍!

你是否曾為 AI 應用的開發門檻而頭疼?調試代碼耗費數小時、集成外部工具需要復雜配置、想要快速構建智能系統卻不知從何下手…別擔心!PIG AI 最新版本帶來的 MCP(Model Context Protocol)能力,正為這些問題提供一站式解決方案。本文將帶你深入淺出地了解這一重磅升級,手把…

Springboot+vue超市管理系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot前端框架Vue持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續…

一文快速了解Docker和命令詳解

本文讓你快速了解Docker是什么的東西&#xff0c;在我們程序開發的時候到底有什么作用&#xff0c;為什么需要去學習它。本文章只是做一個簡單的概述配套黑馬課程讓你快速了解、使用Docker。 一、什么是Docker&#xff1f; Docker是一個開源的容器化平臺&#xff0c;允許開發者…

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件 背景 GaussDB 從505和506版本起&#xff08;前面的版本不清楚&#xff09;&#xff0c;華為官方不再提供用腳本安裝GaussDB的方式&#xff08;應該是基于運維交付標準化的角度考慮&#xff09;&#xff0c;僅支持使用T…

ETH 交易流程深度技術詳解

概述在前面對 PolkaVM 和 Revive 的文章中&#xff0c;我們介紹了很多技術細節&#xff0c;開發工具。還對比 EVM&#xff0c;知道了 PolkaVM 的優勢。很多同學還是對 Polkadot SDK 為什么可以運行 EVM 兼容的智能合約&#xff0c;以及交易處理的整個流程不太清楚。這篇文章將會…

【算法訓練營Day17】二叉樹part7

文章目錄二叉樹的最近公共祖先二叉搜索樹的最近公共祖先二叉搜索樹中的插入操作刪除二叉搜索樹中的節點二叉樹的最近公共祖先 題目鏈接&#xff1a;236. 二叉樹的最近公共祖先 解題邏輯&#xff1a; 最近公共祖先的定義為&#xff1a;對于有根樹 T 的兩個節點 p、q&#xff0c…

Vue插件與組件核心區別詳解

在 Vue 中&#xff0c;插件&#xff08;Plugin&#xff09; 和 組件&#xff08;Component&#xff09; 是兩種不同層次的概念&#xff0c;它們的主要區別如下&#xff1a;1. 組件 (Component) 定義&#xff1a; Vue 應用的基本構建單元&#xff0c;是可復用的 Vue 實例&#x…