hal: update audio patch handling in auto hal

Update audio patch in automotive HAL extension
to support device to device patch only.
Remove playback or capture patch as they are
supported at audio hw level.

Change-Id: If3cf097e4ed010548e1d3ab421611490f284157b
This commit is contained in:
Derek Chen 2020-02-26 00:30:42 -08:00
parent 5f67a9480c
commit 6c0f3de886
5 changed files with 34 additions and 166 deletions

View File

@ -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

View File

@ -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 ==================================================

View File

@ -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));
@ -257,8 +170,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 */
@ -273,31 +186,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;
}
@ -309,10 +220,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);
@ -338,42 +245,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);
@ -401,10 +272,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__);
@ -637,15 +504,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,
@ -990,6 +857,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;
}

View File

@ -10209,7 +10209,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) {

View File

@ -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,
@ -801,6 +797,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.