Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# and unity #2592

Merged
merged 6 commits into from
Oct 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion wrappers/csharp/Intel.RealSense/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_library(${PROJECT_NAME}
StreamProfile.cs
Types.cs
SoftwareDevice.cs
Option.cs
.nuget/Intel.RealSense.targets

Properties/AssemblyInfo.cs
Expand Down Expand Up @@ -56,4 +57,8 @@ add_dependencies(${PROJECT_NAME} realsense2)

set_target_properties (${PROJECT_NAME} PROPERTIES
FOLDER Wrappers/csharp
)
)

set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_REFERENCES
"System"
)
10 changes: 8 additions & 2 deletions wrappers/csharp/Intel.RealSense/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ internal Device(IntPtr dev)

public class CameraInfos
{
IntPtr m_device;
readonly IntPtr m_device;
public CameraInfos(IntPtr device) { m_device = device; }

public string this[CameraInfo info]
Expand Down Expand Up @@ -258,6 +258,12 @@ internal PlaybackDevice(IntPtr dev) : base(dev)

}


protected override void Dispose(bool disposing)
{
// Intentionally empty, does not own the native device, only wraps it.
}

public static PlaybackDevice FromDevice(Device dev)
{
object error;
Expand Down Expand Up @@ -346,7 +352,7 @@ public float Speed

public class RecordDevice : Device
{
IntPtr m_dev;
readonly IntPtr m_dev;

public RecordDevice(Device dev, string file) : base(IntPtr.Zero)
{
Expand Down
161 changes: 124 additions & 37 deletions wrappers/csharp/Intel.RealSense/Frame.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Intel.RealSense
{
public class Frame : IDisposable
{
internal HandleRef m_instance;
public static readonly FramePool<Frame> Pool = new FramePool<Frame>(ptr => new Frame(ptr));

public IntPtr NativePtr { get { return m_instance.Handle; } }

public Frame(IntPtr ptr)
{
m_instance = new HandleRef(this, ptr);
NativeMethods.rs2_keep_frame(m_instance.Handle);
}

internal static Frame CreateFrame(IntPtr ptr)
{
object error;
if (NativeMethods.rs2_is_frame_extendable_to(ptr, Extension.Points, out error) > 0)
return Points.Pool.Get(ptr);
else if (NativeMethods.rs2_is_frame_extendable_to(ptr, Extension.DepthFrame, out error) > 0)
return DepthFrame.Pool.Get(ptr);
else if (NativeMethods.rs2_is_frame_extendable_to(ptr, Extension.VideoFrame, out error) > 0)
return VideoFrame.Pool.Get(ptr);
else
return Frame.Pool.Get(ptr);
}

#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
internal bool disposedValue = false; // To detect redundant calls

protected virtual void Dispose(bool disposing)
{
Expand Down Expand Up @@ -49,18 +65,28 @@ public void Dispose()
}
#endregion

public void Release()
public virtual void Release()
{
if (m_instance.Handle != IntPtr.Zero)
NativeMethods.rs2_release_frame(m_instance.Handle);
m_instance = new HandleRef(this, IntPtr.Zero);
Pool.Release(this);
}

public Frame Clone()
{
object error;
NativeMethods.rs2_frame_add_ref(m_instance.Handle, out error);
return new Frame(m_instance.Handle);
return CreateFrame(m_instance.Handle);
}

public bool IsComposite
{
get
{
object error;
return NativeMethods.rs2_is_frame_extendable_to(m_instance.Handle, Extension.CompositeFrame, out error) > 0;
}
}

public IntPtr Data
Expand All @@ -77,7 +103,7 @@ public StreamProfile Profile
get
{
object error;
return new StreamProfile(NativeMethods.rs2_get_frame_stream_profile(m_instance.Handle, out error));
return StreamProfile.Pool.Get(NativeMethods.rs2_get_frame_stream_profile(m_instance.Handle, out error));
}
}

Expand Down Expand Up @@ -115,6 +141,8 @@ public TimestampDomain TimestampDomain

public class VideoFrame : Frame
{
public static readonly new FramePool<VideoFrame> Pool = new FramePool<VideoFrame>(ptr => new VideoFrame(ptr));

public VideoFrame(IntPtr ptr) : base(ptr)
{
}
Expand Down Expand Up @@ -164,26 +192,69 @@ public int BitsPerPixel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
//public void CopyTo<T>(out T[] array)
public void CopyTo<T>(T[] array)
{
if (array == null)
throw new ArgumentNullException("array");
throw new ArgumentNullException(nameof(array));
var handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
//System.Diagnostics.Debug.Assert((array.Length * Marshal.SizeOf(typeof(T))) == (Stride * Height));
CopyTo(handle.AddrOfPinnedObject());
}
finally
{
handle.Free();
}
}

public void CopyTo(IntPtr ptr)
{
//System.Diagnostics.Debug.Assert(ptr != IntPtr.Zero);
NativeMethods.memcpy(ptr, Data, Stride * Height);
}

/// <summary>
/// Copy from data from managed array
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
public void CopyFrom<T>(T[] array)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
var handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
//System.Diagnostics.Debug.Assert((array.Length * Marshal.SizeOf(typeof(T))) == (Stride * Height));
NativeMethods.memcpy(handle.AddrOfPinnedObject(), Data, Stride * Height);
CopyFrom(handle.AddrOfPinnedObject());
}
finally
{
handle.Free();
}
}

public void CopyFrom(IntPtr ptr)
{
//System.Diagnostics.Debug.Assert(ptr != IntPtr.Zero);
NativeMethods.memcpy(Data, ptr, Stride * Height);
}

public override void Release()
{
//base.Release();
if (m_instance.Handle != IntPtr.Zero)
NativeMethods.rs2_release_frame(m_instance.Handle);
m_instance = new HandleRef(this, IntPtr.Zero);
Pool.Release(this);
}
}

public class DepthFrame : VideoFrame
{
public static readonly new FramePool<DepthFrame> Pool = new FramePool<DepthFrame>(ptr => new DepthFrame(ptr));

public DepthFrame(IntPtr ptr) : base(ptr)
{
}
Expand All @@ -193,11 +264,22 @@ public float GetDistance(int x, int y)
object error;
return NativeMethods.rs2_depth_frame_get_distance(m_instance.Handle, x, y, out error);
}

public override void Release()
{
//base.Release();
if (m_instance.Handle != IntPtr.Zero)
NativeMethods.rs2_release_frame(m_instance.Handle);
m_instance = new HandleRef(this, IntPtr.Zero);
Pool.Release(this);
}
}


public class Points : Frame
{
public static readonly new FramePool<Points> Pool = new FramePool<Points>(ptr => new Points(ptr));

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct Vertex
{
Expand All @@ -210,6 +292,7 @@ public struct TextureCoordinate
public float u;
public float v;
}

public Points(IntPtr ptr) : base(ptr)
{
}
Expand Down Expand Up @@ -240,7 +323,7 @@ public IntPtr VertexData
public void CopyTo(Vertex[] array)
{
if (array == null)
throw new ArgumentNullException("array");
throw new ArgumentNullException(nameof(array));
var handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
Expand All @@ -267,7 +350,7 @@ public IntPtr TextureData
public void CopyTo(TextureCoordinate[] textureArray)
{
if (textureArray == null)
throw new ArgumentNullException("textureArray");
throw new ArgumentNullException(nameof(textureArray));

var handle = GCHandle.Alloc(textureArray, GCHandleType.Pinned);
try
Expand All @@ -280,45 +363,49 @@ public void CopyTo(TextureCoordinate[] textureArray)
handle.Free();
}
}
}



class FrameMarshaler : ICustomMarshaler
{
private static FrameMarshaler Instance;

public static ICustomMarshaler GetInstance(string s)
{
if (Instance == null)
{
Instance = new FrameMarshaler();
}
return Instance;
}

public void CleanUpManagedData(object ManagedObj)
public override void Release()
{
//base.Release();
if (m_instance.Handle != IntPtr.Zero)
NativeMethods.rs2_release_frame(m_instance.Handle);
m_instance = new HandleRef(this, IntPtr.Zero);
Pool.Release(this);
}
}

public void CleanUpNativeData(IntPtr pNativeData)
{
}
public class FramePool<T> where T : Frame
{
readonly Stack<T> stack = new Stack<T>();
readonly object locker = new object();
readonly Func<IntPtr, T> factory;

public int GetNativeDataSize()
public FramePool(Func<IntPtr, T> factory)
{
//return IntPtr.Size;
return -1;
this.factory = factory;
}

public IntPtr MarshalManagedToNative(object ManagedObj)
public T Get(IntPtr ptr)
{
throw new NotImplementedException();

lock (locker)
{
if(stack.Count == 0)
return factory(ptr);
T f = stack.Pop();
f.m_instance = new HandleRef(f, ptr);
f.disposedValue = false;
//NativeMethods.rs2_keep_frame(ptr);
return f;
}
}

public object MarshalNativeToManaged(IntPtr pNativeData)
public void Release(T t)
{
return new Frame(pNativeData);
lock (locker)
{
stack.Push(t);
}
}
}
}
22 changes: 12 additions & 10 deletions wrappers/csharp/Intel.RealSense/FrameQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,37 @@ public class FrameQueue : IDisposable, IEnumerable<Frame>
{
internal HandleRef m_instance;

public FrameQueue(int capacity = 10)
public FrameQueue(int capacity = 1)
{
object error;
m_instance = new HandleRef(this, NativeMethods.rs2_create_frame_queue(capacity, out error));
}

public bool PollForFrame(out Frame frame, FramesReleaser releaser = null)
public bool PollForFrame(out Frame frame)
{
object error;
if (NativeMethods.rs2_poll_for_frame(m_instance.Handle, out frame, out error) > 0)
IntPtr ptr;
if (NativeMethods.rs2_poll_for_frame(m_instance.Handle, out ptr, out error) > 0)
{
frame = FramesReleaser.ScopedReturn(releaser, FrameSet.CreateFrame(frame.m_instance.Handle));
frame = Frame.CreateFrame(ptr);
return true;
}
frame = null;
return false;
}

public Frame WaitForFrame(FramesReleaser releaser = null)
public Frame WaitForFrame(uint timeout_ms = 5000)
{
object error;
var ptr = NativeMethods.rs2_wait_for_frame(m_instance.Handle, 5000, out error);
return FramesReleaser.ScopedReturn(releaser, FrameSet.CreateFrame(ptr));
var ptr = NativeMethods.rs2_wait_for_frame(m_instance.Handle, timeout_ms, out error);
return Frame.CreateFrame(ptr);
}

public FrameSet WaitForFrames(FramesReleaser releaser = null)
public FrameSet WaitForFrames(uint timeout_ms = 5000)
{
object error;
var ptr = NativeMethods.rs2_wait_for_frame(m_instance.Handle, 5000, out error);
return FramesReleaser.ScopedReturn(releaser, new FrameSet(ptr));
var ptr = NativeMethods.rs2_wait_for_frame(m_instance.Handle, timeout_ms, out error);
return FrameSet.Pool.Get(ptr);
}

public void Enqueue(Frame f)
Expand Down
Loading