private Frame ApplyFilter(Frame frame, FrameSource frameSource, FramesReleaser framesReleaser, RsProcessingBlock vpb, Action <Frame> handleFrame)
    {
        if (!vpb.CanProcess(frame))
        {
            return(frame);
        }

        // run the processing block.
        var processedFrame = vpb.Process(frame, frameSource, framesReleaser);

        // incase fork is requested, notify on new frame and use the original frame for the new frameset.
        if (vpb.Fork())
        {
            handleFrame(processedFrame);
            processedFrame.Dispose();
            return(frame);
        }

        // avoid disposing the frame incase the filter returns the original frame.
        if (processedFrame == frame)
        {
            return(frame);
        }

        // replace the current frame with the processed one to be used as the input to the next iteration (next filter)
        frame.Dispose();
        return(processedFrame);
    }
 private FrameSet HandleMultiFramesProcessingBlocks(FrameSet frameSet, FrameSource frameSource, FramesReleaser framesReleaser, RsProcessingBlock videoProcessingBlock, Action <FrameSet> handleFrameSet)
 {
     using (var frame = frameSet.AsFrame())
     {
         if (videoProcessingBlock.CanProcess(frame))
         {
             using (var f = videoProcessingBlock.Process(frame, frameSource, framesReleaser))
             {
                 if (videoProcessingBlock.Fork())
                 {
                     handleFrameSet(FrameSet.FromFrame(f, framesReleaser));
                 }
                 else
                 {
                     return(FrameSet.FromFrame(f, framesReleaser));
                 }
             }
         }
     }
     return(frameSet);
 }