当前位置: 首页 > news >正文

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.dtcms.com/a/301763.html

相关文章:

  • Linux学习篇11——Linux软件包管理利器:RPM与YUM详解与实战指南,包含如何配置失效的YUM镜像地址
  • 【RH134 问答题】第 2 章 调度未来任务
  • 第1章 AB实验的基本原理和应用
  • 任务提醒工具怎么选?对比16款热门软件
  • Valgrind Helgrind 工具全解:线程同步的守门人
  • Linux 基础命令大全
  • LC振荡Multisim仿真
  • CPA全国青少年编程能力等级测评试卷及答案 Python编程(二级)
  • 金融市场资金波动模拟程序设计与实现
  • 文件IO——目录操作
  • 大模型蒸馏理论概述
  • 【分布式存储】聊聊一致性哈希算法原理和实现
  • Linux图片元数据提取完全指南:从基础到高级的完整教程
  • day25
  • EPOLLONESHOT 深度解析:Linux epoll 的单次触发机制
  • 单表查询-or优化
  • SpringIoCDI
  • Java 集合进阶:从 Collection 接口到迭代器的实战指南
  • AI入门学习-模型评估示例讲解
  • 解决浏览器无法删除cookie的问题
  • JavaSE知识点(2)
  • mybatis的insert(pojo),会返回pojo吗
  • 2507C++,APC可以干的活
  • Leetcode 3628. Maximum Number of Subsequences After One Inserting
  • mybatis-plus逻辑删除配置
  • 高可用集群KEEPALIVED实战解析
  • Gradio全解8——ChatInterfaceChatbot:聊天界面类与聊天机器人(2)——ChatInterface的自定义函数和界面
  • 芯片库和标准库寻找的方法
  • print(“\033[31m红\033[32m绿\033[34m蓝\033[0m默认色“)
  • 随机密码生成