Loading openflexure_microscope/camera/base.py +4 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,8 @@ class BaseCamera(object): self.frames_iterator = self.frames() logging.debug("Entering worker thread.") self.state['stream_active'] = True for frame in self.frames_iterator: self.frame = frame self.event.set() # send signal to clients Loading @@ -337,5 +339,7 @@ class BaseCamera(object): pass logging.debug("BaseCamera worker thread exiting...") # Set stream_activate state self.state['stream_active'] = False # Reset thread self.thread = None openflexure_microscope/camera/pi.py +47 −59 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ class StreamingCamera(BaseCamera): # Pause stream while changing settings if self.state['stream_active']: # If stream is active logging.info("Pausing stream to update config.") self.pause_stream() # Pause stream self.stop_stream_recording() # Pause stream paused_stream = True # Remember to unpause stream when done # PiCamera parameters (applied directly to PiCamera object) Loading Loading @@ -239,7 +239,7 @@ class StreamingCamera(BaseCamera): # If stream was paused to update config, unpause if paused_stream: logging.info("Resuming stream.") self.resume_stream() self.start_stream_recording() else: raise Exception( Loading Loading @@ -342,18 +342,17 @@ class StreamingCamera(BaseCamera): # Update state dictionary self.state['record_active'] = False def pause_stream( def stop_stream_recording( self, splitter_port: int=1, resolution: Tuple[int, int]=None) -> None: """ Pause capture on a splitter port. Sets the camera resolution to the still-image resolution, and stops recording if the stream is active. Args: splitter_port (int): Splitter port to stop recording on resolution ((int, int)): Resolution to set the camera to, after stopping recording. """ logging.debug("Pausing stream") # If no resolution is specified, default to image_resolution if not resolution: resolution = self.config['image_resolution'] Loading @@ -361,37 +360,47 @@ class StreamingCamera(BaseCamera): # Stop the camera video recording on port 1 try: self.camera.stop_recording(splitter_port=splitter_port) logging.info("Stopped MJPEG stream on port {1}. Switching to {0}.".format(resolution, splitter_port)) except picamera.exc.PiCameraNotRecording: logging.info("Not recording on splitter_port {}".format(splitter_port)) # Increase the resolution for taking an image self.camera.resolution = resolution def resume_stream( def start_stream_recording( self, splitter_port: int=1, resolution: Tuple[int, int]=None) -> None: """ Resume capture on a splitter port. Sets the camera resolution to the video/stream resolution, and starts recording if the stream should be active. Args: splitter_port (int): Splitter port to start recording on resolution ((int, int)): Resolution to set the camera to, before starting recording. resolution ((int, int)): Resolution to set the camera to, before starting recording. Defaults to `self.config['video_resolution']`. """ logging.debug("Resuming stream") # If no stream object exists if not hasattr(self, 'stream'): self.stream = io.BytesIO() # Create a stream object # If no explicit resolution is passed if not resolution: resolution = self.config['video_resolution'] resolution = self.config['video_resolution'] # Default to video recording resolution # Reduce the resolution for video streaming self.camera.resolution = resolution # Resume the video channel # If the stream should be active if self.state['stream_active']: # Start recording on stream port self.camera.start_recording( self.stream, format='mjpeg', quality=self.config['jpeg_quality'], splitter_port=splitter_port) logging.debug("Started MJPEG stream at {} on port {}".format(resolution, splitter_port)) def capture( self, output, Loading Loading @@ -421,31 +430,21 @@ class StreamingCamera(BaseCamera): logging.info("Capturing to {}".format(output)) # TODO: Do we really always want bayer data for full captures? # Set resolution and stop stream recording if necesarry if not use_video_port: # Pause video splitter port 1 self.pause_stream() self.stop_stream_recording() self.camera.capture( output_stream, format=fmt, quality=100, resize=resize, bayer=bayer) # Resume video splitter port 1 self.resume_stream() bayer=(not use_video_port) and bayer, use_video_port=use_video_port) else: self.camera.capture( output_stream, format=fmt, quality=100, resize=resize, bayer=False, use_video_port=bayer) # Set resolution and start stream recording if necesarry if not use_video_port: self.start_stream_recording() return output Loading @@ -471,7 +470,7 @@ class StreamingCamera(BaseCamera): size = resolution if not use_video_port: self.pause_stream(resolution=resolution) self.stop_stream_recording(resolution=resolution) logging.debug("Creating PiYUVArray") with picamera.array.PiYUVArray(self.camera, size=size) as output: Loading @@ -485,7 +484,7 @@ class StreamingCamera(BaseCamera): use_video_port=use_video_port) if not use_video_port: self.resume_stream() self.start_stream_recording() if rgb: logging.debug("Converting to RGB") Loading Loading @@ -515,7 +514,7 @@ class StreamingCamera(BaseCamera): size = resolution # Always pause stream, to prevent resizer memory issues self.pause_stream(resolution=resolution) self.stop_stream_recording(resolution=resolution) logging.debug("Creating PiRGBArray") with picamera.array.PiRGBArray(self.camera, size=size) as output: Loading @@ -529,7 +528,7 @@ class StreamingCamera(BaseCamera): use_video_port=use_video_port) # Resume stream self.resume_stream() self.start_stream_recording() return output.array Loading @@ -544,25 +543,14 @@ class StreamingCamera(BaseCamera): """ # Run this initialisation method self.initialisation() self.wait_for_camera() # Set stream resolution self.camera.resolution = self.config['video_resolution'] # Create stream self.stream = io.BytesIO() # Start recording on video splitter port 1 self.camera.start_recording( self.stream, format='mjpeg', quality=self.config['jpeg_quality'], splitter_port=1) # Start stream recording (and set resolution) self.start_stream_recording() # Update state logging.debug("STREAM ACTIVE") self.state['stream_active'] = True #self.state['stream_active'] = True # While the iterator is not closed try: Loading @@ -582,7 +570,7 @@ class StreamingCamera(BaseCamera): yield frame # When GeneratorExit or StopIteration raised, run cleanup code finally: logging.debug("Stopping stream recording on port 1") self.camera.stop_recording(splitter_port=1) self.state['stream_active'] = False # Stop stream recording (and set resolution) self.stop_stream_recording() logging.debug("FRAME ITERATOR END") Loading
openflexure_microscope/camera/base.py +4 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,8 @@ class BaseCamera(object): self.frames_iterator = self.frames() logging.debug("Entering worker thread.") self.state['stream_active'] = True for frame in self.frames_iterator: self.frame = frame self.event.set() # send signal to clients Loading @@ -337,5 +339,7 @@ class BaseCamera(object): pass logging.debug("BaseCamera worker thread exiting...") # Set stream_activate state self.state['stream_active'] = False # Reset thread self.thread = None
openflexure_microscope/camera/pi.py +47 −59 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ class StreamingCamera(BaseCamera): # Pause stream while changing settings if self.state['stream_active']: # If stream is active logging.info("Pausing stream to update config.") self.pause_stream() # Pause stream self.stop_stream_recording() # Pause stream paused_stream = True # Remember to unpause stream when done # PiCamera parameters (applied directly to PiCamera object) Loading Loading @@ -239,7 +239,7 @@ class StreamingCamera(BaseCamera): # If stream was paused to update config, unpause if paused_stream: logging.info("Resuming stream.") self.resume_stream() self.start_stream_recording() else: raise Exception( Loading Loading @@ -342,18 +342,17 @@ class StreamingCamera(BaseCamera): # Update state dictionary self.state['record_active'] = False def pause_stream( def stop_stream_recording( self, splitter_port: int=1, resolution: Tuple[int, int]=None) -> None: """ Pause capture on a splitter port. Sets the camera resolution to the still-image resolution, and stops recording if the stream is active. Args: splitter_port (int): Splitter port to stop recording on resolution ((int, int)): Resolution to set the camera to, after stopping recording. """ logging.debug("Pausing stream") # If no resolution is specified, default to image_resolution if not resolution: resolution = self.config['image_resolution'] Loading @@ -361,37 +360,47 @@ class StreamingCamera(BaseCamera): # Stop the camera video recording on port 1 try: self.camera.stop_recording(splitter_port=splitter_port) logging.info("Stopped MJPEG stream on port {1}. Switching to {0}.".format(resolution, splitter_port)) except picamera.exc.PiCameraNotRecording: logging.info("Not recording on splitter_port {}".format(splitter_port)) # Increase the resolution for taking an image self.camera.resolution = resolution def resume_stream( def start_stream_recording( self, splitter_port: int=1, resolution: Tuple[int, int]=None) -> None: """ Resume capture on a splitter port. Sets the camera resolution to the video/stream resolution, and starts recording if the stream should be active. Args: splitter_port (int): Splitter port to start recording on resolution ((int, int)): Resolution to set the camera to, before starting recording. resolution ((int, int)): Resolution to set the camera to, before starting recording. Defaults to `self.config['video_resolution']`. """ logging.debug("Resuming stream") # If no stream object exists if not hasattr(self, 'stream'): self.stream = io.BytesIO() # Create a stream object # If no explicit resolution is passed if not resolution: resolution = self.config['video_resolution'] resolution = self.config['video_resolution'] # Default to video recording resolution # Reduce the resolution for video streaming self.camera.resolution = resolution # Resume the video channel # If the stream should be active if self.state['stream_active']: # Start recording on stream port self.camera.start_recording( self.stream, format='mjpeg', quality=self.config['jpeg_quality'], splitter_port=splitter_port) logging.debug("Started MJPEG stream at {} on port {}".format(resolution, splitter_port)) def capture( self, output, Loading Loading @@ -421,31 +430,21 @@ class StreamingCamera(BaseCamera): logging.info("Capturing to {}".format(output)) # TODO: Do we really always want bayer data for full captures? # Set resolution and stop stream recording if necesarry if not use_video_port: # Pause video splitter port 1 self.pause_stream() self.stop_stream_recording() self.camera.capture( output_stream, format=fmt, quality=100, resize=resize, bayer=bayer) # Resume video splitter port 1 self.resume_stream() bayer=(not use_video_port) and bayer, use_video_port=use_video_port) else: self.camera.capture( output_stream, format=fmt, quality=100, resize=resize, bayer=False, use_video_port=bayer) # Set resolution and start stream recording if necesarry if not use_video_port: self.start_stream_recording() return output Loading @@ -471,7 +470,7 @@ class StreamingCamera(BaseCamera): size = resolution if not use_video_port: self.pause_stream(resolution=resolution) self.stop_stream_recording(resolution=resolution) logging.debug("Creating PiYUVArray") with picamera.array.PiYUVArray(self.camera, size=size) as output: Loading @@ -485,7 +484,7 @@ class StreamingCamera(BaseCamera): use_video_port=use_video_port) if not use_video_port: self.resume_stream() self.start_stream_recording() if rgb: logging.debug("Converting to RGB") Loading Loading @@ -515,7 +514,7 @@ class StreamingCamera(BaseCamera): size = resolution # Always pause stream, to prevent resizer memory issues self.pause_stream(resolution=resolution) self.stop_stream_recording(resolution=resolution) logging.debug("Creating PiRGBArray") with picamera.array.PiRGBArray(self.camera, size=size) as output: Loading @@ -529,7 +528,7 @@ class StreamingCamera(BaseCamera): use_video_port=use_video_port) # Resume stream self.resume_stream() self.start_stream_recording() return output.array Loading @@ -544,25 +543,14 @@ class StreamingCamera(BaseCamera): """ # Run this initialisation method self.initialisation() self.wait_for_camera() # Set stream resolution self.camera.resolution = self.config['video_resolution'] # Create stream self.stream = io.BytesIO() # Start recording on video splitter port 1 self.camera.start_recording( self.stream, format='mjpeg', quality=self.config['jpeg_quality'], splitter_port=1) # Start stream recording (and set resolution) self.start_stream_recording() # Update state logging.debug("STREAM ACTIVE") self.state['stream_active'] = True #self.state['stream_active'] = True # While the iterator is not closed try: Loading @@ -582,7 +570,7 @@ class StreamingCamera(BaseCamera): yield frame # When GeneratorExit or StopIteration raised, run cleanup code finally: logging.debug("Stopping stream recording on port 1") self.camera.stop_recording(splitter_port=1) self.state['stream_active'] = False # Stop stream recording (and set resolution) self.stop_stream_recording() logging.debug("FRAME ITERATOR END")