Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/camera_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ struct MatPair {
int64_t captureTimestamp; // In libcamera time units, hopefully uS? TODO
// actually implement
int32_t frameProcessingType; // enum value of shader run on the image
// Per-frame exposure integration time in microseconds, as reported by
// libcamera::controls::ExposureTime. 0 means the metadata was not
// available for this frame; consumers should leave timestamps uncorrected.
int32_t exposureTimeUs;

MatPair() = default;
explicit MatPair(int width, int height)
Expand Down Expand Up @@ -79,6 +83,7 @@ class CameraRunner {
int fd;
ProcessType type;
uint64_t captureTimestamp;
int32_t exposureTimeUs;
};

std::thread m_threshold;
Expand Down
4 changes: 4 additions & 0 deletions include/libcamera_jni.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ JNIEXPORT jlong JNICALL
Java_org_photonvision_raspi_LibCameraJNI_getFrameCaptureTime(JNIEnv *, jclass,
jlong);

JNIEXPORT jlong JNICALL
Java_org_photonvision_raspi_LibCameraJNI_getFrameExposureTimeUs(JNIEnv *,
jclass, jlong);

/*
* Class: org_photonvision_raspi_LibCameraJNI
* Method: grabFrame
Expand Down
13 changes: 11 additions & 2 deletions src/camera_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,15 @@ bool CameraRunner::start() {
.get(libcamera::controls::SensorTimestamp)
.value_or(0));

gpu_queue.push({out, type, sensorTimestamp});
// libcamera reports ExposureTime in microseconds. value_or(0)
// signals "metadata not available" to the Java consumer, which
// then leaves the published timestamp uncorrected.
Comment thread
mcm001 marked this conversation as resolved.
Outdated
int32_t exposureTimeUs = static_cast<int32_t>(
request->metadata()
.get(libcamera::controls::ExposureTime)
Comment thread
mcm001 marked this conversation as resolved.
.value_or(0));

gpu_queue.push({out, type, sensorTimestamp, exposureTimeUs});
}

std::chrono::duration<double, std::milli> elapsedMillis =
Expand Down Expand Up @@ -181,6 +189,7 @@ bool CameraRunner::start() {
// Save the current shader idx
mat_pair.frameProcessingType = static_cast<int32_t>(data.type);
mat_pair.captureTimestamp = data.captureTimestamp;
mat_pair.exposureTimeUs = data.exposureTimeUs;

uint8_t *processed_out_buf = mat_pair.processed.data;
uint8_t *color_out_buf = mat_pair.color.data;
Expand Down Expand Up @@ -262,7 +271,7 @@ void CameraRunner::stop() {
threshold.join();

// push sentinel value to stop display thread
gpu_queue.push({-1, ProcessType::None, 0});
gpu_queue.push({-1, ProcessType::None, 0, 0});
display.join();

std::printf("stopped all\n");
Expand Down
20 changes: 20 additions & 0 deletions src/libcamera_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,26 @@ Java_org_photonvision_raspi_LibCameraJNI_getFrameCaptureTime
return pair->captureTimestamp;
}

/*
* Class: org_photonvision_raspi_LibCameraJNI
* Method: getFrameExposureTimeUs
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL
Java_org_photonvision_raspi_LibCameraJNI_getFrameExposureTimeUs
(JNIEnv *, jclass, jlong pair_)
{
MatPair *pair = reinterpret_cast<MatPair *>(pair_);
if (!pair) {
return 0;
}

// 0 means libcamera did not populate ExposureTime metadata for this
// frame. Consumers should treat 0 as "unknown" and not attempt the
// SOE -> mid-exposure timestamp correction.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 0 means libcamera did not populate ExposureTime metadata for this
// frame. Consumers should treat 0 as "unknown" and not attempt the
// SOE -> mid-exposure timestamp correction.

MatPair::exposureTimeUs already includes this comment

return static_cast<jlong>(pair->exposureTimeUs);
}

/*
* Class: org_photonvision_raspi_LibCameraJNI
* Method: releasePair
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/photonvision/raspi/LibCameraJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ public static native boolean setThresholds(
*/
public static native long getFrameCaptureTime(long p_ptr);

/**
* Get the integration time (exposure window length) for this frame, as reported by libcamera's
* ExposureTime control. Units are microseconds. Returns 0 when libcamera did not populate the
* metadata for this frame; consumers should treat 0 as "unknown" and leave timestamps
* uncorrected.
*/
public static native long getFrameExposureTimeUs(long p_ptr);

/**
* Get the current time, in the same timebase as libcamera gives the frame capture time. Units are
* nanoseconds.
Expand Down
Loading