修复阶段4之前的问题
This commit is contained in:
parent
c36563bc87
commit
26b047f1cf
@ -95,11 +95,13 @@ void QuickSortDescending(std::vector<float>& values, int left, int right, std::v
|
||||
void NMS(int valid_count, std::vector<float>& boxes, std::vector<int>& class_ids,
|
||||
std::vector<int>& order, int filter_id, float threshold) {
|
||||
for (int i = 0; i < valid_count; ++i) {
|
||||
if (order[i] == -1 || class_ids[i] != filter_id) continue;
|
||||
int n = order[i];
|
||||
if (n < 0 || n >= valid_count) continue;
|
||||
if (class_ids[n] != filter_id) continue;
|
||||
for (int j = i + 1; j < valid_count; ++j) {
|
||||
int m = order[j];
|
||||
if (m == -1 || class_ids[j] != filter_id) continue;
|
||||
if (m < 0 || m >= valid_count) continue;
|
||||
if (class_ids[m] != filter_id) continue;
|
||||
float x1_min = boxes[n * 4 + 0];
|
||||
float y1_min = boxes[n * 4 + 1];
|
||||
float x1_max = x1_min + boxes[n * 4 + 2];
|
||||
|
||||
@ -62,6 +62,127 @@ size_t CalcImageSize(int w, int h, PixelFormat fmt) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t CalcImageSizeStrided(int wstride, int hstride, PixelFormat fmt) {
|
||||
if (wstride <= 0 || hstride <= 0) return 0;
|
||||
const size_t ws = static_cast<size_t>(wstride);
|
||||
const size_t hs = static_cast<size_t>(hstride);
|
||||
switch (fmt) {
|
||||
case PixelFormat::NV12: {
|
||||
// Y: ws*hs, UV: ws*(hs/2)
|
||||
return ws * hs + ws * (hs / 2);
|
||||
}
|
||||
case PixelFormat::YUV420: {
|
||||
// Y: ws*hs, U/V: (ws/2)*(hs/2)
|
||||
const size_t y = ws * hs;
|
||||
const size_t uv = (ws / 2) * (hs / 2);
|
||||
return y + uv + uv;
|
||||
}
|
||||
case PixelFormat::RGB:
|
||||
case PixelFormat::BGR:
|
||||
return ws * hs * 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CopyToStridedBuffer(const Frame& src, uint8_t* dst, size_t dst_size,
|
||||
int dst_wstride, int dst_hstride) {
|
||||
if (!dst || dst_size == 0) return false;
|
||||
if (dst_wstride <= 0 || dst_hstride <= 0) return false;
|
||||
|
||||
std::memset(dst, 0, dst_size);
|
||||
|
||||
const int w = src.width;
|
||||
const int h = src.height;
|
||||
if (w <= 0 || h <= 0) return false;
|
||||
|
||||
if (src.format == PixelFormat::NV12) {
|
||||
const size_t y_bytes = static_cast<size_t>(dst_wstride) * dst_hstride;
|
||||
const size_t uv_bytes = static_cast<size_t>(dst_wstride) * (dst_hstride / 2);
|
||||
if (y_bytes + uv_bytes > dst_size) return false;
|
||||
|
||||
const uint8_t* src_y = src.planes[0].data ? src.planes[0].data : src.data;
|
||||
const uint8_t* src_uv = src.planes[1].data ? src.planes[1].data : nullptr;
|
||||
const int src_y_stride = src.planes[0].stride > 0 ? src.planes[0].stride : w;
|
||||
const int src_uv_stride = src.planes[1].stride > 0 ? src.planes[1].stride : w;
|
||||
if (!src_y || !src_uv) return false;
|
||||
|
||||
for (int row = 0; row < h; ++row) {
|
||||
std::memcpy(dst + static_cast<size_t>(row) * dst_wstride,
|
||||
src_y + static_cast<size_t>(row) * src_y_stride,
|
||||
static_cast<size_t>(w));
|
||||
}
|
||||
|
||||
uint8_t* dst_uv = dst + y_bytes;
|
||||
const int uv_rows = h / 2;
|
||||
for (int row = 0; row < uv_rows; ++row) {
|
||||
std::memcpy(dst_uv + static_cast<size_t>(row) * dst_wstride,
|
||||
src_uv + static_cast<size_t>(row) * src_uv_stride,
|
||||
static_cast<size_t>(w));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (src.format == PixelFormat::YUV420) {
|
||||
const size_t y_bytes = static_cast<size_t>(dst_wstride) * dst_hstride;
|
||||
const size_t uv_stride = static_cast<size_t>(dst_wstride) / 2;
|
||||
const size_t uv_h = static_cast<size_t>(dst_hstride) / 2;
|
||||
const size_t u_bytes = uv_stride * uv_h;
|
||||
const size_t v_bytes = u_bytes;
|
||||
if (y_bytes + u_bytes + v_bytes > dst_size) return false;
|
||||
|
||||
const uint8_t* src_y = src.planes[0].data ? src.planes[0].data : src.data;
|
||||
const uint8_t* src_u = src.planes[1].data ? src.planes[1].data : nullptr;
|
||||
const uint8_t* src_v = src.planes[2].data ? src.planes[2].data : nullptr;
|
||||
const int src_y_stride = src.planes[0].stride > 0 ? src.planes[0].stride : w;
|
||||
const int src_u_stride = src.planes[1].stride > 0 ? src.planes[1].stride : (w / 2);
|
||||
const int src_v_stride = src.planes[2].stride > 0 ? src.planes[2].stride : (w / 2);
|
||||
if (!src_y || !src_u || !src_v) return false;
|
||||
|
||||
for (int row = 0; row < h; ++row) {
|
||||
std::memcpy(dst + static_cast<size_t>(row) * dst_wstride,
|
||||
src_y + static_cast<size_t>(row) * src_y_stride,
|
||||
static_cast<size_t>(w));
|
||||
}
|
||||
|
||||
uint8_t* dst_u = dst + y_bytes;
|
||||
uint8_t* dst_v = dst + y_bytes + u_bytes;
|
||||
const int uv_rows = h / 2;
|
||||
const int uv_cols = w / 2;
|
||||
for (int row = 0; row < uv_rows; ++row) {
|
||||
std::memcpy(dst_u + static_cast<size_t>(row) * uv_stride,
|
||||
src_u + static_cast<size_t>(row) * src_u_stride,
|
||||
static_cast<size_t>(uv_cols));
|
||||
std::memcpy(dst_v + static_cast<size_t>(row) * uv_stride,
|
||||
src_v + static_cast<size_t>(row) * src_v_stride,
|
||||
static_cast<size_t>(uv_cols));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (src.format == PixelFormat::RGB || src.format == PixelFormat::BGR) {
|
||||
const size_t need = static_cast<size_t>(dst_wstride) * dst_hstride * 3;
|
||||
if (need > dst_size) return false;
|
||||
|
||||
const uint8_t* src_rgb = src.planes[0].data ? src.planes[0].data : src.data;
|
||||
const int src_stride = src.planes[0].stride > 0
|
||||
? src.planes[0].stride
|
||||
: (src.stride > 0 ? src.stride : w * 3);
|
||||
if (!src_rgb) return false;
|
||||
|
||||
const size_t dst_stride = static_cast<size_t>(dst_wstride) * 3;
|
||||
const size_t row_bytes = static_cast<size_t>(w) * 3;
|
||||
for (int row = 0; row < h; ++row) {
|
||||
std::memcpy(dst + static_cast<size_t>(row) * dst_stride,
|
||||
src_rgb + static_cast<size_t>(row) * src_stride,
|
||||
row_bytes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class PreprocessNode : public INode {
|
||||
@ -181,7 +302,7 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
size_t out_size = CalcImageSize(out_w, out_h, out_fmt);
|
||||
size_t out_size = CalcImageSizeStrided(dst_wstride, dst_hstride, out_fmt);
|
||||
if (out_size == 0 || src_fmt_rga == RK_FORMAT_UNKNOWN || dst_fmt_rga == RK_FORMAT_UNKNOWN) {
|
||||
std::cerr << "[preprocess] unsupported format for RGA\n";
|
||||
PushToDownstream(frame);
|
||||
@ -223,14 +344,18 @@ private:
|
||||
src_wstride, src_hstride, src_fmt_rga);
|
||||
} else if (frame->data) {
|
||||
// Source doesn't have DMA fd, copy to DMA buffer first to avoid >4GB address issue
|
||||
size_t src_size = CalcImageSize(frame->width, frame->height, frame->format);
|
||||
size_t src_size = CalcImageSizeStrided(src_wstride, src_hstride, frame->format);
|
||||
src_dma_buf = DmaAlloc(src_size);
|
||||
if (!src_dma_buf || !src_dma_buf->valid()) {
|
||||
std::cerr << "[preprocess] DMA alloc for src failed\n";
|
||||
PushToDownstream(frame);
|
||||
return;
|
||||
}
|
||||
memcpy(src_dma_buf->data(), frame->data, std::min(src_size, frame->data_size));
|
||||
if (!CopyToStridedBuffer(*frame, src_dma_buf->data(), src_dma_buf->size, src_wstride, src_hstride)) {
|
||||
std::cerr << "[preprocess] copy src to DMA failed\n";
|
||||
PushToDownstream(frame);
|
||||
return;
|
||||
}
|
||||
src_buf = wrapbuffer_fd_t(src_dma_buf->fd, frame->width, frame->height,
|
||||
src_wstride, src_hstride, src_fmt_rga);
|
||||
} else {
|
||||
@ -246,7 +371,7 @@ private:
|
||||
|
||||
if (need_resize && need_cvt) {
|
||||
// Allocate DMA buffer for intermediate result
|
||||
auto tmp_dma = DmaAlloc(CalcImageSize(out_w, out_h, frame->format));
|
||||
auto tmp_dma = DmaAlloc(CalcImageSizeStrided(dst_wstride, dst_hstride, frame->format));
|
||||
if (!tmp_dma || !tmp_dma->valid()) {
|
||||
std::cerr << "[preprocess] DMA alloc for tmp failed\n";
|
||||
PushToDownstream(frame);
|
||||
@ -274,7 +399,9 @@ private:
|
||||
out_frame->width = out_w;
|
||||
out_frame->height = out_h;
|
||||
out_frame->format = out_fmt;
|
||||
out_frame->stride = dst_wstride;
|
||||
out_frame->stride = (out_fmt == PixelFormat::RGB || out_fmt == PixelFormat::BGR)
|
||||
? (dst_wstride * 3)
|
||||
: dst_wstride;
|
||||
out_frame->dma_fd = dma_buf->fd;
|
||||
out_frame->data = dma_buf->data();
|
||||
out_frame->data_size = dma_buf->size;
|
||||
@ -355,7 +482,9 @@ private:
|
||||
out_frame->width = out_w;
|
||||
out_frame->height = out_h;
|
||||
out_frame->format = out_fmt;
|
||||
out_frame->stride = out_w;
|
||||
out_frame->stride = (out_fmt == PixelFormat::RGB || out_fmt == PixelFormat::BGR)
|
||||
? (out_w * 3)
|
||||
: out_w;
|
||||
out_frame->data = buffer->data();
|
||||
out_frame->data_size = buffer->size();
|
||||
out_frame->data_owner = buffer;
|
||||
@ -409,22 +538,74 @@ private:
|
||||
#endif
|
||||
|
||||
void SetupPlanes(Frame& f, PixelFormat fmt) {
|
||||
if (!f.data) return;
|
||||
|
||||
if (fmt == PixelFormat::NV12) {
|
||||
f.plane_count = 2;
|
||||
int y_size = f.width * f.height;
|
||||
f.planes[0] = {f.data, f.width, y_size, 0};
|
||||
f.planes[1] = {f.data + y_size, f.width, y_size / 2, y_size};
|
||||
} else if (fmt == PixelFormat::YUV420) {
|
||||
f.plane_count = 3;
|
||||
int y_size = f.width * f.height;
|
||||
int uv_size = y_size / 4;
|
||||
f.planes[0] = {f.data, f.width, y_size, 0};
|
||||
f.planes[1] = {f.data + y_size, f.width / 2, uv_size, y_size};
|
||||
f.planes[2] = {f.data + y_size + uv_size, f.width / 2, uv_size, y_size + uv_size};
|
||||
} else {
|
||||
f.plane_count = 1;
|
||||
f.planes[0] = {f.data, f.width * 3, static_cast<int>(f.data_size), 0};
|
||||
int y_stride = f.stride > 0 ? f.stride : f.width;
|
||||
if (y_stride <= 0) y_stride = f.width;
|
||||
|
||||
size_t y_bytes = static_cast<size_t>(y_stride) * static_cast<size_t>(f.height);
|
||||
if (f.data_size > 0) {
|
||||
const size_t candidate = (f.data_size * 2) / 3; // total = Y + UV = Y*3/2
|
||||
if (candidate >= y_bytes && candidate <= f.data_size &&
|
||||
(candidate % static_cast<size_t>(y_stride)) == 0) {
|
||||
y_bytes = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
size_t uv_bytes = y_bytes / 2;
|
||||
if (f.data_size > 0 && y_bytes + uv_bytes > f.data_size) {
|
||||
uv_bytes = f.data_size > y_bytes ? (f.data_size - y_bytes) : 0;
|
||||
}
|
||||
|
||||
f.planes[0] = {f.data, y_stride, static_cast<int>(y_bytes), 0};
|
||||
f.planes[1] = {f.data + y_bytes, y_stride, static_cast<int>(uv_bytes), static_cast<int>(y_bytes)};
|
||||
return;
|
||||
}
|
||||
|
||||
if (fmt == PixelFormat::YUV420) {
|
||||
f.plane_count = 3;
|
||||
int y_stride = f.stride > 0 ? f.stride : f.width;
|
||||
if (y_stride <= 0) y_stride = f.width;
|
||||
|
||||
size_t y_bytes = static_cast<size_t>(y_stride) * static_cast<size_t>(f.height);
|
||||
size_t hstride = static_cast<size_t>(f.height);
|
||||
if (f.data_size > 0) {
|
||||
const size_t candidate = (f.data_size * 2) / 3;
|
||||
if (candidate >= y_bytes && candidate <= f.data_size &&
|
||||
(candidate % static_cast<size_t>(y_stride)) == 0) {
|
||||
y_bytes = candidate;
|
||||
hstride = y_bytes / static_cast<size_t>(y_stride);
|
||||
}
|
||||
}
|
||||
|
||||
size_t uv_stride = static_cast<size_t>(y_stride) / 2;
|
||||
size_t uv_h = hstride / 2;
|
||||
size_t u_bytes = uv_stride * uv_h;
|
||||
size_t v_bytes = u_bytes;
|
||||
size_t need = y_bytes + u_bytes + v_bytes;
|
||||
|
||||
if (f.data_size > 0 && need > f.data_size) {
|
||||
// Fallback to tightly packed layout.
|
||||
y_stride = f.width;
|
||||
y_bytes = static_cast<size_t>(f.width) * static_cast<size_t>(f.height);
|
||||
uv_stride = static_cast<size_t>(f.width) / 2;
|
||||
uv_h = static_cast<size_t>(f.height) / 2;
|
||||
u_bytes = uv_stride * uv_h;
|
||||
v_bytes = u_bytes;
|
||||
}
|
||||
|
||||
f.planes[0] = {f.data, y_stride, static_cast<int>(y_bytes), 0};
|
||||
f.planes[1] = {f.data + y_bytes, static_cast<int>(uv_stride), static_cast<int>(u_bytes), static_cast<int>(y_bytes)};
|
||||
f.planes[2] = {f.data + y_bytes + u_bytes, static_cast<int>(uv_stride), static_cast<int>(v_bytes), static_cast<int>(y_bytes + u_bytes)};
|
||||
return;
|
||||
}
|
||||
|
||||
// RGB/BGR
|
||||
f.plane_count = 1;
|
||||
int stride_bytes = f.stride > 0 ? f.stride : (f.width * 3);
|
||||
f.planes[0] = {f.data, stride_bytes, static_cast<int>(f.data_size), 0};
|
||||
}
|
||||
|
||||
std::string id_;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user