All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.