audio: hal: support for out start delay

-Changes to add support for out start delay

Change-Id: I27a55267efa888925c837639cb3349c6e19da249
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 3f120d6..eaf9b06 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -173,12 +173,17 @@
    uint64_t        render_we; /* render window end value in microseconds*/
 };
 
+struct audio_out_start_delay_param {
+   uint64_t        start_delay; /* session start delay 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;
+    struct audio_out_start_delay_param start_delay;
 } audio_extn_param_payload;
 
 typedef enum {
@@ -186,7 +191,8 @@
     AUDIO_EXTN_PARAM_SOUND_FOCUS,
     AUDIO_EXTN_PARAM_APTX_DEC,
     AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT,
-    AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW /* PARAM to set render window */
+    AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW, /* PARAM to set render window */
+    AUDIO_EXTN_PARAM_OUT_START_DELAY
 } 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 42f3676..ed7f479 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -838,4 +838,7 @@
 int audio_extn_utils_compress_set_render_window(
             struct stream_out *out,
             struct audio_out_render_window_param *render_window);
+int audio_extn_utils_compress_set_start_delay(
+            struct stream_out *out,
+            struct audio_out_start_delay_param *start_delay_param);
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 8397b2e..b8be7aa 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1876,3 +1876,63 @@
     return 0;
 }
 #endif
+
+#ifdef SNDRV_COMPRESS_START_DELAY
+int audio_extn_utils_compress_set_start_delay(
+            struct stream_out *out,
+            struct audio_out_start_delay_param *delay_param)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    if(delay_param == NULL) {
+        ALOGE("%s:: Invalid delay_param", __func__);
+        goto exit;
+    }
+
+    ALOGD("%s:: render start delay 0x%"PRIx64" ", __func__,
+          delay_param->start_delay);
+
+    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)) {
+        /* store it to reconfigure in start_output_stream() */
+        out->delay_param.start_delay = delay_param->start_delay;
+    } 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,"
+               "start delay will be configure later", __func__);
+       goto exit;
+    }
+
+    metadata.key = SNDRV_COMPRESS_START_DELAY;
+    metadata.value[0] = 0xFFFFFFFF & delay_param->start_delay; /* lsb */
+    metadata.value[1] = \
+            (0xFFFFFFFF00000000 & delay_param->start_delay) >> 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_start_delay(
+            struct stream_out *out __unused,
+            struct audio_out_start_delay_param *delay_param __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 a13fe8e..2fb471a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2193,6 +2193,9 @@
     if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
         audio_extn_keep_alive_start();
 
+    /*reset delay_param to 0*/
+    out->delay_param.start_delay = 0;
+
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
 }
@@ -2376,6 +2379,7 @@
         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_utils_compress_set_start_delay(out, &out->delay_param);
 
         audio_extn_dts_create_state_notifier_node(out->usecase);
         audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index eb639c0..68dc91b 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -266,6 +266,7 @@
     uint32_t platform_latency;
     render_mode_t render_mode;
     struct audio_out_render_window_param render_window; /*render winodw*/
+    struct audio_out_start_delay_param delay_param; /*start delay*/
 
     audio_offload_info_t info;
 };
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
index 708c698..4806149 100644
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -76,6 +76,10 @@
             ret = audio_extn_utils_compress_set_render_window(out,
                            (struct audio_out_render_window_param *)(payload));
            break;
+        case AUDIO_EXTN_PARAM_OUT_START_DELAY:
+            ret = audio_extn_utils_compress_set_start_delay(out,
+                           (struct audio_out_start_delay_param *)(payload));
+           break;
         default:
             ALOGE("%s:: unsupported param_id %d", __func__, param_id);
             break;
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index 3fe7767..d9231da 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -269,12 +269,17 @@
    uint64_t        render_we; /* render window end value microseconds*/
 };
 
+struct qahw_out_start_delay_param {
+   uint64_t       start_delay; /* session start delay in 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;
+    struct qahw_out_start_delay_param start_delay;
 } qahw_param_payload;
 
 typedef enum {
@@ -282,7 +287,8 @@
     QAHW_PARAM_SOUND_FOCUS,
     QAHW_PARAM_APTX_DEC,
     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_OUT_RENDER_WINDOW, /* PARAM to set render window */
+    QAHW_PARAM_OUT_START_DELAY /* PARAM to set session start delay*/
 } qahw_param_id;
 
 __END_DECLS