修bug
This commit is contained in:
parent
7a937df529
commit
2eb3cefd8a
@ -4,6 +4,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -39,6 +40,21 @@ int ToRgaFormat(PixelFormat fmt) {
|
|||||||
default: return RK_FORMAT_UNKNOWN;
|
default: return RK_FORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::mutex& GlobalRgaMutex() {
|
||||||
|
static std::mutex* mu = new std::mutex();
|
||||||
|
return *mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnsureRgaInitializedOnce() {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, []() {
|
||||||
|
const IM_STATUS st = imcheckHeader();
|
||||||
|
if (st != IM_STATUS_NOERROR && st != IM_STATUS_SUCCESS) {
|
||||||
|
std::cerr << "[preprocess] imcheckHeader failed: " << imStrError(st) << "\n";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PixelFormat ParseFormat(const std::string& s) {
|
PixelFormat ParseFormat(const std::string& s) {
|
||||||
@ -285,6 +301,8 @@ private:
|
|||||||
|
|
||||||
#if defined(RK3588_ENABLE_RGA)
|
#if defined(RK3588_ENABLE_RGA)
|
||||||
bool ProcessRga(FramePtr frame) {
|
bool ProcessRga(FramePtr frame) {
|
||||||
|
EnsureRgaInitializedOnce();
|
||||||
|
|
||||||
PixelFormat out_fmt = (dst_fmt_ != PixelFormat::UNKNOWN) ? dst_fmt_ : frame->format;
|
PixelFormat out_fmt = (dst_fmt_ != PixelFormat::UNKNOWN) ? dst_fmt_ : frame->format;
|
||||||
int out_w = dst_w_;
|
int out_w = dst_w_;
|
||||||
int out_h = dst_h_;
|
int out_h = dst_h_;
|
||||||
@ -374,10 +392,8 @@ private:
|
|||||||
rga_buffer_t dst_buf{};
|
rga_buffer_t dst_buf{};
|
||||||
DmaBufferPtr src_dma_buf; // Keep alive if we allocate
|
DmaBufferPtr src_dma_buf; // Keep alive if we allocate
|
||||||
|
|
||||||
if (frame->dma_fd >= 0) {
|
// Allocate/copy outside the global RGA lock; librga calls are protected below.
|
||||||
src_buf = wrapbuffer_fd_t(frame->dma_fd, frame->width, frame->height,
|
if (frame->data && frame->dma_fd < 0) {
|
||||||
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
|
// Source doesn't have DMA fd, copy to DMA buffer first to avoid >4GB address issue
|
||||||
size_t src_size = CalcImageSizeStrided(src_wstride, src_hstride, frame->format);
|
size_t src_size = CalcImageSizeStrided(src_wstride, src_hstride, frame->format);
|
||||||
src_dma_buf = DmaAlloc(src_size);
|
src_dma_buf = DmaAlloc(src_size);
|
||||||
@ -393,6 +409,15 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DmaSyncEndFd(src_dma_buf->fd);
|
DmaSyncEndFd(src_dma_buf->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize librga/im2d usage; multiple pipelines call RGA concurrently.
|
||||||
|
std::lock_guard<std::mutex> lock(GlobalRgaMutex());
|
||||||
|
|
||||||
|
if (frame->dma_fd >= 0) {
|
||||||
|
src_buf = wrapbuffer_fd_t(frame->dma_fd, frame->width, frame->height,
|
||||||
|
src_wstride, src_hstride, src_fmt_rga);
|
||||||
|
} else if (src_dma_buf && src_dma_buf->valid()) {
|
||||||
src_buf = wrapbuffer_fd_t(src_dma_buf->fd, frame->width, frame->height,
|
src_buf = wrapbuffer_fd_t(src_dma_buf->fd, frame->width, frame->height,
|
||||||
src_wstride, src_hstride, src_fmt_rga);
|
src_wstride, src_hstride, src_fmt_rga);
|
||||||
} else {
|
} else {
|
||||||
@ -403,6 +428,17 @@ private:
|
|||||||
dst_buf = wrapbuffer_fd_t(dma_buf->fd, out_w, out_h,
|
dst_buf = wrapbuffer_fd_t(dma_buf->fd, out_w, out_h,
|
||||||
dst_wstride, dst_hstride, dst_fmt_rga);
|
dst_wstride, dst_hstride, dst_fmt_rga);
|
||||||
|
|
||||||
|
auto Check = [&](const rga_buffer_t& s, const rga_buffer_t& d) -> bool {
|
||||||
|
const im_rect sr{0, 0, s.width, s.height};
|
||||||
|
const im_rect dr{0, 0, d.width, d.height};
|
||||||
|
const IM_STATUS chk = imcheck(s, d, sr, dr);
|
||||||
|
if (chk != IM_STATUS_NOERROR && chk != IM_STATUS_SUCCESS) {
|
||||||
|
std::cerr << "[preprocess] RGA imcheck failed: " << imStrError(chk) << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
IM_STATUS status = IM_STATUS_SUCCESS;
|
IM_STATUS status = IM_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (need_resize && need_cvt) {
|
if (need_resize && need_cvt) {
|
||||||
@ -414,14 +450,23 @@ private:
|
|||||||
}
|
}
|
||||||
rga_buffer_t tmp = wrapbuffer_fd_t(tmp_dma->fd, out_w, out_h,
|
rga_buffer_t tmp = wrapbuffer_fd_t(tmp_dma->fd, out_w, out_h,
|
||||||
dst_wstride, dst_hstride, src_fmt_rga);
|
dst_wstride, dst_hstride, src_fmt_rga);
|
||||||
status = imresize(src_buf, tmp);
|
if (!Check(src_buf, tmp) || !Check(tmp, dst_buf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = imresize(src_buf, tmp, 0, 0, 0, 1, nullptr);
|
||||||
if (status == IM_STATUS_SUCCESS) {
|
if (status == IM_STATUS_SUCCESS) {
|
||||||
status = imcvtcolor(tmp, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
|
status = imcvtcolor(tmp, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT, 1, nullptr);
|
||||||
}
|
}
|
||||||
} else if (need_resize) {
|
} else if (need_resize) {
|
||||||
status = imresize(src_buf, dst_buf);
|
if (!Check(src_buf, dst_buf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = imresize(src_buf, dst_buf, 0, 0, 0, 1, nullptr);
|
||||||
} else if (need_cvt) {
|
} else if (need_cvt) {
|
||||||
status = imcvtcolor(src_buf, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT);
|
if (!Check(src_buf, dst_buf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = imcvtcolor(src_buf, dst_buf, src_fmt_rga, dst_fmt_rga, IM_COLOR_SPACE_DEFAULT, 1, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != IM_STATUS_SUCCESS) {
|
if (status != IM_STATUS_SUCCESS) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user