def get_info(self, _proto): info = { "encodings": self.get_encoding_info(), "video": getVideoHelper().get_info(), } for k, v in codec_versions.items(): info.setdefault("encoding", {}).setdefault(k, {})["version"] = v return info
def get_encodings_caps(self): if B_FRAMES: video_b_frames = ["h264"] #only tested with dec_avcodec2 else: video_b_frames = [] caps = { "flush": PAINT_FLUSH, "scaling.control": self.video_scaling, "client_options": True, "csc_atoms": True, #TODO: check for csc support (swscale only?) "video_reinit": True, "video_scaling": True, "video_b_frames": video_b_frames, "webp_leaks": False, "transparency": self.has_transparency(), "rgb24zlib": True, "max-soft-expired": MAX_SOFT_EXPIRED, "send-timestamps": SEND_TIMESTAMPS, "supports_delta": tuple(x for x in ("png", "rgb24", "rgb32") if x in self.get_core_encodings()), } if self.encoding: caps[""] = self.encoding for k, v in codec_versions.items(): caps["%s.version" % k] = v if self.quality > 0: caps["quality"] = self.quality if self.min_quality > 0: caps["min-quality"] = self.min_quality if self.speed >= 0: caps["speed"] = self.speed if self.min_speed >= 0: caps["min-speed"] = self.min_speed #generic rgb compression flags: for x in compression.ALL_COMPRESSORS: caps["rgb_%s" % x] = x in compression.get_enabled_compressors() #these are the defaults - when we instantiate a window, #we can send different values as part of the map event #these are the RGB modes we want (the ones we are expected to be able to paint with): rgb_formats = ["RGB", "RGBX", "RGBA"] caps["rgb_formats"] = rgb_formats #figure out which CSC modes (usually YUV) can give us those RGB modes: full_csc_modes = getVideoHelper().get_server_full_csc_modes_for_rgb( *rgb_formats) if has_codec("dec_webp"): if self.opengl_enabled: full_csc_modes["webp"] = ("BGRX", "BGRA", "RGBX", "RGBA") else: full_csc_modes["webp"] = ( "BGRX", "BGRA", ) log("supported full csc_modes=%s", full_csc_modes) caps["full_csc_modes"] = full_csc_modes if "h264" in self.get_core_encodings(): # some profile options: "baseline", "main", "high", "high10", ... # set the default to "high10" for I420/YUV420P # as the python client always supports all the profiles # whereas on the server side, the default is baseline to accomodate less capable clients. # I422/YUV422P requires high422, and # I444/YUV444P requires high444, # so we don't bother specifying anything for those two. for old_csc_name, csc_name, default_profile in (("I420", "YUV420P", "high10"), ("I422", "YUV422P", ""), ("I444", "YUV444P", "")): profile = default_profile #try with the old prefix (X264) as well as the more correct one (H264): for H264_NAME in ("X264", "H264"): profile = os.environ.get( "XPRA_%s_%s_PROFILE" % (H264_NAME, old_csc_name), profile) profile = os.environ.get( "XPRA_%s_%s_PROFILE" % (H264_NAME, csc_name), profile) if profile: #send as both old and new names: for h264_name in ("x264", "h264"): caps["%s.%s.profile" % (h264_name, old_csc_name)] = profile caps["%s.%s.profile" % (h264_name, csc_name)] = profile log( "x264 encoding options: %s", str([(k, v) for k, v in caps.items() if k.startswith("x264.")])) log("encoding capabilities: %s", caps) return caps
def get_encodings_caps(self) -> dict: if B_FRAMES: video_b_frames = ("h264", ) #only tested with dec_avcodec2 else: video_b_frames = () caps = { "flush" : PAINT_FLUSH, #v4 servers assume this is available "video_scaling" : True, #v4 servers assume this is available "video_b_frames" : video_b_frames, "video_max_size" : self.video_max_size, "max-soft-expired" : MAX_SOFT_EXPIRED, "send-timestamps" : SEND_TIMESTAMPS, } if self.video_scaling is not None: caps["scaling.control"] = self.video_scaling if self.encoding: caps[""] = self.encoding for k,v in codec_versions.items(): caps["%s.version" % k] = v if self.quality>0: caps["quality"] = self.quality if self.min_quality>0: caps["min-quality"] = self.min_quality if self.speed>=0: caps["speed"] = self.speed if self.min_speed>=0: caps["min-speed"] = self.min_speed #generic rgb compression flags: for x in compression.ALL_COMPRESSORS: caps["rgb_%s" % x] = x in compression.get_enabled_compressors() #these are the defaults - when we instantiate a window, #we can send different values as part of the map event #these are the RGB modes we want (the ones we are expected to be able to paint with): rgb_formats = ["RGB", "RGBX", "RGBA"] caps["rgb_formats"] = rgb_formats #figure out which CSC modes (usually YUV) can give us those RGB modes: full_csc_modes = getVideoHelper().get_server_full_csc_modes_for_rgb(*rgb_formats) if has_codec("dec_webp"): if self.opengl_enabled: full_csc_modes["webp"] = ("BGRX", "BGRA", "RGBX", "RGBA") else: full_csc_modes["webp"] = ("BGRX", "BGRA", ) if has_codec("dec_jpeg") or has_codec("dec_pillow"): full_csc_modes["jpeg"] = ("BGRX", "BGRA", "YUV420P") if has_codec("dec_jpeg"): full_csc_modes["jpega"] = ("BGRA", "RGBA", ) log("supported full csc_modes=%s", full_csc_modes) caps["full_csc_modes"] = full_csc_modes if "h264" in self.get_core_encodings(): # some profile options: "baseline", "main", "high", "high10", ... # set the default to "high10" for YUV420P # as the python client always supports all the profiles # whereas on the server side, the default is baseline to accomodate less capable clients. # YUV422P requires high422, and # YUV444P requires high444, # so we don't bother specifying anything for those two. h264_caps = {} for csc_name, default_profile in ( ("YUV420P", "high"), ("YUV422P", ""), ("YUV444P", "")): profile = os.environ.get("XPRA_H264_%s_PROFILE" % (csc_name), default_profile) if profile: h264_caps["%s.profile" % (csc_name)] = profile h264_caps["fast-decode"] = envbool("XPRA_X264_FAST_DECODE", False) log("x264 encoding options: %s", h264_caps) updict(caps, "h264", h264_caps) log("encoding capabilities: %s", caps) return caps