private int GetBitrate(MMal.MMAL_VIDEO_LEVEL_T level, int bitrate, string[] options) { var paramBitrate = GetConfig.GetInt32("bitrate", 17000000, options); var allowedBitRate = _h264bitRates.FirstOrDefault(c => c.Item1 == level); if (allowedBitRate != null) { return(allowedBitRate.Item2 < paramBitrate ? allowedBitRate.Item2 : paramBitrate); } return(paramBitrate); }
/// <summary> /// Default settings used: /// bitrate=17000000, intra_period=None, profile='high', /// level='4', quantization=0, quality=0, inline_headers=True, /// sei=False, sps_timing=False, motion_output=None, /// intra_refresh=None // Max bitrate we allow for recording /// </summary> public unsafe override void CreateEncoder(ImageFormat format, int resize, params string[] options) { if (_logger.IsDebugEnabled) { _logger.Debug("CreateEncoder {0}", format); } int bitrate = 17000000; bool inlineHeaders = true; bool sei = false; bool sps_timing = false; int quality = 23; uint mmalFormat; if (format == ImageFormat.h264) { mmalFormat = MMal.MMAL_ENCODING_H264; } else if (format == ImageFormat.mpeg) { mmalFormat = MMal.MMAL_ENCODING_MJPEG; } else { throw new Exception(String.Format("Invalid video format {0}", format)); } _outputPort.Format = (uint)mmalFormat; if (format == ImageFormat.h264) { //MMal.MMAL_VIDEO_PROFILE_T _profile = MMal.MMAL_VIDEO_PROFILE_T.MMAL_VIDEO_PROFILE_H264_HIGH; //MMal.MMAL_VIDEO_LEVEL_T _level = MMal.MMAL_VIDEO_LEVEL_T.MMAL_VIDEO_LEVEL_H264_4; MMal.MMAL_VIDEO_PROFILE_T profile = GetProfile(options); MMal.MMAL_VIDEO_LEVEL_T level = GetLevel(options); MMal.MMAL_PARAMETER_VIDEO_PROFILE_T param = new MMal.MMAL_PARAMETER_VIDEO_PROFILE_T(); param.hdr.id = (uint)MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_PROFILE; param.hdr.size = (uint)Marshal.SizeOf(param); param.profile = new MMal.VIDEO_PROFILE(); param.profile.profile = profile; param.profile.level = level; MMal.MMAL_STATUS_T status = MMal.mmal_port_parameter_set(_outputPort.Pointer, ¶m.hdr); if (status != MMal.MMAL_STATUS_T.MMAL_SUCCESS) { throw new Exception(String.Format("Cannot set parameter on port {0} {1}", _outputPort.Name, status)); } bitrate = GetBitrate(level, bitrate, options); // We need to set the frame rate on output to 0, to ensure it gets // updated correctly from the input framerate when port connected _outputPort.Framerate = (0, 1); _outputPort.BitRate = (uint)bitrate; _outputPort.Commit(); if (_logger.IsDebugEnabled) { _logger.Debug("Port Commited"); } if (inlineHeaders) { _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, true); } if (sei) { _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_SEI_ENABLE, true); } if (sps_timing) { _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, true); } // other H264 parameters must be set here } else { _outputPort.BitRate = 1; _outputPort.Commit(); } if (quality != 0) { _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, quality); _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, quality); _outputPort.SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, quality); } Encoder.Inputs[0].SetParam(MMal.MMAL_PARAMETER_IDS.MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, true); Encoder.Enable(); if (_logger.IsDebugEnabled) { _logger.Debug("PiVideoEncoder.CreateEncoder done Output port {0}", _outputPort.ToString()); } base.CreateEncoder(format, resize, options); }