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_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, **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 )
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) * # round up width to nearest multiple of 32 ((height + 15) // 16 * 16) * # round up height to nearest multiple of 16 bytes_per_pixel)
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 _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 )
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")
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")
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")
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 _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")
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 _create_encoder(self, format, **options): super(PiVideoEncoder, self)._create_encoder(format, **options) try: self.output_port[0].format[0].encoding = { 'h264': mmal.MMAL_ENCODING_H264, }[format] except KeyError: raise PiCameraValueError('Unrecognized format %s' % format) bitrate = options.get('bitrate', 17000000) if bitrate > 25000000: raise PiCameraValueError('25Mbps is the maximum bitrate') 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 'intraperiod' in options: mp = mmal.MMAL_PARAMETER_UINT32_T( mmal.MMAL_PARAMETER_HEADER_T( mmal.MMAL_PARAMETER_INTRAPERIOD, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T), ), int(options['intraperiod']) ) mmal_check( mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set encoder intraperiod") if 'profile' in options: mp = mmal.MMAL_PARAMETER_VIDEO_PROFILE_T( mmal.MMAL_PARAMETER_HEADER_T( mmal.MMAL_PARAMETER_PROFILE, ct.sizeof(mmal.MMAL_PARAMETER_VIDEO_PROFILE_T), ), ) 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, }[options['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") # XXX Why does this fail? Is it even needed? #try: # mmal_check( # mmal.mmal_port_parameter_set_boolean( # enc_in, # mmal.MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, # 1), # prefix="Unable to set immutable flag on encoder input port") #except PiCameraError as e: # print(str(e)) # # Continue rather than abort... mmal_check( mmal.mmal_component_enable(self.encoder), prefix="Unable to enable video encoder component")
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")
def _create_encoder( self, format, bitrate=17000000, intra_period=0, profile='high', quantization=0, inline_headers=True, **options): super(PiVideoEncoder, self)._create_encoder(format, **options) try: self.output_port[0].format[0].encoding = { 'h264': mmal.MMAL_ENCODING_H264, }[format] except KeyError: raise PiCameraValueError('Unrecognized format %s' % 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 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 quantization") mp = mmal.MMAL_PARAMETER_UINT32_T( mmal.MMAL_PARAMETER_HEADER_T( mmal.MMAL_PARAMETER_VIDEO_ENCODE_QP_P, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T), ), quantization + 6, ) mmal_check( mmal.mmal_port_parameter_set(self.output_port, mp.hdr), prefix="Unable to set quantization") 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.input_port, mmal.MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, 1), prefix="Unable to set immutable flag on encoder input port") 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 mmal_check( mmal.mmal_component_enable(self.encoder), prefix="Unable to enable video encoder component")
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")
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 # We need the intra-period to calculate the SPS header timeout in # the split method below. If one is not set explicitly, query the # encoder's default 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") self._intra_period = intra_period else: mp = mmal.MMAL_PARAMETER_UINT32_T( mmal.MMAL_PARAMETER_HEADER_T( mmal.MMAL_PARAMETER_INTRAPERIOD, ct.sizeof(mmal.MMAL_PARAMETER_UINT32_T), )) mmal_check( mmal.mmal_port_parameter_get(self.output_port, mp.hdr), prefix="Unable to get encoder intra_period") self._intra_period = mp.value elif self.format == 'mjpeg': # MJPEG doesn't have an intra_period setting as such, but as every # frame is a full-frame, the intra_period is effectively 1 self._intra_period = 1 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")