hal: accumulate written frames when error occurred during write
Frames are discarded directly but not accumulated to written frames
when pcm write failed. This can make the playback position queried
from HAL is less than actual.
Move frames accumulation into a standalone func and handle this
for both failed and successful write.
CRs-Fixed: 2093628
Change-Id: I5b222f123306de603504f6bed4d4e3cdcc7a5b36
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 14b3563..a59e1ea 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3597,6 +3597,20 @@
return -ENOSYS;
}
+static void update_frames_written(struct stream_out *out, size_t bytes)
+{
+ size_t bpf = 0;
+
+ if (is_offload_usecase(out->usecase) && !out->non_blocking &&
+ !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))
+ bpf = 1;
+ else if (!is_offload_usecase(out->usecase))
+ bpf = audio_bytes_per_sample(out->format) *
+ audio_channel_count_from_out_mask(out->channel_mask);
+ if (bpf != 0)
+ out->written += bytes / bpf;
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -3614,14 +3628,6 @@
pthread_mutex_unlock(&out->lock);
return -ENETRESET;
} else {
- /* increase written size during SSR to avoid mismatch
- * with the written frames count in AF
- */
- // bytes per frame
- size_t bpf = audio_bytes_per_sample(out->format) *
- audio_channel_count_from_out_mask(out->channel_mask);
- if (bpf != 0)
- out->written += bytes / bpf;
ALOGD(" %s: sound card is not active/SSR state", __func__);
ret= -EIO;
goto exit;
@@ -3630,8 +3636,6 @@
if (audio_extn_passthru_should_drop_data(out)) {
ALOGV(" %s : Drop data as compress passthrough session is going on", __func__);
- if ((audio_bytes_per_sample(out->format) != 0) && (out->config.channels != 0))
- out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
ret = -EIO;
goto exit;
}
@@ -3655,10 +3659,6 @@
(audio_extn_a2dp_is_suspended())) {
if (!(out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
- size_t bpf = audio_bytes_per_sample(out->format) *
- audio_channel_count_from_out_mask(out->channel_mask);
- if (bpf != 0)
- out->written += bytes / bpf;
ret = -EIO;
goto exit;
}
@@ -3736,6 +3736,9 @@
} else
ret = compress_write(out->compr, buffer, bytes);
+ if ((ret < 0 || ret == (ssize_t)bytes) && !out->non_blocking)
+ update_frames_written(out, bytes);
+
if (ret < 0)
ret = -errno;
ALOGVV("%s: writing buffer (%zu bytes) to compress device returned %zd", __func__, bytes, ret);
@@ -3750,8 +3753,6 @@
out_on_error(&out->stream.common);
return ret;
}
- if ( ret == (ssize_t)bytes && !out->non_blocking)
- out->written += bytes;
/* Call compr start only when non-zero bytes of data is there to be rendered */
if (!out->playback_started && ret > 0) {
@@ -3830,14 +3831,13 @@
if (ret < 0)
ret = -errno;
- else if (ret == 0 && (audio_bytes_per_sample(out->format) != 0))
- out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
- else
+ else if (ret > 0)
ret = -EINVAL;
}
}
exit:
+ update_frames_written(out, bytes);
if (-ENETRESET == ret) {
out->card_status = CARD_STATUS_OFFLINE;
}