audio: hal: support for audio render window

-Changes to add support for audio render window.

Change-Id: I40bb0d8061b8245999c37a485d3a7ee45108fac6
CRs-Fixed: 2009985
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index cbc9014..3f120d6 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -164,18 +164,29 @@
     uint32_t        ref_timer_abs_ts_msw;
 };
 
+/*use these for setting infine window.i.e free run mode */
+#define AUDIO_MAX_RENDER_START_WINDOW 0x8000000000000000
+#define AUDIO_MAX_RENDER_END_WINDOW   0x7FFFFFFFFFFFFFFF
+
+struct audio_out_render_window_param {
+   uint64_t        render_ws; /* render window start value in microseconds*/
+   uint64_t        render_we; /* render window end value in microseconds*/
+};
+
 typedef union {
     struct source_tracking_param st_params;
     struct sound_focus_param sf_params;
     struct aptx_dec_param aptx_params;
     struct audio_avt_device_drift_param drift_params;
+    struct audio_out_render_window_param render_window_param;
 } audio_extn_param_payload;
 
 typedef enum {
     AUDIO_EXTN_PARAM_SOURCE_TRACK,
     AUDIO_EXTN_PARAM_SOUND_FOCUS,
     AUDIO_EXTN_PARAM_APTX_DEC,
-    AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT
+    AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT,
+    AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW /* PARAM to set render window */
 } audio_extn_param_id;
 
 #endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index ab4ce47..42f3676 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -835,4 +835,7 @@
 int audio_extn_utils_compress_get_dsp_latency(struct stream_out *out);
 int audio_extn_utils_compress_set_render_mode(struct stream_out *out);
 int audio_extn_utils_compress_set_clk_rec_mode(struct audio_usecase *usecase);
+int audio_extn_utils_compress_set_render_window(
+            struct stream_out *out,
+            struct audio_out_render_window_param *render_window);
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 5ba85c5..8397b2e 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -20,6 +20,7 @@
 #define LOG_TAG "audio_hw_utils"
 /* #define LOG_NDEBUG 0 */
 
+#include <inttypes.h>
 #include <errno.h>
 #include <cutils/properties.h>
 #include <cutils/config_utils.h>
@@ -1809,3 +1810,69 @@
     return 0;
 }
 #endif
+
+#ifdef SNDRV_COMPRESS_RENDER_WINDOW
+int audio_extn_utils_compress_set_render_window(
+            struct stream_out *out,
+            struct audio_out_render_window_param *render_window)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    ALOGD("%s:: render window start 0x%"PRIx64" end 0x%"PRIx64"",
+          __func__,render_window->render_ws, render_window->render_we);
+
+    if(render_window == NULL) {
+        ALOGE("%s:: Invalid render_window", __func__);
+        goto exit;
+    }
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
+        (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
+        memcpy(&out->render_window, render_window,
+               sizeof(struct audio_out_render_window_param));
+    } else {
+        ALOGD("%s:: only supported in timestamp mode, current "
+              "render mode mode %d", __func__, out->render_mode);
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGW("%s:: offload session not yet opened,"
+               "render window will be configure later", __func__);
+        /* store render window to reconfigure in start_output_stream() */
+       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(out->compr, &metadata);
+    if(ret) {
+        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
+    }
+
+exit:
+    return ret;
+}
+#else
+int audio_extn_utils_compress_set_render_window(
+            struct stream_out *out __unused,
+            struct audio_out_render_window_param *render_window __unused)
+{
+    ALOGD("%s:: configuring render window not supported", __func__);
+    return 0;
+}
+#endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cb759f7..a13fe8e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2372,6 +2372,10 @@
 
         audio_extn_utils_compress_set_render_mode(out);
         audio_extn_utils_compress_set_clk_rec_mode(uc_info);
+        /* set render window if it was set before compress_open() */
+        if (out->render_window.render_ws != 0 && out->render_window.render_we != 0)
+            audio_extn_utils_compress_set_render_window(out,
+                                            &out->render_window);
 
         audio_extn_dts_create_state_notifier_node(out->usecase);
         audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,
@@ -4152,6 +4156,9 @@
             out->render_mode = RENDER_MODE_AUDIO_NO_TIMESTAMP;
         }
 
+        memset(&out->render_window, 0,
+                sizeof(struct audio_out_render_window_param));
+
         out->send_new_metadata = 1;
         out->send_next_track_params = false;
         out->is_compr_metadata_avail = false;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 89e68d1..eb639c0 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -265,6 +265,7 @@
     struct listnode qaf_offload_cmd_list;
     uint32_t platform_latency;
     render_mode_t render_mode;
+    struct audio_out_render_window_param render_window; /*render winodw*/
 
     audio_offload_info_t info;
 };
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
index 25c4503..708c698 100644
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -56,10 +56,33 @@
 }
 
 /* API to send playback stream specific config parameters */
-int qahwi_out_set_param_data(struct audio_stream_out *stream __unused,
-                             audio_extn_param_id param_id __unused,
-                             audio_extn_param_payload *payload __unused) {
-    return -ENOSYS;
+int qahwi_out_set_param_data(struct audio_stream_out *stream,
+                             audio_extn_param_id param_id,
+                             audio_extn_param_payload *payload) {
+    int ret = -EINVAL;
+    struct stream_out *out = (struct stream_out *)stream;
+
+    if (!stream || !payload) {
+        ALOGE("%s:: Invalid Param",__func__);
+        return ret;
+    }
+
+    lock_output_stream(out);
+    ALOGD("%s: enter: stream (%p) usecase(%d: %s) param_id %d", __func__,
+           stream, out->usecase, use_case_table[out->usecase], param_id);
+
+    switch (param_id) {
+        case AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW:
+            ret = audio_extn_utils_compress_set_render_window(out,
+                           (struct audio_out_render_window_param *)(payload));
+           break;
+        default:
+            ALOGE("%s:: unsupported param_id %d", __func__, param_id);
+            break;
+    }
+
+    pthread_mutex_unlock(&out->lock);
+    return ret;
 }
 
 /* API to get playback stream specific config parameters */
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index 63dc4da..3fe7767 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -260,18 +260,29 @@
     uint64_t        ref_timer_abs_ts;
 };
 
+/*use these for setting infine window.i.e free run mode */
+#define QAHW_MAX_RENDER_START_WINDOW 0x8000000000000000
+#define QAHW_MAX_RENDER_END_WINDOW   0x7FFFFFFFFFFFFFFF
+
+struct qahw_out_render_window_param {
+   uint64_t        render_ws; /* render window start value microseconds*/
+   uint64_t        render_we; /* render window end value microseconds*/
+};
+
 typedef union {
     struct qahw_source_tracking_param st_params;
     struct qahw_sound_focus_param sf_params;
     struct qahw_aptx_dec_param aptx_params;
     struct qahw_avt_device_drift_param drift_params;
+    struct qahw_out_render_window_param render_window_params;
 } qahw_param_payload;
 
 typedef enum {
     QAHW_PARAM_SOURCE_TRACK,
     QAHW_PARAM_SOUND_FOCUS,
     QAHW_PARAM_APTX_DEC,
-    QAHW_PARAM_AVT_DEVICE_DRIFT /* PARAM to query AV timer vs device drift */
+    QAHW_PARAM_AVT_DEVICE_DRIFT, /* PARAM to query AV timer vs device drift */
+    QAHW_PARAM_OUT_RENDER_WINDOW /* PARAM to set render window */
 } qahw_param_id;
 
 __END_DECLS