android 怎么选择audio hal
来源:互联网 发布:mac字体库里灰色字体 编辑:程序博客网 时间:2024/04/30 23:06
最近遇到一个问题, 就是不知道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 modules if (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); else strlcpy(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 是否存在, 如果存在就跳到found goto 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 的so goto 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
0 0
- android 怎么选择audio hal
- Android 5.1 Audio HAL分析
- Android Audio HAL層的研究
- Android底层开发之Audio HAL
- android Audio OverView之二(hal)
- 在 Android 8.0 中绕过 hwbinder 实现跨模块对 audio HAL 调用
- android中camera的hal模块怎么被调用
- Android Audio之AudioTrack和AudioFlinger怎么联系起来的?
- Android HAL
- android HAL
- android HAL
- Android Hal
- Android HAL
- Android HAL
- android hal
- Android HAL
- Android HAL
- android hal
- 韩信点兵问题
- 096 Unique Binary Search Trees [Leetcode]
- iOS 通过数字拼音快速搜索股票
- 条款09 绝不在构造和析构过程中调用 virtual 函数
- 静态方法 实例成员变量 静态成员变量 局部变量
- android 怎么选择audio hal
- Java_jdbc 基础笔记之一 数据库连接
- android开发常用网址
- 每天一个Linux命令-24(file)
- (五)在python中创建一个函数
- HDU 3001 【三进制状压DP】
- HDOJ 题目3874 Necklace(线段树+离线求区间去重和)
- kafka部署一
- redis与memcache区别