001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2016. 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/// A source for video that provides a sequence of frames. Each frame may 011/// consist of multiple images (e.g. from a stereo or depth camera); these 012/// are called channels. 013public class VideoSink { 014 public enum Kind { 015 kUnknown(0), kMjpeg(2), kCv(4); 016 private int value; 017 018 private Kind(int value) { 019 this.value = value; 020 } 021 022 public int getValue() { 023 return value; 024 } 025 } 026 027 public static Kind getKindFromInt(int kind) { 028 switch (kind) { 029 case 2: return Kind.kMjpeg; 030 case 4: return Kind.kCv; 031 default: return Kind.kUnknown; 032 } 033 } 034 035 protected VideoSink(int handle) { 036 m_handle = handle; 037 } 038 039 public synchronized void free() { 040 if (m_handle != 0) { 041 CameraServerJNI.releaseSink(m_handle); 042 } 043 m_handle = 0; 044 } 045 046 public boolean isValid() { 047 return m_handle != 0; 048 } 049 050 public int getHandle() { 051 return m_handle; 052 } 053 054 public boolean equals(Object other) { 055 if (this == other) return true; 056 if (other == null) return false; 057 if (getClass() != other.getClass()) return false; 058 VideoSink sink = (VideoSink) other; 059 return m_handle == sink.m_handle; 060 } 061 062 public int hashCode() { 063 return m_handle; 064 } 065 066 /// Get the kind of the sink. 067 public Kind getKind() { 068 return getKindFromInt(CameraServerJNI.getSinkKind(m_handle)); 069 } 070 071 /// Get the name of the sink. The name is an arbitrary identifier 072 /// provided when the sink is created, and should be unique. 073 public String getName() { 074 return CameraServerJNI.getSinkName(m_handle); 075 } 076 077 /// Get the sink description. This is sink-kind specific. 078 public String getDescription() { 079 return CameraServerJNI.getSinkDescription(m_handle); 080 } 081 082 /// Configure which source should provide frames to this sink. Each sink 083 /// can accept frames from only a single source, but a single source can 084 /// provide frames to multiple clients. 085 /// @param source Source 086 public void setSource(VideoSource source) { 087 if (source == null) { 088 CameraServerJNI.setSinkSource(m_handle, 0); 089 } else { 090 CameraServerJNI.setSinkSource(m_handle, source.m_handle); 091 } 092 } 093 094 /// Get the connected source. 095 /// @return Connected source; nullptr if no source connected. 096 public VideoSource getSource() { 097 // While VideoSource.free() will call releaseSource(), getSinkSource() 098 // increments the internal reference count so this is okay to do. 099 return new VideoSource(CameraServerJNI.getSinkSource(m_handle)); 100 } 101 102 /// Get a property of the associated source. 103 /// @param name Property name 104 /// @return Property (kind Property::kNone if no property with 105 /// the given name exists or no source connected) 106 public VideoProperty getSourceProperty(String name) { 107 return new VideoProperty( 108 CameraServerJNI.getSinkSourceProperty(m_handle, name)); 109 } 110 111 /// Enumerate all existing sinks. 112 /// @return Vector of sinks. 113 public static VideoSink[] enumerateSinks() { 114 int[] handles = CameraServerJNI.enumerateSinks(); 115 VideoSink[] rv = new VideoSink[handles.length]; 116 for (int i=0; i<handles.length; i++) { 117 rv[i] = new VideoSink(handles[i]); 118 } 119 return rv; 120 } 121 122 protected int m_handle; 123}