// 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.Linq;
using System.Runtime.InteropServices;
using Intel.RealSense.Base;
using System.Reflection;
public interface IProcessingBlock : IOptions
{
Frame Process(Frame original);
}
///
/// Base class for processing blocks
///
public class ProcessingBlock : Base.Object, IProcessingBlock
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly FrameQueue queue = new FrameQueue(1);
///
public IOptionsContainer Options { get; private set; }
public InfoCollection Info { get; private set; }
///
/// Gets the internal queue
///
public FrameQueue Queue
{
get
{
return queue;
}
}
///
/// Initializes a new instance of the class.
///
/// Starts the processing block directing it's output to the
///
///
/// native rs2_processing_block* pointer
public ProcessingBlock(IntPtr ptr)
: base(ptr, NativeMethods.rs2_delete_processing_block)
{
object error;
Options = new OptionsList(Handle);
Info = new InfoCollection(NativeMethods.rs2_supports_processing_block_info, NativeMethods.rs2_get_processing_block_info, Handle);
NativeMethods.rs2_start_processing_queue(Handle, queue.Handle, out error);
}
///
/// Process frame and return the result
///
/// Frame to process
/// Processed frame
public Frame Process(Frame original)
{
return Process(original);
}
///
/// Process frame and return the result
///
/// Type of frame to return
/// Frame to process
/// Processed frame
/// Thrown when errors occur during processing
public T Process(Frame original)
where T : Frame
{
object error;
NativeMethods.rs2_frame_add_ref(original.Handle, out error);
NativeMethods.rs2_process_frame(Handle, original.Handle, out error);
T f;
if (queue.PollForFrame(out f))
{
return f;
}
// this occurs when the sdk runs out of frame resources and allocate_video_frame fails
// sadly, that exception doesn't propagate here...
// usually a sign of not properly disposing of frames
throw new InvalidOperationException($"Error while running {GetType().Name} processing block, check the log for info");
}
protected override void Dispose(bool disposing)
{
queue.Dispose();
(Options as OptionsList).Dispose();
base.Dispose(disposing);
}
/// Test if the given processing block can be extended to the requested extension
/// The extension to which the processing block should be tested if it is extendable
/// iff the processing block can be extended to the given extension
public bool Is(Extension extension)
{
object error;
return NativeMethods.rs2_is_processing_block_extendable_to(Handle, extension, out error) > 0;
}
/// Cast to a strongly-typed subclass
/// type or subclass
/// an instance of
public T As()
where T : ProcessingBlock
{
return (T)Activator.CreateInstance(
typeof(T),
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance,
null,
new object[] { Handle },
null);
}
}
public static class IProcessingBlockExtensions
{
public static Frame ApplyFilter(this Frame frame, IProcessingBlock block)
{
return block.Process(frame);
}
}
}