Commit ca9929424845449fd235a6d7768716c8e741de78

Authored by Hu Chunming
1 parent 54b6e488

优化图片保存

src/reprocessing_module/save_snapshot_reprocessing.cpp
... ... @@ -23,18 +23,23 @@ save_snapshot_reprocessing::save_snapshot_reprocessing(int devId) {
23 23 callback_ = nullptr;
24 24 #endif
25 25  
  26 + m_devId = devId;
  27 +
26 28 bFinish = false;
27   - m_save_img_thread = std::thread(save_img_thread_process, this);
28 29  
29   - m_devId = devId;
30   - jpegUtil.jpeg_init(m_devId);
  30 + for (size_t i = 0; i < SAVE_THREAD_COUNT; i++)
  31 + {
  32 + m_save_img_thread[i] = std::thread(save_img_thread_process, this);
  33 + }
31 34 }
32 35  
33 36 save_snapshot_reprocessing::~save_snapshot_reprocessing(){
34 37 // 结束线程
35 38 bFinish = true;
36   - m_save_img_thread.join();
37   - jpegUtil.jpeg_release();
  39 + for (size_t i = 0; i < SAVE_THREAD_COUNT; i++)
  40 + {
  41 + m_save_img_thread[i].join();
  42 + }
38 43 }
39 44  
40 45 // 释放资源
... ... @@ -68,7 +73,7 @@ void save_snapshot_reprocessing::reprocessing_process_wo_locus_async(ImgSaveInfo
68 73  
69 74 while(!bFinish){
70 75 waitforsave_img_queue_mutex.lock();
71   - if(waitforsave_img_queue.size() > 100){
  76 + if(waitforsave_img_queue.size() > 320){
72 77 waitforsave_img_queue_mutex.unlock();
73 78 std::this_thread::sleep_for(std::chrono::milliseconds(5));
74 79 continue;
... ... @@ -81,35 +86,41 @@ void save_snapshot_reprocessing::reprocessing_process_wo_locus_async(ImgSaveInfo
81 86 }
82 87  
83 88 void save_snapshot_reprocessing::save_img_process() {
  89 + JpegUtil jpegUtil;
  90 + jpegUtil.jpeg_init(m_devId);
  91 +
84 92 while (true) {
85 93 if (bFinish){
86 94 break;
87 95 }
88 96  
89 97 std::this_thread::sleep_for(std::chrono::milliseconds(2));
90   - std::unique_lock<std::mutex> l(waitforsave_img_queue_mutex);
  98 + waitforsave_img_queue_mutex.lock();
91 99 if (!waitforsave_img_queue.empty()) {
92 100 LOG_DEBUG("waitforsave_image_queue size: {}", waitforsave_img_queue.size());
93 101 ImgSaveInfo cur_image = waitforsave_img_queue.front();
94 102 waitforsave_img_queue.pop();
95   - l.unlock();
  103 + waitforsave_img_queue_mutex.unlock();
96 104  
  105 + bool bSaved = false;
97 106 if(!cur_image.file_path.empty()){
98   - jpegUtil.jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path);
  107 + bSaved = jpegUtil.jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path);
  108 + if(!bSaved){
  109 + LOG_ERROR("jpeg_encode failed");
  110 + }
99 111 }
100 112 VPCUtil::vpc_img_release(cur_image.img_info);
101 113  
102 114 #ifdef POST_USE_RABBITMQ
103   - if (callback_ != nullptr && cur_image.json_str.length() > 0) {
104   - // LOG_DEBUG("mq publish process 00000000000000000");
  115 + if (bSaved && callback_ != nullptr && cur_image.json_str.length() > 0) {
105 116 callback_(cur_image.json_str.c_str());
106   - // LOG_DEBUG("mq publish process 11111111111111111");
107 117 }
108 118 #endif
109 119  
110 120 } else {
111   - l.unlock();
  121 + waitforsave_img_queue_mutex.unlock();
112 122 }
113   -
114 123 }
115   -}
  124 +
  125 + jpegUtil.jpeg_release();
  126 +}
116 127 \ No newline at end of file
... ...
src/reprocessing_module/save_snapshot_reprocessing.h
... ... @@ -25,11 +25,14 @@
25 25  
26 26 using namespace std;
27 27  
  28 +#define SAVE_THREAD_COUNT 16
  29 +
28 30 class DeviceMemory;
29 31  
30 32 struct ImgSaveInfo{
31 33 string file_path {""};
32 34 vpc_img_info img_info;
  35 + // Mat cpu_img;
33 36 string json_str {""};
34 37 sy_rect obj_rect;
35 38 };
... ... @@ -55,13 +58,11 @@ private:
55 58  
56 59 queue<ImgSaveInfo> waitforsave_img_queue;
57 60 mutable std::mutex waitforsave_img_queue_mutex;
58   - std::thread m_save_img_thread;
  61 + std::thread m_save_img_thread[SAVE_THREAD_COUNT];
59 62  
60 63 bool bFinish = false;
61 64 int m_devId;
62 65  
63   - JpegUtil jpegUtil;
64   -
65 66 #ifdef POST_USE_RABBITMQ
66 67 callback_t callback_;
67 68 std::shared_ptr<mq::post_rabbitmq_reprocessing> rbmq_handler_;
... ...
src/util/JpegUtil.cpp
... ... @@ -2,6 +2,7 @@
2 2 #include <cstdlib>
3 3 #include <memory>
4 4 #include "JpegUtil.h"
  5 +#include "../common/logger.hpp"
5 6  
6 7 using namespace std;
7 8  
... ... @@ -18,11 +19,17 @@ int JpegUtil::jpeg_init(int32_t devId){
18 19 // channel 准备
19 20 dvppChannelDesc_ = acldvppCreateChannelDesc();
20 21 ret = acldvppCreateChannel(dvppChannelDesc_);
  22 + if(ret != ACL_ERROR_NONE){
  23 + LOG_ERROR("acldvppCreateChannel failed!");
  24 + exit(-2);
  25 + }
21 26  
22 27 // 创建图片编码配置数据,设置编码质量
23 28 // 编码质量范围[0, 100],其中level 0编码质量与level 100差不多,而在[1, 100]内数值越小输出图片质量越差。
24 29 jpegeConfig_ = acldvppCreateJpegeConfig();
25 30 acldvppSetJpegeConfigLevel(jpegeConfig_, 100);
  31 +
  32 + return 0;
26 33 }
27 34  
28 35 void JpegUtil::jpeg_release(){
... ... @@ -48,17 +55,15 @@ void JpegUtil::jpeg_release(){
48 55 if (context_ != nullptr) {
49 56 ret = aclrtDestroyContext(context_);
50 57 if (ret != ACL_SUCCESS) {
51   - printf("destroy context failed");
  58 + LOG_ERROR("destroy context failed");
52 59 }
53 60 context_ = nullptr;
54 61 }
55   - printf("end to destroy context");
56 62  
57 63 ret = aclrtResetDevice(deviceId_);
58 64 if (ret != ACL_SUCCESS) {
59   - printf("reset device failed");
  65 + LOG_ERROR("reset device failed");
60 66 }
61   - printf("end to reset device is %d", deviceId_);
62 67 }
63 68  
64 69 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
66 71 FILE* fd = nullptr;
67 72 fd = fopen(out_file_name.c_str(), "wb");
68 73 if (fd == nullptr) {
69   - printf("open output file err\n");
  74 + LOG_ERROR("open output file error");
70 75 return 1;
71 76 }
72 77  
... ... @@ -77,7 +82,12 @@ int32_t JpegUtil::jpege_save(char* pcData , uint32_t dataLen, string out_file_na
77 82 return 0;
78 83 }
79 84  
80   -void JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name){
  85 +bool JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name) {
  86 +
  87 + if (nullptr == encodeInputDesc_) {
  88 + LOG_ERROR("encodeInputDesc_ is nullptr!");
  89 + return false;
  90 + }
81 91  
82 92 aclError aclRet ;
83 93 aclRet = aclrtSetDevice(deviceId_);
... ... @@ -86,23 +96,62 @@ void JpegUtil::jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_nam
86 96 // 8. 申请输出内存,申请Device内存encodeOutBufferDev_,存放编码后的输出数据
87 97 uint32_t outBufferSize= 0;
88 98 int ret = acldvppJpegPredictEncSize(encodeInputDesc_, jpegeConfig_, &outBufferSize);
  99 + if (ret != ACL_SUCCESS || outBufferSize <= 0) {
  100 + LOG_ERROR("acldvppJpegPredictEncSize failed!");
  101 + return false;
  102 + }
89 103 void *encodeOutBufferDev_ = nullptr;
90 104 ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize);
  105 + if (ret != ACL_SUCCESS) {
  106 + LOG_ERROR("acldvppMalloc failed!");
  107 + return false;
  108 + }
91 109  
92   - // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
93   - aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_);
94   - aclRet = aclrtSynchronizeStream(stream_);
  110 + bool bRet = false;
  111 + do {
  112 + // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  113 + aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_);
  114 + if (ret != ACL_SUCCESS) {
  115 + LOG_ERROR("acldvppJpegEncodeAsync failed!");
  116 + break;
  117 + }
  118 + aclRet = aclrtSynchronizeStream(stream_);
  119 + if (ret != ACL_SUCCESS) {
  120 + LOG_ERROR("aclrtSynchronizeStream failed!");
  121 + break;
  122 + }
  123 +
  124 + // 申请Host内存outputHostBuffer
  125 + void* outputHostBuffer = malloc(outBufferSize);
  126 + if(outputHostBuffer == nullptr) {
  127 + LOG_ERROR("malloc failed!");
  128 + break;
  129 + }
  130 +
  131 + // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
  132 + aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
  133 + if (ret != ACL_SUCCESS) {
  134 + free(outputHostBuffer);
  135 + outputHostBuffer = nullptr;
  136 + LOG_ERROR("aclrtMemcpy failed!");
  137 + break;
  138 + }
  139 +
  140 + // 数据使用完成后,释放内存
  141 + ret = jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
  142 + free(outputHostBuffer);
  143 + outputHostBuffer = nullptr;
  144 + if(ret != 0) {
  145 + LOG_ERROR("jpege_save failed!");
  146 + break;
  147 + }
95 148  
96   - // 该模式下,由于处理结果在Device侧,因此需要调用内存复制接口传输结果数据后,再释放Device侧内存
97   - // 申请Host内存outputHostBuffer
98   - void* outputHostBuffer = malloc(outBufferSize);
99   - // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
100   - aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
  149 + bRet = true;
  150 + } while (0);
  151 +
101 152 // 释放掉输入输出的device内存
102 153 (void)acldvppFree(encodeOutBufferDev_);
103 154 encodeOutBufferDev_ = nullptr;
104   - // 数据使用完成后,释放内存
105   - jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
106   - free(outputHostBuffer);
107   - outputHostBuffer = nullptr;
  155 + aclRet = aclrtResetDevice(deviceId_);
  156 + return bRet;
108 157 }
109 158 \ No newline at end of file
... ...
src/util/JpegUtil.h
... ... @@ -15,7 +15,7 @@ public:
15 15  
16 16 void jpeg_release();
17 17  
18   - void jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name);
  18 + bool jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name);
19 19  
20 20 private:
21 21 int32_t jpege_save(char* pcData , uint32_t dataLen, string out_file_name);
... ...