Пример #1
0
 def wait(self, timeout=None):
     """
     Waits for the encoder to finish (successfully or otherwise)
     """
     result = self.event.wait(timeout)
     if result:
         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),
                 prefix="Failed to disable encoder output port")
         except PiCameraMMALError as e:
             if e.status != mmal.MMAL_EINVAL:
                 raise
         self._close_output()
         # Check whether the callback set an exception
         if self.exception:
             raise self.exception
     return result
Пример #2
0
    def __init__(
            self, parent, layer=0, alpha=255, fullscreen=True, window=None,
            crop=None, rotation=0, vflip=False, hflip=False):
        # Create and enable the renderer component
        self._rotation = 0
        self._vflip = False
        self._hflip = False
        self.parent = parent
        self.renderer = ct.POINTER(mmal.MMAL_COMPONENT_T)()
        mmal_check(
            mmal.mmal_component_create(
                mmal.MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, self.renderer),
            prefix="Failed to create renderer component")
        try:
            if not self.renderer[0].input_num:
                raise PiCameraError("No input ports on renderer component")

            self.layer = layer
            self.alpha = alpha
            self.fullscreen = fullscreen
            if window is not None:
                self.window = window
            if crop is not None:
                self.crop = crop
            self.rotation = rotation
            self.vflip = vflip
            self.hflip = hflip

            mmal_check(
                mmal.mmal_component_enable(self.renderer),
                prefix="Renderer component couldn't be enabled")
        except:
            mmal.mmal_component_destroy(self.renderer)
            raise
Пример #3
0
    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")
Пример #4
0
 def stop(self):
     """
     Stops the encoder, regardless of whether it's finished
     """
     # The check on is_enabled below is not a race condition; we ignore the
     # EINVAL error in the case the port turns out to be disabled when we
     # 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:
         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), prefix="Failed to disable encoder output port")
         except PiCameraMMALError as e:
             if e.status != mmal.MMAL_EINVAL:
                 raise
     self.stopped = True
     self.event.set()
     self._close_output()
Пример #5
0
 def _set_fullscreen(self, value):
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION, ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
         set=mmal.MMAL_DISPLAY_SET_FULLSCREEN,
         fullscreen=bool(value),
     )
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0], mp.hdr), prefix="Failed to set fullscreen")
Пример #6
0
 def _create_encoder(self, **options):
     """
     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
     )
Пример #7
0
 def _create_resizer(self, width, height):
     super(PiRawEncoderMixin, self)._create_resizer(width, height)
     # Set the resizer's output encoding to the requested format. If a
     # non-alpha format is requested, use the alpha-inclusive format and set
     # a flag to get the callback to strip the alpha bytes
     encoding, bytes_per_pixel = {
         "yuv": (mmal.MMAL_ENCODING_I420, 1.5),
         "rgb": (mmal.MMAL_ENCODING_RGBA, 3),
         "rgba": (mmal.MMAL_ENCODING_RGBA, 4),
         "bgr": (mmal.MMAL_ENCODING_BGRA, 3),
         "bgra": (mmal.MMAL_ENCODING_BGRA, 4),
     }[self.format]
     self._strip_alpha = self.format in ("rgb", "bgr")
     port = self.resizer[0].output[0]
     port[0].format[0].encoding = encoding
     port[0].format[0].encoding_variant = encoding
     mmal_check(mmal.mmal_port_format_commit(port), prefix="Failed to set resizer output port format")
     # Calculate the expected image size, to be used by the callback to
     # decide when a frame ends. This is to work around a firmware bug that
     # causes the raw image to be returned twice when the maximum camera
     # resolution is requested
     self._expected_size = int(
         ((width + 31) // 32 * 32)
         * ((height + 15) // 16 * 16)  # round up width to nearest multiple of 32
         * bytes_per_pixel  # round up height to nearest multiple of 16
     )
Пример #8
0
 def _set_transform(self, value):
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION, ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
         set=mmal.MMAL_DISPLAY_SET_TRANSFORM,
         transform=value,
     )
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0], mp.hdr), prefix="Failed to set transform")
Пример #9
0
 def _add_exif_tag(self, tag, value):
     # Format the tag and value into an appropriate bytes string, encoded
     # with the Exif encoding (ASCII)
     if isinstance(tag, str):
         tag = tag.encode(self.exif_encoding)
     if isinstance(value, str):
         value = value.encode(self.exif_encoding)
     elif isinstance(value, datetime.datetime):
         value = value.strftime('%Y:%m:%d %H:%M:%S').encode(self.exif_encoding)
     # MMAL_PARAMETER_EXIF_T is a variable sized structure, hence all the
     # mucking about with string buffers here...
     buf = ct.create_string_buffer(
         ct.sizeof(mmal.MMAL_PARAMETER_EXIF_T) + len(tag) + len(value) + 1)
     mp = ct.cast(buf, ct.POINTER(mmal.MMAL_PARAMETER_EXIF_T))
     mp[0].hdr.id = mmal.MMAL_PARAMETER_EXIF
     mp[0].hdr.size = len(buf)
     if (b'=' in tag or b'\x00' in value):
         data = tag + value
         mp[0].keylen = len(tag)
         mp[0].value_offset = len(tag)
         mp[0].valuelen = len(value)
     else:
         data = tag + b'=' + value
     ct.memmove(mp[0].data, data, len(data))
     mmal_check(
         mmal.mmal_port_parameter_set(self.output_port, mp[0].hdr),
         prefix="Failed to set Exif tag %s" % tag)
Пример #10
0
 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")
Пример #11
0
 def _create_resizer(self, width, height):
     super(PiRawEncoderMixin, self)._create_resizer(width, height)
     encoding = self.RAW_ENCODINGS[self.format][0]
     port = self.resizer[0].output[0]
     port[0].format[0].encoding = encoding
     port[0].format[0].encoding_variant = encoding
     mmal_check(
         mmal.mmal_port_format_commit(port),
         prefix="Failed to set resizer output port format")
Пример #12
0
def test_mmal_check():
    mmal_check(mmal.MMAL_SUCCESS)
    with pytest.raises(PiCameraError):
        mmal_check(mmal.MMAL_ENOSYS)
    with pytest.raises(PiCameraError):
        mmal_check(mmal.MMAL_ENOMEM)
    with pytest.raises(PiCameraError):
        mmal_check(mmal.MMAL_ENOSPC)
    with pytest.raises(PiCameraError):
        mmal_check(mmal.MMAL_EINVAL)
Пример #13
0
 def _get_fullscreen(self):
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(
             mmal.MMAL_PARAMETER_DISPLAYREGION,
             ct.sizeof(mmal.MMAL_DISPLAYREGION_T)
         ))
     mmal_check(
         mmal.mmal_port_parameter_get(self.renderer[0].input[0], mp.hdr),
         prefix="Failed to get fullscreen")
     return mp.fullscreen != mmal.MMAL_FALSE
Пример #14
0
 def stop(self):
     """
     Stops the encoder, regardless of whether it's finished
     """
     if self.encoder and self.output_port[0].is_enabled:
         mmal_check(
             mmal.mmal_port_disable(self.output_port),
             prefix="Failed to disable encoder output port")
     self.stopped = True
     self.event.set()
     self._close_output()
Пример #15
0
 def _set_crop(self, value):
     try:
         x, y, w, h = value
     except (TypeError, ValueError) as e:
         raise PiCameraValueError("Invalid crop rectangle (x, y, w, h) tuple: %s" % value)
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION, ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
         set=mmal.MMAL_DISPLAY_SET_SRC_RECT,
         src_rect=mmal.MMAL_RECT_T(x, y, w, h),
     )
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0], mp.hdr), prefix="Failed to set crop")
Пример #16
0
 def _set_layer(self, value):
     try:
         if not (0 <= value <= 255):
             raise PiCameraValueError("Invalid layer value: %d (valid range 0..255)" % value)
     except TypeError:
         raise PiCameraValueError("Invalid layer value: %s" % value)
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION, ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
         set=mmal.MMAL_DISPLAY_SET_LAYER,
         layer=value,
     )
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0], mp.hdr), prefix="Failed to set layer")
Пример #17
0
    def _create_encoder(self, quality=85, thumbnail=(64, 48, 35), bayer=False):
        super(PiImageEncoder, self)._create_encoder()

        try:
            self.output_port[0].format[0].encoding = {
                'jpeg': mmal.MMAL_ENCODING_JPEG,
                'png':  mmal.MMAL_ENCODING_PNG,
                'gif':  mmal.MMAL_ENCODING_GIF,
                'bmp':  mmal.MMAL_ENCODING_BMP,
                }[self.format]
        except KeyError:
            raise PiCameraValueError("Unrecognized format %s" % self.format)
        mmal_check(
            mmal.mmal_port_format_commit(self.output_port),
            prefix="Unable to set format on encoder output port")

        if self.format == 'jpeg':
            mmal_check(
                mmal.mmal_port_parameter_set_uint32(
                    self.output_port,
                    mmal.MMAL_PARAMETER_JPEG_Q_FACTOR,
                    quality),
                prefix="Failed to set JPEG quality")

            mmal_check(
                mmal.mmal_port_parameter_set_boolean(
                    self.camera_port,
                    mmal.MMAL_PARAMETER_ENABLE_RAW_CAPTURE,
                    int(bool(bayer))),
                prefix="Failed to set raw capture")

            if thumbnail is None:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)
                        ),
                    0, 0, 0, 0)
            else:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)
                        ),
                    1, *thumbnail)
            mmal_check(
                mmal.mmal_port_parameter_set(self.encoder[0].control, mp.hdr),
                prefix="Failed to set thumbnail configuration")

        mmal_check(
            mmal.mmal_component_enable(self.encoder),
            prefix="Unable to enable encoder component")
Пример #18
0
 def _get_crop(self):
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION,
                                      ct.sizeof(mmal.MMAL_DISPLAYREGION_T)))
     mmal_check(mmal.mmal_port_parameter_get(self.renderer[0].input[0],
                                             mp.hdr),
                prefix="Failed to get crop")
     return (
         mp.src_rect.x,
         mp.src_rect.y,
         mp.src_rect.width,
         mp.src_rect.height,
     )
Пример #19
0
    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")
Пример #20
0
 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_disable(self.output_port),
             prefix="Failed to disable encoder output port")
         self._close_output()
         # Check whether the callback set an exception
         if self.exception:
             raise self.exception
     return result
Пример #21
0
    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",
            )
Пример #22
0
 def __init__(self, parent, source):
     self.parent = parent
     self.renderer = ct.POINTER(mmal.MMAL_COMPONENT_T)()
     mmal_check(
         mmal.mmal_component_create(mmal.MMAL_COMPONENT_DEFAULT_NULL_SINK, self.renderer),
         prefix="Failed to create null sink component",
     )
     try:
         if not self.renderer[0].input_num:
             raise PiCameraError("No input ports on null sink component")
         mmal_check(mmal.mmal_component_enable(self.renderer), prefix="Null sink component couldn't be enabled")
     except:
         mmal.mmal_component_destroy(self.renderer)
         raise
     self.connection = self.parent._connect_ports(source, self.renderer[0].input[0])
Пример #23
0
 def _set_layer(self, value):
     try:
         if not (0 <= value <= 255):
             raise PiCameraValueError(
                 "Invalid layer value: %d (valid range 0..255)" % value)
     except TypeError:
         raise PiCameraValueError("Invalid layer value: %s" % value)
     mp = mmal.MMAL_DISPLAYREGION_T(mmal.MMAL_PARAMETER_HEADER_T(
         mmal.MMAL_PARAMETER_DISPLAYREGION,
         ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
                                    set=mmal.MMAL_DISPLAY_SET_LAYER,
                                    layer=value)
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0],
                                             mp.hdr),
                prefix="Failed to set layer")
Пример #24
0
 def _set_crop(self, value):
     try:
         x, y, w, h = value
     except (TypeError, ValueError) as e:
         raise PiCameraValueError(
             "Invalid crop rectangle (x, y, w, h) tuple: %s" % value)
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(mmal.MMAL_PARAMETER_DISPLAYREGION,
                                      ct.sizeof(mmal.MMAL_DISPLAYREGION_T)),
         set=mmal.MMAL_DISPLAY_SET_SRC_RECT,
         src_rect=mmal.MMAL_RECT_T(x, y, w, h),
     )
     mmal_check(mmal.mmal_port_parameter_set(self.renderer[0].input[0],
                                             mp.hdr),
                prefix="Failed to set crop")
Пример #25
0
 def _get_crop(self):
     mp = mmal.MMAL_DISPLAYREGION_T(
         mmal.MMAL_PARAMETER_HEADER_T(
             mmal.MMAL_PARAMETER_DISPLAYREGION,
             ct.sizeof(mmal.MMAL_DISPLAYREGION_T)
         ))
     mmal_check(
         mmal.mmal_port_parameter_get(self.renderer[0].input[0], mp.hdr),
         prefix="Failed to get crop")
     return (
         mp.src_rect.x,
         mp.src_rect.y,
         mp.src_rect.width,
         mp.src_rect.height,
         )
Пример #26
0
 def __init__(self, parent, source):
     self.parent = parent
     self.renderer = ct.POINTER(mmal.MMAL_COMPONENT_T)()
     mmal_check(mmal.mmal_component_create(
         mmal.MMAL_COMPONENT_DEFAULT_NULL_SINK, self.renderer),
                prefix="Failed to create null sink component")
     try:
         if not self.renderer[0].input_num:
             raise PiCameraError("No input ports on null sink component")
         mmal_check(mmal.mmal_component_enable(self.renderer),
                    prefix="Null sink component couldn't be enabled")
     except:
         mmal.mmal_component_destroy(self.renderer)
         raise
     self.connection = self.parent._connect_ports(source,
                                                  self.renderer[0].input[0])
Пример #27
0
 def _create_connection(self):
     """
     Connects the camera to the encoder object
     """
     assert not self.connection
     self.connection = ct.POINTER(mmal.MMAL_CONNECTION_T)()
     mmal_check(
         mmal.mmal_connection_create(
             self.connection,
             self.camera[0].output[self.port],
             self.input_port,
             mmal.MMAL_CONNECTION_FLAG_TUNNELLING |
             mmal.MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT),
         prefix="Failed to connect camera to encoder")
     mmal_check(
         mmal.mmal_connection_enable(self.connection),
         prefix="Failed to enable encoder connection")
Пример #28
0
 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 and self.output.write(
                        ct.string_at(buf[0].data, buf[0].length)) != buf[0].length:
                     raise PiCameraError(
                         "Unable to write buffer to file - aborting")
         finally:
             mmal.mmal_buffer_header_mem_unlock(buf)
     return False
Пример #29
0
 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)
Пример #30
0
    def _create_encoder(self, quality=85, thumbnail=(64, 48, 35), bayer=False):
        super(PiImageEncoder, self)._create_encoder()

        try:
            self.output_port[0].format[0].encoding = {
                'jpeg': mmal.MMAL_ENCODING_JPEG,
                'png': mmal.MMAL_ENCODING_PNG,
                'gif': mmal.MMAL_ENCODING_GIF,
                'bmp': mmal.MMAL_ENCODING_BMP,
            }[self.format]
        except KeyError:
            raise PiCameraValueError("Unrecognized format %s" % self.format)
        mmal_check(mmal.mmal_port_format_commit(self.output_port),
                   prefix="Unable to set format on encoder output port")

        if self.format == 'jpeg':
            mmal_check(mmal.mmal_port_parameter_set_uint32(
                self.output_port, mmal.MMAL_PARAMETER_JPEG_Q_FACTOR, quality),
                       prefix="Failed to set JPEG quality")

            mmal_check(mmal.mmal_port_parameter_set_boolean(
                self.camera_port, mmal.MMAL_PARAMETER_ENABLE_RAW_CAPTURE,
                int(bool(bayer))),
                       prefix="Failed to set raw capture")

            if thumbnail is None:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)), 0,
                    0, 0, 0)
            else:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)), 1,
                    *thumbnail)
            mmal_check(mmal.mmal_port_parameter_set(self.encoder[0].control,
                                                    mp.hdr),
                       prefix="Failed to set thumbnail configuration")

        mmal_check(mmal.mmal_component_enable(self.encoder),
                   prefix="Unable to enable encoder component")
Пример #31
0
    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")
Пример #32
0
 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
Пример #33
0
 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")
Пример #34
0
 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"
     )
Пример #35
0
    def __init__(self,
                 parent,
                 layer=0,
                 alpha=255,
                 fullscreen=True,
                 window=None,
                 crop=None,
                 rotation=0,
                 vflip=False,
                 hflip=False):
        # Create and enable the renderer component
        self._rotation = 0
        self._vflip = False
        self._hflip = False
        self.parent = parent
        self.renderer = ct.POINTER(mmal.MMAL_COMPONENT_T)()
        mmal_check(mmal.mmal_component_create(
            mmal.MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, self.renderer),
                   prefix="Failed to create renderer component")
        try:
            if not self.renderer[0].input_num:
                raise PiCameraError("No input ports on renderer component")

            self.layer = layer
            self.alpha = alpha
            self.fullscreen = fullscreen
            if window is not None:
                self.window = window
            if crop is not None:
                self.crop = crop
            self.rotation = rotation
            self.vflip = vflip
            self.hflip = hflip

            mmal_check(mmal.mmal_component_enable(self.renderer),
                       prefix="Renderer component couldn't be enabled")
        except:
            mmal.mmal_component_destroy(self.renderer)
            raise
Пример #36
0
 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)
Пример #37
0
 def wait(self, timeout=None):
     """
     Waits for the encoder to finish (successfully or otherwise)
     """
     result = self.event.wait(timeout)
     if result:
         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),
                        prefix="Failed to disable encoder output port")
         except PiCameraMMALError as e:
             if e.status != mmal.MMAL_EINVAL:
                 raise
         # Check whether the callback set an exception
         if self.exception:
             raise self.exception
     return result
Пример #38
0
    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")
Пример #39
0
 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
Пример #40
0
 def _create_encoder(self, format, **options):
     """
     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]
     self.input_port = self.encoder[0].input[0]
     mmal.mmal_format_copy(self.output_port[0].format,
                           self.input_port[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)
Пример #41
0
 def stop(self):
     """
     Stops the encoder, regardless of whether it's finished
     """
     # The check on is_enabled below is not a race condition; we ignore the
     # EINVAL error in the case the port turns out to be disabled when we
     # 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:
         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),
                        prefix="Failed to disable encoder output port")
         except PiCameraMMALError as e:
             if e.status != mmal.MMAL_EINVAL:
                 raise
     self.stopped = True
     self.event.set()
     self._close_output()
Пример #42
0
    def _create_encoder(self, format, **options):
        super(PiImageEncoder, self)._create_encoder(format, **options)

        try:
            self.output_port[0].format[0].encoding = {
                'jpeg': mmal.MMAL_ENCODING_JPEG,
                'png':  mmal.MMAL_ENCODING_PNG,
                'gif':  mmal.MMAL_ENCODING_GIF,
                'bmp':  mmal.MMAL_ENCODING_BMP,
                }[format]
        except KeyError:
            raise PiCameraValueError("Unrecognized format %s" % format)
        mmal_check(
            mmal.mmal_port_format_commit(self.output_port),
            prefix="Unable to set format on encoder output port")

        if format == 'jpeg':
            mmal_check(
                mmal.mmal_port_parameter_set_uint32(
                    self.output_port,
                    mmal.MMAL_PARAMETER_JPEG_Q_FACTOR,
                    options.get('quality', 85)),
                prefix="Failed to set JPEG quality")

            thumbnail = options.get('thumbnail', (64, 48, 35))
            if thumbnail is None:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)
                        ),
                    0, 0, 0, 0)
            else:
                mp = mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_THUMBNAIL_CONFIGURATION,
                        ct.sizeof(mmal.MMAL_PARAMETER_THUMBNAIL_CONFIG_T)
                        ),
                    1, *thumbnail)
            mmal_check(
                mmal.mmal_port_parameter_set(self.encoder[0].control, mp.hdr),
                prefix="Failed to set thumbnail configuration")

        mmal_check(
            mmal.mmal_component_enable(self.encoder),
            prefix="Unable to enable encoder component")
Пример #43
0
    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)
Пример #44
0
    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)
Пример #45
0
    def _create_encoder(
        self, bitrate=17000000, intra_period=0, profile="high", quantization=0, inline_headers=True, **options
    ):
        super(PiVideoEncoder, self)._create_encoder(**options)

        try:
            self.output_port[0].format[0].encoding = {
                "h264": mmal.MMAL_ENCODING_H264,
                "mjpeg": mmal.MMAL_ENCODING_MJPEG,
            }[self.format]
        except KeyError:
            raise PiCameraValueError("Unrecognized format %s" % self.format)

        if not (0 <= bitrate <= 25000000):
            raise PiCameraValueError("bitrate must be between 0 (VBR) and 25Mbps")
        if quantization and bitrate:
            warnings.warn("Setting bitrate to 0 as quantization is non-zero", PiCameraWarning)
            bitrate = 0
        self.output_port[0].format[0].bitrate = bitrate
        mmal_check(mmal.mmal_port_format_commit(self.output_port), prefix="Unable to set format on encoder output port")

        if self.format == "h264":
            mp = mmal.MMAL_PARAMETER_VIDEO_PROFILE_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_PROFILE, ct.sizeof(mmal.MMAL_PARAMETER_VIDEO_PROFILE_T)
                )
            )
            try:
                mp.profile[0].profile = {
                    "baseline": mmal.MMAL_VIDEO_PROFILE_H264_BASELINE,
                    "main": mmal.MMAL_VIDEO_PROFILE_H264_MAIN,
                    "high": mmal.MMAL_VIDEO_PROFILE_H264_HIGH,
                    "constrained": mmal.MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
                }[profile]
            except KeyError:
                raise PiCameraValueError("Invalid H.264 profile %s" % profile)
            mp.profile[0].level = mmal.MMAL_VIDEO_LEVEL_H264_4
            mmal_check(
                mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set encoder H.264 profile"
            )

            mmal_check(
                mmal.mmal_port_parameter_set_boolean(
                    self.output_port, mmal.MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, int(inline_headers)
                ),
                prefix="Unable to set inline_headers",
            )

            if not (bitrate and inline_headers):
                # If inline_headers is disabled, or VBR encoding is configured,
                # disable the split function
                self._next_output = None

            if intra_period:
                mp = mmal.MMAL_PARAMETER_UINT32_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_INTRAPERIOD, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T)
                    ),
                    intra_period,
                )
                mmal_check(
                    mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set encoder intra_period"
                )

        if quantization:
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T)
                ),
                quantization,
            )
            mmal_check(
                mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set initial quantization"
            )
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T)
                ),
                quantization,
            )
            mmal_check(
                mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set minimum quantization"
            )
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T)
                ),
                quantization,
            )
            mmal_check(
                mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set maximum quantization"
            )

        mmal_check(
            mmal.mmal_port_parameter_set_boolean(
                self.encoder[0].input[0], mmal.MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, 1
            ),
            prefix="Unable to set immutable flag on encoder input port",
        )

        mmal_check(mmal.mmal_component_enable(self.encoder), prefix="Unable to enable video encoder component")
Пример #46
0
    def _create_encoder(self,
                        bitrate=17000000,
                        intra_period=0,
                        profile='high',
                        quantization=0,
                        inline_headers=True,
                        sei=False):
        super(PiVideoEncoder, self)._create_encoder()

        try:
            self.output_port[0].format[0].encoding = {
                'h264': mmal.MMAL_ENCODING_H264,
                'mjpeg': mmal.MMAL_ENCODING_MJPEG,
            }[self.format]
        except KeyError:
            raise PiCameraValueError('Unrecognized format %s' % self.format)

        if not (0 <= bitrate <= 25000000):
            raise PiCameraValueError(
                'bitrate must be between 0 (VBR) and 25Mbps')
        if quantization and bitrate:
            warnings.warn('Setting bitrate to 0 as quantization is non-zero',
                          PiCameraWarning)
            bitrate = 0
        self.output_port[0].format[0].bitrate = bitrate
        mmal_check(mmal.mmal_port_format_commit(self.output_port),
                   prefix="Unable to set format on encoder output port")

        if self.format == 'h264':
            mp = mmal.MMAL_PARAMETER_VIDEO_PROFILE_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_PROFILE,
                    ct.sizeof(mmal.MMAL_PARAMETER_VIDEO_PROFILE_T),
                ), )
            try:
                mp.profile[0].profile = {
                    'baseline':
                    mmal.MMAL_VIDEO_PROFILE_H264_BASELINE,
                    'main':
                    mmal.MMAL_VIDEO_PROFILE_H264_MAIN,
                    'high':
                    mmal.MMAL_VIDEO_PROFILE_H264_HIGH,
                    'constrained':
                    mmal.MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
                }[profile]
            except KeyError:
                raise PiCameraValueError("Invalid H.264 profile %s" % profile)
            mp.profile[0].level = mmal.MMAL_VIDEO_LEVEL_H264_4
            mmal_check(mmal.mmal_port_parameter_set(self.output_port, mp.hdr),
                       prefix="Unable to set encoder H.264 profile")

            mmal_check(mmal.mmal_port_parameter_set_boolean(
                self.output_port,
                mmal.MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
                int(inline_headers)),
                       prefix="Unable to set inline_headers")

            mmal_check(mmal.mmal_port_parameter_set_boolean(
                self.output_port, mmal.MMAL_PARAMETER_VIDEO_ENCODE_SEI_ENABLE,
                int(sei)),
                       prefix="Enable to set SEI")

            if not (bitrate and inline_headers):
                # If inline_headers is disabled, or VBR encoding is configured,
                # disable the split function
                self._next_output = None

            if intra_period:
                mp = mmal.MMAL_PARAMETER_UINT32_T(
                    mmal.MMAL_PARAMETER_HEADER_T(
                        mmal.MMAL_PARAMETER_INTRAPERIOD,
                        ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T),
                    ), intra_period)
                mmal_check(mmal.mmal_port_parameter_set(
                    self.output_port, mp.hdr),
                           prefix="Unable to set encoder intra_period")

        if quantization:
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT,
                    ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T),
                ), quantization)
            mmal_check(mmal.mmal_port_parameter_set(self.output_port, mp.hdr),
                       prefix="Unable to set initial quantization")
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT,
                    ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T),
                ),
                quantization,
            )
            mmal_check(mmal.mmal_port_parameter_set(self.output_port, mp.hdr),
                       prefix="Unable to set minimum quantization")
            mp = mmal.MMAL_PARAMETER_UINT32_T(
                mmal.MMAL_PARAMETER_HEADER_T(
                    mmal.MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT,
                    ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T),
                ),
                quantization,
            )
            mmal_check(mmal.mmal_port_parameter_set(self.output_port, mp.hdr),
                       prefix="Unable to set maximum quantization")

        mmal_check(mmal.mmal_port_parameter_set_boolean(
            self.encoder[0].input[0],
            mmal.MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, 1),
                   prefix="Unable to set immutable flag on encoder input port")

        mmal_check(mmal.mmal_component_enable(self.encoder),
                   prefix="Unable to enable video encoder component")