Skip to content

Commit

Permalink
Add method to get a body index map.
Browse files Browse the repository at this point in the history
  • Loading branch information
thorikawa committed Aug 21, 2019
1 parent 351dfd7 commit 04cd54d
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
99 changes: 99 additions & 0 deletions unity/Assets/AzureKinectDK/Scripts/M4ABT/BodyFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,105 @@ public UInt32 GetBodyId(UInt32 index)
}
}

// This function retrieves a native image handle from the native API.
//
// If this is the first time calling the property, we construct a new wrapper
// If the handle is for an Image we have already constructed a wrapper for, we return the existing wrapper
// If the handle is for a different Image, or if the wrapper has already been disposed, we construct a new wrapper and dispose the old one
private Image GetImageWrapperAndDisposePrevious(Func<BodyTrackingNativeMethods.k4abt_frame_t, NativeMethods.k4a_image_t> nativeMethod,
ref Image cache)
{
// Lock must be held to ensure the Image in cache is not replaced while we are inspecting it
// It is still possible for that Image to be accessed or Disposed while this lock is held
lock (this)
{
if (this.disposedValue)
{
throw new ObjectDisposedException(nameof(Capture));
}

NativeMethods.k4a_image_t image = nativeMethod(this.handle);
// This try block ensures that we close image
try
{
if (cache != null)
{
IntPtr imageHandle = image.DangerousGetHandle();

// Only attempt to access cache in this try block
try
{
// If cache was disposed before we called the native accessor (by the caller or another thread),
// the handle could have been reused and the values would incorrectly match. However, cache.DangerousGetHandle()
// will throw an exception, and we will correctly construct a new image wrapper.
if (cache.DangerousGetHandle().DangerousGetHandle() != imageHandle)
{
// The image has changed, invalidate the current image and construct a new wrapper
cache.Dispose();
cache = null;
}
}
catch (ObjectDisposedException)
{
// If cache has been disposed by the caller or another thread we will discard
// it and construct a new wrapper
cache = null;
}
}

if (cache == null && !image.IsInvalid)
{
// Construct a new wrapper and return it
// The native function may have returned
cache = new Image(image);

// Since we have wrapped image, it is now owned by the UnsafeImage object and we should no longer close it
image = null;
}
}
finally
{
// Ensure the native handle is closed if we have a failure creating the Image object
if (image != null)
{
image.Close();
}
}

return cache;
}
}

private Image _BodyIndexMap;

public Image BodyIndexMap
{
get
{
return this.GetImageWrapperAndDisposePrevious(BodyTrackingNativeMethods.k4abt_frame_get_body_index_map, ref this._BodyIndexMap);
}
set
{
lock (this)
{
if (this.disposedValue)
{
throw new ObjectDisposedException(nameof(BodyFrame));
}

// If the assignment is a new managed wrapper we need
// to release the reference to the old wrapper.
// If it is the same object though, we should not dispose it.
if (this._BodyIndexMap != null && !object.ReferenceEquals(
this._BodyIndexMap, value))
{
this._BodyIndexMap.Dispose();
}
this._BodyIndexMap = value;
}
}
}

public BodyFrame Reference()
{
lock (this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ protected override bool ReleaseHandle()
[NativeReference]
public static extern UInt32 k4abt_frame_get_body_id(k4abt_frame_t body_frame_handle, UInt32 index);

[DllImport("k4abt", CallingConvention = CallingConvention.Cdecl)]
[NativeReference]
public static extern NativeMethods.k4a_image_t k4abt_frame_get_body_index_map(k4abt_frame_t body_frame_handle);

#endregion

}
Expand Down

0 comments on commit 04cd54d

Please sign in to comment.