def split(self, output): with self.lock: if self._next_output is None: raise PiCameraRuntimeError( 'Cannot use split_recording without inline_headers and CBR' ) self._next_output.append(output) # XXX Instead of a 10-second timeout, how about a warning here (which # can be converted to an error and captured by the test suite?) if not self.event.wait(10): raise PiCameraRuntimeError('Timed out waiting for an SPS header') self.event.clear()
def split(self, output): with self.lock: if self._next_output is None: raise PiCameraRuntimeError( 'Cannot use split_recording without inline_headers and CBR') self._next_output.append(output) # intra_period / framerate gives the time between I-frames (which # should also coincide with SPS headers). We multiply by two to ensure # the timeout is deliberately excessive timeout = float(self._intra_period / self.parent.framerate) * 2.0 if not self.event.wait(timeout): raise PiCameraRuntimeError('Timed out waiting for an SPS header') self.event.clear()
def __init__(self, parent, camera_port, input_port, format, resize, **options): self.parent = parent self.format = format self.encoder = None self.resizer = None self.encoder_connection = None self.resizer_connection = None self.camera_port = camera_port self.input_port = input_port self.output_port = None self.pool = None self.started_capture = False self.opened_output = False self.output = None self.lock = threading.Lock() # protects access to self.output self.exception = None self.event = threading.Event() self.stopped = True try: if parent.closed: raise PiCameraRuntimeError("Camera is closed") if resize: self._create_resizer(*resize) self._create_encoder(**options) self._create_pool() self._create_connection() except: self.close() raise
def start(self, output): """ Starts the encoder object writing to the specified output """ self.event.clear() self.stopped = False self.exception = None self._open_output(output) self.output_port[0].userdata = ct.cast(ct.pointer(ct.py_object(self)), ct.c_void_p) mmal_check(mmal.mmal_port_enable(self.output_port, _encoder_callback), prefix="Failed to enable encoder output port") for q in range(mmal.mmal_queue_length(self.pool[0].queue)): buf = mmal.mmal_queue_get(self.pool[0].queue) if not buf: raise PiCameraRuntimeError( "Unable to get a required buffer from pool queue") 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_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 update(self, source): """ Update the overlay with a new source of data. The new *source* buffer must have the same size as the original buffer used to create the overlay. There is currently no method for changing the size of an existing overlay (remove and recreate the overlay if you require this). """ port = self.renderer[0].input[0] fmt = port[0].format bp = ct.c_uint8 * (fmt[0].es[0].video.width * fmt[0].es[0].video.height * 3) try: sp = bp.from_buffer(source) except TypeError: sp = bp.from_buffer_copy(source) buf = mmal.mmal_queue_get(self.pool[0].queue) if not buf: raise PiCameraRuntimeError( "Couldn't get a buffer from the overlay's pool") ct.memmove(buf[0].data, sp, buf[0].alloc_size) buf[0].length = buf[0].alloc_size mmal_check(mmal.mmal_port_send_buffer(port, buf), prefix="Unable to send a buffer to the overlay's port")
def __init__(self, parent, source, size=None, layer=0, alpha=255, fullscreen=True, window=None, crop=None, rotation=0, vflip=False, hflip=False): super(PiOverlayRenderer, self).__init__(parent, layer, alpha, fullscreen, window, crop, rotation, vflip, hflip) # Copy format from camera's preview port, then adjust the encoding to # RGB888 and optionally adjust the resolution and size port = self.renderer[0].input[0] fmt = port[0].format mmal.mmal_format_copy( fmt, parent._camera[0].output[parent.CAMERA_PREVIEW_PORT][0].format) fmt[0].encoding = mmal.MMAL_ENCODING_RGB24 fmt[0].encoding_variant = mmal.MMAL_ENCODING_RGB24 if size is not None: w, h = size fmt[0].es[0].video.width = mmal.VCOS_ALIGN_UP(w, 32) fmt[0].es[0].video.height = mmal.VCOS_ALIGN_UP(h, 16) fmt[0].es[0].video.crop.width = w fmt[0].es[0].video.crop.height = h mmal_check(mmal.mmal_port_format_commit(port), prefix="Overlay format couldn't be set") port[0].buffer_num = port[0].buffer_num_min port[0].buffer_size = port[0].buffer_size_recommended mmal_check(mmal.mmal_component_enable(self.renderer), prefix="Overlay couldn't be enabled") mmal_check(mmal.mmal_port_enable(port, _overlay_callback), prefix="Overlay input port couldn't be enabled") self.pool = mmal.mmal_port_pool_create(port, port[0].buffer_num, port[0].buffer_size) if not self.pool: raise PiCameraRuntimeError("Couldn't create pool for overlay") self.update(source)
def start(self, output): """ Starts the encoder object writing to the specified output """ self.event.clear() self.stopped = False self.exception = None self._open_output(output) self.output_port[0].userdata = ct.cast(ct.pointer(ct.py_object(self)), ct.c_void_p) mmal_check(mmal.mmal_port_enable(self.output_port, _encoder_callback), prefix="Failed to enable encoder output port") for q in range(mmal.mmal_queue_length(self.pool[0].queue)): buf = mmal.mmal_queue_get(self.pool[0].queue) if not buf: raise PiCameraRuntimeError( "Unable to get a required buffer from pool queue") mmal_check(mmal.mmal_port_send_buffer(self.output_port, buf), prefix="Unable to send a buffer to encoder output port")
def __init__(self, parent, port, format, **options): self.parent = parent self.encoder = None self.camera_port = port self.input_port = None self.output_port = None self.pool = None self.connection = None self.opened = False self.output = None self.lock = threading.Lock() # protects access to self.output self.exception = None self.event = threading.Event() self.stopped = True try: if parent.closed: raise PiCameraRuntimeError("Camera is closed") self._create_encoder(format, **options) self._create_pool() self._create_connection() except: self.close() raise