[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/4] audio/hda: detect output buffer overruns and un
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 4/4] audio/hda: detect output buffer overruns and underruns |
Date: |
Thu, 19 Apr 2018 15:10:51 +0200 |
If some event caused some larger playback hickup the fine-grained timer
adjust isn't able to recover. Use a buffer overruns and underruns as
indicator for that. Reset timer adjust logic in case we detected one.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/audio/hda-codec.c | 22 ++++++++++++++++++++++
hw/audio/trace-events | 2 ++
2 files changed, 24 insertions(+)
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index f6fb1d0fa0..623021b7c7 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -261,6 +261,13 @@ static void hda_audio_input_cb(void *opaque, int avail)
int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail);
+ if (to_transfer == 0) {
+ /* reset timer adjust */
+ st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ trace_hda_audio_underrun(st->node->name);
+ return;
+ }
+
hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
while (to_transfer) {
@@ -325,6 +332,21 @@ static void hda_audio_output_cb(void *opaque, int avail)
int64_t to_transfer = audio_MIN(wpos - rpos, avail);
+ if (to_transfer == 0) {
+ /* reset timer adjust */
+ st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ trace_hda_audio_underrun(st->node->name);
+ return;
+ }
+ if (wpos - rpos == B_SIZE) {
+ /* drop buffer, reset timer adjust */
+ st->rpos = 0;
+ st->wpos = 0;
+ st->buft_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ trace_hda_audio_overrun(st->node->name);
+ return;
+ }
+
hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
while (to_transfer) {
diff --git a/hw/audio/trace-events b/hw/audio/trace-events
index 30112d97c4..3b2ea2727b 100644
--- a/hw/audio/trace-events
+++ b/hw/audio/trace-events
@@ -22,3 +22,5 @@ milkymist_ac97_out_cb_transferred(int transferred)
"transferred %d"
hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run
%d"
hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st
%s, %d x %s @ %d Hz"
hda_audio_adjust(const char *stream, int pos) "st %s, pos %d"
+hda_audio_overrun(const char *stream) "st %s"
+hda_audio_underrun(const char *stream) "st %s"
--
2.9.3