Skip to content

Commit

Permalink
Fix #49
Browse files Browse the repository at this point in the history
Ensure that the encoder knows when it was responsible for starting the
camera's capture and that it only attempts to disable capture when it
was responsible.
  • Loading branch information
waveform80 committed Jan 31, 2014
1 parent 8ed5923 commit f14dc29
Showing 1 changed file with 36 additions and 16 deletions.
52 changes: 36 additions & 16 deletions picamera/encoders.py
Expand Up @@ -105,7 +105,8 @@ def __init__(
self.input_port = input_port
self.output_port = None
self.pool = None
self.opened = False
self.started_capture = False
self.opened_output = False
self.output = None
self.lock = threading.Lock() # protects access to self.output
self.exception = None
Expand Down Expand Up @@ -270,8 +271,8 @@ def _open_output(self, output):
we were the one to open it.
"""
with self.lock:
self.opened = isinstance(output, (bytes, str))
if self.opened:
self.opened_output = isinstance(output, (bytes, str))
if self.opened_output:
# Open files in binary mode with a decent buffer size
self.output = io.open(output, 'wb', buffering=65536)
else:
Expand All @@ -284,12 +285,12 @@ def _close_output(self):
"""
with self.lock:
if self.output:
if self.opened:
if self.opened_output:
self.output.close()
elif hasattr(self.output, 'flush'):
self.output.flush()
self.output = None
self.opened = False
self.opened_output = False

def start(self, output):
"""
Expand All @@ -314,21 +315,36 @@ def start(self, output):
mmal_check(
mmal.mmal_port_send_buffer(self.output_port, buf),
prefix="Unable to send a buffer to encoder output port")
b = mmal.MMAL_BOOL_T()
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port, mmal.MMAL_PARAMETER_CAPTURE, mmal.MMAL_TRUE),
prefix="Failed to start capture")
mmal.mmal_port_parameter_get_boolean(
self.camera_port,
mmal.MMAL_PARAMETER_CAPTURE,
b),
prefix="Failed to query capture status")
self.started_capture = not bool(b)
if self.started_capture:
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port,
mmal.MMAL_PARAMETER_CAPTURE,
mmal.MMAL_TRUE),
prefix="Failed to start capture")

def wait(self, timeout=None):
"""
Waits for the encoder to finish (successfully or otherwise)
"""
result = self.event.wait(timeout)
if result:
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port, mmal.MMAL_PARAMETER_CAPTURE, mmal.MMAL_FALSE),
prefix="Failed to stop capture")
if self.started_capture:
self.started_capture = False
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port,
mmal.MMAL_PARAMETER_CAPTURE,
mmal.MMAL_FALSE),
prefix="Failed to stop capture")
try:
mmal_check(
mmal.mmal_port_disable(self.output_port),
Expand All @@ -350,10 +366,14 @@ def stop(self):
# disable below. The check exists purely to prevent stderr getting
# spammed by our continued attempts to disable an already disabled port
if self.encoder and self.output_port[0].is_enabled:
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port, mmal.MMAL_PARAMETER_CAPTURE, mmal.MMAL_FALSE),
prefix="Failed to stop capture")
if self.started_capture:
self.started_capture = False
mmal_check(
mmal.mmal_port_parameter_set_boolean(
self.camera_port,
mmal.MMAL_PARAMETER_CAPTURE,
mmal.MMAL_FALSE),
prefix="Failed to stop capture")
try:
mmal_check(
mmal.mmal_port_disable(self.output_port),
Expand Down

0 comments on commit f14dc29

Please sign in to comment.