#ifndef WPIUTIL_WPI_RAWFRAME_H_
#define WPIUTIL_WPI_RAWFRAME_H_
#include <stdint.h>
#ifdef __cplusplus
#include <concepts>
#include <cstddef>
#else
#include <stddef.h>
#endif
#ifdef WPI_RAWFRAME_JNI
#include "wpi/jni_util.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct WPI_RawFrame { uint8_t* data;
void (*freeFunc)(void* cbdata, void* data, size_t capacity);
void* freeCbData; size_t capacity; size_t size; int pixelFormat; int width; int height; int stride; uint64_t timestamp; int timestampSrc; } WPI_RawFrame;
enum WPI_PixelFormat {
WPI_PIXFMT_UNKNOWN = 0, WPI_PIXFMT_MJPEG, WPI_PIXFMT_YUYV, WPI_PIXFMT_RGB565, WPI_PIXFMT_BGR, WPI_PIXFMT_GRAY, WPI_PIXFMT_Y16, WPI_PIXFMT_UYVY, WPI_PIXFMT_BGRA, };
enum WPI_TimestampSource {
WPI_TIMESRC_UNKNOWN = 0, WPI_TIMESRC_FRAME_DEQUEUE, WPI_TIMESRC_V4L_EOF, WPI_TIMESRC_V4L_SOE, };
int WPI_AllocateRawFrameData(WPI_RawFrame* frame, size_t requestedSize);
void WPI_FreeRawFrameData(WPI_RawFrame* frame);
void WPI_SetRawFrameData(WPI_RawFrame* frame, void* data, size_t size,
size_t capacity, void* cbdata,
void (*freeFunc)(void* cbdata, void* data,
size_t capacity));
#ifdef __cplusplus
} #endif
#ifdef __cplusplus
namespace wpi {
struct RawFrame : public WPI_RawFrame {
RawFrame() {
data = nullptr;
freeFunc = nullptr;
freeCbData = nullptr;
capacity = 0;
size = 0;
pixelFormat = WPI_PIXFMT_UNKNOWN;
width = 0;
height = 0;
timestamp = 0;
timestampSrc = WPI_TIMESRC_UNKNOWN;
}
RawFrame(const RawFrame&) = delete;
RawFrame& operator=(const RawFrame&) = delete;
RawFrame(RawFrame&& rhs) noexcept : WPI_RawFrame{rhs} {
rhs.data = nullptr;
rhs.freeFunc = nullptr;
rhs.freeCbData = nullptr;
rhs.capacity = 0;
rhs.size = 0;
}
RawFrame& operator=(RawFrame&& rhs) noexcept {
*static_cast<WPI_RawFrame*>(this) = rhs;
rhs.data = nullptr;
rhs.freeFunc = nullptr;
rhs.freeCbData = nullptr;
rhs.capacity = 0;
rhs.size = 0;
return *this;
}
void SetData(void* data, size_t size, size_t capacity, void* cbdata,
void (*freeFunc)(void* cbdata, void* data, size_t capacity)) {
WPI_SetRawFrameData(this, data, size, capacity, cbdata, freeFunc);
}
bool Reserve(size_t size) {
return WPI_AllocateRawFrameData(this, size) != 0;
}
~RawFrame() { WPI_FreeRawFrameData(this); }
};
#ifdef WPI_RAWFRAME_JNI
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;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<jlong>(frame.timestamp),
static_cast<jint>(frame.timestampSrc));
} else {
static jmethodID setInfo =
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<jlong>(frame.timestamp),
static_cast<jint>(frame.timestampSrc));
}
}
#endif
} #endif
#endif