mirror of
https://github.com/cosyneco/MediaPipe.NET.git
synced 2025-07-04 04:06:46 +08:00
Huge update to get on par with MediaPipeUnityPlugin (#39)
* Use new MediaPipe packages and update version * Apply updates from MediaPipeUnityPlugin All while keeping C pointers like `void*` instead of `IntPtr` and various other practices. * Add VSCode task to debug tests * Fix unset freeHGlobal delegate This can happen because the static code of the NativeMethods class could have not run, for some reason... * Fix all examples * Fix import reordering
This commit is contained in:
27
.vscode/tasks.json
vendored
27
.vscode/tasks.json
vendored
@ -12,6 +12,31 @@
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": ".NET Core Test with debugger (that one crashing test)",
|
||||
"type": "process",
|
||||
"isBackground": true,
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"test",
|
||||
"--logger",
|
||||
"console;verbosity=detailed"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/Mediapipe.Net.Tests",
|
||||
"env": {
|
||||
"VSTEST_HOST_DEBUG": "1"
|
||||
},
|
||||
},
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediapipe.Net.Examples.Pose
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediapipe.Net.Examples.OsuFrameworkVisualTests", "Mediapipe.Net.Examples.OsuFrameworkVisualTests\Mediapipe.Net.Examples.OsuFrameworkVisualTests.csproj", "{34F0FFCF-F81E-4556-BC74-ED9AEBA7F731}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediapipe.Net.Examples.HandsGpu", "Mediapipe.Net.Examples.HandsGpu\Mediapipe.Net.Examples.HandsGpu.csproj", "{52AF90A3-E637-44F4-9FE8-15114829DD5D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -60,5 +62,9 @@ Global
|
||||
{34F0FFCF-F81E-4556-BC74-ED9AEBA7F731}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{34F0FFCF-F81E-4556-BC74-ED9AEBA7F731}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{34F0FFCF-F81E-4556-BC74-ED9AEBA7F731}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{52AF90A3-E637-44F4-9FE8-15114829DD5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{52AF90A3-E637-44F4-9FE8-15114829DD5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{52AF90A3-E637-44F4-9FE8-15114829DD5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{52AF90A3-E637-44F4-9FE8-15114829DD5D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace Mediapipe.Net.Examples.FaceMesh
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
List<NormalizedLandmarkList>? landmarks = calculator.Compute(imgframe);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace Mediapipe.Net.Examples.FaceMeshGpu
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
List<NormalizedLandmarkList>? landmarks = calculator.Compute(imgframe);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -7,6 +7,7 @@ using CommandLine;
|
||||
using FFmpeg.AutoGen;
|
||||
using Mediapipe.Net.External;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Solutions;
|
||||
using Mediapipe.Net.Util;
|
||||
using SeeShark;
|
||||
@ -93,7 +94,7 @@ namespace Mediapipe.Net.Examples.Hands
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
HandsOutput handsOutput = calculator.Compute(imgframe);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -8,6 +8,7 @@ using CommandLine;
|
||||
using FFmpeg.AutoGen;
|
||||
using Mediapipe.Net.External;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Solutions;
|
||||
using Mediapipe.Net.Util;
|
||||
using SeeShark;
|
||||
@ -95,7 +96,7 @@ namespace Mediapipe.Net.Examples.HandsGpu
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
HandsOutput handsOutput = calculator.Compute(imgframe);
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="0.8.9" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2022.707.0" />
|
||||
|
@ -18,6 +18,7 @@ using osu.Framework.Graphics.Textures;
|
||||
using SeeShark;
|
||||
using SeeShark.Device;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using Anchor = osu.Framework.Graphics.Anchor;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace Mediapipe.Net.Examples.OsuFrameworkVisualTests
|
||||
@ -72,7 +73,7 @@ namespace Mediapipe.Net.Examples.OsuFrameworkVisualTests
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
using ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
List<NormalizedLandmarkList>? landmarkList = calculator.Compute(imgframe);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -7,6 +7,7 @@ using CommandLine;
|
||||
using FFmpeg.AutoGen;
|
||||
using Mediapipe.Net.External;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Solutions;
|
||||
using Mediapipe.Net.Util;
|
||||
using SeeShark;
|
||||
@ -86,7 +87,7 @@ namespace Mediapipe.Net.Examples.Pose
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
PoseOutput handsOutput = calculator.Compute(imgframe);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="0.8.9.1" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="SeeShark" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -7,6 +7,7 @@ using CommandLine;
|
||||
using FFmpeg.AutoGen;
|
||||
using Mediapipe.Net.External;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Solutions;
|
||||
using Mediapipe.Net.Util;
|
||||
using SeeShark;
|
||||
@ -86,7 +87,7 @@ namespace Mediapipe.Net.Examples.PoseGpu
|
||||
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
|
||||
Frame cFrame = converter.Convert(frame);
|
||||
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
|
||||
ImageFrame imgframe = new ImageFrame(ImageFormat.Types.Format.Srgba,
|
||||
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
|
||||
|
||||
PoseOutput handsOutput = calculator.Compute(imgframe);
|
||||
|
@ -43,8 +43,8 @@ output_stream: ""out""
|
||||
{
|
||||
using var graph = new CalculatorGraph(valid_config_text);
|
||||
var config = graph.Config();
|
||||
Assert.AreEqual(config.InputStream[0], "in");
|
||||
Assert.AreEqual(config.OutputStream[0], "out");
|
||||
Assert.AreEqual("in", config.InputStream[0]);
|
||||
Assert.AreEqual("out", config.OutputStream[0]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -77,8 +77,8 @@ output_stream: ""out""
|
||||
}
|
||||
|
||||
var config = graph.Config();
|
||||
Assert.AreEqual(config.InputStream[0], "in");
|
||||
Assert.AreEqual(config.OutputStream[0], "out");
|
||||
Assert.AreEqual("in", config.InputStream[0]);
|
||||
Assert.AreEqual("out", config.OutputStream[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -86,7 +86,7 @@ output_stream: ""out""
|
||||
{
|
||||
using var graph = new CalculatorGraph(valid_config_text);
|
||||
using var status = graph.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(valid_config_text));
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.Internal);
|
||||
Assert.AreEqual(Status.StatusCode.Internal, status.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -112,7 +112,7 @@ output_stream: ""out""
|
||||
var config = CalculatorGraphConfig.Parser.ParseFromTextFormat(valid_config_text);
|
||||
|
||||
using var status = graph.Initialize(config, sidePackets);
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.Internal);
|
||||
Assert.AreEqual(Status.StatusCode.Internal, status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -137,7 +137,7 @@ output_stream: ""out""
|
||||
using var graph = new CalculatorGraph(valid_config_text);
|
||||
Assert.True(graph.StartRun().Ok());
|
||||
graph.Cancel();
|
||||
Assert.AreEqual(graph.WaitUntilDone().Code, Status.StatusCode.Cancelled);
|
||||
Assert.AreEqual(Status.StatusCode.Cancelled, graph.WaitUntilDone().Code);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -6,67 +6,60 @@ using System;
|
||||
using System.Linq;
|
||||
using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Tests;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mediapipe.Net.Tests.Framework.Format
|
||||
namespace Mediapipe.Tests
|
||||
{
|
||||
public class ImageFrameTest
|
||||
{
|
||||
#region Constructor
|
||||
[Test, SignalAbort]
|
||||
public void Ctor_ShouldInstantiateImageFrame_When_CalledWithNoArguments()
|
||||
[Test]
|
||||
public unsafe void Ctor_ShouldInstantiateImageFrame_When_CalledWithNoArguments()
|
||||
{
|
||||
using var imageFrame = new ImageFrame();
|
||||
#pragma warning disable IDE0058
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Unknown);
|
||||
Assert.AreEqual(imageFrame.Width, 0);
|
||||
Assert.AreEqual(imageFrame.Height, 0);
|
||||
// As these are now properties, i had to ToString() them so that they are run.
|
||||
Assert.Throws<FormatException>(() => imageFrame.ChannelSize.ToString());
|
||||
Assert.Throws<FormatException>(() => imageFrame.NumberOfChannels.ToString());
|
||||
Assert.Throws<FormatException>(() => imageFrame.ByteDepth.ToString());
|
||||
Assert.AreEqual(imageFrame.WidthStep, 0);
|
||||
Assert.AreEqual(imageFrame.PixelDataSize, 0);
|
||||
Assert.Throws<FormatException>(() => imageFrame.PixelDataSizeStoredContiguously.ToString());
|
||||
Assert.AreEqual(ImageFormat.Types.Format.Unknown, imageFrame.Format);
|
||||
Assert.AreEqual(0, imageFrame.Width);
|
||||
Assert.AreEqual(0, imageFrame.Height, 0);
|
||||
Assert.AreEqual(0, imageFrame.ChannelSize);
|
||||
Assert.AreEqual(0, imageFrame.NumberOfChannels);
|
||||
Assert.AreEqual(0, imageFrame.ByteDepth);
|
||||
Assert.AreEqual(0, imageFrame.WidthStep);
|
||||
Assert.AreEqual(0, imageFrame.PixelDataSize);
|
||||
Assert.AreEqual(0, imageFrame.PixelDataSizeStoredContiguously);
|
||||
Assert.True(imageFrame.IsEmpty);
|
||||
Assert.False(imageFrame.IsContiguous);
|
||||
Assert.False(imageFrame.IsAligned(16));
|
||||
unsafe
|
||||
{
|
||||
Assert.True(imageFrame.MutablePixelData == null);
|
||||
}
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormat()
|
||||
public unsafe void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormat()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Sbgra, 640, 480);
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Sbgra);
|
||||
Assert.AreEqual(imageFrame.Width, 640);
|
||||
Assert.AreEqual(imageFrame.Height, 480);
|
||||
Assert.AreEqual(imageFrame.ChannelSize, 1);
|
||||
Assert.AreEqual(imageFrame.NumberOfChannels, 4);
|
||||
Assert.AreEqual(imageFrame.ByteDepth, 1);
|
||||
Assert.AreEqual(imageFrame.WidthStep, 640 * 4);
|
||||
Assert.AreEqual(imageFrame.PixelDataSize, 640 * 480 * 4);
|
||||
Assert.AreEqual(imageFrame.PixelDataSizeStoredContiguously, 640 * 480 * 4);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 640, 480);
|
||||
Assert.AreEqual(ImageFormat.Types.Format.Sbgra, imageFrame.Format);
|
||||
Assert.AreEqual(640, imageFrame.Width);
|
||||
Assert.AreEqual(480, imageFrame.Height);
|
||||
Assert.AreEqual(1, imageFrame.ChannelSize);
|
||||
Assert.AreEqual(4, imageFrame.NumberOfChannels);
|
||||
Assert.AreEqual(1, imageFrame.ByteDepth);
|
||||
Assert.AreEqual(640 * 4, imageFrame.WidthStep);
|
||||
Assert.AreEqual(640 * 480 * 4, imageFrame.PixelDataSize);
|
||||
Assert.AreEqual(640 * 480 * 4, imageFrame.PixelDataSizeStoredContiguously);
|
||||
Assert.False(imageFrame.IsEmpty);
|
||||
Assert.True(imageFrame.IsContiguous);
|
||||
Assert.True(imageFrame.IsAligned(16));
|
||||
unsafe
|
||||
{
|
||||
Assert.True(imageFrame.MutablePixelData != null);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormatAndAlignmentBoundary()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray8, 100, 100, 8);
|
||||
Assert.AreEqual(imageFrame.Width, 100);
|
||||
Assert.AreEqual(imageFrame.NumberOfChannels, 1);
|
||||
Assert.AreEqual(imageFrame.WidthStep, 104);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 100, 100, 8);
|
||||
Assert.AreEqual(100, imageFrame.Width);
|
||||
Assert.AreEqual(1, imageFrame.NumberOfChannels);
|
||||
Assert.AreEqual(104, imageFrame.WidthStep);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -77,71 +70,83 @@ namespace Mediapipe.Net.Tests.Framework.Format
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
};
|
||||
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Sbgra, 4, 2, 16, srcBytes);
|
||||
Assert.AreEqual(imageFrame.Width, 4);
|
||||
Assert.AreEqual(imageFrame.Height, 2);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 4, 2, 16, srcBytes);
|
||||
Assert.AreEqual(4, imageFrame.Width);
|
||||
Assert.AreEqual(2, imageFrame.Height);
|
||||
Assert.False(imageFrame.IsEmpty);
|
||||
|
||||
byte[] bytes = imageFrame.CopyToByteBuffer(srcBytes.Length);
|
||||
byte[] bytes = new byte[32];
|
||||
imageFrame.CopyToBuffer(bytes);
|
||||
Assert.IsEmpty(bytes.Where((x, i) => x != srcBytes[i]));
|
||||
}
|
||||
|
||||
|
||||
[Test, SignalAbort]
|
||||
public void Ctor_ShouldThrowMediapipeException_When_CalledWithInvalidArgument()
|
||||
public void Ctor_ShouldThrowMediaPipeException_When_CalledWithInvalidArgument()
|
||||
{
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { new ImageFrame(ImageFormat.Sbgra, 640, 480, 0); });
|
||||
Assert.Throws<MediapipeException>(() => { new ImageFrame(ImageFormat.Types.Format.Sbgra, 640, 480, 0); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IsDisposed
|
||||
#region #isDisposed
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnFalse_When_NotDisposedYet()
|
||||
{
|
||||
using var imageFrame = new ImageFrame();
|
||||
using ImageFrame imageFrame = new ImageFrame();
|
||||
Assert.False(imageFrame.IsDisposed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnTrue_When_AlreadyDisposed()
|
||||
{
|
||||
var imageFrame = new ImageFrame();
|
||||
ImageFrame imageFrame = new ImageFrame();
|
||||
imageFrame.Dispose();
|
||||
|
||||
Assert.True(imageFrame.IsDisposed);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetToZero
|
||||
#region #SetToZero
|
||||
[Test]
|
||||
public void SetToZero_ShouldSetZeroToAllBytes()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray8, 10, 10);
|
||||
var origBytes = imageFrame.CopyToByteBuffer(100);
|
||||
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
||||
imageFrame.SetToZero();
|
||||
var bytes = imageFrame.CopyToByteBuffer(100);
|
||||
var bytes = new byte[100];
|
||||
imageFrame.CopyToBuffer(bytes);
|
||||
Assert.True(bytes.All((x) => x == 0));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetAlignmentPaddingAreas
|
||||
#region #SetAlignmentPaddingAreas
|
||||
[Test]
|
||||
public void SetAlignmentPaddingAreas_ShouldNotThrow()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray8, 10, 10, 16);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10, 16);
|
||||
Assert.DoesNotThrow(() => { imageFrame.SetAlignmentPaddingAreas(); });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CopyToBuffer
|
||||
[Test, SignalAbort]
|
||||
public void CopyToByteBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new byte[100]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyToByteBuffer_ShouldReturnByteArray_When_BufferSizeIsLargeEnough()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray8, 10, 10);
|
||||
var normalBuffer = imageFrame.CopyToByteBuffer(100);
|
||||
var largeBuffer = imageFrame.CopyToByteBuffer(120);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
||||
var normalBuffer = new byte[100];
|
||||
var largeBuffer = new byte[120];
|
||||
imageFrame.CopyToBuffer(normalBuffer);
|
||||
imageFrame.CopyToBuffer(largeBuffer);
|
||||
|
||||
Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i]));
|
||||
}
|
||||
@ -149,18 +154,29 @@ namespace Mediapipe.Net.Tests.Framework.Format
|
||||
[Test, SignalAbort]
|
||||
public void CopyToByteBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray8, 10, 10);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToByteBuffer(99); });
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new byte[99]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test, SignalAbort]
|
||||
public void CopyToUshortBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new ushort[100]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyToUshortBuffer_ShouldReturnUshortArray_When_BufferSizeIsLargeEnough()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray16, 10, 10);
|
||||
var normalBuffer = imageFrame.CopyToUshortBuffer(100);
|
||||
var largeBuffer = imageFrame.CopyToUshortBuffer(120);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
||||
var normalBuffer = new ushort[100];
|
||||
var largeBuffer = new ushort[120];
|
||||
imageFrame.CopyToBuffer(normalBuffer);
|
||||
imageFrame.CopyToBuffer(largeBuffer);
|
||||
|
||||
Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i]));
|
||||
}
|
||||
@ -168,18 +184,29 @@ namespace Mediapipe.Net.Tests.Framework.Format
|
||||
[Test, SignalAbort]
|
||||
public void CopyToUshortBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Gray16, 10, 10);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToUshortBuffer(99); });
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new ushort[99]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test, SignalAbort]
|
||||
public void CopyToFloatBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new float[100]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyToFloatBuffer_ShouldReturnFloatArray_When_BufferSizeIsLargeEnough()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Vec32f1, 10, 10);
|
||||
var normalBuffer = imageFrame.CopyToFloatBuffer(100);
|
||||
var largeBuffer = imageFrame.CopyToFloatBuffer(120);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Vec32F1, 10, 10);
|
||||
var normalBuffer = new float[100];
|
||||
var largeBuffer = new float[120];
|
||||
imageFrame.CopyToBuffer(normalBuffer);
|
||||
imageFrame.CopyToBuffer(largeBuffer);
|
||||
|
||||
Assert.IsEmpty(normalBuffer.Where((x, i) => Math.Abs(x - largeBuffer[i]) > 1e-9));
|
||||
}
|
||||
@ -187,11 +214,11 @@ namespace Mediapipe.Net.Tests.Framework.Format
|
||||
[Test, SignalAbort]
|
||||
public void CopyToFloatBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
||||
{
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Vec32f1, 10, 10);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Vec32F1, 10, 10);
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToFloatBuffer(99); });
|
||||
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new float[99]); });
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System;
|
||||
using Mediapipe.Net.Framework;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mediapipe.Net.Tests.Framework.NewPacket
|
||||
@ -26,8 +27,8 @@ namespace Mediapipe.Net.Tests.Framework.NewPacket
|
||||
using var statusOrImageFrame = packet.ConsumeImageFrame();
|
||||
Assert.True(statusOrImageFrame.Ok());
|
||||
|
||||
using var imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Unknown);
|
||||
using ImageFrame? imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame?.Format, ImageFormat.Types.Format.Unknown);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -47,7 +48,7 @@ namespace Mediapipe.Net.Tests.Framework.NewPacket
|
||||
Assert.True(statusOrImageFrame.Ok());
|
||||
|
||||
using var imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Unknown);
|
||||
Assert.AreEqual(imageFrame?.Format, ImageFormat.Types.Format.Unknown);
|
||||
Assert.AreEqual(packet.Timestamp(), timestamp);
|
||||
}
|
||||
#endregion
|
||||
@ -74,9 +75,9 @@ namespace Mediapipe.Net.Tests.Framework.NewPacket
|
||||
[Test]
|
||||
public void Get_ShouldReturnImageFrame_When_DataIsNotEmpty()
|
||||
{
|
||||
using var packet = PacketFactory.ImageFramePacket(new ImageFrame(ImageFormat.Sbgra, 10, 10));
|
||||
using var packet = PacketFactory.ImageFramePacket(new ImageFrame(ImageFormat.Types.Format.Sbgra, 10, 10));
|
||||
using var imageFrame = packet.GetImageFrame();
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Sbgra);
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Types.Format.Sbgra);
|
||||
Assert.AreEqual(imageFrame.Width, 10);
|
||||
Assert.AreEqual(imageFrame.Height, 10);
|
||||
}
|
||||
@ -86,14 +87,14 @@ namespace Mediapipe.Net.Tests.Framework.NewPacket
|
||||
[Test]
|
||||
public void Consume_ShouldReturnImageFrame()
|
||||
{
|
||||
using var packet = PacketFactory.ImageFramePacket(new ImageFrame(ImageFormat.Sbgra, 10, 10));
|
||||
using var packet = PacketFactory.ImageFramePacket(new ImageFrame(ImageFormat.Types.Format.Sbgra, 10, 10));
|
||||
using var statusOrImageFrame = packet.ConsumeImageFrame();
|
||||
Assert.True(statusOrImageFrame.Ok());
|
||||
|
||||
using var imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame.Format, ImageFormat.Sbgra);
|
||||
Assert.AreEqual(imageFrame.Width, 10);
|
||||
Assert.AreEqual(imageFrame.Height, 10);
|
||||
using ImageFrame? imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame?.Format, ImageFormat.Types.Format.Sbgra);
|
||||
Assert.AreEqual(imageFrame?.Width, 10);
|
||||
Assert.AreEqual(imageFrame?.Height, 10);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
public void Status_ShouldReturnOk_When_StatusIsOk()
|
||||
{
|
||||
using var statusOrGpuResources = GpuResources.Create();
|
||||
Assert.AreEqual(statusOrGpuResources.Status.Code, Status.StatusCode.Ok);
|
||||
Assert.AreEqual(Status.StatusCode.Ok, statusOrGpuResources.Status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -6,6 +6,7 @@ using Mediapipe.Net.Framework;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mediapipe.Net.Tests.Framework.Port
|
||||
@ -18,7 +19,7 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
{
|
||||
using var statusOrImageFrame = initializeSubject();
|
||||
Assert.True(statusOrImageFrame.Ok());
|
||||
Assert.AreEqual(statusOrImageFrame.Status.Code, Status.StatusCode.Ok);
|
||||
Assert.AreEqual(Status.StatusCode.Ok, statusOrImageFrame.Status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -48,15 +49,15 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
Assert.True(statusOrImageFrame.Ok());
|
||||
|
||||
using var imageFrame = statusOrImageFrame.Value();
|
||||
Assert.AreEqual(imageFrame.Width, 10);
|
||||
Assert.AreEqual(imageFrame.Height, 10);
|
||||
Assert.AreEqual(10, imageFrame.Width);
|
||||
Assert.AreEqual(10, imageFrame.Height);
|
||||
Assert.True(statusOrImageFrame.IsDisposed);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private static StatusOrImageFrame initializeSubject()
|
||||
{
|
||||
var imageFrame = new ImageFrame(ImageFormat.Sbgra, 10, 10);
|
||||
var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 10, 10);
|
||||
var packet = PacketFactory.ImageFramePacket(imageFrame, new Timestamp(1));
|
||||
|
||||
return (StatusOrImageFrame)packet.ConsumeImageFrame();
|
||||
|
75
Mediapipe.Net.Tests/Framework/Port/StatusOrStringTest.cs
Normal file
75
Mediapipe.Net.Tests/Framework/Port/StatusOrStringTest.cs
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mediapipe.Net.Tests
|
||||
{
|
||||
public class StatusOrStringTest
|
||||
{
|
||||
#region #status
|
||||
[Test]
|
||||
public void Status_ShouldReturnOk_When_StatusIsOk()
|
||||
{
|
||||
using var statusOrString = initializeSubject("");
|
||||
Assert.True(statusOrString.Ok());
|
||||
Assert.AreEqual(Status.StatusCode.Ok, statusOrString.Status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #isDisposed
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnFalse_When_NotDisposedYet()
|
||||
{
|
||||
using var statusOrString = initializeSubject("");
|
||||
Assert.False(statusOrString.IsDisposed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnTrue_When_AlreadyDisposed()
|
||||
{
|
||||
var statusOrString = initializeSubject("");
|
||||
statusOrString.Dispose();
|
||||
|
||||
Assert.True(statusOrString.IsDisposed);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #Value
|
||||
[Test]
|
||||
public void Value_ShouldReturnString_When_StatusIsOk()
|
||||
{
|
||||
var bytes = new byte[] { (byte)'a', (byte)'b', 0, (byte)'c' };
|
||||
using var statusOrString = initializeSubject(bytes);
|
||||
Assert.True(statusOrString.Ok());
|
||||
Assert.AreEqual("ab", statusOrString.Value());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #ValueAsByteArray
|
||||
[Test]
|
||||
public void ValueAsByteArray_ShouldReturnByteArray_When_StatusIsOk()
|
||||
{
|
||||
var bytes = new byte[] { (byte)'a', (byte)'b', 0, (byte)'c' };
|
||||
using var statusOrString = initializeSubject(bytes);
|
||||
Assert.True(statusOrString.Ok());
|
||||
Assert.AreEqual(bytes, statusOrString.ValueAsByteArray());
|
||||
}
|
||||
#endregion
|
||||
|
||||
private StatusOrString initializeSubject(string str)
|
||||
{
|
||||
using Packet packet = PacketFactory.StringPacket(str);
|
||||
return (StatusOrString)packet.ConsumeString();
|
||||
}
|
||||
|
||||
private StatusOrString initializeSubject(byte[] bytes)
|
||||
{
|
||||
using Packet packet = PacketFactory.StringPacket(bytes);
|
||||
return (StatusOrString)packet.ConsumeString();
|
||||
}
|
||||
}
|
||||
}
|
@ -15,14 +15,14 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
public void Code_ShouldReturnStatusCode_When_StatusIsOk()
|
||||
{
|
||||
using var status = Status.Ok();
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.Ok);
|
||||
Assert.AreEqual(Status.StatusCode.Ok, status.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Code_ShouldReturnStatusCode_When_StatusIsFailedPrecondition()
|
||||
{
|
||||
using var status = Status.FailedPrecondition();
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.FailedPrecondition);
|
||||
Assert.AreEqual(Status.StatusCode.FailedPrecondition, status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -49,14 +49,14 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
public void RawCode_ShouldReturnRawCode_When_StatusIsOk()
|
||||
{
|
||||
using var status = Status.Ok();
|
||||
Assert.AreEqual(status.RawCode, 0);
|
||||
Assert.AreEqual(0, status.RawCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RawCode_ShouldReturnRawCode_When_StatusIsFailedPrecondition()
|
||||
{
|
||||
using var status = Status.FailedPrecondition();
|
||||
Assert.AreEqual(status.RawCode, 9);
|
||||
Assert.AreEqual(9, status.RawCode);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -108,8 +108,64 @@ namespace Mediapipe.Net.Tests.Framework.Port
|
||||
{
|
||||
var message = "Some error";
|
||||
using var status = Status.FailedPrecondition(message);
|
||||
Assert.AreEqual(status.ToString(), $"FAILED_PRECONDITION: {message}");
|
||||
Assert.AreEqual($"FAILED_PRECONDITION: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsAborted()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.Aborted(message);
|
||||
Assert.AreEqual($"ABORTED: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsOutOfRange()
|
||||
{
|
||||
string message = "Some error";
|
||||
using Status status = Status.OutOfRange(message);
|
||||
Assert.AreEqual($"OUT_OF_RANGE: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsUnimplemented()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.Unimplemented(message);
|
||||
Assert.AreEqual($"UNIMPLEMENTED: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsInternal()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.Internal(message);
|
||||
Assert.AreEqual($"INTERNAL: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsUnavailable()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.Unavailable(message);
|
||||
Assert.AreEqual($"UNAVAILABLE: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsDataLoss()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.DataLoss(message);
|
||||
Assert.AreEqual($"DATA_LOSS: {message}", status.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToString_ShouldReturnMessage_When_StatusIsUnauthenticated()
|
||||
{
|
||||
var message = "Some error";
|
||||
using Status status = Status.Unauthenticated(message);
|
||||
Assert.AreEqual($"UNAUTHENTICATED: {message}", status.ToString());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
public void Value_ShouldReturnValue()
|
||||
{
|
||||
using var timestamp = new Timestamp(10);
|
||||
Assert.AreEqual(timestamp.Value, 10);
|
||||
Assert.AreEqual(10, timestamp.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -41,7 +41,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
public void Seconds_ShouldReturnValueInSeconds()
|
||||
{
|
||||
using var timestamp = new Timestamp(1_000_000);
|
||||
Assert.AreEqual(timestamp.Seconds, 1d, 1e-9);
|
||||
Assert.AreEqual(1d, timestamp.Seconds, 1e-9);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -50,7 +50,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
public void Microseconds_ShouldReturnValueInMicroseconds()
|
||||
{
|
||||
using var timestamp = new Timestamp(1_000_000);
|
||||
Assert.AreEqual(timestamp.Microseconds, 1_000_000);
|
||||
Assert.AreEqual(1_000_000, timestamp.Microseconds);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -142,14 +142,14 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
public void DebugString_ShouldReturnDebugString()
|
||||
{
|
||||
using var timestamp = new Timestamp(1);
|
||||
Assert.AreEqual(timestamp.DebugString, "1");
|
||||
Assert.AreEqual("1", timestamp.DebugString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DebugString_ShouldReturnDebugString_When_TimestampIsUnset()
|
||||
{
|
||||
using var timestamp = Timestamp.Unset();
|
||||
Assert.AreEqual(timestamp.DebugString, "Timestamp::Unset()");
|
||||
Assert.AreEqual("Timestamp::Unset()", timestamp.DebugString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -159,7 +159,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
{
|
||||
using var timestamp = new Timestamp(1);
|
||||
using var nextTimestamp = timestamp.NextAllowedInStream();
|
||||
Assert.AreEqual(nextTimestamp.Microseconds, 2);
|
||||
Assert.AreEqual(2, nextTimestamp.Microseconds);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -167,7 +167,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
{
|
||||
using var timestamp = Timestamp.PostStream();
|
||||
using var nextTimestamp = timestamp.NextAllowedInStream();
|
||||
Assert.AreEqual(nextTimestamp, Timestamp.OneOverPostStream());
|
||||
Assert.AreEqual(Timestamp.OneOverPostStream(), nextTimestamp);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -177,7 +177,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
{
|
||||
using var timestamp = new Timestamp(1);
|
||||
using var nextTimestamp = timestamp.PreviousAllowedInStream();
|
||||
Assert.AreEqual(nextTimestamp.Microseconds, 0);
|
||||
Assert.AreEqual(0, nextTimestamp.Microseconds);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -185,7 +185,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
{
|
||||
using var timestamp = Timestamp.PreStream();
|
||||
using var nextTimestamp = timestamp.PreviousAllowedInStream();
|
||||
Assert.AreEqual(nextTimestamp, Timestamp.Unstarted());
|
||||
Assert.AreEqual(Timestamp.Unstarted(), nextTimestamp);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -194,7 +194,7 @@ namespace Mediapipe.Net.Tests.Framework
|
||||
public void FromSeconds_ShouldReturnTimestamp()
|
||||
{
|
||||
using var timestamp = Timestamp.FromSeconds(1d);
|
||||
Assert.AreEqual(timestamp.Microseconds, 1_000_000);
|
||||
Assert.AreEqual(1_000_000, timestamp.Microseconds);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
public void GetUnusedNodeName_ShouldReturnUniqueName(string configJson, string nameBase, string uniqueName)
|
||||
{
|
||||
var config = CalculatorGraphConfig.Parser.ParseJson(configJson);
|
||||
Assert.AreEqual(GetUnusedNodeName(config, nameBase), uniqueName);
|
||||
Assert.AreEqual(uniqueName, GetUnusedNodeName(config, nameBase));
|
||||
}
|
||||
|
||||
[TestCase("{}", "base", "base")]
|
||||
@ -28,7 +28,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
public void GetUnusedSidePacketName_ShouldReturnUniqueName(string configJson, string nameBase, string uniqueName)
|
||||
{
|
||||
var config = CalculatorGraphConfig.Parser.ParseJson(configJson);
|
||||
Assert.AreEqual(GetUnusedSidePacketName(config, nameBase), uniqueName);
|
||||
Assert.AreEqual(uniqueName, GetUnusedSidePacketName(config, nameBase));
|
||||
}
|
||||
|
||||
[TestCase(@"{""node"":[{""name"":""x""}]}", 0, "x")]
|
||||
@ -43,7 +43,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
public void CanonicalNodeName_ShouldReturnCanonicalNodeName_When_NodeIdIsValid(string configJson, int nodeId, string name)
|
||||
{
|
||||
var config = CalculatorGraphConfig.Parser.ParseJson(configJson);
|
||||
Assert.AreEqual(CanonicalNodeName(config, nodeId), name);
|
||||
Assert.AreEqual(name, CanonicalNodeName(config, nodeId));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -78,7 +78,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
[TestCase("TAG:1:x", "x")]
|
||||
public void ParseNameFromStream_ShouldReturnName_When_InputIsValid(string stream, string name)
|
||||
{
|
||||
Assert.AreEqual(ParseNameFromStream(stream), name);
|
||||
Assert.AreEqual(name, ParseNameFromStream(stream));
|
||||
}
|
||||
|
||||
[TestCase(":stream")]
|
||||
@ -99,8 +99,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
{
|
||||
var output = ParseTagIndex(tagIndex);
|
||||
|
||||
Assert.AreEqual(output.Item1, tag);
|
||||
Assert.AreEqual(output.Item2, index);
|
||||
Assert.AreEqual(tag, output.Item1);
|
||||
Assert.AreEqual(index, output.Item2);
|
||||
}
|
||||
|
||||
[TestCase("tag")]
|
||||
@ -121,8 +121,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
{
|
||||
var output = ParseTagIndexFromStream(stream);
|
||||
|
||||
Assert.AreEqual(output.Item1, tag);
|
||||
Assert.AreEqual(output.Item2, index);
|
||||
Assert.AreEqual(tag, output.Item1);
|
||||
Assert.AreEqual(index, output.Item2);
|
||||
}
|
||||
|
||||
[TestCase(":stream")]
|
||||
@ -141,7 +141,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
[TestCase("TAG", 1, "TAG:1")]
|
||||
public void CatTag_ShouldReturnTag(string tag, int index, string output)
|
||||
{
|
||||
Assert.AreEqual(CatTag(tag, index), output);
|
||||
Assert.AreEqual(output, CatTag(tag, index));
|
||||
}
|
||||
|
||||
[TestCase("", -1, "x", "x")]
|
||||
@ -150,7 +150,7 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
[TestCase("TAG", 1, "x", "TAG:1:x")]
|
||||
public void CatStream_ShouldReturnStream(string tag, int index, string name, string output)
|
||||
{
|
||||
Assert.AreEqual(CatStream((tag, index), name), output);
|
||||
Assert.AreEqual(output, CatStream((tag, index), name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,8 +112,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
{
|
||||
ParseTagAndName(input, out var tag, out var name);
|
||||
|
||||
Assert.AreEqual(tag, expectedTag);
|
||||
Assert.AreEqual(name, expectedName);
|
||||
Assert.AreEqual(expectedTag, tag);
|
||||
Assert.AreEqual(expectedName, name);
|
||||
}
|
||||
|
||||
[TestCase(":humphrey")]
|
||||
@ -128,8 +128,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<ArgumentException>(() => { ParseTagAndName(input, out tag, out name); });
|
||||
Assert.AreEqual(tag, "UNTOUCHED");
|
||||
Assert.AreEqual(name, "untouched");
|
||||
Assert.AreEqual("UNTOUCHED", tag);
|
||||
Assert.AreEqual("untouched", name);
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
@ -156,9 +156,9 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
{
|
||||
ParseTagIndexName(input, out var tag, out var index, out var name);
|
||||
|
||||
Assert.AreEqual(tag, expectedTag);
|
||||
Assert.AreEqual(index, expectedIndex);
|
||||
Assert.AreEqual(name, expectedName);
|
||||
Assert.AreEqual(expectedTag, tag);
|
||||
Assert.AreEqual(expectedIndex, index);
|
||||
Assert.AreEqual(expectedName, name);
|
||||
}
|
||||
|
||||
[TestCase("")]
|
||||
@ -205,9 +205,9 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<ArgumentException>(() => { ParseTagIndexName(input, out tag, out index, out name); });
|
||||
Assert.AreEqual(tag, "UNTOUCHED");
|
||||
Assert.AreEqual(index, -1);
|
||||
Assert.AreEqual(name, "untouched");
|
||||
Assert.AreEqual("UNTOUCHED", tag);
|
||||
Assert.AreEqual(-1, index);
|
||||
Assert.AreEqual("untouched", name);
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
@ -235,8 +235,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
{
|
||||
ParseTagIndex(input, out var tag, out var index);
|
||||
|
||||
Assert.AreEqual(tag, expectedTag);
|
||||
Assert.AreEqual(index, expectedIndex);
|
||||
Assert.AreEqual(expectedTag, tag);
|
||||
Assert.AreEqual(expectedIndex, index);
|
||||
}
|
||||
|
||||
[TestCase("a")]
|
||||
@ -270,8 +270,8 @@ namespace Mediapipe.Net.Tests.Framework.Tool
|
||||
|
||||
#pragma warning disable IDE0058
|
||||
Assert.Throws<ArgumentException>(() => { ParseTagIndex(input, out tag, out index); });
|
||||
Assert.AreEqual(tag, "UNTOUCHED");
|
||||
Assert.AreEqual(index, -1);
|
||||
Assert.AreEqual("UNTOUCHED", tag);
|
||||
Assert.AreEqual(-1, index);
|
||||
#pragma warning restore IDE0058
|
||||
}
|
||||
|
||||
|
743
Mediapipe.Net.Tests/Framework/ValidatedGraphConfigTest.cs
Normal file
743
Mediapipe.Net.Tests/Framework/ValidatedGraphConfigTest.cs
Normal file
@ -0,0 +1,743 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Linq;
|
||||
using Mediapipe.Net.Framework;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Framework.ValidatedGraphConfig;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mediapipe.Net.Tests
|
||||
{
|
||||
public class ValidatedGraphConfigTest
|
||||
{
|
||||
private const string pass_through_config_text = @"
|
||||
node {
|
||||
calculator: ""PassThroughCalculator""
|
||||
input_stream: ""in""
|
||||
output_stream: ""out1""
|
||||
}
|
||||
node {
|
||||
calculator: ""PassThroughCalculator""
|
||||
input_stream: ""out1""
|
||||
output_stream: ""out""
|
||||
}
|
||||
input_stream: ""in""
|
||||
output_stream: ""out""
|
||||
";
|
||||
|
||||
private const string flow_limiter_config_text = @"
|
||||
input_stream: ""input_video""
|
||||
input_stream: ""output""
|
||||
|
||||
node {
|
||||
calculator: ""FlowLimiterCalculator""
|
||||
input_stream: ""input_video""
|
||||
input_stream: ""FINISHED:output""
|
||||
input_stream_info: {
|
||||
tag_index: ""FINISHED""
|
||||
back_edge: true
|
||||
}
|
||||
input_side_packet: ""MAX_IN_FLIGHT:max_in_flight""
|
||||
input_side_packet: ""OPTIONS:flow_limiter_calculator_options""
|
||||
output_stream: ""throttled_input_video""
|
||||
}
|
||||
";
|
||||
|
||||
private const string image_transformation_config_text = @"
|
||||
input_stream: ""input_video""
|
||||
|
||||
node: {
|
||||
calculator: ""ImageTransformationCalculator""
|
||||
input_stream: ""IMAGE:input_video""
|
||||
input_side_packet: ""ROTATION_DEGREES:input_rotation""
|
||||
input_side_packet: ""FLIP_HORIZONTALLY:input_horizontally_flipped""
|
||||
input_side_packet: ""FLIP_VERTICALLY:input_vertically_flipped""
|
||||
output_stream: ""IMAGE:transformed_input_video""
|
||||
}
|
||||
";
|
||||
|
||||
private const string constant_side_packet_config_text = @"
|
||||
node {
|
||||
calculator: ""ConstantSidePacketCalculator""
|
||||
output_side_packet: ""PACKET:0:int_packet""
|
||||
output_side_packet: ""PACKET:1:float_packet""
|
||||
output_side_packet: ""PACKET:2:bool_packet""
|
||||
output_side_packet: ""PACKET:3:string_packet""
|
||||
options: {
|
||||
[mediapipe.ConstantSidePacketCalculatorOptions.ext]: {
|
||||
packet { int_value: 256 }
|
||||
packet { float_value: 0.5f }
|
||||
packet { bool_value: false }
|
||||
packet { string_value: ""string"" }
|
||||
}
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
private const string face_detection_short_range_common_config_text = @"
|
||||
input_stream: ""detection_tensors""
|
||||
input_stream: ""transform_matrix""
|
||||
|
||||
node {
|
||||
calculator: ""FaceDetectionShortRangeCommon""
|
||||
input_stream: ""TENSORS:detection_tensors""
|
||||
input_stream: ""MATRIX:transform_matrix""
|
||||
output_stream: ""DETECTIONS:detections""
|
||||
}
|
||||
";
|
||||
|
||||
#region Constructor
|
||||
[Test]
|
||||
public void Ctor_ShouldInstantiateValidatedGraphConfig()
|
||||
{
|
||||
Assert.DoesNotThrow(() =>
|
||||
{
|
||||
var config = new ValidatedGraphConfig();
|
||||
config.Dispose();
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #IsDisposed
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnFalse_When_NotDisposedYet()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.False(config.IsDisposed);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDisposed_ShouldReturnTrue_When_AlreadyDisposed()
|
||||
{
|
||||
var config = new ValidatedGraphConfig();
|
||||
config.Dispose();
|
||||
|
||||
Assert.True(config.IsDisposed);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #Initialize
|
||||
[Test]
|
||||
public void Initialize_ShouldReturnOk_When_CalledWithConfig()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
using (var status = config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
Assert.True(config.Initialized());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Initialize_ShouldReturnOk_When_CalledWithValidGraphType()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
using (var status = config.Initialize("SwitchContainer"))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
Assert.True(config.Initialized());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Initialize_ShouldReturnInternalError_When_CalledWithInvalidGraphType()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
using (var status = config.Initialize("InvalidSubgraph"))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.NotFound, status.Code);
|
||||
}
|
||||
Assert.False(config.Initialized());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region #ValidateRequiredSidePackets
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnOk_When_TheConfigDoesNotRequireSidePackets_And_SidePacketIsEmpty()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnOk_When_TheConfigDoesNotRequireSidePackets_And_SidePacketIsNotEmpty()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
sidePackets.Emplace("in", PacketFactory.IntPacket(0));
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnOk_When_AllTheSidePacketsAreOptional_And_SidePacketIsEmpty()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(flow_limiter_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnInvalidArgumentError_When_TheConfigRequiresSidePackets_And_SidePacketIsEmpty()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(image_transformation_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.InvalidArgument, status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnInvalidArgumentError_When_AllTheRequiredSidePacketsAreNotGiven()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(image_transformation_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
sidePackets.Emplace("input_horizontally_flipped", PacketFactory.BoolPacket(false));
|
||||
sidePackets.Emplace("input_vertically_flipped", PacketFactory.BoolPacket(true));
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.InvalidArgument, status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnInvalidArgumentError_When_TheSidePacketValuesAreWrong()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(image_transformation_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
sidePackets.Emplace("input_horizontally_flipped", PacketFactory.BoolPacket(false));
|
||||
sidePackets.Emplace("input_vertically_flipped", PacketFactory.BoolPacket(true));
|
||||
sidePackets.Emplace("input_rotation", PacketFactory.StringPacket("0"));
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.InvalidArgument, status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValidateRequiredSidePackets_ShouldReturnOk_When_AllTheRequiredSidePacketsAreGiven()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(image_transformation_config_text)).AssertOk();
|
||||
using (var sidePackets = new SidePackets())
|
||||
{
|
||||
sidePackets.Emplace("input_horizontally_flipped", PacketFactory.BoolPacket(false));
|
||||
sidePackets.Emplace("input_vertically_flipped", PacketFactory.BoolPacket(true));
|
||||
sidePackets.Emplace("input_rotation", PacketFactory.IntPacket(0));
|
||||
using (var status = config.ValidateRequiredSidePackets(sidePackets))
|
||||
{
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Config
|
||||
[Test]
|
||||
public void Config_ShouldReturnAnEmptyConfig_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
var canonicalizedConfig = config.Config();
|
||||
Assert.AreEqual(canonicalizedConfig.CalculateSize(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Config_ShouldReturnTheCanonicalizedConfig_When_TheConfigIsPassThroughConfig()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
var originalConfig = CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text);
|
||||
config.Initialize(originalConfig).AssertOk();
|
||||
var canonicalizedConfig = config.Config();
|
||||
|
||||
Assert.AreEqual(originalConfig.Node, canonicalizedConfig.Node);
|
||||
Assert.AreEqual(originalConfig.InputStream, canonicalizedConfig.InputStream);
|
||||
Assert.AreEqual(originalConfig.OutputStream, canonicalizedConfig.OutputStream);
|
||||
Assert.IsEmpty(originalConfig.Executor);
|
||||
Assert.AreEqual(1, canonicalizedConfig.Executor.Count);
|
||||
Assert.AreEqual(0, canonicalizedConfig.Executor[0].CalculateSize());
|
||||
|
||||
Assert.AreEqual(80, originalConfig.CalculateSize());
|
||||
Assert.AreEqual(82, canonicalizedConfig.CalculateSize());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Config_ShouldReturnTheCanonicalizedConfig_When_TheConfigIsFaceDetectionShortRangeCommonConfig()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
var originalConfig = CalculatorGraphConfig.Parser.ParseFromTextFormat(face_detection_short_range_common_config_text);
|
||||
config.Initialize(originalConfig).AssertOk();
|
||||
var canonicalizedConfig = config.Config();
|
||||
|
||||
Assert.AreEqual(145, originalConfig.CalculateSize());
|
||||
Assert.AreEqual(936, canonicalizedConfig.CalculateSize());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InputStreamInfos
|
||||
[Test]
|
||||
public void InputStreamInfos_ShouldReturnEmptyList_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.IsEmpty(config.InputStreamInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InputStreamInfos_ShouldReturnEmptyList_When_NoInputStreamExists()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(constant_side_packet_config_text)).AssertOk();
|
||||
Assert.IsEmpty(config.InputStreamInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InputStreamInfos_ShouldReturnEdgeInfoList_When_InputStreamsExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
var inputStreamInfos = config.InputStreamInfos();
|
||||
|
||||
Assert.AreEqual(inputStreamInfos.Count, 2);
|
||||
|
||||
var inStream = inputStreamInfos.First((edgeInfo) => edgeInfo.Name == "in");
|
||||
Assert.AreEqual(0, inStream.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, inStream.ParentNode.Type);
|
||||
Assert.AreEqual(0, inStream.ParentNode.Index);
|
||||
Assert.False(inStream.BackEdge);
|
||||
|
||||
var out1Stream = inputStreamInfos.First((edgeInfo) => edgeInfo.Name == "out1");
|
||||
Assert.AreEqual(1, out1Stream.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, out1Stream.ParentNode.Type);
|
||||
Assert.AreEqual(1, out1Stream.ParentNode.Index);
|
||||
Assert.False(out1Stream.BackEdge);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OutputStreamInfos
|
||||
[Test]
|
||||
public void OutputStreamInfos_ShouldReturnEmptyList_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.IsEmpty(config.OutputStreamInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamInfos_ShouldReturnEdgeInfoList_When_OutputStreamsExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
var outputStreamInfos = config.OutputStreamInfos();
|
||||
|
||||
Assert.AreEqual(3, outputStreamInfos.Count);
|
||||
|
||||
var inStream = outputStreamInfos.First((edgeInfo) => edgeInfo.Name == "in");
|
||||
Assert.AreEqual(-1, inStream.Upstream);
|
||||
Assert.AreEqual(NodeType.GraphInputStream, inStream.ParentNode.Type);
|
||||
Assert.AreEqual(2, inStream.ParentNode.Index, 2);
|
||||
Assert.False(inStream.BackEdge);
|
||||
|
||||
var out1Stream = outputStreamInfos.First((edgeInfo) => edgeInfo.Name == "out1");
|
||||
Assert.AreEqual(-1, out1Stream.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, out1Stream.ParentNode.Type);
|
||||
Assert.AreEqual(0, out1Stream.ParentNode.Index);
|
||||
Assert.False(out1Stream.BackEdge);
|
||||
|
||||
var outStream = outputStreamInfos.First((edgeInfo) => edgeInfo.Name == "out");
|
||||
Assert.AreEqual(-1, outStream.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, outStream.ParentNode.Type);
|
||||
Assert.AreEqual(1, outStream.ParentNode.Index);
|
||||
Assert.False(outStream.BackEdge);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InputSidePacketInfos
|
||||
[Test]
|
||||
public void InputSidePacketInfos_ShouldReturnEmptyList_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.IsEmpty(config.InputSidePacketInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InputSidePacketInfos_ShouldReturnEmptyList_When_NoInputSidePacketExists()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.IsEmpty(config.InputSidePacketInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InputSidePacketInfos_ShouldReturnEdgeInfoList_When_InputSidePacketsExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(flow_limiter_config_text)).AssertOk();
|
||||
var inputSidePacketInfos = config.InputSidePacketInfos();
|
||||
|
||||
Assert.True(inputSidePacketInfos.Count >= 2);
|
||||
|
||||
var maxInFlightPacket = inputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "max_in_flight");
|
||||
Assert.AreEqual(-1, maxInFlightPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, maxInFlightPacket.ParentNode.Type);
|
||||
Assert.False(maxInFlightPacket.BackEdge);
|
||||
|
||||
var flowLimiterCalculatorOptionsPacket = inputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "flow_limiter_calculator_options");
|
||||
Assert.AreEqual(-1, flowLimiterCalculatorOptionsPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, flowLimiterCalculatorOptionsPacket.ParentNode.Type);
|
||||
Assert.False(flowLimiterCalculatorOptionsPacket.BackEdge);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OutputSidePacketInfos
|
||||
[Test]
|
||||
public void OutputSidePacketInfos_ShouldReturnEmptyList_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.IsEmpty(config.OutputSidePacketInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputSidePacketInfos_ShouldReturnEmptyList_When_NoOutputSidePacketExists()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.IsEmpty(config.OutputSidePacketInfos());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputSidePacketInfos_ShouldReturnEdgeInfoList_When_OutputSidePacketsExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(constant_side_packet_config_text)).AssertOk();
|
||||
var outputSidePacketInfos = config.OutputSidePacketInfos();
|
||||
|
||||
Assert.AreEqual(4, outputSidePacketInfos.Count);
|
||||
|
||||
var intPacket = outputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "int_packet");
|
||||
Assert.AreEqual(-1, intPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, intPacket.ParentNode.Type);
|
||||
Assert.False(intPacket.BackEdge);
|
||||
|
||||
var floatPacket = outputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "float_packet");
|
||||
Assert.AreEqual(-1, floatPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, floatPacket.ParentNode.Type);
|
||||
Assert.False(floatPacket.BackEdge);
|
||||
|
||||
var boolPacket = outputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "bool_packet");
|
||||
Assert.AreEqual(-1, boolPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, boolPacket.ParentNode.Type);
|
||||
Assert.False(boolPacket.BackEdge);
|
||||
|
||||
var stringPacket = outputSidePacketInfos.First((edgeInfo) => edgeInfo.Name == "string_packet");
|
||||
Assert.AreEqual(-1, stringPacket.Upstream);
|
||||
Assert.AreEqual(NodeType.Calculator, stringPacket.ParentNode.Type);
|
||||
Assert.False(stringPacket.BackEdge);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OutputStreamIndex
|
||||
[Test]
|
||||
public void OutputStreamIndex_ShouldReturnNegativeValue_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.AreEqual(-1, config.OutputStreamIndex(""));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamIndex_ShouldReturnNegativeValue_When_TheNameIsInvalid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.AreEqual(-1, config.OutputStreamIndex("unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamIndex_ShouldReturnIndex_When_TheNameIsValid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.AreEqual(2, config.OutputStreamIndex("out"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamIndex_ShouldReturnIndex_When_TheStreamIsNotPublic()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.AreEqual(1, config.OutputStreamIndex("out1"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OutputSidePacketIndex
|
||||
[Test]
|
||||
public void OutputSidePacketIndex_ShouldReturnNegativeValue_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.AreEqual(-1, config.OutputSidePacketIndex(""));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputSidePacketIndex_ShouldReturnNegativeValue_When_TheNameIsInvalid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(constant_side_packet_config_text)).AssertOk();
|
||||
Assert.AreEqual(-1, config.OutputSidePacketIndex("unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputSidePacketIndex_ShouldReturnIndex_When_TheNameIsValid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(constant_side_packet_config_text)).AssertOk();
|
||||
Assert.AreEqual(0, config.OutputSidePacketIndex("int_packet"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region OutputStreamToNode
|
||||
[Test]
|
||||
public void OutputStreamToNode_ShouldReturnNegativeValue_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.AreEqual(-1, config.OutputStreamToNode(""));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamToNode_ShouldReturnNegativeValue_When_TheNameIsInvalid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.AreEqual(-1, config.OutputStreamToNode("unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OutputStreamToNode_ShouldReturnIndex_When_TheNameIsValid()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.AreEqual(0, config.OutputStreamToNode("out1"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RegisteredSidePacketTypeName
|
||||
[Test]
|
||||
public void RegisteredSidePacketTypeName_ShouldReturnInvalidArgumentError_When_TheSidePacketDoesNotExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
using (var statusOrString = config.RegisteredSidePacketTypeName("max_in_flight"))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.InvalidArgument, statusOrString.Status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisteredSidePacketTypeName_ShouldReturnUnknownError_When_TheSidePacketTypeCannotBeDetermined()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(flow_limiter_config_text)).AssertOk();
|
||||
using (var statusOrString = config.RegisteredSidePacketTypeName("max_in_flight"))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.Unknown, statusOrString.Status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RegisteredStreamTypeName
|
||||
[Test]
|
||||
public void RegisteredStreamTypeName_ShouldReturnInvalidArgumentError_When_TheStreamDoesNotExist()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
using (var statusOrString = config.RegisteredStreamTypeName("in"))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.InvalidArgument, statusOrString.Status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisteredStreamTypeName_ShouldReturnUnknownError_When_TheStreamTypeCannotBeDetermined()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
using (var statusOrString = config.RegisteredStreamTypeName("in"))
|
||||
{
|
||||
Assert.AreEqual(Status.StatusCode.Unknown, statusOrString.Status.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Package
|
||||
[Test]
|
||||
public void Package_ShouldReturnNull_When_NotInitialized()
|
||||
{
|
||||
using var config = new ValidatedGraphConfig();
|
||||
Assert.IsNull(config.Package());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Package_ShouldReturnNull_When_TheNamespaceIsNotSet()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(pass_through_config_text)).AssertOk();
|
||||
Assert.IsNull(config.Package());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IsReservedExecutorName
|
||||
[Test]
|
||||
public void IsReservedExecutorName_ShouldReturnFalse_When_TheNameIsNotReserved()
|
||||
{
|
||||
Assert.False(ValidatedGraphConfig.IsReservedExecutorName("unknown"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsReservedExecutorName_ShouldReturnFalse_When_TheNameIsReserved()
|
||||
{
|
||||
Assert.True(ValidatedGraphConfig.IsReservedExecutorName("default"));
|
||||
Assert.True(ValidatedGraphConfig.IsReservedExecutorName("gpu"));
|
||||
Assert.True(ValidatedGraphConfig.IsReservedExecutorName("__gpu"));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IsExternalSidePacket
|
||||
[Test]
|
||||
public void IsExternalSidePacket_ShouldReturnFalse_When_NotInitialized()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
Assert.False(config.IsExternalSidePacket("max_in_flight"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void IsExternalSidePacket_ShouldReturnFalse_When_TheSidePacketIsInternal()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(constant_side_packet_config_text)).AssertOk();
|
||||
Assert.False(config.IsExternalSidePacket("int_packet"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsExternalSidePacket_ShouldReturnTrue_When_TheSidePacketIsExternal()
|
||||
{
|
||||
using (var config = new ValidatedGraphConfig())
|
||||
{
|
||||
config.Initialize(CalculatorGraphConfig.Parser.ParseFromTextFormat(flow_limiter_config_text)).AssertOk();
|
||||
Assert.True(config.IsExternalSidePacket("max_in_flight"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Gpu;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Internal;
|
||||
@ -61,31 +62,18 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
var status = glCalculatorHelper.RunInGlContext(() => { return Status.Ok(); });
|
||||
Status status = glCalculatorHelper.RunInGlContext(() => { });
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
|
||||
[Test, GpuOnly]
|
||||
public void RunInGlContext_ShouldReturnInternal_When_FunctionReturnsInternal()
|
||||
public void RunInGlContext_ShouldReturnInternal_When_FunctionThrows()
|
||||
{
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
var status = glCalculatorHelper.RunInGlContext(() => { return Status.Build(Status.StatusCode.Internal, "error"); });
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.Internal);
|
||||
}
|
||||
|
||||
[Test, GpuOnly]
|
||||
public void RunInGlContext_ShouldReturnFailedPreCondition_When_FunctionThrows()
|
||||
{
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
#pragma warning disable IDE0039
|
||||
GlCalculatorHelper.GlStatusFunction glStatusFunction = () => { throw new InvalidProgramException(); };
|
||||
#pragma warning restore IDE0039
|
||||
var status = glCalculatorHelper.RunInGlContext(glStatusFunction);
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.FailedPrecondition);
|
||||
Status status = glCalculatorHelper.RunInGlContext((GlCalculatorHelper.GlFunction)(() => { throw new Exception("Function Throws"); }));
|
||||
Assert.AreEqual(Status.StatusCode.Internal, status.Code);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -96,16 +84,15 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Srgba, 32, 24);
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Srgba, 32, 24);
|
||||
var status = glCalculatorHelper.RunInGlContext(() =>
|
||||
{
|
||||
var texture = glCalculatorHelper.CreateSourceTexture(imageFrame);
|
||||
|
||||
Assert.AreEqual(texture.Width, 32);
|
||||
Assert.AreEqual(texture.Height, 24);
|
||||
Assert.AreEqual(32, texture.Width);
|
||||
Assert.AreEqual(24, texture.Height);
|
||||
|
||||
texture.Dispose();
|
||||
return Status.Ok();
|
||||
});
|
||||
Assert.True(status.Ok());
|
||||
|
||||
@ -113,21 +100,19 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
}
|
||||
|
||||
[Test, GpuOnly]
|
||||
[Ignore("Skip because a thread will hang")]
|
||||
public void CreateSourceTexture_ShouldFail_When_ImageFrameFormatIsInvalid()
|
||||
{
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Sbgra, 32, 24);
|
||||
var status = glCalculatorHelper.RunInGlContext(() =>
|
||||
{
|
||||
using (var texture = glCalculatorHelper.CreateSourceTexture(imageFrame))
|
||||
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 32, 24);
|
||||
Status status = glCalculatorHelper.RunInGlContext(() =>
|
||||
{
|
||||
using GlTexture texture = glCalculatorHelper.CreateSourceTexture(imageFrame);
|
||||
texture.Release();
|
||||
}
|
||||
return Status.Ok();
|
||||
});
|
||||
Assert.AreEqual(status.Code, Status.StatusCode.FailedPrecondition);
|
||||
Assert.AreEqual(Status.StatusCode.FailedPrecondition, status.Code);
|
||||
|
||||
status.Dispose();
|
||||
}
|
||||
@ -140,20 +125,19 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
using var glCalculatorHelper = new GlCalculatorHelper();
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
var status = glCalculatorHelper.RunInGlContext(() =>
|
||||
Status status = glCalculatorHelper.RunInGlContext(() =>
|
||||
{
|
||||
var glTexture = glCalculatorHelper.CreateDestinationTexture(32, 24, GpuBufferFormat.KBgra32);
|
||||
GlTexture glTexture = glCalculatorHelper.CreateDestinationTexture(32, 24, GpuBufferFormat.KBgra32);
|
||||
|
||||
Assert.AreEqual(glTexture.Width, 32);
|
||||
Assert.AreEqual(glTexture.Height, 24);
|
||||
return Status.Ok();
|
||||
Assert.AreEqual(32, glTexture.Width);
|
||||
Assert.AreEqual(24, glTexture.Height);
|
||||
});
|
||||
|
||||
Assert.True(status.Ok());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Framebuffer
|
||||
#region framebuffer
|
||||
[Test, GpuOnly]
|
||||
public void Framebuffer_ShouldReturnGLName()
|
||||
{
|
||||
@ -161,7 +145,7 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
glCalculatorHelper.InitializeForTest(GpuResources.Create().Value());
|
||||
|
||||
// default frame buffer
|
||||
Assert.AreEqual(glCalculatorHelper.Framebuffer, 0);
|
||||
Assert.AreEqual(0, glCalculatorHelper.Framebuffer);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Gpu;
|
||||
using NUnit.Framework;
|
||||
|
||||
@ -28,10 +27,9 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
|
||||
glCalculatorHelper.RunInGlContext(() =>
|
||||
{
|
||||
using var glContext = GlContext.GetCurrent();
|
||||
using GlContext? glContext = GlContext.GetCurrent();
|
||||
Assert.NotNull(glContext);
|
||||
Assert.True(glContext?.IsCurrent());
|
||||
return Status.Ok();
|
||||
}).AssertOk();
|
||||
}
|
||||
#endregion
|
||||
@ -56,9 +54,9 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
Assert.True(glContext.EglDisplay != null);
|
||||
Assert.True(glContext.EglConfig != null);
|
||||
Assert.True(glContext.EglContext != null);
|
||||
Assert.AreEqual(glContext.GlMajorVersion, 3);
|
||||
Assert.AreEqual(glContext.GlMinorVersion, 2);
|
||||
Assert.AreEqual(glContext.GlFinishCount, 0);
|
||||
Assert.AreEqual(3, glContext.GlMajorVersion);
|
||||
Assert.AreEqual(2, glContext.GlMinorVersion);
|
||||
Assert.AreEqual(0, glContext.GlFinishCount);
|
||||
}
|
||||
else if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
|
@ -14,8 +14,8 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
public void Ctor_ShouldInstantiateGlTexture_When_CalledWithNoArguments()
|
||||
{
|
||||
using var glTexture = new GlTexture();
|
||||
Assert.AreEqual(glTexture.Width, 0);
|
||||
Assert.AreEqual(glTexture.Height, 0);
|
||||
Assert.AreEqual(0, glTexture.Width);
|
||||
Assert.AreEqual(0, glTexture.Height);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Mediapipe.Net.Tests.Gpu
|
||||
public void Target_ShouldReturnTarget()
|
||||
{
|
||||
using var glTexture = new GlTexture();
|
||||
Assert.AreEqual(glTexture.Target, Gl.GL_TEXTURE_2D);
|
||||
Assert.AreEqual(Gl.GL_TEXTURE_2D, glTexture.Target);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -9,9 +9,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Package references">
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="0.8.9" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="0.8.9.1" />
|
||||
<!-- <PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="0.8.9.1" /> -->
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="1.0.0-alpha2" />
|
||||
<PackageReference Include="Mediapipe.Net.Runtime.CPU" Version="1.0.0-alpha2" />
|
||||
<!-- <PackageReference Include="Mediapipe.Net.Runtime.GPU" Version="1.0.0-alpha2" /> -->
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
|
@ -10,7 +10,17 @@ namespace Mediapipe.Net.Core
|
||||
{
|
||||
public unsafe abstract class MpResourceHandle : Disposable, IMpResourceHandle
|
||||
{
|
||||
protected void* Ptr;
|
||||
private void* ptr = null;
|
||||
protected void* Ptr
|
||||
{
|
||||
get => ptr;
|
||||
set
|
||||
{
|
||||
if (value != null && OwnsResource)
|
||||
throw new InvalidOperationException($"This object owns another resource");
|
||||
ptr = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected MpResourceHandle(bool isOwner = true) : this(null, isOwner) { }
|
||||
|
||||
@ -34,10 +44,12 @@ namespace Mediapipe.Net.Core
|
||||
if (OwnsResource)
|
||||
DeleteMpPtr();
|
||||
|
||||
ReleaseMpPtr();
|
||||
TransferOwnership();
|
||||
}
|
||||
|
||||
public bool OwnsResource => IsOwner && Ptr != null;
|
||||
protected bool IsResourcePresent => Ptr != null;
|
||||
public bool OwnsResource => IsOwner && IsResourcePresent;
|
||||
#endregion
|
||||
|
||||
protected override void DisposeUnmanaged()
|
||||
@ -62,11 +74,14 @@ namespace Mediapipe.Net.Core
|
||||
protected abstract void DeleteMpPtr();
|
||||
|
||||
protected delegate MpReturnCode StringOutFunc(void* ptr, out sbyte* strPtr);
|
||||
protected string MarshalStringFromNative(StringOutFunc func)
|
||||
protected string? MarshalStringFromNative(StringOutFunc func)
|
||||
{
|
||||
func(MpPtr, out sbyte* strPtr).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
if (strPtr == null)
|
||||
return null;
|
||||
|
||||
string str = new string(strPtr);
|
||||
UnsafeNativeMethods.delete_array__PKc(strPtr);
|
||||
|
||||
|
42
Mediapipe.Net/External/Protobuf.cs
vendored
42
Mediapipe.Net/External/Protobuf.cs
vendored
@ -2,11 +2,47 @@
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
namespace Mediapipe.Net.External
|
||||
{
|
||||
internal static class Protobuf
|
||||
public static class Protobuf
|
||||
{
|
||||
public delegate void ProtobufLogHandler(int level, string filename, int line, string message);
|
||||
// TODO: (from homuler) Overwrite protobuf logger to show logs in Console Window.
|
||||
public delegate void LogHandler(int level, string filename, int line, string message);
|
||||
public static readonly LogHandler DefaultLogHandler = logProtobufMessage;
|
||||
|
||||
public static void SetLogHandler(LogHandler logHandler)
|
||||
{
|
||||
UnsafeNativeMethods.google_protobuf__SetLogHandler__PF(logHandler).Assert();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the <see cref="LogHandler" />.
|
||||
/// If <see cref="SetLogHandler" /> is called, this method should be called before the program exits.
|
||||
/// </summary>
|
||||
public static void ResetLogHandler()
|
||||
{
|
||||
UnsafeNativeMethods.google_protobuf__ResetLogHandler().Assert();
|
||||
}
|
||||
|
||||
private static void logProtobufMessage(int level, string filename, int line, string message)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
Console.Error.WriteLine($"[libprotobuf WARN {filename}:{line}] {message}");
|
||||
break;
|
||||
case 2:
|
||||
Console.Error.WriteLine($"[libprotobuf ERROR {filename}:{line}] {message}");
|
||||
break;
|
||||
case 3:
|
||||
Console.Error.WriteLine($"[libprotobuf FATAL {filename}:{line}] {message}");
|
||||
break;
|
||||
default:
|
||||
Console.Error.WriteLine($"[libprotobuf INFO {filename}:{line}] {message}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
Mediapipe.Net/External/SerializedProto.cs
vendored
6
Mediapipe.Net/External/SerializedProto.cs
vendored
@ -10,10 +10,10 @@ using Mediapipe.Net.Util;
|
||||
namespace Mediapipe.Net.External
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct SerializedProto
|
||||
internal unsafe readonly struct SerializedProto
|
||||
{
|
||||
public sbyte* StrPtr;
|
||||
public int Length;
|
||||
public readonly sbyte* StrPtr;
|
||||
public readonly int Length;
|
||||
|
||||
// TODO: That Dispose() method is looking very sus...
|
||||
// Might wanna investigate if it's better as a child of Disposable.
|
||||
|
16
Mediapipe.Net/External/SerializedProtoVector.cs
vendored
16
Mediapipe.Net/External/SerializedProtoVector.cs
vendored
@ -10,19 +10,13 @@ using Mediapipe.Net.Native;
|
||||
namespace Mediapipe.Net.External
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct SerializedProtoVector
|
||||
internal unsafe readonly struct SerializedProtoVector
|
||||
{
|
||||
public SerializedProto* Data;
|
||||
public int Size;
|
||||
public readonly SerializedProto* Data;
|
||||
public readonly int Size;
|
||||
|
||||
// TODO: This is looking just as sus as SerializedProto.Dispose().
|
||||
// Should be investigated in the same way.
|
||||
public void Dispose()
|
||||
{
|
||||
for (int i = 0; i < Size; i++)
|
||||
Data[i].Dispose();
|
||||
UnsafeNativeMethods.mp_api_SerializedProtoArray__delete(Data);
|
||||
}
|
||||
// The array element freeing loop has been moved to MediaPipe.NET.Runtime.
|
||||
public void Dispose() => UnsafeNativeMethods.mp_api_SerializedProtoArray__delete(Data, Size);
|
||||
|
||||
public List<T> Deserialize<T>(MessageParser<T> parser) where T : IMessage<T>
|
||||
{
|
||||
|
@ -17,8 +17,8 @@ namespace Mediapipe.Net.Framework
|
||||
{
|
||||
public unsafe class CalculatorGraph : MpResourceHandle
|
||||
{
|
||||
public delegate void* NativePacketCallback(void* graphPtr, void* packetPtr);
|
||||
public delegate Status PacketCallback(Packet packet);
|
||||
public delegate Status.StatusArgs NativePacketCallback(void* graphPtr, int streamId, void* packetPtr);
|
||||
public delegate void PacketCallback(Packet packet);
|
||||
|
||||
public CalculatorGraph() : base()
|
||||
{
|
||||
@ -26,13 +26,7 @@ namespace Mediapipe.Net.Framework
|
||||
Ptr = ptr;
|
||||
}
|
||||
|
||||
public CalculatorGraph(string textFormatConfig) : base()
|
||||
{
|
||||
UnsafeNativeMethods.mp_CalculatorGraph__PKc(textFormatConfig, out var ptr).Assert();
|
||||
Ptr = ptr;
|
||||
}
|
||||
|
||||
public CalculatorGraph(byte[] serializedConfig) : base()
|
||||
private CalculatorGraph(byte[] serializedConfig) : base()
|
||||
{
|
||||
UnsafeNativeMethods.mp_CalculatorGraph__PKc_i(serializedConfig, serializedConfig.Length, out var ptr).Assert();
|
||||
Ptr = ptr;
|
||||
@ -40,6 +34,8 @@ namespace Mediapipe.Net.Framework
|
||||
|
||||
public CalculatorGraph(CalculatorGraphConfig config) : this(config.ToByteArray()) { }
|
||||
|
||||
public CalculatorGraph(string textFormatConfig) : this(CalculatorGraphConfig.Parser.ParseFromTextFormat(textFormatConfig)) { }
|
||||
|
||||
protected override void DeleteMpPtr() => UnsafeNativeMethods.mp_CalculatorGraph__delete(Ptr);
|
||||
|
||||
public Status Initialize(CalculatorGraphConfig config)
|
||||
@ -72,9 +68,9 @@ namespace Mediapipe.Net.Framework
|
||||
return config;
|
||||
}
|
||||
|
||||
public Status ObserveOutputStream(string streamName, NativePacketCallback nativePacketCallback, bool observeTimestampBounds = false)
|
||||
public Status ObserveOutputStream(string streamName, int streamId, NativePacketCallback nativePacketCallback, bool observeTimestampBounds = false)
|
||||
{
|
||||
UnsafeNativeMethods.mp_CalculatorGraph__ObserveOutputStream__PKc_PF_b(MpPtr, streamName, nativePacketCallback, observeTimestampBounds, out var statusPtr).Assert();
|
||||
UnsafeNativeMethods.mp_CalculatorGraph__ObserveOutputStream__PKc_PF_b(MpPtr, streamName, streamId, nativePacketCallback, observeTimestampBounds, out var statusPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new Status(statusPtr);
|
||||
@ -82,24 +78,25 @@ namespace Mediapipe.Net.Framework
|
||||
|
||||
public Status ObserveOutputStream(string streamName, PacketCallback packetCallback, bool observeTimestampBounds, out GCHandle callbackHandle)
|
||||
{
|
||||
NativePacketCallback nativePacketCallback = (_, packetPtr) =>
|
||||
NativePacketCallback nativePacketCallback = (void* graphPtr, int streamId, void* packetPtr) =>
|
||||
{
|
||||
Status status;
|
||||
try
|
||||
{
|
||||
Packet packet = new Packet(packetPtr, false);
|
||||
status = packetCallback(packet);
|
||||
packetCallback(packet);
|
||||
// This packet is not being disposed in MediaPipeUnityPlugin?
|
||||
packet.Dispose();
|
||||
return Status.StatusArgs.Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = Status.FailedPrecondition(e.ToString());
|
||||
return Status.StatusArgs.Internal(e.ToString());
|
||||
}
|
||||
return status.MpPtr;
|
||||
};
|
||||
callbackHandle = GCHandle.Alloc(nativePacketCallback, GCHandleType.Normal);
|
||||
|
||||
return ObserveOutputStream(streamName, nativePacketCallback, observeTimestampBounds);
|
||||
// Thought: why have a streamId at all if we just put 0 in there?
|
||||
return ObserveOutputStream(streamName, 0, nativePacketCallback, observeTimestampBounds);
|
||||
}
|
||||
|
||||
public Status ObserveOutputStream(string streamName, PacketCallback packetCallback, out GCHandle callbackHandle)
|
||||
|
@ -1,23 +0,0 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
namespace Mediapipe.Net.Framework.Format
|
||||
{
|
||||
public enum ImageFormat : int
|
||||
{
|
||||
Unknown = 0,
|
||||
Srgb = 1,
|
||||
Srgba = 2,
|
||||
Gray8 = 3,
|
||||
Gray16 = 4,
|
||||
Ycbcr420p = 5,
|
||||
Ycbcr420p10 = 6,
|
||||
Srgb48 = 7,
|
||||
Srgba64 = 8,
|
||||
Vec32f1 = 9,
|
||||
Vec32f2 = 12,
|
||||
Lab8 = 10,
|
||||
Sbgra = 11,
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
namespace Mediapipe.Net.Framework.Format
|
||||
@ -22,15 +22,15 @@ namespace Mediapipe.Net.Framework.Format
|
||||
|
||||
public ImageFrame(void* imageFramePtr, bool isOwner = true) : base(imageFramePtr, isOwner) { }
|
||||
|
||||
public ImageFrame(ImageFormat format, int width, int height) : this(format, width, height, DefaultAlignmentBoundary) { }
|
||||
public ImageFrame(ImageFormat.Types.Format format, int width, int height) : this(format, width, height, DefaultAlignmentBoundary) { }
|
||||
|
||||
public ImageFrame(ImageFormat format, int width, int height, uint alignmentBoundary) : base()
|
||||
public ImageFrame(ImageFormat.Types.Format format, int width, int height, uint alignmentBoundary) : base()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ImageFrame__ui_i_i_ui(format, width, height, alignmentBoundary, out var ptr).Assert();
|
||||
Ptr = ptr;
|
||||
}
|
||||
|
||||
public unsafe ImageFrame(ImageFormat format, int width, int height, int widthStep, byte[] pixelData) : base()
|
||||
public unsafe ImageFrame(ImageFormat.Types.Format format, int width, int height, int widthStep, byte[] pixelData) : base()
|
||||
{
|
||||
fixed (byte* pixelDataPtr = pixelData)
|
||||
{
|
||||
@ -42,7 +42,7 @@ namespace Mediapipe.Net.Framework.Format
|
||||
}
|
||||
}
|
||||
|
||||
public ImageFrame(ImageFormat format, int width, int height, int widthStep, ReadOnlySpan<byte> pixelData) : base()
|
||||
public ImageFrame(ImageFormat.Types.Format format, int width, int height, int widthStep, ReadOnlySpan<byte> pixelData) : base()
|
||||
{
|
||||
fixed (byte* pixelDataPtr = pixelData)
|
||||
{
|
||||
@ -56,6 +56,111 @@ namespace Mediapipe.Net.Framework.Format
|
||||
|
||||
protected override void DeleteMpPtr() => UnsafeNativeMethods.mp_ImageFrame__delete(Ptr);
|
||||
|
||||
/// <returns>
|
||||
/// The number of channels for a <paramref name="format" />.
|
||||
/// If channels don't make sense in the <paramref name="format" />, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public static int NumberOfChannelsForFormat(ImageFormat.Types.Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.Types.Format.Srgb:
|
||||
case ImageFormat.Types.Format.Srgb48:
|
||||
return 3;
|
||||
case ImageFormat.Types.Format.Srgba:
|
||||
case ImageFormat.Types.Format.Srgba64:
|
||||
case ImageFormat.Types.Format.Sbgra:
|
||||
return 4;
|
||||
case ImageFormat.Types.Format.Gray8:
|
||||
case ImageFormat.Types.Format.Gray16:
|
||||
return 1;
|
||||
case ImageFormat.Types.Format.Vec32F1:
|
||||
return 1;
|
||||
case ImageFormat.Types.Format.Vec32F2:
|
||||
return 2;
|
||||
case ImageFormat.Types.Format.Lab8:
|
||||
return 3;
|
||||
case ImageFormat.Types.Format.Ycbcr420P:
|
||||
case ImageFormat.Types.Format.Ycbcr420P10:
|
||||
case ImageFormat.Types.Format.Unknown:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// The channel size for a <paramref name="format" />.
|
||||
/// If channels don't make sense in the <paramref name="format" />, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public static int ChannelSizeForFormat(ImageFormat.Types.Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.Types.Format.Srgb:
|
||||
case ImageFormat.Types.Format.Srgba:
|
||||
case ImageFormat.Types.Format.Sbgra:
|
||||
return sizeof(byte);
|
||||
case ImageFormat.Types.Format.Srgb48:
|
||||
case ImageFormat.Types.Format.Srgba64:
|
||||
return sizeof(ushort);
|
||||
case ImageFormat.Types.Format.Gray8:
|
||||
return sizeof(byte);
|
||||
case ImageFormat.Types.Format.Gray16:
|
||||
return sizeof(ushort);
|
||||
case ImageFormat.Types.Format.Vec32F1:
|
||||
case ImageFormat.Types.Format.Vec32F2:
|
||||
// sizeof float may be wrong since it's platform-dependent, but we assume that it's constant across all supported platforms.
|
||||
return sizeof(float);
|
||||
case ImageFormat.Types.Format.Lab8:
|
||||
return sizeof(byte);
|
||||
case ImageFormat.Types.Format.Ycbcr420P:
|
||||
case ImageFormat.Types.Format.Ycbcr420P10:
|
||||
case ImageFormat.Types.Format.Unknown:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// The depth of each channel in bytes for a <paramref name="format" />.
|
||||
/// If channels don't make sense in the <paramref name="format" />, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public static int ByteDepthForFormat(ImageFormat.Types.Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.Types.Format.Srgb:
|
||||
case ImageFormat.Types.Format.Srgba:
|
||||
case ImageFormat.Types.Format.Sbgra:
|
||||
return 1;
|
||||
case ImageFormat.Types.Format.Srgb48:
|
||||
case ImageFormat.Types.Format.Srgba64:
|
||||
return 2;
|
||||
case ImageFormat.Types.Format.Gray8:
|
||||
return 1;
|
||||
case ImageFormat.Types.Format.Gray16:
|
||||
return 2;
|
||||
case ImageFormat.Types.Format.Vec32F1:
|
||||
case ImageFormat.Types.Format.Vec32F2:
|
||||
return 4;
|
||||
case ImageFormat.Types.Format.Lab8:
|
||||
return 1;
|
||||
case ImageFormat.Types.Format.Ycbcr420P:
|
||||
case ImageFormat.Types.Format.Ycbcr420P10:
|
||||
case ImageFormat.Types.Format.Unknown:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public bool IsEmpty => SafeNativeMethods.mp_ImageFrame__IsEmpty(MpPtr) > 0;
|
||||
|
||||
public bool IsContiguous => SafeNativeMethods.mp_ImageFrame__IsContiguous(MpPtr) > 0;
|
||||
@ -68,61 +173,46 @@ namespace Mediapipe.Net.Framework.Format
|
||||
return value;
|
||||
}
|
||||
|
||||
public ImageFormat Format => SafeNativeMethods.mp_ImageFrame__Format(MpPtr);
|
||||
public ImageFormat.Types.Format Format => SafeNativeMethods.mp_ImageFrame__Format(MpPtr);
|
||||
|
||||
public int Width => SafeNativeMethods.mp_ImageFrame__Width(MpPtr);
|
||||
|
||||
public int Height => SafeNativeMethods.mp_ImageFrame__Height(MpPtr);
|
||||
|
||||
public int ChannelSize
|
||||
{
|
||||
get
|
||||
{
|
||||
var code = SafeNativeMethods.mp_ImageFrame__ChannelSize(MpPtr, out var value);
|
||||
/// <returns>
|
||||
/// The channel size.
|
||||
/// If channels don't make sense, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public int ChannelSize => ChannelSizeForFormat(Format);
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return valueOrFormatException(code, value);
|
||||
}
|
||||
}
|
||||
/// <returns>
|
||||
/// The Number of channels.
|
||||
/// If channels don't make sense, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public int NumberOfChannels => NumberOfChannelsForFormat(Format);
|
||||
|
||||
public int NumberOfChannels
|
||||
{
|
||||
get
|
||||
{
|
||||
var code = SafeNativeMethods.mp_ImageFrame__NumberOfChannels(MpPtr, out var value);
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return valueOrFormatException(code, value);
|
||||
}
|
||||
}
|
||||
|
||||
public int ByteDepth
|
||||
{
|
||||
get
|
||||
{
|
||||
var code = SafeNativeMethods.mp_ImageFrame__ByteDepth(MpPtr, out var value);
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return valueOrFormatException(code, value);
|
||||
}
|
||||
}
|
||||
/// <returns>
|
||||
/// The depth of each image channel in bytes.
|
||||
/// If channels don't make sense, returns <c>0</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Unlike the original implementation, this API won't signal SIGABRT.
|
||||
/// </remarks>
|
||||
public int ByteDepth => ByteDepthForFormat(Format);
|
||||
|
||||
public int WidthStep => SafeNativeMethods.mp_ImageFrame__WidthStep(MpPtr);
|
||||
|
||||
public byte* MutablePixelData => SafeNativeMethods.mp_ImageFrame__MutablePixelData(MpPtr);
|
||||
|
||||
public int PixelDataSize => SafeNativeMethods.mp_ImageFrame__PixelDataSize(MpPtr);
|
||||
public int PixelDataSize => Height * WidthStep;
|
||||
|
||||
public int PixelDataSizeStoredContiguously
|
||||
{
|
||||
get
|
||||
{
|
||||
var code = SafeNativeMethods.mp_ImageFrame__PixelDataSizeStoredContiguously(MpPtr, out var value);
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return valueOrFormatException(code, value);
|
||||
}
|
||||
}
|
||||
public int PixelDataSizeStoredContiguously => Width * Height * ByteDepth * NumberOfChannels;
|
||||
|
||||
public void SetToZero()
|
||||
{
|
||||
@ -136,140 +226,30 @@ namespace Mediapipe.Net.Framework.Format
|
||||
GC.KeepAlive(this);
|
||||
}
|
||||
|
||||
public byte[] CopyToByteBuffer(int bufferSize)
|
||||
=> copyToBuffer<byte>(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pui8_i, bufferSize);
|
||||
public void CopyToBuffer(byte[] buffer)
|
||||
=> copyToBuffer(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pui8_i, buffer);
|
||||
|
||||
public ushort[] CopyToUshortBuffer(int bufferSize)
|
||||
=> copyToBuffer<ushort>(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pui16_i, bufferSize);
|
||||
public void CopyToBuffer(ushort[] buffer)
|
||||
=> copyToBuffer(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pui16_i, buffer);
|
||||
|
||||
public float[] CopyToFloatBuffer(int bufferSize)
|
||||
=> copyToBuffer<float>(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pf_i, bufferSize);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a specific channel only.
|
||||
/// It's useful when only one channel is used (e.g. Hair Segmentation mask).
|
||||
/// </summary>
|
||||
/// <param name="channelNumber">
|
||||
/// Specify from which channel the data will be retrieved.
|
||||
/// For example, if the format is RGB, 0 means R channel, 1 means G channel, and 2 means B channel.
|
||||
/// </param>
|
||||
/// <param name="colors" >
|
||||
/// The array to which the output data will be written.
|
||||
/// </param>
|
||||
public byte[] GetChannel(int channelNumber, bool flipVertically, byte[] colors)
|
||||
{
|
||||
var format = Format;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ImageFormat.Srgb:
|
||||
if (channelNumber < 0 || channelNumber > 3)
|
||||
throw new ArgumentException($"There are only 3 channels, but No. {channelNumber} is specified");
|
||||
readChannel(MutablePixelData, channelNumber, 3, Width, Height, WidthStep, flipVertically, colors);
|
||||
return colors;
|
||||
case ImageFormat.Srgba:
|
||||
if (channelNumber < 0 || channelNumber > 4)
|
||||
throw new ArgumentException($"There are only 4 channels, but No. {channelNumber} is specified");
|
||||
readChannel(MutablePixelData, channelNumber, 4, Width, Height, WidthStep, flipVertically, colors);
|
||||
return colors;
|
||||
default:
|
||||
throw new NotImplementedException($"Currently only SRGB and SRGBA format are supported: {format}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a specific channel only.
|
||||
/// It's useful when only one channel is used (e.g. Hair Segmentation mask).
|
||||
/// </summary>
|
||||
/// <param name="channelNumber">
|
||||
/// Specify from which channel the data will be retrieved.
|
||||
/// For example, if the format is RGB, 0 means R channel, 1 means G channel, and 2 means B channel.
|
||||
/// </param>
|
||||
public byte[] GetChannel(int channelNumber, bool flipVertically)
|
||||
=> GetChannel(channelNumber, flipVertically, new byte[Width * Height]);
|
||||
public void CopyToBuffer(float[] buffer)
|
||||
=> copyToBuffer(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pf_i, buffer);
|
||||
|
||||
private delegate MpReturnCode CopyToBufferHandler<T>(void* ptr, T* buffer, int bufferSize)
|
||||
where T : unmanaged;
|
||||
|
||||
private T[] copyToBuffer<T>(CopyToBufferHandler<T> handler, int bufferSize)
|
||||
private void copyToBuffer<T>(CopyToBufferHandler<T> handler, T[] buffer)
|
||||
where T : unmanaged
|
||||
{
|
||||
var buffer = new T[bufferSize];
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (T* bufferPtr = buffer)
|
||||
{
|
||||
handler(MpPtr, bufferPtr, bufferSize).Assert();
|
||||
handler(MpPtr, bufferPtr, buffer.Length).Assert();
|
||||
}
|
||||
}
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private T valueOrFormatException<T>(MpReturnCode code, T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
code.Assert();
|
||||
return value;
|
||||
}
|
||||
catch (MediapipeException)
|
||||
{
|
||||
throw new FormatException($"Invalid image format: {Format}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// In the source array, pixels are laid out left to right, top to bottom,
|
||||
/// but in the returned array, left to right, top to bottom.
|
||||
/// </remarks>
|
||||
private static void readChannel(byte* ptr, int channelNumber, int channelCount, int width, int height, int widthStep, bool flipVertically, byte[] colors)
|
||||
{
|
||||
if (colors.Length != width * height)
|
||||
throw new ArgumentException("colors length is invalid");
|
||||
var padding = widthStep - channelCount * width;
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* dest = colors)
|
||||
{
|
||||
var pSrc = ptr;
|
||||
pSrc += channelNumber;
|
||||
|
||||
if (flipVertically)
|
||||
{
|
||||
var pDest = dest + colors.Length - 1;
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
*pDest-- = *pSrc;
|
||||
pSrc += channelCount;
|
||||
}
|
||||
pSrc += padding;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var pDest = dest + width * (height - 1);
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
*pDest++ = *pSrc;
|
||||
pSrc += channelCount;
|
||||
}
|
||||
pSrc += padding;
|
||||
pDest -= 2 * width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +136,14 @@ namespace Mediapipe.Net.Framework.Packets
|
||||
GC.KeepAlive(this);
|
||||
return new StatusOrGpuBuffer(statusOrGpuBufferPtr);
|
||||
}
|
||||
|
||||
public StatusOr<string> ConsumeString()
|
||||
{
|
||||
UnsafeNativeMethods.mp_Packet__ConsumeString(MpPtr, out var statusOrStringPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new StatusOrString(statusOrStringPtr);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Validators
|
||||
|
@ -2,6 +2,8 @@
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
@ -30,6 +32,69 @@ namespace Mediapipe.Net.Framework.Port
|
||||
Unauthenticated = 16,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public readonly struct StatusArgs
|
||||
{
|
||||
private readonly StatusCode code;
|
||||
private readonly IntPtr message;
|
||||
|
||||
private StatusArgs(StatusCode code, string? message = null)
|
||||
{
|
||||
this.code = code;
|
||||
this.message = Marshal.StringToHGlobalAnsi(message);
|
||||
}
|
||||
|
||||
public static StatusArgs Ok() => new StatusArgs(StatusCode.Ok);
|
||||
|
||||
public static StatusArgs Cancelled(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Cancelled, message);
|
||||
|
||||
public static StatusArgs Unknown(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Unknown, message);
|
||||
|
||||
public static StatusArgs InvalidArgument(string? message = null)
|
||||
=> new StatusArgs(StatusCode.InvalidArgument, message);
|
||||
|
||||
public static StatusArgs DeadlineExceeded(string? message = null)
|
||||
=> new StatusArgs(StatusCode.DeadlineExceeded, message);
|
||||
|
||||
public static StatusArgs NotFound(string? message = null)
|
||||
=> new StatusArgs(StatusCode.NotFound, message);
|
||||
|
||||
public static StatusArgs AlreadyExists(string? message = null)
|
||||
=> new StatusArgs(StatusCode.AlreadyExists, message);
|
||||
|
||||
public static StatusArgs PermissionDenied(string? message = null)
|
||||
=> new StatusArgs(StatusCode.PermissionDenied, message);
|
||||
|
||||
public static StatusArgs ResourceExhausted(string? message = null)
|
||||
=> new StatusArgs(StatusCode.ResourceExhausted, message);
|
||||
|
||||
public static StatusArgs FailedPrecondition(string? message = null)
|
||||
=> new StatusArgs(StatusCode.FailedPrecondition, message);
|
||||
|
||||
public static StatusArgs Aborted(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Aborted, message);
|
||||
|
||||
public static StatusArgs OutOfRange(string? message = null)
|
||||
=> new StatusArgs(StatusCode.OutOfRange, message);
|
||||
|
||||
public static StatusArgs Unimplemented(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Unimplemented, message);
|
||||
|
||||
public static StatusArgs Internal(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Internal, message);
|
||||
|
||||
public static StatusArgs Unavailable(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Unavailable, message);
|
||||
|
||||
public static StatusArgs DataLoss(string? message = null)
|
||||
=> new StatusArgs(StatusCode.DataLoss, message);
|
||||
|
||||
public static StatusArgs Unauthenticated(string? message = null)
|
||||
=> new StatusArgs(StatusCode.Unauthenticated, message);
|
||||
}
|
||||
|
||||
public Status(void* ptr, bool isOwner = true) : base(ptr, isOwner) { }
|
||||
|
||||
protected override void DeleteMpPtr() => UnsafeNativeMethods.absl_Status__delete(Ptr);
|
||||
@ -76,7 +141,52 @@ namespace Mediapipe.Net.Framework.Port
|
||||
|
||||
public static Status Ok(bool isOwner = true) => Build(StatusCode.Ok, "", isOwner);
|
||||
|
||||
public static Status Cancelled(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Cancelled, message, isOwner);
|
||||
|
||||
public static Status Unknown(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Unknown, message, isOwner);
|
||||
|
||||
public static Status InvalidArgument(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.InvalidArgument, message, isOwner);
|
||||
|
||||
public static Status DeadlineExceeded(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.DeadlineExceeded, message, isOwner);
|
||||
|
||||
public static Status NotFound(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.NotFound, message, isOwner);
|
||||
|
||||
public static Status AlreadyExists(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.AlreadyExists, message, isOwner);
|
||||
|
||||
public static Status PermissionDenied(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.PermissionDenied, message, isOwner);
|
||||
|
||||
public static Status ResourceExhausted(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.ResourceExhausted, message, isOwner);
|
||||
|
||||
public static Status FailedPrecondition(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.FailedPrecondition, message, isOwner);
|
||||
|
||||
public static Status Aborted(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Aborted, message, isOwner);
|
||||
|
||||
public static Status OutOfRange(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.OutOfRange, message, isOwner);
|
||||
|
||||
public static Status Unimplemented(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Unimplemented, message, isOwner);
|
||||
|
||||
public static Status Internal(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Internal, message, isOwner);
|
||||
|
||||
public static Status Unavailable(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Unavailable, message, isOwner);
|
||||
|
||||
public static Status DataLoss(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.DataLoss, message, isOwner);
|
||||
|
||||
public static Status Unauthenticated(string message = "", bool isOwner = true)
|
||||
=> Build(StatusCode.Unauthenticated, message, isOwner);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ namespace Mediapipe.Net.Framework.Port
|
||||
public virtual T? ValueOr(T? defaultValue = default) => Ok() ? Value() : defaultValue;
|
||||
|
||||
/// <exception cref="MediapipeNetException">Thrown when status is not ok</exception>
|
||||
public abstract T Value();
|
||||
public abstract T? Value();
|
||||
}
|
||||
}
|
||||
|
58
Mediapipe.Net/Framework/Port/StatusOrString.cs
Normal file
58
Mediapipe.Net/Framework/Port/StatusOrString.cs
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using Mediapipe.Net.Native;
|
||||
using Mediapipe.Net.Util;
|
||||
|
||||
namespace Mediapipe.Net.Framework.Port
|
||||
{
|
||||
public unsafe class StatusOrString : StatusOr<string>
|
||||
{
|
||||
public StatusOrString(void* ptr) : base(ptr) { }
|
||||
|
||||
protected override void DeleteMpPtr()
|
||||
{
|
||||
UnsafeNativeMethods.mp_StatusOrString__delete(Ptr);
|
||||
}
|
||||
|
||||
private Status? status;
|
||||
public override Status Status
|
||||
{
|
||||
get
|
||||
{
|
||||
if (status == null || status.IsDisposed)
|
||||
{
|
||||
UnsafeNativeMethods.mp_StatusOrString__status(MpPtr, out var statusPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
status = new Status(statusPtr);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Ok() => SafeNativeMethods.mp_StatusOrString__ok(MpPtr) > 0;
|
||||
|
||||
public override string? Value()
|
||||
{
|
||||
var str = MarshalStringFromNative(UnsafeNativeMethods.mp_StatusOrString__value);
|
||||
Dispose(); // respect move semantics
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public byte[] ValueAsByteArray()
|
||||
{
|
||||
UnsafeNativeMethods.mp_StatusOrString__bytearray(MpPtr, out var strPtr, out var size).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
byte[] bytes = UnsafeUtil.SafeArrayCopy((byte*)strPtr, size);
|
||||
UnsafeNativeMethods.delete_array__PKc(strPtr);
|
||||
Dispose();
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
25
Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfo.cs
Normal file
25
Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfo.cs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mediapipe.Net.Framework.ValidatedGraphConfig
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public readonly struct EdgeInfo
|
||||
{
|
||||
public readonly int Upstream;
|
||||
public readonly NodeRef ParentNode;
|
||||
public readonly string? Name;
|
||||
public readonly bool BackEdge;
|
||||
|
||||
internal EdgeInfo(int upstream, NodeRef parentNode, string? name, bool backEdge)
|
||||
{
|
||||
Upstream = upstream;
|
||||
ParentNode = parentNode;
|
||||
Name = name;
|
||||
BackEdge = backEdge;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
namespace Mediapipe.Net.Framework.ValidatedGraphConfig
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe readonly struct EdgeInfoVector
|
||||
{
|
||||
private readonly void* data;
|
||||
private readonly int size;
|
||||
|
||||
public void Dispose() => UnsafeNativeMethods.mp_api_EdgeInfoArray__delete(data, size);
|
||||
|
||||
public List<EdgeInfo> Copy()
|
||||
{
|
||||
var edgeInfos = new List<EdgeInfo>(size);
|
||||
|
||||
unsafe
|
||||
{
|
||||
var edgeInfoPtr = (EdgeInfoTmp*)data;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
EdgeInfoTmp edgeInfoTmp = Marshal.PtrToStructure<EdgeInfoTmp>((IntPtr)edgeInfoPtr++);
|
||||
edgeInfos.Add(edgeInfoTmp.Copy());
|
||||
}
|
||||
}
|
||||
|
||||
return edgeInfos;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private readonly struct EdgeInfoTmp
|
||||
{
|
||||
private readonly int upstream;
|
||||
private readonly NodeRef parentNode;
|
||||
private readonly IntPtr name;
|
||||
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
private readonly bool backEdge;
|
||||
|
||||
public EdgeInfo Copy()
|
||||
{
|
||||
string? name = Marshal.PtrToStringAnsi(this.name);
|
||||
return new EdgeInfo(upstream, parentNode, name, backEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
Mediapipe.Net/Framework/ValidatedGraphConfig/NodeRef.cs
Normal file
15
Mediapipe.Net/Framework/ValidatedGraphConfig/NodeRef.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mediapipe.Net.Framework.ValidatedGraphConfig
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public readonly struct NodeRef
|
||||
{
|
||||
public readonly NodeType Type;
|
||||
public readonly int Index;
|
||||
}
|
||||
}
|
15
Mediapipe.Net/Framework/ValidatedGraphConfig/NodeType.cs
Normal file
15
Mediapipe.Net/Framework/ValidatedGraphConfig/NodeType.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
namespace Mediapipe.Net.Framework.ValidatedGraphConfig
|
||||
{
|
||||
public enum NodeType : int
|
||||
{
|
||||
Unknown = 0,
|
||||
Calculator = 1,
|
||||
PacketGenerator = 2,
|
||||
GraphInputStream = 3,
|
||||
StatusHandler = 4,
|
||||
};
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Google.Protobuf;
|
||||
using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
namespace Mediapipe.Net.Framework.ValidatedGraphConfig
|
||||
{
|
||||
public unsafe class ValidatedGraphConfig : MpResourceHandle
|
||||
{
|
||||
public ValidatedGraphConfig() : base()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__(out var ptr).Assert();
|
||||
Ptr = ptr;
|
||||
}
|
||||
|
||||
protected override void DeleteMpPtr() => UnsafeNativeMethods.mp_ValidatedGraphConfig__delete(Ptr);
|
||||
|
||||
public Status Initialize(CalculatorGraphConfig config)
|
||||
{
|
||||
var bytes = config.ToByteArray();
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__Initialize__Rcgc(MpPtr, bytes, bytes.Length, out var statusPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new Status(statusPtr);
|
||||
}
|
||||
|
||||
public Status Initialize(string graphType)
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__Initialize__PKc(MpPtr, graphType, out var statusPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new Status(statusPtr);
|
||||
}
|
||||
|
||||
public bool Initialized() => SafeNativeMethods.mp_ValidatedGraphConfig__Initialized(MpPtr) > 0;
|
||||
|
||||
public Status ValidateRequiredSidePackets(SidePackets sidePackets)
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__ValidateRequiredSidePackets__Rsp(MpPtr, sidePackets.MpPtr, out var statusPtr).Assert();
|
||||
|
||||
GC.KeepAlive(sidePackets);
|
||||
GC.KeepAlive(this);
|
||||
return new Status(statusPtr);
|
||||
}
|
||||
|
||||
public CalculatorGraphConfig Config(ExtensionRegistry? extensionRegistry = null)
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__Config(MpPtr, out var serializedProto).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
var parser = extensionRegistry == null ? CalculatorGraphConfig.Parser : CalculatorGraphConfig.Parser.WithExtensionRegistry(extensionRegistry);
|
||||
var config = serializedProto.Deserialize(parser);
|
||||
serializedProto.Dispose();
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
public List<EdgeInfo> InputStreamInfos()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__InputStreamInfos(MpPtr, out var edgeInfoVector).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
var edgeInfos = edgeInfoVector.Copy();
|
||||
edgeInfoVector.Dispose();
|
||||
return edgeInfos;
|
||||
}
|
||||
|
||||
public List<EdgeInfo> OutputStreamInfos()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__OutputStreamInfos(MpPtr, out var edgeInfoVector).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
var edgeInfos = edgeInfoVector.Copy();
|
||||
edgeInfoVector.Dispose();
|
||||
return edgeInfos;
|
||||
}
|
||||
|
||||
public List<EdgeInfo> InputSidePacketInfos()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__InputSidePacketInfos(MpPtr, out var edgeInfoVector).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
var edgeInfos = edgeInfoVector.Copy();
|
||||
edgeInfoVector.Dispose();
|
||||
return edgeInfos;
|
||||
}
|
||||
|
||||
public List<EdgeInfo> OutputSidePacketInfos()
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__OutputSidePacketInfos(MpPtr, out var edgeInfoVector).Assert();
|
||||
GC.KeepAlive(this);
|
||||
|
||||
var edgeInfos = edgeInfoVector.Copy();
|
||||
edgeInfoVector.Dispose();
|
||||
return edgeInfos;
|
||||
}
|
||||
|
||||
public int OutputStreamIndex(string name)
|
||||
=> SafeNativeMethods.mp_ValidatedGraphConfig__OutputStreamIndex__PKc(MpPtr, name);
|
||||
|
||||
public int OutputSidePacketIndex(string name)
|
||||
=> SafeNativeMethods.mp_ValidatedGraphConfig__OutputSidePacketIndex__PKc(MpPtr, name);
|
||||
|
||||
public int OutputStreamToNode(string name)
|
||||
=> SafeNativeMethods.mp_ValidatedGraphConfig__OutputStreamToNode__PKc(MpPtr, name);
|
||||
|
||||
public StatusOrString RegisteredSidePacketTypeName(string name)
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__RegisteredSidePacketTypeName(MpPtr, name, out var statusOrStringPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new StatusOrString(statusOrStringPtr);
|
||||
}
|
||||
|
||||
public StatusOrString RegisteredStreamTypeName(string name)
|
||||
{
|
||||
UnsafeNativeMethods.mp_ValidatedGraphConfig__RegisteredStreamTypeName(MpPtr, name, out var statusOrStringPtr).Assert();
|
||||
|
||||
GC.KeepAlive(this);
|
||||
return new StatusOrString(statusOrStringPtr);
|
||||
}
|
||||
|
||||
public string? Package() => MarshalStringFromNative(UnsafeNativeMethods.mp_ValidatedGraphConfig__Package);
|
||||
|
||||
public static bool IsReservedExecutorName(string name)
|
||||
=> SafeNativeMethods.mp_ValidatedGraphConfig_IsReservedExecutorName(name) > 0;
|
||||
|
||||
public bool IsExternalSidePacket(string name)
|
||||
=> SafeNativeMethods.mp_ValidatedGraphConfig__IsExternalSidePacket__PKc(MpPtr, name) > 0;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
@ -14,8 +13,8 @@ namespace Mediapipe.Net.Gpu
|
||||
{
|
||||
public unsafe class GlCalculatorHelper : MpResourceHandle
|
||||
{
|
||||
public delegate void* NativeGlStatusFunction();
|
||||
public delegate Status GlStatusFunction();
|
||||
public delegate Status.StatusArgs NativeGlStatusFunction();
|
||||
public delegate void GlFunction();
|
||||
|
||||
public GlCalculatorHelper() : base()
|
||||
{
|
||||
@ -45,34 +44,20 @@ namespace Mediapipe.Net.Gpu
|
||||
return new Status(statusPtr);
|
||||
}
|
||||
|
||||
public Status RunInGlContext(GlStatusFunction glStatusFunc)
|
||||
public Status RunInGlContext(GlFunction glFunction)
|
||||
{
|
||||
Status? tmpStatus = null;
|
||||
|
||||
NativeGlStatusFunction nativeGlStatusFunc = () =>
|
||||
return RunInGlContext(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
tmpStatus = glStatusFunc();
|
||||
glFunction();
|
||||
return Status.StatusArgs.Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
tmpStatus = Status.FailedPrecondition(e.ToString());
|
||||
return Status.StatusArgs.Internal(e.ToString());
|
||||
}
|
||||
return tmpStatus.MpPtr;
|
||||
};
|
||||
|
||||
// Was previously `GCHandleType.Pinned`. It had to be changed because
|
||||
// the `NativeGlStatusFunction` delegate type is non-blittable.
|
||||
// Using `GCHandleType.Normal` should be fine as it seems that all we
|
||||
// need to do is to make sure that the delegate doesn't get garbage-collected.
|
||||
var nativeGlStatusFuncHandle = GCHandle.Alloc(nativeGlStatusFunc, GCHandleType.Normal);
|
||||
var status = RunInGlContext(nativeGlStatusFunc);
|
||||
nativeGlStatusFuncHandle.Free();
|
||||
|
||||
if (tmpStatus != null)
|
||||
tmpStatus.Dispose();
|
||||
return status;
|
||||
});
|
||||
}
|
||||
|
||||
public GlTexture CreateSourceTexture(ImageFrame imageFrame)
|
||||
|
@ -12,7 +12,7 @@ namespace Mediapipe.Net.Gpu
|
||||
{
|
||||
private SharedPtrHandle? sharedPtrHandle;
|
||||
|
||||
public GlSyncPoint(void* ptr) : base(ptr)
|
||||
public GlSyncPoint(void* ptr) : base()
|
||||
{
|
||||
sharedPtrHandle = new SharedGlSyncPointPtr(ptr);
|
||||
Ptr = sharedPtrHandle.Get();
|
||||
|
@ -29,7 +29,7 @@ namespace Mediapipe.Net.Gpu
|
||||
/// Make sure that this function doesn't throw exceptions and won't be GCed.
|
||||
/// </param>
|
||||
public GlTextureBuffer(uint target, uint name, int width, int height,
|
||||
GpuBufferFormat format, DeletionCallback callback, GlContext? glContext)
|
||||
GpuBufferFormat format, DeletionCallback callback, GlContext? glContext) : base()
|
||||
{
|
||||
var sharedContextPtr = glContext == null ? null : glContext.SharedPtr;
|
||||
UnsafeNativeMethods.mp_SharedGlTextureBuffer__ui_ui_i_i_ui_PF_PSgc(
|
||||
|
@ -22,10 +22,6 @@ namespace Mediapipe.Net.Gpu
|
||||
|
||||
protected override void DeleteMpPtr() => UnsafeNativeMethods.mp_GpuBuffer__delete(Ptr);
|
||||
|
||||
[SupportedOSPlatform("Linux"), SupportedOSPlatform("Android")]
|
||||
public GlTextureBuffer GetGlTextureBuffer()
|
||||
=> new GlTextureBuffer(SafeNativeMethods.mp_GpuBuffer__GetGlTextureBufferSharedPtr(MpPtr), false);
|
||||
|
||||
public GpuBufferFormat Format => SafeNativeMethods.mp_GpuBuffer__format(MpPtr);
|
||||
|
||||
public int Width => SafeNativeMethods.mp_GpuBuffer__width(MpPtr);
|
||||
|
@ -2,14 +2,14 @@
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Native;
|
||||
|
||||
namespace Mediapipe.Net.Gpu
|
||||
{
|
||||
public static class GpuBufferFormatExtension
|
||||
{
|
||||
public static ImageFormat ImageFormatFor(this GpuBufferFormat gpuBufferFormat)
|
||||
public static ImageFormat.Types.Format ImageFormatFor(this GpuBufferFormat gpuBufferFormat)
|
||||
=> SafeNativeMethods.mp__ImageFormatForGpuBufferFormat__ui(gpuBufferFormat);
|
||||
|
||||
public static GlTextureInfo GlTextureInfoFor(this GpuBufferFormat gpuBufferFormat, int plane, GlVersion glVersion = GlVersion.KGles3)
|
||||
|
@ -11,7 +11,7 @@
|
||||
<PropertyGroup Label="Nuget">
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageId>Mediapipe.Net</PackageId>
|
||||
<Version>0.8.9.1</Version>
|
||||
<Version>1.0.0-alpha2</Version>
|
||||
<Authors>homuler;Vignette</Authors>
|
||||
<PackageTags>Google;Mediapipe;Tracking;Media Analysis</PackageTags>
|
||||
<Title>Mediapipe.Net</Title>
|
||||
@ -22,8 +22,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="Google.Protobuf" Version="3.19.4" />
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="0.8.9" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.21.3" />
|
||||
<PackageReference Include="Mediapipe.Net.Framework.Protobuf" Version="1.0.0-alpha2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Label="Documents">
|
||||
|
15
Mediapipe.Net/Native/SafeNativeMethods/External/Stdlib.cs
vendored
Normal file
15
Mediapipe.Net/Native/SafeNativeMethods/External/Stdlib.cs
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
internal unsafe partial class SafeNativeMethods
|
||||
{
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern byte mp_StatusOrString__ok(void* statusOrString);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
@ -21,7 +21,7 @@ namespace Mediapipe.Net.Native
|
||||
void* imageFrame, uint alignmentBoundary, out bool value);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern ImageFormat mp_ImageFrame__Format(void* imageFrame);
|
||||
public static extern ImageFormat.Types.Format mp_ImageFrame__Format(void* imageFrame);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern int mp_ImageFrame__Width(void* imageFrame);
|
||||
|
@ -0,0 +1,33 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
internal unsafe partial class SafeNativeMethods
|
||||
{
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern byte mp_ValidatedGraphConfig__Initialized(void* config);
|
||||
|
||||
#pragma warning disable CA2101
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern int mp_ValidatedGraphConfig__OutputStreamIndex__PKc(void* config, string name);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern int mp_ValidatedGraphConfig__OutputSidePacketIndex__PKc(void* config, string name);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern int mp_ValidatedGraphConfig__OutputStreamToNode__PKc(void* config, string name);
|
||||
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern byte mp_ValidatedGraphConfig_IsReservedExecutorName(string name);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern byte mp_ValidatedGraphConfig__IsExternalSidePacket__PKc(void* config, string name);
|
||||
#pragma warning restore CA2101
|
||||
}
|
||||
}
|
@ -4,17 +4,12 @@
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Mediapipe.Net.Gpu;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
internal unsafe partial class SafeNativeMethods : NativeMethods
|
||||
{
|
||||
[SupportedOSPlatform("Linux"), SupportedOSPlatform("Android")]
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void* mp_GpuBuffer__GetGlTextureBufferSharedPtr(void* gpuBuffer);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern int mp_GpuBuffer__width(void* gpuBuffer);
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
using Mediapipe.Net.Gpu;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
@ -12,9 +12,9 @@ namespace Mediapipe.Net.Native
|
||||
internal unsafe partial class SafeNativeMethods : NativeMethods
|
||||
{
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern ImageFormat mp__ImageFormatForGpuBufferFormat__ui(GpuBufferFormat format);
|
||||
public static extern ImageFormat.Types.Format mp__ImageFormatForGpuBufferFormat__ui(GpuBufferFormat format);
|
||||
|
||||
[Pure, DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern ImageFormat mp__GpuBufferFormatForImageFormat__ui(ImageFormat format);
|
||||
public static extern ImageFormat.Types.Format mp__GpuBufferFormatForImageFormat__ui(ImageFormat.Types.Format format);
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,13 @@ namespace Mediapipe.Net.Native
|
||||
internal unsafe partial class UnsafeNativeMethods : NativeMethods
|
||||
{
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode google_protobuf__SetLogHandler__PF(
|
||||
Protobuf.ProtobufLogHandler logHandler);
|
||||
public static extern MpReturnCode google_protobuf__SetLogHandler__PF(Protobuf.LogHandler logHandler);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void mp_api_SerializedProtoArray__delete(void* serializedProtoVectorData);
|
||||
public static extern MpReturnCode google_protobuf__ResetLogHandler();
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void mp_api_SerializedProtoArray__delete(void* serializedProtoVectorData, int size);
|
||||
|
||||
#region MessageProto
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
|
@ -21,5 +21,19 @@ namespace Mediapipe.Net.Native
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void std_string__swap__Rstr(void* src, void* dst);
|
||||
#endregion
|
||||
|
||||
#region StatusOrString
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void mp_StatusOrString__delete(void* statusOrString);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_StatusOrString__status(void* statusOrString, out void* status);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_StatusOrString__value(void* statusOrString, out sbyte* value);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_StatusOrString__bytearray(void* statusOrString, out sbyte* value, out int size);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,6 @@ namespace Mediapipe.Net.Native
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_CalculatorGraph__(out void* graph);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern MpReturnCode mp_CalculatorGraph__PKc(string textFormatConfig, out void* graph);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_CalculatorGraph__PKc_i(byte[] serializedConfig, int size, out void* graph);
|
||||
|
||||
@ -35,7 +32,7 @@ namespace Mediapipe.Net.Native
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern MpReturnCode mp_CalculatorGraph__ObserveOutputStream__PKc_PF_b(void* graph, string streamName,
|
||||
CalculatorGraph.NativePacketCallback packetCallback,
|
||||
int streamId, CalculatorGraph.NativePacketCallback packetCallback,
|
||||
bool observeTimestampBounds, out void* status);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
|
@ -3,7 +3,7 @@
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Protobuf;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
@ -14,11 +14,11 @@ namespace Mediapipe.Net.Native
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ImageFrame__ui_i_i_ui(
|
||||
ImageFormat format, int width, int height, uint alignmentBoundary, out void* imageFrame);
|
||||
ImageFormat.Types.Format format, int width, int height, uint alignmentBoundary, out void* imageFrame);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ImageFrame__ui_i_i_i_Pui8(
|
||||
ImageFormat format, int width, int height, int widthStep, byte* pixelData,
|
||||
ImageFormat.Types.Format format, int width, int height, int widthStep, byte* pixelData,
|
||||
out void* imageFrame);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
|
@ -31,6 +31,9 @@ namespace Mediapipe.Net.Native
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_Packet__RegisteredTypeName(void* packet, out sbyte* str);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_Packet__ConsumeString(void* packet, out void* statusOrValue);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_Packet__DebugTypeName(void* packet, out sbyte* str);
|
||||
#endregion
|
||||
|
@ -0,0 +1,59 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using Mediapipe.Net.External;
|
||||
using Mediapipe.Net.Framework.ValidatedGraphConfig;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
internal unsafe partial class UnsafeNativeMethods
|
||||
{
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__(out void* config);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void mp_ValidatedGraphConfig__delete(void* config);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__Initialize__Rcgc(void* config, byte[] serializedConfig, int size, out void* status);
|
||||
|
||||
#pragma warning disable CA2101
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__Initialize__PKc(void* config, string graphType, out void* status);
|
||||
#pragma warning restore CA2101
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__ValidateRequiredSidePackets__Rsp(void* config, void* sidePackets, out void* status);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__Config(void* config, out SerializedProto serializedProto);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__InputStreamInfos(void* config, out EdgeInfoVector edgeInfoVector);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__OutputStreamInfos(void* config, out EdgeInfoVector edgeInfoVector);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__InputSidePacketInfos(void* config, out EdgeInfoVector edgeInfoVector);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__OutputSidePacketInfos(void* config, out EdgeInfoVector edgeInfoVector);
|
||||
|
||||
#pragma warning disable CA2101
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__RegisteredSidePacketTypeName(void* config, string name, out void* statusOrString);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true, CharSet = CharSet.Ansi)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__RegisteredStreamTypeName(void* config, string name, out void* statusOrString);
|
||||
#pragma warning restore CA2101
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern MpReturnCode mp_ValidatedGraphConfig__Package(void* config, out sbyte* str);
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
public static extern void mp_api_EdgeInfoArray__delete(void* data, int size);
|
||||
}
|
||||
}
|
31
Mediapipe.Net/Native/UnsafeNativeMethods/FreeHGlobal.cs
Normal file
31
Mediapipe.Net/Native/UnsafeNativeMethods/FreeHGlobal.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) homuler and The Vignette Authors
|
||||
// This file is part of MediaPipe.NET.
|
||||
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mediapipe.Net.Native
|
||||
{
|
||||
internal unsafe partial class UnsafeNativeMethods : NativeMethods
|
||||
{
|
||||
// This is required to be a field in order to bypass the GC.
|
||||
private static readonly FreeHGlobalDelegate freeHGlobalDelegate;
|
||||
|
||||
static UnsafeNativeMethods()
|
||||
{
|
||||
freeHGlobalDelegate = new FreeHGlobalDelegate(freeHGlobal);
|
||||
mp_api__SetFreeHGlobal(freeHGlobalDelegate);
|
||||
}
|
||||
|
||||
private delegate void FreeHGlobalDelegate(IntPtr hglobal);
|
||||
|
||||
private static void freeHGlobal(IntPtr hglobal)
|
||||
{
|
||||
Marshal.FreeHGlobal(hglobal);
|
||||
}
|
||||
|
||||
[DllImport(MEDIAPIPE_LIBRARY, ExactSpelling = true)]
|
||||
private static extern void mp_api__SetFreeHGlobal(FreeHGlobalDelegate freeHGlobal);
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
using Mediapipe.Net.Gpu;
|
||||
|
||||
namespace Mediapipe.Net.Solutions
|
||||
@ -50,8 +49,6 @@ namespace Mediapipe.Net.Solutions
|
||||
Timestamp timestamp = new Timestamp(SimulatedTimestamp);
|
||||
Packet packet = PacketFactory.GpuBufferPacket(gpuBuffer, timestamp);
|
||||
inputs.Add(GpuBufferInput, packet);
|
||||
|
||||
return Status.Ok();
|
||||
}).AssertOk();
|
||||
|
||||
return Process(inputs);
|
||||
@ -74,8 +71,6 @@ namespace Mediapipe.Net.Solutions
|
||||
}
|
||||
Gl.Flush();
|
||||
texture.Release();
|
||||
|
||||
return Status.Ok();
|
||||
}).AssertOk();
|
||||
|
||||
if (outFrame == null)
|
||||
|
@ -10,7 +10,6 @@ using Mediapipe.Net.Core;
|
||||
using Mediapipe.Net.Framework;
|
||||
using Mediapipe.Net.Framework.Format;
|
||||
using Mediapipe.Net.Framework.Packets;
|
||||
using Mediapipe.Net.Framework.Port;
|
||||
|
||||
namespace Mediapipe.Net.Solutions
|
||||
{
|
||||
@ -49,7 +48,6 @@ namespace Mediapipe.Net.Solutions
|
||||
packet.PacketType = packetType;
|
||||
lock (GraphOutputs)
|
||||
GraphOutputs.Add(output, packet.Get());
|
||||
return Status.Ok();
|
||||
}, out GCHandle handle).AssertOk();
|
||||
observeStreamHandles.Add(output, handle);
|
||||
}
|
||||
|
Reference in New Issue
Block a user