예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        /// <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();
            }
        }
예제 #4
0
        private List <IDownstreamComponent> PopulateProcessingList(IDownstreamComponent initialComponent)
        {
            var list = new List <IDownstreamComponent>();

            if (initialComponent != null)
            {
                this.FindComponents(initialComponent, list);
            }

            return(list);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        /// <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();
            }
        }
예제 #9
0
        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));
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
        /// <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);
            }
        }