audio: Presentation time enhancements

1) Add API to query platform render latency. This API is only
valid for deep-buffer and low-latency streams.
2) Adjust frames rendered for deep-buffer and low-latency streams
with the platform render latency
3) Use tinycompress APIs to query presentation time in case of
offload streams.

Bug: 10551158
Change-Id: If94e0994bfc0b757f29aa4b48be6fc63dc17bca0
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 76533c6..c89d88e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1442,8 +1442,12 @@
             size_t avail;
             if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
                 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
-                // FIXME This calculation is incorrect if there is buffering after app processor
                 int64_t signed_frames = out->written - kernel_buffer_size + avail;
+                // This adjustment accounts for buffering after app processor.
+                // It is based on estimated DSP latency per use case, rather than exact.
+                signed_frames -=
+                    (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL);
+
                 // It would be unusual for this value to be negative, but check just in case ...
                 if (signed_frames >= 0) {
                     *frames = signed_frames;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e533f33..b200e27 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -200,6 +200,9 @@
     [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
 };
 
+#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
+#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
+
 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
 static bool is_tmus = false;
 
@@ -880,3 +883,16 @@
 
     return max_channels;
 }
+
+/* Delay in Us */
+int64_t platform_render_latency(audio_usecase_t usecase)
+{
+    switch (usecase) {
+        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
+            return DEEP_BUFFER_PLATFORM_DELAY;
+        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
+            return LOW_LATENCY_PLATFORM_DELAY;
+        default:
+            return 0;
+    }
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index cd7150c..b5d568f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -185,6 +185,9 @@
     [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
 };
 
+#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
+#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
+
 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
 static bool is_tmus = false;
 
@@ -840,3 +843,16 @@
 
     return max_channels;
 }
+
+/* Delay in Us */
+int64_t platform_render_latency(audio_usecase_t usecase)
+{
+    switch (usecase) {
+        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
+            return DEEP_BUFFER_PLATFORM_DELAY;
+        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
+            return LOW_LATENCY_PLATFORM_DELAY;
+        default:
+            return 0;
+    }
+}
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 2362a5b..afd2ee4 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -36,4 +36,7 @@
 int platform_set_hdmi_channels(void *platform, int channel_count);
 int platform_edid_get_max_channels(void *platform);
 
+/* returns the latency for a usecase in Us */
+int64_t platform_render_latency(audio_usecase_t usecase);
+
 #endif // QCOM_AUDIO_PLATFORM_API_H