Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a11cb29 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: update audio patch handling in auto hal"

parents 097325ea 6c0f3de8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5748,6 +5748,7 @@ int audio_extn_auto_hal_init(struct audio_device *adev)
        auto_hal_init_config.fp_adev_get_active_input = adev_get_active_input;
        auto_hal_init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
        auto_hal_init_config.fp_platform_get_eccarstate = platform_get_eccarstate;
        auto_hal_init_config.fp_generate_patch_handle = generate_patch_handle;
        return auto_hal_init(adev, auto_hal_init_config);
    }
    else
+2 −0
Original line number Diff line number Diff line
@@ -1346,6 +1346,7 @@ typedef streams_output_ctxt_t* (*fp_out_get_stream_t)(struct audio_device*, audi
typedef size_t (*fp_get_output_period_size_t)(uint32_t, audio_format_t, int, int);
typedef int (*fp_audio_extn_ext_hw_plugin_set_audio_gain_t)(void*, struct audio_usecase*, uint32_t);
typedef struct stream_in* (*fp_adev_get_active_input_t)(const struct audio_device*);
typedef audio_patch_handle_t (*fp_generate_patch_handle_t)(void);

typedef struct auto_hal_init_config {
    fp_in_get_stream_t                           fp_in_get_stream;
@@ -1361,6 +1362,7 @@ typedef struct auto_hal_init_config {
    fp_adev_get_active_input_t                   fp_adev_get_active_input;
    fp_platform_set_echo_reference_t             fp_platform_set_echo_reference;
    fp_platform_get_eccarstate_t                 fp_platform_get_eccarstate;
    fp_generate_patch_handle_t                   fp_generate_patch_handle;
} auto_hal_init_config_t;
// END: AUTO_HAL FEATURE ==================================================

+28 −160
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ static fp_disable_snd_device_t fp_disable_snd_device;
static fp_adev_get_active_input_t                   fp_adev_get_active_input;
static fp_platform_set_echo_reference_t             fp_platform_set_echo_reference;
static fp_platform_get_eccarstate_t                 fp_platform_get_eccarstate;
static fp_generate_patch_handle_t                   fp_generate_patch_handle;

/* Auto hal module struct */
static struct auto_hal_module *auto_hal = NULL;
@@ -91,14 +92,9 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev,
{
    struct audio_device *adev = (struct audio_device *)dev;
    int ret = 0;
    char *str = NULL;
    struct str_parms *parms = NULL;
    char *address = NULL;
    struct audio_usecase *uc_info = NULL;
    struct audio_patch_record *patch_record = NULL;
    audio_usecase_t usecase = USECASE_INVALID;
    audio_io_handle_t input_io_handle = AUDIO_IO_HANDLE_NONE;
    audio_io_handle_t output_io_handle = AUDIO_IO_HANDLE_NONE;

    ALOGV("%s: enter", __func__);

@@ -115,17 +111,6 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev,
         return -EINVAL;
    }

    /* Release patch if valid handle */
    if (*handle != AUDIO_PATCH_HANDLE_NONE) {
        ret = auto_hal_release_audio_patch(dev,
                        *handle);
        if (ret) {
            ALOGE("%s: failed to release audio patch 0x%x", __func__, *handle);
            return ret;
        }
        *handle = AUDIO_PATCH_HANDLE_NONE;
    }

    /* No validation on num of sources and sinks to allow patch with
     * multiple sinks being created, but only the first source and
     * sink are used to create patch.
@@ -138,84 +123,12 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev,
     *   Playback: MIX -> DEVICE
     * For DEVICE -> DEVICE patch type, it refers to routing from/to external
     * codec/amplifier and allow Android streams to be mixed at the H/W level.
     *
     * Auto extension here is to act on Device to Device patch only as playback
     * and capture patches as well as the book-keeeping information are already
     * being handled at audio_hw entry.
     */
    if ((sources->type == AUDIO_PORT_TYPE_DEVICE) &&
        (sinks->type == AUDIO_PORT_TYPE_MIX)) {
        pthread_mutex_lock(&adev->lock);
        streams_input_ctxt_t *in_ctxt = fp_in_get_stream(adev,
                        sinks->ext.mix.handle);
        if (!in_ctxt) {
            ALOGE("%s, failed to find input stream", __func__);
            ret = -EINVAL;
        }
        pthread_mutex_unlock(&adev->lock);
        if(ret)
            return ret;
        input_io_handle = sinks->ext.mix.handle;

        if (strcmp(sources->ext.device.address, "") != 0) {
            address = audio_device_address_to_parameter(
                                                sources->ext.device.type,
                                                sources->ext.device.address);
        } else {
            address = (char *)calloc(1, 1);
        }
        if (address == NULL) {
            ALOGE("%s: failed to get address",__func__);
            ret = -EFAULT;
            goto exit;
        }
        parms = str_parms_create_str(address);
        if (!parms) {
            ALOGE("%s: failed to allocate mem for parms", __func__);
            ret = -ENOMEM;
            goto exit;
        }
        str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING,
                        (int)sources->ext.device.type);
        str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE,
                        (int)sinks->ext.mix.usecase.source);
        str = str_parms_to_str(parms);
        in_ctxt->input->stream.common.set_parameters(
                        (struct audio_stream *)in_ctxt->input, str);
    } else if ((sources->type == AUDIO_PORT_TYPE_MIX) &&
            (sinks->type == AUDIO_PORT_TYPE_DEVICE)) {
        pthread_mutex_lock(&adev->lock);
        streams_output_ctxt_t *out_ctxt = fp_out_get_stream(adev,
            sources->ext.mix.handle);
        if (!out_ctxt) {
            ALOGE("%s, failed to find output stream", __func__);
            ret = -EINVAL;
        }
        pthread_mutex_unlock(&adev->lock);
        if(ret)
            return ret;
        output_io_handle = sources->ext.mix.handle;

        if (strcmp(sinks->ext.device.address, "") != 0) {
            address = audio_device_address_to_parameter(
                                                sinks->ext.device.type,
                                                sinks->ext.device.address);
        } else {
            address = (char *)calloc(1, 1);
        }
        if (address == NULL) {
            ALOGE("%s: failed to get address",__func__);
            ret = -EFAULT;
            goto exit;
        }
        parms = str_parms_create_str(address);
        if (!parms) {
            ALOGE("%s: failed to allocate mem for parms", __func__);
            ret = -ENOMEM;
            goto exit;
        }
        str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING,
                        (int)sinks->ext.device.type);
        str = str_parms_to_str(parms);
        out_ctxt->output->stream.common.set_parameters(
                        (struct audio_stream *)out_ctxt->output, str);
    } else if ((sources->type == AUDIO_PORT_TYPE_DEVICE) &&
            (sinks->type == AUDIO_PORT_TYPE_DEVICE)) {
        /* allocate use case and call to plugin driver*/
        uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
@@ -258,8 +171,8 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev,
        list_add_tail(&adev->usecase_list, &uc_info->list);
        pthread_mutex_unlock(&adev->lock);
    } else {
        ALOGW("%s: audio patch not supported",__func__);
        return -EINVAL;
        ALOGV("%s: audio patch not supported", __func__);
        goto exit;
    }

    /* patch created success, add to patch record list */
@@ -274,31 +187,29 @@ int auto_hal_create_audio_patch(struct audio_hw_device *dev,
    }

    pthread_mutex_lock(&adev->lock);
    adev->audio_patch_index++;
    patch_record->handle = adev->audio_patch_index;
    if (*handle == AUDIO_PATCH_HANDLE_NONE) {
        ALOGD("%s: audio patch handle not allocated 0x%x", __func__, *handle);
        *handle = fp_generate_patch_handle();
    }
    patch_record->handle = *handle;
    patch_record->usecase = usecase;
    patch_record->input_io_handle = input_io_handle;
    patch_record->output_io_handle = output_io_handle;
    memcpy((void *)&patch_record->source, (void *)sources,
        sizeof(struct audio_port_config));
    memcpy((void *)&patch_record->sink, (void *)sinks,
        sizeof(struct audio_port_config));
    patch_record->patch.id = *handle;
    patch_record->patch.num_sources = num_sources;
    patch_record->patch.num_sinks = num_sinks;
    for (int i = 0; i < num_sources; i++)
        patch_record->patch.sources[i] = sources[i];
    for (int i = 0; i < num_sinks; i++)
        patch_record->patch.sinks[i] = sinks[i];

    list_add_tail(&adev->audio_patch_record_list, &patch_record->list);
    pthread_mutex_unlock(&adev->lock);

    *handle = patch_record->handle;
    goto exit;

error:
    if(uc_info)
        free(uc_info);
exit:
    if (parms)
        str_parms_destroy(parms);
    if (str)
        free(str);
    if (address)
        free(address);
    ALOGV("%s: exit: handle 0x%x", __func__, *handle);
    return ret;
}
@@ -310,10 +221,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev,
    struct audio_device *adev = (struct audio_device *)dev;
    struct audio_usecase *uc_info = NULL;
    struct audio_patch_record *patch_record = NULL;
    streams_input_ctxt_t *in_ctxt = NULL;
    streams_output_ctxt_t *out_ctxt = NULL;
    char *str = NULL;
    struct str_parms *parms = NULL;

    ALOGV("%s: enter: handle 0x%x", __func__, handle);

@@ -339,42 +246,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev,
    if(ret)
        goto exit;

    if (patch_record->input_io_handle) {
        pthread_mutex_lock(&adev->lock);
        in_ctxt = fp_in_get_stream(adev, patch_record->input_io_handle);
        if (!in_ctxt) {
            ALOGE("%s, Could not find input stream", __func__);
            ret = -EINVAL;
        }
        pthread_mutex_unlock(&adev->lock);
        if(ret)
            goto exit;

        parms = str_parms_create();
        str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, 0);
        str = str_parms_to_str(parms);
        in_ctxt->input->stream.common.set_parameters(
                        (struct audio_stream *)in_ctxt->input, str);
    }

    if (patch_record->output_io_handle) {
        pthread_mutex_lock(&adev->lock);
        out_ctxt = fp_out_get_stream(adev, patch_record->output_io_handle);
        if (!out_ctxt) {
            ALOGE("%s, Could not find output stream", __func__);
            ret = -EINVAL;
        }
        pthread_mutex_unlock(&adev->lock);
        if(ret)
            goto exit;

        parms = str_parms_create();
        str_parms_add_int(parms, AUDIO_PARAMETER_STREAM_ROUTING, 0);
        str = str_parms_to_str(parms);
        out_ctxt->output->stream.common.set_parameters(
                        (struct audio_stream *)out_ctxt->output, str);
    }

    if (patch_record->usecase != USECASE_INVALID) {
        pthread_mutex_lock(&adev->lock);
        uc_info = fp_get_usecase_from_list(adev, patch_record->usecase);
@@ -402,10 +273,6 @@ int auto_hal_release_audio_patch(struct audio_hw_device *dev,
    list_remove(&patch_record->list);
    pthread_mutex_unlock(&adev->lock);
    free(patch_record);
    if (parms)
        str_parms_destroy(parms);
    if (str)
        free(str);

exit:
    ALOGV("%s: exit", __func__);
@@ -638,15 +505,15 @@ int auto_hal_set_audio_port_config(struct audio_hw_device *dev,
                                                    struct audio_patch_record,
                                                    list);
                /* limit audio gain support for device -> bus device patch */
                if (patch_record->source.type == AUDIO_PORT_TYPE_DEVICE &&
                    patch_record->sink.type == AUDIO_PORT_TYPE_DEVICE &&
                    patch_record->sink.role == AUDIO_PORT_ROLE_SINK &&
                    patch_record->sink.ext.device.type == AUDIO_DEVICE_OUT_BUS &&
                    patch_record->sink.ext.device.type == config->ext.device.type &&
                    strcmp(patch_record->sink.ext.device.address,
                if (patch_record->patch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
                    patch_record->patch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
                    patch_record->patch.sinks[0].role == AUDIO_PORT_ROLE_SINK &&
                    patch_record->patch.sinks[0].ext.device.type == AUDIO_DEVICE_OUT_BUS &&
                    patch_record->patch.sinks[0].ext.device.type == config->ext.device.type &&
                    strcmp(patch_record->patch.sinks[0].ext.device.address,
                        config->ext.device.address) == 0) {
                    /* cache audio port configuration for sink */
                    memcpy((void *)&patch_record->sink, (void *)config,
                    memcpy((void *)&patch_record->patch.sinks[0], (void *)config,
                        sizeof(struct audio_port_config));

                    struct audio_usecase *uc_info = fp_get_usecase_from_list(adev,
@@ -992,6 +859,7 @@ int auto_hal_init(struct audio_device *adev, auto_hal_init_config_t init_config)
    fp_adev_get_active_input = init_config.fp_adev_get_active_input;
    fp_platform_set_echo_reference = init_config.fp_platform_set_echo_reference;
    fp_platform_get_eccarstate = init_config.fp_platform_get_eccarstate;
    fp_generate_patch_handle = init_config.fp_generate_patch_handle;

    return ret;
}
+0 −1
Original line number Diff line number Diff line
@@ -10228,7 +10228,6 @@ static int adev_open(const hw_module_t *module, const char *name,
    list_init(&adev->active_inputs_list);
    list_init(&adev->active_outputs_list);
    list_init(&adev->audio_patch_record_list);
    adev->audio_patch_index = 0;
    adev->io_streams_map = hashmapCreate(AUDIO_IO_PORTS_MAX, audio_extn_utils_hash_fn,
                                         audio_extn_utils_hash_eq);
    if (!adev->io_streams_map) {
+3 −5
Original line number Diff line number Diff line
@@ -715,7 +715,6 @@ struct audio_device {
    int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
    bool adm_routing_changed;
    struct listnode audio_patch_record_list;
    unsigned int audio_patch_index;
    Hashmap *patch_map;
    Hashmap *io_streams_map;
};
@@ -724,10 +723,7 @@ struct audio_patch_record {
    struct listnode list;
    audio_patch_handle_t handle;
    audio_usecase_t usecase;
    audio_io_handle_t input_io_handle;
    audio_io_handle_t output_io_handle;
    struct audio_port_config source;
    struct audio_port_config sink;
    struct audio_patch patch;
};

int select_devices(struct audio_device *adev,
@@ -816,6 +812,8 @@ int route_input_stream(struct stream_in *stream,
                       struct listnode *devices,
                       audio_source_t source);

audio_patch_handle_t generate_patch_handle();

/*
 * NOTE: when multiple mutexes have to be acquired, always take the
 * stream_in or stream_out mutex first, followed by the audio_device mutex.