Beispiel #1
0
def has_stream_compressor(stream_compressor):
    if stream_compressor not in ("lz4", "lzo"):
        log.warn("Warning: invalid stream compressor '%s'", stream_compressor)
        return False
    from xpra.net.compression import use
    if stream_compressor=="lz4" and not use("lz4"):
        return False
    if stream_compressor=="lzo" and not use("lzo"):
        return False
    return True
Beispiel #2
0
 def test_main(self):
     compression.init_all()
     assert compression.use("zlib")
     assert compression.get_compression_caps()
     assert compression.get_enabled_compressors()
     for x in compression.get_enabled_compressors():
         assert compression.get_compressor(x)
Beispiel #3
0
    def init_state(self):
        self.wants_encodings = False
        self.wants_features = False

        #contains default values, some of which may be supplied by the client:
        self.default_batch_config = batch_config.DamageBatchConfig()
        self.global_batch_config = self.default_batch_config.clone()      #global batch config

        self.supports_transparency = False
        self.encoding = None                        #the default encoding for all windows
        self.encodings = ()                         #all the encodings supported by the client
        self.core_encodings = ()
        self.encodings_packet = False               #supports delayed encodings initialization?
        self.window_icon_encodings = ["premult_argb32"]
        self.rgb_formats = ("RGB",)
        self.encoding_options = typedict()
        self.icons_encoding_options = typedict()
        self.default_encoding_options = typedict()
        self.auto_refresh_delay = 0

        self.zlib = True
        self.lz4 = use("lz4")

        #for managing the recalculate_delays work:
        self.calculate_window_pixels = {}
        self.calculate_window_ids = set()
        self.calculate_timer = 0
        self.calculate_last_time = 0

        #if we "proxy video", we will modify the video helper to add
        #new encoders, so we must make a deep copy to preserve the original
        #which may be used by other clients (other ServerSource instances)
        self.video_helper = getVideoHelper().clone()
        self.cuda_device_context = None
Beispiel #4
0
 def test_compressed_wrapper(self):
     r = compression.compressed_wrapper("test", b"a"*(compression.MIN_COMPRESS_SIZE+1))
     if not r.datatype.startswith("raw"):
         raise Exception("should not be able to use the wrapper without enabling a compressor, but got %s" % r)
     for x in ("lz4", "brotli", "zlib", "none"):
         if not compression.use(x):
             continue
         kwargs = {x : True}
         for level in (0, 1, 5, 10):
             for data in (
                 b"0"*1024,
                 b"0"*16,
                 b"\0",
                 memoryview(b"hello"),
                 bytearray(b"hello"),
                 b"1"*1024*1024*16,
                 ):
                 v = compression.compressed_wrapper("test", data, level=level, **kwargs)
                 assert v
                 assert repr(v)
                 assert compression.get_compression_type(v.level)
                 #and back:
                 try:
                     d = compression.decompress_by_name(v.data, v.algorithm)
                     assert d
                     if x!="none":
                         #we can't do none,
                         #because it would be mistaken for "zlib"
                         #(for historical reasons - 'zlib' uses level=0, and 'none' has no level)
                         d = compression.decompress(v.data, v.level)
                         assert d
                 except Exception:
                     print("error decompressing %s - generated with settings: %s" % (v, kwargs))
                     raise
Beispiel #5
0
 def compress_clipboard():
     log(
         "compress_clipboard() compressing %s, server compressors=%s",
         compressible, self.server_compressors)
     from xpra.net import compression
     if "brotli" in self.server_compressors and compression.use(
             "brotli"):
         return compression.compressed_wrapper(
             compressible.datatype,
             compressible.data,
             level=9,
             brotli=True,
             can_inline=False)
     return self.compressed_wrapper(compressible.datatype,
                                    compressible.data)
Beispiel #6
0
 def compressed_wrapper(self, datatype, data, level=5, **kwargs):
     if level>0 and len(data)>=256:
         kw = {}
         #brotli is not enabled by default as a generic compressor
         #but callers may choose to enable it via kwargs:
         for algo, defval in {
             "zlib" : True,
             "lz4" : True,
             "brotli" : False,
             }.items():
             kw[algo] = algo in self.server_compressors and compression.use(algo) and kwargs.get(algo, defval)
         cw = compression.compressed_wrapper(datatype, data, level=level, can_inline=False, **kw)
         if len(cw)<len(data):
             #the compressed version is smaller, use it:
             return cw
     #we can't compress, so at least avoid warnings in the protocol layer:
     return compression.Compressed("raw %s" % datatype, data, can_inline=True)
Beispiel #7
0
    def parse_client_caps(self, c : typedict):
        #batch options:
        def batch_value(prop, default, minv=None, maxv=None):
            assert default is not None
            def parse_batch_int(value, varname):
                if value is not None:
                    try:
                        return int(value)
                    except (TypeError, ValueError):
                        log.error("Error: invalid value '%s' for batch option %s", value, varname)
                return None
            #from client caps first:
            cpname = "batch.%s" % prop
            v = parse_batch_int(c.get(cpname), cpname)
            #try env:
            if v is None:
                evname = "XPRA_BATCH_%s" % prop.upper()
                v = parse_batch_int(os.environ.get(evname), evname)
            #fallback to default:
            if v is None:
                v = default
            if minv is not None:
                v = max(minv, v)
            if maxv is not None:
                v = min(maxv, v)
            assert v is not None
            return v

        #general features:
        self.zlib = c.boolget("zlib", True)
        self.lz4 = c.boolget("lz4", False) and use("lz4")
        self.brotli = c.boolget("brotli", False) and use("brotli")
        log("compressors: zlib=%s, lz4=%s, brotli=%s",
            self.zlib, self.lz4, self.brotli)

        delay = batch_config.START_DELAY
        dbc = self.default_batch_config
        dbc.always      = bool(batch_value("always", batch_config.ALWAYS))
        dbc.min_delay   = batch_value("min_delay", batch_config.MIN_DELAY, 0, 1000)
        dbc.max_delay   = batch_value("max_delay", batch_config.MAX_DELAY, 1, 15000)
        dbc.max_events  = batch_value("max_events", batch_config.MAX_EVENTS)
        dbc.max_pixels  = batch_value("max_pixels", batch_config.MAX_PIXELS)
        dbc.time_unit   = batch_value("time_unit", batch_config.TIME_UNIT, 1)
        self.vrefresh = c.intget("vrefresh", -1)
        dbc.match_vrefresh(self.vrefresh)
        dbc.delay       = batch_value("delay", delay, dbc.min_delay)
        log("default batch config: %s", dbc)

        #encodings:
        self.encodings_packet = c.boolget("encodings.packet", False)
        self.encodings = c.strtupleget("encodings")
        self.core_encodings = c.strtupleget("encodings.core", self.encodings)
        log("encodings=%s, core_encodings=%s", self.encodings, self.core_encodings)
        #we can't assume that the window mixin is loaded,
        #or that the ui_client flag exists:
        send_ui = getattr(self, "ui_client", True) and getattr(self, "send_windows", True)
        if send_ui and not self.core_encodings:
            raise ClientException("client failed to specify any supported encodings")
        self.window_icon_encodings = c.strtupleget("encodings.window-icon", ("premult_argb32",))
        #try both spellings for older versions:
        for x in ("encodings", "encoding",):
            self.rgb_formats = c.strtupleget(x+".rgb_formats", self.rgb_formats)
        #skip all other encoding related settings if we don't send pixels:
        if not send_ui:
            log("windows/pixels forwarding is disabled for this client")
        else:
            self.parse_encoding_caps(c)