]> xenbits.xensource.com Git - libvirt.git/commitdiff
Spice: support audio, images and stream compression
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 14 Apr 2011 08:44:20 +0000 (10:44 +0200)
committerEric Blake <eblake@redhat.com>
Thu, 14 Apr 2011 16:23:59 +0000 (10:23 -0600)
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.

docs/formatdomain.html.in
docs/schemas/domain.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml

index 6ffb0d2be7ef2e7b50edeb2e0b871f206a63cd92..a055b38ec4bbe13f861221d4baa3693e2891a9e9 100644 (file)
@@ -1663,7 +1663,25 @@ qemu-kvm -net nic,model=? /dev/null
   &lt;graphics type='spice' port='-1' tlsPort='-1' autoport='yes'&gt;
     &lt;channel name='main' mode='secure'/&gt;
     &lt;channel name='record' mode='insecure'/&gt;
+    &lt;image compression='auto_glz'/&gt;
   &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>
           <dt><code>"rdp"</code></dt>
           <dd>
index 0fbf326886ad241d45c1c303c9a91320997ba8c8..7163c6e18637b53f8d6f422b23ddb509ab4039da 100644 (file)
               <text/>
             </attribute>
           </optional>
-          <zeroOrMore>
-            <element name="channel">
-              <attribute name="name">
-                <choice>
-                  <value>main</value>
-                  <value>display</value>
-                  <value>inputs</value>
-                  <value>cursor</value>
-                  <value>playback</value>
-                  <value>record</value>
-                  <value>smartcard</value>
-                </choice>
-              </attribute>
-              <attribute name="mode">
-                <choice>
-                  <value>any</value>
-                  <value>secure</value>
-                  <value>insecure</value>
-                </choice>
-              </attribute>
-              <empty/>
-            </element>
-          </zeroOrMore>
+          <interleave>
+            <zeroOrMore>
+              <element name="channel">
+                <attribute name="name">
+                  <choice>
+                    <value>main</value>
+                    <value>display</value>
+                    <value>inputs</value>
+                    <value>cursor</value>
+                    <value>playback</value>
+                    <value>record</value>
+                    <value>smartcard</value>
+                  </choice>
+                </attribute>
+                <attribute name="mode">
+                  <choice>
+                    <value>any</value>
+                    <value>secure</value>
+                    <value>insecure</value>
+                  </choice>
+                </attribute>
+                <empty/>
+              </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>
           <attribute name="type">
index 6116c09c71b6e8942226960a711988d76a78a881..4afc4896424286cfcb06f7d0a62b3de8d871d525 100644 (file)
@@ -322,6 +322,36 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceChannelMode,
               "secure",
               "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,
               "subsystem",
               "capabilities")
@@ -3955,6 +3985,89 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
                     VIR_FREE(mode);
 
                     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;
@@ -7818,6 +7931,18 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
                               virDomainGraphicsSpiceChannelNameTypeToString(i),
                               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) {
index 95bd11e8066ba13386797e17f789c33639d7b476..60a33ceab708684a531eab8de6abecb27b48b354 100644 (file)
@@ -658,6 +658,44 @@ enum virDomainGraphicsSpiceChannelMode {
     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 virDomainGraphicsDef *virDomainGraphicsDefPtr;
 struct _virDomainGraphicsDef {
@@ -695,6 +733,10 @@ struct _virDomainGraphicsDef {
             virDomainGraphicsAuthDef auth;
             unsigned int autoport :1;
             int channels[VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST];
+            int image;
+            int jpeg;
+            int zlib;
+            int playback;
         } spice;
     } data;
 };
@@ -1423,6 +1465,10 @@ VIR_ENUM_DECL(virDomainInputBus)
 VIR_ENUM_DECL(virDomainGraphics)
 VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName)
 VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
+VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression)
+VIR_ENUM_DECL(virDomainGraphicsSpiceJpegCompression)
+VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression)
+VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState)
 VIR_ENUM_DECL(virDomainSeclabel)
index 54e4482b4272f0e855b9daac562f688e9332a204..d2aa07743b859ff1e2640649c9576311c0a86ac1 100644 (file)
@@ -262,6 +262,14 @@ virDomainGraphicsSpiceChannelModeTypeFromString;
 virDomainGraphicsSpiceChannelModeTypeToString;
 virDomainGraphicsSpiceChannelNameTypeFromString;
 virDomainGraphicsSpiceChannelNameTypeToString;
+virDomainGraphicsSpiceImageCompressionTypeToString;
+virDomainGraphicsSpiceImageCompressionTypeFromString;
+virDomainGraphicsSpiceJpegCompressionTypeFromString;
+virDomainGraphicsSpiceJpegCompressionTypeToString;
+virDomainGraphicsSpicePlaybackCompressionTypeFromString;
+virDomainGraphicsSpicePlaybackCompressionTypeToString;
+virDomainGraphicsSpiceZlibCompressionTypeFromString;
+virDomainGraphicsSpiceZlibCompressionTypeToString;
 virDomainGraphicsTypeFromString;
 virDomainGraphicsTypeToString;
 virDomainHostdevDefFree;
index fea00681521a752e29bdfc797a2a40ec60e95672..89668d4463efe4e0fb17b83e6c73a36f0cf45010 100644 (file)
@@ -4032,6 +4032,18 @@ qemuBuildCommandLine(virConnectPtr conn,
                 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");
         virCommandAddArgBuffer(cmd, &opt);
index c788bb6402ac4604e714fc478815d54d3f238274..70cd35b08842a3da18d8a43a46d83c42ca1bae03 100644 (file)
@@ -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 \
 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,\
-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 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index 5d46509a90ada18da619fa5e6c008108f5adeb7a..a29f50d1cebb04db8b5ef8ef7b82658f63d72032 100644 (file)
     <graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
       <channel name='main' mode='secure'/>
       <channel name='inputs' mode='insecure'/>
+      <image compression='auto_glz'/>
+      <jpeg compression='auto'/>
+      <zlib compression='auto'/>
+      <playback compression='on'/>
     </graphics>
     <video>
       <model type='qxl' vram='18432' heads='1'/>