def _create_resizer(self, width, height): self.resizer = ct.POINTER(mmal.MMAL_COMPONENT_T)() mmal_check(mmal.mmal_component_create( mmal.MMAL_COMPONENT_DEFAULT_RESIZER, self.resizer), prefix="Failed to create resizer component") if not self.resizer[0].input_num: raise PiCameraError("No input ports on resizer component") if not self.resizer[0].output_num: raise PiCameraError("No output ports on resizer component") # Copy the original input port's format to the resizer's input, # then the resizer's input format to the output, and configure it mmal.mmal_format_copy(self.resizer[0].input[0][0].format, self.input_port[0].format) mmal_check(mmal.mmal_port_format_commit(self.resizer[0].input[0]), prefix="Failed to set resizer input port format") mmal.mmal_format_copy(self.resizer[0].output[0][0].format, self.resizer[0].input[0][0].format) fmt = self.resizer[0].output[0][0].format fmt[0].es[0].video.width = width fmt[0].es[0].video.height = height fmt[0].es[0].video.crop.x = 0 fmt[0].es[0].video.crop.y = 0 fmt[0].es[0].video.crop.width = width fmt[0].es[0].video.crop.height = height mmal_check(mmal.mmal_port_format_commit(self.resizer[0].output[0]), prefix="Failed to set resizer output port format")
def _create_encoder(self): """ Creates and configures the encoder itself """ assert not self.encoder self.encoder = ct.POINTER(mmal.MMAL_COMPONENT_T)() mmal_check(mmal.mmal_component_create(self.encoder_type, self.encoder), prefix="Failed to create encoder component") if not self.encoder[0].input_num: raise PiCameraError("No input ports on encoder component") if not self.encoder[0].output_num: raise PiCameraError("No output ports on encoder component") # Ensure output format is the same as the input self.output_port = self.encoder[0].output[0] if self.resizer: mmal.mmal_format_copy(self.encoder[0].input[0][0].format, self.resizer[0].output[0][0].format) else: mmal.mmal_format_copy(self.encoder[0].input[0][0].format, self.input_port[0].format) mmal_check(mmal.mmal_port_format_commit(self.encoder[0].input[0]), prefix="Failed to set encoder input port format") mmal.mmal_format_copy(self.output_port[0].format, self.encoder[0].input[0][0].format) # Set buffer size and number to appropriate values self.output_port[0].buffer_size = max( self.output_port[0].buffer_size_recommended, self.output_port[0].buffer_size_min) self.output_port[0].buffer_num = max( self.output_port[0].buffer_num_recommended, self.output_port[0].buffer_num_min)
def _callback_recycle(self, port, buf): """ Recycles the buffer on behalf of the encoder callback function """ new_buf = mmal.mmal_queue_get(self.pool[0].queue) if not new_buf: raise PiCameraError( "Unable to get a buffer to return to the encoder port") mmal_check(mmal.mmal_port_send_buffer(port, new_buf), prefix="Unable to return a buffer to the encoder port")
def _create_pool(self): """ Allocates a pool of buffers for the encoder """ assert not self.pool self.pool = mmal.mmal_port_pool_create(self.output_port, self.output_port[0].buffer_num, self.output_port[0].buffer_size) if not self.pool: raise PiCameraError( "Failed to create buffer header pool for encoder component")
def _callback_write(self, buf): """ Performs output writing on behalf of the encoder callback function; return value determines whether writing has completed. """ if buf[0].length: mmal_check(mmal.mmal_buffer_header_mem_lock(buf), prefix="Unable to lock buffer header memory") try: with self.lock: if self.output: written = self.output.write( ct.string_at(buf[0].data, buf[0].length)) # Ignore None return value; most Python 2 streams have # no return value for write() if (written is not None) and (written != buf[0].length): raise PiCameraError( "Unable to write buffer to file - aborting") finally: mmal.mmal_buffer_header_mem_unlock(buf) return bool(buf[0].flags & mmal.MMAL_BUFFER_HEADER_FLAG_EOS)
def _callback_write(self, buf): # Overridden to strip alpha bytes when necessary, and manually # calculate the frame end if buf[0].length and self._image_size: mmal_check(mmal.mmal_buffer_header_mem_lock(buf), prefix="Unable to lock buffer header memory") try: s = ct.string_at(buf[0].data, buf[0].length) if self._strip_alpha: s = b''.join(s[i:i + 3] for i in range(0, len(s), 4)) with self.lock: if self.output: written = self.output.write(s) # Ignore None return value; most Python 2 streams have # no return value for write() if (written is not None) and (written != len(s)): raise PiCameraError( "Unable to write buffer to file - aborting") self._image_size -= len(s) assert self._image_size >= 0 finally: mmal.mmal_buffer_header_mem_unlock(buf) return self._image_size <= 0