From ca9929424845449fd235a6d7768716c8e741de78 Mon Sep 17 00:00:00 2001 From: Hu Chunming <2657262686@qq.com> Date: Wed, 6 Aug 2025 11:29:42 +0800 Subject: [PATCH] 优化图片保存 --- src/reprocessing_module/save_snapshot_reprocessing.cpp | 41 ++++++++++++++++++++++++++--------------- src/reprocessing_module/save_snapshot_reprocessing.h | 7 ++++--- src/util/JpegUtil.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ src/util/JpegUtil.h | 2 +- 4 files changed, 98 insertions(+), 37 deletions(-) diff --git a/src/reprocessing_module/save_snapshot_reprocessing.cpp b/src/reprocessing_module/save_snapshot_reprocessing.cpp index 1fff9d8..94ea282 100644 --- a/src/reprocessing_module/save_snapshot_reprocessing.cpp +++ b/src/reprocessing_module/save_snapshot_reprocessing.cpp @@ -23,18 +23,23 @@ save_snapshot_reprocessing::save_snapshot_reprocessing(int devId) { callback_ = nullptr; #endif + m_devId = devId; + bFinish = false; - m_save_img_thread = std::thread(save_img_thread_process, this); - m_devId = devId; - jpegUtil.jpeg_init(m_devId); + for (size_t i = 0; i < SAVE_THREAD_COUNT; i++) + { + m_save_img_thread[i] = std::thread(save_img_thread_process, this); + } } save_snapshot_reprocessing::~save_snapshot_reprocessing(){ // 结束线程 bFinish = true; - m_save_img_thread.join(); - jpegUtil.jpeg_release(); + for (size_t i = 0; i < SAVE_THREAD_COUNT; i++) + { + m_save_img_thread[i].join(); + } } // 释放资源 @@ -68,7 +73,7 @@ void save_snapshot_reprocessing::reprocessing_process_wo_locus_async(ImgSaveInfo while(!bFinish){ waitforsave_img_queue_mutex.lock(); - if(waitforsave_img_queue.size() > 100){ + if(waitforsave_img_queue.size() > 320){ waitforsave_img_queue_mutex.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(5)); continue; @@ -81,35 +86,41 @@ void save_snapshot_reprocessing::reprocessing_process_wo_locus_async(ImgSaveInfo } void save_snapshot_reprocessing::save_img_process() { + JpegUtil jpegUtil; + jpegUtil.jpeg_init(m_devId); + while (true) { if (bFinish){ break; } std::this_thread::sleep_for(std::chrono::milliseconds(2)); - std::unique_lock l(waitforsave_img_queue_mutex); + waitforsave_img_queue_mutex.lock(); if (!waitforsave_img_queue.empty()) { LOG_DEBUG("waitforsave_image_queue size: {}", waitforsave_img_queue.size()); ImgSaveInfo cur_image = waitforsave_img_queue.front(); waitforsave_img_queue.pop(); - l.unlock(); + waitforsave_img_queue_mutex.unlock(); + bool bSaved = false; if(!cur_image.file_path.empty()){ - jpegUtil.jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path); + bSaved = jpegUtil.jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path); + if(!bSaved){ + LOG_ERROR("jpeg_encode failed"); + } } VPCUtil::vpc_img_release(cur_image.img_info); #ifdef POST_USE_RABBITMQ - if (callback_ != nullptr && cur_image.json_str.length() > 0) { - // LOG_DEBUG("mq publish process 00000000000000000"); + if (bSaved && callback_ != nullptr && cur_image.json_str.length() > 0) { callback_(cur_image.json_str.c_str()); - // LOG_DEBUG("mq publish process 11111111111111111"); } #endif } else { - l.unlock(); + waitforsave_img_queue_mutex.unlock(); } - } -} + + jpegUtil.jpeg_release(); +} \ No newline at end of file diff --git a/src/reprocessing_module/save_snapshot_reprocessing.h b/src/reprocessing_module/save_snapshot_reprocessing.h index 7ddebc2..9687a35 100644 --- a/src/reprocessing_module/save_snapshot_reprocessing.h +++ b/src/reprocessing_module/save_snapshot_reprocessing.h @@ -25,11 +25,14 @@ using namespace std; +#define SAVE_THREAD_COUNT 16 + class DeviceMemory; struct ImgSaveInfo{ string file_path {""}; vpc_img_info img_info; + // Mat cpu_img; string json_str {""}; sy_rect obj_rect; }; @@ -55,13 +58,11 @@ private: queue waitforsave_img_queue; mutable std::mutex waitforsave_img_queue_mutex; - std::thread m_save_img_thread; + std::thread m_save_img_thread[SAVE_THREAD_COUNT]; bool bFinish = false; int m_devId; - JpegUtil jpegUtil; - #ifdef POST_USE_RABBITMQ callback_t callback_; std::shared_ptr rbmq_handler_; diff --git a/src/util/JpegUtil.cpp b/src/util/JpegUtil.cpp index 0dac6d5..7045126 100644 --- a/src/util/JpegUtil.cpp +++ b/src/util/JpegUtil.cpp @@ -2,6 +2,7 @@ #include #include #include "JpegUtil.h" +#include "../common/logger.hpp" using namespace std; @@ -18,11 +19,17 @@ int JpegUtil::jpeg_init(int32_t devId){ // channel 准备 dvppChannelDesc_ = acldvppCreateChannelDesc(); ret = acldvppCreateChannel(dvppChannelDesc_); + if(ret != ACL_ERROR_NONE){ + LOG_ERROR("acldvppCreateChannel failed!"); + exit(-2); + } // 创建图片编码配置数据,设置编码质量 // 编码质量范围[0, 100],其中level 0编码质量与level 100差不多,而在[1, 100]内数值越小输出图片质量越差。 jpegeConfig_ = acldvppCreateJpegeConfig(); acldvppSetJpegeConfigLevel(jpegeConfig_, 100); + + return 0; } void JpegUtil::jpeg_release(){ @@ -48,17 +55,15 @@ void JpegUtil::jpeg_release(){ if (context_ != nullptr) { ret = aclrtDestroyContext(context_); if (ret != ACL_SUCCESS) { - printf("destroy context failed"); + LOG_ERROR("destroy context failed"); } context_ = nullptr; } - printf("end to destroy context"); ret = aclrtResetDevice(deviceId_); if (ret != ACL_SUCCESS) { - printf("reset device failed"); + LOG_ERROR("reset device failed"); } - printf("end to reset device is %d", deviceId_); } int32_t JpegUtil::jpege_save(char* pcData , uint32_t dataLen, string out_file_name) @@ -66,7 +71,7 @@ int32_t JpegUtil::jpege_save(char* pcData , uint32_t dataLen, string out_file_na FILE* fd = nullptr; fd = fopen(out_file_name.c_str(), "wb"); if (fd == nullptr) { - printf("open output file err\n"); + LOG_ERROR("open output file error"); return 1; } @@ -77,7 +82,12 @@ int32_t JpegUtil::jpege_save(char* pcData , uint32_t dataLen, string out_file_na return 0; } -void JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name){ +bool JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name) { + + if (nullptr == encodeInputDesc_) { + LOG_ERROR("encodeInputDesc_ is nullptr!"); + return false; + } aclError aclRet ; aclRet = aclrtSetDevice(deviceId_); @@ -86,23 +96,62 @@ void JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_nam // 8. 申请输出内存,申请Device内存encodeOutBufferDev_,存放编码后的输出数据 uint32_t outBufferSize= 0; int ret = acldvppJpegPredictEncSize(encodeInputDesc_, jpegeConfig_, &outBufferSize); + if (ret != ACL_SUCCESS || outBufferSize <= 0) { + LOG_ERROR("acldvppJpegPredictEncSize failed!"); + return false; + } void *encodeOutBufferDev_ = nullptr; ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize); + if (ret != ACL_SUCCESS) { + LOG_ERROR("acldvppMalloc failed!"); + return false; + } - // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 - aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_); - aclRet = aclrtSynchronizeStream(stream_); + bool bRet = false; + do { + // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 + aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_); + if (ret != ACL_SUCCESS) { + LOG_ERROR("acldvppJpegEncodeAsync failed!"); + break; + } + aclRet = aclrtSynchronizeStream(stream_); + if (ret != ACL_SUCCESS) { + LOG_ERROR("aclrtSynchronizeStream failed!"); + break; + } + + // 申请Host内存outputHostBuffer + void* outputHostBuffer = malloc(outBufferSize); + if(outputHostBuffer == nullptr) { + LOG_ERROR("malloc failed!"); + break; + } + + // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host + aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != ACL_SUCCESS) { + free(outputHostBuffer); + outputHostBuffer = nullptr; + LOG_ERROR("aclrtMemcpy failed!"); + break; + } + + // 数据使用完成后,释放内存 + ret = jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name); + free(outputHostBuffer); + outputHostBuffer = nullptr; + if(ret != 0) { + LOG_ERROR("jpege_save failed!"); + break; + } - // 该模式下,由于处理结果在Device侧,因此需要调用内存复制接口传输结果数据后,再释放Device侧内存 - // 申请Host内存outputHostBuffer - void* outputHostBuffer = malloc(outBufferSize); - // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host - aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); + bRet = true; + } while (0); + // 释放掉输入输出的device内存 (void)acldvppFree(encodeOutBufferDev_); encodeOutBufferDev_ = nullptr; - // 数据使用完成后,释放内存 - jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name); - free(outputHostBuffer); - outputHostBuffer = nullptr; + aclRet = aclrtResetDevice(deviceId_); + return bRet; } \ No newline at end of file diff --git a/src/util/JpegUtil.h b/src/util/JpegUtil.h index a569a9a..8e74d42 100644 --- a/src/util/JpegUtil.h +++ b/src/util/JpegUtil.h @@ -15,7 +15,7 @@ public: void jpeg_release(); - void jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name); + bool jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name); private: int32_t jpege_save(char* pcData , uint32_t dataLen, string out_file_name); -- libgit2 0.21.4