hal: AV sync latency correction for split A2dp

Audio lagging video for split A2DP. Encoder latencies were not
considered for SBC/APTX/APTXHD/AAC formats taking deep buffer,
PCM offload, low latency paths. A latency of 200-300ms observed
across formats. Our current solution changes the out_get_latency()
function in primary HAL to update latency based on BT codec formats.

CRs-Fixed: 2004199
Change-Id: I8f19018054e3945d618ba6bcfef5d28e4fbab716
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index cc4b283..3dc00fb 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -824,4 +824,51 @@
   a2dp.is_handoff_in_progress = false;
   update_offload_codec_capabilities();
 }
+
+uint32_t audio_extn_a2dp_get_encoder_latency()
+{
+    void *codec_info = NULL;
+    uint8_t multi_cast = 0, num_dev = 1;
+    audio_format_t codec_type = AUDIO_FORMAT_INVALID;
+    uint32_t latency = 0;
+    int avsync_runtime_prop = 0;
+    int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0;
+    char value[PROPERTY_VALUE_MAX];
+
+    if (!a2dp.audio_get_codec_config) {
+        ALOGE(" a2dp handle is not identified");
+        return latency;
+    }
+    codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
+                               &codec_type);
+
+    memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
+    avsync_runtime_prop = property_get("audio.a2dp.codec.latency", value, NULL);
+    if (avsync_runtime_prop > 0) {
+        if (sscanf(value, "%d/%d/%d/%d",
+                  &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset) != 4) {
+            ALOGI("Failed to parse avsync offset params from '%s'.", value);
+            avsync_runtime_prop = 0;
+        }
+    }
+
+    switch(codec_type) {
+        case AUDIO_FORMAT_SBC:
+            latency = (avsync_runtime_prop > 0) ? sbc_offset : 150;
+            break;
+        case AUDIO_FORMAT_APTX:
+            latency = (avsync_runtime_prop > 0) ? aptx_offset : 200;
+            break;
+        case AUDIO_FORMAT_APTX_HD:
+            latency = (avsync_runtime_prop > 0) ? aptxhd_offset : 200;
+            break;
+        case AUDIO_FORMAT_AAC:
+            latency = (avsync_runtime_prop > 0) ? aac_offset : 250;
+            break;
+        default:
+            latency = 200;
+            break;
+    }
+    return latency;
+}
 #endif // SPLIT_A2DP_ENABLED
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 8d58d09..c114d2d 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -205,6 +205,7 @@
 #define audio_extn_a2dp_is_force_device_switch()         (0)
 #define audio_extn_a2dp_set_handoff_mode(is_on)          (0)
 #define audio_extn_a2dp_get_apptype_params(sample_rate,bit_width)    (0)
+#define audio_extn_a2dp_get_encoder_latency()            (0)
 
 #else
 void audio_extn_a2dp_init(void *adev);
@@ -215,6 +216,7 @@
 void audio_extn_a2dp_set_handoff_mode(bool is_on);
 void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
                                         uint32_t *bit_width);
+uint32_t audio_extn_a2dp_get_encoder_latency();
 
 #endif
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 6f33acf..262fec5 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2895,6 +2895,10 @@
            (out->config.rate);
     }
 
+    if ((AUDIO_DEVICE_OUT_BLUETOOTH_A2DP == out->devices) &&
+            !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))
+        latency += audio_extn_a2dp_get_encoder_latency();
+
     ALOGV("%s: Latency %d", __func__, latency);
     return latency;
 }