[wpiutil] Move RawFrame to wpiutil; add generation of RawFrame for AprilTags (#5923)

This commit is contained in:
Drew Williams
2023-11-23 13:55:10 -05:00
committed by GitHub
parent 437cc91af5
commit ca81ced409
23 changed files with 300 additions and 155 deletions

View File

@@ -40,7 +40,7 @@ void RawSinkImpl::Stop() {
}
}
uint64_t RawSinkImpl::GrabFrame(CS_RawFrame& image) {
uint64_t RawSinkImpl::GrabFrame(WPI_RawFrame& image) {
SetEnabled(true);
auto source = GetSource();
@@ -60,7 +60,7 @@ uint64_t RawSinkImpl::GrabFrame(CS_RawFrame& image) {
return GrabFrameImpl(image, frame);
}
uint64_t RawSinkImpl::GrabFrame(CS_RawFrame& image, double timeout) {
uint64_t RawSinkImpl::GrabFrame(WPI_RawFrame& image, double timeout) {
SetEnabled(true);
auto source = GetSource();
@@ -80,11 +80,11 @@ uint64_t RawSinkImpl::GrabFrame(CS_RawFrame& image, double timeout) {
return GrabFrameImpl(image, frame);
}
uint64_t RawSinkImpl::GrabFrameImpl(CS_RawFrame& rawFrame,
uint64_t RawSinkImpl::GrabFrameImpl(WPI_RawFrame& rawFrame,
Frame& incomingFrame) {
Image* newImage = nullptr;
if (rawFrame.pixelFormat == CS_PixelFormat::CS_PIXFMT_UNKNOWN) {
if (rawFrame.pixelFormat == WPI_PixelFormat::WPI_PIXFMT_UNKNOWN) {
// Always get incoming image directly on unknown
newImage = incomingFrame.GetExistingImage(0);
} else {
@@ -106,7 +106,7 @@ uint64_t RawSinkImpl::GrabFrameImpl(CS_RawFrame& rawFrame,
return 0;
}
CS_AllocateRawFrameData(&rawFrame, newImage->size());
WPI_AllocateRawFrameData(&rawFrame, newImage->size());
rawFrame.height = newImage->height;
rawFrame.width = newImage->width;
rawFrame.pixelFormat = newImage->pixelFormat;
@@ -159,7 +159,7 @@ CS_Sink CreateRawSinkCallback(std::string_view name,
inst.telemetry, processFrame));
}
uint64_t GrabSinkFrame(CS_Sink sink, CS_RawFrame& image, CS_Status* status) {
uint64_t GrabSinkFrame(CS_Sink sink, WPI_RawFrame& image, CS_Status* status) {
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_RAW) {
*status = CS_INVALID_HANDLE;
@@ -168,7 +168,7 @@ uint64_t GrabSinkFrame(CS_Sink sink, CS_RawFrame& image, CS_Status* status) {
return static_cast<RawSinkImpl&>(*data->sink).GrabFrame(image);
}
uint64_t GrabSinkFrameTimeout(CS_Sink sink, CS_RawFrame& image, double timeout,
uint64_t GrabSinkFrameTimeout(CS_Sink sink, WPI_RawFrame& image, double timeout,
CS_Status* status) {
auto data = Instance::GetInstance().GetSink(sink);
if (!data || data->kind != CS_SINK_RAW) {
@@ -192,12 +192,12 @@ CS_Sink CS_CreateRawSinkCallback(const char* name, void* data,
name, [=](uint64_t time) { processFrame(data, time); }, status);
}
uint64_t CS_GrabRawSinkFrame(CS_Sink sink, struct CS_RawFrame* image,
uint64_t CS_GrabRawSinkFrame(CS_Sink sink, struct WPI_RawFrame* image,
CS_Status* status) {
return cs::GrabSinkFrame(sink, *image, status);
}
uint64_t CS_GrabRawSinkFrameTimeout(CS_Sink sink, struct CS_RawFrame* image,
uint64_t CS_GrabRawSinkFrameTimeout(CS_Sink sink, struct WPI_RawFrame* image,
double timeout, CS_Status* status) {
return cs::GrabSinkFrameTimeout(sink, *image, timeout, status);
}

View File

@@ -32,13 +32,13 @@ class RawSinkImpl : public SinkImpl {
void Stop();
uint64_t GrabFrame(CS_RawFrame& frame);
uint64_t GrabFrame(CS_RawFrame& frame, double timeout);
uint64_t GrabFrame(WPI_RawFrame& frame);
uint64_t GrabFrame(WPI_RawFrame& frame, double timeout);
private:
void ThreadMain();
uint64_t GrabFrameImpl(CS_RawFrame& rawFrame, Frame& incomingFrame);
uint64_t GrabFrameImpl(WPI_RawFrame& rawFrame, Frame& incomingFrame);
std::atomic_bool m_active; // set to false to terminate threads
std::thread m_thread;

View File

@@ -21,7 +21,7 @@ RawSourceImpl::RawSourceImpl(std::string_view name, wpi::Logger& logger,
RawSourceImpl::~RawSourceImpl() = default;
void RawSourceImpl::PutFrame(const CS_RawFrame& image) {
void RawSourceImpl::PutFrame(const WPI_RawFrame& image) {
int type;
switch (image.pixelFormat) {
case VideoMode::kYUYV:
@@ -57,7 +57,7 @@ CS_Source CreateRawSource(std::string_view name, const VideoMode& mode,
inst.telemetry, mode));
}
void PutSourceFrame(CS_Source source, const CS_RawFrame& image,
void PutSourceFrame(CS_Source source, const WPI_RawFrame& image,
CS_Status* status) {
auto data = Instance::GetInstance().GetSource(source);
if (!data || data->kind != CS_SOURCE_RAW) {
@@ -75,7 +75,7 @@ CS_Source CS_CreateRawSource(const char* name, const CS_VideoMode* mode,
status);
}
void CS_PutRawSourceFrame(CS_Source source, const struct CS_RawFrame* image,
void CS_PutRawSourceFrame(CS_Source source, const struct WPI_RawFrame* image,
CS_Status* status) {
return cs::PutSourceFrame(source, *image, status);
}

View File

@@ -25,7 +25,7 @@ class RawSourceImpl : public ConfigurableSourceImpl {
~RawSourceImpl() override;
// Raw-specific functions
void PutFrame(const CS_RawFrame& image);
void PutFrame(const WPI_RawFrame& image);
private:
std::atomic_bool m_connected{true};

View File

@@ -181,7 +181,7 @@ CS_Bool CS_SetSourceVideoMode(CS_Source source, const CS_VideoMode* mode,
}
CS_Bool CS_SetSourceVideoModeDiscrete(CS_Source source,
enum CS_PixelFormat pixelFormat,
enum WPI_PixelFormat pixelFormat,
int width, int height, int fps,
CS_Status* status) {
return cs::SetSourceVideoMode(
@@ -193,7 +193,7 @@ CS_Bool CS_SetSourceVideoModeDiscrete(CS_Source source,
}
CS_Bool CS_SetSourcePixelFormat(CS_Source source,
enum CS_PixelFormat pixelFormat,
enum WPI_PixelFormat pixelFormat,
CS_Status* status) {
return cs::SetSourcePixelFormat(
source,
@@ -541,25 +541,4 @@ void CS_FreeNetworkInterfaces(char** interfaces, int count) {
std::free(interfaces);
}
void CS_AllocateRawFrameData(CS_RawFrame* frame, int requestedSize) {
if (frame->dataLength >= requestedSize) {
return;
}
if (frame->data) {
frame->data =
static_cast<char*>(wpi::safe_realloc(frame->data, requestedSize));
} else {
frame->data = static_cast<char*>(wpi::safe_malloc(requestedSize));
}
frame->dataLength = requestedSize;
}
void CS_FreeRawFrameData(CS_RawFrame* frame) {
if (frame->data) {
std::free(frame->data);
frame->data = nullptr;
frame->dataLength = 0;
}
}
} // extern "C"

View File

@@ -10,7 +10,6 @@
#include <wpi/SmallString.h>
#include <wpi/jni_util.h>
#include "cscore_cpp.h"
#include "cscore_cv.h"
#include "cscore_raw.h"
#include "cscore_runloop.h"
@@ -43,8 +42,7 @@ static JNIEnv* listenerEnv = nullptr;
static const JClassInit classes[] = {
{"edu/wpi/first/cscore/UsbCameraInfo", &usbCameraInfoCls},
{"edu/wpi/first/cscore/VideoMode", &videoModeCls},
{"edu/wpi/first/cscore/VideoEvent", &videoEventCls},
{"edu/wpi/first/cscore/raw/RawFrame", &rawFrameCls}};
{"edu/wpi/first/cscore/VideoEvent", &videoEventCls}};
static const JExceptionInit exceptions[] = {
{"edu/wpi/first/cscore/VideoException", &videoEx},
@@ -1233,7 +1231,7 @@ Java_edu_wpi_first_cscore_CameraServerJNI_putRawSourceFrameBB
(JNIEnv* env, jclass, jint source, jobject byteBuffer, jint width,
jint height, jint pixelFormat, jint totalData)
{
CS_RawFrame rawFrame;
WPI_RawFrame rawFrame;
rawFrame.data =
reinterpret_cast<char*>(env->GetDirectBufferAddress(byteBuffer));
rawFrame.totalData = totalData;
@@ -1255,7 +1253,7 @@ Java_edu_wpi_first_cscore_CameraServerJNI_putRawSourceFrame
(JNIEnv* env, jclass, jint source, jlong ptr, jint width, jint height,
jint pixelFormat, jint totalData)
{
CS_RawFrame rawFrame;
WPI_RawFrame rawFrame;
rawFrame.data = reinterpret_cast<char*>(static_cast<intptr_t>(ptr));
rawFrame.totalData = totalData;
rawFrame.pixelFormat = pixelFormat;
@@ -1725,7 +1723,7 @@ Java_edu_wpi_first_cscore_CameraServerCvJNI_grabSinkFrameTimeout
static void SetRawFrameData(JNIEnv* env, jobject rawFrameObj,
jobject byteBuffer, bool didChangeDataPtr,
const CS_RawFrame& frame) {
const WPI_RawFrame& frame) {
static jmethodID setMethod =
env->GetMethodID(rawFrameCls, "setData", "(Ljava/nio/ByteBuffer;JIIII)V");
jlong framePtr = static_cast<jlong>(reinterpret_cast<intptr_t>(frame.data));
@@ -1750,8 +1748,8 @@ Java_edu_wpi_first_cscore_CameraServerJNI_grabRawSinkFrameImpl
(JNIEnv* env, jclass, jint sink, jobject rawFrameObj, jlong rawFramePtr,
jobject byteBuffer, jint width, jint height, jint pixelFormat)
{
CS_RawFrame* ptr =
reinterpret_cast<CS_RawFrame*>(static_cast<intptr_t>(rawFramePtr));
WPI_RawFrame* ptr =
reinterpret_cast<WPI_RawFrame*>(static_cast<intptr_t>(rawFramePtr));
auto origDataPtr = ptr->data;
ptr->width = width;
ptr->height = height;
@@ -1776,8 +1774,8 @@ Java_edu_wpi_first_cscore_CameraServerJNI_grabRawSinkFrameTimeoutImpl
jobject byteBuffer, jint width, jint height, jint pixelFormat,
jdouble timeout)
{
CS_RawFrame* ptr =
reinterpret_cast<CS_RawFrame*>(static_cast<intptr_t>(rawFramePtr));
WPI_RawFrame* ptr =
reinterpret_cast<WPI_RawFrame*>(static_cast<intptr_t>(rawFramePtr));
auto origDataPtr = ptr->data;
ptr->width = width;
ptr->height = height;
@@ -2201,34 +2199,6 @@ Java_edu_wpi_first_cscore_CameraServerJNI_setLogger
minLevel);
}
/*
* Class: edu_wpi_first_cscore_CameraServerJNI
* Method: allocateRawFrame
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_edu_wpi_first_cscore_CameraServerJNI_allocateRawFrame
(JNIEnv*, jclass)
{
cs::RawFrame* rawFrame = new cs::RawFrame{};
intptr_t rawFrameIntPtr = reinterpret_cast<intptr_t>(rawFrame);
return static_cast<jlong>(rawFrameIntPtr);
}
/*
* Class: edu_wpi_first_cscore_CameraServerJNI
* Method: freeRawFrame
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_cscore_CameraServerJNI_freeRawFrame
(JNIEnv*, jclass, jlong rawFrame)
{
cs::RawFrame* ptr =
reinterpret_cast<cs::RawFrame*>(static_cast<intptr_t>(rawFrame));
delete ptr;
}
/*
* Class: edu_wpi_first_cscore_CameraServerJNI
* Method: runMainRunLoop

View File

@@ -7,6 +7,8 @@
#include <stdint.h>
#include <wpi/RawFrame.h>
#ifdef __cplusplus
#include <cstddef>
#else
@@ -84,20 +86,6 @@ enum CS_LogLevel {
CS_LOG_DEBUG4 = 6
};
/**
* Pixel formats
*/
enum CS_PixelFormat {
CS_PIXFMT_UNKNOWN = 0,
CS_PIXFMT_MJPEG,
CS_PIXFMT_YUYV,
CS_PIXFMT_RGB565,
CS_PIXFMT_BGR,
CS_PIXFMT_GRAY,
CS_PIXFMT_Y16,
CS_PIXFMT_UYVY
};
/**
* Video mode
*/
@@ -302,11 +290,11 @@ void CS_GetSourceVideoMode(CS_Source source, CS_VideoMode* mode,
CS_Bool CS_SetSourceVideoMode(CS_Source source, const CS_VideoMode* mode,
CS_Status* status);
CS_Bool CS_SetSourceVideoModeDiscrete(CS_Source source,
enum CS_PixelFormat pixelFormat,
enum WPI_PixelFormat pixelFormat,
int width, int height, int fps,
CS_Status* status);
CS_Bool CS_SetSourcePixelFormat(CS_Source source,
enum CS_PixelFormat pixelFormat,
enum WPI_PixelFormat pixelFormat,
CS_Status* status);
CS_Bool CS_SetSourceResolution(CS_Source source, int width, int height,
CS_Status* status);

View File

@@ -13,6 +13,7 @@
#include <string_view>
#include <vector>
#include <wpi/RawFrame.h>
#include <wpi/SmallVector.h>
#include <wpi/json_fwd.h>
@@ -60,14 +61,14 @@ struct UsbCameraInfo {
*/
struct VideoMode : public CS_VideoMode {
enum PixelFormat {
kUnknown = CS_PIXFMT_UNKNOWN,
kMJPEG = CS_PIXFMT_MJPEG,
kYUYV = CS_PIXFMT_YUYV,
kRGB565 = CS_PIXFMT_RGB565,
kBGR = CS_PIXFMT_BGR,
kGray = CS_PIXFMT_GRAY,
kY16 = CS_PIXFMT_Y16,
kUYVY = CS_PIXFMT_UYVY
kUnknown = WPI_PIXFMT_UNKNOWN,
kMJPEG = WPI_PIXFMT_MJPEG,
kYUYV = WPI_PIXFMT_YUYV,
kRGB565 = WPI_PIXFMT_RGB565,
kBGR = WPI_PIXFMT_BGR,
kGray = WPI_PIXFMT_GRAY,
kY16 = WPI_PIXFMT_Y16,
kUYVY = WPI_PIXFMT_UYVY
};
VideoMode() {
pixelFormat = 0;

View File

@@ -9,36 +9,23 @@
#include "cscore_c.h"
// NOLINTBEGIN
#ifdef __cplusplus
#include "cscore_oo.h"
#endif
/**
* Raw Frame
*/
typedef struct CS_RawFrame { // NOLINT
char* data;
int dataLength;
int pixelFormat;
int width;
int height;
int totalData;
} CS_RawFrame;
#ifdef __cplusplus
extern "C" {
#endif
// NOLINTEND
/**
* @defgroup cscore_raw_cfunc Raw Image Functions
* @{
*/
void CS_AllocateRawFrameData(CS_RawFrame* frame, int requestedSize);
void CS_FreeRawFrameData(CS_RawFrame* frame);
uint64_t CS_GrabRawSinkFrame(CS_Sink sink, struct CS_RawFrame* rawImage,
uint64_t CS_GrabRawSinkFrame(CS_Sink sink, struct WPI_RawFrame* rawImage,
CS_Status* status);
uint64_t CS_GrabRawSinkFrameTimeout(CS_Sink sink, struct CS_RawFrame* rawImage,
uint64_t CS_GrabRawSinkFrameTimeout(CS_Sink sink, struct WPI_RawFrame* rawImage,
double timeout, CS_Status* status);
CS_Sink CS_CreateRawSink(const char* name, CS_Status* status);
@@ -48,7 +35,7 @@ CS_Sink CS_CreateRawSinkCallback(const char* name, void* data,
uint64_t time),
CS_Status* status);
void CS_PutRawSourceFrame(CS_Source source, const struct CS_RawFrame* image,
void CS_PutRawSourceFrame(CS_Source source, const struct WPI_RawFrame* image,
CS_Status* status);
CS_Source CS_CreateRawSource(const char* name, const CS_VideoMode* mode,
@@ -62,19 +49,6 @@ CS_Source CS_CreateRawSource(const char* name, const CS_VideoMode* mode,
#ifdef __cplusplus
namespace cs {
struct RawFrame : public CS_RawFrame {
RawFrame() {
data = nullptr;
dataLength = 0;
pixelFormat = CS_PIXFMT_UNKNOWN;
width = 0;
height = 0;
totalData = 0;
}
~RawFrame() { CS_FreeRawFrameData(this); }
};
/**
* @defgroup cscore_raw_func Raw Image Functions
* @{
@@ -88,10 +62,10 @@ CS_Sink CreateRawSinkCallback(std::string_view name,
std::function<void(uint64_t time)> processFrame,
CS_Status* status);
void PutSourceFrame(CS_Source source, const CS_RawFrame& image,
void PutSourceFrame(CS_Source source, const WPI_RawFrame& image,
CS_Status* status);
uint64_t GrabSinkFrame(CS_Sink sink, CS_RawFrame& image, CS_Status* status);
uint64_t GrabSinkFrameTimeout(CS_Sink sink, CS_RawFrame& image, double timeout,
uint64_t GrabSinkFrame(CS_Sink sink, WPI_RawFrame& image, CS_Status* status);
uint64_t GrabSinkFrameTimeout(CS_Sink sink, WPI_RawFrame& image, double timeout,
CS_Status* status);
/**
@@ -129,7 +103,7 @@ class RawSource : public ImageSource {
*
* @param image raw frame image
*/
void PutFrame(RawFrame& image);
void PutFrame(wpi::RawFrame& image);
};
/**
@@ -177,7 +151,7 @@ class RawSink : public ImageSink {
* and is in 1 us increments.
*/
[[nodiscard]]
uint64_t GrabFrame(RawFrame& image, double timeout = 0.225) const;
uint64_t GrabFrame(wpi::RawFrame& image, double timeout = 0.225) const;
/**
* Wait for the next frame and get the image. May block forever.
@@ -188,7 +162,7 @@ class RawSink : public ImageSink {
* and is in 1 us increments.
*/
[[nodiscard]]
uint64_t GrabFrameNoTimeout(RawFrame& image) const;
uint64_t GrabFrameNoTimeout(wpi::RawFrame& image) const;
};
inline RawSource::RawSource(std::string_view name, const VideoMode& mode) {
@@ -202,7 +176,7 @@ inline RawSource::RawSource(std::string_view name,
CreateRawSource(name, VideoMode{format, width, height, fps}, &m_status);
}
inline void RawSource::PutFrame(RawFrame& image) {
inline void RawSource::PutFrame(wpi::RawFrame& image) {
m_status = 0;
PutSourceFrame(m_handle, image, &m_status);
}
@@ -216,12 +190,12 @@ inline RawSink::RawSink(std::string_view name,
m_handle = CreateRawSinkCallback(name, processFrame, &m_status);
}
inline uint64_t RawSink::GrabFrame(RawFrame& image, double timeout) const {
inline uint64_t RawSink::GrabFrame(wpi::RawFrame& image, double timeout) const {
m_status = 0;
return GrabSinkFrameTimeout(m_handle, image, timeout, &m_status);
}
inline uint64_t RawSink::GrabFrameNoTimeout(RawFrame& image) const {
inline uint64_t RawSink::GrabFrameNoTimeout(wpi::RawFrame& image) const {
m_status = 0;
return GrabSinkFrame(m_handle, image, &m_status);
}

View File

@@ -62,7 +62,7 @@ class RawCvSource : public RawSource {
void PutFrame(cv::Mat& image);
private:
RawFrame rawFrame;
wpi::RawFrame rawFrame;
};
/**
@@ -151,7 +151,7 @@ class RawCvSink : public RawSink {
uint64_t GrabFrameNoTimeoutDirect(cv::Mat& image);
private:
RawFrame rawFrame;
wpi::RawFrame rawFrame;
};
inline RawCvSource::RawCvSource(std::string_view name, const VideoMode& mode)
@@ -168,7 +168,8 @@ inline void RawCvSource::PutFrame(cv::Mat& image) {
rawFrame.width = image.cols;
rawFrame.height = image.rows;
rawFrame.totalData = image.total() * image.channels();
rawFrame.pixelFormat = image.channels() == 3 ? CS_PIXFMT_BGR : CS_PIXFMT_GRAY;
rawFrame.pixelFormat =
image.channels() == 3 ? WPI_PIXFMT_BGR : WPI_PIXFMT_GRAY;
PutSourceFrame(m_handle, rawFrame, &m_status);
}
@@ -201,7 +202,7 @@ inline uint64_t RawCvSink::GrabFrameNoTimeout(cv::Mat& image) {
inline uint64_t RawCvSink::GrabFrameDirect(cv::Mat& image, double timeout) {
rawFrame.height = 0;
rawFrame.width = 0;
rawFrame.pixelFormat = CS_PixelFormat::CS_PIXFMT_BGR;
rawFrame.pixelFormat = WPI_PixelFormat::WPI_PIXFMT_BGR;
m_status = RawSink::GrabFrame(rawFrame, timeout);
if (m_status <= 0) {
return m_status;
@@ -213,7 +214,7 @@ inline uint64_t RawCvSink::GrabFrameDirect(cv::Mat& image, double timeout) {
inline uint64_t RawCvSink::GrabFrameNoTimeoutDirect(cv::Mat& image) {
rawFrame.height = 0;
rawFrame.width = 0;
rawFrame.pixelFormat = CS_PixelFormat::CS_PIXFMT_BGR;
rawFrame.pixelFormat = WPI_PixelFormat::WPI_PIXFMT_BGR;
m_status = RawSink::GrabFrameNoTimeout(rawFrame);
if (m_status <= 0) {
return m_status;