修bug
Some checks are pending
CI / host-build (push) Waiting to run
CI / rk3588-cross-build (push) Waiting to run

This commit is contained in:
sladro 2026-01-06 15:03:22 +08:00
parent d9ec32d40f
commit 8ed1824ea2
2 changed files with 40 additions and 13 deletions

View File

@ -393,33 +393,59 @@ private:
DmaBufferPtr src_dma_buf; // Keep alive if we allocate
// Allocate/copy outside the global RGA lock; librga calls are protected below.
if (frame->data && frame->dma_fd < 0) {
// 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);
// Important: some RGA drivers cannot map DMABUF whose physical address is >4GB.
// MPP decode outputs often come as dma_fd; to avoid kernel-side mapping failures
// (and downstream heap corruption), prefer copying into our own <4GB dma_heap buffer
// when CPU mapping is available.
const bool can_cpu_read_src = (frame->data != nullptr && frame->data_size > 0);
const bool should_copy_src_for_rga = (frame->dma_fd >= 0 && can_cpu_read_src);
if (should_copy_src_for_rga || (frame->dma_fd < 0 && frame->data)) {
// Use tight/aligned strides for the copied source buffer.
const int copy_wstride = Align16(frame->width);
const int copy_hstride = Align16(frame->height);
const size_t src_size = CalcImageSizeStrided(copy_wstride, copy_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";
return false;
}
// If source is a DMA-BUF, sync it before CPU reads.
if (frame->dma_fd >= 0) {
DmaSyncStartFd(frame->dma_fd);
}
// CPU writes to a DMA-BUF must be flushed before RGA reads it.
DmaSyncStartFd(src_dma_buf->fd);
if (!CopyToStridedBuffer(*frame, src_dma_buf->data(), src_dma_buf->size, src_wstride, src_hstride)) {
if (!CopyToStridedBuffer(*frame, src_dma_buf->data(), src_dma_buf->size, copy_wstride, copy_hstride)) {
DmaSyncEndFd(src_dma_buf->fd);
if (frame->dma_fd >= 0) {
DmaSyncEndFd(frame->dma_fd);
}
std::cerr << "[preprocess] copy src to DMA failed\n";
return false;
}
DmaSyncEndFd(src_dma_buf->fd);
if (frame->dma_fd >= 0) {
DmaSyncEndFd(frame->dma_fd);
}
// Update strides used for RGA to match the copied buffer.
src_wstride = copy_wstride;
src_hstride = copy_hstride;
}
// 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()) {
if (src_dma_buf && src_dma_buf->valid()) {
src_buf = wrapbuffer_fd_t(src_dma_buf->fd, frame->width, frame->height,
src_wstride, src_hstride, src_fmt_rga);
} else 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 {
return false;
}

View File

@ -169,15 +169,16 @@ DmaBufferPtr DmaAlloc(size_t alloc_size) {
// - Some RGA drivers cannot map buffers whose physical address is >4GB; prefer DMA32 heaps.
// - CMA heaps are also <4GB friendly but can be small/fragmented under multi-stream load.
const char* heap_paths[] = {
// Prefer CMA first when available.
// Prefer DMA32 heaps to keep allocations under 4GB.
// This avoids RGA drivers that cannot map >4GB physical addresses.
"/dev/dma_heap/system-dma32",
"/dev/dma_heap/system-uncached-dma32",
// CMA is also <4GB friendly, but can be small/fragmented under multi-stream load.
"/dev/dma_heap/cma",
"/dev/dma_heap/cma-uncached",
"/dev/dma_heap/linux,cma",
// Then prefer DMA32 heaps to keep allocations under 4GB.
"/dev/dma_heap/system-dma32",
"/dev/dma_heap/system-uncached-dma32",
// Generic system heaps (may allocate >4GB on high-mem systems).
"/dev/dma_heap/system-uncached",
"/dev/dma_heap/system",