hal: Add support for PCM in offload path
- Translate PCM Offload format to pcm codec id
- Set 16/24 sub format id in compress params format
- Calculate offload fragment size for pcm
- Move offload calculation functions to platform file
- Update audio policy manager isOffloadSupported
for pcm offload profile. Use audio.offload.pcm.enable
Change-Id: I2064d646b66e8283fce2cc736e96fb93cba0a552
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e93716d..51d3538 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -31,12 +31,30 @@
#include "platform.h"
#include "audio_extn.h"
#include "voice_extn.h"
+#include "sound/compress_params.h"
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
+#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
+#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+
+/* Used in calculating fragment size for pcm offload */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */
+
+/* MAX PCM fragment size cannot be increased further due
+ * to flinger's cblk size of 1mb,and it has to be a multiple of
+ * 24 - lcm of channels supported by DSP
+ */
+#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
+#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+
+#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
/*
* This file will have a maximum of 38 bytes:
*
@@ -1694,3 +1712,69 @@
else
return false;
}
+
+/* Read offload buffer size from a property.
+ * If value is not power of 2 round it to
+ * power of 2.
+ */
+uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
+{
+ char value[PROPERTY_VALUE_MAX] = {0};
+ uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ if((property_get("audio.offload.buffer.size.kb", value, "")) &&
+ atoi(value)) {
+ fragment_size = atoi(value) * 1024;
+ }
+
+ if (info != NULL && info->has_video && info->is_streaming) {
+ fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
+ ALOGV("%s: offload fragment size reduced for AV streaming to %d",
+ __func__, out->compr_config.fragment_size);
+ }
+
+ fragment_size = ALIGN( fragment_size, 1024);
+
+ if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ ALOGV("%s: fragment_size %d", __func__, fragment_size);
+ return fragment_size;
+}
+
+uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
+{
+ uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ uint32_t bits_per_sample = 16;
+
+ if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
+ bits_per_sample = 32;
+ }
+
+ if (!info->has_video) {
+ fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+
+ } else if (info->has_video && info->is_streaming) {
+ fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
+ * info->sample_rate
+ * bits_per_sample
+ * popcount(info->channel_mask))/1000;
+
+ } else if (info->has_video) {
+ fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
+ * info->sample_rate
+ * bits_per_sample
+ * popcount(info->channel_mask))/1000;
+ }
+
+ fragment_size = ALIGN( fragment_size, 1024);
+
+ if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+
+ ALOGV("%s: fragment_size %d", __func__, fragment_size);
+ return fragment_size;
+}
+