001/*----------------------------------------------------------------------------*/
002/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.cscore;
009
010import org.opencv.core.Mat;
011
012/**
013 * A sink for user code to accept video frames as OpenCV images.
014 */
015public class CvSink extends VideoSink {
016  /**
017   * Create a sink for accepting OpenCV images.
018   * WaitForFrame() must be called on the created sink to get each new
019   * image.
020   * @param name Source name (arbitrary unique identifier)
021   */
022  public CvSink(String name) {
023    super(CameraServerJNI.createCvSink(name));
024  }
025
026  /// Create a sink for accepting OpenCV images in a separate thread.
027  /// A thread will be created that calls WaitForFrame() and calls the
028  /// processFrame() callback each time a new frame arrives.
029  /// @param name Source name (arbitrary unique identifier)
030  /// @param processFrame Frame processing function; will be called with a
031  ///        time=0 if an error occurred.  processFrame should call GetImage()
032  ///        or GetError() as needed, but should not call (except in very
033  ///        unusual circumstances) WaitForImage().
034  //public CvSink(llvm::StringRef name,
035  //       std::function<void(uint64_t time)> processFrame) {
036  //  super(CameraServerJNI.createCvSinkCallback(name, processFrame));
037  //}
038
039  /**
040   * Set sink description.
041   * @param description Description
042   */
043  public void setDescription(String description) {
044    CameraServerJNI.setSinkDescription(m_handle, description);
045  }
046
047  /**
048   * Wait for the next frame and get the image.
049   * Times out (returning 0) after 0.225 seconds.
050   * The provided image will have three 3-bit channels stored in BGR order.
051   * @return Frame time, or 0 on error (call GetError() to obtain the error
052   *         message)
053   */
054  public long grabFrame(Mat image) {
055    return grabFrame(image, 0.225);
056  }
057
058  /**
059   * Wait for the next frame and get the image.
060   * Times out (returning 0) after timeout seconds.
061   * The provided image will have three 3-bit channels stored in BGR order.
062   * @return Frame time, or 0 on error (call GetError() to obtain the error
063   *         message); the frame time is in 1 us increments.
064   */
065  public long grabFrame(Mat image, double timeout) {
066    return CameraServerJNI.grabSinkFrameTimeout(m_handle, image.nativeObj, timeout);
067  }
068
069  /**
070   * Wait for the next frame and get the image.  May block forever.
071   * The provided image will have three 3-bit channels stored in BGR order.
072   * @return Frame time, or 0 on error (call GetError() to obtain the error
073   *         message); the frame time is in 1 us increments.
074   */
075  public long grabFrameNoTimeout(Mat image) {
076    return CameraServerJNI.grabSinkFrame(m_handle, image.nativeObj);
077  }
078
079  /**
080   * Get error string.  Call this if WaitForFrame() returns 0 to determine
081   * what the error is.
082   */
083  public String getError() {
084    return CameraServerJNI.getSinkError(m_handle);
085  }
086
087  /**
088   * Enable or disable getting new frames.
089   * Disabling will cause processFrame (for callback-based CvSinks) to not
090   * be called and WaitForFrame() to not return.  This can be used to save
091   * processor resources when frames are not needed.
092   */
093  public void setEnabled(boolean enabled) {
094    CameraServerJNI.setSinkEnabled(m_handle, enabled);
095  }
096}