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.raw.RawFrame;
008import edu.wpi.first.util.RuntimeLoader;
009import java.io.IOException;
010import java.nio.ByteBuffer;
011import java.util.concurrent.atomic.AtomicBoolean;
012import java.util.function.Consumer;
013
014public class CameraServerJNI {
015  static boolean libraryLoaded = false;
016
017  static RuntimeLoader<CameraServerJNI> loader = null;
018
019  public static class Helper {
020    private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
021
022    public static boolean getExtractOnStaticLoad() {
023      return extractOnStaticLoad.get();
024    }
025
026    public static void setExtractOnStaticLoad(boolean load) {
027      extractOnStaticLoad.set(load);
028    }
029  }
030
031  static {
032    if (Helper.getExtractOnStaticLoad()) {
033      try {
034        loader =
035            new RuntimeLoader<>(
036                "cscorejni", RuntimeLoader.getDefaultExtractionRoot(), CameraServerJNI.class);
037        loader.loadLibrary();
038      } catch (IOException ex) {
039        ex.printStackTrace();
040        System.exit(1);
041      }
042      libraryLoaded = true;
043    }
044  }
045
046  /**
047   * Force load the library.
048   *
049   * @throws IOException if library load failed
050   */
051  public static synchronized void forceLoad() throws IOException {
052    if (libraryLoaded) {
053      return;
054    }
055    loader =
056        new RuntimeLoader<>(
057            "cscorejni", RuntimeLoader.getDefaultExtractionRoot(), CameraServerJNI.class);
058    loader.loadLibrary();
059    libraryLoaded = true;
060  }
061
062  //
063  // Property Functions
064  //
065  public static native int getPropertyKind(int property);
066
067  public static native String getPropertyName(int property);
068
069  public static native int getProperty(int property);
070
071  public static native void setProperty(int property, int value);
072
073  public static native int getPropertyMin(int property);
074
075  public static native int getPropertyMax(int property);
076
077  public static native int getPropertyStep(int property);
078
079  public static native int getPropertyDefault(int property);
080
081  public static native String getStringProperty(int property);
082
083  public static native void setStringProperty(int property, String value);
084
085  public static native String[] getEnumPropertyChoices(int property);
086
087  //
088  // Source Creation Functions
089  //
090  public static native int createUsbCameraDev(String name, int dev);
091
092  public static native int createUsbCameraPath(String name, String path);
093
094  public static native int createHttpCamera(String name, String url, int kind);
095
096  public static native int createHttpCameraMulti(String name, String[] urls, int kind);
097
098  public static native int createRawSource(
099      String name, int pixelFormat, int width, int height, int fps);
100
101  //
102  // Source Functions
103  //
104  public static native int getSourceKind(int source);
105
106  public static native String getSourceName(int source);
107
108  public static native String getSourceDescription(int source);
109
110  public static native long getSourceLastFrameTime(int source);
111
112  public static native void setSourceConnectionStrategy(int source, int strategy);
113
114  public static native boolean isSourceConnected(int source);
115
116  public static native boolean isSourceEnabled(int source);
117
118  public static native int getSourceProperty(int source, String name);
119
120  public static native int[] enumerateSourceProperties(int source);
121
122  public static native VideoMode getSourceVideoMode(int source);
123
124  public static native boolean setSourceVideoMode(
125      int source, int pixelFormat, int width, int height, int fps);
126
127  public static native boolean setSourcePixelFormat(int source, int pixelFormat);
128
129  public static native boolean setSourceResolution(int source, int width, int height);
130
131  public static native boolean setSourceFPS(int source, int fps);
132
133  public static native boolean setSourceConfigJson(int source, String config);
134
135  public static native String getSourceConfigJson(int source);
136
137  public static native VideoMode[] enumerateSourceVideoModes(int source);
138
139  public static native int[] enumerateSourceSinks(int source);
140
141  public static native int copySource(int source);
142
143  public static native void releaseSource(int source);
144
145  //
146  // Camera Source Common Property Fuctions
147  //
148  public static native void setCameraBrightness(int source, int brightness);
149
150  public static native int getCameraBrightness(int source);
151
152  public static native void setCameraWhiteBalanceAuto(int source);
153
154  public static native void setCameraWhiteBalanceHoldCurrent(int source);
155
156  public static native void setCameraWhiteBalanceManual(int source, int value);
157
158  public static native void setCameraExposureAuto(int source);
159
160  public static native void setCameraExposureHoldCurrent(int source);
161
162  public static native void setCameraExposureManual(int source, int value);
163
164  //
165  // UsbCamera Source Functions
166  //
167  public static native void setUsbCameraPath(int source, String path);
168
169  public static native String getUsbCameraPath(int source);
170
171  public static native UsbCameraInfo getUsbCameraInfo(int source);
172
173  //
174  // HttpCamera Source Functions
175  //
176  public static native int getHttpCameraKind(int source);
177
178  public static native void setHttpCameraUrls(int source, String[] urls);
179
180  public static native String[] getHttpCameraUrls(int source);
181
182  //
183  // Image Source Functions
184  //
185  public static native void putRawSourceFrameBB(
186      int source, ByteBuffer data, int width, int height, int pixelFormat, int totalData);
187
188  public static native void putRawSourceFrame(
189      int source, long data, int width, int height, int pixelFormat, int totalData);
190
191  public static void putRawSourceFrame(int source, RawFrame raw) {
192    putRawSourceFrame(
193        source,
194        raw.getDataPtr(),
195        raw.getWidth(),
196        raw.getHeight(),
197        raw.getPixelFormat(),
198        raw.getTotalData());
199  }
200
201  public static native void notifySourceError(int source, String msg);
202
203  public static native void setSourceConnected(int source, boolean connected);
204
205  public static native void setSourceDescription(int source, String description);
206
207  public static native int createSourceProperty(
208      int source,
209      String name,
210      int kind,
211      int minimum,
212      int maximum,
213      int step,
214      int defaultValue,
215      int value);
216
217  public static native void setSourceEnumPropertyChoices(
218      int source, int property, String[] choices);
219
220  //
221  // Sink Creation Functions
222  //
223  public static native int createMjpegServer(String name, String listenAddress, int port);
224
225  public static native int createRawSink(String name);
226
227  //
228  // Sink Functions
229  //
230  public static native int getSinkKind(int sink);
231
232  public static native String getSinkName(int sink);
233
234  public static native String getSinkDescription(int sink);
235
236  public static native int getSinkProperty(int sink, String name);
237
238  public static native int[] enumerateSinkProperties(int sink);
239
240  public static native boolean setSinkConfigJson(int sink, String config);
241
242  public static native String getSinkConfigJson(int sink);
243
244  public static native void setSinkSource(int sink, int source);
245
246  public static native int getSinkSourceProperty(int sink, String name);
247
248  public static native int getSinkSource(int sink);
249
250  public static native int copySink(int sink);
251
252  public static native void releaseSink(int sink);
253
254  //
255  // MjpegServer Sink Functions
256  //
257  public static native String getMjpegServerListenAddress(int sink);
258
259  public static native int getMjpegServerPort(int sink);
260
261  //
262  // Image Sink Functions
263  //
264  public static native void setSinkDescription(int sink, String description);
265
266  private static native long grabRawSinkFrameImpl(
267      int sink,
268      RawFrame rawFrame,
269      long rawFramePtr,
270      ByteBuffer byteBuffer,
271      int width,
272      int height,
273      int pixelFormat);
274
275  private static native long grabRawSinkFrameTimeoutImpl(
276      int sink,
277      RawFrame rawFrame,
278      long rawFramePtr,
279      ByteBuffer byteBuffer,
280      int width,
281      int height,
282      int pixelFormat,
283      double timeout);
284
285  public static long grabSinkFrame(int sink, RawFrame rawFrame) {
286    return grabRawSinkFrameImpl(
287        sink,
288        rawFrame,
289        rawFrame.getFramePtr(),
290        rawFrame.getDataByteBuffer(),
291        rawFrame.getWidth(),
292        rawFrame.getHeight(),
293        rawFrame.getPixelFormat());
294  }
295
296  public static long grabSinkFrameTimeout(int sink, RawFrame rawFrame, double timeout) {
297    return grabRawSinkFrameTimeoutImpl(
298        sink,
299        rawFrame,
300        rawFrame.getFramePtr(),
301        rawFrame.getDataByteBuffer(),
302        rawFrame.getWidth(),
303        rawFrame.getHeight(),
304        rawFrame.getPixelFormat(),
305        timeout);
306  }
307
308  public static native String getSinkError(int sink);
309
310  public static native void setSinkEnabled(int sink, boolean enabled);
311
312  //
313  // Listener Functions
314  //
315  public static native int addListener(
316      Consumer<VideoEvent> listener, int eventMask, boolean immediateNotify);
317
318  public static native void removeListener(int handle);
319
320  public static native int createListenerPoller();
321
322  public static native void destroyListenerPoller(int poller);
323
324  public static native int addPolledListener(int poller, int eventMask, boolean immediateNotify);
325
326  public static native VideoEvent[] pollListener(int poller) throws InterruptedException;
327
328  public static native VideoEvent[] pollListenerTimeout(int poller, double timeout)
329      throws InterruptedException;
330
331  public static native void cancelPollListener(int poller);
332
333  //
334  // Telemetry Functions
335  //
336  public enum TelemetryKind {
337    kSourceBytesReceived(1),
338    kSourceFramesReceived(2);
339
340    private final int value;
341
342    TelemetryKind(int value) {
343      this.value = value;
344    }
345
346    public int getValue() {
347      return value;
348    }
349  }
350
351  public static native void setTelemetryPeriod(double seconds);
352
353  public static native double getTelemetryElapsedTime();
354
355  public static native long getTelemetryValue(int handle, int kind);
356
357  public static long getTelemetryValue(int handle, TelemetryKind kind) {
358    return getTelemetryValue(handle, kind.getValue());
359  }
360
361  public static native double getTelemetryAverageValue(int handle, int kind);
362
363  public static double getTelemetryAverageValue(int handle, TelemetryKind kind) {
364    return getTelemetryAverageValue(handle, kind.getValue());
365  }
366
367  //
368  // Logging Functions
369  //
370  @FunctionalInterface
371  public interface LoggerFunction {
372    void apply(int level, String file, int line, String msg);
373  }
374
375  public static native void setLogger(LoggerFunction func, int minLevel);
376
377  //
378  // Utility Functions
379  //
380  public static native UsbCameraInfo[] enumerateUsbCameras();
381
382  public static native int[] enumerateSources();
383
384  public static native int[] enumerateSinks();
385
386  public static native String getHostname();
387
388  public static native String[] getNetworkInterfaces();
389
390  public static native long allocateRawFrame();
391
392  public static native void freeRawFrame(long frame);
393}