def send_webcam_frame(self): if not self.webcam_lock.acquire(False): return False log("send_webcam_frame() webcam_device=%s", self.webcam_device) try: assert self.webcam_device_no>=0, "device number is not set" assert self.webcam_device, "no webcam device to capture from" from xpra.codecs.pillow.encoder import get_encodings client_webcam_encodings = get_encodings() common_encodings = list(set(self.server_webcam_encodings).intersection(client_webcam_encodings)) log("common encodings (server=%s, client=%s): %s", csv(self.server_encodings), csv(client_webcam_encodings), csv(common_encodings)) if not common_encodings: log.error("Error: cannot send webcam image, no common formats") log.error(" the server supports: %s", csv(self.server_webcam_encodings)) log.error(" the client supports: %s", csv(client_webcam_encodings)) self.stop_sending_webcam() return False preferred_order = ["jpeg", "png", "png/L", "png/P", "webp"] formats = [x for x in preferred_order if x in common_encodings] + common_encodings encoding = formats[0] start = monotonic_time() import cv2 ret, frame = self.webcam_device.read() assert ret, "capture failed" assert frame.ndim==3, "invalid frame data" h, w, Bpp = frame.shape assert Bpp==3 and frame.size==w*h*Bpp rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # @UndefinedVariable end = monotonic_time() log("webcam frame capture took %ims", (end-start)*1000) start = monotonic_time() from PIL import Image from io import BytesIO image = Image.fromarray(rgb) buf = BytesIO() image.save(buf, format=encoding) data = buf.getvalue() buf.close() end = monotonic_time() log("webcam frame compression to %s took %ims", encoding, (end-start)*1000) frame_no = self.webcam_frame_no self.webcam_frame_no += 1 self.send("webcam-frame", self.webcam_device_no, frame_no, encoding, w, h, compression.Compressed(encoding, data)) self.cancel_webcam_check_ack_timer() self.webcam_ack_check_timer = self.timeout_add(10*1000, self.webcam_check_acks) return True except Exception as e: log.error("webcam frame %i failed", self.webcam_frame_no, exc_info=True) log.error("Error sending webcam frame: %s", e) self.stop_sending_webcam() summary = "Webcam forwarding has failed" body = "The system encountered the following error:\n" + \ ("%s\n" % e) self.may_notify(XPRA_WEBCAM_NOTIFICATION_ID, summary, body, expire_timeout=10*1000, icon_name="webcam") return False finally: self.webcam_lock.release()
def test_encode_image_formats(self): for pixel_format, bpp in { "r210": 32, "BGRA": 32, "BGR565": 16, "RLE8": 8, }.items(): for encoding in get_encodings(): if encoding == "jpeg" and pixel_format != "BGRA": continue self.do_test_pixel_format(pixel_format, bpp, encoding)