mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpiutil] Move RawFrame to wpiutil; add generation of RawFrame for AprilTags (#5923)
This commit is contained in:
@@ -6,7 +6,9 @@ package edu.wpi.first.apriltag;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import edu.wpi.first.apriltag.jni.AprilTagJNI;
|
||||
import edu.wpi.first.math.geometry.Pose3d;
|
||||
import edu.wpi.first.util.RawFrame;
|
||||
import java.util.Objects;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
@@ -44,4 +46,28 @@ public class AprilTag {
|
||||
public String toString() {
|
||||
return "AprilTag(ID: " + ID + ", pose: " + pose + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a RawFrame containing the apriltag with the id with family 16h5 passed in.
|
||||
*
|
||||
* @param id id
|
||||
* @return A RawFrame containing the AprilTag image
|
||||
*/
|
||||
public static RawFrame generate16h5AprilTagImage(int id) {
|
||||
RawFrame generatedImage = new RawFrame();
|
||||
AprilTagJNI.generate16h5AprilTagImage(id, generatedImage.getDataPtr());
|
||||
return generatedImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a RawFrame containing the apriltag with the id with family 36h11 passed in.
|
||||
*
|
||||
* @param id id
|
||||
* @return A RawFrame containing the AprilTag image
|
||||
*/
|
||||
public static RawFrame generate36h11AprilTagImage(int id) {
|
||||
RawFrame generatedImage = new RawFrame();
|
||||
AprilTagJNI.generate36h11AprilTagImage(id, generatedImage.getDataPtr());
|
||||
return generatedImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,4 +189,8 @@ public class AprilTagJNI {
|
||||
double fy,
|
||||
double cx,
|
||||
double cy);
|
||||
|
||||
public static native void generate16h5AprilTagImage(int id, long nativeAddr);
|
||||
|
||||
public static native void generate36h11AprilTagImage(int id, long nativeAddr);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,56 @@
|
||||
|
||||
#include <wpi/json.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4200)
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
#endif
|
||||
|
||||
#include "apriltag.h"
|
||||
#include "tag16h5.h"
|
||||
#include "tag36h11.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
wpi::RawFrame AprilTag::Generate36h11AprilTagImage(int id) {
|
||||
apriltag_family_t* tagFamily = tag36h11_create();
|
||||
image_u8_t* image = apriltag_to_image(tagFamily, id);
|
||||
wpi::RawFrame markerFrame{};
|
||||
size_t totalDataSize = image->height * image->stride * sizeof(char);
|
||||
markerFrame.data = static_cast<char*>(
|
||||
std::calloc(image->height * image->stride, sizeof(char)));
|
||||
std::memcpy(markerFrame.data, image->buf, totalDataSize);
|
||||
markerFrame.dataLength = image->width;
|
||||
markerFrame.height = image->height;
|
||||
markerFrame.pixelFormat = WPI_PIXFMT_GRAY;
|
||||
markerFrame.width = image->stride;
|
||||
markerFrame.totalData = totalDataSize;
|
||||
image_u8_destroy(image);
|
||||
tag36h11_destroy(tagFamily);
|
||||
return markerFrame;
|
||||
}
|
||||
|
||||
wpi::RawFrame AprilTag::Generate16h5AprilTagImage(int id) {
|
||||
apriltag_family_t* tagFamily = tag16h5_create();
|
||||
image_u8_t* image = apriltag_to_image(tagFamily, id);
|
||||
wpi::RawFrame markerFrame{};
|
||||
size_t totalDataSize = image->height * image->stride * sizeof(char);
|
||||
markerFrame.data = static_cast<char*>(
|
||||
std::calloc(image->height * image->stride, sizeof(char)));
|
||||
std::memcpy(markerFrame.data, image->buf, totalDataSize);
|
||||
markerFrame.dataLength = image->width;
|
||||
markerFrame.height = image->height;
|
||||
markerFrame.pixelFormat = WPI_PIXFMT_GRAY;
|
||||
markerFrame.width = image->stride;
|
||||
markerFrame.totalData = totalDataSize;
|
||||
image_u8_destroy(image);
|
||||
tag16h5_destroy(tagFamily);
|
||||
return markerFrame;
|
||||
}
|
||||
|
||||
void frc::to_json(wpi::json& json, const AprilTag& apriltag) {
|
||||
json = wpi::json{{"ID", apriltag.ID}, {"pose", apriltag.pose}};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <wpi/jni_util.h>
|
||||
|
||||
#include "edu_wpi_first_apriltag_jni_AprilTagJNI.h"
|
||||
#include "frc/apriltag/AprilTag.h"
|
||||
#include "frc/apriltag/AprilTagDetector.h"
|
||||
#include "frc/apriltag/AprilTagPoseEstimator.h"
|
||||
|
||||
@@ -587,4 +588,30 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
|
||||
return MakeJObject(env, estimator.Estimate(harr, carr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
|
||||
* Method: generate16h5AprilTagImage
|
||||
* Signature: (IJ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_generate16h5AprilTagImage
|
||||
(JNIEnv* env, jclass, jint id, jlong framePtr)
|
||||
{
|
||||
wpi::RawFrame* javaRawFrame = (wpi::RawFrame*)framePtr;
|
||||
*javaRawFrame = AprilTag::Generate16h5AprilTagImage(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
|
||||
* Method: generate36h11AprilTagImage
|
||||
* Signature: (IJ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_generate36h11AprilTagImage
|
||||
(JNIEnv* env, jclass, jint id, jlong framePtr)
|
||||
{
|
||||
wpi::RawFrame* javaRawFrame = (wpi::RawFrame*)framePtr;
|
||||
*javaRawFrame = AprilTag::Generate36h11AprilTagImage(id);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wpi/RawFrame.h>
|
||||
#include <wpi/SymbolExports.h>
|
||||
#include <wpi/json_fwd.h>
|
||||
|
||||
@@ -20,6 +21,9 @@ struct WPILIB_DLLEXPORT AprilTag {
|
||||
* Checks equality between this AprilTag and another object.
|
||||
*/
|
||||
bool operator==(const AprilTag&) const = default;
|
||||
|
||||
static wpi::RawFrame Generate36h11AprilTagImage(int id);
|
||||
static wpi::RawFrame Generate16h5AprilTagImage(int id);
|
||||
};
|
||||
|
||||
WPILIB_DLLEXPORT
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package edu.wpi.first.cscore;
|
||||
|
||||
import edu.wpi.first.cscore.raw.RawFrame;
|
||||
import edu.wpi.first.util.RawFrame;
|
||||
import edu.wpi.first.util.RuntimeLoader;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -387,10 +387,6 @@ public class CameraServerJNI {
|
||||
|
||||
public static native String[] getNetworkInterfaces();
|
||||
|
||||
public static native long allocateRawFrame();
|
||||
|
||||
public static native void freeRawFrame(long frame);
|
||||
|
||||
public static native void runMainRunLoop();
|
||||
|
||||
public static native int runMainRunLoopTimeout(double timeoutSeconds);
|
||||
|
||||
@@ -6,6 +6,7 @@ package edu.wpi.first.cscore.raw;
|
||||
|
||||
import edu.wpi.first.cscore.CameraServerJNI;
|
||||
import edu.wpi.first.cscore.ImageSink;
|
||||
import edu.wpi.first.util.RawFrame;
|
||||
|
||||
/**
|
||||
* A sink for user code to accept video frames as raw bytes.
|
||||
|
||||
@@ -7,6 +7,7 @@ package edu.wpi.first.cscore.raw;
|
||||
import edu.wpi.first.cscore.CameraServerJNI;
|
||||
import edu.wpi.first.cscore.ImageSource;
|
||||
import edu.wpi.first.cscore.VideoMode;
|
||||
import edu.wpi.first.util.RawFrame;
|
||||
|
||||
/**
|
||||
* A source for user code to provide video frames as raw bytes.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
// 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.cscore.raw;
|
||||
package edu.wpi.first.util;
|
||||
|
||||
import edu.wpi.first.cscore.CameraServerJNI;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
@@ -23,7 +22,7 @@ public class RawFrame implements AutoCloseable {
|
||||
|
||||
/** Construct a new RawFrame. */
|
||||
public RawFrame() {
|
||||
m_framePtr = CameraServerJNI.allocateRawFrame();
|
||||
m_framePtr = WPIUtilJNI.allocateRawFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,7 +31,7 @@ public class RawFrame implements AutoCloseable {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
CameraServerJNI.freeRawFrame(m_framePtr);
|
||||
WPIUtilJNI.freeRawFrame(m_framePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +80,10 @@ public class WPIUtilJNI {
|
||||
|
||||
public static native boolean releaseSemaphore(int semHandle, int releaseCount);
|
||||
|
||||
public static native long allocateRawFrame();
|
||||
|
||||
public static native void freeRawFrame(long frame);
|
||||
|
||||
/**
|
||||
* Waits for a handle to be signaled.
|
||||
*
|
||||
|
||||
30
wpiutil/src/main/native/cpp/RawFrame.cpp
Normal file
30
wpiutil/src/main/native/cpp/RawFrame.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
#include "wpi/RawFrame.h"
|
||||
|
||||
#include <wpi/MemAlloc.h>
|
||||
|
||||
extern "C" {
|
||||
void WPI_AllocateRawFrameData(WPI_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 WPI_FreeRawFrameData(WPI_RawFrame* frame) {
|
||||
if (frame->data) {
|
||||
std::free(frame->data);
|
||||
frame->data = nullptr;
|
||||
frame->dataLength = 0;
|
||||
}
|
||||
}
|
||||
} // extern "C"
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "edu_wpi_first_util_WPIUtilJNI.h"
|
||||
#include "wpi/RawFrame.h"
|
||||
#include "wpi/Synchronization.h"
|
||||
#include "wpi/jni_util.h"
|
||||
#include "wpi/timestamp.h"
|
||||
@@ -317,4 +318,32 @@ Java_edu_wpi_first_util_WPIUtilJNI_waitForObjectsTimeout
|
||||
return MakeJIntArray(env, signaled);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: allocateRawFrame
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_allocateRawFrame
|
||||
(JNIEnv*, jclass)
|
||||
{
|
||||
wpi::RawFrame* rawFrame = new wpi::RawFrame{};
|
||||
intptr_t rawFrameIntPtr = reinterpret_cast<intptr_t>(rawFrame);
|
||||
return static_cast<jlong>(rawFrameIntPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: freeRawFrame
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_freeRawFrame
|
||||
(JNIEnv*, jclass, jlong rawFrame)
|
||||
{
|
||||
wpi::RawFrame* ptr =
|
||||
reinterpret_cast<wpi::RawFrame*>(static_cast<intptr_t>(rawFrame));
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
63
wpiutil/src/main/native/include/wpi/RawFrame.h
Normal file
63
wpiutil/src/main/native/include/wpi/RawFrame.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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.
|
||||
|
||||
#ifndef WPIUTIL_WPI_RAWFRAME_H_
|
||||
#define WPIUTIL_WPI_RAWFRAME_H_
|
||||
|
||||
/**
|
||||
* Raw Frame
|
||||
*/
|
||||
typedef struct WPI_RawFrame { // NOLINT
|
||||
char* data;
|
||||
int dataLength;
|
||||
int pixelFormat;
|
||||
int width;
|
||||
int height;
|
||||
int totalData;
|
||||
} WPI_RawFrame;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pixel formats
|
||||
*/
|
||||
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
|
||||
};
|
||||
|
||||
void WPI_AllocateRawFrameData(WPI_RawFrame* frame, int requestedSize);
|
||||
void WPI_FreeRawFrameData(WPI_RawFrame* frame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi {
|
||||
struct RawFrame : public WPI_RawFrame {
|
||||
RawFrame() {
|
||||
data = nullptr;
|
||||
dataLength = 0;
|
||||
pixelFormat = WPI_PIXFMT_UNKNOWN;
|
||||
width = 0;
|
||||
height = 0;
|
||||
totalData = 0;
|
||||
}
|
||||
|
||||
~RawFrame() { WPI_FreeRawFrameData(this); }
|
||||
};
|
||||
} // namespace wpi
|
||||
|
||||
#endif
|
||||
|
||||
#endif // WPIUTIL_WPI_RAWFRAME_H_
|
||||
Reference in New Issue
Block a user