mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
conf: add support for audio backend specific settings
This pulls in the remaining QEMU audio backend specific settings to the XML schema. <audio id="1" type="alsa"> <input dev="/dev/dsp0"/> <output dev="/dev/dsp1"/> </audio> <audio id="1" type="coreaudio"> <input bufferCount="50"/> <output bufferCount="42"/> </audio> <audio id="1" type="file" path="audio.wav"/> <audio id="1" type="jack"> <input serverName="fish" clientName="food" connectPorts="yum"/> <output serverName="fish" clientName="food" connectPorts="yum"/> </audio> <audio id="1" type="oss" tryMMap="yes" exclusive="yes" dspPolicy="3"> <input dev="/dev/dsp0" bufferCount="50" tryPoll="yes"/> <output dev="/dev/dsp1" bufferCount="30" tryPoll="no"/> </audio> <audio id="1" type="pulseaudio" serverName="acme.example.org"> <input name="fish" streamName="food" latency="100"/> <output name="fish" streamName="food" latency="200"/> </audio> <audio type='sdl' id='1' driver='pulseaudio'> <input bufferCount='40'/> <output bufferCount='40'/> </audio> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
c99e72d18d
commit
3e97d81a81
@ -6929,29 +6929,6 @@ ALSA audio backend
|
||||
|
||||
The 'alsa' audio type uses the ALSA host audio device framework.
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
Coreaudio audio backend
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'coreaudio' audio backend delegates to a CoreAudio host audio framework
|
||||
for input and output on macOS.
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
Jack audio backend
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'jack' audio backend delegates to a Jack daemon for audio input
|
||||
and output.
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
OSS audio backend
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'oss' audio type uses the OSS host audio device framework.
|
||||
|
||||
The following additional attributes are permitted on the ``<input>``
|
||||
and ``<output>`` elements
|
||||
|
||||
@ -6962,9 +6939,116 @@ and ``<output>`` elements
|
||||
|
||||
::
|
||||
|
||||
<audio type='oss' id='1'>
|
||||
<input dev='/dev/dsp0'/>
|
||||
<output dev='/dev/dsp0'/>
|
||||
<audio id="1" type="alsa">
|
||||
<input dev="/dev/dsp0"/>
|
||||
<output dev="/dev/dsp1"/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
Coreaudio audio backend
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'coreaudio' audio backend delegates to a CoreAudio host audio framework
|
||||
for input and output on macOS.
|
||||
|
||||
The following additional attributes are permitted on the ``<input>``
|
||||
and ``<output>`` elements
|
||||
|
||||
* ``bufferCount``
|
||||
|
||||
The number of buffers. It is recommended to set the ``bufferLength``
|
||||
attribute at the same time.
|
||||
|
||||
::
|
||||
|
||||
<audio id="1" type="coreaudio">
|
||||
<input bufferCount="50"/>
|
||||
<output bufferCount="42"/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
Jack audio backend
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'jack' audio backend delegates to a Jack daemon for audio input
|
||||
and output.
|
||||
|
||||
The following additional attributes are permitted on the ``<input>``
|
||||
and ``<output>`` elements
|
||||
|
||||
* ``serverName``
|
||||
|
||||
Select the Jack server instance to connect to.
|
||||
|
||||
* ``clientName``
|
||||
|
||||
The client name to identify as. The server may modify this to
|
||||
ensure uniqueness unless ``exactName`` is enabled
|
||||
|
||||
* ``connectPorts``
|
||||
|
||||
A regular expression of Jack client port names to monitor and
|
||||
connect to.
|
||||
|
||||
* ``exactName``
|
||||
|
||||
Use the exact ``clientName`` requested
|
||||
|
||||
::
|
||||
|
||||
<audio id="1" type="jack">
|
||||
<input serverName="fish" clientName="food" connectPorts="system:capture_[13]" exactName="yes"/>
|
||||
<output serverName="fish" clientName="food" connectPorts="system:playback_[13]" exactName="yes"/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
OSS audio backend
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 'oss' audio type uses the OSS host audio device framework.
|
||||
|
||||
The following additional attributes are permitted on the ``<audio>``
|
||||
element
|
||||
|
||||
* ``tryMMap``
|
||||
|
||||
Attempt to use mmap for data transfer
|
||||
|
||||
* ``exclusive``
|
||||
|
||||
Enforce exclusive access to the host device
|
||||
|
||||
* ``dspPolicy``
|
||||
|
||||
Set the timing policy of the device, values between -1 and 10.
|
||||
Smaller numbers result in lower latency but higher CPU usage.
|
||||
A negatve value requests use of fragment mode.
|
||||
|
||||
The following additional attributes are permitted on the ``<input>``
|
||||
and ``<output>`` elements
|
||||
|
||||
* ``dev``
|
||||
|
||||
Path to the host device node to connect the backend to. A hypervisor
|
||||
specific default applies if not specified.
|
||||
|
||||
* ``bufferCount``
|
||||
|
||||
The number of buffers. It is recommended to set the ``bufferLength``
|
||||
attribute at the same time.
|
||||
|
||||
* ``tryPoll``
|
||||
|
||||
Attempt to use polling mode
|
||||
|
||||
::
|
||||
|
||||
<audio type='oss' id='1' tryMMap='yes' exclusive='yes' dspPolicy='4'>
|
||||
<input dev='/dev/dsp0' bufferCount='40' tryPoll='yes'/>
|
||||
<output dev='/dev/dsp0' bufferCount='40' tryPoll='yes'/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 6.7.0, bhyve; Since 7.2.0, qemu`
|
||||
@ -6975,6 +7059,35 @@ PulseAudio audio backend
|
||||
The 'pulseaudio' audio backend delegates to a PulseAudio daemon audio input
|
||||
and output.
|
||||
|
||||
The following additional attributes are permitted on the ``<audio>``
|
||||
element
|
||||
|
||||
* ``serverName``
|
||||
|
||||
Hostname of the PulseAudio server
|
||||
|
||||
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="pulseaudio" serverName="acme.example.org">
|
||||
<input name="fish" streamName="food" latency="100"/>
|
||||
<output name="fish" streamName="food" latency="200"/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
SDL audio backend
|
||||
@ -6991,9 +7104,20 @@ element
|
||||
SDL audio driver. The ``name`` attribute specifies SDL driver name,
|
||||
one of 'esd', 'alsa', 'arts', 'pulseaudio'.
|
||||
|
||||
The following additional attributes are permitted on the ``<input>``
|
||||
and ``<output>`` elements
|
||||
|
||||
* ``bufferCount``
|
||||
|
||||
The number of buffers. It is recommended to set the ``bufferLength``
|
||||
attribute at the same time.
|
||||
|
||||
::
|
||||
|
||||
<audio type='sdl' id='1' driver='pulseaudio'/>
|
||||
<audio type='sdl' id='1' driver='pulseaudio'>
|
||||
<input bufferCount='40'/>
|
||||
<output bufferCount='40'/>
|
||||
</audio>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
@ -7005,6 +7129,10 @@ it does not connect to any host audio framework. It exclusively
|
||||
allows a SPICE server to send and receive audio. This is the default
|
||||
backend when SPICE graphics are enabled in QEMU.
|
||||
|
||||
::
|
||||
|
||||
<audio type='spice' id='1'/>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
File audio backend
|
||||
@ -7014,6 +7142,10 @@ The 'file' audio backend is an output only driver which records
|
||||
audio to a file. The file format is implementation defined, and
|
||||
defaults to 'WAV' with QEMU.
|
||||
|
||||
::
|
||||
|
||||
<audio id="1" type="file" path="audio.wav"/>
|
||||
|
||||
:since:`Since 7.2.0, qemu`
|
||||
|
||||
:anchor:`<a id="elementsWatchdog"/>`
|
||||
|
@ -4608,6 +4608,26 @@
|
||||
|
||||
<define name="audiojack">
|
||||
<ref name="audiocommonattr"/>
|
||||
<optional>
|
||||
<attribute name="serverName">
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="clientName">
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="connectPorts">
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="exactName">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<ref name="audiocommonchild"/>
|
||||
</define>
|
||||
|
||||
@ -4618,16 +4638,46 @@
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="bufferCount">
|
||||
<ref name="uint32"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="tryPoll">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<ref name="audiocommonchild"/>
|
||||
</define>
|
||||
|
||||
<define name="audiopulseaudio">
|
||||
<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="audiosdl">
|
||||
<ref name="audiocommonattr"/>
|
||||
<optional>
|
||||
<attribute name="bufferCount">
|
||||
<ref name="uint32"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<ref name="audiocommonchild"/>
|
||||
</define>
|
||||
|
||||
@ -4721,6 +4771,21 @@
|
||||
<value>oss</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="tryMMap">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="exclusive">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="dspPolicy">
|
||||
<data type="int"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="input">
|
||||
@ -4738,6 +4803,11 @@
|
||||
<attribute name="type">
|
||||
<value>pulseaudio</value>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="serverName">
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="input">
|
||||
@ -4799,6 +4869,11 @@
|
||||
<attribute name="type">
|
||||
<value>file</value>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="path">
|
||||
<ref name="filePath"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="input">
|
||||
|
@ -2918,12 +2918,33 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
|
||||
g_free(def);
|
||||
}
|
||||
|
||||
static void
|
||||
virDomainAudioIOALSAFree(virDomainAudioIOALSAPtr def)
|
||||
{
|
||||
g_free(def->dev);
|
||||
}
|
||||
|
||||
static void
|
||||
virDomainAudioIOJackFree(virDomainAudioIOJackPtr def)
|
||||
{
|
||||
g_free(def->serverName);
|
||||
g_free(def->clientName);
|
||||
g_free(def->connectPorts);
|
||||
}
|
||||
|
||||
static void
|
||||
virDomainAudioIOOSSFree(virDomainAudioIOOSSPtr def)
|
||||
{
|
||||
g_free(def->dev);
|
||||
}
|
||||
|
||||
static void
|
||||
virDomainAudioIOPulseAudioFree(virDomainAudioIOPulseAudioPtr def)
|
||||
{
|
||||
g_free(def->name);
|
||||
g_free(def->streamName);
|
||||
}
|
||||
|
||||
void
|
||||
virDomainAudioDefFree(virDomainAudioDefPtr def)
|
||||
{
|
||||
@ -2935,12 +2956,16 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
|
||||
virDomainAudioIOALSAFree(&def->backend.alsa.input);
|
||||
virDomainAudioIOALSAFree(&def->backend.alsa.output);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_JACK:
|
||||
virDomainAudioIOJackFree(&def->backend.jack.input);
|
||||
virDomainAudioIOJackFree(&def->backend.jack.output);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_OSS:
|
||||
@ -2949,6 +2974,9 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
|
||||
virDomainAudioIOPulseAudioFree(&def->backend.pulseaudio.input);
|
||||
virDomainAudioIOPulseAudioFree(&def->backend.pulseaudio.output);
|
||||
g_free(def->backend.pulseaudio.serverName);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_SDL:
|
||||
@ -2958,6 +2986,7 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_FILE:
|
||||
g_free(def->backend.file.path);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_LAST:
|
||||
@ -14046,12 +14075,118 @@ virDomainAudioCommonParse(virDomainAudioIOCommonPtr def,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioALSAParse(virDomainAudioIOALSAPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
def->dev = virXMLPropString(node, "dev");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainAudioCoreAudioParse(virDomainAudioIOCoreAudioPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
|
||||
|
||||
if (bufferCount &&
|
||||
virStrToLong_ui(bufferCount, NULL, 10,
|
||||
&def->bufferCount) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainAudioJackParse(virDomainAudioIOJackPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
g_autofree char *exactName = virXMLPropString(node, "exactName");
|
||||
|
||||
def->serverName = virXMLPropString(node, "serverName");
|
||||
def->clientName = virXMLPropString(node, "clientName");
|
||||
def->connectPorts = virXMLPropString(node, "connectPorts");
|
||||
|
||||
if (exactName &&
|
||||
((def->exactName =
|
||||
virTristateBoolTypeFromString(exactName)) <= 0)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unknown 'exactName' value '%s'"), exactName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainAudioOSSParse(virDomainAudioIOOSSPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
g_autofree char *tryPoll = virXMLPropString(node, "tryPoll");
|
||||
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
|
||||
|
||||
def->dev = virXMLPropString(node, "dev");
|
||||
|
||||
if (tryPoll &&
|
||||
((def->tryPoll =
|
||||
virTristateBoolTypeFromString(tryPoll)) <= 0)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unknown 'tryPoll' value '%s'"), tryPoll);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bufferCount &&
|
||||
virStrToLong_ui(bufferCount, NULL, 10,
|
||||
&def->bufferCount) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainAudioPulseAudioParse(virDomainAudioIOPulseAudioPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
g_autofree char *latency = virXMLPropString(node, "latency");
|
||||
|
||||
def->name = virXMLPropString(node, "name");
|
||||
def->streamName = virXMLPropString(node, "streamName");
|
||||
|
||||
if (latency &&
|
||||
virStrToLong_ui(latency, NULL, 10,
|
||||
&def->latency) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("cannot parse 'latency' value '%s'"), latency);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainAudioSDLParse(virDomainAudioIOSDLPtr def,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
|
||||
|
||||
if (bufferCount &&
|
||||
virStrToLong_ui(bufferCount, NULL, 10,
|
||||
&def->bufferCount) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -14109,22 +14244,69 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
|
||||
if (inputNode)
|
||||
virDomainAudioALSAParse(&def->backend.alsa.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioALSAParse(&def->backend.alsa.output, outputNode);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
|
||||
if (inputNode)
|
||||
virDomainAudioCoreAudioParse(&def->backend.coreaudio.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioCoreAudioParse(&def->backend.coreaudio.output, outputNode);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_JACK:
|
||||
if (inputNode)
|
||||
virDomainAudioJackParse(&def->backend.jack.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioJackParse(&def->backend.jack.output, outputNode);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_OSS:
|
||||
case VIR_DOMAIN_AUDIO_TYPE_OSS: {
|
||||
g_autofree char *tryMMap = virXMLPropString(node, "tryMMap");
|
||||
g_autofree char *exclusive = virXMLPropString(node, "exclusive");
|
||||
g_autofree char *dspPolicy = virXMLPropString(node, "dspPolicy");
|
||||
|
||||
if (tryMMap && ((def->backend.oss.tryMMap =
|
||||
virTristateBoolTypeFromString(tryMMap)) <= 0)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unknown 'tryMMap' value '%s'"), tryMMap);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (exclusive && ((def->backend.oss.exclusive =
|
||||
virTristateBoolTypeFromString(exclusive)) <= 0)) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unknown 'exclusive' value '%s'"), exclusive);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dspPolicy) {
|
||||
if (virStrToLong_i(dspPolicy, NULL, 10,
|
||||
&def->backend.oss.dspPolicy) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("cannot parse 'dspPolicy' value '%s'"), dspPolicy);
|
||||
goto error;
|
||||
}
|
||||
def->backend.oss.dspPolicySet = true;
|
||||
}
|
||||
|
||||
if (inputNode)
|
||||
virDomainAudioOSSParse(&def->backend.oss.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioOSSParse(&def->backend.oss.output, outputNode);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
|
||||
def->backend.pulseaudio.serverName = virXMLPropString(node, "serverName");
|
||||
|
||||
if (inputNode)
|
||||
virDomainAudioPulseAudioParse(&def->backend.pulseaudio.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioPulseAudioParse(&def->backend.pulseaudio.output, outputNode);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_SDL: {
|
||||
@ -14136,6 +14318,11 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
|
||||
_("unknown SDL driver '%s'"), driver);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (inputNode)
|
||||
virDomainAudioSDLParse(&def->backend.sdl.input, inputNode);
|
||||
if (outputNode)
|
||||
virDomainAudioSDLParse(&def->backend.sdl.output, outputNode);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -14143,6 +14330,7 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_FILE:
|
||||
def->backend.file.path = virXMLPropString(node, "path");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_LAST:
|
||||
@ -26635,11 +26823,68 @@ virDomainAudioCommonFormat(virDomainAudioIOCommonPtr def,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioALSAFormat(virDomainAudioIOALSAPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
virBufferEscapeString(buf, " dev='%s'", def->dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioCoreAudioFormat(virDomainAudioIOCoreAudioPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
if (def->bufferCount)
|
||||
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioJackFormat(virDomainAudioIOJackPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
virBufferEscapeString(buf, " serverName='%s'", def->serverName);
|
||||
virBufferEscapeString(buf, " clientName='%s'", def->clientName);
|
||||
virBufferEscapeString(buf, " connectPorts='%s'", def->connectPorts);
|
||||
if (def->exactName)
|
||||
virBufferAsprintf(buf, " exactName='%s'",
|
||||
virTristateBoolTypeToString(def->exactName));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioOSSFormat(virDomainAudioIOOSSPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
virBufferEscapeString(buf, " dev='%s'", def->dev);
|
||||
if (def->bufferCount)
|
||||
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
|
||||
if (def->tryPoll)
|
||||
virBufferAsprintf(buf, " tryPoll='%s'",
|
||||
virTristateBoolTypeToString(def->tryPoll));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioPulseAudioFormat(virDomainAudioIOPulseAudioPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
virBufferEscapeString(buf, " name='%s'", def->name);
|
||||
virBufferEscapeString(buf, " streamName='%s'", def->streamName);
|
||||
if (def->latency)
|
||||
virBufferAsprintf(buf, " latency='%u'", def->latency);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainAudioSDLFormat(virDomainAudioIOSDLPtr def,
|
||||
virBufferPtr buf)
|
||||
{
|
||||
if (def->bufferCount)
|
||||
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
|
||||
}
|
||||
|
||||
|
||||
@ -26665,20 +26910,40 @@ virDomainAudioDefFormat(virBufferPtr buf,
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
|
||||
virDomainAudioALSAFormat(&def->backend.alsa.input, &inputBuf);
|
||||
virDomainAudioALSAFormat(&def->backend.alsa.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
|
||||
virDomainAudioCoreAudioFormat(&def->backend.coreaudio.input, &inputBuf);
|
||||
virDomainAudioCoreAudioFormat(&def->backend.coreaudio.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_JACK:
|
||||
virDomainAudioJackFormat(&def->backend.jack.input, &inputBuf);
|
||||
virDomainAudioJackFormat(&def->backend.jack.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_OSS:
|
||||
if (def->backend.oss.tryMMap)
|
||||
virBufferAsprintf(buf, " tryMMap='%s'",
|
||||
virTristateBoolTypeToString(def->backend.oss.tryMMap));
|
||||
if (def->backend.oss.exclusive)
|
||||
virBufferAsprintf(buf, " exclusive='%s'",
|
||||
virTristateBoolTypeToString(def->backend.oss.exclusive));
|
||||
if (def->backend.oss.dspPolicySet)
|
||||
virBufferAsprintf(buf, " dspPolicy='%d'", def->backend.oss.dspPolicy);
|
||||
|
||||
virDomainAudioOSSFormat(&def->backend.oss.input, &inputBuf);
|
||||
virDomainAudioOSSFormat(&def->backend.oss.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
|
||||
virBufferEscapeString(buf, " serverName='%s'",
|
||||
def->backend.pulseaudio.serverName);
|
||||
|
||||
virDomainAudioPulseAudioFormat(&def->backend.pulseaudio.input, &inputBuf);
|
||||
virDomainAudioPulseAudioFormat(&def->backend.pulseaudio.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_SDL:
|
||||
@ -26686,12 +26951,16 @@ virDomainAudioDefFormat(virBufferPtr buf,
|
||||
virBufferAsprintf(buf, " driver='%s'",
|
||||
virDomainAudioSDLDriverTypeToString(
|
||||
def->backend.sdl.driver));
|
||||
|
||||
virDomainAudioSDLFormat(&def->backend.sdl.input, &inputBuf);
|
||||
virDomainAudioSDLFormat(&def->backend.sdl.output, &outputBuf);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_FILE:
|
||||
virBufferEscapeString(buf, " path='%s'", def->backend.file.path);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_AUDIO_TYPE_LAST:
|
||||
|
@ -1494,11 +1494,47 @@ struct _virDomainAudioIOCommon {
|
||||
unsigned int bufferLength; /* milliseconds */
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOALSA virDomainAudioIOALSA;
|
||||
typedef virDomainAudioIOALSA *virDomainAudioIOALSAPtr;
|
||||
struct _virDomainAudioIOALSA {
|
||||
char *dev;
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOCoreAudio virDomainAudioIOCoreAudio;
|
||||
typedef virDomainAudioIOCoreAudio *virDomainAudioIOCoreAudioPtr;
|
||||
struct _virDomainAudioIOCoreAudio {
|
||||
unsigned int bufferCount;
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOJack virDomainAudioIOJack;
|
||||
typedef virDomainAudioIOJack *virDomainAudioIOJackPtr;
|
||||
struct _virDomainAudioIOJack {
|
||||
char *serverName;
|
||||
char *clientName;
|
||||
char *connectPorts;
|
||||
virTristateBool exactName;
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOOSS virDomainAudioIOOSS;
|
||||
typedef virDomainAudioIOOSS *virDomainAudioIOOSSPtr;
|
||||
struct _virDomainAudioIOOSS {
|
||||
char *dev;
|
||||
unsigned int bufferCount;
|
||||
virTristateBool tryPoll;
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOPulseAudio virDomainAudioIOPulseAudio;
|
||||
typedef virDomainAudioIOPulseAudio *virDomainAudioIOPulseAudioPtr;
|
||||
struct _virDomainAudioIOPulseAudio {
|
||||
char *name;
|
||||
char *streamName;
|
||||
unsigned int latency;
|
||||
};
|
||||
|
||||
typedef struct _virDomainAudioIOSDL virDomainAudioIOSDL;
|
||||
typedef virDomainAudioIOSDL *virDomainAudioIOSDLPtr;
|
||||
struct _virDomainAudioIOSDL {
|
||||
unsigned int bufferCount;
|
||||
};
|
||||
|
||||
struct _virDomainAudioDef {
|
||||
@ -1509,13 +1545,39 @@ struct _virDomainAudioDef {
|
||||
virDomainAudioIOCommon input;
|
||||
virDomainAudioIOCommon output;
|
||||
union {
|
||||
struct {
|
||||
virDomainAudioIOALSA input;
|
||||
virDomainAudioIOALSA output;
|
||||
} alsa;
|
||||
struct {
|
||||
virDomainAudioIOCoreAudio input;
|
||||
virDomainAudioIOCoreAudio output;
|
||||
} coreaudio;
|
||||
struct {
|
||||
virDomainAudioIOJack input;
|
||||
virDomainAudioIOJack output;
|
||||
} jack;
|
||||
struct {
|
||||
virDomainAudioIOOSS input;
|
||||
virDomainAudioIOOSS output;
|
||||
virTristateBool tryMMap;
|
||||
virTristateBool exclusive;
|
||||
bool dspPolicySet;
|
||||
int dspPolicy;
|
||||
} oss;
|
||||
struct {
|
||||
virDomainAudioIOPulseAudio input;
|
||||
virDomainAudioIOPulseAudio output;
|
||||
char *serverName;
|
||||
} pulseaudio;
|
||||
struct {
|
||||
virDomainAudioIOSDL input;
|
||||
virDomainAudioIOSDL output;
|
||||
int driver; /* virDomainAudioSDLDriver */
|
||||
} sdl;
|
||||
struct {
|
||||
char *path;
|
||||
} file;
|
||||
} backend;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user