You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.8 KiB

// 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);
}
/// <summary>
/// Base class for processing blocks
/// </summary>
public class ProcessingBlock : Base.Object, IProcessingBlock
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly FrameQueue queue = new FrameQueue(1);
/// <inheritdoc/>
public IOptionsContainer Options { get; private set; }
public InfoCollection Info { get; private set; }
/// <summary>
/// Gets the internal queue
/// </summary>
public FrameQueue Queue
{
get
{
return queue;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="ProcessingBlock"/> class.
/// <para>
/// Starts the processing block directing it's output to the <see cref="Queue"/>
/// </para>
/// </summary>
/// <param name="ptr">native <c>rs2_processing_block*</c> pointer</param>
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);
}
/// <summary>
/// Process frame and return the result
/// </summary>
/// <param name="original">Frame to process</param>
/// <returns>Processed frame</returns>
public Frame Process(Frame original)
{
return Process<Frame>(original);
}
/// <summary>
/// Process frame and return the result
/// </summary>
/// <typeparam name="T">Type of frame to return</typeparam>
/// <param name="original">Frame to process</param>
/// <returns>Processed frame</returns>
/// <exception cref="InvalidOperationException">Thrown when errors occur during processing</exception>
public T Process<T>(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<T>(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);
}
/// <summary>Test if the given processing block can be extended to the requested extension</summary>
/// <param name="extension">The extension to which the processing block should be tested if it is extendable</param>
/// <returns><see langword="true"/> iff the processing block can be extended to the given extension</returns>
public bool Is(Extension extension)
{
object error;
return NativeMethods.rs2_is_processing_block_extendable_to(Handle, extension, out error) > 0;
}
/// <summary>Cast to a strongly-typed <see cref="ProcessingBlock"/> subclass</summary>
/// <typeparam name="T"><see cref="ProcessingBlock"/> type or subclass</typeparam>
/// <returns>an instance of <typeparamref name="T"/></returns>
public T As<T>()
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);
}
}
}