No blocking portals
This commit is contained in:
parent
ca3f339cbe
commit
e7f669cb56
4 changed files with 13 additions and 28 deletions
|
|
@ -70,18 +70,17 @@ class OpenCVCamera(BaseCamera):
|
|||
return False
|
||||
|
||||
def _capture_frames(self) -> None:
|
||||
portal = lt.get_blocking_portal(self)
|
||||
while self._capture_enabled:
|
||||
ret, frame = self.cap.read()
|
||||
if not ret:
|
||||
LOGGER.error(f"Failed to capture frame from camera {self.camera_index}")
|
||||
break
|
||||
jpeg = cv2.imencode(".jpg", frame)[1].tobytes()
|
||||
self.mjpeg_stream.add_frame(jpeg, portal)
|
||||
self.mjpeg_stream.add_frame(jpeg)
|
||||
jpeg_lores = cv2.imencode(".jpg", cv2.resize(frame, (320, 240)))[
|
||||
1
|
||||
].tobytes()
|
||||
self.lores_mjpeg_stream.add_frame(jpeg_lores, portal)
|
||||
self.lores_mjpeg_stream.add_frame(jpeg_lores)
|
||||
|
||||
@lt.action
|
||||
def discard_frames(self) -> None:
|
||||
|
|
|
|||
|
|
@ -68,9 +68,7 @@ class MissingCalibrationError(RuntimeError):
|
|||
class PicameraStreamOutput(Output):
|
||||
"""An Output class that sends frames to a stream."""
|
||||
|
||||
def __init__(
|
||||
self, stream: lt.outputs.MJPEGStream, portal: lt.deps.BlockingPortal
|
||||
) -> None:
|
||||
def __init__(self, stream: lt.outputs.MJPEGStream) -> None:
|
||||
"""Create an output that puts frames in an MJPEGStream.
|
||||
|
||||
We need to pass the stream object, and also the blocking portal, because
|
||||
|
|
@ -80,7 +78,6 @@ class PicameraStreamOutput(Output):
|
|||
"""
|
||||
Output.__init__(self)
|
||||
self.stream = stream
|
||||
self.portal = portal
|
||||
|
||||
def outputframe(
|
||||
self,
|
||||
|
|
@ -91,7 +88,7 @@ class PicameraStreamOutput(Output):
|
|||
_audio: bool = False,
|
||||
) -> None:
|
||||
"""Add a frame to the stream's ringbuffer."""
|
||||
self.stream.add_frame(frame, self.portal)
|
||||
self.stream.add_frame(frame)
|
||||
|
||||
|
||||
class SensorMode(BaseModel):
|
||||
|
|
@ -480,18 +477,12 @@ class StreamingPiCamera2(BaseCamera):
|
|||
stream_name = "lores" if main_resolution[0] > 1280 else "main"
|
||||
picam.start_recording(
|
||||
MJPEGEncoder(self.mjpeg_bitrate),
|
||||
PicameraStreamOutput(
|
||||
self.mjpeg_stream,
|
||||
lt.get_blocking_portal(self),
|
||||
),
|
||||
PicameraStreamOutput(self.mjpeg_stream),
|
||||
name=stream_name,
|
||||
)
|
||||
picam.start_encoder(
|
||||
MJPEGEncoder(100000000),
|
||||
PicameraStreamOutput(
|
||||
self.lores_mjpeg_stream,
|
||||
lt.get_blocking_portal(self),
|
||||
),
|
||||
PicameraStreamOutput(self.lores_mjpeg_stream),
|
||||
name="lores",
|
||||
)
|
||||
except Exception as e:
|
||||
|
|
@ -515,9 +506,8 @@ class StreamingPiCamera2(BaseCamera):
|
|||
else:
|
||||
self.stream_active = False
|
||||
if stop_web_stream:
|
||||
portal = lt.get_blocking_portal(self)
|
||||
self.mjpeg_stream.stop(portal)
|
||||
self.lores_mjpeg_stream.stop(portal)
|
||||
self.mjpeg_stream.stop()
|
||||
self.lores_mjpeg_stream.stop()
|
||||
LOGGER.info("Stopped MJPEG stream.")
|
||||
|
||||
# Adding a sleep to prevent camera getting confused by rapid commands
|
||||
|
|
|
|||
|
|
@ -290,7 +290,6 @@ class SimulatedCamera(BaseCamera):
|
|||
noise_level: float = lt.property(default=2.0)
|
||||
|
||||
def _capture_frames(self) -> None:
|
||||
portal = lt.get_blocking_portal(self)
|
||||
last_frame_t = time.time()
|
||||
while self._capture_enabled:
|
||||
wait_time = last_frame_t - time.time() - self.frame_interval
|
||||
|
|
@ -299,9 +298,9 @@ class SimulatedCamera(BaseCamera):
|
|||
last_frame_t = time.time()
|
||||
try:
|
||||
frame = self.generate_frame()
|
||||
self.mjpeg_stream.add_frame(_frame2bytes(frame), portal)
|
||||
self.mjpeg_stream.add_frame(_frame2bytes(frame))
|
||||
ds_frame = frame.resize((320, 240), resample=Image.NEAREST)
|
||||
self.lores_mjpeg_stream.add_frame(_frame2bytes(ds_frame), portal)
|
||||
self.lores_mjpeg_stream.add_frame(_frame2bytes(ds_frame))
|
||||
|
||||
except Exception as e:
|
||||
LOGGER.exception(f"Failed to capture frame: {e}, retrying...")
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@ def test_handle_broken_frame():
|
|||
|
||||
camera.mjpeg_stream.grab_frame = flaky_grabber
|
||||
with camera_server(camera):
|
||||
portal = lt.get_blocking_portal(camera)
|
||||
|
||||
# Check that this does cause broken frames.
|
||||
# The noqa is because we don't know exactly when the error is thrown so we
|
||||
# can't have a single simple statement in the pytest raises.
|
||||
|
|
@ -60,13 +58,13 @@ def test_handle_broken_frame():
|
|||
OSError, match="broken data stream when reading image file"
|
||||
):
|
||||
for _i in range(15):
|
||||
jpeg = camera.grab_jpeg(portal)
|
||||
jpeg = camera.grab_jpeg()
|
||||
np.asarray(Image.open(jpeg.open()))
|
||||
|
||||
# Check that grab_as_array handles the broken frames and completes without
|
||||
# the same error.
|
||||
for _i in range(15):
|
||||
array = camera.grab_as_array(portal)
|
||||
array = camera.grab_as_array()
|
||||
assert isinstance(array, np.ndarray)
|
||||
|
||||
|
||||
|
|
@ -74,8 +72,7 @@ def test_simulation_cam_calibration():
|
|||
"""Test that the simulated camera can be calibrated and reports calibration correctly."""
|
||||
camera = SimulatedCamera()
|
||||
with camera_server(camera):
|
||||
portal = lt.get_blocking_portal(camera)
|
||||
assert camera.calibration_required
|
||||
camera.full_auto_calibrate(portal)
|
||||
camera.full_auto_calibrate()
|
||||
assert not camera.calibration_required
|
||||
assert camera.background_detector_status.ready
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue