
On Tue, Nov 07, 2023 at 13:55:22 +0100, Michal Privoznik wrote:
QEMU gained support for PipeWire audio backend (see QEMU commit of v8.0.0-403-gc2d3d1c294). Its configuration knobs are basically the same as pulseaudio's, except for PA's server name. Therefore, a lot of code is copied over from pulseadio and fixed by s/Pulse/Pipewire/ or s/pulseaudio/pipewire/.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> ---
[...]
+PipeWire audio backend +^^^^^^^^^^^^^^^^^^^^^^ + +The ``pipewire`` audio backend delegates to a PipeWire daemon audio input and +output. + +The following additional attributes are permitted on the ``<input/>`` and +``<output/>`` elements: + +* ``name`` + + The sink/source name to use + +* ``streamName`` + + The name to identify the stream associated with the VM + +* ``latency`` + + Desired latency for the server to target in microseconds + +:: + + <audio id="1" type="pipewire"> + <input name="fish" streamName="food" latency="100"/> + <output name="fish" streamName="food" latency="200"/> + </audio> + +:since:`Since 9.4.0, qemu`
This is a bit stale ;)
+static int +virDomainAudioPipewireAudioParse(virDomainAudioIOPipewireAudio *def, + xmlNodePtr node) +{ + def->name = virXMLPropString(node, "name"); + def->streamName = virXMLPropString(node, "streamName"); + + if (virXMLPropUInt(node, "latency", 10, VIR_XML_PROP_NONE, + &def->latency) < 0)
You probably want VIR_XML_PROP_NONZERO, as ...
+ return -1; + + return 0; +}
[...]
+static void +virDomainAudioPipewireAudioFormat(virDomainAudioIOPipewireAudio *def, + virBuffer *buf) +{ + virBufferEscapeString(buf, " name='%s'", def->name); + virBufferEscapeString(buf, " streamName='%s'", def->streamName); + if (def->latency)
... 0 is considered as default.
+ virBufferAsprintf(buf, " latency='%u'", def->latency); + +}
[...]
@@ -29267,6 +29321,16 @@ virDomainAudioIOSDLIsEqual(virDomainAudioIOSDL *this, }
+static bool +virDomainAudioIOPipewireAudioIsEqual(virDomainAudioIOPipewireAudio *this, + virDomainAudioIOPipewireAudio *that) +{ + return STREQ_NULLABLE(this->name, that->name) && + STREQ_NULLABLE(this->streamName, that->streamName) && + this->latency == that->latency;
'this' and 'that' share too much of a prefix to be easily visually distinguishible .... but ...
+} + + static bool virDomainAudioBackendIsEqual(virDomainAudioDef *this, virDomainAudioDef *that)
.... it seems to be prior art, unfortunately.
@@ -29327,6 +29391,12 @@ virDomainAudioBackendIsEqual(virDomainAudioDef *this, case VIR_DOMAIN_AUDIO_TYPE_FILE: return STREQ_NULLABLE(this->backend.file.path, that->backend.file.path);
+ case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: + return virDomainAudioIOPipewireAudioIsEqual(&this->backend.pipewire.input, + &that->backend.pipewire.input) && + virDomainAudioIOPipewireAudioIsEqual(&this->backend.pipewire.output, + &that->backend.pipewire.output);
The alignment here is rather funky. Did the mailing list mess this up?
+ case VIR_DOMAIN_AUDIO_TYPE_DBUS: case VIR_DOMAIN_AUDIO_TYPE_LAST: default:
With the default of the latency properly handled: Reviewed-by: Peter Krempa <pkrempa@redhat.com>