예제 #1
0
 def process_webcam_frame(self, device_id, frame_no, encoding, w, h, data):
     webcam = self.webcam_forwarding_devices.get(device_id)
     log("process_webcam_frame: device %s, frame no %i: %s %ix%i, %i bytes, webcam=%s", device_id, frame_no, encoding, w, h, len(data), webcam)
     assert encoding and w and h and data
     if not webcam:
         log.error("Error: webcam forwarding is not active, dropping frame")
         self.send_webcam_stop(device_id, "not started")
         return
     try:
         from xpra.codecs.pillow.decode import get_encodings
         assert encoding in get_encodings(), "invalid encoding specified: %s (must be one of %s)" % (encoding, get_encodings())
         rgb_pixel_format = "BGRX"       #BGRX
         from PIL import Image
         buf = BytesIOClass(data)
         img = Image.open(buf)
         pixels = img.tobytes('raw', rgb_pixel_format)
         from xpra.codecs.image_wrapper import ImageWrapper
         bgrx_image = ImageWrapper(0, 0, w, h, pixels, rgb_pixel_format, 32, w*4, planes=ImageWrapper.PACKED)
         src_format = webcam.get_src_format()
         if not src_format:
             #closed / closing
             return
         #one of those two should be present
         try:
             csc_mod = "csc_libyuv"
             from xpra.codecs.csc_libyuv.colorspace_converter import get_input_colorspaces, get_output_colorspaces, ColorspaceConverter        #@UnresolvedImport
         except ImportError:
             self.send_webcam_stop(device_id, "no csc module")
             return
         try:
             assert rgb_pixel_format in get_input_colorspaces(), "unsupported RGB pixel format %s" % rgb_pixel_format
             assert src_format in get_output_colorspaces(rgb_pixel_format), "unsupported output colourspace format %s" % src_format
         except Exception as e:
             log.error("Error: cannot convert %s to %s using %s:", rgb_pixel_format, src_format, csc_mod)
             log.error(" input-colorspaces: %s", csv(get_input_colorspaces()))
             log.error(" output-colorspaces: %s", csv(get_output_colorspaces(rgb_pixel_format)))
             self.send_webcam_stop(device_id, "csc format error")
             return
         tw = webcam.get_width()
         th = webcam.get_height()
         csc = ColorspaceConverter()
         csc.init_context(w, h, rgb_pixel_format, tw, th, src_format)
         image = csc.convert_image(bgrx_image)
         webcam.push_image(image)
         #tell the client all is good:
         self.send_webcam_ack(device_id, frame_no)
     except Exception as e:
         log("error on %ix%i frame %i using encoding %s", w, h, frame_no, encoding, exc_info=True)
         log.error("Error processing webcam frame:")
         msg = str(e)
         if not msg:
             msg = "unknown error"
             log.error(" %s error" % webcam, exc_info=True)
         log.error(" %s", msg)
         self.send_webcam_stop(device_id, msg)
         self.stop_virtual_webcam(device_id)
예제 #2
0
    def start_virtual_webcam(self, device_id, w, h):
        log("start_virtual_webcam%s", (device_id, w, h))
        assert w > 0 and h > 0
        webcam = self.webcam_forwarding_devices.get(device_id)
        if webcam:
            log.warn("Warning: virtual webcam device %s already in use,",
                     device_id)
            log.warn(" stopping it first")
            self.stop_virtual_webcam(device_id)

        def fail(msg):
            log.error("Error: cannot start webcam forwarding")
            log.error(" %s", msg)
            self.send_webcam_stop(device_id, msg)

        if not self.webcam_enabled:
            fail("webcam forwarding is disabled")
            return False
        devices = self.get_device_options(device_id)
        if not devices:
            fail("no virtual devices found")
            return False
        if len(self.webcam_forwarding_devices) > MAX_WEBCAM_DEVICES:
            fail("too many virtual devices are already in use: %i" %
                 len(self.webcam_forwarding_devices))
            return False
        errs = {}
        for vid, device_info in devices.items():
            log("trying device %s: %s", vid, device_info)
            device_str = device_info.get("device")
            try:
                from xpra.codecs.v4l2.pusher import Pusher, get_input_colorspaces  #@UnresolvedImport
                in_cs = get_input_colorspaces()
                p = Pusher()
                src_format = in_cs[0]
                p.init_context(w, h, w, src_format, device_str)
                self.webcam_forwarding_devices[device_id] = p
                log.info("webcam forwarding using %s", device_str)
                #this tell the client to start sending, and the size to use - which may have changed:
                self.send_webcam_ack(device_id, 0, p.get_width(),
                                     p.get_height())
                return True
            except Exception as e:
                log.error("Error: failed to start virtual webcam")
                log.error(" using device %s: %s",
                          vid,
                          device_info,
                          exc_info=True)
                errs[device_str] = str(e)
                del e
        fail("all devices failed")
        if len(errs) > 1:
            log.error(" tried %i devices:", len(errs))
        for device_str, err in errs.items():
            log.error(" %s : %s", device_str, err)
        return False