mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
Merge branch 'main' into 2027
This commit is contained in:
@@ -18,6 +18,8 @@ public class RawFrame implements AutoCloseable {
|
||||
private int m_height;
|
||||
private int m_stride;
|
||||
private PixelFormat m_pixelFormat = PixelFormat.kUnknown;
|
||||
private long m_time;
|
||||
private TimestampSource m_timeSource = TimestampSource.kUnknown;
|
||||
|
||||
/** Construct a new empty RawFrame. */
|
||||
public RawFrame() {
|
||||
@@ -43,12 +45,15 @@ public class RawFrame implements AutoCloseable {
|
||||
* @param stride The number of bytes in each row of image data
|
||||
* @param pixelFormat The PixelFormat of the frame
|
||||
*/
|
||||
void setDataJNI(ByteBuffer data, int width, int height, int stride, int pixelFormat) {
|
||||
void setDataJNI(
|
||||
ByteBuffer data, int width, int height, int stride, int pixelFormat, long time, int timeSrc) {
|
||||
m_data = data;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
m_pixelFormat = PixelFormat.getFromInt(pixelFormat);
|
||||
m_time = time;
|
||||
m_timeSource = TimestampSource.getFromInt(timeSrc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,11 +64,13 @@ public class RawFrame implements AutoCloseable {
|
||||
* @param stride The number of bytes in each row of image data
|
||||
* @param pixelFormat The PixelFormat of the frame
|
||||
*/
|
||||
void setInfoJNI(int width, int height, int stride, int pixelFormat) {
|
||||
void setInfoJNI(int width, int height, int stride, int pixelFormat, long time, int timeSrc) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
m_pixelFormat = PixelFormat.getFromInt(pixelFormat);
|
||||
m_time = time;
|
||||
m_timeSource = TimestampSource.getFromInt(timeSrc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +117,19 @@ public class RawFrame implements AutoCloseable {
|
||||
pixelFormat.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this frame's timestamp info.
|
||||
*
|
||||
* @param frameTime the time this frame was grabbed at. This uses the same time base as
|
||||
* wpi::Now(), in us.
|
||||
* @param frameTimeSource the time source for the timestamp this frame was grabbed at.
|
||||
*/
|
||||
public void setTimeInfo(long frameTime, TimestampSource frameTimeSource) {
|
||||
m_time = frameTime;
|
||||
m_timeSource = frameTimeSource;
|
||||
WPIUtilJNI.setRawFrameTime(m_nativeObj, frameTime, frameTimeSource.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pointer to native representation of this frame.
|
||||
*
|
||||
@@ -185,4 +205,22 @@ public class RawFrame implements AutoCloseable {
|
||||
public PixelFormat getPixelFormat() {
|
||||
return m_pixelFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time this frame was grabbed at. This uses the same time base as wpi::Now(), in us.
|
||||
*
|
||||
* @return Time in 1 us increments.
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return m_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time source for the timestamp this frame was grabbed at.
|
||||
*
|
||||
* @return Time source
|
||||
*/
|
||||
public TimestampSource getTimestampSource() {
|
||||
return m_timeSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.util;
|
||||
|
||||
/**
|
||||
* Options for where the timestamp an {@link RawFrame} was captured at can be measured relative to.
|
||||
*/
|
||||
public enum TimestampSource {
|
||||
/** unknown. */
|
||||
kUnknown(0),
|
||||
/**
|
||||
* wpi::Now when the new frame was dequeued by CSCore. Does not account for camera exposure time
|
||||
* or V4L latency.
|
||||
*/
|
||||
kFrameDequeue(1),
|
||||
/** End of Frame. Same as V4L2_BUF_FLAG_TSTAMP_SRC_EOF, translated into wpi::Now's timebase. */
|
||||
kV4LEOF(2),
|
||||
/**
|
||||
* Start of Exposure. Same as V4L2_BUF_FLAG_TSTAMP_SRC_SOE, translated into wpi::Now's timebase.
|
||||
*/
|
||||
kV4LSOE(3);
|
||||
|
||||
private final int value;
|
||||
|
||||
TimestampSource(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the integer value of the pixel format.
|
||||
*
|
||||
* @return Integer value
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final TimestampSource[] s_values = values();
|
||||
|
||||
/**
|
||||
* Gets a TimestampSource enum value from its integer value.
|
||||
*
|
||||
* @param timestampSource integer value
|
||||
* @return Enum value
|
||||
*/
|
||||
public static TimestampSource getFromInt(int timestampSource) {
|
||||
return s_values[timestampSource];
|
||||
}
|
||||
}
|
||||
@@ -175,6 +175,8 @@ public class WPIUtilJNI {
|
||||
static native void setRawFrameInfo(
|
||||
long frame, int size, int width, int height, int stride, int pixelFormat);
|
||||
|
||||
static native void setRawFrameTime(long frame, long timestamp, int timeSource);
|
||||
|
||||
/**
|
||||
* Waits for a handle to be signaled.
|
||||
*
|
||||
|
||||
@@ -426,6 +426,24 @@ Java_edu_wpi_first_util_WPIUtilJNI_setRawFrameData
|
||||
f->pixelFormat = pixelFormat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: setRawFrameTime
|
||||
* Signature: (JJI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_setRawFrameTime
|
||||
(JNIEnv* env, jclass, jlong frame, jlong time, jint timeSource)
|
||||
{
|
||||
auto* f = reinterpret_cast<wpi::RawFrame*>(frame);
|
||||
if (!f) {
|
||||
wpi::ThrowNullPointerException(env, "frame is null");
|
||||
return;
|
||||
}
|
||||
f->timestamp = time;
|
||||
f->timestampSrc = timeSource;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: setRawFrameInfo
|
||||
|
||||
@@ -34,13 +34,15 @@ typedef struct WPI_RawFrame { // NOLINT
|
||||
uint8_t* data;
|
||||
// function to free image data (may be NULL)
|
||||
void (*freeFunc)(void* cbdata, void* data, size_t capacity);
|
||||
void* freeCbData; // data passed to freeFunc
|
||||
size_t capacity; // data buffer capacity, in bytes
|
||||
size_t size; // actual size of data, in bytes
|
||||
int pixelFormat; // WPI_PixelFormat
|
||||
int width; // width of image, in pixels
|
||||
int height; // height of image, in pixels
|
||||
int stride; // size of each row of data, in bytes (may be 0)
|
||||
void* freeCbData; // data passed to freeFunc
|
||||
size_t capacity; // data buffer capacity, in bytes
|
||||
size_t size; // actual size of data, in bytes
|
||||
int pixelFormat; // WPI_PixelFormat
|
||||
int width; // width of image, in pixels
|
||||
int height; // height of image, in pixels
|
||||
int stride; // size of each row of data, in bytes (may be 0)
|
||||
uint64_t timestamp; // image capture timestamp
|
||||
int timestampSrc; // WPI_TimestampSource
|
||||
} WPI_RawFrame;
|
||||
|
||||
/**
|
||||
@@ -58,6 +60,21 @@ enum WPI_PixelFormat {
|
||||
WPI_PIXFMT_BGRA, // BGRA 8-8-8-8-, 32 bpp
|
||||
};
|
||||
|
||||
/**
|
||||
* Timestamp metadata. Timebase is the same as wpi::Now
|
||||
*/
|
||||
enum WPI_TimestampSource {
|
||||
WPI_TIMESRC_UNKNOWN = 0, // unknown
|
||||
WPI_TIMESRC_FRAME_DEQUEUE, // wpi::Now when the new frame was dequeued by
|
||||
// CSCore. Does not account for camera exposure
|
||||
// time or V4L latency.
|
||||
WPI_TIMESRC_V4L_EOF, // End of Frame. Same as V4L2_BUF_FLAG_TSTAMP_SRC_EOF,
|
||||
// translated into wpi::Now's timebase.
|
||||
WPI_TIMESRC_V4L_SOE, // Start of Exposure. Same as
|
||||
// V4L2_BUF_FLAG_TSTAMP_SRC_SOE, translated into
|
||||
// wpi::Now's timebase.
|
||||
};
|
||||
|
||||
// Returns nonzero if the frame data was allocated/reallocated
|
||||
int WPI_AllocateRawFrameData(WPI_RawFrame* frame, size_t requestedSize);
|
||||
void WPI_FreeRawFrameData(WPI_RawFrame* frame);
|
||||
@@ -82,6 +99,8 @@ struct RawFrame : public WPI_RawFrame {
|
||||
pixelFormat = WPI_PIXFMT_UNKNOWN;
|
||||
width = 0;
|
||||
height = 0;
|
||||
timestamp = 0;
|
||||
timestampSrc = WPI_TIMESRC_UNKNOWN;
|
||||
}
|
||||
RawFrame(const RawFrame&) = delete;
|
||||
RawFrame& operator=(const RawFrame&) = delete;
|
||||
@@ -120,19 +139,23 @@ template <std::same_as<wpi::RawFrame> T>
|
||||
void SetFrameData(JNIEnv* env, jclass rawFrameCls, jobject jframe,
|
||||
const T& frame, bool newData) {
|
||||
if (newData) {
|
||||
static jmethodID setData = env->GetMethodID(rawFrameCls, "setDataJNI",
|
||||
"(Ljava/nio/ByteBuffer;IIII)V");
|
||||
static jmethodID setData = env->GetMethodID(
|
||||
rawFrameCls, "setDataJNI", "(Ljava/nio/ByteBuffer;IIIIJI)V");
|
||||
env->CallVoidMethod(
|
||||
jframe, setData, env->NewDirectByteBuffer(frame.data, frame.size),
|
||||
static_cast<jint>(frame.width), static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride), static_cast<jint>(frame.pixelFormat));
|
||||
static_cast<jint>(frame.stride), static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
} else {
|
||||
static jmethodID setInfo =
|
||||
env->GetMethodID(rawFrameCls, "setInfoJNI", "(IIII)V");
|
||||
env->GetMethodID(rawFrameCls, "setInfoJNI", "(IIIIJI)V");
|
||||
env->CallVoidMethod(jframe, setInfo, static_cast<jint>(frame.width),
|
||||
static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride),
|
||||
static_cast<jint>(frame.pixelFormat));
|
||||
static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -407,7 +407,7 @@ class SignalObject final {
|
||||
}
|
||||
SignalObject& operator=(SignalObject&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroySemaphore(m_handle);
|
||||
DestroySignalObject(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
|
||||
Reference in New Issue
Block a user