mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-30 02:31:40 +00:00
Use CameraServer directly instead of duplicating its functionality
This commit is contained in:
@@ -17,11 +17,9 @@
|
|||||||
|
|
||||||
package org.photonvision.vision.frame.consumer;
|
package org.photonvision.vision.frame.consumer;
|
||||||
|
|
||||||
|
import edu.wpi.first.cameraserver.CameraServer;
|
||||||
import edu.wpi.first.cscore.*;
|
import edu.wpi.first.cscore.*;
|
||||||
import edu.wpi.first.networktables.NetworkTable;
|
|
||||||
import edu.wpi.first.networktables.NetworkTableInstance;
|
|
||||||
import edu.wpi.first.util.PixelFormat;
|
import edu.wpi.first.util.PixelFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import org.photonvision.common.util.math.MathUtils;
|
import org.photonvision.common.util.math.MathUtils;
|
||||||
import org.photonvision.vision.frame.StaticFrames;
|
import org.photonvision.vision.frame.StaticFrames;
|
||||||
import org.photonvision.vision.opencv.CVMat;
|
import org.photonvision.vision.opencv.CVMat;
|
||||||
@@ -34,59 +32,13 @@ public class MJPGFrameConsumer implements AutoCloseable {
|
|||||||
private CvSource cvSource;
|
private CvSource cvSource;
|
||||||
private MjpegServer mjpegServer;
|
private MjpegServer mjpegServer;
|
||||||
|
|
||||||
private VideoListener listener;
|
|
||||||
|
|
||||||
private final NetworkTable table;
|
|
||||||
|
|
||||||
public MJPGFrameConsumer(String sourceName, int width, int height, int port) {
|
public MJPGFrameConsumer(String sourceName, int width, int height, int port) {
|
||||||
this.cvSource = new CvSource(sourceName, PixelFormat.kMJPEG, width, height, 30);
|
this.cvSource = new CvSource(sourceName, PixelFormat.kMJPEG, width, height, 30);
|
||||||
this.table =
|
|
||||||
NetworkTableInstance.getDefault().getTable("/CameraPublisher").getSubTable(sourceName);
|
|
||||||
|
|
||||||
this.mjpegServer = new MjpegServer("serve_" + cvSource.getName(), port);
|
this.mjpegServer = new MjpegServer("serve_" + cvSource.getName(), port);
|
||||||
mjpegServer.setSource(cvSource);
|
mjpegServer.setSource(cvSource);
|
||||||
mjpegServer.setCompression(75);
|
mjpegServer.setCompression(75);
|
||||||
|
CameraServer.addServer(mjpegServer);
|
||||||
listener =
|
|
||||||
new VideoListener(
|
|
||||||
event -> {
|
|
||||||
if (event.kind == VideoEvent.Kind.kNetworkInterfacesChanged) {
|
|
||||||
table.getEntry("source").setString("cv:");
|
|
||||||
table.getEntry("streams");
|
|
||||||
table.getEntry("connected").setBoolean(true);
|
|
||||||
table.getEntry("mode").setString(videoModeToString(cvSource.getVideoMode()));
|
|
||||||
table.getEntry("modes").setStringArray(getSourceModeValues(cvSource.getHandle()));
|
|
||||||
updateStreamValues();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
0x4fff,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void updateStreamValues() {
|
|
||||||
// Get port
|
|
||||||
int port = mjpegServer.getPort();
|
|
||||||
|
|
||||||
// Generate values
|
|
||||||
var addresses = CameraServerJNI.getNetworkInterfaces();
|
|
||||||
ArrayList<String> values = new ArrayList<>(addresses.length + 1);
|
|
||||||
String listenAddress = CameraServerJNI.getMjpegServerListenAddress(mjpegServer.getHandle());
|
|
||||||
if (!listenAddress.isEmpty()) {
|
|
||||||
// If a listen address is specified, only use that
|
|
||||||
values.add(makeStreamValue(listenAddress, port));
|
|
||||||
} else {
|
|
||||||
// Otherwise generate for hostname and all interface addresses
|
|
||||||
values.add(makeStreamValue(CameraServerJNI.getHostname() + ".local", port));
|
|
||||||
for (String addr : addresses) {
|
|
||||||
if ("127.0.0.1".equals(addr)) {
|
|
||||||
continue; // ignore localhost
|
|
||||||
}
|
|
||||||
values.add(makeStreamValue(addr, port));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] streamAddresses = values.toArray(new String[0]);
|
|
||||||
table.getEntry("streams").setStringArray(streamAddresses);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MJPGFrameConsumer(String name, int port) {
|
public MJPGFrameConsumer(String name, int port) {
|
||||||
@@ -106,53 +58,12 @@ public class MJPGFrameConsumer implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentStreamPort() {
|
|
||||||
return mjpegServer.getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String makeStreamValue(String address, int port) {
|
|
||||||
return "mjpg:http://" + address + ":" + port + "/?action=stream";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] getSourceModeValues(int sourceHandle) {
|
|
||||||
VideoMode[] modes = CameraServerJNI.enumerateSourceVideoModes(sourceHandle);
|
|
||||||
String[] modeStrings = new String[modes.length];
|
|
||||||
for (int i = 0; i < modes.length; i++) {
|
|
||||||
modeStrings[i] = videoModeToString(modes[i]);
|
|
||||||
}
|
|
||||||
return modeStrings;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String videoModeToString(VideoMode mode) {
|
|
||||||
return mode.width
|
|
||||||
+ "x"
|
|
||||||
+ mode.height
|
|
||||||
+ " "
|
|
||||||
+ pixelFormatToString(mode.pixelFormat)
|
|
||||||
+ " "
|
|
||||||
+ mode.fps
|
|
||||||
+ " fps";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String pixelFormatToString(PixelFormat pixelFormat) {
|
|
||||||
return switch (pixelFormat) {
|
|
||||||
case kMJPEG -> "MJPEG";
|
|
||||||
case kYUYV -> "YUYV";
|
|
||||||
case kRGB565 -> "RGB565";
|
|
||||||
case kBGR -> "BGR";
|
|
||||||
case kGray -> "Gray";
|
|
||||||
case kUYVY, kUnknown, kY16, kBGRA -> "Unknown";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
table.getEntry("connected").setBoolean(false);
|
CameraServer.removeServer(mjpegServer.getName());
|
||||||
mjpegServer.close();
|
mjpegServer.close();
|
||||||
cvSource.close();
|
cvSource.close();
|
||||||
listener.close();
|
|
||||||
mjpegServer = null;
|
mjpegServer = null;
|
||||||
cvSource = null;
|
cvSource = null;
|
||||||
listener = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user