From c8f61ce6b8fe4a2a6bddc203a40d842c644eb566 Mon Sep 17 00:00:00 2001 From: Junrou Nishida Date: Sun, 12 Jan 2025 18:30:07 +0900 Subject: [PATCH] fix: acquire a lock when drawing DetectionResult annotations (#1306) --- .../Components/Containers/DetectionResult.cs | 37 +++++++++++++++++++ .../Components/Containers/ListExtension.cs | 13 +++++++ .../DetectionResultAnnotationController.cs | 19 ++++++++-- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/DetectionResult.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/DetectionResult.cs index a34f9378a..e15cccf58 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/DetectionResult.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/DetectionResult.cs @@ -113,6 +113,29 @@ internal static void Copy(in NativeDetection source, ref Detection destination) destination = new Detection(categories, boundingBox, keypoints); } + public void CloneTo(ref Detection destination) + { + if (categories == null) + { + destination = default; + return; + } + + var dstCategories = destination.categories ?? new List(categories.Count); + dstCategories.Clear(); + dstCategories.AddRange(categories); + + var dstKeypoints = destination.keypoints; + if (keypoints != null) + { + dstKeypoints ??= new List(keypoints.Count); + dstKeypoints.Clear(); + dstKeypoints.AddRange(keypoints); + } + + destination = new Detection(dstCategories, boundingBox, dstKeypoints); + } + public override string ToString() => $"{{ \"categories\": {Util.Format(categories)}, \"boundingBox\": {boundingBox}, \"keypoints\": {Util.Format(keypoints)} }}"; } @@ -173,6 +196,20 @@ internal static void Copy(NativeDetectionResult source, ref DetectionResult dest destination = new DetectionResult(detections); } + public void CloneTo(ref DetectionResult destination) + { + if (detections == null) + { + destination = default; + return; + } + + var dstDetections = destination.detections ?? new List(detections.Count); + dstDetections.CopyFrom(detections); + + destination = new DetectionResult(dstDetections); + } + public override string ToString() => $"{{ \"detections\": {Util.Format(detections)} }}"; } } diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/ListExtension.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/ListExtension.cs index 9530c962b..fcb33df37 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/ListExtension.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/ListExtension.cs @@ -23,6 +23,19 @@ public static void CopyFrom(this List target, List target, List source) + { + target.ResizeTo(source.Count); + + var i = 0; + foreach (var x in source) + { + var v = target[i]; + x.CloneTo(ref v); + target[i++] = v; + } + } + public static void CopyFrom(this List target, List source) { target.ResizeTo(source.Count); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/Annotation/DetectionResultAnnotationController.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/Annotation/DetectionResultAnnotationController.cs index e4df7b5e6..40e5c0a6e 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/Annotation/DetectionResultAnnotationController.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/Annotation/DetectionResultAnnotationController.cs @@ -14,6 +14,7 @@ public class DetectionResultAnnotationController : AnnotationController UpdateCurrentTarget(target, ref _currentTarget); + public void DrawLater(mptcc.DetectionResult target) => UpdateCurrentTarget(target); + + protected void UpdateCurrentTarget(mptcc.DetectionResult newTarget) + { + lock (_currentTargetLock) + { + newTarget.CloneTo(ref _currentTarget); + isStale = true; + } + } protected override void SyncNow() { - isStale = false; - annotation.Draw(_currentTarget, imageSize, _threshold); + lock (_currentTargetLock) + { + isStale = false; + annotation.Draw(_currentTarget, imageSize, _threshold); + } } } }