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