最近遇到一个问题, 就是不知道audioFlinger 在选择hal 的时候是怎么选择的, 为什么选择的是vendor 的audio hal 而不是default 的?

本文急于5.1 的代码。

audioflinger 什么时候会去打开audio hal 的so, 5.1版本的不是初始化audioflinger 时就去选择。会在openoutput 时找hw 时去选择,如果已有就不需要找,第一次就要找, 看下面代码

status_t AudioFlinger::openOutput(audio_module_handle_t module,audio_io_handle_t *output,audio_config_t *config,audio_devices_t *devices,const String8& address,uint32_t *latencyMs,audio_output_flags_t flags)
{ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",module,(devices != NULL) ? *devices : 0,config->sample_rate,config->format,config->channel_mask,flags);if (*devices == AUDIO_DEVICE_NONE) {return BAD_VALUE;}Mutex::Autolock _l(mLock);sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);if (thread != 0) {
sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,audio_io_handle_t *output,audio_config_t *config,audio_devices_t devices,const String8& address,audio_output_flags_t flags)
{AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);if (outHwDev == NULL) {return 0;}
AudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module,audio_devices_t devices)
{// if module is 0, the request comes from an old policy manager and we should load// well known modulesif (module == 0) {ALOGW("findSuitableHwDev_l() loading well know audio hw modules");for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {loadHwModule_l(audio_interfaces[i]);}// then try to find a module supporting the requested device.for (size_t i = 0; i < mAudioHwDevs.size(); i++) {AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);audio_hw_device_t *dev = audioHwDevice->hwDevice();if ((dev->get_supported_devices != NULL) &&(dev->get_supported_devices(dev) & devices) == devices)return audioHwDevice;
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{for (size_t i = 0; i < mAudioHwDevs.size(); i++) {if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {ALOGW("loadHwModule() module %s already loaded", name);return mAudioHwDevs.keyAt(i);}}audio_hw_device_t *dev;int rc = load_audio_interface(name, &dev);if (rc) {ALOGI("loadHwModule() error %d loading module %s ", rc, name);return 0;}
static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{const hw_module_t *mod;int rc;rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));if (rc) {goto out;}
int hw_get_module_by_class(const char *class_id, const char *inst,const struct hw_module_t **module)
{int i;char prop[PATH_MAX];char path[PATH_MAX];char name[PATH_MAX];char prop_name[PATH_MAX];if (inst)snprintf(name, PATH_MAX, "%s.%s", class_id, inst);elsestrlcpy(name, class_id, PATH_MAX);/** Here we rely on the fact that calling dlopen multiple times on* the same .so will simply increment a refcount (and not load* a new copy of the library).* We also assume that dlopen() is thread-safe.*//* First try a property specific to the class and possibly instance */snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);if (property_get(prop_name, prop, NULL) > 0) {                  //这里会找出cpu 厂商对cpu型号的命名if (hw_module_exists(path, sizeof(path), name, prop) == 0) {// 合理会去找对应的so 是否存在, 如果存在就跳到foundgoto found;}}/* Loop through the configuration variants looking for a module */for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {if (property_get(variant_keys[i], prop, NULL) == 0) {continue;}if (hw_module_exists(path, sizeof(path), name, prop) == 0) {goto found;}}/* Nothing found, try the default */if (hw_module_exists(path, sizeof(path), name, "default") == 0) { //找不到厂商的, 就会去找default 的sogoto found;}return -ENOENT;found:/* load the module, if this fails, we're doomed, and we should not try* to load a different variant. */return load(class_id, path, module);
}
static int hw_module_exists(char *path, size_t path_len, const char *name,const char *subname)
{snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH2, name, subname);if (access(path, R_OK) == 0)return 0;snprintf(path, path_len, "%s/%s.%s.so",HAL_LIBRARY_PATH1, name, subname);if (access(path, R_OK) == 0)return 0;return -ENOENT;
}

所有的玄机都在函数 hw_get_module_by_class, 在这个函数,会先去找目录/vendor/lib, 64bit 是/vendor/64lib/ 目录下的so, 然后再去找/system/lib, 同样64bit 找/system/64lib 下的so, 先找vendor 的so,找不到就会找default的so, 一般是system/lib/audio.primary.default.so

android 怎么选择audio hal相关推荐

  1. Android底层开发之Audio HAL Android Audio Overview

    http://blog.csdn.net/kangear/article/details/44939429 Android底层开发之Audio HAL 在Android音频底层调试-基于tinyals ...

  2. Android音频驱动学习(一) Audio HAL

    Hal加载过程 加载audio hal需要分三步 1.hw_get_module_by_class :加载hal module 2.audio_hw_device_open:调用audio devic ...

  3. Android底层开发之Audio HAL

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Andr ...

  4. Android Audio HAL 接口介绍之 adev_set_parameters()和out_set_parameters()

    前言 这几天一直再解决BUG,是两个usease同时存在的场景,插入耳机来实现音频切换的问题.有Recroding+HFP_Call场景,有两个Recording同时存在的场景.当插入有线耳机后,音频 ...

  5. Android 8.1 Audio框架(二)AudioPolicy路由策略实例分析

    概述 这里以蓝牙耳机连接手机这一场景为例分析Audio路由策略是如何进行设备切换和管理输出的.蓝牙耳机连接上Android系统后,AudioService的handleDeviceConnection ...

  6. mtk+android+之mt6577驱动笔记,MTK6577+Android之音频(audio)移植

    MTK6577+Android之音频(audio)移植 备注:audio PA音频功放(power amplifier) 先借用<Y1MT6577 design notice V0.1>关 ...

  7. Android 7.0 Audio的Resample过程详解

    Android 7.0 Audio的Resample过程详解 Qidi 2017.02.23 (Markdown & Haroopad) [前言] 处理过音频文件的工程师都知道音频数据存在采样 ...

  8. Android : Camera之camx hal架构

    sheldon_blogs https://www.cnblogs.com/blogs-of-lxl/p/10668554.html Android : Camera之camx hal架构 一.cam ...

  9. Audio HAL 提供的操作

    Audio HAL 操作接口 Audio HAL 本身主要包括接口服务层,和硬件模块层.接口服务层的接口一般在 HIDL 文件中定义,代码通过工具自动生成.接口服务层封装了硬件模块层,它们提供的操作最 ...

  10. Android N的Audio系统(五)

    AudioFlinger 回放录制线程 AndioFlinger 作为 Android 的音频系统引擎,重任之一是负责输入输出流设备的管理及音频流数据的处理传输,这是由回放线程(PlaybackThr ...

最新文章

  1. Redis源码解析——Zipmap
  2. PgSQL · 实战经验 · 如何预测Freeze IO风暴
  3. [CSAcademy]A-Game
  4. leetcode算法题--树的子结构
  5. RocketMQ--生产者与消费者的简单示例
  6. SpringAMQP--WorkQueue模型
  7. 15年大厂经历!大佬总结:0基础如何学习Python?
  8. vs设计窗口不见了_龙猫腕表评测:VS沛纳海320V2版本
  9. win10树莓派改ip_在树莓派2上安装 Windows 10
  10. c语言按位取反 补码,按位取反运算符,数值取反之后是反码,还是补码- -
  11. android style 与theme的区别
  12. Apache Commons CLI 开发命令行工具示例
  13. 长大了还不如小时候那么能够坚持了
  14. 黑苹果日记六(双系统引导)
  15. mysql查询重复名字的数据都查出来_mysql 查询重复字段 内容
  16. android 如何读取u盘中数据恢复,U盘数据恢复
  17. MyEclipse2015破解安装与使用
  18. Windows10 LTSB/LTSC 企业版安装应用商店
  19. Echarts曲线渐变色lineStyle
  20. ARC 强变量 弱变量

热门文章

  1. 禅修内观 | 一个璀璨的思想成就
  2. 如何查看一个期刊是sci几区以及影响因子 入藏号 ISSN等信息
  3. response.text 与 response.content
  4. 3D MAX 插件的基本知识和安装方法
  5. C - Reverse Polish Calculator
  6. 把数字翻译成字符串——python
  7. PyCharm设置背景颜色为白色
  8. 中央C-高低音谱号里的中央C和其它音节
  9. Vue01介绍+数据双向绑定+生命周期+什么是BootCDN+代码示例
  10. UI设计实用经验分享