From 9a0780c87c2d425a7c1f3678f95dd003308a7913 Mon Sep 17 00:00:00 2001 From: homuler Date: Sun, 24 Jan 2021 23:27:00 +0900 Subject: [PATCH] feat(sdk): implement FloatArrayPacket --- .../Framework/Packet/FloatArrayPacket.cs | 70 +++++++++++++++ .../Framework/Packet/FloatArrayPacket.cs.meta | 11 +++ .../NativeMethods/Framework/Packet_Unsafe.cs | 14 +++ .../Framework/Packet/FloatArrayPacketTest.cs | 86 +++++++++++++++++++ .../Packet/FloatArrayPacketTest.cs.meta | 11 +++ C/mediapipe_api/framework/packet.cc | 36 ++++++++ C/mediapipe_api/framework/packet.h | 9 ++ 7 files changed, 237 insertions(+) create mode 100644 Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs create mode 100644 Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs.meta create mode 100644 Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs create mode 100644 Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs.meta diff --git a/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs b/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs new file mode 100644 index 000000000..b1c10c69d --- /dev/null +++ b/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs @@ -0,0 +1,70 @@ +using System; + +namespace Mediapipe { + public class FloatArrayPacket : Packet { + int _Length = -1; + + public int Length { + get { return _Length; } + set { + if (_Length >= 0) { + throw new InvalidOperationException("Length is already set and cannot be changed"); + } + + _Length = value; + } + } + + public FloatArrayPacket() : base() {} + + public FloatArrayPacket(IntPtr ptr, bool isOwner = true) : base(ptr, isOwner) {} + + public FloatArrayPacket(float[] value) : base() { + UnsafeNativeMethods.mp__MakeFloatArrayPacket__Pf_i(value, value.Length, out var ptr).Assert(); + this.ptr = ptr; + Length = value.Length; + } + + public FloatArrayPacket(float[] value, Timestamp timestamp) : base() { + UnsafeNativeMethods.mp__MakeFloatArrayPacket_At__Pf_i_Rtimestamp(value, value.Length, timestamp.mpPtr, out var ptr).Assert(); + GC.KeepAlive(timestamp); + this.ptr = ptr; + Length = value.Length; + } + + public override float[] Get() { + if (Length < 0) { + throw new InvalidOperationException("The array's length is unknown, set Length first"); + } + + var result = new float[Length]; + + unsafe { + float* src = (float*)GetArrayPtr(); + + for (var i = 0; i < result.Length; i++) { + result[i] = *src++; + } + } + + return result; + } + + public IntPtr GetArrayPtr() { + UnsafeNativeMethods.mp_Packet__GetFloatArray(mpPtr, out var value).Assert(); + GC.KeepAlive(this); + return value; + } + + public override StatusOr Consume() { + throw new NotSupportedException(); + } + + public override Status ValidateAsType() { + UnsafeNativeMethods.mp_Packet__ValidateAsFloatArray(mpPtr, out var statusPtr).Assert(); + + GC.KeepAlive(this); + return new Status(statusPtr); + } + } +} diff --git a/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs.meta b/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs.meta new file mode 100644 index 000000000..68c8520df --- /dev/null +++ b/Assets/MediaPipe/SDK/Scripts/Framework/Packet/FloatArrayPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: febbf4ee3984896dc8b2f12c06963c37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs b/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs index f8e312936..9c53e2b81 100644 --- a/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs +++ b/Assets/MediaPipe/SDK/Scripts/PInvoke/NativeMethods/Framework/Packet_Unsafe.cs @@ -71,6 +71,20 @@ internal static partial class UnsafeNativeMethods { public static extern MpReturnCode mp_Packet__ValidateAsInt(IntPtr packet, out IntPtr status); #endregion + #region FloatArray + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp__MakeFloatArrayPacket__Pf_i(float[] value, int size, out IntPtr packet); + + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp__MakeFloatArrayPacket_At__Pf_i_Rtimestamp(float[] value, int size, IntPtr timestamp, out IntPtr packet); + + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_Packet__GetFloatArray(IntPtr packet, out IntPtr value); + + [DllImport (MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_Packet__ValidateAsFloatArray(IntPtr packet, out IntPtr status); + #endregion + #region String [DllImport (MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode mp__MakeStringPacket__PKc(string value, out IntPtr packet); diff --git a/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs b/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs new file mode 100644 index 000000000..c747ef5b7 --- /dev/null +++ b/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs @@ -0,0 +1,86 @@ +using Mediapipe; +using NUnit.Framework; +using System; + +namespace Tests { + public class FloatArrayPacketTest { + #region Constructor + [Test, SignalAbort] + public void Ctor_ShouldInstantiatePacket_When_CalledWithNoArguments() { + var packet = new FloatArrayPacket(); + packet.Length = 0; + + Assert.AreEqual(packet.ValidateAsType().code, Status.StatusCode.Internal); + Assert.Throws(() => { packet.Get(); }); + Assert.AreEqual(packet.Timestamp(), Timestamp.Unset()); + } + + [Test] + public void Ctor_ShouldInstantiatePacket_When_CalledWithEmptyArray() { + float[] array = {}; + var packet = new FloatArrayPacket(array); + + Assert.True(packet.ValidateAsType().ok); + Assert.AreEqual(packet.Get(), array); + Assert.AreEqual(packet.Timestamp(), Timestamp.Unset()); + } + + [Test] + public void Ctor_ShouldInstantiatePacket_When_CalledWithArray() { + float[] array = { 0.01f }; + var packet = new FloatArrayPacket(array); + + Assert.True(packet.ValidateAsType().ok); + Assert.AreEqual(packet.Get(), array); + Assert.AreEqual(packet.Timestamp(), Timestamp.Unset()); + } + + [Test] + public void Ctor_ShouldInstantiatePacket_When_CalledWithValueAndTimestamp() { + var timestamp = new Timestamp(1); + float[] array = { 0.01f, 0.02f }; + var packet = new FloatArrayPacket(array, timestamp); + + Assert.True(packet.ValidateAsType().ok); + Assert.AreEqual(packet.Get(), array); + Assert.AreEqual(packet.Timestamp(), timestamp); + } + #endregion + + #region #isDisposed + [Test] + public void isDisposed_ShouldReturnFalse_When_NotDisposedYet() { + var packet = new FloatArrayPacket(); + + Assert.False(packet.isDisposed); + } + + [Test] + public void isDisposed_ShouldReturnTrue_When_AlreadyDisposed() { + var packet = new FloatArrayPacket(); + packet.Dispose(); + + Assert.True(packet.isDisposed); + } + #endregion + + #region #Consume + [Test] + public void Consume_ShouldThrowNotSupportedException() { + var packet = new FloatArrayPacket(); + + Assert.Throws(() => { packet.Consume(); }); + } + #endregion + + #region #DebugTypeName + [Test] + public void DebugTypeName_ShouldReturnFloat_When_ValueIsSet() { + float[] array = { 0.01f }; + var packet = new FloatArrayPacket(array); + + Assert.AreEqual(packet.DebugTypeName(), "float []"); + } + #endregion + } +} diff --git a/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs.meta b/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs.meta new file mode 100644 index 000000000..4eb5dcc46 --- /dev/null +++ b/Assets/MediaPipe/SDK/Tests/EditMode/Framework/Packet/FloatArrayPacketTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43430c0ef642804f9a6347fce4ec497a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/C/mediapipe_api/framework/packet.cc b/C/mediapipe_api/framework/packet.cc index 2aefc9a6e..7f9af6dd8 100644 --- a/C/mediapipe_api/framework/packet.cc +++ b/C/mediapipe_api/framework/packet.cc @@ -143,6 +143,42 @@ MpReturnCode mp_Packet__ValidateAsInt(mediapipe::Packet* packet, mediapipe::Stat } CATCH_EXCEPTION } +// FloatArrayPacket +MpReturnCode mp__MakeFloatArrayPacket__Pf_i(float* value, int size, mediapipe::Packet** packet_out) { + TRY { + float* array = new float[size]; + std::memcpy(array, value, size * sizeof(float)); + *packet_out = new mediapipe::Packet { mediapipe::Adopt(reinterpret_cast(array)) }; + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION +} + +MpReturnCode mp__MakeFloatArrayPacket_At__Pf_i_Rtimestamp(float* value, + int size, + mediapipe::Timestamp* timestamp, + mediapipe::Packet** packet_out) { + TRY { + float* array = new float[size]; + std::memcpy(array, value, size * sizeof(float)); + *packet_out = new mediapipe::Packet { mediapipe::Adopt(reinterpret_cast(array)).At(*timestamp) }; + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION +} + +MpReturnCode mp_Packet__GetFloatArray(mediapipe::Packet* packet, const float** value_out) { + TRY_ALL { + *value_out = packet->Get(); + RETURN_CODE(MpReturnCode::Success); + } CATCH_ALL +} + +MpReturnCode mp_Packet__ValidateAsFloatArray(mediapipe::Packet* packet, mediapipe::Status** status_out) { + TRY { + *status_out = new mediapipe::Status { packet->ValidateAsType() }; + RETURN_CODE(MpReturnCode::Success); + } CATCH_EXCEPTION +} + // StringPacket MpReturnCode mp__MakeStringPacket__PKc(const char* str, mediapipe::Packet** packet_out) { TRY { diff --git a/C/mediapipe_api/framework/packet.h b/C/mediapipe_api/framework/packet.h index e1009d06c..4381fe433 100644 --- a/C/mediapipe_api/framework/packet.h +++ b/C/mediapipe_api/framework/packet.h @@ -52,6 +52,15 @@ MP_CAPI(MpReturnCode) mp__MakeIntPacket_At__i_Rtimestamp(int value, mediapipe::T MP_CAPI(MpReturnCode) mp_Packet__GetInt(mediapipe::Packet* packet, int* value_out); MP_CAPI(MpReturnCode) mp_Packet__ValidateAsInt(mediapipe::Packet* packet, mediapipe::Status** status_out); +// Float Array +MP_CAPI(MpReturnCode) mp__MakeFloatArrayPacket__Pf_i(float* value, int size, mediapipe::Packet** packet_out); +MP_CAPI(MpReturnCode) mp__MakeFloatArrayPacket_At__Pf_i_Rtimestamp(float* value, + int size, + mediapipe::Timestamp* timestamp, + mediapipe::Packet** packet_out); +MP_CAPI(MpReturnCode) mp_Packet__GetFloatArray(mediapipe::Packet* packet, const float** value_out); +MP_CAPI(MpReturnCode) mp_Packet__ValidateAsFloatArray(mediapipe::Packet* packet, mediapipe::Status** status_out); + // String MP_CAPI(MpReturnCode) mp__MakeStringPacket__PKc(const char* str, mediapipe::Packet** packet_out); MP_CAPI(MpReturnCode) mp__MakeStringPacket_At__PKc_Rtimestamp(const char* str,