summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexy Joseph <alexyj@codeaurora.org>2014-12-03 02:46:47 -0800
committerSteve Kondik <steve@cyngn.com>2014-12-23 13:00:23 -0800
commit3cfe58d71f27ff926bbb7b4ddbef97d22ed947bb (patch)
tree5d52cdf6dfb540f0e4924f7e13cc1d938ed4b07e
parent3e98fd72e1984f45389af2d00927a71b6c8154f7 (diff)
downloadandroid_hardware_qcom_audio-3cfe58d71f27ff926bbb7b4ddbef97d22ed947bb.tar.gz
android_hardware_qcom_audio-3cfe58d71f27ff926bbb7b4ddbef97d22ed947bb.tar.bz2
android_hardware_qcom_audio-3cfe58d71f27ff926bbb7b4ddbef97d22ed947bb.zip
hal: bug fixes for PCM offload
When pcm offload is done, override the buffer size that was calculated and use the value from the system property Make write call blocking if small buffers are used in offload Update latency value for pcm offload with small buffer hint based on period size and period count. Change-Id: Ic74caa6bd172c8e4554384e9fa98a5137117f07c
-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;
}