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}