Beispiel #1
0
        /// <summary>
        /// Call to initialise the camera component.
        /// </summary>
        /// <param name="stillCaptureHandler">A capture handler when capturing raw image frames from the camera's still port (no encoder attached).</param>
        /// <param name="videoCaptureHandler">A capture handler when capturing raw video from the camera's video port (no encoder attached).</param>
        public void Initialise(IOutputCaptureHandler stillCaptureHandler = null, IOutputCaptureHandler videoCaptureHandler = null)
        {
            this.DisableComponent();

            var camConfig = new MMAL_PARAMETER_CAMERA_CONFIG_T(
                new MMAL_PARAMETER_HEADER_T(MMALParametersCamera.MMAL_PARAMETER_CAMERA_CONFIG, Marshal.SizeOf <MMAL_PARAMETER_CAMERA_CONFIG_T>()),
                this.CameraInfo.MaxWidth,
                this.CameraInfo.MaxHeight,
                0,
                1,
                MMALCameraConfig.VideoResolution.Width,
                MMALCameraConfig.VideoResolution.Height,
                3 + Math.Max(0, (MMALCameraConfig.VideoFramerate.Num - 30) / 10),
                0,
                0,
                MMALCameraConfig.ClockMode);

            this.SetCameraConfig(camConfig);

            MMALLog.Logger.LogDebug("Camera config set");

            this.Control.Start();

            MMALLog.Logger.LogDebug("Configuring camera parameters.");

            this.SetCameraParameters();

            this.InitialisePreview();
            this.InitialiseVideo(videoCaptureHandler);
            this.InitialiseStill(stillCaptureHandler);

            this.EnableComponent();

            MMALLog.Logger.LogDebug("Camera component configured.");
        }
Beispiel #2
0
        /// <inheritdoc />
        public override void Configure(IMMALPortConfig config, IInputPort copyFrom, IOutputCaptureHandler handler)
        {
            base.Configure(config, copyFrom, handler);

            if (config != null && config.EncodingType == MMALEncoding.JPEG)
            {
                this.SetParameter(MMALParametersCamera.MMAL_PARAMETER_JPEG_Q_FACTOR, config.Quality);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Initialises the camera's video port using the width, height and encoding as specified by the user.
        /// </summary>
        /// <param name="handler">The capture handler to associate with this port.</param>
        private void InitialiseVideo(IOutputCaptureHandler handler)
        {
            int currentWidth  = MMALCameraConfig.Resolution.Width;
            int currentHeight = MMALCameraConfig.Resolution.Height;

            if (currentWidth == 0 || currentWidth > this.CameraInfo.MaxWidth)
            {
                currentWidth = this.CameraInfo.MaxWidth;
            }

            if (currentHeight == 0 || currentHeight > this.CameraInfo.MaxHeight)
            {
                currentHeight = this.CameraInfo.MaxHeight;
            }

            var portConfig = new MMALPortConfig(
                MMALCameraConfig.Encoding,
                MMALCameraConfig.EncodingSubFormat,
                width: currentWidth,
                height: currentHeight,
                framerate: MMALCameraConfig.Framerate,
                bufferNum: Math.Max(MMALCameraConfig.UserBufferNum, Math.Max(this.VideoPort.BufferNumRecommended, 3)),
                bufferSize: Math.Max(MMALCameraConfig.UserBufferSize, Math.Max(this.VideoPort.BufferSizeRecommended, this.VideoPort.BufferSizeMin)),
                crop: new Rectangle(0, 0, currentWidth, currentHeight));

            MMALLog.Logger.LogDebug("Commit video");

            this.VideoPort.Configure(portConfig, null, handler);

            // Use Raspistill values.
            if (MMALCameraConfig.ShutterSpeed > 6000000)
            {
                this.VideoPort.SetFramerateRange(new MMAL_RATIONAL_T(5, 1000), new MMAL_RATIONAL_T(166, 1000));
            }
            else if (MMALCameraConfig.ShutterSpeed > 1000000)
            {
                this.VideoPort.SetFramerateRange(new MMAL_RATIONAL_T(167, 1000), new MMAL_RATIONAL_T(999, 1000));
            }
        }
        /// <inheritdoc />
        public override IDownstreamComponent ConfigureOutputPort(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
        {
            this.Quality = config.Quality;

            var bufferSize = 0;
            var framerate  = 0;

            if (config.EncodingType == MMALEncoding.H264)
            {
                bufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, this.Outputs[outputPort].Ptr->BufferSizeMin);
            }
            else
            {
                // Follow raspivid logic.
                bufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, 256 << 10);
            }

            var bitrate = this.GetValidBitrate(outputPort, config);

            // Force framerate to be 0 in case it was provided by user.
            config = new MMALPortConfig(config.EncodingType, config.PixelFormat, config.Width, config.Height, framerate,
                                        config.Quality, bitrate, config.ZeroCopy, config.Timeout, config.Split, config.BufferNum, bufferSize, config.Crop,
                                        config.StoreMotionVectors);

            base.ConfigureOutputPort(outputPort, config, handler);

            if (this.Outputs[outputPort].EncodingType == MMALEncoding.H264)
            {
                this.ConfigureIntraPeriod(outputPort);

                this.ConfigureVideoProfile(outputPort);

                this.ConfigureInlineHeaderFlag(outputPort);

                this.ConfigureInlineVectorsFlag(outputPort);

                this.ConfigureIntraRefresh(outputPort);

                this.ConfigureQuantisationParameter(outputPort);
            }

            this.ConfigureImmutableInput(outputPort);

            return(this);
        }
Beispiel #5
0
        /// <summary>
        /// Initialises the camera's still port using the width, height and encoding as specified by the user.
        /// </summary>
        /// <param name="handler">The capture handler to associate with the still port.</param>
        private void InitialiseStill(IOutputCaptureHandler handler)
        {
            int currentWidth  = MMALCameraConfig.StillResolution.Width;
            int currentHeight = MMALCameraConfig.StillResolution.Height;

            if (currentWidth == 0 || currentWidth > this.CameraInfo.MaxWidth)
            {
                currentWidth = this.CameraInfo.MaxWidth;
            }

            if (currentHeight == 0 || currentHeight > this.CameraInfo.MaxHeight)
            {
                currentHeight = this.CameraInfo.MaxHeight;
            }

            MMALCameraConfig.StillResolution = new Resolution(currentWidth, currentHeight);

            MMALPortConfig portConfig = null;

            if (MMALCameraConfig.StillEncoding == MMALEncoding.RGB32 ||
                MMALCameraConfig.StillEncoding == MMALEncoding.RGB24 ||
                MMALCameraConfig.StillEncoding == MMALEncoding.RGB16)
            {
                MMALLog.Logger.LogWarning("Encoding set to RGB. Setting width padding to multiple of 16.");

                var resolution = MMALCameraConfig.StillResolution.Pad(16, 16);
                var encoding   = MMALCameraConfig.StillEncoding;

                try
                {
                    if (!this.StillPort.RgbOrderFixed())
                    {
                        MMALLog.Logger.LogWarning("Using old firmware. Setting encoding to BGR24");
                        encoding = MMALEncoding.BGR24;
                    }
                }
                catch
                {
                    MMALLog.Logger.LogWarning("Using old firmware. Setting encoding to BGR24");
                    encoding = MMALEncoding.BGR24;
                }

                portConfig = new MMALPortConfig(encoding, null, resolution.Width, resolution.Height,
                                                MMALCameraConfig.StillFramerate.Num, 0, 0, false, null,
                                                Math.Max(this.StillPort.BufferNumRecommended, 3),
                                                Math.Max(this.StillPort.BufferSizeRecommended, this.StillPort.BufferSizeMin),
                                                new Rectangle(0, 0, currentWidth, currentHeight));
            }
            else
            {
                var resolution = MMALCameraConfig.StillResolution.Pad();

                portConfig = new MMALPortConfig(MMALCameraConfig.StillEncoding, MMALCameraConfig.StillSubFormat, resolution.Width, resolution.Height,
                                                MMALCameraConfig.StillFramerate.Num, 0, 0, false, null,
                                                Math.Max(this.StillPort.BufferNumRecommended, 3),
                                                Math.Max(this.StillPort.BufferSizeRecommended, this.StillPort.BufferSizeMin),
                                                new Rectangle(0, 0, currentWidth, currentHeight));
            }

            MMALLog.Logger.LogDebug("Commit still");
            this.StillPort.Configure(portConfig, null, handler);

            // Use Raspistill values.
            if (MMALCameraConfig.ShutterSpeed > 6000000)
            {
                this.StillPort.SetFramerateRange(new MMAL_RATIONAL_T(50, 1000), new MMAL_RATIONAL_T(166, 1000));
            }
            else if (MMALCameraConfig.ShutterSpeed > 1000000)
            {
                this.StillPort.SetFramerateRange(new MMAL_RATIONAL_T(167, 1000), new MMAL_RATIONAL_T(999, 1000));
            }
        }
Beispiel #6
0
        /// <summary>
        /// Call to configure an output port.
        /// </summary>
        /// <param name="config">The port configuration object.</param>
        /// <param name="copyFrom">The port to copy from.</param>
        /// <param name="handler">The capture handler to assign to this port.</param>
        public virtual void Configure(IMMALPortConfig config, IInputPort copyFrom, IOutputCaptureHandler handler)
        {
            if (config != null)
            {
                this.PortConfig = config;

                copyFrom?.ShallowCopy(this);

                if (config.EncodingType != null)
                {
                    this.NativeEncodingType = config.EncodingType.EncodingVal;
                }

                if (config.PixelFormat != null)
                {
                    this.NativeEncodingSubformat = config.PixelFormat.EncodingVal;
                }

                this.Par = new MMAL_RATIONAL_T(1, 1);

                MMAL_VIDEO_FORMAT_T tempVid = this.Ptr->Format->Es->Video;

                try
                {
                    this.Commit();
                }
                catch
                {
                    // If commit fails using new settings, attempt to reset using old temp MMAL_VIDEO_FORMAT_T.
                    MMALLog.Logger.LogWarning($"{this.Name}: Commit of output port failed. Attempting to reset values.");
                    this.Ptr->Format->Es->Video = tempVid;
                    this.Commit();
                }

                if (config.ZeroCopy)
                {
                    this.ZeroCopy = true;
                    this.SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
                }

                if (MMALCameraConfig.VideoColorSpace != null &&
                    MMALCameraConfig.VideoColorSpace.EncType == MMALEncoding.EncodingType.ColorSpace)
                {
                    this.VideoColorSpace = MMALCameraConfig.VideoColorSpace;
                }

                if (config.Framerate > 0)
                {
                    this.FrameRate = config.Framerate;
                }

                if (config.Bitrate > 0)
                {
                    this.Bitrate = config.Bitrate;
                }

                this.EncodingType = config.EncodingType;
                this.PixelFormat  = config.PixelFormat;

                if (config.Width > 0 && config.Height > 0)
                {
                    if (config.Crop.HasValue)
                    {
                        this.Crop = config.Crop.Value;
                    }
                    else
                    {
                        this.Crop = new Rectangle(0, 0, config.Width, config.Height);
                    }

                    this.Resolution = new Resolution(config.Width, config.Height);
                }
                else
                {
                    // Use config or don't set depending on port type.
                    this.Resolution = new Resolution(0, 0);

                    // Certain resolution overrides set to global config Video/Still resolutions so check here if the width and height are greater than 0.
                    if (this.Resolution.Width > 0 && this.Resolution.Height > 0)
                    {
                        this.Crop = new Rectangle(0, 0, this.Resolution.Width, this.Resolution.Height);
                    }
                }

                this.BufferNum  = Math.Max(this.BufferNumMin, config.BufferNum > 0 ? config.BufferNum : this.BufferNumRecommended);
                this.BufferSize = Math.Max(this.BufferSizeMin, config.BufferSize > 0 ? config.BufferSize : this.BufferSizeRecommended);

                // It is important to re-commit changes to width and height.
                this.Commit();
            }

            this.CallbackHandler = new DefaultOutputPortCallbackHandler(this, handler);
        }
        /// <inheritdoc />
        public override void Configure(IMMALPortConfig config, IInputPort copyFrom, IOutputCaptureHandler handler)
        {
            base.Configure(config, copyFrom, handler);

            this.CallbackHandler = new FastImageOutputCallbackHandler(this, handler);
        }
Beispiel #8
0
        /// <inheritdoc />
        public override void Configure(MMALPortConfig config, IInputPort copyFrom, IOutputCaptureHandler handler)
        {
            // The splitter component should not have its resolution set on the output port so override method accordingly.
            if (config != null)
            {
                this.PortConfig = config;

                copyFrom?.ShallowCopy(this);

                if (config.EncodingType != null)
                {
                    this.NativeEncodingType = config.EncodingType.EncodingVal;
                }

                if (config.PixelFormat != null)
                {
                    this.NativeEncodingSubformat = config.PixelFormat.EncodingVal;
                }

                MMAL_VIDEO_FORMAT_T tempVid = this.Ptr->Format->Es->Video;

                try
                {
                    this.Commit();
                }
                catch
                {
                    // If commit fails using new settings, attempt to reset using old temp MMAL_VIDEO_FORMAT_T.
                    MMALLog.Logger.LogWarning("Commit of output port failed. Attempting to reset values.");
                    this.Ptr->Format->Es->Video = tempVid;
                    this.Commit();
                }

                if (config.ZeroCopy)
                {
                    this.ZeroCopy = true;
                    this.SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
                }

                if (MMALCameraConfig.VideoColorSpace != null &&
                    MMALCameraConfig.VideoColorSpace.EncType == MMALEncoding.EncodingType.ColorSpace)
                {
                    this.VideoColorSpace = MMALCameraConfig.VideoColorSpace;
                }

                if (config.Bitrate > 0)
                {
                    this.Bitrate = config.Bitrate;
                }

                this.EncodingType = config.EncodingType;
                this.PixelFormat  = config.PixelFormat;

                this.Commit();

                this.BufferNum  = Math.Max(this.BufferNumMin, config.BufferNum > 0 ? config.BufferNum : this.BufferNumRecommended);
                this.BufferSize = Math.Max(this.BufferSizeMin, config.BufferSize > 0 ? config.BufferSize : this.BufferSizeRecommended);
            }

            this.CallbackHandler = new VideoOutputCallbackHandler(this, (IVideoCaptureHandler)handler, null);
        }
Beispiel #9
0
        /// <inheritdoc />
        public override IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
        {
            this.Quality = config.Quality;

            if (config.EncodingType == MMALEncoding.H264)
            {
                config.BufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, this.Outputs[outputPort].Ptr->BufferSizeMin);
            }
            else
            {
                // Follow raspivid logic.
                config.BufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, 256 << 10);
            }

            // Force framerate to be 0 in case it was provided by user.
            config.Framerate = 0;

            this.ConfigureBitrate(outputPort, config);

            base.ConfigureOutputPort(outputPort, config, handler);

            if (this.Outputs[outputPort].EncodingType == MMALEncoding.H264)
            {
                this.ConfigureIntraPeriod(outputPort);

                this.ConfigureVideoProfile(outputPort);

                this.ConfigureInlineHeaderFlag(outputPort);

                this.ConfigureInlineVectorsFlag(outputPort);

                this.ConfigureIntraRefresh(outputPort);

                this.ConfigureQuantisationParameter(outputPort);
            }

            this.ConfigureImmutableInput(outputPort);

            return(this);
        }
Beispiel #10
0
 /// <inheritdoc />
 public void EnableAnalysis(IOutputCaptureHandler handler = null)
 {
     _parameters.AnalysisMode = true;
     _outputHandler           = handler;
 }