Beispiel #1
0
        /// <summary>
        /// Constructor that Takes an IImage
        /// </summary>
        /// <param name="image"></param>
        /// <param name="clone"></param>
        /// <param name="aspectRatio"></param>
        /// <param name="fourCC"></param>
        /// <param name="frameRateNumerator"></param>
        /// <param name="frameRateDenominator"></param>
        /// <param name="format"></param>
        public VideoFrame(IImage image, bool clone, float aspectRatio, NDIlib.FourCC_type_e fourCC,
                          int frameRateNumerator, int frameRateDenominator, NDIlib.frame_format_type_e format)
        {
            var ar = aspectRatio;

            if (ar <= 0.0)
            {
                ar = (float)image.Info.Width / image.Info.Height;
            }

            int bufferSize = image.Info.ImageSize;

            IntPtr videoBufferPtr;

            if (clone)
            {
                // we have to know to free it later
                _memoryOwned = true;

                // allocate some memory for a video buffer
                videoBufferPtr = Marshal.AllocHGlobal(bufferSize);

                using (var handle = image.GetData().Bytes.Pin())
                {
                    unsafe
                    {
                        System.Buffer.MemoryCopy((void *)handle.Pointer, (void *)videoBufferPtr.ToPointer(), bufferSize, bufferSize);
                    }
                }
            }
            else
            {
                _pinnedBytes = true;
                unsafe
                {
                    _handle        = image.GetData().Bytes.Pin(); //unpin when frame gets Disposed
                    videoBufferPtr = (IntPtr)_handle.Pointer;
                }
            }

            _ndiVideoFrame = new NDIlib.video_frame_v2_t()
            {
                xres                 = image.Info.Width,
                yres                 = image.Info.Height,
                FourCC               = fourCC,
                frame_rate_N         = frameRateNumerator,
                frame_rate_D         = frameRateDenominator,
                picture_aspect_ratio = ar,
                frame_format_type    = format,
                timecode             = NDIlib.send_timecode_synthesize,
                p_data               = videoBufferPtr,
                line_stride_in_bytes = image.Info.ScanSize,
                p_metadata           = IntPtr.Zero,
                timestamp            = 0
            };
        }
Beispiel #2
0
        public unsafe PointerBitmap(System.Buffers.MemoryHandle bitmapData, BitmapInfo bitmapInfo, bool isReadOnly = false)
        {
            if (bitmapData.Pointer == null)
            {
                throw new ArgumentNullException(nameof(bitmapData));
            }

            _Pointer    = new IntPtr(bitmapData.Pointer);
            _Info       = bitmapInfo;
            _IsReadOnly = isReadOnly;
        }
        /// <summary>
        /// Creates a new pinned buffer from an existing buffer
        /// </summary>
        /// <param name="buffer">existing buffer to pin</param>
        public PinnedBuffer(T[] buffer)
        {
            // allocate managed space
            ManagedBuffer = buffer;

            // pin the memory
            Memory = new Memory <T>(ManagedBuffer);
            Handle = Memory.Pin();

            // get a pointer to the pinned memory
            pData = (T *)Handle.Pointer;
        }
        /// <summary>
        /// Runs the loaded model for the given inputs and outputs. Uses the given RunOptions for this run.
        ///
        /// Outputs need to be created with correct type and dimension to receive the fetched data.
        /// </summary>
        /// <param name="inputNames">Specify a collection of string that indicates the input names. Should match <paramref name="inputValues"/>.</param>
        /// <param name="inputValues">Specify a collection of <see cref="FixedBufferOnnxValue"/> that indicates the input values.</param>
        /// <param name="output">Specify a collection of <see cref="NamedOnnxValue"/> that indicates the output values.</param>
        /// <param name="options"></param>
        public void Run(
            IReadOnlyCollection <string> inputNames,
            IReadOnlyCollection <FixedBufferOnnxValue> inputValues,
            IReadOnlyCollection <NamedOnnxValue> outputs,
            RunOptions options)
        {
            if (inputNames.Count != inputValues.Count)
            {
                throw new ArgumentException($"Length of {nameof(inputNames)} ({inputNames.Count}) must match that of {nameof(inputValues)} ({inputValues.Count}).");
            }

            var outputNamesArray          = new string[outputs.Count];
            var outputValuesArray         = new IntPtr[outputs.Count];
            var pinnedOutputBufferHandles = new System.Buffers.MemoryHandle[outputs.Count];
            var disposeOutputs            = new bool[outputs.Count];

            try
            {
                // prepare inputs
                string[] inputNamesArray  = inputNames as string[] ?? inputNames.ToArray();
                IntPtr[] inputValuesArray = new IntPtr[inputNames.Count];
                int      inputIndex       = 0;
                foreach (var input in inputValues)
                {
                    inputValuesArray[inputIndex] = input.Value;

                    inputIndex++;
                }

                // prepare outputs

                int outputIndex = 0;
                foreach (var output in outputs)
                {
                    outputNamesArray[outputIndex] = output.Name;

                    // create native OrtValue from the output if feasible, else throw notsupported exception for now
                    output.ToNativeOnnxValue(
                        out outputValuesArray[outputIndex],
                        out pinnedOutputBufferHandles[outputIndex],
                        out disposeOutputs[outputIndex]);

                    outputIndex++;
                }

                IntPtr status = NativeMethods.OrtRun(
                    _nativeHandle,
                    options.Handle,
                    inputNamesArray,
                    inputValuesArray,
                    (UIntPtr)inputNames.Count,
                    outputNamesArray,
                    (UIntPtr)outputs.Count,
                    outputValuesArray                                 /* pointers to Pre-allocated OrtValue instances */
                    );


                NativeApiStatus.VerifySuccess(status);
            }
            finally
            {
                for (int i = 0; i < outputs.Count; i++)
                {
                    if (disposeOutputs[i])
                    {
                        NativeMethods.OrtReleaseValue(outputValuesArray[i]); // For elementary type Tensors, this should not release the buffer, but should delete the native tensor object.
                                                                             // For string tensors, this releases the native memory allocated for the tensor, including the buffer
                        pinnedOutputBufferHandles[i].Dispose();
                    }
                }
            }
        }
        /// <summary>
        /// Runs the loaded model for the given inputs, and fetches the specified outputs in <paramref name="outputNames"/>. Uses the given RunOptions for this run.
        /// </summary>
        /// <param name="inputs">Specify a collection of <see cref="NamedOnnxValue"/> that indicates the input values.</param>
        /// <param name="outputNames">Specify a collection of string that indicates the output names to fetch.</param>
        /// <param name="options"></param>
        /// <returns>Output Tensors in a Collection of NamedOnnxValue. User must dispose the output.</returns>
        public IDisposableReadOnlyCollection <DisposableNamedOnnxValue> Run(IReadOnlyCollection <NamedOnnxValue> inputs, IReadOnlyCollection <string> outputNames, RunOptions options)
        {
            // prepare inputs
            var inputNamesArray          = new string[inputs.Count];
            var inputValuesArray         = new IntPtr[inputs.Count];
            var pinnedInputBufferHandles = new System.Buffers.MemoryHandle[inputs.Count];
            var disposeInputs            = new bool[inputs.Count];

            int inputIndex = 0;

            foreach (var input in inputs)
            {
                inputNamesArray[inputIndex] = input.Name;

                // create Tensor from the input if feasible, else throw notsupported exception for now
                input.ToNativeOnnxValue(
                    out inputValuesArray[inputIndex],
                    out pinnedInputBufferHandles[inputIndex],
                    out disposeInputs[inputIndex]);

                inputIndex++;
            }

            // prepare outputs
            string[] outputNamesArray  = outputNames as string[] ?? outputNames.ToArray();
            IntPtr[] outputValuesArray = new IntPtr[outputNames.Count];

            IntPtr status = NativeMethods.OrtRun(
                _nativeHandle,
                options.Handle,
                inputNamesArray,
                inputValuesArray,
                (UIntPtr)inputs.Count,
                outputNamesArray,
                (UIntPtr)outputNames.Count,
                outputValuesArray                                 /* Empty array is passed in to receive output OrtValue pointers */
                );

            try
            {
                NativeApiStatus.VerifySuccess(status);
                var result = new DisposableList <DisposableNamedOnnxValue>(outputValuesArray.Length);
                for (int i = 0; i < outputValuesArray.Length; i++)
                {
                    result.Add(DisposableNamedOnnxValue.CreateFromOnnxValue(outputNamesArray[i], outputValuesArray[i]));
                }

                return(result);
            }
            catch (OnnxRuntimeException e)
            {
                //clean up the individual output tensors if it is not null;
                for (int i = 0; i < outputValuesArray.Length; i++)
                {
                    if (outputValuesArray[i] != IntPtr.Zero)
                    {
                        NativeMethods.OrtReleaseValue(outputValuesArray[i]);
                    }
                }
                throw e;
            }
            finally
            {
                for (int i = 0; i < inputs.Count; i++)
                {
                    if (disposeInputs[i])
                    {
                        NativeMethods.OrtReleaseValue(inputValuesArray[i]); // For elementary type Tensors, this should not release the buffer, but should delete the native tensor object.
                                                                            // For string tensors, this releases the native memory allocated for the tensor, including the buffer
                        pinnedInputBufferHandles[i].Dispose();
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Runs the loaded model for the given inputs, and fetches the specified outputs in <paramref name="outputNames"/>.
        /// </summary>
        /// <param name="inputs"></param>
        /// <param name="outputNames"></param>
        /// <param name="options"></param>
        /// <returns>Output Tensors in a Dictionary</returns>
        //TODO: kept internal until RunOptions is made public
        internal IReadOnlyCollection <NamedOnnxValue> Run(IReadOnlyCollection <NamedOnnxValue> inputs, IReadOnlyCollection <string> outputNames, RunOptions options)
        {
            var inputNames          = new string[inputs.Count];
            var inputTensors        = new IntPtr[inputs.Count];
            var pinnedBufferHandles = new System.Buffers.MemoryHandle[inputs.Count];

            int offset = 0;

            foreach (var input in inputs)
            {
                inputNames[offset] = input.Name;

                // create Tensor from the input if feasible, else throw notsupported exception for now
                input.ToNativeOnnxValue(out inputTensors[offset], out pinnedBufferHandles[offset]);

                offset++;
            }

            string[] outputNamesArray = outputNames.ToArray();
            IntPtr[] outputValueArray = new IntPtr[outputNames.Count];

            IntPtr status = NativeMethods.OrtRunInference(
                this._nativeHandle,
                IntPtr.Zero,                                  // TODO: use Run options when Run options creation API is available
                                                              // Passing null uses the default run options in the C-api
                inputNames,
                inputTensors,
                (ulong)(inputTensors.Length),                    /* TODO: size_t, make it portable for x86 arm */
                outputNamesArray,
                (ulong)outputNames.Count,                        /* TODO: size_t, make it portable for x86 and arm */
                outputValueArray                                 /* An array of output value pointers. Array must be allocated by the caller */
                );

            try
            {
                NativeApiStatus.VerifySuccess(status);
                var result = new List <NamedOnnxValue>();
                for (uint i = 0; i < outputValueArray.Length; i++)
                {
                    result.Add(NamedOnnxValue.CreateFromOnnxValue(outputNamesArray[i], outputValueArray[i]));
                }

                return(result);
            }
            catch (OnnxRuntimeException e)
            {
                //clean up the individual output tensors if it is not null;
                for (uint i = 0; i < outputValueArray.Length; i++)
                {
                    if (outputValueArray[i] != IntPtr.Zero)
                    {
                        NativeMethods.OrtReleaseValue(outputValueArray[i]);
                    }
                }
                throw e;
            }
            finally
            {
                // always unpin the input buffers, and delete the native Onnx value objects
                for (int i = 0; i < inputs.Count; i++)
                {
                    NativeMethods.OrtReleaseValue(inputTensors[i]); // this should not release the buffer, but should delete the native tensor object
                    pinnedBufferHandles[i].Dispose();
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Runs the loaded model for the given inputs, and fetches the specified outputs in <paramref name="outputNames". Uses the given RunOptions for this run./>.
        /// </summary>
        /// <param name="inputs"></param>
        /// <param name="outputNames"></param>
        /// <param name="options"></param>
        /// <returns>Output Tensors in a Collection of NamedOnnxValue. User must dispose the output.</returns>
        public IDisposableReadOnlyCollection <DisposableNamedOnnxValue> Run(IReadOnlyCollection <NamedOnnxValue> inputs, IReadOnlyCollection <string> outputNames, RunOptions options)
        {
            var inputNames          = new string[inputs.Count];
            var inputTensors        = new IntPtr[inputs.Count];
            var pinnedBufferHandles = new System.Buffers.MemoryHandle[inputs.Count];

            int inputIndex = 0;

            foreach (var input in inputs)
            {
                inputNames[inputIndex] = input.Name;

                // create Tensor from the input if feasible, else throw notsupported exception for now
                input.ToNativeOnnxValue(out inputTensors[inputIndex],
                                        out pinnedBufferHandles[inputIndex]);

                inputIndex++;
            }

            string[] outputNamesArray = outputNames.ToArray();
            IntPtr[] outputValueArray = new IntPtr[outputNames.Count];

            IntPtr status = NativeMethods.OrtRun(
                this._nativeHandle,
                options.Handle,
                inputNames,
                inputTensors,
                (UIntPtr)(inputTensors.Length),
                outputNamesArray,
                (UIntPtr)outputNames.Count,
                outputValueArray                                 /* An array of output value pointers. Array must be allocated by the caller */
                );

            try
            {
                NativeApiStatus.VerifySuccess(status);
                var result = new DisposableList <DisposableNamedOnnxValue>();
                for (uint i = 0; i < outputValueArray.Length; i++)
                {
                    result.Add(DisposableNamedOnnxValue.CreateFromOnnxValue(outputNamesArray[i], outputValueArray[i]));
                }

                return(result);
            }
            catch (OnnxRuntimeException e)
            {
                //clean up the individual output tensors if it is not null;
                for (uint i = 0; i < outputValueArray.Length; i++)
                {
                    if (outputValueArray[i] != IntPtr.Zero)
                    {
                        NativeMethods.OrtReleaseValue(outputValueArray[i]);
                    }
                }
                throw e;
            }
            finally
            {
                inputIndex = 0;
                foreach (var input in inputs)
                {
                    // For NamedOnnxValue, always unpin the input buffers, and delete the native Onnx value objects
                    // For DisposableNamedOnnxValue, the user needs to do this by invoking Dispose
                    if (input.GetType() == typeof(NamedOnnxValue))
                    {
                        NativeMethods.OrtReleaseValue(inputTensors[inputIndex]); // For elementary type Tensors, this should not release the buffer, but should delete the native tensor object.
                                                                                 // For string tensors, this releases the native memory allocated for the tensor, including the buffer
                        pinnedBufferHandles[inputIndex].Dispose();
                    }

                    inputIndex++;
                }
            }
        }