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
010/**
011 * A source for video that provides a sequence of frames.  Each frame may
012 * consist of multiple images (e.g. from a stereo or depth camera); these
013 * are called channels.
014 */
015public class VideoSource {
016  public enum Kind {
017    kUnknown(0), kUsb(1), kHttp(2), kCv(4);
018    private int value;
019
020    private Kind(int value) {
021      this.value = value;
022    }
023
024    public int getValue() {
025      return value;
026    }
027  }
028
029  public static Kind getKindFromInt(int kind) {
030    switch (kind) {
031      case 1: return Kind.kUsb;
032      case 2: return Kind.kHttp;
033      case 4: return Kind.kCv;
034      default: return Kind.kUnknown;
035    }
036  }
037
038  protected VideoSource(int handle) {
039    m_handle = handle;
040  }
041
042  public synchronized void free() {
043    if (m_handle != 0) {
044      CameraServerJNI.releaseSource(m_handle);
045    }
046    m_handle = 0;
047  }
048
049  public boolean isValid() {
050    return m_handle != 0;
051  }
052
053  public int getHandle() {
054    return m_handle;
055  }
056
057  public boolean equals(Object other) {
058    if (this == other) return true;
059    if (other == null) return false;
060    if (getClass() != other.getClass()) return false;
061    VideoSource source = (VideoSource) other;
062    return m_handle == source.m_handle;
063  }
064
065  public int hashCode() {
066    return m_handle;
067  }
068
069  /**
070   * Get the kind of the source.
071   */
072  public Kind getKind() {
073    return getKindFromInt(CameraServerJNI.getSourceKind(m_handle));
074  }
075
076  /**
077   * Get the name of the source.  The name is an arbitrary identifier
078   * provided when the source is created, and should be unique.
079   */
080  public String getName() {
081    return CameraServerJNI.getSourceName(m_handle);
082  }
083
084  /**
085   * Get the source description.  This is source-kind specific.
086   */
087  public String getDescription() {
088    return CameraServerJNI.getSourceDescription(m_handle);
089  }
090
091  /**
092   * Get the last time a frame was captured.
093   * @return Time in 1 us increments.
094   */
095  public long getLastFrameTime() {
096    return CameraServerJNI.getSourceLastFrameTime(m_handle);
097  }
098
099  /**
100   * Is the source currently connected to whatever is providing the images?
101   */
102  public boolean isConnected() {
103    return CameraServerJNI.isSourceConnected(m_handle);
104  }
105
106  /**
107   * Get a property.
108   * @param name Property name
109   * @return Property contents (of kind Property::kNone if no property with
110   *         the given name exists)
111   */
112  public VideoProperty getProperty(String name) {
113    return new VideoProperty(CameraServerJNI.getSourceProperty(m_handle, name));
114  }
115
116  /**
117   * Enumerate all properties of this source.
118   */
119  public VideoProperty[] enumerateProperties() {
120    int[] handles = CameraServerJNI.enumerateSourceProperties(m_handle);
121    VideoProperty[] rv = new VideoProperty[handles.length];
122    for (int i=0; i<handles.length; i++) {
123      rv[i] = new VideoProperty(handles[i]);
124    }
125    return rv;
126  }
127
128  /**
129   * Get the current video mode.
130   */
131  public VideoMode getVideoMode() {
132    return CameraServerJNI.getSourceVideoMode(m_handle);
133  }
134
135  /**
136   * Set the video mode.
137   * @param mode Video mode
138   */
139  public boolean setVideoMode(VideoMode mode) {
140    return CameraServerJNI.setSourceVideoMode(m_handle, mode.pixelFormat.getValue(), mode.width, mode.height, mode.fps);
141  }
142
143  /**
144   * Set the video mode.
145   * @param pixelFormat desired pixel format
146   * @param width desired width
147   * @param height desired height
148   * @param fps desired FPS
149   * @return True if set successfully
150   */
151  public boolean setVideoMode(VideoMode.PixelFormat pixelFormat, int width, int height, int fps) {
152    return CameraServerJNI.setSourceVideoMode(m_handle, pixelFormat.getValue(), width, height, fps);
153  }
154
155  /**
156   * Set the pixel format.
157   * @param pixelFormat desired pixel format
158   * @return True if set successfully
159   */
160  public boolean setPixelFormat(VideoMode.PixelFormat pixelFormat) {
161    return CameraServerJNI.setSourcePixelFormat(m_handle, pixelFormat.getValue());
162  }
163
164  /**
165   * Set the resolution.
166   * @param width desired width
167   * @param height desired height
168   * @return True if set successfully
169   */
170  public boolean setResolution(int width, int height) {
171    return CameraServerJNI.setSourceResolution(m_handle, width, height);
172  }
173
174  /**
175   * Set the frames per second (FPS).
176   * @param fps desired FPS
177   * @return True if set successfully
178   */
179  public boolean setFPS(int fps) {
180    return CameraServerJNI.setSourceFPS(m_handle, fps);
181  }
182
183  /**
184   * Enumerate all known video modes for this source.
185   */
186  public VideoMode[] enumerateVideoModes() {
187    return CameraServerJNI.enumerateSourceVideoModes(m_handle);
188  }
189
190  /**
191   * Enumerate all sinks connected to this source.
192   * @return Vector of sinks.
193   */
194  public VideoSink[] enumerateSinks() {
195    int[] handles = CameraServerJNI.enumerateSourceSinks(m_handle);
196    VideoSink[] rv = new VideoSink[handles.length];
197    for (int i=0; i<handles.length; i++) {
198      rv[i] = new VideoSink(handles[i]);
199    }
200    return rv;
201  }
202
203  /**
204   * Enumerate all existing sources.
205   * @return Vector of sources.
206   */
207  public static VideoSource[] enumerateSources() {
208    int[] handles = CameraServerJNI.enumerateSources();
209    VideoSource[] rv = new VideoSource[handles.length];
210    for (int i=0; i<handles.length; i++) {
211      rv[i] = new VideoSource(handles[i]);
212    }
213    return rv;
214  }
215
216  protected int m_handle;
217}