public void TakePictureRawBayer(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            AsyncContext.Run(async() =>
            {
                var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension);

                TestHelper.CleanDirectory("/home/pi/images/tests");

                using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler, true))
                {
                    imgEncoder.ConfigureOutputPort(0, encodingType, pixelFormat, 90);

                    //Create our component pipeline.
                    fixture.MMALCamera.Camera.StillPort
                    .ConnectTo(imgEncoder);
                    fixture.MMALCamera.Camera.PreviewPort
                    .ConnectTo(new MMALNullSinkComponent());

                    fixture.MMALCamera.ConfigureCameraSettings();

                    await fixture.MMALCamera.BeginProcessing(fixture.MMALCamera.Camera.StillPort, imgEncoder);
                }

                if (System.IO.File.Exists(imgCaptureHandler.GetFilepath()))
                {
                    var length = new System.IO.FileInfo(imgCaptureHandler.GetFilepath()).Length;
                    Assert.True(length > 0);
                }
                else
                {
                    Assert.True(false, $"File {imgCaptureHandler.GetFilepath()} was not created");
                }
            });
        }
Example #2
0
        public async Task TakeVideoWithCircularBuffer(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("TakeVideoWithCircularBuffer", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();
            TestHelper.CleanDirectory("/home/pi/videos/tests");

            using (var circularBufferHandler = new CircularBufferCaptureHandler(4096, "/home/pi/videos/tests", extension))
                using (var preview = new MMALVideoRenderer())
                    using (var vidEncoder = new MMALVideoEncoder())
                    {
                        Fixture.MMALCamera.ConfigureCameraSettings();

                        var portConfig = new MMALPortConfig(encodingType, pixelFormat, 10, 25000000, null, storeMotionVectors: true);

                        vidEncoder.ConfigureOutputPort(portConfig, circularBufferHandler);

                        // Create our component pipeline.
                        Fixture.MMALCamera.Camera.VideoPort
                        .ConnectTo(vidEncoder);
                        Fixture.MMALCamera.Camera.PreviewPort
                        .ConnectTo(preview);

                        // Camera warm up time
                        await Task.Delay(2000);

                        CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

                        // Record video for 10 seconds
                        await Fixture.MMALCamera.ProcessAsync(Fixture.MMALCamera.Camera.VideoPort, cts.Token);

                        // Check that the circular buffer has stored some data during the recording operation.
                        Assert.True(circularBufferHandler.Buffer.Size > 0);
                    }
        }
Example #3
0
 /// <summary>
 /// Create a new instance of <see cref="MMALPortConfig"/>.
 /// </summary>
 /// <param name="encodingType">The encoding type.</param>
 /// <param name="pixelFormat">The pixel format.</param>
 /// <param name="quality">The quality value. Can be used with JPEG encoding (value between 1-100). Can be used with H.264 encoding which affects the quantization parameter (typical values between 10-40, see wiki for info). Set both bitrate param and quality param to 0 for variable bitrate.</param>
 /// <param name="bitrate">The working bitrate, applies to Video Encoder only.</param>
 /// <param name="timeout">Video record timeout. This is useful if you have multiple video recording streams which you want to stop at different times.</param>
 /// <param name="split">Video split configuration object.</param>
 /// <param name="storeMotionVectors">Indicates whether to store motion vectors. Applies to H.264 video encoding.</param>
 /// <param name="width">The input/output width value.</param>
 /// <param name="height">The input/output height value.</param>
 /// <param name="framerate">Framerate value. Only useful when not using the camera component to specify input framerate.</param>
 /// <param name="zeroCopy">Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).</param>
 /// <param name="bufferNum">Requested number of buffer headers.</param>
 /// <param name="bufferSize">Requested size of buffer headers.</param>
 /// <param name="crop">The Region of Interest requested.</param>
 /// <param name="userPortName">User provided name for port. Helps with debugging..</param>
 public MMALPortConfig(
     MMALEncoding encodingType,
     MMALEncoding pixelFormat,
     int quality             = 0,
     int bitrate             = 0,
     DateTime?timeout        = null,
     Split split             = null,
     bool storeMotionVectors = false,
     int width           = 0,
     int height          = 0,
     double framerate    = 0,
     bool zeroCopy       = false,
     int bufferNum       = 0,
     int bufferSize      = 0,
     Rectangle?crop      = null,
     string userPortName = "")
 {
     this.EncodingType       = encodingType;
     this.PixelFormat        = pixelFormat;
     this.Width              = width;
     this.Height             = height;
     this.Framerate          = framerate;
     this.Quality            = quality;
     this.Bitrate            = bitrate;
     this.ZeroCopy           = zeroCopy;
     this.Timeout            = timeout;
     this.Split              = split;
     this.BufferNum          = bufferNum;
     this.BufferSize         = bufferSize;
     this.Crop               = crop;
     this.StoreMotionVectors = storeMotionVectors;
     this.UserPortName       = userPortName;
 }
Example #4
0
        /// <summary>
        /// Configures a specific input port on a downstream component. This method will perform a shallow copy of the output
        /// port it is to be connected to.
        /// </summary>
        /// <param name="encodingType">The encoding type the input port shall be expecting.</param>
        /// <param name="pixelFormat">The pixel format the input port shall be expecting.</param>
        /// <param name="copyPort">The output port we are copying format data from.</param>
        /// <param name="zeroCopy">Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).</param>
        /// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
        public virtual MMALDownstreamComponent ConfigureInputPort(MMALEncoding encodingType, MMALEncoding pixelFormat, PortBase copyPort, bool zeroCopy = false)
        {
            if (copyPort != null)
            {
                copyPort.ShallowCopy(this.Inputs[0]);
            }

            if (encodingType != null)
            {
                this.Inputs[0].NativeEncodingType = encodingType.EncodingVal;
            }

            if (pixelFormat != null)
            {
                this.Inputs[0].NativeEncodingSubformat = pixelFormat.EncodingVal;
            }

            this.Inputs[0].Commit();

            if (zeroCopy)
            {
                this.Inputs[0].ZeroCopy = true;
                this.Inputs[0].SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
            }

            return(this);
        }
        /// <summary>
        /// Self-contained method for capturing timelapse images.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420)</param>
        /// <param name="timelapse">A Timelapse object which specifies the timeout and rate at which images should be taken</param>
        /// <returns>The awaitable Task</returns>
        public async Task TakePictureTimelapse(ImageStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, Timelapse timelapse)
        {
            int interval = 0;

            if (timelapse == null)
            {
                throw new PiCameraError("Timelapse object null. This must be initialized for Timelapse mode");
            }

            while (DateTime.Now.CompareTo(timelapse.Timeout) < 0)
            {
                switch (timelapse.Mode)
                {
                case TimelapseMode.Millisecond:
                    interval = timelapse.Value;
                    break;

                case TimelapseMode.Second:
                    interval = timelapse.Value * 1000;
                    break;

                case TimelapseMode.Minute:
                    interval = (timelapse.Value * 60) * 1000;
                    break;
                }

                await Task.Delay(interval);

                await TakePicture(handler, encodingType, pixelFormat);
            }
        }
        public void TakeVideoSplit(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.SetConfigurationDefaults();

            MMALCameraConfig.InlineHeaders = true;

            AsyncContext.Run(async() =>
            {
                var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos/tests/split_test", extension);

                TestHelper.CleanDirectory("/home/pi/videos/tests/split_test");

                using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler, new MMAL_RATIONAL_T(25, 1),
                                                             DateTime.Now.AddSeconds(30), new Split {
                    Mode = TimelapseMode.Second, Value = 15
                }))
                {
                    vidEncoder.ConfigureOutputPort(0, encodingType, pixelFormat, 10, 25000000);

                    //Create our component pipeline.
                    fixture.MMALCamera.Camera.VideoPort
                    .ConnectTo(vidEncoder);
                    fixture.MMALCamera.Camera.PreviewPort
                    .ConnectTo(new MMALVideoRenderer());

                    fixture.MMALCamera.ConfigureCameraSettings();

                    //2 files should be created from this test.
                    await fixture.MMALCamera.BeginProcessing(fixture.MMALCamera.Camera.VideoPort, vidEncoder);

                    Assert.True(Directory.GetFiles("/home/pi/videos/tests/split_test").Length == 2);
                }
            });
        }
        /// <summary>
        /// Call to configure changes on an Image Encoder input port. Used when providing an image file directly
        /// to the component.
        /// </summary>
        /// <param name="encodingType">The encoding type the input port will expect data in.</param>
        /// <param name="pixelFormat">The pixel format the input port will expect data in.</param>
        /// <param name="width">The width of the incoming frame.</param>
        /// <param name="height">The height of the incoming frame.</param>
        /// <param name="zeroCopy">Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).</param>
        public virtual unsafe void ConfigureInputPort(MMALEncoding encodingType, MMALEncoding pixelFormat, int width, int height, bool zeroCopy = false)
        {
            this.InitialiseInputPort(0);

            if (encodingType != null)
            {
                this.Inputs[0].NativeEncodingType = encodingType.EncodingVal;
            }

            if (pixelFormat != null)
            {
                this.Inputs[0].NativeEncodingSubformat = pixelFormat.EncodingVal;
            }

            this.Inputs[0].BufferNum  = this.Inputs[0].Ptr->BufferNumMin;
            this.Inputs[0].BufferSize = this.Inputs[0].Ptr->BufferSizeMin;

            this.Inputs[0].EncodingType = encodingType;

            this.Inputs[0].Commit();

            if (this.Outputs.Count > 0 && this.Outputs[0].Ptr->Format->Type == MMALFormat.MMAL_ES_TYPE_T.MMAL_ES_TYPE_UNKNOWN)
            {
                throw new PiCameraError("Unable to determine settings for output port.");
            }

            if (zeroCopy)
            {
                this.Inputs[0].ZeroCopy = true;
                this.Inputs[0].SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
            }
        }
Example #8
0
        private void TakePictureOperations(MMALEncoding encoding, MMALEncoding pixelFormat)
        {
            Console.WriteLine("\nPlease enter a file extension.");
            var extension = Console.ReadLine();

            this.TakePictureManual(extension, encoding, pixelFormat).GetAwaiter().GetResult();
        }
        public async Task EdgeDetectionKernelProcessor(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("EdgeDetectionKernelProcessor", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();
            TestHelper.CleanDirectory("/home/pi/images/tests");

            using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension))
                using (var preview = new MMALNullSinkComponent())
                    using (var imgEncoder = new MMALImageEncoder())
                    {
                        Fixture.MMALCamera.ConfigureCameraSettings();

                        var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90);

                        imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);

                        // Create our component pipeline.
                        Fixture.MMALCamera.Camera.StillPort
                        .ConnectTo(imgEncoder);
                        Fixture.MMALCamera.Camera.PreviewPort
                        .ConnectTo(preview);

                        imgCaptureHandler.Manipulate(context =>
                        {
                            context.Apply(new EdgeDetection(EDStrength.High));
                        }, ImageFormat.Jpeg);

                        // Camera warm up time
                        await Task.Delay(2000);

                        await Fixture.MMALCamera.ProcessAsync(Fixture.MMALCamera.Camera.StillPort);

                        Fixture.CheckAndAssertFilepath(imgCaptureHandler.GetFilepath());
                    }
        }
Example #10
0
        public async Task TakePicturesFromVideoPort(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("TakePicturesFromVideoPort", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();
            TestHelper.CleanDirectory("/home/pi/images/tests");

            using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension))
                using (var splitter = new MMALSplitterComponent())
                    using (var preview = new MMALNullSinkComponent())
                        using (var imgEncoder = new MMALImageEncoder(continuousCapture: true))
                        {
                            Fixture.MMALCamera.ConfigureCameraSettings();

                            var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90);

                            imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);

                            // Create our component pipeline.
                            Fixture.MMALCamera.Camera.VideoPort
                            .ConnectTo(splitter);
                            splitter.Outputs[0].ConnectTo(imgEncoder);
                            Fixture.MMALCamera.Camera.PreviewPort
                            .ConnectTo(preview);

                            // Camera warm up time
                            await Task.Delay(2000);

                            var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

                            await Fixture.MMALCamera.ProcessAsync(Fixture.MMALCamera.Camera.VideoPort, cts.Token);

                            Fixture.CheckAndAssertDirectory(imgCaptureHandler.Directory);
                        }
        }
Example #11
0
        /// <summary>
        /// Call to configure changes on a Downstream video output port.
        /// </summary>
        /// <param name="outputPort">The output port we are configuring</param>
        /// <param name="encodingType">The encoding type this output port will send data in</param>
        /// <param name="pixelFormat">The pixel format this output port will send data in</param>
        /// <param name="quality">Quantisation parameter - quality. When using this setting, set bitrate 0 and set this for variable bitrate</param>
        /// <param name="bitrate">The bitrate we are sending data at</param>
        public override void ConfigureOutputPort(int outputPort, MMALEncoding encodingType, MMALEncoding pixelFormat, int quality, int bitrate = 0)
        {
            base.ConfigureOutputPort(outputPort, encodingType, pixelFormat, quality, bitrate);

            ((MMALVideoPort)this.Outputs[outputPort]).Timeout = this.Timeout;
            this.Outputs[outputPort].Ptr->BufferSize          = 512 * 1024;
            this.Quality = quality;
            this.Bitrate = bitrate;

            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);
            this.ConfigureBitrate(outputPort);
        }
Example #12
0
        /// <summary>
        /// Self-contained method for capturing a single image from the camera still port.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component.</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param>
        /// <returns>The awaitable Task.</returns>
        public async Task TakePicture(ICaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            using (var imgEncoder = new MMALImageEncoder(handler))
                using (var renderer = new MMALNullSinkComponent())
                {
                    this.ConfigureCameraSettings();

                    var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90);

                    imgEncoder.ConfigureOutputPort(portConfig);

                    // Create our component pipeline.
                    this.Camera.StillPort.ConnectTo(imgEncoder);
                    this.Camera.PreviewPort.ConnectTo(renderer);

                    // Enable the image encoder output port.
                    MMALLog.Logger.Info($"Preparing to take picture. Resolution: {this.Camera.StillPort.Resolution.Width} x {this.Camera.StillPort.Resolution.Height}. " +
                                        $"Encoder: {encodingType.EncodingName}. Pixel Format: {pixelFormat.EncodingName}.");

                    // Camera warm up time
                    await Task.Delay(2000).ConfigureAwait(false);

                    await this.ProcessAsync(this.Camera.StillPort).ConfigureAwait(false);
                }
        }
        public async Task TakePictureRawBayer(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("TakePictureRawBayer", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();
            TestHelper.CleanDirectory("/home/pi/images/tests");

            using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension))
                using (var preview = new MMALNullSinkComponent())
                    using (var imgEncoder = new MMALImageEncoder(true))
                    {
                        Fixture.MMALCamera.ConfigureCameraSettings();

                        var portConfig = new MMALPortConfig(encodingType, pixelFormat, quality: 90);

                        imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);

                        // Create our component pipeline.
                        Fixture.MMALCamera.Camera.StillPort
                        .ConnectTo(imgEncoder);
                        Fixture.MMALCamera.Camera.PreviewPort
                        .ConnectTo(preview);

                        // Camera warm up time
                        await Task.Delay(2000);

                        await Fixture.MMALCamera.ProcessAsync(Fixture.MMALCamera.Camera.StillPort);

                        Fixture.CheckAndAssertFilepath(imgCaptureHandler.GetFilepath());
                    }
        }
        /// <summary>
        /// Configures a specific input port on a downstream component. This method will perform a shallow copy of the output
        /// port it is to be connected to.
        /// </summary>
        /// <param name="encodingType">The encoding type the input port shall be expecting.</param>
        /// <param name="pixelFormat">The pixel format the input port shall be expecting.</param>
        /// <param name="copyPort">The output port we are copying format data from.</param>
        /// <param name="zeroCopy">Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).</param>
        public virtual void ConfigureInputPort(MMALEncoding encodingType, MMALEncoding pixelFormat, MMALPortImpl copyPort, bool zeroCopy = false)
        {
            this.InitialiseInputPort(0);

            if (copyPort != null)
            {
                copyPort.ShallowCopy(this.Inputs[0]);
            }

            if (encodingType != null)
            {
                this.Inputs[0].NativeEncodingType = encodingType.EncodingVal;
            }

            if (pixelFormat != null)
            {
                this.Inputs[0].NativeEncodingSubformat = pixelFormat.EncodingVal;
            }

            this.Inputs[0].Commit();

            if (zeroCopy)
            {
                this.Inputs[0].ZeroCopy = true;
                this.Inputs[0].SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
            }
        }
Example #15
0
        /// <summary>
        /// Call to configure changes on an Image Encoder input port. Used when providing an image file directly
        /// to the component.
        /// </summary>
        /// <param name="encodingType">The encoding type the input port will expect data in</param>
        /// <param name="width">The width of the incoming frame</param>
        /// <param name="height">The height of the incoming frame</param>
        public virtual unsafe void ConfigureInputPort(MMALEncoding encodingType, int width, int height)
        {
            this.InitialiseInputPort(0);

            if (encodingType != null)
            {
                this.Inputs[0].Ptr->Format->encoding = encodingType.EncodingVal;
            }

            this.Inputs[0].Ptr->Format->es->video.height = MMALUtil.VCOS_ALIGN_UP(height, 32);
            this.Inputs[0].Ptr->Format->es->video.width  = MMALUtil.VCOS_ALIGN_UP(width, 32);
            this.Inputs[0].Ptr->Format->es->video.crop   = new MMAL_RECT_T(0, 0, width, height);

            this.Inputs[0].Commit();

            if (this.Outputs[0].Ptr->Format->type == MMALFormat.MMAL_ES_TYPE_T.MMAL_ES_TYPE_UNKNOWN)
            {
                throw new PiCameraError("Unable to determine settings for output port.");
            }

            this.Inputs[0].Ptr->BufferNum  = Math.Max(this.Inputs[0].Ptr->BufferNumRecommended, this.Inputs[0].Ptr->BufferNumMin);
            this.Inputs[0].Ptr->BufferSize = Math.Max(this.Inputs[0].Ptr->BufferSizeRecommended, this.Inputs[0].Ptr->BufferSizeMin);

            this.Inputs[0].EncodingType = encodingType;
        }
Example #16
0
        public async Task TakeVideo(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("TakeVideo", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();
            TestHelper.CleanDirectory("/home/pi/videos/tests");

            using (var vidCaptureHandler = new VideoStreamCaptureHandler("/home/pi/videos/tests", extension))
                using (var preview = new MMALVideoRenderer())
                    using (var vidEncoder = new MMALVideoEncoder(vidCaptureHandler))
                    {
                        Fixture.MMALCamera.ConfigureCameraSettings();

                        var portConfig = new MMALPortConfig(encodingType, pixelFormat, 25, 10, 25000000, null);

                        vidEncoder.ConfigureOutputPort(portConfig);

                        // Create our component pipeline.
                        Fixture.MMALCamera.Camera.VideoPort
                        .ConnectTo(vidEncoder);
                        Fixture.MMALCamera.Camera.PreviewPort
                        .ConnectTo(preview);

                        // Camera warm up time
                        await Task.Delay(2000);

                        CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(15));

                        // Record video for 20 seconds
                        await Fixture.MMALCamera.ProcessAsync(Fixture.MMALCamera.Camera.VideoPort, cts.Token);

                        Fixture.CheckAndAssertFilepath(vidCaptureHandler.GetFilepath());
                    }
        }
Example #17
0
        private async Task ResizePicture(string extension, MMALEncoding encoding, MMALEncoding pixelFormat, int width, int height)
        {
            using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", extension))
                using (var resizer = new MMALResizerComponent())
                    using (var imgEncoder = new MMALImageEncoder())
                        using (var nullSink = new MMALNullSinkComponent())
                        {
                            this.Cam.ConfigureCameraSettings();

                            await Task.Delay(2000);

                            var resizerConfig = new MMALPortConfig(pixelFormat, pixelFormat, width: width, height: height);
                            var encoderConfig = new MMALPortConfig(encoding, pixelFormat, quality: 90);

                            // Create our component pipeline.
                            resizer.ConfigureInputPort(new MMALPortConfig(MMALCameraConfig.Encoding, MMALCameraConfig.EncodingSubFormat), this.Cam.Camera.StillPort, null);
                            resizer.ConfigureOutputPort(resizerConfig, null);
                            imgEncoder.ConfigureOutputPort(encoderConfig, imgCaptureHandler);

                            this.Cam.Camera.StillPort.ConnectTo(resizer);
                            resizer.Outputs[0].ConnectTo(imgEncoder);
                            this.Cam.Camera.PreviewPort.ConnectTo(nullSink);

                            await this.Cam.ProcessAsync(this.Cam.Camera.StillPort);
                        }
        }
        public void TakePictureTimeout(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            AsyncContext.Run(async() =>
            {
                var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests/split_tests", extension);

                TestHelper.CleanDirectory("/home/pi/images/tests/split_tests");

                using (var imgEncoder = new MMALImageEncoder(imgCaptureHandler))
                {
                    fixture.MMALCamera.ConfigureCameraSettings();

                    imgEncoder.ConfigureOutputPort(0, encodingType, pixelFormat, 90);

                    //Create our component pipeline.
                    fixture.MMALCamera.Camera.StillPort
                    .ConnectTo(imgEncoder);
                    fixture.MMALCamera.Camera.PreviewPort
                    .ConnectTo(new MMALNullSinkComponent());

                    var timeout = DateTime.Now.AddSeconds(30);

                    //Camera warm up time
                    await Task.Delay(2000);

                    while (DateTime.Now.CompareTo(timeout) < 0)
                    {
                        await fixture.MMALCamera.BeginProcessing(fixture.MMALCamera.Camera.StillPort);
                    }
                }
            });
        }
        public void TakePictureRawSensor(string extension, MMALEncoding encodingType, MMALEncoding pixelFormat)
        {
            TestHelper.BeginTest("TakePictureRawSensor", encodingType.EncodingName, pixelFormat.EncodingName);
            TestHelper.SetConfigurationDefaults();

            AsyncContext.Run(async() =>
            {
                using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/tests", extension))
                {
                    TestHelper.CleanDirectory("/home/pi/images/tests");

                    await _fixture.MMALCamera.TakeRawPicture(imgCaptureHandler);

                    var encodings = _fixture.MMALCamera.Camera.StillPort.GetSupportedEncodings();

                    if (System.IO.File.Exists(imgCaptureHandler.GetFilepath()))
                    {
                        var length = new System.IO.FileInfo(imgCaptureHandler.GetFilepath()).Length;

                        if (encodings.Contains(encodingType.EncodingVal))
                        {
                            Assert.True(length > 1);
                        }
                    }
                    else
                    {
                        Assert.True(false, $"File {imgCaptureHandler.GetFilepath()} was not created");
                    }
                }
            });
        }
Example #20
0
        /// <summary>
        /// Self-contained method for capturing a continual images from the camera still port for a specified period of time.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component.</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param>
        /// <param name="cancellationToken">A cancellationToken to trigger stop capturing.</param>
        /// <param name="burstMode">When enabled, burst mode will increase the rate at which images are taken, at the expense of quality.</param>
        /// <returns>The awaitable Task.</returns>
        public async Task TakePictureTimeout(IFileStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, CancellationToken cancellationToken, bool burstMode = false)
        {
            if (burstMode)
            {
                MMALCameraConfig.StillBurstMode = true;
            }

            using (var imgEncoder = new MMALImageEncoder())
                using (var renderer = new MMALNullSinkComponent())
                {
                    this.ConfigureCameraSettings();

                    var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90);

                    imgEncoder.ConfigureOutputPort(portConfig, handler);

                    // Create our component pipeline.
                    this.Camera.StillPort.ConnectTo(imgEncoder);
                    this.Camera.PreviewPort.ConnectTo(renderer);

                    // Camera warm up time
                    await Task.Delay(2000).ConfigureAwait(false);

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        await this.ProcessAsync(this.Camera.StillPort).ConfigureAwait(false);

                        if (!cancellationToken.IsCancellationRequested)
                        {
                            handler.NewFile();
                        }
                    }
                }
        }
Example #21
0
        /// <summary>
        /// Self-contained method for capturing a continual images from the camera still port for a specified period of time.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component.</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param>
        /// <param name="cancellationToken">A cancellationToken to trigger stop capturing.</param>
        /// <param name="burstMode">When enabled, burst mode will increase the rate at which images are taken, at the expense of quality.</param>
        /// <returns>The awaitable Task.</returns>
        public async Task TakePictureTimeout(ImageStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, CancellationToken cancellationToken, bool burstMode = false)
        {
            if (burstMode)
            {
                this.Camera.StillPort.SetParameter(MMALParametersCamera.MMAL_PARAMETER_CAMERA_BURST_CAPTURE, true);
            }

            using (var imgEncoder = new MMALImageEncoder(handler))
                using (var renderer = new MMALNullSinkComponent())
                {
                    this.ConfigureCameraSettings();

                    imgEncoder.ConfigureOutputPort(encodingType, pixelFormat, 90);

                    // Create our component pipeline.
                    this.Camera.StillPort.ConnectTo(imgEncoder);
                    this.Camera.PreviewPort.ConnectTo(renderer);

                    // Camera warm up time
                    await Task.Delay(2000);

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        await this.ProcessAsync(this.Camera.StillPort);
                    }
                }
        }
Example #22
0
 /// <summary>
 /// Create a new instance of <see cref="MMALPortConfig"/> with parameters useful for video capture.
 /// </summary>
 /// <param name="encodingType">The encoding type.</param>
 /// <param name="pixelFormat">The pixel format.</param>
 /// <param name="quality">The output quality. Affects the quantization parameter for H.264 encoding. Set bitrate 0 and set this for variable bitrate.</param>
 /// <param name="bitrate">The output bitrate.</param>
 /// <param name="timeout">Video record timeout. This is useful if you have multiple video recording streams which you want to stop at different times.</param>
 public MMALPortConfig(MMALEncoding encodingType, MMALEncoding pixelFormat, int quality, int bitrate, DateTime?timeout)
 {
     this.EncodingType = encodingType;
     this.PixelFormat  = pixelFormat;
     this.Quality      = quality;
     this.Bitrate      = bitrate;
     this.Timeout      = timeout;
 }
        /// <inheritdoc />
        public override unsafe MMALDownstreamComponent ConfigureInputPort(MMALEncoding encodingType, MMALEncoding pixelFormat, PortBase copyPort, bool zeroCopy = false)
        {
            base.ConfigureInputPort(encodingType, pixelFormat, copyPort, zeroCopy);

            this.Inputs[0].Ptr->BufferNum = Math.Max(this.Inputs[0].Ptr->BufferNumRecommended, 3);

            return(this);
        }
        internal static void CheckSupportedEncoding(this MMALPortImpl port, MMALEncoding encoding)
        {
            var encodings = port.GetSupportedEncodings();

            if (!encodings.Any(c => c == encoding.EncodingVal))
            {
                throw new PiCameraError("Unsupported encoding type for this port");
            }
        }
        /// <summary>
        /// Call to configure changes on an Downstream component output port.
        /// </summary>
        /// <param name="outputPort">The output port we are configuring.</param>
        /// <param name="encodingType">The encoding type this output port will send data in.</param>
        /// <param name="pixelFormat">The pixel format this output port will send data in.</param>
        /// <param name="quality">The quality of our outputted data.</param>
        /// <param name="bitrate">The bitrate we are sending data at.</param>
        /// <param name="zeroCopy">Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).</param>
        public virtual unsafe void ConfigureOutputPort(int outputPort, MMALEncoding encodingType, MMALEncoding pixelFormat, int quality, int bitrate = 0, bool zeroCopy = false)
        {
            this.InitialiseOutputPort(outputPort);
            this.ProcessingPorts.Add(outputPort);

            this.Inputs[0].ShallowCopy(this.Outputs[outputPort]);

            if (encodingType != null)
            {
                this.Outputs[outputPort].NativeEncodingType = encodingType.EncodingVal;
            }

            if (pixelFormat != null)
            {
                this.Outputs[outputPort].NativeEncodingSubformat = pixelFormat.EncodingVal;
            }

            MMAL_VIDEO_FORMAT_T tempVid = this.Outputs[outputPort].Ptr->Format->Es->Video;

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

            if (encodingType == MMALEncoding.JPEG)
            {
                this.Outputs[outputPort].SetParameter(MMALParametersCamera.MMAL_PARAMETER_JPEG_Q_FACTOR, quality);
            }

            if (zeroCopy)
            {
                this.Outputs[outputPort].ZeroCopy = true;
                this.Outputs[outputPort].SetParameter(MMALParametersCommon.MMAL_PARAMETER_ZERO_COPY, true);
            }

            this.Outputs[outputPort].EncodingType = encodingType;
            this.Outputs[outputPort].PixelFormat  = pixelFormat;

            this.Outputs[outputPort].Resolution = new Resolution(this.Width, this.Height).Pad();
            this.Outputs[outputPort].Crop       = new Rectangle(0, 0, this.Width, this.Height);

            // It is important to re-commit changes to width and height.
            this.Outputs[outputPort].Commit();

            this.Outputs[outputPort].BufferNum  = Math.Max(this.Outputs[outputPort].Ptr->BufferNumRecommended, this.Outputs[outputPort].Ptr->BufferNumMin);
            this.Outputs[outputPort].BufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, this.Outputs[outputPort].Ptr->BufferSizeMin);

            this.Outputs[outputPort].ManagedOutputCallback = OutputCallbackProvider.FindCallback(this.Outputs[outputPort]);
        }
Example #26
0
        /// <summary>
        /// Self-contained method for capturing timelapse images.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component.</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP.</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420).</param>
        /// <param name="timelapse">A Timelapse object which specifies the timeout and rate at which images should be taken.</param>
        /// <returns>The awaitable Task.</returns>
        /// <exception cref="ArgumentNullException"/>
        public async Task TakePictureTimelapse(IFileStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, Timelapse timelapse)
        {
            int interval = 0;

            if (timelapse == null)
            {
                throw new ArgumentNullException(nameof(timelapse), "Timelapse object null. This must be initialized for Timelapse mode");
            }

            using (var imgEncoder = new MMALImageEncoder())
                using (var renderer = new MMALNullSinkComponent())
                {
                    this.ConfigureCameraSettings();

                    var portConfig = new MMALPortConfig(encodingType, pixelFormat, 90);

                    imgEncoder.ConfigureOutputPort(portConfig, handler);

                    // Create our component pipeline.
                    this.Camera.StillPort.ConnectTo(imgEncoder);
                    this.Camera.PreviewPort.ConnectTo(renderer);

                    // Camera warm up time
                    await Task.Delay(2000).ConfigureAwait(false);

                    while (!timelapse.CancellationToken.IsCancellationRequested)
                    {
                        switch (timelapse.Mode)
                        {
                        case TimelapseMode.Millisecond:
                            interval = timelapse.Value;
                            break;

                        case TimelapseMode.Second:
                            interval = timelapse.Value * 1000;
                            break;

                        case TimelapseMode.Minute:
                            interval = (timelapse.Value * 60) * 1000;
                            break;
                        }

                        await Task.Delay(interval).ConfigureAwait(false);

                        MMALLog.Logger.LogInformation($"Preparing to take picture. Resolution: {MMALCameraConfig.StillResolution.Width} x {MMALCameraConfig.StillResolution.Height}. " +
                                                      $"Encoder: {encodingType.EncodingName}. Pixel Format: {pixelFormat.EncodingName}.");

                        await this.ProcessAsync(this.Camera.StillPort).ConfigureAwait(false);

                        if (!timelapse.CancellationToken.IsCancellationRequested)
                        {
                            handler.NewFile();
                        }
                    }
                }
        }
Example #27
0
 /// <summary>
 /// Create a new instance of <see cref="MMALPortConfig"/> with parameters useful for video capture.
 /// </summary>
 /// <param name="encodingType">The encoding type.</param>
 /// <param name="pixelFormat">The pixel format.</param>
 /// <param name="quality">The output quality. Affects the quantization parameter for H.264 encoding. Set bitrate 0 and set this for variable bitrate.</param>
 /// <param name="bitrate">The output bitrate.</param>
 /// <param name="timeout">Video record timeout. This is useful if you have multiple video recording streams which you want to stop at different times.</param>
 /// <param name="split">Video split configuration object.</param>
 /// <param name="storeMotionVectors">Indicates whether to store motion vectors. Applies to H.264 video encoding.</param>
 public MMALPortConfig(MMALEncoding encodingType, MMALEncoding pixelFormat, int quality, int bitrate, DateTime?timeout, Split split = null, bool storeMotionVectors = false)
 {
     this.EncodingType       = encodingType;
     this.PixelFormat        = pixelFormat;
     this.Quality            = quality;
     this.Bitrate            = bitrate;
     this.Timeout            = timeout;
     this.Split              = split;
     this.StoreMotionVectors = storeMotionVectors;
 }
Example #28
0
        private static object[] GetEncoderData(MMALEncoding encodingType, MMALEncoding pixelFormat, string extension)
        {
            var supportedEncodings = Fixture.MMALCamera.Camera.StillPort.GetSupportedEncodings();

            if (!supportedEncodings.Contains(pixelFormat.EncodingVal))
            {
                throw new ArgumentException("Unsupported pixel format requested.");
            }

            return(new object[] { extension, encodingType, pixelFormat });
        }
        /// <summary>
        /// Self-contained method for capturing a continual images from the camera still port for a specified period of time.
        /// An MMALImageEncoder component will be created and attached to the still port.
        /// </summary>
        /// <param name="handler">The image capture handler to apply to the encoder component</param>
        /// <param name="encodingType">The image encoding type e.g. JPEG, BMP</param>
        /// <param name="pixelFormat">The pixel format to use with the encoder e.g. I420 (YUV420)</param>
        /// <param name="timeout">The DateTime which capturing should stop</param>
        /// <param name="burstMode">When enabled, burst mode will increase the rate at which images are taken, at the expense of quality</param>
        /// <returns>The awaitable Task</returns>
        public async Task TakePictureTimeout(ImageStreamCaptureHandler handler, MMALEncoding encodingType, MMALEncoding pixelFormat, DateTime timeout, bool burstMode = false)
        {
            if (burstMode)
            {
                this.Camera.StillPort.SetParameter(MMALParametersCamera.MMAL_PARAMETER_CAMERA_BURST_CAPTURE, true);
            }

            while (DateTime.Now.CompareTo(timeout) < 0)
            {
                await TakePicture(handler, encodingType, pixelFormat);
            }
        }
Example #30
0
 /// <summary>
 /// Create a new instance of <see cref="MMALPortConfig"/> with parameters useful for standalone image/video processing.
 /// </summary>
 /// <param name="encodingType">The encoding type.</param>
 /// <param name="pixelFormat">The pixel format.</param>
 /// <param name="width">The output width.</param>
 /// <param name="height">The output height.</param>
 /// <param name="framerate">The output framerate.</param>
 /// <param name="quality">The output quality.</param>
 /// <param name="bitrate">The output bitrate.</param>
 /// <param name="zeroCopy">Specify zero copy.</param>
 /// <param name="timeout">Video record timeout.</param>
 public MMALPortConfig(MMALEncoding encodingType, MMALEncoding pixelFormat, int width, int height, int framerate,
                       int quality, int bitrate, bool zeroCopy, DateTime?timeout)
 {
     this.EncodingType = encodingType;
     this.PixelFormat  = pixelFormat;
     this.Width        = width;
     this.Height       = height;
     this.Framerate    = framerate;
     this.Quality      = quality;
     this.Bitrate      = bitrate;
     this.ZeroCopy     = zeroCopy;
     this.Timeout      = timeout;
 }