hal: Add support for acquiring inital sink latency

Split a2dp get initial sink latency from BT host ipc.

Change-Id: Ia97f4379f6bd8ae925bc79f7e458383eaabc2bd2
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 0c51ec0..5239a30 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -74,6 +74,14 @@
 #define MIXER_ENC_FMT_APTX         "APTX"
 #define MIXER_ENC_FMT_APTXHD       "APTXHD"
 #define MIXER_ENC_FMT_NONE         "NONE"
+#define ENCODER_LATENCY_SBC        10
+#define ENCODER_LATENCY_APTX       40
+#define ENCODER_LATENCY_APTX_HD    20
+#define ENCODER_LATENCY_AAC        70
+#define DEFAULT_SINK_LATENCY_SBC       140
+#define DEFAULT_SINK_LATENCY_APTX      160
+#define DEFAULT_SINK_LATENCY_APTX_HD   180
+#define DEFAULT_SINK_LATENCY_AAC       180
 
 typedef int (*audio_stream_open_t)(void);
 typedef int (*audio_stream_close_t)(void);
@@ -85,6 +93,7 @@
 typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
                                audio_format_t *codec_type);
 typedef int (*audio_check_a2dp_ready_t)(void);
+typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
 
 enum A2DP_STATE {
     A2DP_STATE_CONNECTED,
@@ -109,6 +118,7 @@
     clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
     audio_get_codec_config_t audio_get_codec_config;
     audio_check_a2dp_ready_t audio_check_a2dp_ready;
+    audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
     enum A2DP_STATE bt_state;
     audio_format_t bt_encoder_format;
     uint32_t enc_sampling_rate;
@@ -293,6 +303,8 @@
                           dlsym(a2dp.bt_lib_handle, "audio_stream_close");
             a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
                         dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
+            a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
+                        dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
         }
     }
 
@@ -901,18 +913,27 @@
         }
     }
 
+    uint32_t slatency = 0;
+    if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
+        slatency = a2dp.audio_get_a2dp_sink_latency();
+    }
+
     switch(a2dp.bt_encoder_format) {
         case AUDIO_FORMAT_SBC:
-            latency = (avsync_runtime_prop > 0) ? sbc_offset : 150;
+            latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
+            latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
             break;
         case AUDIO_FORMAT_APTX:
-            latency = (avsync_runtime_prop > 0) ? aptx_offset : 200;
+            latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
+            latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
             break;
         case AUDIO_FORMAT_APTX_HD:
-            latency = (avsync_runtime_prop > 0) ? aptxhd_offset : 200;
+            latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
+            latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
             break;
         case AUDIO_FORMAT_AAC:
-            latency = (avsync_runtime_prop > 0) ? aac_offset : 250;
+            latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
+            latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
             break;
         default:
             latency = 200;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 868b562..2531b85 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3269,8 +3269,7 @@
            (out->config.rate);
     }
 
-    if ((AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) &&
-            !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))
+    if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices)
         latency += audio_extn_a2dp_get_encoder_latency();
 
     ALOGV("%s: Latency %d", __func__, latency);
@@ -3708,6 +3707,13 @@
     if (is_offload_usecase(out->usecase) && out->compr != NULL && out->non_blocking) {
         ret = compress_get_tstamp(out->compr, &dsp_frames,
                  &out->sample_rate);
+        // Adjustment accounts for A2dp encoder latency with offload usecases
+        // Note: Encoder latency is returned in ms.
+        if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) {
+            unsigned long offset =
+                        (audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000);
+            dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0;
+        }
         ALOGVV("%s rendered frames %ld sample_rate %d",
                __func__, dsp_frames, out->sample_rate);
         *frames = dsp_frames;