diff --git a/photon-core/src/main/java/org/photonvision/raspi/PicamJNI.java b/photon-core/src/main/java/org/photonvision/raspi/PicamJNI.java index 2b76cd23d..94908de13 100644 --- a/photon-core/src/main/java/org/photonvision/raspi/PicamJNI.java +++ b/photon-core/src/main/java/org/photonvision/raspi/PicamJNI.java @@ -85,7 +85,7 @@ public class PicamJNI { } public static boolean isSupported() { - return libraryLoaded && getSensorModel() != SensorModel.Disconnected; + return libraryLoaded && isVCSMSupported() && getSensorModel() != SensorModel.Disconnected; } public static SensorModel getSensorModel() { @@ -105,6 +105,9 @@ public class PicamJNI { private static native String getSensorModelRaw(); + // This is the main thing we need that isn't supported on Pi 4s, which makes it a good check + private static native boolean isVCSMSupported(); + // Everything here is static because multiple picams are unsupported at the hardware level /** diff --git a/photon-core/src/main/java/org/photonvision/vision/camera/ZeroCopyPicamSource.java b/photon-core/src/main/java/org/photonvision/vision/camera/ZeroCopyPicamSource.java index f4b7a5219..1b2443f3a 100644 --- a/photon-core/src/main/java/org/photonvision/vision/camera/ZeroCopyPicamSource.java +++ b/photon-core/src/main/java/org/photonvision/vision/camera/ZeroCopyPicamSource.java @@ -136,19 +136,22 @@ public class ZeroCopyPicamSource extends VisionSource { @Override public void setExposure(double exposure) { lastExposure = exposure; - PicamJNI.setExposure((int) Math.round(exposure)); + var success = PicamJNI.setExposure((int) Math.round(exposure)); + if (!success) logger.warn("Couldn't set Pi camera exposure"); } @Override public void setBrightness(int brightness) { lastBrightness = brightness; - PicamJNI.setBrightness(brightness); + var success = PicamJNI.setBrightness(brightness); + if (!success) logger.warn("Couldn't set Pi camera brightness"); } @Override public void setGain(int gain) { lastGain = gain; - PicamJNI.setGain(gain); + var success = PicamJNI.setGain(gain); + if (!success) logger.warn("Couldn't set Pi camera gain"); } @Override @@ -159,8 +162,14 @@ public class ZeroCopyPicamSource extends VisionSource { @Override protected void setVideoModeInternal(VideoMode videoMode) { var mode = (FPSRatedVideoMode) videoMode; - PicamJNI.destroyCamera(); - PicamJNI.createCamera(mode.width, mode.height, mode.fpsActual); + var success = PicamJNI.destroyCamera(); + if (!success) + throw new RuntimeException( + "Couldn't destroy a zero copy Pi camera while switching video modes"); + success = PicamJNI.createCamera(mode.width, mode.height, mode.fpsActual); + if (!success) + throw new RuntimeException( + "Couldn't create a zero copy Pi camera while switching video modes"); // We don't store last settings on the native side, and when you change video mode these get // reset on MMAL's end diff --git a/photon-core/src/main/java/org/photonvision/vision/frame/provider/AcceleratedPicamFrameProvider.java b/photon-core/src/main/java/org/photonvision/vision/frame/provider/AcceleratedPicamFrameProvider.java index efdf12ffb..d48491f54 100644 --- a/photon-core/src/main/java/org/photonvision/vision/frame/provider/AcceleratedPicamFrameProvider.java +++ b/photon-core/src/main/java/org/photonvision/vision/frame/provider/AcceleratedPicamFrameProvider.java @@ -35,7 +35,13 @@ public class AcceleratedPicamFrameProvider implements FrameProvider { this.settables = visionSettables; var vidMode = settables.getCurrentVideoMode(); - PicamJNI.createCamera(vidMode.width, vidMode.height, vidMode.fps); + var success = PicamJNI.createCamera(vidMode.width, vidMode.height, vidMode.fps); + if (!success) { + success = PicamJNI.destroyCamera(); + if (!success) throw new RuntimeException("Couldn't destroy Pi camera after init failure!"); + throw new RuntimeException( + "Couldn't initialize zero copy Pi camera; check stdout for native code logs"); + } } @Override diff --git a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java index f8c8568c5..e812c56e8 100644 --- a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java +++ b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java @@ -302,8 +302,9 @@ public class VisionSourceManager { var cameraSources = new ArrayList(); for (var configuration : camConfigs) { if (configuration.baseName.startsWith("mmal service") && PicamJNI.isSupported()) { - configuration.cameraType = CameraType.ZeroCopyPicam; var piCamSrc = new ZeroCopyPicamSource(configuration); + + configuration.cameraType = CameraType.ZeroCopyPicam; cameraSources.add(piCamSrc); continue; } diff --git a/photon-server/src/main/resources/nativelibraries/libpicam.so b/photon-server/src/main/resources/nativelibraries/libpicam.so index 24f857d9e..b76359bfe 100755 Binary files a/photon-server/src/main/resources/nativelibraries/libpicam.so and b/photon-server/src/main/resources/nativelibraries/libpicam.so differ