hal: add support for configuring render window
Add support to set render window in transcode loopback usecase.
Render window is used by DSP to take rendering decision, i.e,
whether input frame should be rendered, dropped or repeated.
Change-Id: I87560a8e437b33dcd15094f30a532b3ed3d3749f
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 0e1848e..a0b1949 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -306,4 +306,12 @@
AUDIO_EXTN_PARAM_LICENSE_PARAMS,
} audio_extn_param_id;
+typedef union {
+ struct audio_out_render_window_param render_window_params;
+} audio_extn_loopback_param_payload;
+
+typedef enum {
+ AUDIO_EXTN_PARAM_LOOPBACK_RENDER_WINDOW /* PARAM to set render window */
+} audio_extn_loopback_param_id;
+
#endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index dd48a35..452c9a2 100755
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1522,6 +1522,33 @@
return ret;
}
+#ifdef AUDIO_HW_LOOPBACK_ENABLED
+int audio_extn_hw_loopback_set_param_data(audio_patch_handle_t handle,
+ audio_extn_loopback_param_id param_id,
+ audio_extn_loopback_param_payload *payload) {
+ int ret = -EINVAL;
+
+ if (!payload) {
+ ALOGE("%s:: Invalid Param",__func__);
+ return ret;
+ }
+
+ ALOGD("%d: %s: param id is %d\n", __LINE__, __func__, param_id);
+
+ switch(param_id) {
+ case AUDIO_EXTN_PARAM_LOOPBACK_RENDER_WINDOW:
+ ret = audio_extn_hw_loopback_set_render_window(handle, payload);
+ break;
+ default:
+ ALOGE("%s: unsupported param id %d", __func__, param_id);
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+
/* API to get playback stream specific config parameters */
int audio_extn_out_get_param_data(struct stream_out *out,
audio_extn_param_id param_id,
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 959985d..7cb6ce5 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1037,6 +1037,14 @@
const struct audio_port_config *config);
int audio_extn_hw_loopback_get_audio_port(struct audio_hw_device *dev,
struct audio_port *port_in);
+
+int audio_extn_hw_loopback_set_param_data(audio_patch_handle_t handle,
+ audio_extn_loopback_param_id param_id,
+ audio_extn_loopback_param_payload *payload);
+
+int audio_extn_hw_loopback_set_render_window(audio_patch_handle_t handle,
+ struct audio_out_render_window_param *render_window);
+
int audio_extn_hw_loopback_init(struct audio_device *adev);
void audio_extn_hw_loopback_deinit(struct audio_device *adev);
#else
@@ -1064,6 +1072,18 @@
{
return -ENOSYS;
}
+static int __unused audio_extn_hw_loopback_set_param_data(audio_patch_handle_t handle __unused,
+ audio_extn_loopback_param_id param_id __unused,
+ audio_extn_loopback_param_payload *payload __unused)
+{
+ return -ENOSYS;
+}
+
+static int __unused audio_extn_hw_loopback_set_render_window(audio_patch_handle_t handle __unused,
+ struct audio_out_render_window_param *render_window __unused)
+{
+ return -ENOSYS;
+}
static int __unused audio_extn_hw_loopback_init(struct audio_device *adev __unused)
{
return -ENOSYS;
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index 990a283..7516717 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -357,6 +357,78 @@
return 0;
}
+#ifdef SNDRV_COMPRESS_RENDER_WINDOW
+static loopback_patch_t *get_active_loopback_patch(audio_patch_handle_t handle)
+{
+ int n = 0;
+ int patch_index = -1;
+ loopback_patch_t *active_loopback_patch = NULL;
+
+ for (n=0; n < MAX_NUM_PATCHES; n++) {
+ if (audio_loopback_mod->patch_db.num_patches > 0) {
+ if (audio_loopback_mod->patch_db.loopback_patch[n].patch_handle_id == handle) {
+ patch_index = n;
+ break;
+ }
+ } else {
+ ALOGE("%s, No active audio loopback patch", __func__);
+ return active_loopback_patch;
+ }
+ }
+
+ if ((patch_index > -1) && (patch_index < MAX_NUM_PATCHES))
+ active_loopback_patch = &(audio_loopback_mod->patch_db.loopback_patch[
+ patch_index]);
+ else
+ ALOGE("%s, Requested Patch handle does not exist", __func__);
+
+ return active_loopback_patch;
+}
+
+int audio_extn_hw_loopback_set_render_window(audio_patch_handle_t handle,
+ struct audio_out_render_window_param *render_window)
+{
+ struct snd_compr_metadata metadata = {0};
+ int ret = 0;
+ loopback_patch_t *active_loopback_patch = get_active_loopback_patch(handle);
+
+ if (active_loopback_patch == NULL) {
+ ALOGE("%s: Invalid patch handle", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (render_window == NULL) {
+ ALOGE("%s: Invalid render_window", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ metadata.key = SNDRV_COMPRESS_RENDER_WINDOW;
+ /*render window start value */
+ metadata.value[0] = 0xFFFFFFFF & render_window->render_ws; /* lsb */
+ metadata.value[1] = \
+ (0xFFFFFFFF00000000 & render_window->render_ws) >> 32; /* msb*/
+ /*render window end value */
+ metadata.value[2] = 0xFFFFFFFF & render_window->render_we; /* lsb */
+ metadata.value[3] = \
+ (0xFFFFFFFF00000000 & render_window->render_we) >> 32; /* msb*/
+
+ ret = compress_set_metadata(active_loopback_patch->sink_stream, &metadata);
+
+exit:
+ return ret;
+}
+#else
+int audio_extn_hw_loopback_set_render_window(struct audio_hw_device *dev,
+ audio_patch_handle_t handle __unused,
+ struct audio_out_render_window_param *render_window __unused)
+{
+ ALOGD("%s:: configuring render window not supported", __func__);
+ return 0;
+}
+#endif
+
#if defined SNDRV_COMPRESS_LATENCY_MODE
static void transcode_loopback_util_set_latency_mode(
loopback_patch_t *active_loopback_patch,
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
index f5e0659..310b537 100644
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2017, 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -423,6 +423,19 @@
return ret;
}
+int qahwi_loopback_set_param_data(audio_patch_handle_t handle,
+ audio_extn_loopback_param_id param_id,
+ void *payload) {
+ int ret = 0;
+
+ ret = audio_extn_hw_loopback_set_param_data(
+ handle,
+ param_id,
+ (audio_extn_loopback_param_payload *)payload);
+
+ return ret;
+}
+
void qahwi_init(hw_device_t *device)
{
struct audio_device *adev = (struct audio_device *) device;
diff --git a/qahw/inc/qahw.h b/qahw/inc/qahw.h
index e91fd00..dd5b403 100644
--- a/qahw/inc/qahw.h
+++ b/qahw/inc/qahw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2011 The Android Open Source Project *
@@ -463,6 +463,13 @@
/* Release an audio patch */
int qahw_release_audio_patch_l(qahw_module_handle_t *hw_module,
audio_patch_handle_t handle);
+
+/* API to set loopback stream specific config parameters. */
+int qahw_loopback_set_param_data_l(qahw_module_handle_t *hw_module,
+ audio_patch_handle_t handle,
+ qahw_loopback_param_id param_id,
+ qahw_loopback_param_payload *payload);
+
/* Fills the list of supported attributes for a given audio port.
* As input, "port" contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
diff --git a/qahw/inc/qahw_defs.h b/qahw/inc/qahw_defs.h
index 4e7faff..755553b 100644
--- a/qahw/inc/qahw_defs.h
+++ b/qahw/inc/qahw_defs.h
@@ -417,6 +417,14 @@
QAHW_PARAM_LICENSE_PARAMS,
} qahw_param_id;
+typedef union {
+ struct qahw_out_render_window_param render_window_params;
+} qahw_loopback_param_payload;
+
+typedef enum {
+ QAHW_PARAM_LOOPBACK_RENDER_WINDOW /* PARAM to set render window */
+} qahw_loopback_param_id;
+
__END_DECLS
#endif // QTI_AUDIO_HAL_DEFS_H
diff --git a/qahw/src/qahw.c b/qahw/src/qahw.c
index 0c00158..126f794 100644
--- a/qahw/src/qahw.c
+++ b/qahw/src/qahw.c
@@ -69,6 +69,10 @@
qahw_param_id param_id,
qahw_param_payload *payload);
+typedef int (*qahwi_loopback_set_param_data_t)(audio_patch_handle_t patch_handle,
+ qahw_param_id param_id,
+ qahw_param_payload *payload);
+
typedef struct {
audio_hw_device_t *audio_device;
char module_name[MAX_MODULE_NAME_LENGTH];
@@ -80,6 +84,7 @@
const hw_module_t* module;
qahwi_get_param_data_t qahwi_get_param_data;
qahwi_set_param_data_t qahwi_set_param_data;
+ qahwi_loopback_set_param_data_t qahwi_loopback_set_param_data;
} qahw_module_t;
typedef struct {
@@ -1438,6 +1443,34 @@
return ret;
}
+int qahw_loopback_set_param_data_l(qahw_module_handle_t *hw_module,
+ audio_patch_handle_t handle,
+ qahw_loopback_param_id param_id,
+ qahw_loopback_param_payload *payload)
+
+{
+ int ret = -EINVAL;
+ qahw_module_t *qahw_module = (qahw_module_t *)hw_module;
+
+ if (!payload) {
+ ALOGE("%s:: invalid param", __func__);
+ goto exit;
+ }
+
+ if (qahw_module->qahwi_loopback_set_param_data) {
+ ret = qahw_module->qahwi_loopback_set_param_data(handle,
+ param_id,
+ (void *)payload);
+ } else {
+ ret = -ENOSYS;
+ ALOGE("%s not supported\n", __func__);
+ }
+
+exit:
+ return ret;
+
+}
+
/* Fills the list of supported attributes for a given audio port.
* As input, "port" contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
@@ -1889,6 +1922,12 @@
if (!qahw_module->qahwi_set_param_data)
ALOGD("%s::qahwi_set_param_data api is not defined\n",__func__);
+ qahw_module->qahwi_loopback_set_param_data = (qahwi_loopback_set_param_data_t)
+ dlsym(module->dso,
+ "qahwi_loopback_set_param_data");
+ if (!qahw_module->qahwi_loopback_set_param_data)
+ ALOGD("%s::qahwi_loopback_set_param_data api is not defined\n", __func__);
+
if (!qahw_list_count)
list_init(&qahw_module_list);
qahw_list_count++;
diff --git a/qahw_api/inc/qahw_api.h b/qahw_api/inc/qahw_api.h
index 0aa3c79..823c6bb 100644
--- a/qahw_api/inc/qahw_api.h
+++ b/qahw_api/inc/qahw_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2011 The Android Open Source Project *
@@ -459,6 +459,13 @@
/* Release an audio patch */
int qahw_release_audio_patch(qahw_module_handle_t *hw_module,
audio_patch_handle_t handle);
+
+/* API to set loopback stream specific config parameters */
+int qahw_loopback_set_param_data(qahw_module_handle_t *hw_module,
+ audio_patch_handle_t handle,
+ qahw_loopback_param_id param_id,
+ qahw_loopback_param_payload *payload);
+
/* Fills the list of supported attributes for a given audio port.
* As input, "port" contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index c6d42ca..7c01c57 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -399,6 +399,15 @@
QAHW_PARAM_LICENSE_PARAMS,
} qahw_param_id;
+
+typedef union {
+ struct qahw_out_render_window_param render_window_params;
+} qahw_loopback_param_payload;
+
+typedef enum {
+ QAHW_PARAM_LOOPBACK_RENDER_WINDOW /* PARAM to set render window */
+} qahw_loopback_param_id;
+
__END_DECLS
#endif // QTI_AUDIO_HAL_DEFS_H
diff --git a/qahw_api/src/qahw_api.cpp b/qahw_api/src/qahw_api.cpp
index cbd9041..f1c75f4 100644
--- a/qahw_api/src/qahw_api.cpp
+++ b/qahw_api/src/qahw_api.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -915,6 +915,15 @@
}
}
+int qahw_loopback_set_param_data(qahw_module_handle_t *hw_module __unused,
+ audio_patch_handle_t handle __unused,
+ qahw_loopback_param_id param_id __unused,
+ qahw_loopback_param_payload *payload __unused)
+{
+ ALOGD("%d:%s", __LINE__, __func__);
+ return -ENOSYS;
+}
+
int qahw_get_audio_port(qahw_module_handle_t *hw_module,
struct audio_port *port)
{
@@ -1699,6 +1708,15 @@
return qahw_release_audio_patch_l(hw_module, handle);
}
+int qahw_loopback_set_param_data(qahw_module_handle_t *hw_module,
+ audio_patch_handle_t handle,
+ qahw_loopback_param_id param_id,
+ qahw_loopback_param_payload *payload)
+{
+ ALOGV("%d:%s\n", __LINE__, __func__);
+ return qahw_loopback_set_param_data_l(hw_module, handle, param_id, payload);
+}
+
int qahw_get_audio_port(qahw_module_handle_t *hw_module,
struct audio_port *port)
{