001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.cscore;
006
007import edu.wpi.first.cscore.VideoMode.PixelFormat;
008import org.opencv.core.Mat;
009
010/**
011 * A sink for user code to accept video frames as OpenCV images. These sinks require the WPILib
012 * OpenCV builds. For an alternate OpenCV, see the documentation how to build your own with RawSink.
013 */
014public class CvSink extends ImageSink {
015  /**
016   * Create a sink for accepting OpenCV images. WaitForFrame() must be called on the created sink to
017   * get each new image.
018   *
019   * @param name Source name (arbitrary unique identifier)
020   * @param pixelFormat Source pixel format
021   */
022  public CvSink(String name, PixelFormat pixelFormat) {
023    super(CameraServerCvJNI.createCvSink(name, pixelFormat.getValue()));
024  }
025
026  /**
027   * Create a sink for accepting OpenCV images. WaitForFrame() must be called on the created sink to
028   * get each new image. Defaults to kBGR for pixelFormat
029   *
030   * @param name Source name (arbitrary unique identifier)
031   */
032  public CvSink(String name) {
033    this(name, PixelFormat.kBGR);
034  }
035
036  /// Create a sink for accepting OpenCV images in a separate thread.
037  /// A thread will be created that calls WaitForFrame() and calls the
038  /// processFrame() callback each time a new frame arrives.
039  /// @param name Source name (arbitrary unique identifier)
040  /// @param processFrame Frame processing function; will be called with a
041  ///        time=0 if an error occurred.  processFrame should call GetImage()
042  ///        or GetError() as needed, but should not call (except in very
043  ///        unusual circumstances) WaitForImage().
044  // public CvSink(wpi::StringRef name,
045  //       std::function<void(uint64_t time)> processFrame) {
046  //  super(CameraServerJNI.createCvSinkCallback(name, processFrame));
047  // }
048
049  /**
050   * Wait for the next frame and get the image. Times out (returning 0) after 0.225 seconds. The
051   * provided image will have three 3-bit channels stored in BGR order.
052   *
053   * @param image Where to store the image.
054   * @return Frame time, or 0 on error (call GetError() to obtain the error message)
055   */
056  public long grabFrame(Mat image) {
057    return grabFrame(image, 0.225);
058  }
059
060  /**
061   * Wait for the next frame and get the image. Times out (returning 0) after timeout seconds. The
062   * provided image will have three 3-bit channels stored in BGR order.
063   *
064   * @param image Where to store the image.
065   * @param timeout Retrieval timeout in seconds.
066   * @return Frame time, or 0 on error (call GetError() to obtain the error message); the frame time
067   *     is in 1 us increments.
068   */
069  public long grabFrame(Mat image, double timeout) {
070    return CameraServerCvJNI.grabSinkFrameTimeout(m_handle, image.nativeObj, timeout);
071  }
072
073  /**
074   * Wait for the next frame and get the image. May block forever. The provided image will have
075   * three 3-bit channels stored in BGR order.
076   *
077   * @param image Where to store the image.
078   * @return Frame time, or 0 on error (call GetError() to obtain the error message); the frame time
079   *     is in 1 us increments.
080   */
081  public long grabFrameNoTimeout(Mat image) {
082    return CameraServerCvJNI.grabSinkFrame(m_handle, image.nativeObj);
083  }
084}