hal: Add support for buffer duration in offload usecase

Add support for buffer duration in offload usecase.
HAL configures the buffer size corresponding to the
duration specified by the client.

Change-Id: I73faf8ddd633ba8a889f3189fcc6d4392a0e1a42
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 171f69e..8d9cd33 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1525,11 +1525,15 @@
 
 uint32_t get_alsa_fragment_size(uint32_t bytes_per_sample,
                                   uint32_t sample_rate,
-                                  uint32_t noOfChannels)
+                                  uint32_t noOfChannels,
+                                  int64_t duration_ms)
 {
     uint32_t fragment_size = 0;
     uint32_t pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION;
 
+    if (duration_ms >= MIN_OFFLOAD_BUFFER_DURATION_MS && duration_ms <= MAX_OFFLOAD_BUFFER_DURATION_MS)
+        pcm_offload_time = duration_ms;
+
     fragment_size = (pcm_offload_time
                      * sample_rate
                      * bytes_per_sample
@@ -1564,7 +1568,8 @@
     out->compr_config.fragment_size =
              get_alsa_fragment_size(hal_op_bytes_per_sample,
                                       out->sample_rate,
-                                      popcount(out->channel_mask));
+                                      popcount(out->channel_mask),
+                                      out->info.duration_us / 1000);
 
     if ((src_format != dst_format) &&
          hal_op_bytes_per_sample != hal_ip_bytes_per_sample) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 76c14ab..7519ee7 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -7463,6 +7463,10 @@
 
             out->compr_config.fragments = DIRECT_PCM_NUM_FRAGMENTS;
 
+            if ((config->offload_info.duration_us >= MIN_OFFLOAD_BUFFER_DURATION_MS * 1000) &&
+                   (config->offload_info.duration_us <= MAX_OFFLOAD_BUFFER_DURATION_MS * 1000))
+                out->info.duration_us = (int64_t)config->offload_info.duration_us;
+
             /* Check if alsa session is configured with the same format as HAL input format,
              * if not then derive correct fragment size needed to accomodate the
              * conversion of HAL input format to alsa format.
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 459c37c..9abb1cb 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -7948,6 +7948,9 @@
 {
     char value[PROPERTY_VALUE_MAX] = {0};
     uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+    uint32_t new_fragment_size = 0;
+    int32_t duration_ms = 0;
+    int channel_count = 0;
     if((property_get("vendor.audio.offload.buffer.size.kb", value, "")) &&
             atoi(value)) {
         fragment_size =  atoi(value) * 1024;
@@ -7961,6 +7964,17 @@
         fragment_size = info->offload_buffer_size;
     }
 
+    /* Use client specified buffer size if mentioned */
+    if ((info != NULL) && (info->duration_us > 0)) {
+        duration_ms = info->duration_us / 1000;
+        channel_count = audio_channel_count_from_in_mask(info->channel_mask);
+
+        new_fragment_size = (duration_ms * info->sample_rate * channel_count * audio_bytes_per_sample(info->format)) / 1000;
+        ALOGI("%s:: Overwriting offload buffer size with client requested size old:%d new:%d", __func__, fragment_size, new_fragment_size);
+
+        fragment_size = new_fragment_size;
+    }
+
     if (info != NULL) {
         if (info->is_streaming && info->has_video) {
             fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;