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"); } }); }
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); } }
/// <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; }
/// <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); } }
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()); } }
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); } }
/// <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); }
/// <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); } }
/// <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; }
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()); } }
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"); } } }); }
/// <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(); } } } }
/// <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); } } }
/// <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]); }
/// <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(); } } } }
/// <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; }
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); } }
/// <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; }