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
This commit is contained in:
Dhananjay Kumar 2016-12-01 23:27:29 +05:30
parent d6d3215836
commit 4d91c1a064
6 changed files with 59 additions and 8 deletions

View File

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

View File

@ -519,6 +519,7 @@ void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
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 @@ void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
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);

View File

@ -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 @@ static void update_streams_cfg_list(cnode *root, void *platform,
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 @@ void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
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 @@ void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
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 @@ void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
__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 @@ void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
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 @@ void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
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;

View File

@ -2671,6 +2671,20 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
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 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
}
}
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 @@ int adev_open_output_stream(struct audio_hw_device *dev,
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 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
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 */

View File

@ -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 @@ struct stream_out {
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 @@ struct stream_in {
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 @@ typedef union {
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;

View File

@ -162,6 +162,9 @@ __BEGIN_DECLS
#define QAHW_OFFLOAD_CODEC_VORBIS_BITSTREAM_FMT "music_offload_vorbis_bitstream_fmt"
/* Set or Query stream profile type */
#define QAHW_PARAMETER_STREAM_PROFILE "audio_stream_profile"
/* Query fm volume */
#define QAHW_PARAMETER_KEY_FM_VOLUME "fm_volume"