/// <summary> /// Force capture to stop on a port (Still or Video). /// </summary> /// <param name="port">The capture port.</param> public void ForceStop(MMALPortImpl port) { if (port.Trigger.CurrentCount > 0) { port.Trigger.Signal(); } }
internal static unsafe void SetStereoMode(this MMALPortImpl port, StereoMode mode) { MMAL_PARAMETER_STEREOSCOPIC_MODE_T stereo = new MMAL_PARAMETER_STEREOSCOPIC_MODE_T(new MMAL_PARAMETER_HEADER_T(MMALParametersCamera.MMAL_PARAMETER_STEREOSCOPIC_MODE, Marshal.SizeOf <MMAL_PARAMETER_STEREOSCOPIC_MODE_T>()), mode.Mode, mode.Decimate, mode.SwapEyes); MMALCheck(MMALPort.mmal_port_parameter_set(port.Ptr, &stereo.hdr), "Unable to set Stereo mode"); }
/// <summary> /// Stop capture on one of the camera's output ports. /// </summary> /// <param name="port">An output port of the camera component.</param> public void StopCapture(MMALPortImpl port) { if (port == this.Camera.StillPort || port == this.Camera.VideoPort) { port.SetImageCapture(false); } }
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"); } }
internal static unsafe int[] GetSupportedEncodings(this MMALPortImpl port) { MMAL_PARAMETER_ENCODING_T encodings = new MMAL_PARAMETER_ENCODING_T( new MMAL_PARAMETER_HEADER_T(MMALParametersCommon.MMAL_PARAMETER_SUPPORTED_ENCODINGS, Marshal.SizeOf <MMAL_PARAMETER_ENCODING_T>()), new[] { 0 }); MMALCheck(MMALPort.mmal_port_parameter_get(port.Ptr, &encodings.hdr), "Unable to get supported encodings"); return(encodings.Value); }
/// <summary> /// Helper method to begin processing image data. Starts the Camera port and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="cameraPort">The camera port which image data is coming from</param> /// <param name="handlerComponents">The handler component(s) we are processing data on</param> /// <returns>The awaitable Task</returns> public async Task BeginProcessing(MMALPortImpl cameraPort, params MMALDownstreamHandlerComponent[] handlerComponents) { //Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); foreach (var portNum in component.ProcessingPorts) { component.Start(portNum, new Action <MMALBufferImpl, MMALPortBase>(component.ManagedOutputCallback)); component.Outputs[portNum].Trigger = new Nito.AsyncEx.AsyncCountdownEvent(1); } } //We now begin capturing on the camera, processing will commence based on the pipeline configured. this.StartCapture(cameraPort); List <Task> tasks = new List <Task>(); //Wait until the process is complete. foreach (var component in handlerComponents) { foreach (var portNum in component.ProcessingPorts) { tasks.Add(component.Outputs[portNum].Trigger.WaitAsync()); } } await Task.WhenAll(tasks.ToArray()); this.StopCapture(cameraPort); //If taking raw image, the camera component will hold the handler this.Camera.Handler?.PostProcess(); //Disable the image encoder output port. foreach (var component in handlerComponents) { //Apply any final processing on each component component.Handler?.PostProcess(); foreach (var portNum in component.ProcessingPorts) { component.Stop(portNum); } //Close open connections. component.DisableConnections(); component.CleanPortPools(); } }
internal static bool RgbOrderFixed(this MMALPortImpl port) { int newFirmware = 0; var encodings = port.GetSupportedEncodings(); foreach (int enc in encodings) { if (enc == MMALUtil.MMAL_FOURCC("BGR3")) { break; } if (enc == MMALUtil.MMAL_FOURCC("RGB3")) { newFirmware = 1; } } return(newFirmware == 1); }
/// <summary> /// Retrieves an array of FourCC integer codes that this port is compatible with. /// </summary> /// <param name="port">The port we are getting supported encodings for.</param> /// <returns>An array of FourCC integers.</returns> public static unsafe int[] GetSupportedEncodings(this MMALPortImpl port) { IntPtr ptr1 = Marshal.AllocHGlobal(Marshal.SizeOf <MMAL_PARAMETER_ENCODING_T>() + 20); var str1 = (MMAL_PARAMETER_HEADER_T *)ptr1; str1->Id = MMALParametersCommon.MMAL_PARAMETER_SUPPORTED_ENCODINGS; // Deliberately undersize to check if running on older firmware. str1->Size = Marshal.SizeOf <MMAL_PARAMETER_ENCODING_T>() + 20; MMAL_PARAMETER_ENCODING_T encodings; try { MMALCheck(MMALPort.mmal_port_parameter_get(port.Ptr, str1), "Unable to get supported encodings"); encodings = (MMAL_PARAMETER_ENCODING_T)Marshal.PtrToStructure(ptr1, typeof(MMAL_PARAMETER_ENCODING_T)); return(encodings.Value); } finally { Marshal.FreeHGlobal(ptr1); } }
internal static void SetRawCapture(this MMALPortImpl port, bool raw) { port.SetParameter(MMAL_PARAMETER_ENABLE_RAW_CAPTURE, raw); }
public static bool GetRawCapture(this MMALPortImpl port) { return(port.GetParameter(MMAL_PARAMETER_ENABLE_RAW_CAPTURE)); }
internal static void SetImageCapture(this MMALPortImpl port, bool enable) { port.SetParameter(MMAL_PARAMETER_CAPTURE, enable); }
/// <summary> /// Helper method to begin processing image data. Starts the Camera port and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="cameraPort">The camera port which image data is coming from.</param> /// <param name="cancellationToken">A CancellationToken to observe while waiting for a task to complete.</param> /// <returns>The awaitable Task.</returns> public async Task ProcessAsync(MMALPortImpl cameraPort, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(); List <Task> tasks = new List <Task>(); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); foreach (var portNum in component.ProcessingPorts) { if (component.Outputs[portNum].ConnectedReference == null) { component.Start(portNum); component.Outputs[portNum].Trigger = new Nito.AsyncEx.AsyncCountdownEvent(1); tasks.Add(component.Outputs[portNum].Trigger.WaitAsync()); } } } // We now begin capturing on the camera, processing will commence based on the pipeline configured. this.StartCapture(cameraPort); if (cancellationToken == CancellationToken.None) { await Task.WhenAll(tasks); } else { await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks); } // If taking raw image, the camera component will hold the handler this.Camera.Handler?.PostProcess(); // Disable the image encoder output port. foreach (var component in handlerComponents) { // Apply any final processing on each component component.Handler?.PostProcess(); foreach (var portNum in component.ProcessingPorts) { await Task.Delay(100); if (component.Outputs[portNum].ConnectedReference == null) { component.Stop(portNum); } } component.CleanPortPools(); component.DisableConnections(); } this.StopCapture(cameraPort); }