142 lines
3.6 KiB
C++
142 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "behavior/behavior_event.h"
|
|
#include "hw/frame_buffer.h"
|
|
#include "frame/rect.h"
|
|
|
|
namespace rk3588 {
|
|
|
|
struct FaceDetResult;
|
|
struct FaceRecogResult;
|
|
struct PoseResult;
|
|
|
|
enum class PixelFormat {
|
|
NV12,
|
|
YUV420,
|
|
RGB,
|
|
BGR,
|
|
UNKNOWN
|
|
};
|
|
|
|
struct Detection {
|
|
int cls_id = -1;
|
|
float score = 0.0f;
|
|
Rect bbox{};
|
|
int track_id = -1;
|
|
};
|
|
|
|
struct DetectionResult {
|
|
std::vector<Detection> items;
|
|
int img_w = 0;
|
|
int img_h = 0;
|
|
std::string model_name;
|
|
};
|
|
|
|
struct FrameTransformMeta {
|
|
bool valid = false;
|
|
bool letterbox = false;
|
|
int src_w = 0;
|
|
int src_h = 0;
|
|
int dst_w = 0;
|
|
int dst_h = 0;
|
|
float scale_x = 1.0f;
|
|
float scale_y = 1.0f;
|
|
float pad_x = 0.0f;
|
|
float pad_y = 0.0f;
|
|
};
|
|
|
|
struct FramePlane {
|
|
uint8_t* data = nullptr;
|
|
int stride = 0; // bytes per row
|
|
int size = 0; // valid bytes in this plane
|
|
int offset = 0; // offset from base data pointer
|
|
};
|
|
|
|
struct Frame {
|
|
int width = 0;
|
|
int height = 0;
|
|
PixelFormat format = PixelFormat::UNKNOWN;
|
|
|
|
// Fallback stride for single-plane formats; prefer per-plane stride.
|
|
int stride = 0;
|
|
|
|
int dma_fd = -1;
|
|
uint64_t pts = 0; // microseconds
|
|
uint64_t frame_id = 0;
|
|
|
|
uint8_t* data = nullptr; // base pointer if mapped to CPU
|
|
size_t data_size = 0; // total mapped buffer size
|
|
int plane_count = 0;
|
|
std::array<FramePlane, 3> planes{};
|
|
|
|
// Optional owner to keep underlying buffer alive (e.g., shared_ptr<vector<uint8_t>> or MPP buffer).
|
|
std::shared_ptr<void> data_owner;
|
|
std::shared_ptr<FrameBuffer> buffer;
|
|
|
|
std::shared_ptr<DetectionResult> det;
|
|
std::shared_ptr<BehaviorEventResult> behavior_events;
|
|
std::shared_ptr<PoseResult> pose;
|
|
// Face recognition pipeline meta (kept separate from user_meta to avoid conflicts with publish).
|
|
std::shared_ptr<FaceDetResult> face_det;
|
|
std::shared_ptr<FaceRecogResult> face_recog;
|
|
std::shared_ptr<FrameTransformMeta> transform_meta;
|
|
std::shared_ptr<void> user_meta;
|
|
|
|
int DmaFd() const { return buffer ? buffer->DmaFd() : dma_fd; }
|
|
void SetDmaFd(int fd) {
|
|
dma_fd = fd;
|
|
if (buffer) buffer->SetDmaFd(fd);
|
|
}
|
|
|
|
const std::shared_ptr<void>& Owner() const { return buffer ? buffer->Owner() : data_owner; }
|
|
void SetOwner(std::shared_ptr<void> owner) {
|
|
data_owner = std::move(owner);
|
|
if (buffer) buffer->SetOwner(data_owner);
|
|
}
|
|
|
|
void SyncStart() const {
|
|
if (buffer) {
|
|
buffer->SyncStart();
|
|
} else if (dma_fd >= 0) {
|
|
DmaSyncStartFd(dma_fd);
|
|
}
|
|
}
|
|
|
|
void SyncEnd() const {
|
|
if (buffer) {
|
|
buffer->SyncEnd();
|
|
} else if (dma_fd >= 0) {
|
|
DmaSyncEndFd(dma_fd);
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<FrameBuffer> EnsureBuffer() {
|
|
if (!buffer) buffer = std::make_shared<FrameBuffer>();
|
|
return buffer;
|
|
}
|
|
|
|
void SyncBufferFromFrame() {
|
|
EnsureBuffer();
|
|
buffer->SetDmaFd(dma_fd);
|
|
buffer->SetOwner(data_owner);
|
|
const int count = std::min(plane_count, static_cast<int>(planes.size()));
|
|
std::vector<FrameBuffer::Plane> plane_list;
|
|
plane_list.reserve(static_cast<size_t>(std::max(0, count)));
|
|
for (int i = 0; i < count; ++i) {
|
|
const FramePlane& p = planes[i];
|
|
plane_list.push_back({p.data, p.stride, p.size, p.offset});
|
|
}
|
|
buffer->SetPlanes(std::move(plane_list));
|
|
}
|
|
};
|
|
|
|
} // namespace rk3588
|