Merge "policy_hal: add support for multiple offload playback"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 39ad4d1..ce8f965 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -874,9 +874,7 @@
static perf_lock_acquire_t perf_lock_acq;
static perf_lock_release_t perf_lock_rel;
-static int perf_lock_handle;
char opt_lib_path[512] = {0};
-int perf_lock_opts[1] = {0x20E};
int audio_extn_perf_lock_init(void)
{
@@ -914,19 +912,30 @@
return ret;
}
-void audio_extn_perf_lock_acquire(void)
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *perf_lock_opts, int size)
{
- if (perf_lock_acq)
- perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 1);
- else
- ALOGE("%s: Perf lock acquire error \n", __func__);
+
+ if (!perf_lock_opts || !size || !perf_lock_acq || !handle)
+ return -EINVAL;
+ /*
+ * Acquire performance lock for 1 sec during device path bringup.
+ * Lock will be released either after 1 sec or when perf_lock_release
+ * function is executed.
+ */
+ *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+ if (*handle <= 0)
+ ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+ __func__, *handle);
}
-void audio_extn_perf_lock_release(void)
+void audio_extn_perf_lock_release(int *handle)
{
- if (perf_lock_rel && perf_lock_handle)
- perf_lock_rel(perf_lock_handle);
- else
+ if (perf_lock_rel && handle && (*handle > 0)) {
+ perf_lock_rel(*handle);
+ *handle = 0;
+ } else {
ALOGE("%s: Perf lock release error \n", __func__);
+ }
}
#endif /* KPI_OPTIMIZE_ENABLED */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3645cdb..b4848a4 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -503,12 +503,14 @@
#ifndef KPI_OPTIMIZE_ENABLED
#define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire() (0)
-#define audio_extn_perf_lock_release() (0)
+#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
+#define audio_extn_perf_lock_release(handle) (0)
#else
int audio_extn_perf_lock_init(void);
-void audio_extn_perf_lock_acquire(void);
-void audio_extn_perf_lock_release(void);
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *opts, int size);
+void audio_extn_perf_lock_release(int *handle);
+
#endif /* KPI_OPTIMIZE_ENABLED */
#ifndef AUDIO_EXTERNAL_HDMI_ENABLED
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9b716cb..e6fbc5f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1124,7 +1124,9 @@
uc_info->out_snd_device = SND_DEVICE_NONE;
list_add_tail(&adev->usecase_list, &uc_info->list);
- audio_extn_perf_lock_acquire();
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, in->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1166,16 +1168,14 @@
goto error_open;
}
- audio_extn_perf_lock_release();
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return ret;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_input_stream(in);
- audio_extn_perf_lock_release();
-
error_config:
adev->active_input = NULL;
/*
@@ -1644,6 +1644,9 @@
}
list_add_tail(&adev->usecase_list, &uc_info->list);
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, out->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1734,11 +1737,12 @@
audio_extn_check_and_set_dts_hpx_state(adev);
}
}
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return 0;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_output_stream(out);
error_config:
/*
@@ -3661,7 +3665,6 @@
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */
audio_extn_sound_trigger_check_and_get_session(in);
- audio_extn_perf_lock_init();
*stream_in = &in->stream;
ALOGV("%s: exit", __func__);
@@ -3822,6 +3825,9 @@
adev->cur_wfd_channels = 2;
adev->offload_usecases_state = 0;
adev->is_channel_status_set = false;
+ adev->perf_lock_opts[0] = 0x101;
+ adev->perf_lock_opts[1] = 0x20E;
+ adev->perf_lock_opts_size = 2;
pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
@@ -3939,6 +3945,7 @@
if (adev->adm_init)
adev->adm_data = adev->adm_init();
+ audio_extn_perf_lock_init();
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 62610b0..fd19211 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -74,6 +74,8 @@
#define SND_CARD_STATE_OFFLINE 0
#define SND_CARD_STATE_ONLINE 1
+#define MAX_PERF_LOCK_OPTS 20
+
/* These are the supported use cases by the hardware.
* Each usecase is mapped to a specific PCM device.
* Refer to pcm_device_table[].
@@ -353,6 +355,9 @@
void (*offload_effects_set_parameters)(struct str_parms *);
bool multi_offload_enable;
+ int perf_lock_handle;
+ int perf_lock_opts[MAX_PERF_LOCK_OPTS];
+ int perf_lock_opts_size;
};
int select_devices(struct audio_device *adev,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e59ed3e..0bf50be 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -118,6 +118,7 @@
#define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data"
#define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
+#define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
/* Query external audio device connection status */
#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -1260,7 +1261,7 @@
char value[PROPERTY_VALUE_MAX];
struct platform_data *my_data = NULL;
int retry_num = 0, snd_card_num = 0, key = 0;
- const char *snd_card_name;
+ const char *snd_card_name = NULL;
char *cvd_version = NULL;
char *snd_internal_name = NULL;
char *tmp = NULL;
@@ -1372,7 +1373,8 @@
if (snd_card_num >= MAX_SND_CARD) {
ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
free(my_data);
- free(snd_card_name);
+ if (snd_card_name)
+ free(snd_card_name);
return NULL;
}
@@ -3000,6 +3002,44 @@
free(dptr);
}
+static void perf_lock_set_params(struct platform_data *platform,
+ struct str_parms *parms,
+ char *value, int len)
+{
+ int err = 0, i = 0, num_opts = 0;
+ char *test_r = NULL;
+ char *opts = NULL;
+ char *opts_size = NULL;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS,
+ value, len);
+ if (err >= 0) {
+ opts_size = strtok_r(value, ", ", &test_r);
+ if (opts_size == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ return;
+ }
+ num_opts = atoi(opts_size);
+ if (num_opts > 0) {
+ if (num_opts > MAX_PERF_LOCK_OPTS) {
+ ALOGD("%s: num_opts %d exceeds max %d, setting to max\n",
+ __func__, num_opts, MAX_PERF_LOCK_OPTS);
+ num_opts = MAX_PERF_LOCK_OPTS;
+ }
+ for (i = 0; i < num_opts; i++) {
+ opts = strtok_r(NULL, ", ", &test_r);
+ if (opts == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ break;
+ }
+ platform->adev->perf_lock_opts[i] = strtoul(opts, NULL, 16);
+ }
+ platform->adev->perf_lock_opts_size = i;
+ }
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS);
+ }
+}
+
int platform_set_parameters(void *platform, struct str_parms *parms)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -3093,6 +3133,7 @@
set_audiocal(platform, parms, value, len);
native_audio_set_params(platform, parms, value, len);
audio_extn_spkr_prot_set_parameters(parms, value, len);
+ perf_lock_set_params(platform, parms, value, len);
done:
ALOGV("%s: exit with code(%d)", __func__, ret);
if(kv_pairs != NULL)
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d540bf5..e1dd026 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -324,6 +324,13 @@
* Effect Control Interface Implementation
*/
+static inline int16_t clamp16(int32_t sample)
+{
+ if ((sample>>15) ^ (sample>>31))
+ sample = 0x7FFF ^ (sample>>31);
+ return sample;
+}
+
static int vol_effect_process(effect_handle_t self,
audio_buffer_t *in_buffer,
audio_buffer_t *out_buffer)
@@ -342,7 +349,14 @@
// calculation based on channel count 2
if (in_buffer->raw != out_buffer->raw) {
- memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+ if (context->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+ size_t i;
+ for (i = 0; i < out_buffer->frameCount*2; i++) {
+ out_buffer->s16[i] = clamp16(out_buffer->s16[i] + in_buffer->s16[i]);
+ }
+ } else {
+ memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+ }
} else {
ALOGV("%s: something wrong, didn't handle in_buffer and out_buffer same address case",
__func__);
@@ -386,6 +400,12 @@
case EFFECT_CMD_SET_CONFIG:
ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
+ if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
+ || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
+ return -EINVAL;
+ }
+ context->config = *(effect_config_t *)p_cmd_data;
+ *(int *)p_reply_data = 0;
break;
case EFFECT_CMD_GET_CONFIG:
@@ -612,7 +632,7 @@
static int vol_prc_lib_create(const effect_uuid_t *uuid,
int32_t session_id,
- int32_t io_id,
+ int32_t io_id __unused,
effect_handle_t *p_handle)
{
int itt = 0;