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 VideoSink {
016  public enum Kind {
017    kUnknown(0), kMjpeg(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 2: return Kind.kMjpeg;
032      case 4: return Kind.kCv;
033      default: return Kind.kUnknown;
034    }
035  }
036
037  protected VideoSink(int handle) {
038    m_handle = handle;
039  }
040
041  public synchronized void free() {
042    if (m_handle != 0) {
043      CameraServerJNI.releaseSink(m_handle);
044    }
045    m_handle = 0;
046  }
047
048  public boolean isValid() {
049    return m_handle != 0;
050  }
051
052  public int getHandle() {
053    return m_handle;
054  }
055
056  public boolean equals(Object other) {
057    if (this == other) return true;
058    if (other == null) return false;
059    if (getClass() != other.getClass()) return false;
060    VideoSink sink = (VideoSink) other;
061    return m_handle == sink.m_handle;
062  }
063
064  public int hashCode() {
065    return m_handle;
066  }
067
068  /**
069   * Get the kind of the sink.
070   */
071  public Kind getKind() {
072    return getKindFromInt(CameraServerJNI.getSinkKind(m_handle));
073  }
074
075  /**
076   * Get the name of the sink.  The name is an arbitrary identifier
077   * provided when the sink is created, and should be unique.
078   */
079  public String getName() {
080    return CameraServerJNI.getSinkName(m_handle);
081  }
082
083  /**
084   * Get the sink description.  This is sink-kind specific.
085   */
086  public String getDescription() {
087    return CameraServerJNI.getSinkDescription(m_handle);
088  }
089
090  /**
091   * Configure which source should provide frames to this sink.  Each sink
092   * can accept frames from only a single source, but a single source can
093   * provide frames to multiple clients.
094   * @param source Source
095   */
096  public void setSource(VideoSource source) {
097    if (source == null) {
098      CameraServerJNI.setSinkSource(m_handle, 0);
099    } else {
100      CameraServerJNI.setSinkSource(m_handle, source.m_handle);
101    }
102  }
103
104  /**
105   * Get the connected source.
106   * @return Connected source; nullptr if no source connected.
107   */
108  public VideoSource getSource() {
109    // While VideoSource.free() will call releaseSource(), getSinkSource()
110    // increments the internal reference count so this is okay to do.
111    return new VideoSource(CameraServerJNI.getSinkSource(m_handle));
112  }
113
114  /**
115   * Get a property of the associated source.
116   * @param name Property name
117   * @return Property (kind Property::kNone if no property with
118   *         the given name exists or no source connected)
119   */
120  public VideoProperty getSourceProperty(String name) {
121    return new VideoProperty(
122        CameraServerJNI.getSinkSourceProperty(m_handle, name));
123  }
124
125  /**
126   * Enumerate all existing sinks.
127   * @return Vector of sinks.
128   */
129  public static VideoSink[] enumerateSinks() {
130    int[] handles = CameraServerJNI.enumerateSinks();
131    VideoSink[] rv = new VideoSink[handles.length];
132    for (int i=0; i<handles.length; i++) {
133      rv[i] = new VideoSink(handles[i]);
134    }
135    return rv;
136  }
137
138  protected int m_handle;
139}