diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index a31425b..ed3a6ef 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -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": []
+ },
]
}
diff --git a/MediaPipe.NET.sln b/MediaPipe.NET.sln
index 93cc30e..ec35b65 100644
--- a/MediaPipe.NET.sln
+++ b/MediaPipe.NET.sln
@@ -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
diff --git a/Mediapipe.Net.Examples.FaceMesh/Mediapipe.Net.Examples.FaceMesh.csproj b/Mediapipe.Net.Examples.FaceMesh/Mediapipe.Net.Examples.FaceMesh.csproj
index 97dba70..d320722 100644
--- a/Mediapipe.Net.Examples.FaceMesh/Mediapipe.Net.Examples.FaceMesh.csproj
+++ b/Mediapipe.Net.Examples.FaceMesh/Mediapipe.Net.Examples.FaceMesh.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.FaceMesh/Program.cs b/Mediapipe.Net.Examples.FaceMesh/Program.cs
index 4c59afd..6463037 100644
--- a/Mediapipe.Net.Examples.FaceMesh/Program.cs
+++ b/Mediapipe.Net.Examples.FaceMesh/Program.cs
@@ -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? landmarks = calculator.Compute(imgframe);
diff --git a/Mediapipe.Net.Examples.FaceMeshGpu/Mediapipe.Net.Examples.FaceMeshGpu.csproj b/Mediapipe.Net.Examples.FaceMeshGpu/Mediapipe.Net.Examples.FaceMeshGpu.csproj
index c0f730a..81d857b 100644
--- a/Mediapipe.Net.Examples.FaceMeshGpu/Mediapipe.Net.Examples.FaceMeshGpu.csproj
+++ b/Mediapipe.Net.Examples.FaceMeshGpu/Mediapipe.Net.Examples.FaceMeshGpu.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.FaceMeshGpu/Program.cs b/Mediapipe.Net.Examples.FaceMeshGpu/Program.cs
index 72e375b..c088fca 100644
--- a/Mediapipe.Net.Examples.FaceMeshGpu/Program.cs
+++ b/Mediapipe.Net.Examples.FaceMeshGpu/Program.cs
@@ -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? landmarks = calculator.Compute(imgframe);
diff --git a/Mediapipe.Net.Examples.Hands/Mediapipe.Net.Examples.Hands.csproj b/Mediapipe.Net.Examples.Hands/Mediapipe.Net.Examples.Hands.csproj
index 97dba70..d320722 100644
--- a/Mediapipe.Net.Examples.Hands/Mediapipe.Net.Examples.Hands.csproj
+++ b/Mediapipe.Net.Examples.Hands/Mediapipe.Net.Examples.Hands.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.Hands/Program.cs b/Mediapipe.Net.Examples.Hands/Program.cs
index 489d489..245f238 100644
--- a/Mediapipe.Net.Examples.Hands/Program.cs
+++ b/Mediapipe.Net.Examples.Hands/Program.cs
@@ -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);
diff --git a/Mediapipe.Net.Examples.HandsGpu/Mediapipe.Net.Examples.HandsGpu.csproj b/Mediapipe.Net.Examples.HandsGpu/Mediapipe.Net.Examples.HandsGpu.csproj
index c0f730a..81d857b 100644
--- a/Mediapipe.Net.Examples.HandsGpu/Mediapipe.Net.Examples.HandsGpu.csproj
+++ b/Mediapipe.Net.Examples.HandsGpu/Mediapipe.Net.Examples.HandsGpu.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.HandsGpu/Program.cs b/Mediapipe.Net.Examples.HandsGpu/Program.cs
index 4e4099c..3514e34 100644
--- a/Mediapipe.Net.Examples.HandsGpu/Program.cs
+++ b/Mediapipe.Net.Examples.HandsGpu/Program.cs
@@ -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);
diff --git a/Mediapipe.Net.Examples.OsuFrameworkVisualTests/Mediapipe.Net.Examples.OsuFrameworkVisualTests.csproj b/Mediapipe.Net.Examples.OsuFrameworkVisualTests/Mediapipe.Net.Examples.OsuFrameworkVisualTests.csproj
index 51188df..e3633f1 100644
--- a/Mediapipe.Net.Examples.OsuFrameworkVisualTests/Mediapipe.Net.Examples.OsuFrameworkVisualTests.csproj
+++ b/Mediapipe.Net.Examples.OsuFrameworkVisualTests/Mediapipe.Net.Examples.OsuFrameworkVisualTests.csproj
@@ -11,8 +11,8 @@
-
-
+
+
diff --git a/Mediapipe.Net.Examples.OsuFrameworkVisualTests/MediapipeDrawable.cs b/Mediapipe.Net.Examples.OsuFrameworkVisualTests/MediapipeDrawable.cs
index 1fba685..537921d 100644
--- a/Mediapipe.Net.Examples.OsuFrameworkVisualTests/MediapipeDrawable.cs
+++ b/Mediapipe.Net.Examples.OsuFrameworkVisualTests/MediapipeDrawable.cs
@@ -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? landmarkList = calculator.Compute(imgframe);
diff --git a/Mediapipe.Net.Examples.Pose/Mediapipe.Net.Examples.Pose.csproj b/Mediapipe.Net.Examples.Pose/Mediapipe.Net.Examples.Pose.csproj
index 97dba70..d320722 100644
--- a/Mediapipe.Net.Examples.Pose/Mediapipe.Net.Examples.Pose.csproj
+++ b/Mediapipe.Net.Examples.Pose/Mediapipe.Net.Examples.Pose.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.Pose/Program.cs b/Mediapipe.Net.Examples.Pose/Program.cs
index 282774b..573cf74 100644
--- a/Mediapipe.Net.Examples.Pose/Program.cs
+++ b/Mediapipe.Net.Examples.Pose/Program.cs
@@ -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);
diff --git a/Mediapipe.Net.Examples.PoseGpu/Mediapipe.Net.Examples.PoseGpu.csproj b/Mediapipe.Net.Examples.PoseGpu/Mediapipe.Net.Examples.PoseGpu.csproj
index c0f730a..81d857b 100644
--- a/Mediapipe.Net.Examples.PoseGpu/Mediapipe.Net.Examples.PoseGpu.csproj
+++ b/Mediapipe.Net.Examples.PoseGpu/Mediapipe.Net.Examples.PoseGpu.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Mediapipe.Net.Examples.PoseGpu/Program.cs b/Mediapipe.Net.Examples.PoseGpu/Program.cs
index 348c29e..35202e5 100644
--- a/Mediapipe.Net.Examples.PoseGpu/Program.cs
+++ b/Mediapipe.Net.Examples.PoseGpu/Program.cs
@@ -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);
diff --git a/Mediapipe.Net.Tests/Framework/CalculatorGraphTest.cs b/Mediapipe.Net.Tests/Framework/CalculatorGraphTest.cs
index 45a7694..ef83140 100644
--- a/Mediapipe.Net.Tests/Framework/CalculatorGraphTest.cs
+++ b/Mediapipe.Net.Tests/Framework/CalculatorGraphTest.cs
@@ -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
}
diff --git a/Mediapipe.Net.Tests/Framework/Format/ImageFrameTest.cs b/Mediapipe.Net.Tests/Framework/Format/ImageFrameTest.cs
index 65a89a1..5e1ce61 100644
--- a/Mediapipe.Net.Tests/Framework/Format/ImageFrameTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Format/ImageFrameTest.cs
@@ -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(() => imageFrame.ChannelSize.ToString());
- Assert.Throws(() => imageFrame.NumberOfChannels.ToString());
- Assert.Throws(() => imageFrame.ByteDepth.ToString());
- Assert.AreEqual(imageFrame.WidthStep, 0);
- Assert.AreEqual(imageFrame.PixelDataSize, 0);
- Assert.Throws(() => 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
+ Assert.True(imageFrame.MutablePixelData == null);
}
[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);
- }
+ 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(() => { new ImageFrame(ImageFormat.Sbgra, 640, 480, 0); });
+ Assert.Throws(() => { 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(() => { 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(() => { imageFrame.CopyToByteBuffer(99); });
+ Assert.Throws(() => { 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(() => { 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(() => { imageFrame.CopyToUshortBuffer(99); });
+ Assert.Throws(() => { 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(() => { 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(() => { imageFrame.CopyToFloatBuffer(99); });
+ Assert.Throws(() => { imageFrame.CopyToBuffer(new float[99]); });
#pragma warning restore IDE0058
}
- #endregion
}
+ #endregion
}
diff --git a/Mediapipe.Net.Tests/Framework/Packets/ImageFramePacketTest.cs b/Mediapipe.Net.Tests/Framework/Packets/ImageFramePacketTest.cs
index 46e0319..f2ab01e 100644
--- a/Mediapipe.Net.Tests/Framework/Packets/ImageFramePacketTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Packets/ImageFramePacketTest.cs
@@ -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
diff --git a/Mediapipe.Net.Tests/Framework/Port/StatusOrGpuResourcesTest.cs b/Mediapipe.Net.Tests/Framework/Port/StatusOrGpuResourcesTest.cs
index 15bfbf7..5fe64e1 100644
--- a/Mediapipe.Net.Tests/Framework/Port/StatusOrGpuResourcesTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Port/StatusOrGpuResourcesTest.cs
@@ -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
diff --git a/Mediapipe.Net.Tests/Framework/Port/StatusOrImageFrameTest.cs b/Mediapipe.Net.Tests/Framework/Port/StatusOrImageFrameTest.cs
index ad6991d..70ef1bc 100644
--- a/Mediapipe.Net.Tests/Framework/Port/StatusOrImageFrameTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Port/StatusOrImageFrameTest.cs
@@ -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();
diff --git a/Mediapipe.Net.Tests/Framework/Port/StatusOrStringTest.cs b/Mediapipe.Net.Tests/Framework/Port/StatusOrStringTest.cs
new file mode 100644
index 0000000..3290418
--- /dev/null
+++ b/Mediapipe.Net.Tests/Framework/Port/StatusOrStringTest.cs
@@ -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();
+ }
+ }
+}
diff --git a/Mediapipe.Net.Tests/Framework/Port/StatusTest.cs b/Mediapipe.Net.Tests/Framework/Port/StatusTest.cs
index b0f3c98..be1da76 100644
--- a/Mediapipe.Net.Tests/Framework/Port/StatusTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Port/StatusTest.cs
@@ -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
}
+ #endregion
}
diff --git a/Mediapipe.Net.Tests/Framework/TimestampTest.cs b/Mediapipe.Net.Tests/Framework/TimestampTest.cs
index 5754b7d..13b2ecf 100644
--- a/Mediapipe.Net.Tests/Framework/TimestampTest.cs
+++ b/Mediapipe.Net.Tests/Framework/TimestampTest.cs
@@ -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
}
diff --git a/Mediapipe.Net.Tests/Framework/Tool/NameUtilTest.cs b/Mediapipe.Net.Tests/Framework/Tool/NameUtilTest.cs
index a2957fd..395abbe 100644
--- a/Mediapipe.Net.Tests/Framework/Tool/NameUtilTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Tool/NameUtilTest.cs
@@ -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));
}
}
}
diff --git a/Mediapipe.Net.Tests/Framework/Tool/ValidateNameTest.cs b/Mediapipe.Net.Tests/Framework/Tool/ValidateNameTest.cs
index d563693..df59c90 100644
--- a/Mediapipe.Net.Tests/Framework/Tool/ValidateNameTest.cs
+++ b/Mediapipe.Net.Tests/Framework/Tool/ValidateNameTest.cs
@@ -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(() => { 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(() => { 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(() => { 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
}
diff --git a/Mediapipe.Net.Tests/Framework/ValidatedGraphConfigTest.cs b/Mediapipe.Net.Tests/Framework/ValidatedGraphConfigTest.cs
new file mode 100644
index 0000000..50c103b
--- /dev/null
+++ b/Mediapipe.Net.Tests/Framework/ValidatedGraphConfigTest.cs
@@ -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
+ }
+}
diff --git a/Mediapipe.Net.Tests/Gpu/GlCalculatorHelperTest.cs b/Mediapipe.Net.Tests/Gpu/GlCalculatorHelperTest.cs
index fea81cc..3c15aff 100644
--- a/Mediapipe.Net.Tests/Gpu/GlCalculatorHelperTest.cs
+++ b/Mediapipe.Net.Tests/Gpu/GlCalculatorHelperTest.cs
@@ -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 imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 32, 24);
+ Status status = glCalculatorHelper.RunInGlContext(() =>
{
- using (var texture = glCalculatorHelper.CreateSourceTexture(imageFrame))
- {
- texture.Release();
- }
- return Status.Ok();
+ using GlTexture texture = glCalculatorHelper.CreateSourceTexture(imageFrame);
+ texture.Release();
});
- 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
diff --git a/Mediapipe.Net.Tests/Gpu/GlContextTest.cs b/Mediapipe.Net.Tests/Gpu/GlContextTest.cs
index 3f64881..fbc7d80 100644
--- a/Mediapipe.Net.Tests/Gpu/GlContextTest.cs
+++ b/Mediapipe.Net.Tests/Gpu/GlContextTest.cs
@@ -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())
{
diff --git a/Mediapipe.Net.Tests/Gpu/GlTextureTest.cs b/Mediapipe.Net.Tests/Gpu/GlTextureTest.cs
index fb11034..a12bc49 100644
--- a/Mediapipe.Net.Tests/Gpu/GlTextureTest.cs
+++ b/Mediapipe.Net.Tests/Gpu/GlTextureTest.cs
@@ -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
}
diff --git a/Mediapipe.Net.Tests/Mediapipe.Net.Tests.csproj b/Mediapipe.Net.Tests/Mediapipe.Net.Tests.csproj
index 39bb84d..4d3ad88 100644
--- a/Mediapipe.Net.Tests/Mediapipe.Net.Tests.csproj
+++ b/Mediapipe.Net.Tests/Mediapipe.Net.Tests.csproj
@@ -9,9 +9,9 @@
-
-
-
+
+
+
diff --git a/Mediapipe.Net/Core/MpResourceHandle.cs b/Mediapipe.Net/Core/MpResourceHandle.cs
index dc025e7..d641ac6 100644
--- a/Mediapipe.Net/Core/MpResourceHandle.cs
+++ b/Mediapipe.Net/Core/MpResourceHandle.cs
@@ -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);
diff --git a/Mediapipe.Net/External/Protobuf.cs b/Mediapipe.Net/External/Protobuf.cs
index 8e0f555..f164c7d 100644
--- a/Mediapipe.Net/External/Protobuf.cs
+++ b/Mediapipe.Net/External/Protobuf.cs
@@ -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();
+ }
+
+ ///
+ /// Reset the .
+ /// If is called, this method should be called before the program exits.
+ ///
+ 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;
+ }
+ }
}
}
diff --git a/Mediapipe.Net/External/SerializedProto.cs b/Mediapipe.Net/External/SerializedProto.cs
index 4833258..751e67f 100644
--- a/Mediapipe.Net/External/SerializedProto.cs
+++ b/Mediapipe.Net/External/SerializedProto.cs
@@ -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.
diff --git a/Mediapipe.Net/External/SerializedProtoVector.cs b/Mediapipe.Net/External/SerializedProtoVector.cs
index 51d2173..f78ff94 100644
--- a/Mediapipe.Net/External/SerializedProtoVector.cs
+++ b/Mediapipe.Net/External/SerializedProtoVector.cs
@@ -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 Deserialize(MessageParser parser) where T : IMessage
{
diff --git a/Mediapipe.Net/Framework/CalculatorGraph.cs b/Mediapipe.Net/Framework/CalculatorGraph.cs
index 1d11453..9fe2d5e 100644
--- a/Mediapipe.Net/Framework/CalculatorGraph.cs
+++ b/Mediapipe.Net/Framework/CalculatorGraph.cs
@@ -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)
diff --git a/Mediapipe.Net/Framework/Format/ImageFormat.cs b/Mediapipe.Net/Framework/Format/ImageFormat.cs
deleted file mode 100644
index e79a9b5..0000000
--- a/Mediapipe.Net/Framework/Format/ImageFormat.cs
+++ /dev/null
@@ -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,
- }
-}
diff --git a/Mediapipe.Net/Framework/Format/ImageFrame.cs b/Mediapipe.Net/Framework/Format/ImageFrame.cs
index df0625c..785603b 100644
--- a/Mediapipe.Net/Framework/Format/ImageFrame.cs
+++ b/Mediapipe.Net/Framework/Format/ImageFrame.cs
@@ -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 pixelData) : base()
+ public ImageFrame(ImageFormat.Types.Format format, int width, int height, int widthStep, ReadOnlySpan pixelData) : base()
{
fixed (byte* pixelDataPtr = pixelData)
{
@@ -56,6 +56,111 @@ namespace Mediapipe.Net.Framework.Format
protected override void DeleteMpPtr() => UnsafeNativeMethods.mp_ImageFrame__delete(Ptr);
+ ///
+ /// The number of channels for a .
+ /// If channels don't make sense in the , returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ 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;
+ }
+ }
+
+ ///
+ /// The channel size for a .
+ /// If channels don't make sense in the , returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ 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;
+ }
+ }
+
+ ///
+ /// The depth of each channel in bytes for a .
+ /// If channels don't make sense in the , returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ 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);
+ ///
+ /// The channel size.
+ /// If channels don't make sense, returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ public int ChannelSize => ChannelSizeForFormat(Format);
- GC.KeepAlive(this);
- return valueOrFormatException(code, value);
- }
- }
+ ///
+ /// The Number of channels.
+ /// If channels don't make sense, returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ 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);
- }
- }
+ ///
+ /// The depth of each image channel in bytes.
+ /// If channels don't make sense, returns 0.
+ ///
+ ///
+ /// Unlike the original implementation, this API won't signal SIGABRT.
+ ///
+ 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(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(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(UnsafeNativeMethods.mp_ImageFrame__CopyToBuffer__Pf_i, bufferSize);
-
-
- ///
- /// Get the value of a specific channel only.
- /// It's useful when only one channel is used (e.g. Hair Segmentation mask).
- ///
- ///
- /// 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.
- ///
- ///
- /// The array to which the output data will be written.
- ///
- 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}");
- }
- }
-
- ///
- /// Get the value of a specific channel only.
- /// It's useful when only one channel is used (e.g. Hair Segmentation mask).
- ///
- ///
- /// 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.
- ///
- 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(void* ptr, T* buffer, int bufferSize)
where T : unmanaged;
- private T[] copyToBuffer(CopyToBufferHandler handler, int bufferSize)
+ private void copyToBuffer(CopyToBufferHandler 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(MpReturnCode code, T value)
- {
- try
- {
- code.Assert();
- return value;
- }
- catch (MediapipeException)
- {
- throw new FormatException($"Invalid image format: {Format}");
- }
- }
-
- ///
- /// 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.
- ///
- 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;
- }
- }
- }
- }
}
}
}
diff --git a/Mediapipe.Net/Framework/Packets/Packet.cs b/Mediapipe.Net/Framework/Packets/Packet.cs
index 9ccaee1..2c1056c 100644
--- a/Mediapipe.Net/Framework/Packets/Packet.cs
+++ b/Mediapipe.Net/Framework/Packets/Packet.cs
@@ -136,6 +136,14 @@ namespace Mediapipe.Net.Framework.Packets
GC.KeepAlive(this);
return new StatusOrGpuBuffer(statusOrGpuBufferPtr);
}
+
+ public StatusOr ConsumeString()
+ {
+ UnsafeNativeMethods.mp_Packet__ConsumeString(MpPtr, out var statusOrStringPtr).Assert();
+
+ GC.KeepAlive(this);
+ return new StatusOrString(statusOrStringPtr);
+ }
#endregion
#region Validators
diff --git a/Mediapipe.Net/Framework/Port/Status.cs b/Mediapipe.Net/Framework/Port/Status.cs
index 52cb425..8c7dd62 100644
--- a/Mediapipe.Net/Framework/Port/Status.cs
+++ b/Mediapipe.Net/Framework/Port/Status.cs
@@ -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);
}
}
diff --git a/Mediapipe.Net/Framework/Port/StatusOr.cs b/Mediapipe.Net/Framework/Port/StatusOr.cs
index 4347a63..790108d 100644
--- a/Mediapipe.Net/Framework/Port/StatusOr.cs
+++ b/Mediapipe.Net/Framework/Port/StatusOr.cs
@@ -16,6 +16,6 @@ namespace Mediapipe.Net.Framework.Port
public virtual T? ValueOr(T? defaultValue = default) => Ok() ? Value() : defaultValue;
/// Thrown when status is not ok
- public abstract T Value();
+ public abstract T? Value();
}
}
diff --git a/Mediapipe.Net/Framework/Port/StatusOrString.cs b/Mediapipe.Net/Framework/Port/StatusOrString.cs
new file mode 100644
index 0000000..f29ca4f
--- /dev/null
+++ b/Mediapipe.Net/Framework/Port/StatusOrString.cs
@@ -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
+ {
+ 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;
+ }
+ }
+}
diff --git a/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfo.cs b/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfo.cs
new file mode 100644
index 0000000..cfa09f8
--- /dev/null
+++ b/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfo.cs
@@ -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;
+ }
+ }
+}
diff --git a/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfoVector.cs b/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfoVector.cs
new file mode 100644
index 0000000..f36929b
--- /dev/null
+++ b/Mediapipe.Net/Framework/ValidatedGraphConfig/EdgeInfoVector.cs
@@ -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 Copy()
+ {
+ var edgeInfos = new List(size);
+
+ unsafe
+ {
+ var edgeInfoPtr = (EdgeInfoTmp*)data;
+
+ for (int i = 0; i < size; i++)
+ {
+ EdgeInfoTmp edgeInfoTmp = Marshal.PtrToStructure((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);
+ }
+ }
+ }
+}
diff --git a/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeRef.cs b/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeRef.cs
new file mode 100644
index 0000000..9197ded
--- /dev/null
+++ b/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeRef.cs
@@ -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;
+ }
+}
diff --git a/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeType.cs b/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeType.cs
new file mode 100644
index 0000000..4828043
--- /dev/null
+++ b/Mediapipe.Net/Framework/ValidatedGraphConfig/NodeType.cs
@@ -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,
+ };
+}
diff --git a/Mediapipe.Net/Framework/ValidatedGraphConfig/ValidatedGraphConfig.cs b/Mediapipe.Net/Framework/ValidatedGraphConfig/ValidatedGraphConfig.cs
new file mode 100644
index 0000000..62ad731
--- /dev/null
+++ b/Mediapipe.Net/Framework/ValidatedGraphConfig/ValidatedGraphConfig.cs
@@ -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 InputStreamInfos()
+ {
+ UnsafeNativeMethods.mp_ValidatedGraphConfig__InputStreamInfos(MpPtr, out var edgeInfoVector).Assert();
+ GC.KeepAlive(this);
+
+ var edgeInfos = edgeInfoVector.Copy();
+ edgeInfoVector.Dispose();
+ return edgeInfos;
+ }
+
+ public List OutputStreamInfos()
+ {
+ UnsafeNativeMethods.mp_ValidatedGraphConfig__OutputStreamInfos(MpPtr, out var edgeInfoVector).Assert();
+ GC.KeepAlive(this);
+
+ var edgeInfos = edgeInfoVector.Copy();
+ edgeInfoVector.Dispose();
+ return edgeInfos;
+ }
+
+ public List InputSidePacketInfos()
+ {
+ UnsafeNativeMethods.mp_ValidatedGraphConfig__InputSidePacketInfos(MpPtr, out var edgeInfoVector).Assert();
+ GC.KeepAlive(this);
+
+ var edgeInfos = edgeInfoVector.Copy();
+ edgeInfoVector.Dispose();
+ return edgeInfos;
+ }
+
+ public List 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;
+ }
+}
diff --git a/Mediapipe.Net/Gpu/GlCalculatorHelper.cs b/Mediapipe.Net/Gpu/GlCalculatorHelper.cs
index 8dac91e..8b87b74 100644
--- a/Mediapipe.Net/Gpu/GlCalculatorHelper.cs
+++ b/Mediapipe.Net/Gpu/GlCalculatorHelper.cs
@@ -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)
diff --git a/Mediapipe.Net/Gpu/GlSyncPoint.cs b/Mediapipe.Net/Gpu/GlSyncPoint.cs
index c6a0271..8c572fc 100644
--- a/Mediapipe.Net/Gpu/GlSyncPoint.cs
+++ b/Mediapipe.Net/Gpu/GlSyncPoint.cs
@@ -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();
diff --git a/Mediapipe.Net/Gpu/GlTextureBuffer.cs b/Mediapipe.Net/Gpu/GlTextureBuffer.cs
index c6e7eb1..d8a7154 100644
--- a/Mediapipe.Net/Gpu/GlTextureBuffer.cs
+++ b/Mediapipe.Net/Gpu/GlTextureBuffer.cs
@@ -29,7 +29,7 @@ namespace Mediapipe.Net.Gpu
/// Make sure that this function doesn't throw exceptions and won't be GCed.
///
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(
diff --git a/Mediapipe.Net/Gpu/GpuBuffer.cs b/Mediapipe.Net/Gpu/GpuBuffer.cs
index 67522a0..c73ce53 100644
--- a/Mediapipe.Net/Gpu/GpuBuffer.cs
+++ b/Mediapipe.Net/Gpu/GpuBuffer.cs
@@ -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);
diff --git a/Mediapipe.Net/Gpu/GpuBufferFormatExtension.cs b/Mediapipe.Net/Gpu/GpuBufferFormatExtension.cs
index 536e647..63ebc10 100644
--- a/Mediapipe.Net/Gpu/GpuBufferFormatExtension.cs
+++ b/Mediapipe.Net/Gpu/GpuBufferFormatExtension.cs
@@ -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)
diff --git a/Mediapipe.Net/Mediapipe.Net.csproj b/Mediapipe.Net/Mediapipe.Net.csproj
index b13894f..565484e 100644
--- a/Mediapipe.Net/Mediapipe.Net.csproj
+++ b/Mediapipe.Net/Mediapipe.Net.csproj
@@ -11,7 +11,7 @@
true
Mediapipe.Net
- 0.8.9.1
+ 1.0.0-alpha2
homuler;Vignette
Google;Mediapipe;Tracking;Media Analysis
Mediapipe.Net
@@ -22,8 +22,8 @@
-
-
+
+
diff --git a/Mediapipe.Net/Native/SafeNativeMethods/External/Stdlib.cs b/Mediapipe.Net/Native/SafeNativeMethods/External/Stdlib.cs
new file mode 100644
index 0000000..b903ca4
--- /dev/null
+++ b/Mediapipe.Net/Native/SafeNativeMethods/External/Stdlib.cs
@@ -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);
+ }
+}
diff --git a/Mediapipe.Net/Native/SafeNativeMethods/Framework/Format/ImageFormat.cs b/Mediapipe.Net/Native/SafeNativeMethods/Framework/Format/ImageFormat.cs
index 42b5d4d..cd353d7 100644
--- a/Mediapipe.Net/Native/SafeNativeMethods/Framework/Format/ImageFormat.cs
+++ b/Mediapipe.Net/Native/SafeNativeMethods/Framework/Format/ImageFormat.cs
@@ -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);
diff --git a/Mediapipe.Net/Native/SafeNativeMethods/Framework/ValidatedGraphConfig.cs b/Mediapipe.Net/Native/SafeNativeMethods/Framework/ValidatedGraphConfig.cs
new file mode 100644
index 0000000..ae9e4a9
--- /dev/null
+++ b/Mediapipe.Net/Native/SafeNativeMethods/Framework/ValidatedGraphConfig.cs
@@ -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
+ }
+}
diff --git a/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBuffer.cs b/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBuffer.cs
index b3071d2..1c0af37 100644
--- a/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBuffer.cs
+++ b/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBuffer.cs
@@ -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);
diff --git a/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBufferFormat.cs b/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBufferFormat.cs
index 7800dd2..9bb4bec 100644
--- a/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBufferFormat.cs
+++ b/Mediapipe.Net/Native/SafeNativeMethods/Gpu/GpuBufferFormat.cs
@@ -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);
}
}
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/External/Protobuf.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/External/Protobuf.cs
index 1f14af1..e33b633 100644
--- a/Mediapipe.Net/Native/UnsafeNativeMethods/External/Protobuf.cs
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/External/Protobuf.cs
@@ -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)]
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/External/Stdlib.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/External/Stdlib.cs
index 262f105..c91f9fd 100644
--- a/Mediapipe.Net/Native/UnsafeNativeMethods/External/Stdlib.cs
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/External/Stdlib.cs
@@ -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
}
}
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/CalculatorGraph.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/CalculatorGraph.cs
index c82f232..8a746bb 100644
--- a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/CalculatorGraph.cs
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/CalculatorGraph.cs
@@ -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)]
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Format/ImageFormat.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Format/ImageFormat.cs
index 0b37c2f..5e311f4 100644
--- a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Format/ImageFormat.cs
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Format/ImageFormat.cs
@@ -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)]
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Packet.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Packet.cs
index 9754e72..6782625 100644
--- a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Packet.cs
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/Packet.cs
@@ -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
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/ValidatedGraphConfig.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/ValidatedGraphConfig.cs
new file mode 100644
index 0000000..2c828e7
--- /dev/null
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/Framework/ValidatedGraphConfig.cs
@@ -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);
+ }
+}
diff --git a/Mediapipe.Net/Native/UnsafeNativeMethods/FreeHGlobal.cs b/Mediapipe.Net/Native/UnsafeNativeMethods/FreeHGlobal.cs
new file mode 100644
index 0000000..9a1673f
--- /dev/null
+++ b/Mediapipe.Net/Native/UnsafeNativeMethods/FreeHGlobal.cs
@@ -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);
+ }
+}
diff --git a/Mediapipe.Net/Solutions/GpuSolution.cs b/Mediapipe.Net/Solutions/GpuSolution.cs
index 9aab459..c8b917f 100644
--- a/Mediapipe.Net/Solutions/GpuSolution.cs
+++ b/Mediapipe.Net/Solutions/GpuSolution.cs
@@ -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)
diff --git a/Mediapipe.Net/Solutions/Solution.cs b/Mediapipe.Net/Solutions/Solution.cs
index 3a5da7f..3e91f30 100644
--- a/Mediapipe.Net/Solutions/Solution.cs
+++ b/Mediapipe.Net/Solutions/Solution.cs
@@ -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);
}