From d7c944d898cc8e21f2a0a0159c8aaea7bac73045 Mon Sep 17 00:00:00 2001 From: sladro Date: Mon, 5 Jan 2026 19:10:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8A=B1=E5=B1=8F4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/alarm/uploaders/minio_uploader.cpp | 4 ++- plugins/preprocess/preprocess_node.cpp | 33 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/plugins/alarm/uploaders/minio_uploader.cpp b/plugins/alarm/uploaders/minio_uploader.cpp index 21ccf97..4149521 100644 --- a/plugins/alarm/uploaders/minio_uploader.cpp +++ b/plugins/alarm/uploaders/minio_uploader.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -323,7 +324,8 @@ bool MinioUploader::Init(const SimpleJson& config) { use_ssl_ = endpoint_.find("https://") == 0; #if HAS_CURL - curl_global_init(CURL_GLOBAL_DEFAULT); + static std::once_flag curl_once; + std::call_once(curl_once, [] { curl_global_init(CURL_GLOBAL_DEFAULT); }); #endif if (presign_endpoint_.empty() && (access_key_.empty() || secret_key_.empty())) { diff --git a/plugins/preprocess/preprocess_node.cpp b/plugins/preprocess/preprocess_node.cpp index 3b99166..0488ddd 100644 --- a/plugins/preprocess/preprocess_node.cpp +++ b/plugins/preprocess/preprocess_node.cpp @@ -105,7 +105,12 @@ bool CopyToStridedBuffer(const Frame& src, uint8_t* dst, size_t dst_size, 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; + if (!src_y) return false; + if (!src_uv) { + // Fallback: packed NV12 layout. + if (!src.data) return false; + src_uv = src.data + static_cast(src_y_stride) * static_cast(h); + } for (int row = 0; row < h; ++row) { std::memcpy(dst + static_cast(row) * dst_wstride, @@ -309,11 +314,31 @@ private: return true; } - // Calculate proper strides (RGA requires aligned strides) - // For YUV formats, wstride is the width of Y plane - // For RGB/BGR formats, wstride is width (not width*3) + // Calculate proper strides. + // IMPORTANT: For DMA-BUF frames (e.g. MPP decode output), the actual vertical stride + // (ver_stride) may be larger than `height`. We must honor that, otherwise RGA will + // read UV from the wrong offset (典型花屏/错色). int src_wstride = Align16(frame->width); int src_hstride = Align16(frame->height); + if (frame->format == PixelFormat::NV12 || frame->format == PixelFormat::YUV420) { + const int y_stride = frame->planes[0].stride > 0 ? frame->planes[0].stride + : (frame->stride > 0 ? frame->stride : frame->width); + if (y_stride > 0) src_wstride = y_stride; + if (frame->planes[0].size > 0 && y_stride > 0) { + const int hs = frame->planes[0].size / y_stride; + if (hs >= frame->height) src_hstride = hs; + } + } else if (frame->format == PixelFormat::RGB || frame->format == PixelFormat::BGR) { + const int stride_bytes = frame->planes[0].stride > 0 ? frame->planes[0].stride + : (frame->stride > 0 ? frame->stride : frame->width * 3); + if (stride_bytes > 0 && (stride_bytes % 3) == 0) { + src_wstride = stride_bytes / 3; + } + if (frame->planes[0].size > 0 && stride_bytes > 0) { + const int hs = frame->planes[0].size / stride_bytes; + if (hs >= frame->height) src_hstride = hs; + } + } int dst_wstride = Align16(out_w); int dst_hstride = Align16(out_h);