hal: add support for profile based app_type selection
Add support to use profile tag in app_type configuration.
Profile tag need to be mentioned with profile string and
same should be set to a stream using set param.
If no profile is set to the stream, matching would be done
only against app_type entries without profile tag keeping
backward compatibility.
Change-Id: I24f0b67d638517fe4f428c0d650fcc72c380faa1
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 1c5da54..0a7586c 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -103,4 +103,7 @@
#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
+/* Set or Query stream profile type */
+#define AUDIO_PARAMETER_STREAM_PROFILE "audio_stream_profile"
+
#endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 7c3f98d..d7f127a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -519,6 +519,7 @@
uint32_t sample_rate,
uint32_t bit_width,
audio_channel_mask_t channel_mask,
+ char *profile,
struct stream_app_type_cfg *app_type_cfg);
void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
struct listnode *streams_input_cfg_list,
@@ -527,6 +528,7 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
+ char *profile,
struct stream_app_type_cfg *app_type_cfg);
int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
struct audio_usecase *usecase);
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 45ea3b7..d4ffadd 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -54,6 +54,7 @@
#define DYNAMIC_VALUE_TAG "dynamic"
#define FLAGS_TAG "flags"
+#define PROFILES_TAG "profile"
#define FORMATS_TAG "formats"
#define SAMPLING_RATES_TAG "sampling_rates"
#define BIT_WIDTH_TAG "bit_width"
@@ -286,6 +287,8 @@
while (node) {
if (strcmp(node->name, FLAGS_TAG) == 0) {
s_info->flags = parse_flag_names((char *)node->value);
+ } else if (strcmp(node->name, PROFILES_TAG) == 0) {
+ strlcpy(s_info->profile, (char *)node->value, sizeof(s_info->profile));
} else if (strcmp(node->name, FORMATS_TAG) == 0) {
parse_format_names((char *)node->value, s_info);
} else if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
@@ -578,18 +581,22 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
+ char* profile,
struct stream_app_type_cfg *app_type_cfg)
{
struct listnode *node_i, *node_j;
struct streams_io_cfg *s_info;
struct stream_format *sf_info;
- ALOGV("%s: flags: 0x%x, format: 0x%x sample_rate %d",
- __func__, flags, format, sample_rate);
+ ALOGV("%s: flags: 0x%x, format: 0x%x sample_rate %d, profile %s",
+ __func__, flags, format, sample_rate, profile);
list_for_each(node_i, streams_input_cfg_list) {
s_info = node_to_item(node_i, struct streams_io_cfg, list);
- if (s_info->flags.in_flags == flags) {
+ /* Along with flags do profile matching if set at either end.*/
+ if (s_info->flags.in_flags == flags &&
+ ((profile[0] == '\0' && s_info->profile[0] == '\0') ||
+ strncmp(s_info->profile, profile, sizeof(s_info->profile)) == 0)) {
list_for_each(node_j, &s_info->format_list) {
sf_info = node_to_item(node_j, struct stream_format, list);
if (sf_info->format == format) {
@@ -613,6 +620,7 @@
uint32_t sample_rate,
uint32_t bit_width,
audio_channel_mask_t channel_mask,
+ char *profile,
struct stream_app_type_cfg *app_type_cfg)
{
struct listnode *node_i, *node_j;
@@ -661,11 +669,14 @@
__func__, sample_rate, bit_width);
}
- ALOGV("%s: flags: %x, format: %x sample_rate %d",
- __func__, flags, format, sample_rate);
+ ALOGV("%s: flags: %x, format: %x sample_rate %d, profile %s",
+ __func__, flags, format, sample_rate, profile);
list_for_each(node_i, streams_output_cfg_list) {
s_info = node_to_item(node_i, struct streams_io_cfg, list);
- if (s_info->flags.out_flags == flags) {
+ /* Along with flags do profile matching if set at either end.*/
+ if (s_info->flags.out_flags == flags &&
+ ((profile[0] == '\0' && s_info->profile[0] == '\0') ||
+ strncmp(s_info->profile, profile, sizeof(s_info->profile)) == 0)) {
list_for_each(node_j, &s_info->format_list) {
sf_info = node_to_item(node_j, struct stream_format, list);
if (sf_info->format == format) {
@@ -723,6 +734,7 @@
usecase->stream.out->sample_rate,
usecase->stream.out->bit_width,
usecase->stream.out->channel_mask,
+ usecase->stream.out->profile,
&usecase->stream.out->app_type_cfg);
ALOGV("%s Selected apptype: %d", __func__, usecase->stream.out->app_type_cfg.app_type);
break;
@@ -734,6 +746,7 @@
usecase->stream.in->format,
usecase->stream.in->sample_rate,
usecase->stream.in->bit_width,
+ usecase->stream.in->profile,
&usecase->stream.in->app_type_cfg);
ALOGV("%s Selected apptype: %d", __func__, usecase->stream.in->app_type_cfg.app_type);
break;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index fa04db9..ca5d3ad 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2671,6 +2671,20 @@
pthread_mutex_unlock(&out->lock);
}
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_PROFILE, value, sizeof(value));
+ if (err >= 0) {
+ strlcpy(out->profile, value, sizeof(out->profile));
+ ALOGV("updating stream profile with value '%s'", out->profile);
+ lock_output_stream(out);
+ audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
+ &adev->streams_output_cfg_list,
+ out->devices, out->flags, out->format,
+ out->sample_rate, out->bit_width,
+ out->channel_mask, out->profile,
+ &out->app_type_cfg);
+ pthread_mutex_unlock(&out->lock);
+ }
+
str_parms_destroy(parms);
error:
ALOGV("%s: exit: code(%d)", __func__, ret);
@@ -3508,6 +3522,17 @@
}
}
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_PROFILE, value, sizeof(value));
+ if (err >= 0) {
+ strlcpy(in->profile, value, sizeof(in->profile));
+ ALOGV("updating stream profile with value '%s'", in->profile);
+ audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
+ &adev->streams_input_cfg_list,
+ in->device, in->flags, in->format,
+ in->sample_rate, in->bit_width,
+ in->profile, &in->app_type_cfg);
+ }
+
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&in->lock);
@@ -4130,7 +4155,7 @@
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
devices, flags, format, out->sample_rate,
- out->bit_width, out->channel_mask,
+ out->bit_width, out->channel_mask, out->profile,
&out->app_type_cfg);
if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
(flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
@@ -4764,7 +4789,7 @@
audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
&adev->streams_input_cfg_list,
devices, flags, in->format, in->sample_rate,
- in->bit_width, &in->app_type_cfg);
+ in->bit_width, in->profile, &in->app_type_cfg);
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index b733be8..8402578 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -79,6 +79,8 @@
#define MAX_PERF_LOCK_OPTS 20
+#define MAX_STREAM_PROFILE_STR_LEN 32
+
typedef enum card_status_t {
CARD_STATUS_OFFLINE,
CARD_STATUS_ONLINE
@@ -206,6 +208,7 @@
audio_format_t format;
audio_devices_t devices;
audio_output_flags_t flags;
+ char profile[MAX_STREAM_PROFILE_STR_LEN];
audio_usecase_t usecase;
/* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
@@ -262,6 +265,7 @@
audio_format_t format;
audio_io_handle_t capture_handle;
audio_input_flags_t flags;
+ char profile[MAX_STREAM_PROFILE_STR_LEN];
bool is_st_session;
bool is_st_session_active;
int sample_rate;
@@ -321,6 +325,7 @@
struct streams_io_cfg {
struct listnode list;
audio_io_flags_t flags;
+ char profile[MAX_STREAM_PROFILE_STR_LEN];
struct listnode format_list;
struct listnode sample_rate_list;
struct stream_app_type_cfg app_type_cfg;