qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 0/6] Audio 20200106 patches
@ 2020-01-06 12:52 Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 1/6] hda-codec: fix playback rate control Gerd Hoffmann
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The following changes since commit f0dcfddecee8b860e015bb07d67cfcbdfbfd51d9:

  Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2020-01-03 17:18:08 +0000)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/audio-20200106-pull-request

for you to fetch changes up to 40ad46d3cc463fab5a23db466f77e37aff23f927:

  audio: fix integer overflow (2020-01-06 08:47:16 +0100)

----------------------------------------------------------------
audio: bugfixes.

----------------------------------------------------------------

Volker Rümelin (6):
  hda-codec: fix playback rate control
  hda-codec: fix recording rate control
  paaudio: drop recording stream in qpa_fini_in
  paaudio: try to drain the recording stream
  paaudio: wait until the recording stream is ready
  audio: fix integer overflow

 audio/audio.c        |  2 +-
 audio/paaudio.c      | 68 +++++++++++++++++++++++++++++++-------------
 hw/audio/hda-codec.c |  8 +++---
 3 files changed, 53 insertions(+), 25 deletions(-)

-- 
2.18.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PULL 1/6] hda-codec: fix playback rate control
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 2/6] hda-codec: fix recording " Gerd Hoffmann
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

Since commit 1930616b98 "audio: make mixeng optional" the
function hda_audio_output_cb can no longer assume the function
parameter avail contains the free buffer size. With the playback
mixing-engine turned off this leads to a broken playback rate
control and playback buffer drops in regular intervals.

This patch moves down the rate calculation, so the correct
buffer fill level is used for the calculation.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200104091122.13971-1-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/audio/hda-codec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index f17e8d8dcea2..768ba31e7926 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -338,8 +338,6 @@ static void hda_audio_output_cb(void *opaque, int avail)
         return;
     }
 
-    hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
-
     while (to_transfer) {
         uint32_t start = (uint32_t) (rpos & B_MASK);
         uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
@@ -351,6 +349,8 @@ static void hda_audio_output_cb(void *opaque, int avail)
             break;
         }
     }
+
+    hda_timer_sync_adjust(st, (wpos - rpos) - (B_SIZE >> 1));
 }
 
 static void hda_audio_compat_input_cb(void *opaque, int avail)
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PULL 2/6] hda-codec: fix recording rate control
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 1/6] hda-codec: fix playback rate control Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 3/6] paaudio: drop recording stream in qpa_fini_in Gerd Hoffmann
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

Apply previous commit to hda_audio_input_cb for the same
reasons.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200104091122.13971-2-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/audio/hda-codec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index 768ba31e7926..e711a99a414a 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -265,8 +265,6 @@ static void hda_audio_input_cb(void *opaque, int avail)
 
     int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), avail);
 
-    hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
-
     while (to_transfer) {
         uint32_t start = (uint32_t) (wpos & B_MASK);
         uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
@@ -278,6 +276,8 @@ static void hda_audio_input_cb(void *opaque, int avail)
             break;
         }
     }
+
+    hda_timer_sync_adjust(st, -((wpos - rpos) - (B_SIZE >> 1)));
 }
 
 static void hda_audio_output_timer(void *opaque)
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PULL 3/6] paaudio: drop recording stream in qpa_fini_in
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 1/6] hda-codec: fix playback rate control Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 2/6] hda-codec: fix recording " Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 4/6] paaudio: try to drain the recording stream Gerd Hoffmann
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

Every call to pa_stream_peek which returns a data length > 0
should have a corresponding pa_stream_drop. A call to qpa_read
does not necessarily call pa_stream_drop immediately after a
call to pa_stream_peek. Test in qpa_fini_in if a last
pa_stream_drop is needed.

This prevents following messages in the libvirt log file after
a recording stream gets closed and a new one opened.

pulseaudio: pa_stream_drop failed
pulseaudio: Reason: Bad state
pulseaudio: pa_stream_drop failed
pulseaudio: Reason: Bad state

To reproduce start qemu with
-audiodev pa,id=audio0,in.mixing-engine=off
and in the guest start and stop Audacity several times.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200104091122.13971-3-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 55a91f898073..7db1dc15f09e 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -536,7 +536,6 @@ static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
 {
     int err;
 
-    pa_threaded_mainloop_lock(c->mainloop);
     /*
      * wait until actually connects. workaround pa bug #247
      * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
@@ -550,7 +549,6 @@ static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
         dolog("Failed to disconnect! err=%d\n", err);
     }
     pa_stream_unref(stream);
-    pa_threaded_mainloop_unlock(c->mainloop);
 }
 
 static void qpa_fini_out (HWVoiceOut *hw)
@@ -558,8 +556,12 @@ static void qpa_fini_out (HWVoiceOut *hw)
     PAVoiceOut *pa = (PAVoiceOut *) hw;
 
     if (pa->stream) {
-        qpa_simple_disconnect(pa->g->conn, pa->stream);
+        PAConnection *c = pa->g->conn;
+
+        pa_threaded_mainloop_lock(c->mainloop);
+        qpa_simple_disconnect(c, pa->stream);
         pa->stream = NULL;
+        pa_threaded_mainloop_unlock(c->mainloop);
     }
 }
 
@@ -568,8 +570,20 @@ static void qpa_fini_in (HWVoiceIn *hw)
     PAVoiceIn *pa = (PAVoiceIn *) hw;
 
     if (pa->stream) {
-        qpa_simple_disconnect(pa->g->conn, pa->stream);
+        PAConnection *c = pa->g->conn;
+
+        pa_threaded_mainloop_lock(c->mainloop);
+        if (pa->read_length) {
+            int r = pa_stream_drop(pa->stream);
+            if (r) {
+                qpa_logerr(pa_context_errno(c->context),
+                           "pa_stream_drop failed\n");
+            }
+            pa->read_length = 0;
+        }
+        qpa_simple_disconnect(c, pa->stream);
         pa->stream = NULL;
+        pa_threaded_mainloop_unlock(c->mainloop);
     }
 }
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PULL 4/6] paaudio: try to drain the recording stream
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2020-01-06 12:52 ` [PULL 3/6] paaudio: drop recording stream in qpa_fini_in Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 5/6] paaudio: wait until the recording stream is ready Gerd Hoffmann
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

There is no guarantee a single call to pa_stream_peek every
timer_period microseconds can read a recording stream faster
than the data gets produced at the source. Let qpa_read try to
drain the recording stream.

To reproduce the problem:

Start qemu with -audiodev pa,id=audio0,in.mixing-engine=off

On the host connect the qemu recording stream to the monitor of
a hardware output device. While the problem can also be seen
with a hardware input device, it's obvious with the monitor of
a hardware output device.

In the guest start audio recording with audacity and notice the
slow recording data rate.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200104091122.13971-4-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 7db1dc15f09e..b23274550e1c 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -156,34 +156,43 @@ static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
 {
     PAVoiceIn *p = (PAVoiceIn *) hw;
     PAConnection *c = p->g->conn;
-    size_t l;
-    int r;
+    size_t total = 0;
 
     pa_threaded_mainloop_lock(c->mainloop);
 
     CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                     "pa_threaded_mainloop_lock failed\n");
 
-    if (!p->read_length) {
-        r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
-        CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
-                           "pa_stream_peek failed\n");
-    }
+    while (total < length) {
+        size_t l;
+        int r;
 
-    l = MIN(p->read_length, length);
-    memcpy(data, p->read_data, l);
+        if (!p->read_length) {
+            r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
+            CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
+                               "pa_stream_peek failed\n");
+            if (!p->read_length) {
+                /* buffer is empty */
+                break;
+            }
+        }
 
-    p->read_data += l;
-    p->read_length -= l;
+        l = MIN(p->read_length, length - total);
+        memcpy((char *)data + total, p->read_data, l);
 
-    if (!p->read_length) {
-        r = pa_stream_drop(p->stream);
-        CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
-                           "pa_stream_drop failed\n");
+        p->read_data += l;
+        p->read_length -= l;
+        total += l;
+
+        if (!p->read_length) {
+            r = pa_stream_drop(p->stream);
+            CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
+                               "pa_stream_drop failed\n");
+        }
     }
 
     pa_threaded_mainloop_unlock(c->mainloop);
-    return l;
+    return total;
 
 unlock_and_fail:
     pa_threaded_mainloop_unlock(c->mainloop);
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PULL 5/6] paaudio: wait until the recording stream is ready
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2020-01-06 12:52 ` [PULL 4/6] paaudio: try to drain the recording stream Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 12:52 ` [PULL 6/6] audio: fix integer overflow Gerd Hoffmann
  2020-01-06 17:44 ` [PULL 0/6] Audio 20200106 patches Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

Don't call pa_stream_peek before the recording stream is ready.

Information to reproduce the problem.

Start and stop Audacity in the guest several times because the
problem is racy.

libvirt log file:
-audiodev pa,id=audio0,server=localhost,out.latency=30000,
 out.mixing-engine=off,in.mixing-engine=off \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,
 resourcecontrol=deny \
-msg timestamp=on
: Domain id=4 is tainted: custom-argv
char device redirected to /dev/pts/1 (label charserial0)
audio: Device pcspk: audiodev default parameter is deprecated,
 please specify audiodev=audio0
audio: Device hda: audiodev default parameter is deprecated,
 please specify audiodev=audio0
pulseaudio: pa_stream_peek failed
pulseaudio: Reason: Bad state
pulseaudio: pa_stream_peek failed
pulseaudio: Reason: Bad state

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200104091122.13971-5-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index b23274550e1c..dbfe48c03a1d 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -162,6 +162,10 @@ static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
 
     CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                     "pa_threaded_mainloop_lock failed\n");
+    if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
+        /* wait for stream to become ready */
+        goto unlock;
+    }
 
     while (total < length) {
         size_t l;
@@ -191,6 +195,7 @@ static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
         }
     }
 
+unlock:
     pa_threaded_mainloop_unlock(c->mainloop);
     return total;
 
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PULL 6/6] audio: fix integer overflow
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2020-01-06 12:52 ` [PULL 5/6] paaudio: wait until the recording stream is ready Gerd Hoffmann
@ 2020-01-06 12:52 ` Gerd Hoffmann
  2020-01-06 17:44 ` [PULL 0/6] Audio 20200106 patches Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2020-01-06 12:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Volker Rümelin, Gerd Hoffmann

From: Volker Rümelin <vr_qemu@t-online.de>

Tell the compiler to do a 32bit * 32bit -> 64bit multiplication
because period_ticks is a 64bit variable. The overflow occurs
for audio timer periods larger than 4294967us.

Fixes: be1092afa0 "audio: fix audio timer rate conversion bug"

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 8893a235-66a8-8fbe-7d95-862e29da90b1@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/audio/audio.c b/audio/audio.c
index 56fae5504710..abea027fdf69 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1738,7 +1738,7 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
     if (dev->timer_period <= 0) {
         s->period_ticks = 1;
     } else {
-        s->period_ticks = dev->timer_period * SCALE_US;
+        s->period_ticks = dev->timer_period * (int64_t)SCALE_US;
     }
 
     e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PULL 0/6] Audio 20200106 patches
  2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2020-01-06 12:52 ` [PULL 6/6] audio: fix integer overflow Gerd Hoffmann
@ 2020-01-06 17:44 ` Peter Maydell
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2020-01-06 17:44 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers

On Mon, 6 Jan 2020 at 12:54, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> The following changes since commit f0dcfddecee8b860e015bb07d67cfcbdfbfd51d9:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2020-01-03 17:18:08 +0000)
>
> are available in the Git repository at:
>
>   git://git.kraxel.org/qemu tags/audio-20200106-pull-request
>
> for you to fetch changes up to 40ad46d3cc463fab5a23db466f77e37aff23f927:
>
>   audio: fix integer overflow (2020-01-06 08:47:16 +0100)
>
> ----------------------------------------------------------------
> audio: bugfixes.
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-01-06 17:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-06 12:52 [PULL 0/6] Audio 20200106 patches Gerd Hoffmann
2020-01-06 12:52 ` [PULL 1/6] hda-codec: fix playback rate control Gerd Hoffmann
2020-01-06 12:52 ` [PULL 2/6] hda-codec: fix recording " Gerd Hoffmann
2020-01-06 12:52 ` [PULL 3/6] paaudio: drop recording stream in qpa_fini_in Gerd Hoffmann
2020-01-06 12:52 ` [PULL 4/6] paaudio: try to drain the recording stream Gerd Hoffmann
2020-01-06 12:52 ` [PULL 5/6] paaudio: wait until the recording stream is ready Gerd Hoffmann
2020-01-06 12:52 ` [PULL 6/6] audio: fix integer overflow Gerd Hoffmann
2020-01-06 17:44 ` [PULL 0/6] Audio 20200106 patches Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).