OrangePi3588Media/include/frame/frame.h

140 lines
3.5 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;
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;
// 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