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
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);
|
|
}
|
|
}
|
|
} |