提交 abb1570e 编写于 作者: M Michal Privoznik 提交者: Eric Blake

Spice: support audio, images and stream compression

This extends the SPICE XML to allow variable compression settings for audio,
images and streaming:
    <graphics type='spice' port='5901' tlsPort='-1' autoport='yes'>
        <image compression='auto_glz'/>
        <jpeg compression='auto'/>
        <zlib compression='auto'/>
        <playback compression='on'/>
    </graphics>

All new elements are optional.
上级 eed9d69e
...@@ -1663,7 +1663,25 @@ qemu-kvm -net nic,model=? /dev/null ...@@ -1663,7 +1663,25 @@ qemu-kvm -net nic,model=? /dev/null
&lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt; &lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt;
&lt;channel name='main' mode='secure'/&gt; &lt;channel name='main' mode='secure'/&gt;
&lt;channel name='record' mode='insecure'/&gt; &lt;channel name='record' mode='insecure'/&gt;
&lt;image compression='auto_glz'/&gt;
&lt;/graphics&gt;</pre> &lt;/graphics&gt;</pre>
<p>
Spice supports variable compression settings for audio,
images and streaming, <span class="since">since
0.9.1</span>. These settings are accessible via
the <code>compression</code> attribute in all following
elements: <code>image</code> to set image compression
(accepts <code>auto_glz</code>, <code>auto_lz</code>,
<code>quic</code>, <code>glz</code>, <code>lz</code>,
<code>off</code>), <code>jpeg</code> for JPEG
compression for images over wan
(accepts <code>auto</code>, <code>never</code>,
<code>always</code>), <code>zlib</code> for configuring
wan image compression (accepts <code>auto</code>,
<code>never</code>, <code>always</code>)
and <code>playback</code> for enabling audio stream
compression (accepts <code>on</code> or <code>off</code>).
</p>
</dd> </dd>
<dt><code>"rdp"</code></dt> <dt><code>"rdp"</code></dt>
<dd> <dd>
......
...@@ -1260,29 +1260,81 @@ ...@@ -1260,29 +1260,81 @@
<text/> <text/>
</attribute> </attribute>
</optional> </optional>
<zeroOrMore> <interleave>
<element name="channel"> <zeroOrMore>
<attribute name="name"> <element name="channel">
<choice> <attribute name="name">
<value>main</value> <choice>
<value>display</value> <value>main</value>
<value>inputs</value> <value>display</value>
<value>cursor</value> <value>inputs</value>
<value>playback</value> <value>cursor</value>
<value>record</value> <value>playback</value>
<value>smartcard</value> <value>record</value>
</choice> <value>smartcard</value>
</attribute> </choice>
<attribute name="mode"> </attribute>
<choice> <attribute name="mode">
<value>any</value> <choice>
<value>secure</value> <value>any</value>
<value>insecure</value> <value>secure</value>
</choice> <value>insecure</value>
</attribute> </choice>
<empty/> </attribute>
</element> <empty/>
</zeroOrMore> </element>
</zeroOrMore>
<optional>
<element name="image">
<attribute name="compression">
<choice>
<value>auto_glz</value>
<value>auto_lz</value>
<value>quic</value>
<value>glz</value>
<value>lz</value>
<value>off</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
<optional>
<element name="jpeg">
<attribute name="compression">
<choice>
<value>auto</value>
<value>never</value>
<value>always</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
<optional>
<element name="zlib">
<attribute name="compression">
<choice>
<value>auto</value>
<value>never</value>
<value>always</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
<optional>
<element name="playback">
<attribute name="compression">
<choice>
<value>on</value>
<value>off</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
</interleave>
</group> </group>
<group> <group>
<attribute name="type"> <attribute name="type">
......
...@@ -322,6 +322,36 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode, ...@@ -322,6 +322,36 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode,
"secure", "secure",
"insecure"); "insecure");
VIR_ENUM_IMPL(virDomainGraphicsSpiceImageCompression,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_LAST,
"default",
"auto_glz",
"auto_lz",
"quic",
"glz",
"lz",
"off");
VIR_ENUM_IMPL(virDomainGraphicsSpiceJpegCompression,
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_LAST,
"default",
"auto",
"never",
"always");
VIR_ENUM_IMPL(virDomainGraphicsSpiceZlibCompression,
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_LAST,
"default",
"auto",
"never",
"always");
VIR_ENUM_IMPL(virDomainGraphicsSpicePlaybackCompression,
VIR_DOMAIN_GRAPHICS_SPICE_PLAYBACK_COMPRESSION_LAST,
"default",
"on",
"off");
VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST,
"subsystem", "subsystem",
"capabilities") "capabilities")
...@@ -3955,6 +3985,89 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { ...@@ -3955,6 +3985,89 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
VIR_FREE(mode); VIR_FREE(mode);
def->data.spice.channels[nameval] = modeval; def->data.spice.channels[nameval] = modeval;
} else if (xmlStrEqual(cur->name, BAD_CAST "image")) {
const char *compression = virXMLPropString(cur, "compression");
int compressionVal;
if (!compression) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("spice image missing compression"));
goto error;
}
if ((compressionVal =
virDomainGraphicsSpiceImageCompressionTypeFromString(compression)) <= 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice image compression %s"),
compression);
VIR_FREE(compression);
goto error;
}
VIR_FREE(compression);
def->data.spice.image = compressionVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "jpeg")) {
const char *compression = virXMLPropString(cur, "compression");
int compressionVal;
if (!compression) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("spice jpeg missing compression"));
goto error;
}
if ((compressionVal =
virDomainGraphicsSpiceJpegCompressionTypeFromString(compression)) <= 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice jpeg compression %s"),
compression);
VIR_FREE(compression);
goto error;
}
VIR_FREE(compression);
def->data.spice.jpeg = compressionVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "zlib")) {
const char *compression = virXMLPropString(cur, "compression");
int compressionVal;
if (!compression) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("spice zlib missing compression"));
goto error;
}
if ((compressionVal =
virDomainGraphicsSpiceZlibCompressionTypeFromString(compression)) <= 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice zlib compression %s"),
compression);
VIR_FREE(compression);
goto error;
}
def->data.spice.zlib = compressionVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "playback")) {
const char *compression = virXMLPropString(cur, "compression");
int compressionVal;
if (!compression) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("spice playback missing compression"));
goto error;
}
if ((compressionVal =
virDomainGraphicsSpicePlaybackCompressionTypeFromString(compression)) <= 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice playback compression"));
VIR_FREE(compression);
goto error;
}
VIR_FREE(compression);
def->data.spice.playback = compressionVal;
} }
} }
cur = cur->next; cur = cur->next;
...@@ -7818,6 +7931,18 @@ virDomainGraphicsDefFormat(virBufferPtr buf, ...@@ -7818,6 +7931,18 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
virDomainGraphicsSpiceChannelNameTypeToString(i), virDomainGraphicsSpiceChannelNameTypeToString(i),
virDomainGraphicsSpiceChannelModeTypeToString(mode)); virDomainGraphicsSpiceChannelModeTypeToString(mode));
} }
if (def->data.spice.image)
virBufferVSprintf(buf, " <image compression='%s'/>\n",
virDomainGraphicsSpiceImageCompressionTypeToString(def->data.spice.image));
if (def->data.spice.jpeg)
virBufferVSprintf(buf, " <jpeg compression='%s'/>\n",
virDomainGraphicsSpiceJpegCompressionTypeToString(def->data.spice.jpeg));
if (def->data.spice.zlib)
virBufferVSprintf(buf, " <zlib compression='%s'/>\n",
virDomainGraphicsSpiceZlibCompressionTypeToString(def->data.spice.zlib));
if (def->data.spice.playback)
virBufferVSprintf(buf, " <playback compression='%s'/>\n",
virDomainGraphicsSpicePlaybackCompressionTypeToString(def->data.spice.playback));
} }
if (children) { if (children) {
......
...@@ -658,6 +658,44 @@ enum virDomainGraphicsSpiceChannelMode { ...@@ -658,6 +658,44 @@ enum virDomainGraphicsSpiceChannelMode {
VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_LAST
}; };
enum virDomainGraphicsSpiceImageCompression {
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_AUTO_GLZ,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_AUTO_LZ,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_QUIC,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_GLZ,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_LZ,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_OFF,
VIR_DOMAIN_GRAPHICS_SPICE_IMAGE_COMPRESSION_LAST
};
enum virDomainGraphicsSpiceJpegCompression {
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_AUTO,
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_NEVER,
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_ALWAYS,
VIR_DOMAIN_GRAPHICS_SPICE_JPEG_COMPRESSION_LAST
};
enum virDomainGraphicsSpiceZlibCompression {
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_AUTO,
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_NEVER,
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_ALWAYS,
VIR_DOMAIN_GRAPHICS_SPICE_ZLIB_COMPRESSION_LAST
};
enum virDomainGraphicsSpicePlaybackCompression {
VIR_DOMAIN_GRAPHICS_SPICE_PLAYBACK_COMPRESSION_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_PLAYBACK_COMPRESSION_ON,
VIR_DOMAIN_GRAPHICS_SPICE_PLAYBACK_COMPRESSION_OFF,
VIR_DOMAIN_GRAPHICS_SPICE_PLAYBACK_COMPRESSION_LAST
};
typedef struct _virDomainGraphicsDef virDomainGraphicsDef; typedef struct _virDomainGraphicsDef virDomainGraphicsDef;
typedef virDomainGraphicsDef *virDomainGraphicsDefPtr; typedef virDomainGraphicsDef *virDomainGraphicsDefPtr;
struct _virDomainGraphicsDef { struct _virDomainGraphicsDef {
...@@ -695,6 +733,10 @@ struct _virDomainGraphicsDef { ...@@ -695,6 +733,10 @@ struct _virDomainGraphicsDef {
virDomainGraphicsAuthDef auth; virDomainGraphicsAuthDef auth;
unsigned int autoport :1; unsigned int autoport :1;
int channels[VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST]; int channels[VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST];
int image;
int jpeg;
int zlib;
int playback;
} spice; } spice;
} data; } data;
}; };
...@@ -1423,6 +1465,10 @@ VIR_ENUM_DECL(virDomainInputBus) ...@@ -1423,6 +1465,10 @@ VIR_ENUM_DECL(virDomainInputBus)
VIR_ENUM_DECL(virDomainGraphics) VIR_ENUM_DECL(virDomainGraphics)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceJpegCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression)
VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
/* from libvirt.h */ /* from libvirt.h */
VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainSeclabel) VIR_ENUM_DECL(virDomainSeclabel)
......
...@@ -262,6 +262,14 @@ virDomainGraphicsSpiceChannelModeTypeFromString; ...@@ -262,6 +262,14 @@ virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString; virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString; virDomainGraphicsSpiceChannelNameTypeFromString;
virDomainGraphicsSpiceChannelNameTypeToString; virDomainGraphicsSpiceChannelNameTypeToString;
virDomainGraphicsSpiceImageCompressionTypeToString;
virDomainGraphicsSpiceImageCompressionTypeFromString;
virDomainGraphicsSpiceJpegCompressionTypeFromString;
virDomainGraphicsSpiceJpegCompressionTypeToString;
virDomainGraphicsSpicePlaybackCompressionTypeFromString;
virDomainGraphicsSpicePlaybackCompressionTypeToString;
virDomainGraphicsSpiceZlibCompressionTypeFromString;
virDomainGraphicsSpiceZlibCompressionTypeToString;
virDomainGraphicsTypeFromString; virDomainGraphicsTypeFromString;
virDomainGraphicsTypeToString; virDomainGraphicsTypeToString;
virDomainHostdevDefFree; virDomainHostdevDefFree;
......
...@@ -4032,6 +4032,18 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -4032,6 +4032,18 @@ qemuBuildCommandLine(virConnectPtr conn,
break; break;
} }
} }
if (def->graphics[0]->data.spice.image)
virBufferVSprintf(&opt, ",image-compression=%s",
virDomainGraphicsSpiceImageCompressionTypeToString(def->graphics[0]->data.spice.image));
if (def->graphics[0]->data.spice.jpeg)
virBufferVSprintf(&opt, ",jpeg-wan-compression=%s",
virDomainGraphicsSpiceJpegCompressionTypeToString(def->graphics[0]->data.spice.jpeg));
if (def->graphics[0]->data.spice.zlib)
virBufferVSprintf(&opt, ",zlib-glz-wan-compression=%s",
virDomainGraphicsSpiceZlibCompressionTypeToString(def->graphics[0]->data.spice.zlib));
if (def->graphics[0]->data.spice.playback)
virBufferVSprintf(&opt, ",playback-compression=%s",
virDomainGraphicsSpicePlaybackCompressionTypeToString(def->graphics[0]->data.spice.playback));
virCommandAddArg(cmd, "-spice"); virCommandAddArg(cmd, "-spice");
virCommandAddArgBuffer(cmd, &opt); virCommandAddArgBuffer(cmd, &opt);
......
...@@ -2,6 +2,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \ ...@@ -2,6 +2,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \
/usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor \ /usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor \
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \ unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
/dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\ /dev/HostVG/QEMUGuest1 -usb -spice port=5903,tls-port=5904,addr=127.0.0.1,\
x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs -vga \ x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs,\
image-compression=auto_glz,jpeg-wan-compression=auto,zlib-glz-wan-compression=auto,\
playback-compression=on -vga \
qxl -global qxl.vram_size=18874368 -device qxl,id=video1,vram_size=33554432,bus=pci.0,addr=0x4 \ qxl -global qxl.vram_size=18874368 -device qxl,id=video1,vram_size=33554432,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
<graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'> <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
<channel name='main' mode='secure'/> <channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/> <channel name='inputs' mode='insecure'/>
<image compression='auto_glz'/>
<jpeg compression='auto'/>
<zlib compression='auto'/>
<playback compression='on'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' vram='18432' heads='1'/> <model type='qxl' vram='18432' heads='1'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册