private void FindComponents(IDownstreamComponent downstream, List <IDownstreamComponent> list) { if (downstream.Outputs.Count == 0) { return; } if (downstream.Outputs.Count == 1 && downstream.Outputs[0].ConnectedReference == null) { list.Add(downstream); return; } var checkDownstream = downstream as IDownstreamHandlerComponent; if (checkDownstream != null) { list.Add((IDownstreamHandlerComponent)downstream); } foreach (var output in downstream.Outputs) { if (output.ConnectedReference != null) { this.FindComponents(output.ConnectedReference.DownstreamComponent, list); } } }
private void FindComponents(IDownstreamComponent downstream, List <IDownstreamComponent> list) { if (downstream.Outputs.Count == 0) { return; } if (downstream.Outputs.Count == 1 && downstream.Outputs[0].ConnectedReference == null) { list.Add(downstream); return; } if (downstream.GetType().BaseType == typeof(MMALDownstreamHandlerComponent)) { list.Add((MMALDownstreamHandlerComponent)downstream); } foreach (var output in downstream.Outputs) { if (output.ConnectedReference != null) { this.FindComponents(output.ConnectedReference.DownstreamComponent, list); } } }
/// <summary> /// Prints the currently configured component pipeline to the console window. /// </summary> /// <param name="initialComponent">The first component in your pipeline.</param> public void PrintPipeline(IDownstreamComponent initialComponent) { MMALLog.Logger.LogInformation("Current pipeline:"); MMALLog.Logger.LogInformation(string.Empty); foreach (var component in this.PopulateProcessingList(initialComponent)) { component.PrintComponent(); } }
private List <IDownstreamComponent> PopulateProcessingList(IDownstreamComponent initialComponent) { var list = new List <IDownstreamComponent>(); if (initialComponent != null) { this.FindComponents(initialComponent, list); } return(list); }
/// <summary> /// Connects two components together by their input and output ports. /// </summary> /// <param name="destinationComponent">The component we want to connect to.</param> /// <param name="inputPort">The input port of the component we want to connect to.</param> /// <param name="useCallback">Flag to use connection callback (adversely affects performance).</param> /// <returns>The connection instance between the source output and destination input ports.</returns> public virtual IConnection ConnectTo(IDownstreamComponent destinationComponent, int inputPort = 0, bool useCallback = false) { if (this.ConnectedReference != null) { MMALLog.Logger.LogWarning($"{this.Name}: A connection has already been established on this port"); return(this.ConnectedReference); } var connection = MMALConnectionImpl.CreateConnection(this, destinationComponent.Inputs[inputPort], destinationComponent, useCallback); this.ConnectedReference = connection; destinationComponent.Inputs[inputPort].ConnectTo(this, connection); return(connection); }
MmalConnectionImpl(MmalConnectionType *ptr, IOutputPort output, IInputPort input, IDownstreamComponent inputComponent, IComponent outputComponent, bool useCallback) { Ptr = ptr; OutputPort = output; InputPort = input; DownstreamComponent = inputComponent; UpstreamComponent = outputComponent; if (useCallback) { CallbackHandler = new DefaultConnectionCallbackHandler(this); ConfigureConnectionCallback(output, input); } Enable(); if (useCallback) { OutputPort.SendAllBuffers(ConnectionPool); } }
static void FindComponents(IDownstreamComponent downstream, List <IDownstreamComponent> list) { if (!downstream.Outputs.Any()) { return; } if (downstream.Outputs.Count == 1 && downstream.Outputs[0].ConnectedReference == null) { list.Add(downstream); return; } if (downstream.GetType().BaseType == typeof(MmalDownstreamHandlerComponent)) { list.Add((MmalDownstreamHandlerComponent)downstream); } foreach (var output in downstream.Outputs.Where(output => output.ConnectedReference != null)) { FindComponents(output.ConnectedReference.DownstreamComponent, list); } }
/// <summary> /// Helper method to begin processing user provided image/video data. Starts the initial component control, input and output ports and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="initialComponent">The first component in your pipeline.</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(IDownstreamComponent initialComponent, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(initialComponent); initialComponent.Control.Start(); initialComponent.Inputs[0].Start(); var tasks = new List <Task>(); tasks.Add(initialComponent.Inputs[0].Trigger.Task); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); component.ForceStopProcessing = false; foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.Start(); tasks.Add(port.Trigger.Task); } } } // Get buffer from input port pool var inputBuffer = initialComponent.Inputs[0].BufferPool.Queue.GetBuffer(); if (inputBuffer.CheckState()) { initialComponent.Inputs[0].SendBuffer(inputBuffer); } if (cancellationToken == CancellationToken.None) { await Task.WhenAll(tasks).ConfigureAwait(false); } else { await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()).ConfigureAwait(false); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks).ConfigureAwait(false); } // Cleanup each downstream component. foreach (var component in handlerComponents) { foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.DisablePort(); } } component.CleanPortPools(); component.DisableConnections(); } }
internal static MmalConnectionImpl CreateConnection(IOutputPort output, IInputPort input, IDownstreamComponent inputComponent, bool useCallback) { var ptr = IntPtr.Zero; if (useCallback) { MmalCheck(MmalConnection.Create(&ptr, output.Ptr, input.Ptr, MmalConnection.MmalConnectionFlagAllocationOnInput), "Unable to create connection"); } else { MmalCheck(MmalConnection.Create(&ptr, output.Ptr, input.Ptr, MmalConnection.MmalConnectionFlagTunnelling | MmalConnection.MmalConnectionFlagAllocationOnInput), "Unable to create connection"); } return(new MmalConnectionImpl((MmalConnectionType *)ptr, output, input, inputComponent, output.ComponentReference, useCallback)); }
/// <summary> /// Facility to create a connection between two port objects. /// </summary> /// <param name="output">The output port of the connection.</param> /// <param name="input">The input port of the connection.</param> /// <param name="inputComponent">The managed instance of the component we are connecting to.</param> /// <param name="useCallback">When set to true, enable the connection callback delegate (adversely affects performance).</param> /// <returns>A new managed connection object.</returns> internal static MMALConnectionImpl CreateConnection(IOutputPort output, IInputPort input, IDownstreamComponent inputComponent, bool useCallback) { IntPtr ptr = IntPtr.Zero; if (useCallback) { MMALCheck(MMALConnection.mmal_connection_create(&ptr, output.Ptr, input.Ptr, MMALConnection.MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT), "Unable to create connection"); } else { MMALCheck(MMALConnection.mmal_connection_create(&ptr, output.Ptr, input.Ptr, MMALConnection.MMAL_CONNECTION_FLAG_TUNNELLING | MMALConnection.MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT), "Unable to create connection"); } return(new MMALConnectionImpl((MMAL_CONNECTION_T *)ptr, output, input, inputComponent, output.ComponentReference, useCallback)); }
/// <summary> /// Creates a new instance of <see cref="MMALConnectionImpl"/>. /// </summary> /// <param name="ptr">The native connection pointer.</param> /// <param name="output">The upstream component's output port.</param> /// <param name="input">The downstream component's input port.</param> /// <param name="inputComponent">The upstream component.</param> /// <param name="outputComponent">The downstream component.</param> /// <param name="useCallback"> /// Configure the connection to intercept native callbacks. Note: will adversely impact performance. In addition, this will implicitly enable /// zero copy functionality on both the source and sink ports. /// </param> protected MMALConnectionImpl(MMAL_CONNECTION_T *ptr, IOutputPort output, IInputPort input, IDownstreamComponent inputComponent, IComponent outputComponent, bool useCallback) { this.Ptr = ptr; this.OutputPort = output; this.InputPort = input; this.DownstreamComponent = inputComponent; this.UpstreamComponent = outputComponent; if (useCallback) { this.CallbackHandler = new DefaultConnectionCallbackHandler(this); this.ConfigureConnectionCallback(output, input); } this.Enable(); if (useCallback) { this.OutputPort.SendAllBuffers(this.ConnectionPool); } }