hal: Restrict SSR recording to channel position representation

Surround Sound Recording(SSR) supports only channel position
representation while default channel mask for multi-channel
recording is always index representation.
Return updated channel mask in case index representation is sent
for channel count 6. This ensures audio flinger reopens the session
with updated position representation channel mask.
And also handled the case if any client requests recording with
multichannel when SSR is not enabled, will check the max_mic_count
supported by the device and update the channel mask accordingly.

Change-Id: Ib925a5f31d50182cd595e547f3412ed809224a5a
This commit is contained in:
Divya Narayanan Poojary 2016-09-30 18:52:13 +05:30 committed by Ben Romberger
parent 2f49a7c7ff
commit 45f1919f3d
7 changed files with 127 additions and 29 deletions

View File

@ -1142,3 +1142,52 @@ void audio_extn_perf_lock_release(int *handle)
}
}
#endif /* KPI_OPTIMIZE_ENABLED */
static int audio_extn_set_multichannel_mask(struct audio_device *adev,
struct stream_in *in,
struct audio_config *config,
bool *channel_mask_updated)
{
int ret = -EINVAL;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
*channel_mask_updated = false;
int max_mic_count = platform_get_max_mic_count(adev->platform);
/* validate input params*/
if ((channel_count == 6) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT)) {
switch (max_mic_count) {
case 4:
config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_4;
break;
case 3:
config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_3;
break;
case 2:
config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
break;
default:
config->channel_mask = AUDIO_CHANNEL_IN_STEREO;
break;
}
ret = 0;
*channel_mask_updated = true;
}
return ret;
}
int audio_extn_check_and_set_multichannel_usecase(struct audio_device *adev,
struct stream_in *in,
struct audio_config *config,
bool *update_params)
{
bool ssr_supported = false;
ssr_supported = audio_extn_ssr_check_usecase(in);
if (ssr_supported) {
return audio_extn_ssr_set_usecase(in, config, update_params);
} else {
return audio_extn_set_multichannel_mask(adev, in, config,
update_params);
}
}

View File

@ -189,17 +189,21 @@ void audio_extn_a2dp_set_handoff_mode(bool is_on);
#endif
#ifndef SSR_ENABLED
#define audio_extn_ssr_check_and_set_usecase(in) (-1)
#define audio_extn_ssr_init(in, num_out_chan) (0)
#define audio_extn_ssr_deinit() (0)
#define audio_extn_ssr_update_enabled() (0)
#define audio_extn_ssr_get_enabled() (0)
#define audio_extn_ssr_read(stream, buffer, bytes) (0)
#define audio_extn_ssr_set_parameters(adev, parms) (0)
#define audio_extn_ssr_get_parameters(adev, parms, reply) (0)
#define audio_extn_ssr_get_stream() (0)
#define audio_extn_ssr_check_usecase(in) (0)
#define audio_extn_ssr_set_usecase(in, config, channel_mask_updated) (0)
#define audio_extn_ssr_init(in, num_out_chan) (0)
#define audio_extn_ssr_deinit() (0)
#define audio_extn_ssr_update_enabled() (0)
#define audio_extn_ssr_get_enabled() (0)
#define audio_extn_ssr_read(stream, buffer, bytes) (0)
#define audio_extn_ssr_set_parameters(adev, parms) (0)
#define audio_extn_ssr_get_parameters(adev, parms, reply) (0)
#define audio_extn_ssr_get_stream() (0)
#else
int audio_extn_ssr_check_and_set_usecase(struct stream_in *in);
bool audio_extn_ssr_check_usecase(struct stream_in *in);
int audio_extn_ssr_set_usecase(struct stream_in *in,
struct audio_config *config,
bool *channel_mask_updated);
int32_t audio_extn_ssr_init(struct stream_in *in,
int num_out_chan);
int32_t audio_extn_ssr_deinit();
@ -214,6 +218,10 @@ void audio_extn_ssr_get_parameters(const struct audio_device *adev,
struct str_parms *reply);
struct stream_in *audio_extn_ssr_get_stream();
#endif
int audio_extn_check_and_set_multichannel_usecase(struct audio_device *adev,
struct stream_in *in,
struct audio_config *config,
bool *update_params);
#ifndef HW_VARIANTS_ENABLED
#define hw_info_init(snd_card_name) (0)

View File

@ -331,33 +331,55 @@ bool audio_extn_ssr_get_enabled()
return false;
}
int audio_extn_ssr_check_and_set_usecase(struct stream_in *in)
{
int ret = -1;
bool audio_extn_ssr_check_usecase(struct stream_in *in) {
int ret = false;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
audio_devices_t devices = in->device;
audio_source_t source = in->source;
/* validate input params
* only stereo and 5:1 channel config is supported
* only AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BACK_MIC supports 3 mics */
if (audio_extn_ssr_get_enabled() &&
((channel_count == 2) || (channel_count == 6)) &&
((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) &&
((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT)) {
ALOGD("%s: Found SSR use case starting SSR lib with channel_count :%d",
if ((audio_extn_ssr_get_enabled()) &&
((channel_count == 2) || (channel_count == 6)) &&
((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) &&
((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT)) {
ALOGD("%s: SSR enabled with channel_count :%d",
__func__, channel_count);
ret = true;
}
return ret;
}
if (!audio_extn_ssr_init(in, channel_count)) {
ALOGD("%s: Created SSR session succesfully", __func__);
int audio_extn_ssr_set_usecase(struct stream_in *in,
struct audio_config *config,
bool *update_params)
{
int ret = -EINVAL;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
audio_channel_representation_t representation =
audio_channel_mask_get_representation(in->channel_mask);
*update_params = false;
if (audio_extn_ssr_check_usecase(in)) {
if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
/* update params in case channel representation index.
* on returning error, flinger will retry with supported representation passed
*/
ALOGD("%s: SSR supports only channel representation position, channel_mask(%#x)"
,__func__, config->channel_mask);
config->channel_mask = AUDIO_CHANNEL_IN_5POINT1;
ret = 0;
*update_params = true;
} else {
ALOGE("%s: Unable to start SSR record session", __func__);
if (!audio_extn_ssr_init(in, channel_count)) {
ALOGD("%s: Created SSR session succesfully", __func__);
ret = 0;
} else {
ALOGE("%s: Unable to start SSR record session", __func__);
}
}
}
return ret;
}
return ret;
}
static void pcm_buffer_queue_push(struct pcm_buffer_queue **queue,

View File

@ -4348,6 +4348,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
int ret = 0, buffer_size, frame_size;
int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
bool is_low_latency = false;
bool channel_mask_updated = false;
*stream_in = NULL;
if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
@ -4442,7 +4443,14 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->config.channels = channel_count;
in->config.rate = config->sample_rate;
in->sample_rate = config->sample_rate;
} else if (!audio_extn_ssr_check_and_set_usecase(in)) {
} else if (!audio_extn_check_and_set_multichannel_usecase(adev,
in, config, &channel_mask_updated)) {
if (channel_mask_updated == true) {
ALOGD("%s: return error to retry with updated channel mask (%#x)",
__func__, config->channel_mask);
ret = -EINVAL;
goto err_open;
}
ALOGD("%s: created surround sound session succesfully",__func__);
} else if (audio_extn_compr_cap_enabled() &&
audio_extn_compr_cap_format_supported(config->format) &&

View File

@ -5686,3 +5686,8 @@ int platform_retrieve_audio_cal(void* platform __unused,
{
return -ENOSYS;
}
int platform_get_max_mic_count(void *platform) {
struct platform_data *my_data = (struct platform_data *)platform;
return my_data->max_mic_count;
}

View File

@ -5825,3 +5825,8 @@ int platform_retrieve_audio_cal(void* platform, int acdb_dev_id,
ERROR_RETURN:
return ret;
}
int platform_get_max_mic_count(void *platform) {
struct platform_data *my_data = (struct platform_data *)platform;
return my_data->max_mic_count;
}

View File

@ -178,4 +178,5 @@ int platform_retrieve_audio_cal(void* platform, int acdb_dev_id, int acdb_device
void* data, int* length);
unsigned char* platform_get_license(void* platform, int* size);
int platform_get_max_mic_count(void *platform);
#endif // AUDIO_PLATFORM_API_H