diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs new file mode 100644 index 000000000..fa192137b --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2023 homuler +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Mediapipe +{ + public class ImageVectorPacket : Packet> + { + [StructLayout(LayoutKind.Sequential)] + internal readonly struct ImageVector + { + private readonly IntPtr _data; + private readonly int _size; + + public void Dispose() + { + UnsafeNativeMethods.mp_api_ImageArray__delete(_data); + } + + public List Copy() + { + var images = new List(_size); + + unsafe + { + var imagePtr = (IntPtr*)_data; + + for (var i = 0; i < _size; i++) + { + var image = new Image(*imagePtr++, true); + images.Add(image); + } + } + + return images; + } + } + + /// + /// Creates an empty instance. + /// + public ImageVectorPacket() : base(true) { } + + [UnityEngine.Scripting.Preserve] + public ImageVectorPacket(IntPtr ptr, bool isOwner = true) : base(ptr, isOwner) { } + + public ImageVectorPacket At(Timestamp timestamp) + { + return At(timestamp); + } + + public override List Get() + { + UnsafeNativeMethods.mp_Packet__GetImageVector(mpPtr, out var imageVector).Assert(); + GC.KeepAlive(this); + + var images = imageVector.Copy(); + imageVector.Dispose(); + + return images; + } + + public override List Consume() + { + throw new NotSupportedException(); + } + } +} diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs.meta b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs.meta new file mode 100644 index 000000000..48e511105 --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/ImageVectorPacket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91ad38d62b35d36c38c405427e636f6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Framework/Format/Image_Unsafe.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Framework/Format/Image_Unsafe.cs index f13096aa2..2103e6948 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Framework/Format/Image_Unsafe.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Framework/Format/Image_Unsafe.cs @@ -54,8 +54,14 @@ public static extern MpReturnCode mp_Image__ui_ui_i_i_ui_PF_PSgc( [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode mp_Packet__GetImage(IntPtr packet, out IntPtr image); + [DllImport(MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_Packet__GetImageVector(IntPtr packet, out ImageVectorPacket.ImageVector imageVector); + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode mp_Packet__ValidateAsImage(IntPtr packet, out IntPtr status); + + [DllImport(MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_api_ImageArray__delete(IntPtr array); #endregion } } diff --git a/mediapipe_api/framework/formats/image.cc b/mediapipe_api/framework/formats/image.cc index 3a9d041ab..7f79ed423 100644 --- a/mediapipe_api/framework/formats/image.cc +++ b/mediapipe_api/framework/formats/image.cc @@ -119,9 +119,28 @@ MpReturnCode mp_Packet__GetImage(mediapipe::Packet* packet, const mediapipe::Ima return mp_Packet__Get(packet, value_out); } +MpReturnCode mp_Packet__GetImageVector(mediapipe::Packet* packet, mp_api::StructArray* value_out) { + TRY_ALL + auto vec = packet->Get>(); + auto size = vec.size(); + auto data = new mediapipe::Image*[size]; + + for (auto i = 0; i < size; ++i) { + data[i] = new mediapipe::Image(std::move(vec[i])); + } + value_out->data = data; + value_out->size = static_cast(size); + RETURN_CODE(MpReturnCode::Success); + CATCH_ALL +} + MpReturnCode mp_Packet__ValidateAsImage(mediapipe::Packet* packet, absl::Status** status_out) { TRY *status_out = new absl::Status{packet->ValidateAsType()}; RETURN_CODE(MpReturnCode::Success); CATCH_EXCEPTION } + +void mp_api_ImageArray__delete(mediapipe::Image** image_array) { + delete[] image_array; +} diff --git a/mediapipe_api/framework/formats/image.h b/mediapipe_api/framework/formats/image.h index 6dd89d27f..5e3a73c89 100644 --- a/mediapipe_api/framework/formats/image.h +++ b/mediapipe_api/framework/formats/image.h @@ -63,8 +63,11 @@ MP_CAPI(MpReturnCode) mp__MakeImagePacket__Pif(mediapipe::Image* image, mediapip MP_CAPI(MpReturnCode) mp__MakeImagePacket_At__Pif_Rt(mediapipe::Image* image, mediapipe::Timestamp* timestamp, mediapipe::Packet** packet_out); MP_CAPI(MpReturnCode) mp_Packet__ConsumeImage(mediapipe::Packet* packet, absl::Status **status_out, mediapipe::Image** value_out); MP_CAPI(MpReturnCode) mp_Packet__GetImage(mediapipe::Packet* packet, const mediapipe::Image** value_out); +MP_CAPI(MpReturnCode) mp_Packet__GetImageVector(mediapipe::Packet* packet, mp_api::StructArray* value_out); MP_CAPI(MpReturnCode) mp_Packet__ValidateAsImage(mediapipe::Packet* packet, absl::Status** status_out); +MP_CAPI(void) mp_api_ImageArray__delete(mediapipe::Image** image_array); + } // extern "C" #endif // MEDIAPIPE_API_FRAMEWORK_FORMATS_IMAGE_H_