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
This commit is contained in:
parent
a8646d9d71
commit
aa54c87a7e
|
@ -1944,12 +1944,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,
|
||||
|
@ -2642,6 +2653,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) &&
|
||||
|
@ -2776,6 +2789,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;
|
||||
|
|
|
@ -181,6 +181,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;
|
||||
|
|
|
@ -63,6 +63,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
|
||||
|
@ -2898,44 +2900,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->use_small_bufs) {
|
||||
pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS;
|
||||
} else {
|
||||
if (!info->has_video) {
|
||||
fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
|
||||
|
||||
pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_MAX;
|
||||
} 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;
|
||||
|
||||
pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING;
|
||||
} else if (info->has_video) {
|
||||
fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
|
||||
pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV;
|
||||
}
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue