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 <mpriv...@redhat.com> --- docs/formatdomain.rst | 35 +++++++++- src/conf/domain_conf.c | 70 +++++++++++++++++++ src/conf/domain_conf.h | 12 ++++ src/conf/schemas/domaincommon.rng | 37 ++++++++++ src/qemu/qemu_command.c | 2 + src/qemu/qemu_validate.c | 1 + .../qemuxml2argvdata/audio-pipewire-best.xml | 43 ++++++++++++ .../qemuxml2argvdata/audio-pipewire-full.xml | 43 ++++++++++++ .../audio-pipewire-minimal.xml | 36 ++++++++++ .../audio-pipewire-best.xml | 43 ++++++++++++ .../audio-pipewire-full.xml | 43 ++++++++++++ .../audio-pipewire-minimal.xml | 36 ++++++++++ tests/qemuxml2xmltest.c | 3 + 13 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-minimal.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 99383e725c..1ec68c4776 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7270,7 +7270,8 @@ to the guest sound device. ``type`` The required ``type`` attribute specifies audio backend type. Currently, the supported values are ``none``, ``alsa``, ``coreaudio``, - ``dbus``, ``jack``, ``oss``, ``pulseaudio``, ``sdl``, ``spice``, ``file``. + ``dbus``, ``jack``, ``oss``, ``pipewire``, ``pulseaudio``, ``sdl``, + ``spice``, ``file``. ``id`` Integer id of the audio device. Must be greater than 0. @@ -7354,7 +7355,7 @@ following environment variables: * ``QEMU_AUDIO_DRV`` Valid values are ``pa``, ``none``, ``alsa``, ``coreaudio``, ``jack``, ``oss``, - ``sdl``, ``spice`` or ``wav``. + ``pipewire``, ``sdl``, ``spice`` or ``wav``. None audio backend ^^^^^^^^^^^^^^^^^^ @@ -7503,6 +7504,36 @@ and ``<output>`` elements :since:`Since 6.7.0, bhyve; Since 7.2.0, qemu` +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` + PulseAudio audio backend ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6a864a8db9..62484631cc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -788,6 +788,7 @@ VIR_ENUM_IMPL(virDomainAudioType, "spice", "file", "dbus", + "pipewire", ); VIR_ENUM_IMPL(virDomainAudioSDLDriver, @@ -3226,6 +3227,13 @@ virDomainAudioIOPulseAudioFree(virDomainAudioIOPulseAudio *def) g_free(def->streamName); } +static void +virDomainAudioIOPipewireAudioFree(virDomainAudioIOPipewireAudio *def) +{ + g_free(def->name); + g_free(def->streamName); +} + void virDomainAudioDefFree(virDomainAudioDef *def) { @@ -3270,6 +3278,11 @@ virDomainAudioDefFree(virDomainAudioDef *def) g_free(def->backend.file.path); break; + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: + virDomainAudioIOPipewireAudioFree(&def->backend.pipewire.input); + virDomainAudioIOPipewireAudioFree(&def->backend.pipewire.output); + break; + case VIR_DOMAIN_AUDIO_TYPE_DBUS: case VIR_DOMAIN_AUDIO_TYPE_LAST: break; @@ -11897,6 +11910,21 @@ virDomainAudioSDLParse(virDomainAudioIOSDL *def, } +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) + return -1; + + return 0; +} + + static virDomainAudioDef * virDomainAudioDefParseXML(virDomainXMLOption *xmlopt G_GNUC_UNUSED, xmlNodePtr node, @@ -12027,6 +12055,15 @@ virDomainAudioDefParseXML(virDomainXMLOption *xmlopt G_GNUC_UNUSED, case VIR_DOMAIN_AUDIO_TYPE_DBUS: break; + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: + if (inputNode && + virDomainAudioPipewireAudioParse(&def->backend.pipewire.input, inputNode) < 0) + goto error; + if (outputNode && + virDomainAudioPipewireAudioParse(&def->backend.pipewire.output, outputNode) < 0) + goto error; + break; + case VIR_DOMAIN_AUDIO_TYPE_LAST: default: virReportEnumRangeError(virDomainAudioType, def->type); @@ -24679,6 +24716,18 @@ virDomainAudioSDLFormat(virDomainAudioIOSDL *def, } +static void +virDomainAudioPipewireAudioFormat(virDomainAudioIOPipewireAudio *def, + virBuffer *buf) +{ + virBufferEscapeString(buf, " name='%s'", def->name); + virBufferEscapeString(buf, " streamName='%s'", def->streamName); + if (def->latency) + virBufferAsprintf(buf, " latency='%u'", def->latency); + +} + + static int virDomainAudioDefFormat(virBuffer *buf, virDomainAudioDef *def) @@ -24761,6 +24810,11 @@ virDomainAudioDefFormat(virBuffer *buf, case VIR_DOMAIN_AUDIO_TYPE_DBUS: break; + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: + virDomainAudioPipewireAudioFormat(&def->backend.pipewire.input, &inputBuf); + virDomainAudioPipewireAudioFormat(&def->backend.pipewire.output, &outputBuf); + break; + case VIR_DOMAIN_AUDIO_TYPE_LAST: default: virReportEnumRangeError(virDomainAudioType, def->type); @@ -29065,6 +29119,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; +} + + static bool virDomainAudioBackendIsEqual(virDomainAudioDef *this, virDomainAudioDef *that) @@ -29125,6 +29189,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); + case VIR_DOMAIN_AUDIO_TYPE_DBUS: case VIR_DOMAIN_AUDIO_TYPE_LAST: default: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c1cb2ed69d..7abac25ae1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1614,6 +1614,7 @@ typedef enum { VIR_DOMAIN_AUDIO_TYPE_SPICE, VIR_DOMAIN_AUDIO_TYPE_FILE, VIR_DOMAIN_AUDIO_TYPE_DBUS, + VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE, VIR_DOMAIN_AUDIO_TYPE_LAST } virDomainAudioType; @@ -1689,6 +1690,13 @@ struct _virDomainAudioIOSDL { unsigned int bufferCount; }; +typedef struct _virDomainAudioIOPipewireAudio virDomainAudioIOPipewireAudio; +struct _virDomainAudioIOPipewireAudio { + char *name; + char *streamName; + unsigned int latency; +}; + struct _virDomainAudioDef { virDomainAudioType type; @@ -1732,6 +1740,10 @@ struct _virDomainAudioDef { struct { char *path; } file; + struct { + virDomainAudioIOPipewireAudio input; + virDomainAudioIOPipewireAudio output; + } pipewire; } backend; }; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index f8c7b6a648..793544e15e 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -5121,6 +5121,26 @@ <ref name="audiocommonchild"/> </define> + <define name="audiopipewire"> + <ref name="audiocommonattr"/> + <optional> + <attribute name="name"> + <data type="string"/> + </attribute> + </optional> + <optional> + <attribute name="streamName"> + <data type="string"/> + </attribute> + </optional> + <optional> + <attribute name="latency"> + <ref name="uint32"/> + </attribute> + </optional> + <ref name="audiocommonchild"/> + </define> + <define name="audiopulseaudio"> <ref name="audiocommonattr"/> <optional> @@ -5296,6 +5316,23 @@ </optional> </interleave> </group> + <group> + <attribute name="type"> + <value>pipewire</value> + </attribute> + <interleave> + <optional> + <element name="input"> + <ref name="audiopipewire"/> + </element> + </optional> + <optional> + <element name="output"> + <ref name="audiopipewire"/> + </element> + </optional> + </interleave> + </group> <group> <attribute name="type"> <value>pulseaudio</value> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 2a6d9408f6..3a08cac870 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -142,6 +142,7 @@ qemuAudioDriverTypeToString(virDomainAudioType type) case VIR_DOMAIN_AUDIO_TYPE_SDL: case VIR_DOMAIN_AUDIO_TYPE_SPICE: case VIR_DOMAIN_AUDIO_TYPE_DBUS: + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: case VIR_DOMAIN_AUDIO_TYPE_LAST: break; } @@ -7887,6 +7888,7 @@ qemuBuildAudioCommandLineArg(virCommand *cmd, case VIR_DOMAIN_AUDIO_TYPE_DBUS: break; + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: case VIR_DOMAIN_AUDIO_TYPE_LAST: default: virReportEnumRangeError(virDomainAudioType, def->type); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index da4b9a3b35..90e2517649 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4476,6 +4476,7 @@ qemuValidateDomainDeviceDefAudio(virDomainAudioDef *audio, case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO: case VIR_DOMAIN_AUDIO_TYPE_SDL: case VIR_DOMAIN_AUDIO_TYPE_FILE: + case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: break; case VIR_DOMAIN_AUDIO_TYPE_SPICE: diff --git a/tests/qemuxml2argvdata/audio-pipewire-best.xml b/tests/qemuxml2argvdata/audio-pipewire-best.xml new file mode 100644 index 0000000000..e71688d25b --- /dev/null +++ b/tests/qemuxml2argvdata/audio-pipewire-best.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire' timerPeriod='50'> + <input mixingEngine='yes' fixedSettings='yes' voices='1' bufferLength='200' name='fish'> + <settings frequency='44100' channels='2' format='s16'/> + </input> + <output mixingEngine='yes' fixedSettings='yes' voices='2' bufferLength='200' name='fish'> + <settings frequency='22050' channels='4' format='f32'/> + </output> + </audio> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/audio-pipewire-full.xml b/tests/qemuxml2argvdata/audio-pipewire-full.xml new file mode 100644 index 0000000000..5811eef6d4 --- /dev/null +++ b/tests/qemuxml2argvdata/audio-pipewire-full.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire'> + <input mixingEngine='yes' fixedSettings='yes' voices='1' bufferLength='100' name='fish' streamName='food' latency='100'> + <settings frequency='44100' channels='2' format='s16'/> + </input> + <output mixingEngine='yes' fixedSettings='yes' voices='2' bufferLength='200' name='fish' streamName='food' latency='200'> + <settings frequency='22050' channels='4' format='f32'/> + </output> + </audio> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/audio-pipewire-minimal.xml b/tests/qemuxml2argvdata/audio-pipewire-minimal.xml new file mode 100644 index 0000000000..2085225722 --- /dev/null +++ b/tests/qemuxml2argvdata/audio-pipewire-minimal.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/audio-pipewire-best.xml b/tests/qemuxml2xmloutdata/audio-pipewire-best.xml new file mode 100644 index 0000000000..e71688d25b --- /dev/null +++ b/tests/qemuxml2xmloutdata/audio-pipewire-best.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire' timerPeriod='50'> + <input mixingEngine='yes' fixedSettings='yes' voices='1' bufferLength='200' name='fish'> + <settings frequency='44100' channels='2' format='s16'/> + </input> + <output mixingEngine='yes' fixedSettings='yes' voices='2' bufferLength='200' name='fish'> + <settings frequency='22050' channels='4' format='f32'/> + </output> + </audio> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/audio-pipewire-full.xml b/tests/qemuxml2xmloutdata/audio-pipewire-full.xml new file mode 100644 index 0000000000..5811eef6d4 --- /dev/null +++ b/tests/qemuxml2xmloutdata/audio-pipewire-full.xml @@ -0,0 +1,43 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire'> + <input mixingEngine='yes' fixedSettings='yes' voices='1' bufferLength='100' name='fish' streamName='food' latency='100'> + <settings frequency='44100' channels='2' format='s16'/> + </input> + <output mixingEngine='yes' fixedSettings='yes' voices='2' bufferLength='200' name='fish' streamName='food' latency='200'> + <settings frequency='22050' channels='4' format='f32'/> + </output> + </audio> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/audio-pipewire-minimal.xml b/tests/qemuxml2xmloutdata/audio-pipewire-minimal.xml new file mode 100644 index 0000000000..2085225722 --- /dev/null +++ b/tests/qemuxml2xmloutdata/audio-pipewire-minimal.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='cdrom'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/cdrom'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='pipewire'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 93202e8e18..df019023d0 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1175,6 +1175,7 @@ mymain(void) DO_TEST_NOCAPS("audio-coreaudio-minimal"); DO_TEST_NOCAPS("audio-oss-minimal"); DO_TEST_NOCAPS("audio-pulseaudio-minimal"); + DO_TEST_NOCAPS("audio-pipewire-minimal"); DO_TEST_NOCAPS("audio-sdl-minimal"); DO_TEST("audio-spice-minimal", QEMU_CAPS_SPICE, @@ -1187,6 +1188,7 @@ mymain(void) DO_TEST_NOCAPS("audio-coreaudio-best"); DO_TEST_NOCAPS("audio-oss-best"); DO_TEST_NOCAPS("audio-pulseaudio-best"); + DO_TEST_NOCAPS("audio-pipewire-best"); DO_TEST_NOCAPS("audio-sdl-best"); DO_TEST("audio-spice-best", QEMU_CAPS_SPICE, @@ -1200,6 +1202,7 @@ mymain(void) DO_TEST_NOCAPS("audio-jack-full"); DO_TEST_NOCAPS("audio-oss-full"); DO_TEST_NOCAPS("audio-pulseaudio-full"); + DO_TEST_NOCAPS("audio-pipewire-full"); DO_TEST_NOCAPS("audio-sdl-full"); DO_TEST("audio-spice-full", QEMU_CAPS_SPICE, -- 2.39.3