def _handle_image_received(self, value): """Runs in the kivy thread when we get an image """ t = clock() if self.play_state == 'starting': self._frame_count = 0 self.ts_play = self._ivl_start = t img = value[0] self.metadata_play_used = VideoMetadata(img.get_pixel_format(), *img.get_size(), 0) self.complete_start() if self.play_state != 'playing': return if t - self._ivl_start >= 1.: r = self.real_rate = self._frame_count / (t - self._ivl_start) if not self.metadata_play_used.rate: self.metadata_play_used = VideoMetadata( *self.metadata_play_used[:3], int(2 * r)) self._frame_count = 0 self._ivl_start = t self._frame_count += 1 self.frames_played += 1 img, count, queued_count, t_img = value self.num_queued_frames = queued_count self.process_frame(img, {'t': t_img, 'count': count})
def play(self): if self.cam_state != 'open': raise TypeError("Cannot play camera that isn't open") self.start_cam_process() super(ThorCamPlayer, self).play() self.metadata_play_used = VideoMetadata('', 0, 0, 0) self.send_camera_request('play')
def process_in_kivy_thread(self, *largs): """Processes messages from the client in the kivy thread. """ while self.to_kivy_queue is not None: try: msg, value = self.to_kivy_queue.get(block=False) if msg == 'exception': e, exec_info = value cpl_media.error_callback(e, exc_info=exec_info) elif msg == 'exception_exit': e, exec_info = value cpl_media.error_callback(e, exc_info=exec_info) self.stop_all() if self.play_state != 'none': self.complete_stop() elif msg == 'started_recording': if self.play_state == 'starting': self.ts_play = self._ivl_start = clock() self._frame_count = 0 self.metadata_play_used = VideoMetadata(*value) self.complete_start() elif msg == 'stopped_recording': self.stop() elif msg == 'stopped_playing': self.complete_stop() elif msg == 'image': if self.play_state != 'playing': continue t = clock() if t - self._ivl_start >= 1.: self.real_rate = self._frame_count / (t - self._ivl_start) self._frame_count = 0 self._ivl_start = t self._frame_count += 1 self.frames_played += 1 plane_buffers, pix_fmt, size, linesize, metadata = value sws = SWScale(*size, pix_fmt, ofmt=pix_fmt) img = Image(plane_buffers=plane_buffers, pix_fmt=pix_fmt, size=size, linesize=linesize) self.process_frame(sws.scale(img), metadata) else: print('Got unknown RemoteVideoPlayer message', msg, value) except Empty: break
def finish_ask_config(self, item, *largs, **kwargs): """Called in the kivy thread automatically after the camera has been re-configured. """ if isinstance(item, tuple) and item[0] == 'option': setting, _, _ = item[1] getattr(self, setting).update(kwargs['values']) set_rate = setting in ('frame_rate', 'metadata_play_used') else: for k, v in kwargs.items(): setattr(self, k, v) set_rate = 'frame_rate' in kwargs or 'metadata_play_used' in kwargs self.active_settings = self.get_active_settings() if set_rate: fmt, w, h, r = self.metadata_play_used if 'max' in self.frame_rate: r = max(r, self.frame_rate['max']) self.metadata_play_used = VideoMetadata(fmt, w, h, r)
def config_thread_run(self): """The function run by the configuration thread. """ queue = self.config_queue cc = CameraContext() while True: item = queue.get() try: if item == 'eof': return ip = '' serial = 0 do_serial = False if item == 'serials': cc.rescan_bus() cams = cc.get_gige_cams() old_serial = serial = self.serial old_ip = ip = self.ip ips = ['.'.join(map(str, Camera(serial=s).ip)) for s in cams] if cams: if serial not in cams and ip not in ips: serial = 0 ip = '' elif serial in cams: ip = ips[cams.index(serial)] else: serial = cams[ips.index(ip)] Clock.schedule_once(partial( self.finish_ask_config, item, serials=cams, serial=serial, ips=ips, ip=ip)) if serial: c = Camera(serial=serial) c.connect() if old_serial == serial or old_ip == ip: self.write_gige_opts(c, self.cam_config_opts) self.write_cam_options_config(c) self.read_gige_opts(c) self.read_cam_options_config(c) if self.cam_config_opts['fmt'] not in \ self.ffmpeg_pix_map or \ self.cam_config_opts['fmt'] == 'yuv411': self.cam_config_opts['fmt'] = 'rgb' self.write_gige_opts(c, self.cam_config_opts) c.disconnect() c = None elif item == 'serial': do_serial = True elif item == 'gui': gui = GUI() gui.show_selection() do_serial = True # read possibly updated config elif c or self._camera: cam = c or self._camera if isinstance(item, tuple) and item[0] == 'mirror': if cam.get_horizontal_mirror()[0]: cam.set_horizontal_mirror(item[1]) Clock.schedule_once(partial( self.finish_ask_config, item, mirror=cam.get_horizontal_mirror()[1])) elif isinstance(item, tuple) and item[0] == 'option': _, (setting, name, value) = item if name: self.write_cam_option_config( setting, cam, name, value) Clock.schedule_once(partial( self.finish_ask_config, item, values=self.read_cam_option_config(setting, cam))) if do_serial: _ip = ip = self.ip serial = self.serial if serial or ip: if _ip: _ip = list(map(int, _ip.split('.'))) c = Camera(serial=serial or None, ip=_ip or None) serial = c.serial ip = '.'.join(map(str, c.ip)) c.connect() self.read_gige_opts(c) self.read_cam_options_config(c) if self.cam_config_opts['fmt'] not in \ self.ffmpeg_pix_map or \ self.cam_config_opts['fmt'] == 'yuv411': self.cam_config_opts['fmt'] = 'rgb' self.write_gige_opts(c, self.cam_config_opts) c.disconnect() c = None if serial or ip: opts = self.cam_config_opts if opts['fmt'] not in self.ffmpeg_pix_map: raise Exception('Pixel format {} cannot be converted'. format(opts['fmt'])) if opts['fmt'] == 'yuv411': raise ValueError('yuv411 is not currently supported') metadata = VideoMetadata( self.ffmpeg_pix_map[opts['fmt']], opts['width'], opts['height'], 30.0) Clock.schedule_once(partial( self.finish_ask_config, item, metadata_play=metadata, metadata_play_used=metadata, serial=serial, ip=ip)) except Exception as e: self.exception(e) finally: Clock.schedule_once(partial(self._remove_config_item, item))
def _update_metadata(self, *largs): w, h = self.video_fmts[self.video_fmt] pix_fmt = self.image_fmts[self.pixel_fmt] self.metadata_play = self.metadata_play_used = VideoMetadata( pix_fmt, w, h, 29.97)
def _set_metadata_play(self, fmt, w, h): self.metadata_play = VideoMetadata(fmt, w, h, 0)