// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.
namespace Intel.RealSense
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class FrameSet : Frame, ICompositeDisposable, IEnumerable
{
private readonly List disposables = new List();
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly Enumerator enumerator;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int count;
///
/// Create a new from
///
/// a composite frame
/// a new to be disposed
/// Thrown when frame is not a composite frame
public static FrameSet FromFrame(Frame composite)
{
if (composite.IsComposite)
{
object error;
NativeMethods.rs2_frame_add_ref(composite.Handle, out error);
return Create(composite.Handle);
}
throw new ArgumentException("The frame is a not composite frame", nameof(composite));
}
[Obsolete("This method is obsolete. Use DisposeWith method instead")]
public static FrameSet FromFrame(Frame composite, FramesReleaser releaser)
{
return FromFrame(composite).DisposeWith(releaser);
}
internal override void Initialize()
{
object error;
count = NativeMethods.rs2_embedded_frames_count(Handle, out error);
enumerator.Reset();
disposables.Clear();
}
internal FrameSet(IntPtr ptr)
: base(ptr)
{
object error;
count = NativeMethods.rs2_embedded_frames_count(Handle, out error);
enumerator = new Enumerator(this);
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public new bool IsComposite => true;
///
/// Cast this to a
///
/// a frame to be disposed
public Frame AsFrame()
{
object error;
NativeMethods.rs2_frame_add_ref(Handle, out error);
return Frame.Create(Handle);
}
///
/// Invoke the delegate on each frame in the set
///
/// Delegate to invoke
public void ForEach(Action action)
{
for (int i = 0; i < count; i++)
{
using (var frame = this[i])
{
action(frame);
}
}
}
public T FirstOrDefault(Stream stream, Format format = Format.Any)
where T : Frame
{
return FirstOrDefault(stream, format)?.Cast();
}
public Frame FirstOrDefault(Stream stream, Format format = Format.Any)
{
for (int i = 0; i < count; i++)
{
var frame = this[i];
using (var fp = frame.Profile)
if (fp.Stream == stream && (format == Format.Any || fp.Format == format))
{
return frame;
}
frame.Dispose();
}
return null;
}
public T FirstOrDefault(Predicate predicate)
where T : Frame
{
object error;
for (int i = 0; i < count; i++)
{
var ptr = NativeMethods.rs2_extract_frame(Handle, i, out error);
var frame = Frame.Create(ptr);
if (predicate(frame))
{
return frame;
}
frame.Dispose();
}
return null;
}
///
/// Retrieve back the first frame of specific stream type, if no frame found, error will be thrown
///
/// type or subclass
/// stream type of frame to be retrieved
/// format type of frame to be retrieved, defaults to
/// first found frame with type and type
/// Thrown when requested type not found
public T First(Stream stream, Format format = Format.Any)
where T : Frame
{
var f = FirstOrDefault(stream, format);
if (f == null)
{
throw new ArgumentException("Frame of requested stream type was not found!");
}
return f;
}
///
/// Retrieve back the first frame of specific stream type, if no frame found, error will be thrown
///
/// stream type of frame to be retrieved
/// format type of frame to be retrieved, defaults to
/// first found frame with type and type
/// Thrown when requested type not found
///
public Frame First(Stream stream, Format format = Format.Any) => First(stream, format);
/// Gets the first depth frame
public DepthFrame DepthFrame => FirstOrDefault(Stream.Depth, Format.Z16);
/// Gets the first color frame
public VideoFrame ColorFrame => FirstOrDefault(Stream.Color);
/// Gets the first infrared frame
public VideoFrame InfraredFrame => FirstOrDefault(Stream.Infrared);
/// Gets the first fisheye frame
public VideoFrame FishEyeFrame => FirstOrDefault(Stream.Fisheye);
/// Gets the first pose frame
public PoseFrame PoseFrame => FirstOrDefault(Stream.Pose);
///
public IEnumerator GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
///
IEnumerator IEnumerable.GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
/// Gets the number of frames embedded within a composite frame
/// Number of embedded frames
public int Count => count;
/// Extract frame from within a composite frame
/// Index of the frame to extract within the composite frame
/// returns reference to a frame existing within the composite frame
/// Thrown when is out of range
public Frame this[int index]
{
get
{
if (index < count)
{
object error;
var ptr = NativeMethods.rs2_extract_frame(Handle, index, out error);
return Frame.Create(ptr);
}
throw new ArgumentOutOfRangeException(nameof(index));
}
}
public Frame this[Stream stream, int index = 0]
{
get
{
return FirstOrDefault(f =>
{
using (var p = f.Profile)
{
return p.Stream == stream && p.Index == index;
}
});
}
}
public Frame this[Stream stream, Format format, int index = 0]
{
get
{
return FirstOrDefault(f =>
{
using (var p = f.Profile)
{
return p.Stream == stream && p.Format == format && p.Index == index;
}
});
}
}
public static new FrameSet Create(IntPtr ptr)
{
return ObjectPool.Get