diff --git a/Assets/MediaPipeUnity/Samples/Common/Scripts/GraphRunner.cs b/Assets/MediaPipeUnity/Samples/Common/Scripts/GraphRunner.cs index fd17a6454..9c5ea00ae 100644 --- a/Assets/MediaPipeUnity/Samples/Common/Scripts/GraphRunner.cs +++ b/Assets/MediaPipeUnity/Samples/Common/Scripts/GraphRunner.cs @@ -8,6 +8,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using UnityEngine; using Stopwatch = System.Diagnostics.Stopwatch; @@ -179,7 +180,7 @@ public virtual void Stop() } } - protected void AddPacketToInputStream(string streamName, Packet packet) + protected void AddPacketToInputStream(string streamName, Packet packet) { calculatorGraph.AddPacketToInputStream(streamName, packet); } @@ -201,18 +202,12 @@ protected void AddTextureFrameToInputStream(string streamName, TextureFrame text AddPacketToInputStream(streamName, Packet.CreateImageFrameAt(imageFrame, latestTimestamp)); } - protected void AssertResult(params OutputStream.NextResult[] results) + protected bool TryGetValue(Packet packet, out T value) { - foreach (var result in results) - { - if (!result.ok) - { - throw new Exception("Failed to get the next packet"); - } - } + return TryGetValue(packet, out value, (packet) => packet.Get()); } - protected bool TryGetValue(Packet packet, out T value, Func getter) + protected bool TryGetValue(Packet packet, out T value, Func, T> getter) { if (packet == null) { @@ -223,6 +218,153 @@ protected bool TryGetValue(Packet packet, out T value, Func getter return true; } + protected void AssertResult(OutputStream.NextResult result) + { + if (!result.ok) + { + throw new Exception("Failed to get the next packet"); + } + } + + protected void AssertResult((OutputStream.NextResult, OutputStream.NextResult) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + } + + protected void AssertResult((OutputStream.NextResult, OutputStream.NextResult, OutputStream.NextResult) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + } + + protected void AssertResult((OutputStream.NextResult, OutputStream.NextResult, OutputStream.NextResult, OutputStream.NextResult) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + AssertResult(result.Item4); + } + + protected void AssertResult( + ( + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult + ) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + AssertResult(result.Item4); + AssertResult(result.Item5); + } + + protected void AssertResult( + ( + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult + ) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + AssertResult(result.Item4); + AssertResult(result.Item5); + AssertResult(result.Item6); + } + + protected void AssertResult( + ( + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult + ) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + AssertResult(result.Item4); + AssertResult(result.Item5); + AssertResult(result.Item6); + AssertResult(result.Item7); + } + + protected void AssertResult( + ( + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult, + OutputStream.NextResult + ) result) + { + AssertResult(result.Item1); + AssertResult(result.Item2); + AssertResult(result.Item3); + AssertResult(result.Item4); + AssertResult(result.Item5); + AssertResult(result.Item6); + AssertResult(result.Item7); + AssertResult(result.Item8); + } + + protected async Task<(T1, T2)> WhenAll(Task task1, Task task2) + { + await Task.WhenAll(task1, task2); + return (task1.Result, task2.Result); + } + + protected async Task<(T1, T2, T3)> WhenAll(Task task1, Task task2, Task task3) + { + await Task.WhenAll(task1, task2, task3); + return (task1.Result, task2.Result, task3.Result); + } + + protected async Task<(T1, T2, T3, T4)> WhenAll(Task task1, Task task2, Task task3, Task task4) + { + await Task.WhenAll(task1, task2, task3, task4); + return (task1.Result, task2.Result, task3.Result, task4.Result); + } + + protected async Task<(T1, T2, T3, T4, T5)> WhenAll(Task task1, Task task2, Task task3, Task task4, Task task5) + { + await Task.WhenAll(task1, task2, task3, task4, task5); + return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result); + } + + protected async Task<(T1, T2, T3, T4, T5, T6)> WhenAll(Task task1, Task task2, Task task3, Task task4, Task task5, Task task6) + { + await Task.WhenAll(task1, task2, task3, task4, task5, task6); + return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result); + } + + protected async Task<(T1, T2, T3, T4, T5, T6, T7)> WhenAll(Task task1, Task task2, Task task3, Task task4, Task task5, Task task6, Task task7) + { + await Task.WhenAll(task1, task2, task3, task4, task5, task6, task7); + return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result, task7.Result); + } + + protected async Task<(T1, T2, T3, T4, T5, T6, T7, T8)> WhenAll(Task task1, Task task2, Task task3, Task task4, Task task5, Task task6, Task task7, Task task8) + { + await Task.WhenAll(task1, task2, task3, task4, task5, task6, task7, task8); + return (task1.Result, task2.Result, task3.Result, task4.Result, task5.Result, task6.Result, task7.Result, task8.Result); + } + protected long GetCurrentTimestampMicrosec() { return _stopwatch == null || !_stopwatch.IsRunning ? -1 : _stopwatch.ElapsedTicks / (TimeSpan.TicksPerMillisecond / 1000); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionGraph.cs index 5deadf401..990704b07 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionGraph.cs @@ -28,7 +28,7 @@ public float minDetectionConfidence set => _minDetectionConfidence = Mathf.Clamp01(value); } - public event EventHandler OnFaceDetectionsOutput + public event EventHandler>.OutputEventArgs> OnFaceDetectionsOutput { add => _faceDetectionsStream.AddListener(value, timeoutMicrosec); remove => _faceDetectionsStream.RemoveListener(value); @@ -36,7 +36,7 @@ public event EventHandler OnFaceDetectionsOutput private const string _InputStreamName = "input_video"; private const string _FaceDetectionsStreamName = "face_detections"; - private OutputStream _faceDetectionsStream; + private OutputStream> _faceDetectionsStream; public override void StartRun(ImageSource imageSource) { @@ -82,7 +82,7 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _faceDetectionsStream = new OutputStream(calculatorGraph, _FaceDetectionsStreamName, true); + _faceDetectionsStream = new OutputStream>(calculatorGraph, _FaceDetectionsStreamName, true); Debug.Log(timeoutMicrosec); var faceDetectionCalculators = config.Node.Where((node) => node.Calculator.StartsWith("FaceDetection")).ToList(); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionSolution.cs index 0532346d8..dca24f2e9 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Face Detection/FaceDetectionSolution.cs @@ -5,6 +5,7 @@ // https://opensource.org/licenses/MIT. using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace Mediapipe.Unity.Sample.FaceDetection @@ -48,7 +49,7 @@ protected override IEnumerator WaitForNextValue() _faceDetectionsAnnotationController.DrawNow(task.Result); } - private void OnFaceDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(Detection.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshGraph.cs index 5faf56169..65c917db0 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshGraph.cs @@ -49,25 +49,25 @@ public float minTrackingConfidence set => _minTrackingConfidence = Mathf.Clamp01(value); } - public event EventHandler OnFaceDetectionsOutput + public event EventHandler>.OutputEventArgs> OnFaceDetectionsOutput { add => _faceDetectionsStream.AddListener(value, timeoutMicrosec); remove => _faceDetectionsStream.RemoveListener(value); } - public event EventHandler OnMultiFaceLandmarksOutput + public event EventHandler>.OutputEventArgs> OnMultiFaceLandmarksOutput { add => _multiFaceLandmarksStream.AddListener(value, timeoutMicrosec); remove => _multiFaceLandmarksStream.RemoveListener(value); } - public event EventHandler OnFaceRectsFromLandmarksOutput + public event EventHandler>.OutputEventArgs> OnFaceRectsFromLandmarksOutput { add => _faceRectsFromLandmarksStream.AddListener(value, timeoutMicrosec); remove => _faceRectsFromLandmarksStream.RemoveListener(value); } - public event EventHandler OnFaceRectsFromDetectionsOutput + public event EventHandler>.OutputEventArgs> OnFaceRectsFromDetectionsOutput { add => _faceRectsFromDetectionsStream.AddListener(value, timeoutMicrosec); remove => _faceRectsFromDetectionsStream.RemoveListener(value); @@ -80,10 +80,10 @@ public event EventHandler OnFaceRectsFromDetection private const string _FaceRectsFromLandmarksStreamName = "face_rects_from_landmarks"; private const string _FaceRectsFromDetectionsStreamName = "face_rects_from_detections"; - private OutputStream _faceDetectionsStream; - private OutputStream _multiFaceLandmarksStream; - private OutputStream _faceRectsFromLandmarksStream; - private OutputStream _faceRectsFromDetectionsStream; + private OutputStream> _faceDetectionsStream; + private OutputStream> _multiFaceLandmarksStream; + private OutputStream> _faceRectsFromLandmarksStream; + private OutputStream> _faceRectsFromDetectionsStream; public override void StartRun(ImageSource imageSource) { @@ -117,7 +117,7 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame) public async Task WaitNext() { - var results = await Task.WhenAll( + var results = await WhenAll( _faceDetectionsStream.WaitNextAsync(), _multiFaceLandmarksStream.WaitNextAsync(), _faceRectsFromLandmarksStream.WaitNextAsync(), @@ -125,19 +125,19 @@ public async Task WaitNext() ); AssertResult(results); - _ = TryGetValue(results[0].packet, out var faceDetections, (packet) => + _ = TryGetValue(results.Item1.packet, out var faceDetections, (packet) => { return packet.GetProtoList(Detection.Parser); }); - _ = TryGetValue(results[1].packet, out var multiFaceLandmarks, (packet) => + _ = TryGetValue(results.Item2.packet, out var multiFaceLandmarks, (packet) => { return packet.GetProtoList(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[2].packet, out var faceRectsFromLandmarks, (packet) => + _ = TryGetValue(results.Item3.packet, out var faceRectsFromLandmarks, (packet) => { return packet.GetProtoList(NormalizedRect.Parser); }); - _ = TryGetValue(results[3].packet, out var faceRectsFromDetections, (packet) => + _ = TryGetValue(results.Item4.packet, out var faceRectsFromDetections, (packet) => { return packet.GetProtoList(NormalizedRect.Parser); }); @@ -147,10 +147,10 @@ public async Task WaitNext() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _faceDetectionsStream = new OutputStream(calculatorGraph, _FaceDetectionsStreamName, true); - _multiFaceLandmarksStream = new OutputStream(calculatorGraph, _MultiFaceLandmarksStreamName, true); - _faceRectsFromLandmarksStream = new OutputStream(calculatorGraph, _FaceRectsFromLandmarksStreamName, true); - _faceRectsFromDetectionsStream = new OutputStream(calculatorGraph, _FaceRectsFromDetectionsStreamName, true); + _faceDetectionsStream = new OutputStream>(calculatorGraph, _FaceDetectionsStreamName, true); + _multiFaceLandmarksStream = new OutputStream>(calculatorGraph, _MultiFaceLandmarksStreamName, true); + _faceRectsFromLandmarksStream = new OutputStream>(calculatorGraph, _FaceRectsFromLandmarksStreamName, true); + _faceRectsFromDetectionsStream = new OutputStream>(calculatorGraph, _FaceRectsFromDetectionsStreamName, true); using (var validatedGraphConfig = new ValidatedGraphConfig()) { diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshSolution.cs index 0b74ea3b2..87779f59f 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshSolution.cs @@ -5,6 +5,7 @@ // https://opensource.org/licenses/MIT. using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace Mediapipe.Unity.Sample.FaceMesh @@ -74,28 +75,28 @@ protected override IEnumerator WaitForNextValue() _faceRectsFromDetectionsAnnotationController.DrawNow(result.faceRectsFromDetections); } - private void OnFaceDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(Detection.Parser); _faceDetectionsAnnotationController.DrawLater(value); } - private void OnMultiFaceLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnMultiFaceLandmarksOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedLandmarkList.Parser); _multiFaceLandmarksAnnotationController.DrawLater(value); } - private void OnFaceRectsFromLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceRectsFromLandmarksOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedRect.Parser); _faceRectsFromLandmarksAnnotationController.DrawLater(value); } - private void OnFaceRectsFromDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceRectsFromDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedRect.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationGraph.cs index 82c7419c4..001af9b17 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationGraph.cs @@ -13,7 +13,7 @@ namespace Mediapipe.Unity.Sample.HairSegmentation { public class HairSegmentationGraph : GraphRunner { - public event EventHandler OnHairMaskOutput + public event EventHandler.OutputEventArgs> OnHairMaskOutput { add => _hairMaskStream.AddListener(value, timeoutMicrosec); remove => _hairMaskStream.RemoveListener(value); @@ -25,7 +25,7 @@ public event EventHandler OnHairMaskOutput private const string _InputStreamName = "input_video"; private const string _HairMaskStreamName = "hair_mask"; - private OutputStream _hairMaskStream; + private OutputStream _hairMaskStream; public override void StartRun(ImageSource imageSource) { @@ -71,7 +71,7 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _hairMaskStream = new OutputStream(calculatorGraph, _HairMaskStreamName, true); + _hairMaskStream = new OutputStream(calculatorGraph, _HairMaskStreamName, true); calculatorGraph.Initialize(config); } diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationSolution.cs index ad0b4e17f..8e0ac4282 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Hair Segmentation/HairSegmentationSolution.cs @@ -38,7 +38,7 @@ protected override IEnumerator WaitForNextValue() task.Result?.Dispose(); } - private void OnHairMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnHairMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetImageFrame(); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingGraph.cs index 915c7c95b..0e4283d89 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingGraph.cs @@ -61,37 +61,37 @@ public float minTrackingConfidence set => _minTrackingConfidence = Mathf.Clamp01(value); } - public event EventHandler OnPalmDetectectionsOutput + public event EventHandler>.OutputEventArgs> OnPalmDetectectionsOutput { add => _palmDetectionsStream.AddListener(value, timeoutMicrosec); remove => _palmDetectionsStream.RemoveListener(value); } - public event EventHandler OnHandRectsFromPalmDetectionsOutput + public event EventHandler>.OutputEventArgs> OnHandRectsFromPalmDetectionsOutput { add => _handRectsFromPalmDetectionsStream.AddListener(value, timeoutMicrosec); remove => _handRectsFromPalmDetectionsStream.RemoveListener(value); } - public event EventHandler OnHandLandmarksOutput + public event EventHandler>.OutputEventArgs> OnHandLandmarksOutput { add => _handLandmarksStream.AddListener(value, timeoutMicrosec); remove => _handLandmarksStream.RemoveListener(value); } - public event EventHandler OnHandWorldLandmarksOutput + public event EventHandler>.OutputEventArgs> OnHandWorldLandmarksOutput { add => _handWorldLandmarksStream.AddListener(value, timeoutMicrosec); remove => _handWorldLandmarksStream.RemoveListener(value); } - public event EventHandler OnHandRectsFromLandmarksOutput + public event EventHandler>.OutputEventArgs> OnHandRectsFromLandmarksOutput { add => _handRectsFromLandmarksStream.AddListener(value, timeoutMicrosec); remove => _handRectsFromLandmarksStream.RemoveListener(value); } - public event EventHandler OnHandednessOutput + public event EventHandler>.OutputEventArgs> OnHandednessOutput { add => _handednessStream.AddListener(value, timeoutMicrosec); remove => _handednessStream.RemoveListener(value); @@ -105,12 +105,12 @@ public event EventHandler OnHandednessOutput private const string _HandRectsFromLandmarksStreamName = "hand_rects_from_landmarks"; private const string _HandednessStreamName = "handedness"; - private OutputStream _palmDetectionsStream; - private OutputStream _handRectsFromPalmDetectionsStream; - private OutputStream _handLandmarksStream; - private OutputStream _handWorldLandmarksStream; - private OutputStream _handRectsFromLandmarksStream; - private OutputStream _handednessStream; + private OutputStream> _palmDetectionsStream; + private OutputStream> _handRectsFromPalmDetectionsStream; + private OutputStream> _handLandmarksStream; + private OutputStream> _handWorldLandmarksStream; + private OutputStream> _handRectsFromLandmarksStream; + private OutputStream> _handednessStream; public override void StartRun(ImageSource imageSource) { @@ -150,7 +150,7 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame) public async Task WaitNext() { - var results = await Task.WhenAll( + var results = await WhenAll( _palmDetectionsStream.WaitNextAsync(), _handRectsFromPalmDetectionsStream.WaitNextAsync(), _handLandmarksStream.WaitNextAsync(), @@ -160,27 +160,27 @@ public async Task WaitNext() ); AssertResult(results); - _ = TryGetValue(results[0].packet, out var palmDetections, (packet) => + _ = TryGetValue(results.Item1.packet, out var palmDetections, (packet) => { return packet.GetProtoList(Detection.Parser); }); - _ = TryGetValue(results[1].packet, out var handRectsFromPalmDetections, (packet) => + _ = TryGetValue(results.Item2.packet, out var handRectsFromPalmDetections, (packet) => { return packet.GetProtoList(NormalizedRect.Parser); }); - _ = TryGetValue(results[2].packet, out var handLandmarks, (packet) => + _ = TryGetValue(results.Item3.packet, out var handLandmarks, (packet) => { return packet.GetProtoList(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[3].packet, out var handWorldLandmarks, (packet) => + _ = TryGetValue(results.Item4.packet, out var handWorldLandmarks, (packet) => { return packet.GetProtoList(LandmarkList.Parser); }); - _ = TryGetValue(results[4].packet, out var handRectsFromLandmarks, (packet) => + _ = TryGetValue(results.Item5.packet, out var handRectsFromLandmarks, (packet) => { return packet.GetProtoList(NormalizedRect.Parser); }); - _ = TryGetValue(results[5].packet, out var handedness, (packet) => + _ = TryGetValue(results.Item6.packet, out var handedness, (packet) => { return packet.GetProtoList(ClassificationList.Parser); }); @@ -199,12 +199,12 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _palmDetectionsStream = new OutputStream(calculatorGraph, _PalmDetectionsStreamName, true); - _handRectsFromPalmDetectionsStream = new OutputStream(calculatorGraph, _HandRectsFromPalmDetectionsStreamName, true); - _handLandmarksStream = new OutputStream(calculatorGraph, _HandLandmarksStreamName, true); - _handWorldLandmarksStream = new OutputStream(calculatorGraph, _HandWorldLandmarksStreamName, true); - _handRectsFromLandmarksStream = new OutputStream(calculatorGraph, _HandRectsFromLandmarksStreamName, true); - _handednessStream = new OutputStream(calculatorGraph, _HandednessStreamName, true); + _palmDetectionsStream = new OutputStream>(calculatorGraph, _PalmDetectionsStreamName, true); + _handRectsFromPalmDetectionsStream = new OutputStream>(calculatorGraph, _HandRectsFromPalmDetectionsStreamName, true); + _handLandmarksStream = new OutputStream>(calculatorGraph, _HandLandmarksStreamName, true); + _handWorldLandmarksStream = new OutputStream>(calculatorGraph, _HandWorldLandmarksStreamName, true); + _handRectsFromLandmarksStream = new OutputStream>(calculatorGraph, _HandRectsFromLandmarksStreamName, true); + _handednessStream = new OutputStream>(calculatorGraph, _HandednessStreamName, true); using (var validatedGraphConfig = new ValidatedGraphConfig()) { diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingSolution.cs index 858fac332..70a0f9cb1 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Hand Tracking/HandTrackingSolution.cs @@ -5,6 +5,7 @@ // https://opensource.org/licenses/MIT. using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace Mediapipe.Unity.Sample.HandTracking @@ -77,35 +78,35 @@ protected override IEnumerator WaitForNextValue() _handRectsFromLandmarksAnnotationController.DrawNow(result.handRectsFromLandmarks); } - private void OnPalmDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPalmDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(Detection.Parser); _palmDetectionsAnnotationController.DrawLater(value); } - private void OnHandRectsFromPalmDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnHandRectsFromPalmDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedRect.Parser); _handRectsFromPalmDetectionsAnnotationController.DrawLater(value); } - private void OnHandLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnHandLandmarksOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedLandmarkList.Parser); _handLandmarksAnnotationController.DrawLater(value); } - private void OnHandRectsFromLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnHandRectsFromLandmarksOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(NormalizedRect.Parser); _handRectsFromLandmarksAnnotationController.DrawLater(value); } - private void OnHandednessOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnHandednessOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(ClassificationList.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingGraph.cs index 5e1d50467..55ee50ff1 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingGraph.cs @@ -69,49 +69,49 @@ public float minTrackingConfidence set => _minTrackingConfidence = Mathf.Clamp01(value); } - public event EventHandler OnPoseDetectionOutput + public event EventHandler.OutputEventArgs> OnPoseDetectionOutput { add => _poseDetectionStream.AddListener(value, timeoutMicrosec); remove => _poseDetectionStream.RemoveListener(value); } - public event EventHandler OnPoseLandmarksOutput + public event EventHandler.OutputEventArgs> OnPoseLandmarksOutput { add => _poseLandmarksStream.AddListener(value, timeoutMicrosec); remove => _poseLandmarksStream.RemoveListener(value); } - public event EventHandler OnFaceLandmarksOutput + public event EventHandler.OutputEventArgs> OnFaceLandmarksOutput { add => _faceLandmarksStream.AddListener(value, timeoutMicrosec); remove => _faceLandmarksStream.RemoveListener(value); } - public event EventHandler OnLeftHandLandmarksOutput + public event EventHandler.OutputEventArgs> OnLeftHandLandmarksOutput { add => _leftHandLandmarksStream.AddListener(value, timeoutMicrosec); remove => _leftHandLandmarksStream.RemoveListener(value); } - public event EventHandler OnRightHandLandmarksOutput + public event EventHandler.OutputEventArgs> OnRightHandLandmarksOutput { add => _rightHandLandmarksStream.AddListener(value, timeoutMicrosec); remove => _rightHandLandmarksStream.RemoveListener(value); } - public event EventHandler OnPoseWorldLandmarksOutput + public event EventHandler.OutputEventArgs> OnPoseWorldLandmarksOutput { add => _poseWorldLandmarksStream.AddListener(value, timeoutMicrosec); remove => _poseWorldLandmarksStream.RemoveListener(value); } - public event EventHandler OnSegmentationMaskOutput + public event EventHandler.OutputEventArgs> OnSegmentationMaskOutput { add => _segmentationMaskStream.AddListener(value, timeoutMicrosec); remove => _segmentationMaskStream.RemoveListener(value); } - public event EventHandler OnPoseRoiOutput + public event EventHandler.OutputEventArgs> OnPoseRoiOutput { add => _poseRoiStream.AddListener(value, timeoutMicrosec); remove => _poseRoiStream.RemoveListener(value); @@ -127,14 +127,14 @@ public event EventHandler OnPoseRoiOutput private const string _SegmentationMaskStreamName = "segmentation_mask"; private const string _PoseRoiStreamName = "pose_roi"; - private OutputStream _poseDetectionStream; - private OutputStream _poseLandmarksStream; - private OutputStream _faceLandmarksStream; - private OutputStream _leftHandLandmarksStream; - private OutputStream _rightHandLandmarksStream; - private OutputStream _poseWorldLandmarksStream; - private OutputStream _segmentationMaskStream; - private OutputStream _poseRoiStream; + private OutputStream _poseDetectionStream; + private OutputStream _poseLandmarksStream; + private OutputStream _faceLandmarksStream; + private OutputStream _leftHandLandmarksStream; + private OutputStream _rightHandLandmarksStream; + private OutputStream _poseWorldLandmarksStream; + private OutputStream _segmentationMaskStream; + private OutputStream _poseRoiStream; public override void StartRun(ImageSource imageSource) { @@ -180,7 +180,7 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame) public async Task WaitNextAsync() { - var results = await Task.WhenAll( + var results = await WhenAll( _poseDetectionStream.WaitNextAsync(), _poseLandmarksStream.WaitNextAsync(), _faceLandmarksStream.WaitNextAsync(), @@ -192,35 +192,35 @@ public async Task WaitNextAsync() ); AssertResult(results); - _ = TryGetValue(results[0].packet, out var poseDetection, (packet) => + _ = TryGetValue(results.Item1.packet, out var poseDetection, (packet) => { return packet.GetProto(Detection.Parser); }); - _ = TryGetValue(results[1].packet, out var poseLandmarks, (packet) => + _ = TryGetValue(results.Item2.packet, out var poseLandmarks, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[2].packet, out var faceLandmarks, (packet) => + _ = TryGetValue(results.Item3.packet, out var faceLandmarks, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[3].packet, out var leftHandLandmarks, (packet) => + _ = TryGetValue(results.Item4.packet, out var leftHandLandmarks, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[4].packet, out var rightHandLandmarks, (packet) => + _ = TryGetValue(results.Item5.packet, out var rightHandLandmarks, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[5].packet, out var poseWorldLandmarks, (packet) => + _ = TryGetValue(results.Item6.packet, out var poseWorldLandmarks, (packet) => { return packet.GetProto(LandmarkList.Parser); }); - _ = TryGetValue(results[6].packet, out var segmentationMask, (packet) => + _ = TryGetValue(results.Item7.packet, out var segmentationMask, (packet) => { return packet.GetImageFrame(); }); - _ = TryGetValue(results[7].packet, out var poseRoi, (packet) => + _ = TryGetValue(results.Item8.packet, out var poseRoi, (packet) => { return packet.GetProto(NormalizedRect.Parser); }); @@ -256,14 +256,14 @@ private WaitForResult WaitForPoseLandmarkModel() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _poseDetectionStream = new OutputStream(calculatorGraph, _PoseDetectionStreamName, true); - _poseLandmarksStream = new OutputStream(calculatorGraph, _PoseLandmarksStreamName, true); - _faceLandmarksStream = new OutputStream(calculatorGraph, _FaceLandmarksStreamName, true); - _leftHandLandmarksStream = new OutputStream(calculatorGraph, _LeftHandLandmarksStreamName, true); - _rightHandLandmarksStream = new OutputStream(calculatorGraph, _RightHandLandmarksStreamName, true); - _poseWorldLandmarksStream = new OutputStream(calculatorGraph, _PoseWorldLandmarksStreamName, true); - _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); - _poseRoiStream = new OutputStream(calculatorGraph, _PoseRoiStreamName, true); + _poseDetectionStream = new OutputStream(calculatorGraph, _PoseDetectionStreamName, true); + _poseLandmarksStream = new OutputStream(calculatorGraph, _PoseLandmarksStreamName, true); + _faceLandmarksStream = new OutputStream(calculatorGraph, _FaceLandmarksStreamName, true); + _leftHandLandmarksStream = new OutputStream(calculatorGraph, _LeftHandLandmarksStreamName, true); + _rightHandLandmarksStream = new OutputStream(calculatorGraph, _RightHandLandmarksStreamName, true); + _poseWorldLandmarksStream = new OutputStream(calculatorGraph, _PoseWorldLandmarksStreamName, true); + _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); + _poseRoiStream = new OutputStream(calculatorGraph, _PoseRoiStreamName, true); using (var validatedGraphConfig = new ValidatedGraphConfig()) { diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingSolution.cs index d362b2de3..b99c37b02 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Holistic/HolisticTrackingSolution.cs @@ -109,49 +109,49 @@ protected override IEnumerator WaitForNextValue() result.segmentationMask?.Dispose(); } - private void OnPoseDetectionOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseDetectionOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(Detection.Parser); _poseDetectionAnnotationController.DrawLater(value); } - private void OnFaceLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); _holisticAnnotationController.DrawFaceLandmarkListLater(value); } - private void OnPoseLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); _holisticAnnotationController.DrawPoseLandmarkListLater(value); } - private void OnLeftHandLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnLeftHandLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); _holisticAnnotationController.DrawLeftHandLandmarkListLater(value); } - private void OnRightHandLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnRightHandLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); _holisticAnnotationController.DrawRightHandLandmarkListLater(value); } - private void OnPoseWorldLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseWorldLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(LandmarkList.Parser); _poseWorldLandmarksAnnotationController.DrawLater(value); } - private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetImageFrame(); @@ -159,7 +159,7 @@ private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArg value?.Dispose(); } - private void OnPoseRoiOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseRoiOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedRect.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingGraph.cs index 152be56ad..40f5bf5fc 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingGraph.cs @@ -26,19 +26,19 @@ public IrisTrackingResult(List faceDetections, NormalizedRect faceRec public class IrisTrackingGraph : GraphRunner { - public event EventHandler OnFaceDetectionsOutput + public event EventHandler>.OutputEventArgs> OnFaceDetectionsOutput { add => _faceDetectionsStream.AddListener(value, timeoutMicrosec); remove => _faceDetectionsStream.RemoveListener(value); } - public event EventHandler OnFaceRectOutput + public event EventHandler.OutputEventArgs> OnFaceRectOutput { add => _faceRectStream.AddListener(value, timeoutMicrosec); remove => _faceRectStream.RemoveListener(value); } - public event EventHandler OnFaceLandmarksWithIrisOutput + public event EventHandler.OutputEventArgs> OnFaceLandmarksWithIrisOutput { add => _faceLandmarksWithIrisStream.AddListener(value, timeoutMicrosec); remove => _faceLandmarksWithIrisStream.RemoveListener(value); @@ -50,9 +50,9 @@ public event EventHandler OnFaceLandmarksWithIrisO private const string _FaceRectStreamName = "face_rect"; private const string _FaceLandmarksWithIrisStreamName = "face_landmarks_with_iris"; - private OutputStream _faceDetectionsStream; - private OutputStream _faceRectStream; - private OutputStream _faceLandmarksWithIrisStream; + private OutputStream> _faceDetectionsStream; + private OutputStream _faceRectStream; + private OutputStream _faceLandmarksWithIrisStream; public override void StartRun(ImageSource imageSource) { @@ -83,7 +83,7 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame) public async Task WaitNext() { - var results = await Task.WhenAll( + var results = await WhenAll( _faceDetectionsStream.WaitNextAsync(), _faceRectStream.WaitNextAsync(), _faceLandmarksWithIrisStream.WaitNextAsync() @@ -91,15 +91,15 @@ public async Task WaitNext() AssertResult(results); - _ = TryGetValue(results[0].packet, out var faceDetections, (packet) => + _ = TryGetValue(results.Item1.packet, out var faceDetections, (packet) => { return packet.GetProtoList(Detection.Parser); }); - _ = TryGetValue(results[1].packet, out var faceRect, (packet) => + _ = TryGetValue(results.Item2.packet, out var faceRect, (packet) => { return packet.GetProto(NormalizedRect.Parser); }); - _ = TryGetValue(results[2].packet, out var faceLandmarksWithIris, (packet) => + _ = TryGetValue(results.Item3.packet, out var faceLandmarksWithIris, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); @@ -118,9 +118,9 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _faceDetectionsStream = new OutputStream(calculatorGraph, _FaceDetectionsStreamName, true); - _faceRectStream = new OutputStream(calculatorGraph, _FaceRectStreamName, true); - _faceLandmarksWithIrisStream = new OutputStream(calculatorGraph, _FaceLandmarksWithIrisStreamName, true); + _faceDetectionsStream = new OutputStream>(calculatorGraph, _FaceDetectionsStreamName, true); + _faceRectStream = new OutputStream(calculatorGraph, _FaceRectStreamName, true); + _faceLandmarksWithIrisStream = new OutputStream(calculatorGraph, _FaceLandmarksWithIrisStreamName, true); calculatorGraph.Initialize(config); } diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingSolution.cs index 17d591105..3ff0dd940 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Iris Tracking/IrisTrackingSolution.cs @@ -5,6 +5,7 @@ // https://opensource.org/licenses/MIT. using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace Mediapipe.Unity.Sample.IrisTracking @@ -46,21 +47,21 @@ protected override IEnumerator WaitForNextValue() _faceLandmarksWithIrisAnnotationController.DrawNow(result.faceLandmarksWithIris); } - private void OnFaceDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(Detection.Parser); _faceDetectionsAnnotationController.DrawLater(value); } - private void OnFaceRectOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceRectOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedRect.Parser); _faceRectAnnotationController.DrawLater(value); } - private void OnFaceLandmarksWithIrisOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnFaceLandmarksWithIrisOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/MediaPipe Video/MediaPipeVideoGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/MediaPipe Video/MediaPipeVideoGraph.cs index 82f030c35..16fcfc3a1 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/MediaPipe Video/MediaPipeVideoGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/MediaPipe Video/MediaPipeVideoGraph.cs @@ -16,20 +16,14 @@ public class MediaPipeVideoGraph : GraphRunner { public int maxNumHands = 2; - public event EventHandler OnOutput - { - add => _outputVideoStream.AddListener(value, timeoutMicrosec); - remove => _outputVideoStream.RemoveListener(value); - } - private const string _InputStreamName = "input_video"; - private Packet _outputGpuBufferPacket; + private Packet _outputGpuBufferPacket; private string _destinationBufferName; private TextureFrame _destinationTexture; private const string _OutputVideoStreamName = "output_video"; - private OutputStream _outputVideoStream; + private OutputStream _outputVideoStream; public override void StartRun(ImageSource imageSource) { @@ -95,7 +89,7 @@ protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) sinkNode.InputSidePacket.Add($"DESTINATION:{_destinationBufferName}"); } - _outputVideoStream = new OutputStream(calculatorGraph, _OutputVideoStreamName, true); + _outputVideoStream = new OutputStream(calculatorGraph, _OutputVideoStreamName, true); calculatorGraph.Initialize(config); } diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionGraph.cs index b9daf0702..4d9686769 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionGraph.cs @@ -12,7 +12,7 @@ namespace Mediapipe.Unity.Sample.ObjectDetection { public class ObjectDetectionGraph : GraphRunner { - public event EventHandler OnOutputDetectionsOutput + public event EventHandler>.OutputEventArgs> OnOutputDetectionsOutput { add => _outputDetectionsStream.AddListener(value, timeoutMicrosec); remove => _outputDetectionsStream.RemoveListener(value); @@ -21,7 +21,7 @@ public event EventHandler OnOutputDetectionsOutput private const string _InputStreamName = "input_video"; private const string _OutputDetectionsStreamName = "output_detections"; - private OutputStream _outputDetectionsStream; + private OutputStream> _outputDetectionsStream; public override void StartRun(ImageSource imageSource) { @@ -67,7 +67,7 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _outputDetectionsStream = new OutputStream(calculatorGraph, _OutputDetectionsStreamName, true); + _outputDetectionsStream = new OutputStream>(calculatorGraph, _OutputDetectionsStreamName, true); calculatorGraph.Initialize(config); } diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionSolution.cs index e310e1829..b6ca0baed 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Object Detection/ObjectDetectionSolution.cs @@ -5,6 +5,7 @@ // https://opensource.org/licenses/MIT. using System.Collections; +using System.Collections.Generic; using UnityEngine; namespace Mediapipe.Unity.Sample.ObjectDetection @@ -36,7 +37,7 @@ protected override IEnumerator WaitForNextValue() _outputDetectionsAnnotationController.DrawNow(task.Result); } - private void OnOutputDetectionsOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnOutputDetectionsOutput(object stream, OutputStream>.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProtoList(Detection.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingGraph.cs index c54d937a1..5597d0458 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingGraph.cs @@ -60,31 +60,31 @@ public float minTrackingConfidence set => _minTrackingConfidence = Mathf.Clamp01(value); } - public event EventHandler OnPoseDetectionOutput + public event EventHandler.OutputEventArgs> OnPoseDetectionOutput { add => _poseDetectionStream.AddListener(value, timeoutMicrosec); remove => _poseDetectionStream.RemoveListener(value); } - public event EventHandler OnPoseLandmarksOutput + public event EventHandler.OutputEventArgs> OnPoseLandmarksOutput { add => _poseLandmarksStream.AddListener(value, timeoutMicrosec); remove => _poseLandmarksStream.RemoveListener(value); } - public event EventHandler OnPoseWorldLandmarksOutput + public event EventHandler.OutputEventArgs> OnPoseWorldLandmarksOutput { add => _poseWorldLandmarksStream.AddListener(value, timeoutMicrosec); remove => _poseWorldLandmarksStream.RemoveListener(value); } - public event EventHandler OnSegmentationMaskOutput + public event EventHandler.OutputEventArgs> OnSegmentationMaskOutput { add => _segmentationMaskStream.AddListener(value, timeoutMicrosec); remove => _segmentationMaskStream.RemoveListener(value); } - public event EventHandler OnRoiFromLandmarksOutput + public event EventHandler.OutputEventArgs> OnRoiFromLandmarksOutput { add => _roiFromLandmarksStream.AddListener(value, timeoutMicrosec); remove => _roiFromLandmarksStream.RemoveListener(value); @@ -97,11 +97,11 @@ public event EventHandler OnRoiFromLandmarksOutput private const string _SegmentationMaskStreamName = "segmentation_mask"; private const string _RoiFromLandmarksStreamName = "roi_from_landmarks"; - private OutputStream _poseDetectionStream; - private OutputStream _poseLandmarksStream; - private OutputStream _poseWorldLandmarksStream; - private OutputStream _segmentationMaskStream; - private OutputStream _roiFromLandmarksStream; + private OutputStream _poseDetectionStream; + private OutputStream _poseLandmarksStream; + private OutputStream _poseWorldLandmarksStream; + private OutputStream _segmentationMaskStream; + private OutputStream _roiFromLandmarksStream; public override void StartRun(ImageSource imageSource) { @@ -138,7 +138,7 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame) public async Task WaitNextAsync() { - var results = await Task.WhenAll( + var results = await WhenAll( _poseDetectionStream.WaitNextAsync(), _poseLandmarksStream.WaitNextAsync(), _poseWorldLandmarksStream.WaitNextAsync(), @@ -147,23 +147,23 @@ public async Task WaitNextAsync() ); AssertResult(results); - _ = TryGetValue(results[0].packet, out var poseDetection, (packet) => + _ = TryGetValue(results.Item1.packet, out var poseDetection, (packet) => { return packet.GetProto(Detection.Parser); }); - _ = TryGetValue(results[1].packet, out var poseLandmarks, (packet) => + _ = TryGetValue(results.Item2.packet, out var poseLandmarks, (packet) => { return packet.GetProto(NormalizedLandmarkList.Parser); }); - _ = TryGetValue(results[2].packet, out var poseWorldLandmarks, (packet) => + _ = TryGetValue(results.Item3.packet, out var poseWorldLandmarks, (packet) => { return packet.GetProto(LandmarkList.Parser); }); - _ = TryGetValue(results[3].packet, out var segmentationMask, (packet) => + _ = TryGetValue(results.Item4.packet, out var segmentationMask, (packet) => { return packet.GetImageFrame(); }); - _ = TryGetValue(results[4].packet, out var roiFromLandmarks, (packet) => + _ = TryGetValue(results.Item5.packet, out var roiFromLandmarks, (packet) => { return packet.GetProto(NormalizedRect.Parser); }); @@ -181,11 +181,11 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _poseDetectionStream = new OutputStream(calculatorGraph, _PoseDetectionStreamName, true); - _poseLandmarksStream = new OutputStream(calculatorGraph, _PoseLandmarksStreamName, true); - _poseWorldLandmarksStream = new OutputStream(calculatorGraph, _PoseWorldLandmarksStreamName, true); - _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); - _roiFromLandmarksStream = new OutputStream(calculatorGraph, _RoiFromLandmarksStreamName, true); + _poseDetectionStream = new OutputStream(calculatorGraph, _PoseDetectionStreamName, true); + _poseLandmarksStream = new OutputStream(calculatorGraph, _PoseLandmarksStreamName, true); + _poseWorldLandmarksStream = new OutputStream(calculatorGraph, _PoseWorldLandmarksStreamName, true); + _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); + _roiFromLandmarksStream = new OutputStream(calculatorGraph, _RoiFromLandmarksStreamName, true); using (var validatedGraphConfig = new ValidatedGraphConfig()) { diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingSolution.cs index ed16844a2..8da9b71f2 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Pose Tracking/PoseTrackingSolution.cs @@ -100,28 +100,28 @@ protected override IEnumerator WaitForNextValue() result.segmentationMask?.Dispose(); } - private void OnPoseDetectionOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseDetectionOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(Detection.Parser); _poseDetectionAnnotationController.DrawLater(value); } - private void OnPoseLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedLandmarkList.Parser); _poseLandmarksAnnotationController.DrawLater(value); } - private void OnPoseWorldLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnPoseWorldLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(LandmarkList.Parser); _poseWorldLandmarksAnnotationController.DrawLater(value); } - private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetImageFrame(); @@ -129,7 +129,7 @@ private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArg value?.Dispose(); } - private void OnRoiFromLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnRoiFromLandmarksOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetProto(NormalizedRect.Parser); diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationGraph.cs b/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationGraph.cs index 579d5fa38..a117ad272 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationGraph.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationGraph.cs @@ -13,7 +13,7 @@ namespace Mediapipe.Unity.Sample.SelfieSegmentation { public class SelfieSegmentationGraph : GraphRunner { - public event EventHandler OnSegmentationMaskOutput + public event EventHandler.OutputEventArgs> OnSegmentationMaskOutput { add => _segmentationMaskStream.AddListener(value, timeoutMicrosec); remove => _segmentationMaskStream.RemoveListener(value); @@ -21,7 +21,7 @@ public event EventHandler OnSegmentationMaskOutput private const string _InputStreamName = "input_video"; private const string _SegmentationMaskStreamName = "segmentation_mask"; - private OutputStream _segmentationMaskStream; + private OutputStream _segmentationMaskStream; public override void StartRun(ImageSource imageSource) { @@ -67,7 +67,7 @@ protected override IList RequestDependentAssets() protected override void ConfigureCalculatorGraph(CalculatorGraphConfig config) { - _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); + _segmentationMaskStream = new OutputStream(calculatorGraph, _SegmentationMaskStreamName, true); calculatorGraph.Initialize(config); } diff --git a/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationSolution.cs b/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationSolution.cs index bff564817..ea6781480 100644 --- a/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationSolution.cs +++ b/Assets/MediaPipeUnity/Samples/Scenes/Selfie Segmentation/SelfieSegmentationSolution.cs @@ -39,7 +39,7 @@ protected override IEnumerator WaitForNextValue() task.Result?.Dispose(); } - private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) + private void OnSegmentationMaskOutput(object stream, OutputStream.OutputEventArgs eventArgs) { var packet = eventArgs.packet; var value = packet == null ? default : packet.GetImageFrame(); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/CalculatorGraph.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/CalculatorGraph.cs index 7dbc997ab..56d77dc93 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/CalculatorGraph.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/CalculatorGraph.cs @@ -14,7 +14,7 @@ namespace Mediapipe public class CalculatorGraph : MpResourceHandle { public delegate StatusArgs NativePacketCallback(IntPtr graphPtr, int streamId, IntPtr packetPtr); - public delegate void PacketCallback(Packet packet); + public delegate void PacketCallback(Packet packet); public CalculatorGraph() : base() { @@ -75,13 +75,13 @@ public void ObserveOutputStream(string streamName, int streamId, NativePacketCal AssertStatusOk(statusPtr); } - public void ObserveOutputStream(string streamName, PacketCallback packetCallback, bool observeTimestampBounds, out GCHandle callbackHandle) + public void ObserveOutputStream(string streamName, PacketCallback packetCallback, bool observeTimestampBounds, out GCHandle callbackHandle) { NativePacketCallback nativePacketCallback = (IntPtr graphPtr, int streamId, IntPtr packetPtr) => { try { - var packet = Packet.CreateForReference(packetPtr); + var packet = Packet.CreateForReference(packetPtr); packetCallback(packet); return StatusArgs.Ok(); } @@ -95,18 +95,18 @@ public void ObserveOutputStream(string streamName, PacketCallback packetCallback ObserveOutputStream(streamName, 0, nativePacketCallback, observeTimestampBounds); } - public void ObserveOutputStream(string streamName, PacketCallback packetCallback, out GCHandle callbackHandle) + public void ObserveOutputStream(string streamName, PacketCallback packetCallback, out GCHandle callbackHandle) { ObserveOutputStream(streamName, packetCallback, false, out callbackHandle); } - public OutputStreamPoller AddOutputStreamPoller(string streamName, bool observeTimestampBounds = false) + public OutputStreamPoller AddOutputStreamPoller(string streamName, bool observeTimestampBounds = false) { UnsafeNativeMethods.mp_CalculatorGraph__AddOutputStreamPoller__PKc_b(mpPtr, streamName, observeTimestampBounds, out var statusPtr, out var pollerPtr).Assert(); GC.KeepAlive(this); AssertStatusOk(statusPtr); - return new OutputStreamPoller(pollerPtr); + return new OutputStreamPoller(pollerPtr); } public void Run() @@ -158,7 +158,7 @@ public bool HasError() return SafeNativeMethods.mp_CalculatorGraph__HasError(mpPtr); } - public void AddPacketToInputStream(string streamName, Packet packet) + public void AddPacketToInputStream(string streamName, Packet packet) { UnsafeNativeMethods.mp_CalculatorGraph__AddPacketToInputStream__PKc_Ppacket(mpPtr, streamName, packet.mpPtr, out var statusPtr).Assert(); packet.Dispose(); // respect move semantics diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/OutputStreamPoller.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/OutputStreamPoller.cs index 60d7a60ab..c79ab5887 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/OutputStreamPoller.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/OutputStreamPoller.cs @@ -8,7 +8,7 @@ namespace Mediapipe { - public class OutputStreamPoller : MpResourceHandle + public class OutputStreamPoller : MpResourceHandle { public OutputStreamPoller(IntPtr ptr) : base(ptr) { } @@ -17,7 +17,7 @@ protected override void DeleteMpPtr() UnsafeNativeMethods.mp_OutputStreamPoller__delete(ptr); } - public bool Next(Packet packet) + public bool Next(Packet packet) { UnsafeNativeMethods.mp_OutputStreamPoller__Next_Ppacket(mpPtr, packet.mpPtr, out var result).Assert(); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet.cs index 534c3e44c..d31c40d78 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet.cs @@ -6,64 +6,20 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; using Google.Protobuf; namespace Mediapipe { - public class Packet : MpResourceHandle + public static class Packet { - public Packet() : base(true) - { - UnsafeNativeMethods.mp_Packet__(out var ptr).Assert(); - this.ptr = ptr; - } - - internal Packet(IntPtr ptr, bool isOwner) : base(ptr, isOwner) { } - - protected override void DeleteMpPtr() - { - UnsafeNativeMethods.mp_Packet__delete(ptr); - } - - public long TimestampMicroseconds() - { - var value = SafeNativeMethods.mp_Packet__TimestampMicroseconds(mpPtr); - GC.KeepAlive(this); - - return value; - } - - public bool IsEmpty() => SafeNativeMethods.mp_Packet__IsEmpty(mpPtr); - - internal void SwitchNativePtr(IntPtr packetPtr) - { - if (isOwner) - { - throw new InvalidOperationException("This operation is permitted only when the packet instance is for reference"); - } - ptr = packetPtr; - } - - /// - /// Low-level API to reference the packet that points to. - /// - /// - /// This method is to be used when you want to reference the packet whose lifetime is managed by native code. - /// - /// - /// A pointer to a native Packet instance. - /// - public static Packet CreateForReference(IntPtr ptr) => new Packet(ptr, false); - /// /// Create a bool Packet. /// - public static Packet CreateBool(bool value) + public static Packet CreateBool(bool value) { UnsafeNativeMethods.mp__MakeBoolPacket__b(value, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -72,21 +28,21 @@ public static Packet CreateBool(bool value) /// /// The timestamp of the packet. /// - public static Packet CreateBoolAt(bool value, long timestampMicrosec) + public static Packet CreateBoolAt(bool value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeBoolPacket_At__b_ll(value, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a bool vector Packet. /// - public static Packet CreateBoolVector(bool[] value) + public static Packet> CreateBoolVector(bool[] value) { UnsafeNativeMethods.mp__MakeBoolVectorPacket__Pb_i(value, value.Length, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet>(ptr, true); } /// @@ -95,21 +51,21 @@ public static Packet CreateBoolVector(bool[] value) /// /// The timestamp of the packet. /// - public static Packet CreateBoolVectorAt(bool[] value, long timestampMicrosec) + public static Packet> CreateBoolVectorAt(bool[] value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeBoolVectorPacket_At__Pb_i_ll(value, value.Length, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet>(ptr, true); } /// /// Create a double Packet. /// - public static Packet CreateDouble(double value) + public static Packet CreateDouble(double value) { UnsafeNativeMethods.mp__MakeDoublePacket__d(value, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -118,21 +74,21 @@ public static Packet CreateDouble(double value) /// /// The timestamp of the packet. /// - public static Packet CreateDoubleAt(double value, long timestampMicrosec) + public static Packet CreateDoubleAt(double value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeDoublePacket_At__d_ll(value, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a float Packet. /// - public static Packet CreateFloat(float value) + public static Packet CreateFloat(float value) { UnsafeNativeMethods.mp__MakeFloatPacket__f(value, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -141,21 +97,21 @@ public static Packet CreateFloat(float value) /// /// The timestamp of the packet. /// - public static Packet CreateFloatAt(float value, long timestampMicrosec) + public static Packet CreateFloatAt(float value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeFloatPacket_At__f_ll(value, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a float array Packet. /// - public static Packet CreateFloatArray(float[] value) + public static Packet CreateFloatArray(float[] value) { UnsafeNativeMethods.mp__MakeFloatArrayPacket__Pf_i(value, value.Length, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -164,21 +120,21 @@ public static Packet CreateFloatArray(float[] value) /// /// The timestamp of the packet. /// - public static Packet CreateFloatArrayAt(float[] value, long timestampMicrosec) + public static Packet CreateFloatArrayAt(float[] value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeFloatArrayPacket_At__Pf_i_ll(value, value.Length, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a float vector Packet. /// - public static Packet CreateFloatVector(float[] value) + public static Packet> CreateFloatVector(float[] value) { UnsafeNativeMethods.mp__MakeFloatVectorPacket__Pf_i(value, value.Length, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet>(ptr, true); } /// @@ -187,22 +143,22 @@ public static Packet CreateFloatVector(float[] value) /// /// The timestamp of the packet. /// - public static Packet CreateFloatVectorAt(float[] value, long timestampMicrosec) + public static Packet> CreateFloatVectorAt(float[] value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeFloatVectorPacket_At__Pf_i_ll(value, value.Length, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet>(ptr, true); } /// /// Create an Packet. /// - public static Packet CreateGpuBuffer(GpuBuffer value) + public static Packet CreateGpuBuffer(GpuBuffer value) { UnsafeNativeMethods.mp__MakeGpuBufferPacket__Rgb(value.mpPtr, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -211,23 +167,23 @@ public static Packet CreateGpuBuffer(GpuBuffer value) /// /// The timestamp of the packet. /// - public static Packet CreateGpuBufferAt(GpuBuffer value, long timestampMicrosec) + public static Packet CreateGpuBufferAt(GpuBuffer value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeGpuBufferPacket_At__Rgb_ll(value.mpPtr, timestampMicrosec, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create an Packet. /// - public static Packet CreateImage(Image value) + public static Packet CreateImage(Image value) { UnsafeNativeMethods.mp__MakeImagePacket__PI(value.mpPtr, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -236,23 +192,23 @@ public static Packet CreateImage(Image value) /// /// The timestamp of the packet. /// - public static Packet CreateImageAt(Image value, long timestampMicrosec) + public static Packet CreateImageAt(Image value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeImagePacket_At__PI_ll(value.mpPtr, timestampMicrosec, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create an Packet. /// - public static Packet CreateImageFrame(ImageFrame value) + public static Packet CreateImageFrame(ImageFrame value) { UnsafeNativeMethods.mp__MakeImageFramePacket__Pif(value.mpPtr, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -261,22 +217,22 @@ public static Packet CreateImageFrame(ImageFrame value) /// /// The timestamp of the packet. /// - public static Packet CreateImageFrameAt(ImageFrame value, long timestampMicrosec) + public static Packet CreateImageFrameAt(ImageFrame value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeImageFramePacket_At__Pif_ll(value.mpPtr, timestampMicrosec, out var ptr).Assert(); value.Dispose(); // respect move semantics - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create an int Packet. /// - public static Packet CreateInt(int value) + public static Packet CreateInt(int value) { UnsafeNativeMethods.mp__MakeIntPacket__i(value, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -285,17 +241,17 @@ public static Packet CreateInt(int value) /// /// The timestamp of the packet. /// - public static Packet CreateIntAt(int value, long timestampMicrosec) + public static Packet CreateIntAt(int value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeIntPacket_At__i_ll(value, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a MediaPipe protobuf message Packet. /// - public static Packet CreateProto(T value) where T : IMessage + public static Packet CreateProto(TMessage value) where TMessage : IMessage { unsafe { @@ -305,8 +261,8 @@ public static Packet CreateProto(T value) where T : IMessage UnsafeNativeMethods.mp__PacketFromDynamicProto__PKc_PKc_i(value.Descriptor.FullName, arr, size, out var statusPtr, out var ptr).Assert(); - AssertStatusOk(statusPtr); - return new Packet(ptr, true); + Status.UnsafeAssertOk(statusPtr); + return new Packet(ptr, true); } } @@ -316,7 +272,7 @@ public static Packet CreateProto(T value) where T : IMessage /// /// The timestamp of the packet. /// - public static Packet CreateProtoAt(T value, long timestampMicrosec) where T : IMessage + public static Packet CreateProtoAt(TMessage value, long timestampMicrosec) where TMessage : IMessage { unsafe { @@ -325,30 +281,30 @@ public static Packet CreateProtoAt(T value, long timestampMicrosec) where T : value.WriteTo(new Span(arr, size)); UnsafeNativeMethods.mp__PacketFromDynamicProto_At__PKc_PKc_i_ll(value.Descriptor.FullName, arr, size, timestampMicrosec, out var statusPtr, out var ptr).Assert(); - AssertStatusOk(statusPtr); + Status.UnsafeAssertOk(statusPtr); - return new Packet(ptr, true); + return new Packet(ptr, true); } } /// /// Create a string Packet. /// - public static Packet CreateString(string value) + public static Packet CreateString(string value) { UnsafeNativeMethods.mp__MakeStringPacket__PKc(value ?? "", out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// /// Create a string Packet. /// - public static Packet CreateString(byte[] value) + public static Packet CreateString(byte[] value) { UnsafeNativeMethods.mp__MakeStringPacket__PKc_i(value, value?.Length ?? 0, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -357,11 +313,11 @@ public static Packet CreateString(byte[] value) /// /// The timestamp of the packet. /// - public static Packet CreateStringAt(string value, long timestampMicrosec) + public static Packet CreateStringAt(string value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeStringPacket_At__PKc_ll(value ?? "", timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); + return new Packet(ptr, true); } /// @@ -370,594 +326,57 @@ public static Packet CreateStringAt(string value, long timestampMicrosec) /// /// The timestamp of the packet. /// - public static Packet CreateStringAt(byte[] value, long timestampMicrosec) + public static Packet CreateStringAt(byte[] value, long timestampMicrosec) { UnsafeNativeMethods.mp__MakeStringPacket_At__PKc_i_ll(value, value?.Length ?? 0, timestampMicrosec, out var ptr).Assert(); - return new Packet(ptr, true); - } - - /// - /// Get the content of the as a boolean. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain bool data. - /// - public bool GetBool() - { - UnsafeNativeMethods.mp_Packet__GetBool(mpPtr, out var value).Assert(); - - GC.KeepAlive(this); - return value; - } - - /// - /// Get the content of a bool vector Packet as a . - /// - public List GetBoolList() - { - var value = new List(); - GetBoolList(value); - - return value; - } - - /// - /// Get the content of a bool vector Packet as a . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// - /// - /// If the doesn't contain std::vector<bool> data. - /// - public void GetBoolList(List value) - { - UnsafeNativeMethods.mp_Packet__GetBoolVector(mpPtr, out var structArray).Assert(); - GC.KeepAlive(this); - - structArray.CopyTo(value); - structArray.Dispose(); - } - - /// - /// Get the content of the as . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain data. - /// - public byte[] GetBytes() - { - UnsafeNativeMethods.mp_Packet__GetByteString(mpPtr, out var strPtr, out var size).Assert(); - GC.KeepAlive(this); - - var bytes = new byte[size]; - Marshal.Copy(strPtr, bytes, 0, size); - UnsafeNativeMethods.delete_array__PKc(strPtr); - - return bytes; - } - - /// - /// Get the content of the as . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// If the length of is not enough to store the content of the , - /// the rest of the content will be discarded. - /// - /// - /// The number of written elements in . - /// - /// - /// If the doesn't contain data. - /// - public int GetBytes(byte[] value) - { - UnsafeNativeMethods.mp_Packet__GetByteString(mpPtr, out var strPtr, out var size).Assert(); - GC.KeepAlive(this); - - var length = Math.Min(size, value.Length); - Marshal.Copy(strPtr, value, 0, length); - UnsafeNativeMethods.delete_array__PKc(strPtr); - - return length; + return new Packet(ptr, true); } + } - /// - /// Get the content of the as a double. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain double data. - /// - public double GetDouble() + public partial class Packet : MpResourceHandle + { + public Packet() : base(true) { - UnsafeNativeMethods.mp_Packet__GetDouble(mpPtr, out var value).Assert(); - - GC.KeepAlive(this); - return value; + UnsafeNativeMethods.mp_Packet__(out var ptr).Assert(); + this.ptr = ptr; } - /// - /// Get the content of the as a float. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain float data. - /// - public float GetFloat() - { - UnsafeNativeMethods.mp_Packet__GetFloat(mpPtr, out var value).Assert(); - - GC.KeepAlive(this); - return value; - } + internal Packet(IntPtr ptr, bool isOwner) : base(ptr, isOwner) { } - /// - /// Get the content of a float array Packet as a . - /// - public float[] GetFloatArray(int length) + protected override void DeleteMpPtr() { - var value = new float[length]; - GetFloatArray(value); - - return value; + UnsafeNativeMethods.mp_Packet__delete(ptr); } - /// - /// Get the content of a float array Packet as a . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// - /// - /// If the doesn't contain a float array. - /// - public void GetFloatArray(float[] value) + public long TimestampMicroseconds() { - UnsafeNativeMethods.mp_Packet__GetFloatArray_i(mpPtr, value.Length, out var arrayPtr).Assert(); + var value = SafeNativeMethods.mp_Packet__TimestampMicroseconds(mpPtr); GC.KeepAlive(this); - Marshal.Copy(arrayPtr, value, 0, value.Length); - UnsafeNativeMethods.delete_array__Pf(arrayPtr); - } - - /// - /// Get the content of a float vector Packet as a . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain std::vector<float> data. - /// - public List GetFloatList() - { - var value = new List(); - GetFloatList(value); - return value; } - /// - /// Get the content of a float vector Packet as a . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// - /// - /// If the doesn't contain std::vector<float> data. - /// - public void GetFloatList(List value) - { - UnsafeNativeMethods.mp_Packet__GetFloatVector(mpPtr, out var structArray).Assert(); - GC.KeepAlive(this); - - structArray.CopyTo(value); - structArray.Dispose(); - } - - /// - /// Get the content of the as an . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain . - /// - public Image GetImage() - { - UnsafeNativeMethods.mp_Packet__GetImage(mpPtr, out var ptr).Assert(); - - GC.KeepAlive(this); - return new Image(ptr, false); - } - - /// - /// Get the content of the as a list of . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain std::vector<Image>. - /// - public List GetImageList() - { - var value = new List(); - - GetImageList(value); - return value; - } + public bool IsEmpty() => SafeNativeMethods.mp_Packet__IsEmpty(mpPtr); - /// - /// Get the content of the as a list of . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// - /// - /// If the doesn't contain std::vector<Image>. - /// - public void GetImageList(List value) + internal void SwitchNativePtr(IntPtr packetPtr) { - UnsafeNativeMethods.mp_Packet__GetImageVector(mpPtr, out var imageArray).Assert(); - GC.KeepAlive(this); - - foreach (var image in value) - { - image.Dispose(); - } - value.Clear(); - - foreach (var imagePtr in imageArray.AsReadOnlySpan()) + if (isOwner) { - value.Add(new Image(imagePtr, false)); + throw new InvalidOperationException("This operation is permitted only when the packet instance is for reference"); } + ptr = packetPtr; } /// - /// Get the content of the as an . - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain . - /// - public ImageFrame GetImageFrame() - { - UnsafeNativeMethods.mp_Packet__GetImageFrame(mpPtr, out var ptr).Assert(); - - GC.KeepAlive(this); - return new ImageFrame(ptr, false); - } - - /// - /// Get the content of the as an integer. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain data. - /// - public int GetInt() - { - UnsafeNativeMethods.mp_Packet__GetInt(mpPtr, out var value).Assert(); - - GC.KeepAlive(this); - return value; - } - - /// - /// Get the content of the as a proto message. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain proto messages. - /// - public T GetProto(MessageParser parser) where T : IMessage - { - UnsafeNativeMethods.mp_Packet__GetProtoMessageLite(mpPtr, out var value).Assert(); - - GC.KeepAlive(this); - - var proto = value.Deserialize(parser); - value.Dispose(); - - return proto; - } - - /// - /// Get the content of the as a proto message list. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain a proto message list. - /// - public List GetProtoList(MessageParser parser) where T : IMessage - { - var value = new List(); - GetProtoList(parser, value); - - return value; - } - - /// - /// Get the content of the as a proto message list. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// The to be filled with the content of the . - /// - /// - /// If the doesn't contain a proto message list. - /// - public void GetProtoList(MessageParser parser, List value) where T : IMessage - { - UnsafeNativeMethods.mp_Packet__GetVectorOfProtoMessageLite(mpPtr, out var serializedProtoVector).Assert(); - - GC.KeepAlive(this); - - serializedProtoVector.Deserialize(parser, value); - serializedProtoVector.Dispose(); - } - - /// - /// Write the content of the as a proto message list. + /// Low-level API to reference the packet that points to. /// /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// This method is to be used when you want to reference the packet whose lifetime is managed by native code. /// - /// - /// The to be filled with the content of the . + /// + /// A pointer to a native Packet instance. /// - /// - /// The number of written elements in . - /// - /// - /// If the doesn't contain a proto message list. - /// - public int WriteProtoListTo(MessageParser parser, List value) where T : IMessage - { - UnsafeNativeMethods.mp_Packet__GetVectorOfProtoMessageLite(mpPtr, out var serializedProtoVector).Assert(); - - GC.KeepAlive(this); - - var size = serializedProtoVector.WriteTo(parser, value); - serializedProtoVector.Dispose(); - - return size; - } - - public void GetDetectionList(List outs) - { - foreach (var detection in outs) - { - detection.Clear(); - } - - var size = WriteProtoListTo(Detection.Parser, outs); - outs.RemoveRange(size, outs.Count - size); - } - - /// - /// Get the content of the as a string. - /// - /// - /// On some platforms (e.g. Windows), it will abort the process when should be thrown. - /// - /// - /// If the doesn't contain data. - /// - public string GetString() - { - UnsafeNativeMethods.mp_Packet__GetString(mpPtr, out var ptr).Assert(); - - GC.KeepAlive(this); - return MarshalStringFromNative(ptr); - } - - /// - /// Validate if the content of the is a boolean. - /// - /// - /// If the doesn't contain bool data. - /// - public void ValidateAsBool() - { - UnsafeNativeMethods.mp_Packet__ValidateAsBool(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a std::vector<bool>. - /// - /// - /// If the doesn't contain std::vector<bool>. - /// - public void ValidateAsBoolVector() - { - UnsafeNativeMethods.mp_Packet__ValidateAsBoolVector(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a double. - /// - /// - /// If the doesn't contain double data. - /// - public void ValidateAsDouble() - { - UnsafeNativeMethods.mp_Packet__ValidateAsDouble(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a float. - /// - /// - /// If the doesn't contain float data. - /// - public void ValidateAsFloat() - { - UnsafeNativeMethods.mp_Packet__ValidateAsFloat(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a float array. - /// - /// - /// If the doesn't contain a float array. - /// - public void ValidateAsFloatArray() - { - UnsafeNativeMethods.mp_Packet__ValidateAsFloatArray(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is std::vector<float>. - /// - /// - /// If the doesn't contain std::vector<bool>. - /// - public void ValidateAsFloatVector() - { - UnsafeNativeMethods.mp_Packet__ValidateAsFloatVector(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is an . - /// - /// - /// If the doesn't contain . - /// - public void ValidateAsGpuBuffer() - { - UnsafeNativeMethods.mp_Packet__ValidateAsGpuBuffer(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is an . - /// - /// - /// If the doesn't contain . - /// - public void ValidateAsImage() - { - UnsafeNativeMethods.mp_Packet__ValidateAsImage(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is an . - /// - /// - /// If the doesn't contain . - /// - public void ValidateAsImageFrame() - { - UnsafeNativeMethods.mp_Packet__ValidateAsImageFrame(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is an . - /// - /// - /// If the doesn't contain . - /// - public void ValidateAsInt() - { - UnsafeNativeMethods.mp_Packet__ValidateAsInt(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a proto message. - /// - /// - /// If the doesn't contain proto messages. - /// - public void ValidateAsProtoMessageLite() - { - UnsafeNativeMethods.mp_Packet__ValidateAsProtoMessageLite(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } - - /// - /// Validate if the content of the is a string. - /// - /// - /// If the doesn't contain string. - /// - public void ValidateAsString() - { - UnsafeNativeMethods.mp_Packet__ValidateAsString(mpPtr, out var statusPtr).Assert(); - - GC.KeepAlive(this); - AssertStatusOk(statusPtr); - } + public static Packet CreateForReference(IntPtr ptr) => new Packet(ptr, false); } } diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/PacketMap.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/PacketMap.cs index 5900a604f..18f164fe3 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/PacketMap.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Packet/PacketMap.cs @@ -30,7 +30,7 @@ protected override void DeleteMpPtr() /// This method cannot verify that the packet type corresponding to the is indeed a , /// so you must make sure by youreself that it is. /// - public Packet At(string key) + public Packet At(string key) { UnsafeNativeMethods.mp_PacketMap__find__PKc(mpPtr, key, out var packetPtr).Assert(); @@ -39,10 +39,10 @@ public Packet At(string key) return default; // null } GC.KeepAlive(this); - return new Packet(packetPtr, true); + return new Packet(packetPtr, true); } - public void Emplace(string key, Packet packet) + public void Emplace(string key, Packet packet) { UnsafeNativeMethods.mp_PacketMap__emplace__PKc_Rp(mpPtr, key, packet.mpPtr).Assert(); packet.Dispose(); // respect move semantics diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs new file mode 100644 index 000000000..089b45550 --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs @@ -0,0 +1,470 @@ +// 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; +using Google.Protobuf; + +namespace Mediapipe +{ + public static class PacketGetterExtension + { + /// + /// Get the content of the as a boolean. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain bool data. + /// + public static bool Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetBool(packet.mpPtr, out var value).Assert(); + GC.KeepAlive(packet); + + return value; + } + + [Obsolete("Use Get instead")] + public static bool GetBool(this Packet packet) => Get(packet); + + /// + /// Get the content of a bool vector Packet as a . + /// + public static List Get(this Packet> packet) + { + var value = new List(); + Get(packet, value); + + return value; + } + + [Obsolete("Use Get instead")] + public static List GetBoolList(this Packet> packet) => Get(packet); + + /// + /// Get the content of a bool vector Packet as a . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// If the doesn't contain std::vector<bool> data. + /// + public static void Get(this Packet> packet, List value) + { + UnsafeNativeMethods.mp_Packet__GetBoolVector(packet.mpPtr, out var structArray).Assert(); + GC.KeepAlive(packet); + + structArray.CopyTo(value); + structArray.Dispose(); + } + + [Obsolete("Use Get instead")] + public static void GetBoolList(this Packet> packet, List value) => Get(packet, value); + + /// + /// Get the content of the as . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain data. + /// + public static byte[] GetBytes(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetByteString(packet.mpPtr, out var strPtr, out var size).Assert(); + GC.KeepAlive(packet); + + var bytes = new byte[size]; + Marshal.Copy(strPtr, bytes, 0, size); + UnsafeNativeMethods.delete_array__PKc(strPtr); + + return bytes; + } + + /// + /// Get the content of the as . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// If the length of is not enough to store the content of the , + /// the rest of the content will be discarded. + /// + /// + /// The number of written elements in . + /// + /// + /// If the doesn't contain data. + /// + public static int GetBytes(this Packet packet, byte[] value) + { + UnsafeNativeMethods.mp_Packet__GetByteString(packet.mpPtr, out var strPtr, out var size).Assert(); + GC.KeepAlive(packet); + + var length = Math.Min(size, value.Length); + Marshal.Copy(strPtr, value, 0, length); + UnsafeNativeMethods.delete_array__PKc(strPtr); + + return length; + } + + /// + /// Get the content of the as a double. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain double data. + /// + public static double Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetDouble(packet.mpPtr, out var value).Assert(); + GC.KeepAlive(packet); + + return value; + } + + [Obsolete("Use Get instead")] + public static double GetDouble(this Packet packet) => Get(packet); + + /// + /// Get the content of the as a float. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain float data. + /// + public static float Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetFloat(packet.mpPtr, out var value).Assert(); + GC.KeepAlive(packet); + + return value; + } + + [Obsolete("Use Get instead")] + public static float GetFloat(this Packet packet) => Get(packet); + + /// + /// Get the content of a float array Packet as a . + /// + public static float[] Get(this Packet packet, int length) + { + var value = new float[length]; + Get(packet, value); + + return value; + } + + [Obsolete("Use Get instead")] + public static float[] GetFloatArray(this Packet packet, int length) => Get(packet, length); + + /// + /// Get the content of a float array Packet as a . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// If the doesn't contain a float array. + /// + public static void Get(this Packet packet, float[] value) + { + UnsafeNativeMethods.mp_Packet__GetFloatArray_i(packet.mpPtr, value.Length, out var arrayPtr).Assert(); + GC.KeepAlive(packet); + + Marshal.Copy(arrayPtr, value, 0, value.Length); + UnsafeNativeMethods.delete_array__Pf(arrayPtr); + } + + [Obsolete("Use Get instead")] + public static void GetFloatArray(this Packet packet, float[] value) => Get(packet, value); + + /// + /// Get the content of a float vector Packet as a . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain std::vector<float> data. + /// + public static List Get(this Packet> packet) + { + var value = new List(); + Get(packet, value); + + return value; + } + + [Obsolete("Use Get instead")] + public static List GetFloatList(this Packet> packet) => Get(packet); + + /// + /// Get the content of a float vector Packet as a . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// If the doesn't contain std::vector<float> data. + /// + public static void Get(this Packet> packet, List value) + { + UnsafeNativeMethods.mp_Packet__GetFloatVector(packet.mpPtr, out var structArray).Assert(); + GC.KeepAlive(packet); + + structArray.CopyTo(value); + structArray.Dispose(); + } + + [Obsolete("Use Get instead")] + public static void GetFloatList(this Packet> packet, List value) => Get(packet, value); + + /// + /// Get the content of the as an . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain . + /// + public static Image Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetImage(packet.mpPtr, out var ptr).Assert(); + GC.KeepAlive(packet); + + return new Image(ptr, false); + } + + [Obsolete("Use Get instead")] + public static Image GetImage(this Packet packet) => Get(packet); + + /// + /// Get the content of the as a list of . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain std::vector<Image>. + /// + public static List Get(this Packet> packet) + { + var value = new List(); + + Get(packet, value); + return value; + } + + [Obsolete("Use Get instead")] + public static List GetImageList(this Packet> packet) => Get(packet); + + /// + /// Get the content of the as a list of . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// If the doesn't contain std::vector<Image>. + /// + public static void Get(this Packet> packet, List value) + { + UnsafeNativeMethods.mp_Packet__GetImageVector(packet.mpPtr, out var imageArray).Assert(); + GC.KeepAlive(packet); + + foreach (var image in value) + { + image.Dispose(); + } + value.Clear(); + + foreach (var imagePtr in imageArray.AsReadOnlySpan()) + { + value.Add(new Image(imagePtr, false)); + } + } + + [Obsolete("Use Get instead")] + public static void GetImageList(this Packet> packet, List value) => Get(packet, value); + + /// + /// Get the content of the as an . + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain . + /// + public static ImageFrame Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetImageFrame(packet.mpPtr, out var ptr).Assert(); + GC.KeepAlive(packet); + + return new ImageFrame(ptr, false); + } + + [Obsolete("Use Get instead")] + public static ImageFrame GetImageFrame(this Packet packet) => Get(packet); + + /// + /// Get the content of the as an integer. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain data. + /// + public static int Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetInt(packet.mpPtr, out var value).Assert(); + GC.KeepAlive(packet); + + return value; + } + + [Obsolete("Use Get instead")] + public static int GetInt(this Packet packet) => Get(packet); + + /// + /// Get the content of the as a proto message. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain proto messages. + /// + public static T Get(this Packet packet, MessageParser parser) where T : IMessage + { + UnsafeNativeMethods.mp_Packet__GetProtoMessageLite(packet.mpPtr, out var value).Assert(); + GC.KeepAlive(packet); + + var proto = value.Deserialize(parser); + value.Dispose(); + + return proto; + } + + [Obsolete("Use Get instead")] + public static T GetProto(this Packet packet, MessageParser parser) where T : IMessage => Get(packet, parser); + + /// + /// Get the content of the as a proto message list. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// If the doesn't contain a proto message list. + /// + public static List Get(this Packet> packet, MessageParser parser) where T : IMessage + { + var value = new List(); + Get(packet, parser, value); + + return value; + } + + [Obsolete("Use Get instead")] + public static List GetProtoList(this Packet> packet, MessageParser parser) where T : IMessage => Get(packet, parser); + + /// + /// Get the content of the as a proto message list. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// If the doesn't contain a proto message list. + /// + public static void Get(this Packet> packet, MessageParser parser, List value) where T : IMessage + { + UnsafeNativeMethods.mp_Packet__GetVectorOfProtoMessageLite(packet.mpPtr, out var serializedProtoVector).Assert(); + GC.KeepAlive(packet); + + serializedProtoVector.Deserialize(parser, value); + serializedProtoVector.Dispose(); + } + + [Obsolete("Use Get instead")] + public static void GetProtoList(this Packet> packet, MessageParser parser, List value) where T : IMessage => Get(packet, parser, value); + + /// + /// Write the content of the as a proto message list. + /// + /// + /// On some platforms (e.g. Windows), it will abort the process when should be thrown. + /// + /// + /// The to be filled with the content of the . + /// + /// + /// The number of written elements in . + /// + /// + /// If the doesn't contain a proto message list. + /// + public static int WriteTo(this Packet> packet, MessageParser parser, List value) where T : IMessage + { + UnsafeNativeMethods.mp_Packet__GetVectorOfProtoMessageLite(packet.mpPtr, out var serializedProtoVector).Assert(); + GC.KeepAlive(packet); + + var size = serializedProtoVector.WriteTo(parser, value); + serializedProtoVector.Dispose(); + + return size; + } + + [Obsolete("Use WriteTo instead")] + public static int WriteProtoListTo(this Packet> packet, MessageParser parser, List value) where T : IMessage => WriteTo(packet, parser, value); + + public static string Get(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__GetString(packet.mpPtr, out var ptr).Assert(); + GC.KeepAlive(packet); + + var str = Marshal.PtrToStringAnsi(ptr); + UnsafeNativeMethods.delete_array__PKc(ptr); + + return str; + } + + [Obsolete("Use Get instead")] + public static string GetString(this Packet packet) => Get(packet); + + public static T Get(this Packet packet) => throw new NotImplementedException(); + } +} diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs.meta b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs.meta new file mode 100644 index 000000000..d88d0e95c --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketGetterExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9b7503ece01d51ce9cf0651e8058aac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs new file mode 100644 index 000000000..5c0e78530 --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs @@ -0,0 +1,219 @@ +// 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 Google.Protobuf; + +namespace Mediapipe +{ + public static class PacketValidatorExtension + { + /// + /// Validate if the content of the is a boolean. + /// + /// + /// If the doesn't contain bool data. + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsBool(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsBool(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is a std::vector<bool>. + /// + /// + /// If the doesn't contain std::vector<bool>. + /// + public static void Validate(this Packet> packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsBoolVector(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsBoolVector(this Packet> packet) => Validate(packet); + + /// + /// Validate if the content of the is a double. + /// + /// + /// If the doesn't contain double data. + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsDouble(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsDouble(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is a float. + /// + /// + /// If the doesn't contain float data. + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsFloat(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsFloat(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is a float array. + /// + /// + /// If the doesn't contain a float array. + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsFloatArray(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsFloatArray(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is std::vector<float>. + /// + /// + /// If the doesn't contain std::vector<bool>. + /// + public static void Validate(this Packet> packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsFloatVector(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsFloatVector(this Packet> packet) => Validate(packet); + + /// + /// Validate if the content of the is an . + /// + /// + /// If the doesn't contain . + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsGpuBuffer(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsGpuBuffer(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is an . + /// + /// + /// If the doesn't contain . + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsImage(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsImage(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is an . + /// + /// + /// If the doesn't contain . + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsImageFrame(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsImageFrame(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is an . + /// + /// + /// If the doesn't contain . + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsInt(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsInt(this Packet packet) => Validate(packet); + + /// + /// Validate if the content of the is a proto message. + /// + /// + /// If the doesn't contain proto messages. + /// + public static void Validate(this Packet packet) where T : IMessage + { + UnsafeNativeMethods.mp_Packet__ValidateAsProtoMessageLite(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsProtoMessageLite(this Packet packet) where T : IMessage => Validate(packet); + + /// + /// Validate if the content of the is a string. + /// + /// + /// If the doesn't contain string. + /// + public static void Validate(this Packet packet) + { + UnsafeNativeMethods.mp_Packet__ValidateAsString(packet.mpPtr, out var statusPtr).Assert(); + GC.KeepAlive(packet); + + Status.UnsafeAssertOk(statusPtr); + } + + [Obsolete("Use Validate instead")] + public static void ValidateAsString(this Packet packet) => Validate(packet); + } +} diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs.meta b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs.meta new file mode 100644 index 000000000..853e3d19e --- /dev/null +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/PacketValidatorExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7aae9d3f3d7570f50b004b9772a363c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Port/Status.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Port/Status.cs index 7dccc8d1b..27e884c63 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Port/Status.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Framework/Port/Status.cs @@ -137,6 +137,25 @@ protected override void DeleteMpPtr() UnsafeNativeMethods.absl_Status__delete(ptr); } + /// + /// The optimized implementation of . + /// + public static void UnsafeAssertOk(IntPtr statusPtr) + { + var ok = SafeNativeMethods.absl_Status__ok(statusPtr); + if (!ok) + { + using (var status = new Status(statusPtr, true)) + { + status.AssertOk(); + } + } + else + { + UnsafeNativeMethods.absl_Status__delete(statusPtr); + } + } + private bool? _ok; private int? _rawCode; diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs index fec167fc8..edbc28774 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs @@ -4,13 +4,14 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +using System; using System.Collections.Generic; namespace Mediapipe.Tasks.Components.Containers { public static class PacketExtension { - public static void GetClassificationsVector(this Packet packet, List outs) + public static void Get(this Packet> packet, List outs) { UnsafeNativeMethods.mp_Packet__GetClassificationsVector(packet.mpPtr, out var classificationResult).Assert(); var tmp = new ClassificationResult(outs, null); @@ -18,25 +19,37 @@ public static void GetClassificationsVector(this Packet packet, List> packet, List outs) => Get(packet, outs); + + public static void Get(this Packet packet, ref DetectionResult value) { UnsafeNativeMethods.mp_Packet__GetDetectionResult(packet.mpPtr, out var detectionResult).Assert(); DetectionResult.Copy(detectionResult, ref value); detectionResult.Dispose(); } - public static void GetLandmarksList(this Packet packet, List outs) + [Obsolete("Use Get instead")] + public static void GetDetectionResult(this Packet packet, ref DetectionResult value) => Get(packet, ref value); + + public static void Get(this Packet> packet, List outs) { UnsafeNativeMethods.mp_Packet__GetLandmarksVector(packet.mpPtr, out var landmarksArray).Assert(); outs.FillWith(landmarksArray); landmarksArray.Dispose(); } - public static void GetNormalizedLandmarksList(this Packet packet, List outs) + [Obsolete("Use Get instead")] + public static void GetLandmarksList(this Packet> packet, List outs) => Get(packet, outs); + + public static void Get(this Packet> packet, List outs) { UnsafeNativeMethods.mp_Packet__GetNormalizedLandmarksVector(packet.mpPtr, out var landmarksArray).Assert(); outs.FillWith(landmarksArray); landmarksArray.Dispose(); } + + [Obsolete("Use Get instead")] + public static void GetNormalizedLandmarksList(this Packet> packet, List outs) => Get(packet, outs); } } diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceDetector/FaceDetector.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceDetector/FaceDetector.cs index dc9fd6be9..b8e073db5 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceDetector/FaceDetector.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceDetector/FaceDetector.cs @@ -240,7 +240,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(FaceDe return (PacketMap outputPackets) => { - using var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); + using var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); if (outImagePacket == null || outImagePacket.IsEmpty()) { return; @@ -262,7 +262,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(FaceDe private static bool TryBuildFaceDetectorResult(PacketMap outputPackets, ref FaceDetectionResult result) { - using var detectionsPacket = outputPackets.At(_DETECTIONS_OUT_STREAM_NAME); + using var detectionsPacket = outputPackets.At(_DETECTIONS_OUT_STREAM_NAME); if (detectionsPacket.IsEmpty()) { return false; diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceLandmarker/FaceLandmarker.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceLandmarker/FaceLandmarker.cs index 2cf59bef5..4c6cf2a57 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceLandmarker/FaceLandmarker.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/FaceLandmarker/FaceLandmarker.cs @@ -251,7 +251,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(FaceLa return (PacketMap outputPackets) => { - var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); + var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); if (outImagePacket == null || outImagePacket.IsEmpty()) { return; @@ -271,7 +271,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(FaceLa }; } - private static void GetFaceGeometryList(Packet packet, List outs) + private static void GetFaceGeometryList(Packet> packet, List outs) { foreach (var geometry in outs) { @@ -286,7 +286,7 @@ private static bool TryBuildFaceLandmarkerResult(PacketMap outputPackets, List faceGeometriesForRead, ref FaceLandmarkerResult result) { - using var faceLandmarksPacket = outputPackets.At(_NORM_LANDMARKS_STREAM_NAME); + using var faceLandmarksPacket = outputPackets.At>(_NORM_LANDMARKS_STREAM_NAME); if (faceLandmarksPacket.IsEmpty()) { return false; @@ -296,7 +296,7 @@ private static bool TryBuildFaceLandmarkerResult(PacketMap outputPackets, faceLandmarksPacket.GetNormalizedLandmarksList(result.faceLandmarks); var faceBlendshapesList = result.faceBlendshapes; - using var faceBlendshapesPacket = outputPackets.At(_BLENDSHAPES_STREAM_NAME); + using var faceBlendshapesPacket = outputPackets.At>(_BLENDSHAPES_STREAM_NAME); if (faceBlendshapesPacket != null) { faceBlendshapesList ??= new List(); @@ -304,7 +304,7 @@ private static bool TryBuildFaceLandmarkerResult(PacketMap outputPackets, } var faceTransformationMatrixes = result.facialTransformationMatrixes; - using var faceTransformationMatrixesPacket = outputPackets.At(_FACE_GEOMETRY_STREAM_NAME); + using var faceTransformationMatrixesPacket = outputPackets.At>(_FACE_GEOMETRY_STREAM_NAME); if (faceTransformationMatrixesPacket != null) { GetFaceGeometryList(faceTransformationMatrixesPacket, faceGeometriesForRead); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/HandLandmarker/HandLandmarker.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/HandLandmarker/HandLandmarker.cs index 294126312..53d4cd695 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/HandLandmarker/HandLandmarker.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/HandLandmarker/HandLandmarker.cs @@ -232,7 +232,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(HandLa return (PacketMap outputPackets) => { - var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); + var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); if (outImagePacket == null || outImagePacket.IsEmpty()) { return; @@ -254,7 +254,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(HandLa private static bool TryBuildHandLandmarkerResult(PacketMap outputPackets, ref HandLandmarkerResult result) { - using var handLandmarksPacket = outputPackets.At(_HAND_LANDMARKS_STREAM_NAME); + using var handLandmarksPacket = outputPackets.At>(_HAND_LANDMARKS_STREAM_NAME); if (handLandmarksPacket.IsEmpty()) { return false; @@ -263,11 +263,11 @@ private static bool TryBuildHandLandmarkerResult(PacketMap outputPackets, ref Ha var handLandmarks = result.handLandmarks ?? new List(); handLandmarksPacket.GetNormalizedLandmarksList(handLandmarks); - using var handednessPacket = outputPackets.At(_HANDEDNESS_STREAM_NAME); + using var handednessPacket = outputPackets.At>(_HANDEDNESS_STREAM_NAME); var handedness = result.handedness ?? new List(); handednessPacket.GetClassificationsVector(handedness); - using var handWorldLandmarksPacket = outputPackets.At(_HAND_WORLD_LANDMARKS_STREAM_NAME); + using var handWorldLandmarksPacket = outputPackets.At>(_HAND_WORLD_LANDMARKS_STREAM_NAME); var handWorldLandmarks = result.handWorldLandmarks ?? new List(); handWorldLandmarksPacket.GetLandmarksList(handWorldLandmarks); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/PoseLandmarker/PoseLandmarker.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/PoseLandmarker/PoseLandmarker.cs index 5de2bac2f..f01d470d3 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/PoseLandmarker/PoseLandmarker.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Vision/PoseLandmarker/PoseLandmarker.cs @@ -232,7 +232,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(PoseLa return (PacketMap outputPackets) => { - var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); + var outImagePacket = outputPackets.At(_IMAGE_OUT_STREAM_NAME); if (outImagePacket == null || outImagePacket.IsEmpty()) { return; @@ -254,7 +254,7 @@ private static Tasks.Core.TaskRunner.PacketsCallback BuildPacketsCallback(PoseLa private static bool TryBuildPoseLandmarkerResult(PacketMap outputPackets, ref PoseLandmarkerResult result) { - using var poseLandmarksPacket = outputPackets.At(_NORM_LANDMARKS_STREAM_NAME); + using var poseLandmarksPacket = outputPackets.At>(_NORM_LANDMARKS_STREAM_NAME); if (poseLandmarksPacket.IsEmpty()) { return false; @@ -263,12 +263,12 @@ private static bool TryBuildPoseLandmarkerResult(PacketMap outputPackets, ref Po var poseLandmarks = result.poseLandmarks ?? new List(); poseLandmarksPacket.GetNormalizedLandmarksList(poseLandmarks); - using var poseWorldLandmarksPacket = outputPackets.At(_POSE_WORLD_LANDMARKS_STREAM_NAME); + using var poseWorldLandmarksPacket = outputPackets.At>(_POSE_WORLD_LANDMARKS_STREAM_NAME); var poseWorldLandmarks = result.poseWorldLandmarks ?? new List(); poseWorldLandmarksPacket.GetLandmarksList(poseWorldLandmarks); var segmentationMasks = result.segmentationMasks; - using var segmentationMaskPacket = outputPackets.At(_SEGMENTATION_MASK_STREAM_NAME); + using var segmentationMaskPacket = outputPackets.At>(_SEGMENTATION_MASK_STREAM_NAME); if (segmentationMaskPacket != null) { segmentationMasks ??= new List(); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/OutputStream.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/OutputStream.cs index c78bfc56e..997c7b332 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/OutputStream.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/OutputStream.cs @@ -10,17 +10,7 @@ namespace Mediapipe.Unity { - public class OutputEventArgs : EventArgs - { - public readonly T value; - - public OutputEventArgs(T value) - { - this.value = value; - } - } - - public sealed class OutputStream : IDisposable + public sealed class OutputStream : IDisposable { public readonly struct OutputEventArgs { @@ -28,10 +18,10 @@ public readonly struct OutputEventArgs /// that contains the output value. /// As long as it's not , it's guaranteed that is . /// - public readonly Packet packet; + public readonly Packet packet; public readonly long timestampMicrosecond; - internal OutputEventArgs(Packet packet, long timestampMicrosecond) + internal OutputEventArgs(Packet packet, long timestampMicrosecond) { this.packet = packet; this.timestampMicrosecond = timestampMicrosecond; @@ -44,13 +34,13 @@ public readonly struct NextResult /// that contains the output value. /// As long as it's not , it's guaranteed that is . /// - public readonly Packet packet; + public readonly Packet packet; /// /// if the next packet is retrieved successfully; otherwise . /// public readonly bool ok; - public NextResult(Packet packet, bool ok) + public NextResult(Packet packet, bool ok) { this.packet = packet; this.ok = ok; @@ -58,7 +48,7 @@ public NextResult(Packet packet, bool ok) } private static int _Counter = 0; - private static readonly GlobalInstanceTable _InstanceTable = new GlobalInstanceTable(20); + private static readonly GlobalInstanceTable> _InstanceTable = new GlobalInstanceTable>(20); private CalculatorGraph _calculatorGraph; @@ -66,15 +56,15 @@ public NextResult(Packet packet, bool ok) public readonly string streamName; public readonly bool observeTimestampBounds; - private OutputStreamPoller _poller; - private Packet _outputPacket; - private Packet outputPacket + private OutputStreamPoller _poller; + private Packet _outputPacket; + private Packet outputPacket { get { if (_outputPacket == null) { - _outputPacket = new Packet(); + _outputPacket = new Packet(); _outputPacket.Lock(); } return _outputPacket; @@ -90,14 +80,14 @@ private Packet outputPacket private event EventHandler OnReceived; private long _lastTimestampMicrosec; - private Packet _referencePacket; - private Packet referencePacket + private Packet _referencePacket; + private Packet referencePacket { get { if (_referencePacket == null) { - _referencePacket = Packet.CreateForReference(IntPtr.Zero); + _referencePacket = Packet.CreateForReference(IntPtr.Zero); _referencePacket.Lock(); } return _referencePacket; @@ -202,7 +192,7 @@ public void StartPolling() { ThrowIfDisposed(); - _poller = _calculatorGraph.AddOutputStreamPoller(streamName, observeTimestampBounds); + _poller = _calculatorGraph.AddOutputStreamPoller(streamName, observeTimestampBounds); } /// @@ -238,7 +228,7 @@ public void AddListener(EventHandler callback, long emptyPacket OnReceived += (sender, eventArgs) => { - var stream = (OutputStream)sender; + var stream = (OutputStream)sender; if (eventArgs.packet == null && eventArgs.timestampMicrosecond - stream._lastTimestampMicrosec <= emptyPacketThresholdMicrosecond) { return; @@ -344,7 +334,7 @@ private Task StartWaitNextTask() return Task.Factory.StartNew((state) => { - var stream = (OutputStream)state; + var stream = (OutputStream)state; if (stream.Next(out var packet)) // this blocks the thread { if (packet.IsEmpty()) @@ -357,7 +347,7 @@ private Task StartWaitNextTask() }, this); } - private bool Next(out Packet packet) + private bool Next(out Packet packet) { var result = _poller.Next(outputPacket); packet = outputPacket; @@ -380,7 +370,7 @@ private void ClearWaitTask() } } - private void InvokeOnReceived(Packet nextPacket) + private void InvokeOnReceived(Packet nextPacket) { var isEmpty = nextPacket.IsEmpty(); var timestampMicrosec = nextPacket.TimestampMicroseconds(); diff --git a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/Packet/PacketMapTest.cs b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/Packet/PacketMapTest.cs index 1218e9f73..7d9f2cd03 100644 --- a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/Packet/PacketMapTest.cs +++ b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/Packet/PacketMapTest.cs @@ -44,13 +44,13 @@ public void Emplace_ShouldInsertAndDisposePacket() using (var packetMap = new PacketMap()) { Assert.AreEqual(0, packetMap.size); - Assert.IsNull(packetMap.At("value")); + Assert.IsNull(packetMap.At("value")); var flagPacket = Packet.CreateFloat(1.0f); packetMap.Emplace("value", flagPacket); Assert.AreEqual(1, packetMap.size); - Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); + Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); Assert.True(flagPacket.isDisposed); } } @@ -62,11 +62,11 @@ public void Emplace_ShouldIgnoreValue_When_KeyExists() { var oldValuePacket = Packet.CreateFloat(1.0f); packetMap.Emplace("value", oldValuePacket); - Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); + Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); var newValuePacket = Packet.CreateFloat(2.0f); packetMap.Emplace("value", newValuePacket); - Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); + Assert.AreEqual(1.0f, packetMap.At("value").GetFloat()); } } #endregion diff --git a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/PacketTest.cs b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/PacketTest.cs index d7688e1d0..18c1be1f5 100644 --- a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/PacketTest.cs +++ b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Framework/PacketTest.cs @@ -4,6 +4,7 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using NUnit.Framework; @@ -510,49 +511,49 @@ public void CreateStringAt_ShouldReturnNewStringPacket_When_ByteArrayIsGiven() [Test] public void ValidateAsBool_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet(); _ = Assert.Throws(packet.ValidateAsBool); } [Test] public void ValidateAsBoolVector_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet>(); _ = Assert.Throws(packet.ValidateAsBoolVector); } [Test] public void ValidateAsDouble_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet(); _ = Assert.Throws(packet.ValidateAsDouble); } [Test] public void ValidateAsFloat_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet(); _ = Assert.Throws(packet.ValidateAsFloat); } [Test] public void ValidateAsFloatArray_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet(); _ = Assert.Throws(packet.ValidateAsFloatArray); } [Test] public void ValidateAsFloatVector_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet>(); _ = Assert.Throws(packet.ValidateAsFloatVector); } [Test] public void ValidateAsImage_ShouldThrow_When_ValueIsNotSet() { - using var packet = new Packet(); + using var packet = new Packet(); _ = Assert.Throws(packet.ValidateAsImage); } #endregion diff --git a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Tasks/Core/TaskRunnerTest.cs b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Tasks/Core/TaskRunnerTest.cs index 36e4cbf11..30a743b41 100644 --- a/Packages/com.github.homuler.mediapipe/Tests/EditMode/Tasks/Core/TaskRunnerTest.cs +++ b/Packages/com.github.homuler.mediapipe/Tests/EditMode/Tasks/Core/TaskRunnerTest.cs @@ -89,7 +89,7 @@ public void Process_ShouldReturnOutput_When_InputIsValid() packetMap.Emplace("in", Packet.CreateInt(1)); var outputMap = taskRunner.Process(packetMap); - Assert.AreEqual(1, outputMap.At("out").GetInt()); + Assert.AreEqual(1, outputMap.At("out").GetInt()); Assert.True(packetMap.isDisposed); } }