修复阶段4之前的问题

This commit is contained in:
sladro 2025-12-29 10:52:35 +08:00
parent c36563bc87
commit 26b047f1cf
2 changed files with 204 additions and 21 deletions

View File

@ -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];

View File

@ -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_;