summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hal/audio_hw.c30
-rw-r--r--hal/audio_hw.h1
-rw-r--r--hal/msm8974/platform.c46
3 files changed, 50 insertions, 27 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 7e78713c..95f26b2f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1872,12 +1872,23 @@ static char* out_get_parameters(const struct audio_stream *stream, const char *k
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
struct stream_out *out = (struct stream_out *)stream;
+ uint32_t latency = 0;
- if (is_offload_usecase(out->usecase))
- return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
-
- return (out->config.period_count * out->config.period_size * 1000) /
+ if (is_offload_usecase(out->usecase)) {
+ if (out->use_small_bufs == true)
+ latency = ((out->compr_config.fragments *
+ out->compr_config.fragment_size * 1000) /
+ (out->sample_rate * out->compr_config.codec->ch_in *
+ audio_bytes_per_sample(out->format)));
+ else
+ latency = COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
+ } else {
+ latency = (out->config.period_count * out->config.period_size * 1000) /
(out->config.rate);
+ }
+
+ ALOGV("%s: Latency %d", latency);
+ return latency;
}
static int out_set_volume(struct audio_stream_out *stream, float left,
@@ -2562,6 +2573,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
out->handle = handle;
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ out->non_blocking = 0;
+ out->use_small_bufs = false;
/* Init use case and pcm_config */
if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
@@ -2679,6 +2692,15 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
out->non_blocking = 1;
+ if (config->offload_info.use_small_bufs) {
+ //this flag is set from framework only if its for PCM formats
+ //no need to check for PCM format again
+ out->non_blocking = 0;
+ out->use_small_bufs = true;
+ ALOGI("Keep write blocking for small buff: non_blockling %d",
+ out->non_blocking);
+ }
+
out->send_new_metadata = 1;
out->offload_state = OFFLOAD_STATE_IDLE;
out->playback_started = 0;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 3e749ce9..c5ae874f 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -180,6 +180,7 @@ struct stream_out {
struct stream_app_type_cfg app_type_cfg;
int non_blocking;
+ bool use_small_bufs;
int playback_started;
int offload_state;
pthread_cond_t offload_cond;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 6e7f9c97..37bc1c53 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -56,6 +56,8 @@
/* Used in calculating fragment size for pcm offload */
#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS 20 /* 20 millisecs */
+#define PCM_OFFLOAD_BUFFER_DURATION_MAX 1200 /* 1200 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
@@ -2528,44 +2530,42 @@ uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
{
- uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ uint32_t fragment_size = 0;
uint32_t bits_per_sample = 16;
+ uint32_t pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS;
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 >> 3)
- * popcount(info->channel_mask))/1000;
-
- } else if (info->has_video) {
- fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
- * info->sample_rate
- * (bits_per_sample >> 3)
- * popcount(info->channel_mask))/1000;
+ if (info->use_small_bufs) {
+ pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS;
+ } else {
+ if (!info->has_video) {
+ pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_MAX;
+ } else if (info->has_video && info->is_streaming) {
+ pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING;
+ } else if (info->has_video) {
+ pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV;
+ }
}
- char value[PROPERTY_VALUE_MAX] = {0};
- if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
- atoi(value)) {
- fragment_size = atoi(value) * 1024;
- ALOGV("Using buffer size from sys prop %d", fragment_size);
- }
+ //duration is set to 20 ms worth of stereo data at 48Khz
+ //with 16 bit per sample, modify this when the channel
+ //configuration is different
+ fragment_size = (pcm_offload_time
+ * info->sample_rate
+ * (bits_per_sample >> 3)
+ * popcount(info->channel_mask))/1000;
- fragment_size = ALIGN( fragment_size, 1024);
+ 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);
+ ALOGI("PCM offload Fragment size to %d bytes", fragment_size);
return fragment_size;
}