hal: refine frames rendered calculation for pcm offload
For PCM format, hal input format and alsa format might differ.
Refine frames rendered calculation.
Change-Id: I3ab266648541e6040e13ee4249736000c42382a0
CRs-Fixed: 2694810
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 979781e..ef88867 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -4305,28 +4305,34 @@
static uint64_t get_actual_pcm_frames_rendered(struct stream_out *out, struct timespec *timestamp)
{
uint64_t actual_frames_rendered = 0;
- size_t kernel_buffer_size = out->compr_config.fragment_size * out->compr_config.fragments;
+ uint64_t written_frames = 0;
+ uint64_t kernel_frames = 0;
+ uint64_t dsp_frames = 0;
+ uint64_t signed_frames = 0;
+ size_t kernel_buffer_size = 0;
/* This adjustment accounts for buffering after app processor.
* It is based on estimated DSP latency per use case, rather than exact.
*/
pthread_mutex_lock(&adev->lock);
- int64_t platform_latency = platform_render_latency(out->dev, out->usecase) *
- out->sample_rate / 1000000LL;
+ dsp_frames = platform_render_latency(out->dev, out->usecase) *
+ out->sample_rate / 1000000LL;
pthread_mutex_unlock(&adev->lock);
pthread_mutex_lock(&out->position_query_lock);
+ written_frames = out->written /
+ (audio_bytes_per_sample(out->hal_ip_format) * popcount(out->channel_mask));
+
/* not querying actual state of buffering in kernel as it would involve an ioctl call
* which then needs protection, this causes delay in TS query for pcm_offload usecase
* hence only estimate.
*/
- uint64_t signed_frames = 0;
- if (out->written >= kernel_buffer_size)
- signed_frames = out->written - kernel_buffer_size;
+ kernel_buffer_size = out->compr_config.fragment_size * out->compr_config.fragments;
+ kernel_frames = kernel_buffer_size /
+ (audio_bytes_per_sample(out->hal_op_format) * popcount(out->channel_mask));
- signed_frames = signed_frames / (audio_bytes_per_sample(out->format) * popcount(out->channel_mask));
- if (signed_frames >= platform_latency)
- signed_frames = signed_frames - platform_latency;
+ if (written_frames >= (kernel_frames + dsp_frames))
+ signed_frames = written_frames - kernel_frames - dsp_frames;
if (signed_frames > 0) {
actual_frames_rendered = signed_frames;
@@ -4337,11 +4343,8 @@
}
pthread_mutex_unlock(&out->position_query_lock);
- ALOGVV("%s signed frames %lld out_written %lld kernel_buffer_size %d"
- "bytes/sample %zu channel count %d", __func__, signed_frames,
- (long long int)out->written, (int)kernel_buffer_size,
- audio_bytes_per_sample(out->compr_config.codec->format),
- popcount(out->channel_mask));
+ ALOGVV("%s signed frames %lld written frames %lld kernel frames %lld dsp frames %lld",
+ __func__, signed_frames, written_frames, kernel_frames, dsp_frames);
return actual_frames_rendered;
}