Refactor LibCameraJNILoader to use PhotonJNICommon (#2048)

This commit is contained in:
Gold856
2025-09-16 11:04:25 -04:00
committed by GitHub
parent a1d06a9920
commit e84e3e7c7c
3 changed files with 27 additions and 53 deletions

View File

@@ -53,7 +53,7 @@ public class UIPhotonConfiguration {
new UIGeneralSettings(
PhotonVersion.versionString,
// TODO add support for other types of GPU accel
LibCameraJNILoader.isSupported() ? "Zerocopy Libcamera Working" : "",
LibCameraJNILoader.getInstance().isSupported() ? "Zerocopy Libcamera Working" : "",
MrCalJNILoader.getInstance().isLoaded(),
c.neuralNetworkPropertyManager().getModels(),
NeuralNetworkModelManager.getInstance().getSupportedBackends(),

View File

@@ -17,63 +17,37 @@
package org.photonvision.raspi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.photonvision.common.logging.LogGroup;
import org.photonvision.common.logging.Logger;
import java.util.List;
import org.photonvision.jni.PhotonJNICommon;
/**
* Helper for extracting photon-libcamera-gl-driver shared library files. TODO: Refactor to use
* PhotonJNICommon
*/
public class LibCameraJNILoader {
private static boolean libraryLoaded = false;
private static final Logger logger = new Logger(LibCameraJNILoader.class, LogGroup.Camera);
/** Helper for extracting photon-libcamera-gl-driver shared library files. */
public class LibCameraJNILoader extends PhotonJNICommon {
private boolean libraryLoaded = false;
private static LibCameraJNILoader instance = null;
public static synchronized void forceLoad() throws IOException {
if (libraryLoaded) return;
public static synchronized LibCameraJNILoader getInstance() {
if (instance == null) instance = new LibCameraJNILoader();
var libraryName = "photonlibcamera";
try {
// We always extract the shared object (we could hash each so, but that's a lot of work)
var arch_name = "linuxarm64";
var nativeLibName = System.mapLibraryName(libraryName);
var resourcePath = "/nativelibraries/" + arch_name + "/" + nativeLibName;
var in = LibCameraJNILoader.class.getResourceAsStream(resourcePath);
if (in == null) {
logger.error("Failed to find internal native library at path " + resourcePath);
libraryLoaded = false;
return;
}
// It's important that we don't mangle the names of these files on Windows at least
File temp = new File(System.getProperty("java.io.tmpdir"), nativeLibName);
FileOutputStream fos = new FileOutputStream(temp);
int read = -1;
byte[] buffer = new byte[1024];
while ((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();
System.load(temp.getAbsolutePath());
logger.info("Successfully loaded shared object " + temp.getName());
} catch (UnsatisfiedLinkError e) {
logger.error("Couldn't load shared object " + libraryName, e);
e.printStackTrace();
// logger.error(System.getProperty("java.library.path"));
}
libraryLoaded = true;
return instance;
}
public static boolean isSupported() {
public static synchronized void forceLoad() throws IOException {
forceLoad(
LibCameraJNILoader.getInstance(), LibCameraJNILoader.class, List.of("photonlibcamera"));
}
@Override
public boolean isLoaded() {
return libraryLoaded;
}
@Override
public void setLoaded(boolean state) {
libraryLoaded = state;
}
public boolean isSupported() {
return libraryLoaded && LibCameraJNI.isSupported();
}
}

View File

@@ -300,7 +300,7 @@ public class VisionSourceManager {
.filter(c -> !(String.join("", c.otherPaths()).contains("csi-video")))
.filter(c -> !c.name().equals("unicam"))
.forEach(cameraInfos::add);
if (LibCameraJNILoader.isSupported()) {
if (LibCameraJNILoader.getInstance().isSupported()) {
// find all CSI cameras (Raspberry Pi cameras)
Stream.of(LibCameraJNI.getCameraNames())
.map(