Commit d248da62fff59e75b5da6d00f1cb2c727fc737ff

Authored by Hu Chunming
1 parent 207d694c

优化代码,修正dvpp的一些bug

src/demo/main_dvpp.cpp
... ... @@ -91,23 +91,11 @@ void postDecoded(const void * userPtr, DeviceRgbMemory* devFrame){
91 91 AbstractDecoder* decoder = (AbstractDecoder*)userPtr;
92 92 if (decoder!= nullptr)
93 93 {
94   - // cout << "decode name: " << decoder->getName() << endl;
95   -
96   - // const char* gpu_pixfmt = av_get_pix_fmt_name((AVPixelFormat)gpuFrame->format);
97   - // cout << "pixfmt: " << gpu_pixfmt << endl;
98   - // cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl;
99   - // cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl;
  94 + }
100 95  
101   - int sum = sum1;
102   - if (decoder->getName() == "dec0")
103   - {
104   - sum1 ++ ;
105   - sum = sum1;
106   - } else if (decoder->getName() == "dec2")
107   - {
108   - sum2 ++ ;
109   - sum = sum2;
110   - }
  96 + if(devFrame){
  97 + delete devFrame;
  98 + devFrame = nullptr;
111 99 }
112 100 }
113 101  
... ... @@ -169,7 +157,8 @@ bool decode_request_stream_cbk(const char* deviceId){
169 157 // string test_uri = "rtsp://176.10.0.2:8554/stream";
170 158 // string test_uri = "/mnt/f/fiss/test_data/h265.mp4";
171 159 // string test_uri = "rtsp://176.10.0.4:8554/stream";
172   -string test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0";
  160 +// string test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0";
  161 +string test_uri = "/home/huchunming/data/woyikewangh265.mp4";
173 162  
174 163 void createDecode(int index, const char* gpu_id){
175 164 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
... ... @@ -241,6 +230,7 @@ void createDvppDecoder(int index, char* devId, int channelId){
241 230 AbstractDecoder* decoder = pDecManager->createDecoder(config);
242 231 if (!decoder)
243 232 {
  233 + cout << "创建解码器失败" << endl;
244 234 return ;
245 235 }
246 236 pDecManager->setPostDecArg(config.name, decoder);
... ... @@ -256,7 +246,7 @@ void logFF(void *, int level, const char *fmt, va_list ap)
256 246  
257 247 int main(int argc, char* argv[]){
258 248  
259   - test_uri = argv[1];
  249 + // test_uri = argv[1];
260 250 char* gpuid = argv[2];
261 251 int port = atoi(argv[3]);
262 252 cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl;
... ... @@ -272,7 +262,7 @@ int main(int argc, char* argv[]){
272 262 // cudaSetDevice(atoi(gpuid));
273 263 while (true)
274 264 {
275   - std::this_thread::sleep_for(std::chrono::minutes(1));
  265 + std::this_thread::sleep_for(std::chrono::seconds(10));
276 266 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
277 267 int count = pDecManager->count();
278 268 cout << "当前时间:" << UtilTools::get_cur_time_ms() << " 当前运行路数: " << pDecManager->count() << endl;
... ... @@ -288,6 +278,14 @@ int main(int argc, char* argv[]){
288 278  
289 279 createDvppDecoder(i, gpuid, 0);
290 280 i++;
  281 + createDvppDecoder(i, gpuid, 0);
  282 + i++;
  283 + createDvppDecoder(i, gpuid, 0);
  284 + i++;
  285 +
  286 + for(;i<30;i++){
  287 + createDvppDecoder(i, gpuid, 0);
  288 + }
291 289  
292 290 while (true)
293 291 {
... ...
src/dvpp/DvppDec.cpp
1 1 #include "DvppDec.h"
2 2 #include "DvppSourceManager.h"
3 3  
4   -#define CHECK_AND_RETURN(ret, message) \
5   - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}
6   -#define CHECK_NOT_RETURN(ret, message) \
7   - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
8   -#define CHECK_AND_RETURN_NOVALUE(ret, message) \
9   - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
10   -#define CHECK_AND_BREAK(ret, message) \
11   - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
12   -
13 4 struct Vdec_CallBack_UserData {
14 5 uint64_t frameId;
15 6 long startTime;
... ... @@ -22,10 +13,6 @@ struct Vdec_CallBack_UserData {
22 13 }
23 14 };
24 15  
25   -#ifdef TEST_DECODER
26   -static void *vdecHostAddr = nullptr;
27   -#endif
28   -
29 16 static const int g_pkt_size = 1024 * 1024;
30 17  
31 18 DvppDec::DvppDec(){
... ... @@ -33,11 +20,14 @@ static const int g_pkt_size = 1024 * 1024;
33 20 }
34 21  
35 22 DvppDec::~DvppDec(){
36   -
  23 + releaseResource();
37 24 }
38 25  
39 26 bool DvppDec::init_vdpp(DvppDecConfig cfg){
40   - cout << "Init device....\n";
  27 +
  28 + m_dec_name = cfg.dec_name;
  29 +
  30 + LOG_INFO("[{}]- Init device start...", m_dec_name);
41 31  
42 32 m_dvpp_deviceId = atoi(cfg.dev_id.c_str());
43 33  
... ... @@ -54,7 +44,7 @@ static const int g_pkt_size = 1024 * 1024;
54 44 // h265只有main
55 45 enType = H265_MAIN_LEVEL;
56 46 }else {
57   - cout << "codec_id is not supported!" << endl;
  47 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
58 48 return false;
59 49 }
60 50  
... ... @@ -66,42 +56,47 @@ static const int g_pkt_size = 1024 * 1024;
66 56 m_context = pSrcMgr->getContext(m_dvpp_deviceId);
67 57 m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
68 58 if(m_dvpp_channel < 0){
69   - cout << "该设备channel已经用完了" << endl;
  59 + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
70 60 return false;
71 61 }
72 62  
73   - cout << "devProgram start, device: " << m_dvpp_deviceId << endl;
74   - int ret = aclrtSetCurrentContext(m_context);
75   - if (ret != ACL_ERROR_NONE) {
76   - cout << "aclrtSetCurrentContext failed" << endl;
77   - return false;
78   - }
79   -
80   - // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死
81   - for (size_t i = 0; i < 20; i++){
82   - void *vdecInputbuf = nullptr;
83   - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
84   - if(ret != ACL_ERROR_NONE){
85   - cout << "acldvppMalloc failed" << endl;
86   - return false;;
87   - }
88   - m_vec_vdec.push_back(vdecInputbuf);
89   - }
  63 + do
  64 + {
  65 + CHECK_AND_BREAK(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed !");
90 66  
91   - if(!m_vdecQueue.init(m_vec_vdec)){
92   - return false;
93   - }
  67 + int ret = picConverter.init(m_context, m_dec_name);
  68 + if(ret != ACL_ERROR_NONE){
  69 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  70 + break;
  71 + }
94 72  
95   - ret = picConverter.init(m_context);
96   - if(!ret){
97   - picConverter.release();
98   - }
  73 + // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死
  74 + for (size_t i = 0; i < 20; i++){
  75 + void *vdecInputbuf = nullptr;
  76 + ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  77 + if(ret != ACL_ERROR_NONE){
  78 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  79 + // 析构函数中有对channel 的补救性释放,所以这里可以直接return
  80 + return false;;
  81 + }
  82 + m_vec_vdec.push_back(vdecInputbuf);
  83 + }
99 84  
100   - m_vdec_out_size = cfg.width * cfg.height * 3 / 2;
101   - m_dec_name = cfg.dec_name;
  85 + if(!m_vdecQueue.init(m_vec_vdec)){
  86 + break;
  87 + }
102 88  
103   - cout << "init vdpp success!" << endl;
104   - return true;
  89 + m_vdec_out_size = cfg.width * cfg.height * 3 / 2;
  90 +
  91 + LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
  92 + return true;
  93 +
  94 + } while (0);
  95 +
  96 + LOG_INFO("[{}]- init vdpp failed!", m_dec_name);
  97 + // 初始化失败,释放channel
  98 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  99 + return false;
105 100 }
106 101  
107 102 bool DvppDec::start(){
... ... @@ -139,22 +134,18 @@ void DvppDec::doProcessReport(){
139 134 }
140 135 }
141 136  
142   -static int count_frame = 0;
143   -static long lastts = 0;
144 137 static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
145 138 {
146   - cout << "VdecCallback: " << UtilTools::get_cur_time_ms() - lastts << endl;
147   - lastts = UtilTools::get_cur_time_ms();
148   -
149 139 Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
150   - DvppDec* self = userData->self;
151   - if(self != nullptr){
  140 + if(nullptr != userData){
  141 + DvppDec* self = userData->self;
  142 + if(self != nullptr){
152 143  
153   - self->doVdppVdecCallBack(input, output);
154   - }
155   -
156   - delete userData;
157   - userData = nullptr;
  144 + self->doVdppVdecCallBack(input, output);
  145 + }
  146 + delete userData;
  147 + userData = nullptr;
  148 + }
158 149 }
159 150  
160 151 void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){
... ... @@ -166,43 +157,38 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu
166 157 uint32_t outputSize = acldvppGetPicDescSize(output);
167 158 uint32_t width = acldvppGetPicDescWidth(output);
168 159 uint32_t height = acldvppGetPicDescHeight(output);
169   -
170   - cout << "width = " << width << " height = " << height << " data_size:" << outputSize << endl;
171 160  
172   - if (!m_bPause)
173   - {
174   - DvppRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
175   - post_decoded_cbk(m_postDecArg, rgbMem);
  161 +
  162 + DvppRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
  163 + if(rgbMem != nullptr){
176 164 #ifdef TEST_DECODER
177   - if(rgbMem != nullptr){
178   - // D2H
179   - if(vdecHostAddr == nullptr){
180   - CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");
181   - }
182   - uint32_t data_size = rgbMem->getSize();
183   - CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
184   -
185   - // 保存vdec结果
186   - if(count_frame > 45 && count_frame < 50)
187   - {
188   - string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;
189   - FILE *outputFile = fopen(file_name.c_str(), "a");
190   - if(outputFile){
191   - fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
192   - fclose(outputFile);
193   - }
194   - }
195   - else if(count_frame > 50 && vdecHostAddr != nullptr){
196   - CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
197   - vdecHostAddr = nullptr;
  165 + // D2H
  166 + if(vdecHostAddr == nullptr){
  167 + CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");
  168 + }
  169 + uint32_t data_size = rgbMem->getSize();
  170 + CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
  171 +
  172 + // 保存vdec结果
  173 + if(count_frame > 45 && count_frame < 50)
  174 + {
  175 + string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;
  176 + FILE *outputFile = fopen(file_name.c_str(), "a");
  177 + if(outputFile){
  178 + fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
  179 + fclose(outputFile);
198 180 }
199   - count_frame++;
200   - }
  181 + }
  182 + else if(count_frame > 50 && vdecHostAddr != nullptr){
  183 + CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
  184 + vdecHostAddr = nullptr;
  185 + }
  186 + count_frame++;
201 187 #endif
202   -
203   - }else{
204   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
205   - }
  188 + post_decoded_cbk(m_postDecArg, rgbMem);
  189 + }else{
  190 + LOG_ERROR("[{}]- convert2bgr failed !", m_dec_name);
  191 + }
206 192  
207 193 acldvppFree((uint8_t*)outputDataDev);
208 194 outputDataDev = nullptr;
... ... @@ -211,8 +197,6 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu
211 197  
212 198 CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
213 199 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
214   -
215   - cout << "callback exit." << endl;
216 200 }
217 201  
218 202 void DvppDec::close(){
... ... @@ -227,21 +211,21 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
227 211 // create stream desc
228 212 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
229 213 if (streamInputDesc == nullptr) {
230   - cout << "fail to create input stream desc" << endl;
  214 + LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
231 215 return false;
232 216 }
233 217 aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
234 218 if (ret != ACL_SUCCESS) {
235   - cout << "fail to set eos for stream desc, errorCode = " << static_cast<int32_t>(ret) << endl;
  219 + LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
236 220 (void)acldvppDestroyStreamDesc(streamInputDesc);
237 221 return false;
238 222 }
239 223  
240 224 // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
241   - cout << "send eos" << endl;
  225 + LOG_INFO("[{}]- send eos", m_dec_name);
242 226 ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
243 227 if (ret != ACL_SUCCESS) {
244   - cout << "fail to send eos frame, ret=" << ret << endl;
  228 + LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
245 229 (void)acldvppDestroyStreamDesc(streamInputDesc);
246 230 return false;
247 231 }
... ... @@ -251,7 +235,6 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
251 235 }
252 236  
253 237 void DvppDec::releaseResource(){
254   -
255 238 for(int i = 0; i < m_vec_vdec.size(); i++){
256 239 if(m_vec_vdec[i] != nullptr){
257 240 acldvppFree(m_vec_vdec[i]);
... ... @@ -277,14 +260,14 @@ void DvppDec::decode_thread(){
277 260 pthread_t report_thread;
278 261 ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
279 262 if(ret != 0){
280   - cout << "pthread_create failed" << endl;
  263 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
281 264 return;
282 265 }
283 266  
284 267 // 创建aclvdecChannelDesc类型的数据
285 268 aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
286 269 if (vdecChannelDesc == nullptr) {
287   - cout << "aclvdecCreateChannelDesc failed";
  270 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
288 271 return;
289 272 }
290 273 do{
... ... @@ -301,6 +284,10 @@ void DvppDec::decode_thread(){
301 284 bool bBreak = false;
302 285 while (m_bRunning)
303 286 {
  287 + if (m_bPause){
  288 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  289 + continue;
  290 + }
304 291 int ret = sentFrame(vdecChannelDesc, frame_count);
305 292 if(ret == 2){
306 293 break;
... ... @@ -341,7 +328,8 @@ void DvppDec::decode_thread(){
341 328 m_bExitReportThd = true;
342 329 CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");
343 330  
344   - cout << "decode thread exit." << endl;
  331 + releaseResource();
  332 + LOG_INFO("[{}]- decode thread exit.", m_dec_name);
345 333 }
346 334  
347 335 int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
... ... @@ -349,41 +337,41 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
349 337 AVPacket * pkt = m_pktQueueptr->getHead();
350 338 if(pkt == nullptr){
351 339 std::this_thread::sleep_for(std::chrono::milliseconds(10));
352   - // cout << "getTail failed" << endl;
353   - // continue;
354 340 return 1;
355 341 }
356 342 // 解码
357 343 void *vdecInputbuf = m_vdecQueue.getTail();
358 344 if(vdecInputbuf == nullptr){
359 345 std::this_thread::sleep_for(std::chrono::milliseconds(3));
360   - // cout << "getTail failed" << endl;
361   - // continue;
362 346 return 1;
363 347 }
364 348  
365 349 int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
366 350 if(ACL_ERROR_NONE != ret){
367   - cout << "aclrtMemcpy failed" << endl;
368   - // break;
  351 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
369 352 return 2;
370 353 }
371 354  
372 355 void *vdecOutputBuf = nullptr;
373 356 ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
374 357 if(ret != ACL_ERROR_NONE){
375   - cout << "acldvppMalloc failed" << endl;
376   - // break;
  358 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
377 359 return 2;
378 360 }
379 361  
380 362 acldvppStreamDesc *input_stream_desc = nullptr;
381 363 acldvppPicDesc *output_pic_desc = nullptr;
382 364 do{
383   - input_stream_desc = acldvppCreateStreamDesc();
384   - if (input_stream_desc == nullptr) { cout << "acldvppCreateStreamDesc error" << endl; }
  365 + input_stream_desc = acldvppCreateStreamDesc();
  366 + if (input_stream_desc == nullptr) {
  367 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  368 + break;
  369 + }
385 370 output_pic_desc = acldvppCreatePicDesc();
386   - if (output_pic_desc == nullptr) { cout<< "acldvppCreatePicDesc error" << endl; }
  371 + if (output_pic_desc == nullptr) {
  372 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  373 + break;
  374 + }
387 375 CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
388 376 CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
389 377 CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
... ... @@ -395,12 +383,13 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
395 383 // user_data->startTime = startTime;
396 384 user_data->sendTime = UtilTools::get_cur_time_ms();
397 385 user_data->self = this;
398   -
399 386 ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  387 + av_packet_unref(pkt);
  388 + m_pktQueueptr->addHead();
400 389 if(ret != ACL_ERROR_NONE){
401   - cout << "aclvdecSendFrame failed" << endl;
402   - m_pktQueueptr->addHead();
403   - av_packet_unref(pkt);
  390 + delete user_data;
  391 + user_data = nullptr;
  392 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
404 393 break;
405 394 }
406 395  
... ... @@ -409,6 +398,7 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
409 398 return 0;
410 399 }while (0);
411 400  
  401 + // 报错情形
412 402 if(input_stream_desc){
413 403 CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
414 404 }
... ...
src/dvpp/DvppDec.h
... ... @@ -14,7 +14,6 @@ using namespace std;
14 14  
15 15 #define TEST_DECODER
16 16  
17   -
18 17 struct DvppDecConfig{
19 18 string dec_name;
20 19 POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
... ... @@ -77,4 +76,10 @@ private:
77 76 VpcPicConverter picConverter;
78 77  
79 78 int m_vdec_out_size {-1};
  79 +
  80 +#ifdef TEST_DECODER
  81 + void *vdecHostAddr = nullptr;
  82 + int count_frame = 0;
  83 +#endif
  84 +
80 85 };
81 86 \ No newline at end of file
... ...
src/dvpp/DvppDecoder.cpp
1 1 #include "DvppDecoder.h"
2   -#include "DvppSourceManager.h"
3 2  
4   -#define CHECK_AND_RETURN(ret, message) \
5   - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message; return ret;}
6   -#define CHECK_NOT_RETURN(ret, message) \
7   - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message;}
8   -#define CHECK_AND_RETURN_NOVALUE(ret, message) \
9   - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message; return;}
10   -
11   -
12   -
13   -struct Vdec_CallBack_UserData {
14   - uint64_t frameId;
15   - long startTime;
16   - long sendTime;
17   - // void* vdecOutputBuf;
18   - DvppDecoder* self;
19   - shared_ptr<MemNode> inBufNode;
20   - Vdec_CallBack_UserData() {
21   - frameId = 0;
  3 +void receiver_finish_cbk(const void* userPtr){
  4 + if(userPtr != nullptr){
  5 + DvppDecoder* self = (DvppDecoder*)userPtr;
  6 + self->taskFinishing();
22 7 }
23   -};
24   -
25   -
26   -const int g_pkt_que_size = 10;
27   -const int g_pkt_size = 1024 * 1024;
28   -
29   -#ifdef TEST_DECODER
30   -void *vdecHostAddr;
31   -#endif
32   -
33   -static long GetCurTimeUs(){
34   - chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
35   - = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
36   -
37   - return tpMicro.time_since_epoch().count();
38 8 }
39 9  
40   -DvppDecoder::DvppDecoder()
41   -{
42   - // 初始化解码对象
43   - fmt_ctx = nullptr;
44   - m_bRunning = false;
45   -
46   - stream = nullptr;
47   - stream_index = -1;
48   - pix_fmt = AV_PIX_FMT_NONE;
49   - m_dec_name = "";
50   -
51   - m_bPause = false;
52   - m_bReal = true;
53   -
54   - m_decode_thread = 0;
55   - m_post_decode_thread = 0;
56   -
57   - m_bFinished = false;
58   - m_dec_keyframe = false;
59   - m_fps = 0.0;
  10 +DvppDecoder::DvppDecoder(){
  11 + m_pktQueueptr = new CircularQueue<AVPacket *>();
60 12 }
61 13  
62   -DvppDecoder::~DvppDecoder()
63   -{
64   - m_dec_keyframe = false;
65   - releaseResource();
  14 +DvppDecoder::~DvppDecoder(){
  15 + delete m_pktQueueptr;
  16 + m_pktQueueptr = nullptr;
66 17 }
67 18  
68   -bool DvppDecoder::init_FFmpeg(const char* uri, bool force_tcp){
69   -
70   -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
71   - av_register_all();
72   -#endif
73   -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
74   - avcodec_register_all();
75   -#endif
76   -
77   - avformat_network_init();
78   -
79   - // 打开输入视频文件
80   - AVDictionary *options = nullptr;
81   - av_dict_set( &options, "bufsize", "655360", 0 );
82   - av_dict_set( &options, "rtsp_transport", force_tcp ? "tcp" : "udp", 0 );
83   - // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s
84   - av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
85   -
86   - fmt_ctx = avformat_alloc_context();
87   - const char* input_file = uri;
88   - if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
89   - cout << "Cannot open input file:" << input_file << endl;
90   - return false;
91   - }
92   - av_dump_format(fmt_ctx, 0, input_file, 0);
93   -
94   - // 查找流信息
95   - if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
96   - cout << "Cannot find input stream information" << endl;
97   - return false;
98   - }
99   -
100   - // 查找视频流信息
101   - AVCodec *decoder = nullptr;
102   - stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
103   - if (stream_index < 0) {
104   - cout << "Cannot find a video stream in the input file" << endl;
105   - return false;
106   - }
107   - AVCodec *vcodec = avcodec_find_decoder(decoder->id);
108   -
109   - AVCodecContext *avctx = avcodec_alloc_context3(vcodec);
110   - if(avctx == nullptr){
111   - cout << "alloc AVCodecContext failed." << endl;
112   - return false;
113   - }
114   -
115   - do{
116   - // 得到视频流对象
117   - AVStream* stream = fmt_ctx->streams[stream_index];
118   - AVCodecParameters *codecpar = stream->codecpar;
119   - if (avcodec_parameters_to_context(avctx, codecpar) < 0)
120   - break;
121   -
122   - const AVBitStreamFilter * filter = nullptr;
123   - if(codecpar->codec_id == AV_CODEC_ID_H264){
124   - // 66:Baseline,77:Main,>=100:High
125   - if(codecpar->profile == 77){
126   - enType = H264_MAIN_LEVEL;
127   - }else if(codecpar->profile < 77){
128   - enType = H264_BASELINE_LEVEL;
129   - }else{
130   - enType = H264_HIGH_LEVEL;
131   - }
132   - filter = av_bsf_get_by_name("h264_mp4toannexb");
133   - }else if(codecpar->codec_id == AV_CODEC_ID_HEVC){
134   - // h265只有main
135   - enType = H265_MAIN_LEVEL;
136   - filter = av_bsf_get_by_name("hevc_mp4toannexb");
137   - }else {
138   - cout << "codec_id is not supported!" << endl;
139   - break;
140   - }
141   -
142   - int ret = av_bsf_alloc(filter, &h264bsfc);
143   - if (ret < 0){
144   - break;
145   - }
146   -
147   - avcodec_parameters_copy(h264bsfc->par_in, codecpar);
148   - av_bsf_init(h264bsfc);
149   -
150   - frame_width = codecpar->width;
151   - frame_height = codecpar->height;
152   - pix_fmt = (AVPixelFormat)codecpar->format;
153   - m_fps = av_q2d(stream ->avg_frame_rate);
154   -
155   - m_vdec_out_size = frame_width * frame_height * 3 /2;
156   -
157   - cout << "frame_width = " << frame_width << " frame_height = " << frame_height << " fps = " << m_fps << " m_vdec_out_size:" << m_vdec_out_size << endl;
158   -
159   - cout << "init ffmpeg success!" << endl;
160   -
161   - return true;
162   - }while(0);
163   -
164   - avcodec_free_context(&avctx);
165   -
166   - return false;
167   -}
168   -
169   -static void *ReportThd(void *arg)
170   -{
171   - DvppDecoder *self = (DvppDecoder *)arg;
172   - if(nullptr != self){
173   - self->doProcessReport();
174   - }
175   - return (void *)0;
176   -}
177   -
178   -void DvppDecoder::doProcessReport(){
179   - // aclrtContext thdContext = nullptr;
180   - // CHECK_AND_RETURN_NOVALUE(aclrtCreateContext(&thdContext, m_dvpp_deviceId), "aclrtCreateContext failed");
181   -
182   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
183   - // 阻塞等待vdec线程开始
184   -
185   - int ret;
186   - while (m_bRunning) {
187   - ret = aclrtProcessReport(1000);
188   - if (ret != ACL_ERROR_NONE) {
189   - cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", aclrtProcessReport failed, ret: " << ret << endl;
190   - }
191   - }
192   -
193   - // CHECK_AND_RETURN_NOVALUE(aclrtDestroyContext(thdContext), "aclrtDestroyContext failed");
194   -}
195   -
196   -int count_frame = 0;
197   -long lastts = 0;
198   -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
199   -{
200   - cout << "VdecCallback: " << GetCurTimeUs() - lastts << endl;
201   - lastts = GetCurTimeUs();
202   -
203   - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
204   - DvppDecoder* self = userData->self;
205   - if(self != nullptr){
206   -
207   - self->doVdppVdecCallBack(input, output, self);
208   - }
209   -
210   - delete userData;
211   - userData = nullptr;
212   -}
213   -
214   -void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, DvppDecoder *self){
215   -
216   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
217   -
218   - void *inputDataDev = acldvppGetStreamDescData(input);
219   - void *outputDataDev = acldvppGetPicDescData(output);
220   - uint32_t outputSize = acldvppGetPicDescSize(output);
221   - uint32_t width = acldvppGetPicDescWidth(output);
222   - uint32_t height = acldvppGetPicDescHeight(output);
223   -
224   - cout << "width = " << width << " height = " << height << " data_size:" << outputSize << endl;
225   -
226   - if (!m_bPause)
227   - {
228   - DeviceRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
229   -#ifdef TEST_DECODER
230   - if(rgbMem != nullptr){
231   - // D2H
232   - uint32_t data_size = rgbMem->getSize();
233   - CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
234   -
235   - // 保存vdec结果
236   - if(count_frame > 45 && count_frame < 50)
237   - {
238   - string file_name = "./yuv_pic/vdec_out"+ getName() +".rgb" ;
239   - FILE *outputFile = fopen(file_name.c_str(), "a");
240   - if(outputFile){
241   - fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
242   - fclose(outputFile);
243   - }
244   - }
245   - count_frame++;
246   - }
247   -#endif
248   -
249   - }else{
250   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
251   - }
252   -
253   - cout << "callback acldvppFree." << endl;
254   -
255   - acldvppFree((uint8_t*)outputDataDev);
256   - outputDataDev = nullptr;
257   -
258   - m_vdecQueue.addHead();
259   -
260   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
261   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
262   -
263   - cout << "callback exit." << endl;
264   -}
265   -
266   -bool DvppDecoder::init_vdpp(int devId){
267   - cout << "Init device....\n";
268   - // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
269   - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
270   - m_context = pSrcMgr->getContext(m_dvpp_deviceId);
271   - m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
272   - if(m_dvpp_channel < 0){
273   - cout << "该设备channel已经用完了" << endl;
274   - return false;
275   - }
276   -
277   - cout << "devProgram start, device: " << m_dvpp_deviceId << endl;
278   - int ret = aclrtSetCurrentContext(m_context);
279   - if (ret != ACL_ERROR_NONE) {
280   - cout << "aclrtSetCurrentContext failed" << endl;
281   - return false;
282   - }
283   -
284   - // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死
285   - for (size_t i = 0; i < 20; i++){
286   - void *vdecInputbuf = nullptr;
287   - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
288   - if(ret != ACL_ERROR_NONE){
289   - cout << "acldvppMalloc failed" << endl;
290   - return false;;
291   - }
292   - m_vec_vdec.push_back(vdecInputbuf);
293   - }
294   -
295   - if(!m_vdecQueue.init(m_vec_vdec)){
296   - return false;
297   - }
298   -
299   -#ifdef TEST_DECODER
300   - CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, frame_width * frame_height * 3), "aclrtMallocHost failed");
301   -#endif
302   -
303   - cout << "init vdpp success!" << endl;
304   - return true;
305   -}
306   -
307   -bool DvppDecoder::init(FFDecConfig& cfg){
308   - m_cfg = cfg;
309   -
310   - fstream infile(cfg.uri);
311   - if (infile.is_open()){
312   - m_bReal = false;
313   - infile.close();
314   - }else {
315   - m_bReal = true;
316   - }
317   -
318   - post_decoded_cbk = cfg.post_decoded_cbk;
319   - decode_finished_cbk = cfg.decode_finished_cbk;
320   -
321   - bool ret = init_FFmpeg(cfg.uri.c_str(), cfg.force_tcp);
322   - if(!ret){
323   - return false;
324   - }
325   -
326   - m_dvpp_deviceId = atoi(cfg.gpuid.c_str());
327   - ret = init_vdpp(m_dvpp_deviceId);
328   - if (!ret)
329   - {
330   - releaseFFmpeg();
331   - }
  19 +bool DvppDecoder::init(FFDecConfig cfg){
332 20  
333   - ret = picConverter.init(m_context);
334   - if(!ret){
335   - picConverter.release();
336   - }
337   -
338   - return ret;
339   -}
340   -
341   -bool DvppDecoder::start(){
342   - m_bRunning = true;
343   -
344   - pthread_create(&m_decode_thread,0,
345   - [](void* arg)
346   - {
347   - DvppDecoder* a=(DvppDecoder*)arg;
348   - a->decode_thread();
349   - return (void*)0;
350   - }
351   - ,this);
352   -
353   - return true;
354   -}
355   -
356   -void DvppDecoder::close(){
357   - m_bRunning=false;
358   -
359   - if(m_decode_thread != 0){
360   - pthread_join(m_decode_thread,0);
361   - }
362   -
363   -#ifdef TEST_DECODER
364   - if(vdecHostAddr != nullptr){
365   - CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
366   - }
367   -#endif
368   -}
369   -
370   -bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
371   - // create stream desc
372   - acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
373   - if (streamInputDesc == nullptr) {
374   - cout << "fail to create input stream desc" << endl;
  21 + m_dec_name = cfg.dec_name;
  22 +
  23 + ReceiverConfig receiver_config;
  24 + receiver_config.uri = cfg.uri.c_str();
  25 + receiver_config.dec_name = cfg.dec_name;
  26 + receiver_config.force_tcp = cfg.force_tcp;
  27 + receiver_config.pktQueueptr = m_pktQueueptr;
  28 + receiver_config.receiver_finished_cbk = receiver_finish_cbk;
  29 + AVCodecContext* avctx = m_receiver.init_FFmpeg(receiver_config);
  30 + if(avctx == nullptr){
375 31 return false;
376 32 }
377   - aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
378   - if (ret != ACL_SUCCESS) {
379   - cout << "fail to set eos for stream desc, errorCode = " << static_cast<int32_t>(ret) << endl;
380   - (void)acldvppDestroyStreamDesc(streamInputDesc);
  33 + m_receiver.setFinishCbkArg(this);
  34 +
  35 + DvppDecConfig dec_cfg;
  36 + if(avctx->codec_id == AV_CODEC_ID_H264){
  37 + dec_cfg.codec_id = 0;
  38 + }else if(avctx->codec_id == AV_CODEC_ID_HEVC){
  39 + dec_cfg.codec_id = 1;
  40 + }else {
381 41 return false;
382 42 }
383   -
384   - // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
385   - ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
386   - if (ret != ACL_SUCCESS) {
387   - cout << "fail to send eos frame, ret=" << ret << endl;
388   - (void)acldvppDestroyStreamDesc(streamInputDesc);
  43 + dec_cfg.dec_name = cfg.dec_name;
  44 + dec_cfg.post_decoded_cbk = cfg.post_decoded_cbk;
  45 + dec_cfg.dev_id = cfg.gpuid;
  46 + dec_cfg.force_tcp = cfg.force_tcp;
  47 + dec_cfg.skip_frame = cfg.skip_frame;
  48 + dec_cfg.profile = avctx->profile;
  49 + dec_cfg.pktQueueptr = m_pktQueueptr;
  50 + dec_cfg.width = avctx->width;
  51 + dec_cfg.height = avctx->height;
  52 + bool bRet = m_decoder.init_vdpp(dec_cfg);
  53 + if(!bRet){
389 54 return false;
390 55 }
391   - (void)acldvppDestroyStreamDesc(streamInputDesc);
392   -
393   - return true;
394   -}
395 56  
396   -void DvppDecoder::releaseFFmpeg(){
397   - m_dec_keyframe = false;
398   - if(h264bsfc){
399   - av_bsf_free(&h264bsfc);
400   - h264bsfc = nullptr;
401   - }
402   - if (fmt_ctx)
403   - {
404   - avformat_close_input(&fmt_ctx);
405   - fmt_ctx = nullptr;
406   - }
407   -}
  57 + m_cfg = cfg;
408 58  
409   -void DvppDecoder::releaseResource(){
410   - releaseFFmpeg();
  59 + decode_finished_cbk = cfg.decode_finished_cbk;
411 60  
412   - for(int i = 0; i < m_vec_vdec.size(); i++){
413   - if(m_vec_vdec[i] != nullptr){
414   - acldvppFree((uint8_t*)m_vec_vdec[i]);
415   - m_vec_vdec[i] = nullptr;
416   - }
417   - }
418   - m_vec_vdec.clear();
  61 + m_bFinished = false;
419 62  
420   - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
421   - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  63 + return true;
422 64 }
423 65  
424   -void DvppDecoder::decode_thread(){
425   -
426   - int frame_count = 0;
427   - long startTime = GetCurTimeUs();
428   -
429   - int ret = -1;
430   -
431   - // dvpp解码参数
432   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
433   -
434   - pthread_t report_thread;
435   - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
436   - if(ret != 0){
437   - cout << "pthread_create failed" << endl;
438   - return;
439   - }
440   -
441   - // 创建aclvdecChannelDesc类型的数据
442   - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
443   - if (vdecChannelDesc == nullptr) {
444   - cout << "aclvdecCreateChannelDesc failed";
445   - return;
446   - }
447   - // 创建 channel dec结构体
448   - // 通道ID在dvpp层面为0~31
449   - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
450   - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
451   - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
452   - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");
453   - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
454   - CHECK_AND_RETURN_NOVALUE(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
455   -
456   - AVPacket* pkt ;
457   - pkt = av_packet_alloc();
458   - av_init_packet( pkt );
459   -
460   - acldvppStreamDesc *input_stream_desc = nullptr;
461   - acldvppPicDesc *output_pic_desc = nullptr;
462   -
463   - void *vdecInputbuf = nullptr;
464   - void *vdecOutputBuf = nullptr;
465   - while (m_bRunning)
466   - {
467   - if (!m_bReal)
468   - {
469   - if (m_bPause)
470   - {
471   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
472   - continue;
473   - }
474   - }
475   -
476   - int result = av_read_frame(fmt_ctx, pkt);
477   - if (result == AVERROR_EOF || result < 0)
478   - {
479   - cout << "Failed to read frame!" << endl;
480   - break;
481   - }
482   -
483   - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
484   - av_packet_unref(pkt);
485   - continue;
486   - }
487   -
488   - if (stream_index == pkt->stream_index){
489   -
490   - ret = av_bsf_send_packet(h264bsfc, pkt);
491   - if(ret < 0) {
492   - cout << "av_bsf_send_packet error" << endl;
493   - }
494   -
495   - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
496   - // 解码
497   -
498   - if(pkt->size > g_pkt_size){
499   - cout << "pkt size 大于 预设" << endl;
500   - break;
501   - }
502   -
503   - if(!m_bRunning){
504   - break;
505   - }
506   -
507   - vdecInputbuf = m_vdecQueue.getTail();
508   - if(vdecInputbuf == nullptr){
509   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
510   - // cout << "getTail failed" << endl;
511   - continue;
512   - }
513   -
514   - ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
515   - if(ACL_ERROR_NONE != ret){
516   - cout << "aclrtMemcpy failed" << endl;
517   - goto end_flag;
518   - }
519   -
520   - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
521   - if(ret != ACL_ERROR_NONE){
522   - cout << "acldvppMalloc failed" << endl;
523   - goto end_flag;
524   - }
525   -
526   - /************ 解码*************/
527   - input_stream_desc = acldvppCreateStreamDesc();
528   - if (input_stream_desc == nullptr) { cout << "acldvppCreateStreamDesc error" << endl; }
529   - output_pic_desc = acldvppCreatePicDesc();
530   - if (output_pic_desc == nullptr) { cout<< "acldvppCreatePicDesc error" << endl; }
531   - CHECK_NOT_RETURN(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
532   - CHECK_NOT_RETURN(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
533   - CHECK_NOT_RETURN(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
534   - CHECK_NOT_RETURN(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
535   -
536   - Vdec_CallBack_UserData *user_data = NULL;
537   - user_data = new Vdec_CallBack_UserData;
538   - user_data->frameId = frame_count;
539   - user_data->startTime = startTime;
540   - user_data->sendTime = GetCurTimeUs();
541   - user_data->self = this;
542   - // user_data->inBufNode = bufNode;
543   - cout << "send frame" << endl;
544   - CHECK_NOT_RETURN(aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data)),
545   - "aclvdecSendFrame failed");
546   -
547   - frame_count++;
548   -
549   - m_vdecQueue.addTail();
550   -
551   - vdecInputbuf = nullptr;
552   - vdecOutputBuf = nullptr;
553   - }
554   - /****************************/
555   - }
556   - av_packet_unref(pkt);
557   - }
558   -
559   -end_flag:
560   -
561   - av_packet_free(&pkt);
562   -
563   - sendVdecEos(vdecChannelDesc);
564   -
565   - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
566   - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
567   -
568   - // report_thread 需后于destroy退出
569   - m_bRunning = false;
570   - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");
571   -
572   - if(m_vdecQueue.length() > 0){
573   - cout << m_vdecQueue.length() << endl;
574   - }
575   -
576   - if(vdecOutputBuf != nullptr){
577   - acldvppFree((uint8_t*)vdecOutputBuf);
578   - vdecOutputBuf = nullptr;
579   - }
  66 +bool DvppDecoder::isSurport(FFDecConfig& cfg){
  67 + return true;
  68 +}
580 69  
581   - cout << "read thread exit." << endl;
  70 +bool DvppDecoder::start(){
  71 + m_receiver.start();
  72 + m_decoder.start();
  73 + return true;
582 74 }
583 75  
584   -float DvppDecoder::fps(){
585   - return m_fps;
  76 +void DvppDecoder::close(){
  77 + m_receiver.close();
586 78 }
587 79  
588   -bool DvppDecoder::isSurport(FFDecConfig& cfg){
589   - bool bRet = init(cfg);
590   - return bRet;
  80 +void DvppDecoder::setPostDecArg(const void* postDecArg){
  81 + m_decoder.setPostDecArg(postDecArg);
591 82 }
592 83  
593   -bool DvppDecoder::getResolution( int &width, int &height ){
594   - width = frame_width;
595   - height = frame_height;
596   - return true;
  84 +void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
  85 + m_finishedDecArg = finishedDecArg;
597 86 }
598 87  
599 88 void DvppDecoder::pause(){
600   - m_bPause = true;
  89 + m_receiver.pause();
601 90 }
602 91  
603 92 void DvppDecoder::resume(){
604   - m_bPause = false;
  93 + m_receiver.resume();
605 94 }
606 95  
607   -void DvppDecoder::setDecKeyframe(bool bKeyframe)
608   -{
609   - m_dec_keyframe = bKeyframe;
  96 +void DvppDecoder::setDecKeyframe(bool bKeyframe){
  97 + m_receiver.setDecKeyframe(bKeyframe);
610 98 }
611 99  
612 100 bool DvppDecoder::isRunning(){
613   - return m_bRunning;
  101 + return m_receiver.isRunning();
614 102 }
615 103  
616 104 bool DvppDecoder::isFinished(){
617   - return m_bFinished;
  105 + return m_bFinished;
618 106 }
619 107  
620 108 bool DvppDecoder::isPausing(){
621   - return m_bPause;
  109 + return m_receiver.isPausing();
622 110 }
623 111  
624   -int DvppDecoder::getCachedQueueLength(){
625   - // TODO
626   - return 0;
  112 +bool DvppDecoder::getResolution(int &width, int &height){
  113 + return m_receiver.getResolution(width, height);
  114 +}
  115 +
  116 +float DvppDecoder::fps(){
  117 + return m_receiver.fps();
627 118 }
628 119  
629 120 FFImgInfo* DvppDecoder::snapshot(){
... ... @@ -631,10 +122,16 @@ FFImgInfo* DvppDecoder::snapshot(){
631 122 return nullptr;
632 123 }
633 124  
634   -void DvppDecoder::setPostDecArg(const void* postDecArg){
635   - m_postDecArg = postDecArg;
  125 +int DvppDecoder::getCachedQueueLength(){
  126 + return 0;
636 127 }
637 128  
638   -void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
639   - m_finishedDecArg = finishedDecArg;
  129 +void DvppDecoder::taskFinishing(){
  130 + // receiver 中读取线程结束时执行
  131 + m_decoder.close();
  132 + decode_finished_cbk(m_finishedDecArg);
  133 +
  134 + m_bFinished = true;
  135 +
  136 + LOG_INFO("[{}]- task finished.", m_dec_name);
640 137 }
641 138 \ No newline at end of file
... ...
src/dvpp/DvppDecoder.h
1 1 #include<string>
2   -#include <pthread.h>
3 2  
4   -#include "dvpp_headers.h"
5 3 #include "depend_headers.h"
6   -#include "user_mem.h"
7 4 #include "CircularQueue.hpp"
8   -#include "VpcPicConverter.h"
9   -
10   -#include <queue>
  5 +#include "FFReceiver.h"
  6 +#include "DvppDec.h"
11 7  
12 8 using namespace std;
13 9  
14   -#define TEST_DECODER
15   -
16   -
17 10 class DvppDecoder{
18 11 public:
19 12 DvppDecoder();
20 13 ~DvppDecoder();
21   - bool init(FFDecConfig& cfg);
  14 + bool init(FFDecConfig cfg);
22 15 void close();
23 16 bool start();
24 17 void pause();
... ... @@ -33,12 +26,8 @@ public:
33 26  
34 27 bool isSurport(FFDecConfig& cfg);
35 28  
36   - int getCachedQueueLength();
37   -
38 29 float fps();
39 30  
40   - DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP; }
41   -
42 31 void setName(string nm){
43 32 m_dec_name = nm;
44 33 }
... ... @@ -52,60 +41,22 @@ public:
52 41 void setPostDecArg(const void* postDecArg);
53 42 void setFinishedDecArg(const void* finishedDecArg);
54 43  
55   -public:
56   - void doProcessReport();
57   - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, DvppDecoder *self);
58   -
59   -private:
60   - void decode_thread();
61   - void post_decode_thread();
62   - void releaseFFmpeg();
63   - void releaseResource();
64   - bool init_FFmpeg(const char* uri, bool force_tcp);
65   - bool init_vdpp(int _deviceId);
  44 + int getCachedQueueLength();
66 45  
67   - bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
  46 +public:
  47 + void taskFinishing();
68 48  
69 49 private:
70   - AVStream* stream;
71   - int stream_index;
72   - AVFormatContext *fmt_ctx;
73   - AVPixelFormat pix_fmt;
74   - uint32_t m_vdec_out_size{0};
75   - int frame_width{0};
76   - int frame_height{0};
77   -
78   - int m_dvpp_deviceId {-1};
79   - int m_dvpp_channel {-1};
80   -
81   - pthread_t m_decode_thread;
82   - pthread_t m_post_decode_thread;
83   -
84   - bool m_bRunning;
85   - bool m_bFinished;
86   -
87   - bool m_bPause;
88   -
89   - bool m_bReal; // 是否实时流
90   -
91   - float m_fps;
92   -
93 50 FFDecConfig m_cfg;
94 51 string m_dec_name;
95   - bool m_dec_keyframe;
96   -
97   - AVBSFContext * h264bsfc{nullptr};
98 52  
99   - aclrtContext m_context;
100   - acldvppStreamFormat enType;
  53 + CircularQueue<AVPacket *> *m_pktQueueptr;
  54 + FFReceiver m_receiver;
  55 + DvppDec m_decoder;
101 56  
102   - vector<void*> m_vec_vdec;
103   - CircularQueue<void *> m_vdecQueue;
104   -
105   - const void * m_postDecArg;
106   - POST_DECODE_CALLBACK post_decoded_cbk;
107 57 const void * m_finishedDecArg;
108 58 DECODE_FINISHED_CALLBACK decode_finished_cbk;
109 59  
110   - VpcPicConverter picConverter;
  60 + bool m_bFinished{false};
  61 +
111 62 };
112 63 \ No newline at end of file
... ...
src/dvpp/DvppDecoder2.h deleted
1   -#include<string>
2   -
3   -#include "depend_headers.h"
4   -#include "CircularQueue.hpp"
5   -#include "FFReceiver.h"
6   -#include "DvppDec.h"
7   -
8   -using namespace std;
9   -
10   -class DvppDecoder2{
11   -public:
12   - DvppDecoder2();
13   - ~DvppDecoder2();
14   - bool init(FFDecConfig cfg);
15   - void close();
16   - bool start();
17   - void pause();
18   - void resume();
19   -
20   - void setDecKeyframe(bool bKeyframe);
21   -
22   - bool isRunning();
23   - bool isFinished();
24   - bool isPausing();
25   - bool getResolution( int &width, int &height );
26   -
27   - bool isSurport(FFDecConfig& cfg);
28   -
29   - float fps();
30   -
31   - void setName(string nm){
32   - m_dec_name = nm;
33   - }
34   -
35   - string getName(){
36   - return m_dec_name;
37   - }
38   -
39   - FFImgInfo* snapshot();
40   -
41   - void setPostDecArg(const void* postDecArg);
42   - void setFinishedDecArg(const void* finishedDecArg);
43   -
44   - int getCachedQueueLength();
45   -
46   -public:
47   - void taskFinishing();
48   -
49   -private:
50   -
51   - FFDecConfig m_cfg;
52   - string m_dec_name;
53   -
54   - CircularQueue<AVPacket *> *m_pktQueueptr;
55   - FFReceiver m_receiver;
56   - DvppDec m_decoder;
57   -
58   - const void * m_finishedDecArg;
59   - DECODE_FINISHED_CALLBACK decode_finished_cbk;
60   -
61   -};
62   -
63   -void receiver_finish_cbk(const void* userPtr){
64   - if(userPtr != nullptr){
65   - DvppDecoder2* self = (DvppDecoder2*)userPtr;
66   - self->taskFinishing();
67   - }
68   -}
69   -
70   -DvppDecoder2::DvppDecoder2(){
71   - m_pktQueueptr = new CircularQueue<AVPacket *>();
72   -}
73   -
74   -DvppDecoder2::~DvppDecoder2(){
75   - delete m_pktQueueptr;
76   - m_pktQueueptr = nullptr;
77   -}
78   -
79   -bool DvppDecoder2::init(FFDecConfig cfg){
80   -
81   - ReceiverConfig receiver_config;
82   - receiver_config.uri = cfg.uri.c_str();
83   - receiver_config.dec_name = cfg.dec_name;
84   - receiver_config.force_tcp = cfg.force_tcp;
85   - receiver_config.pktQueueptr = m_pktQueueptr;
86   - receiver_config.receiver_finished_cbk = receiver_finish_cbk;
87   - AVCodecContext* avctx = m_receiver.init_FFmpeg(receiver_config);
88   - if(avctx == nullptr){
89   - return false;
90   - }
91   - m_receiver.setFinishCbkArg(this);
92   -
93   - DvppDecConfig dec_cfg;
94   - if(avctx->codec_id == AV_CODEC_ID_H264){
95   - dec_cfg.codec_id = 0;
96   - }else if(avctx->codec_id == AV_CODEC_ID_HEVC){
97   - dec_cfg.codec_id = 1;
98   - }else {
99   - return false;
100   - }
101   - dec_cfg.dec_name = cfg.dec_name;
102   - dec_cfg.post_decoded_cbk = cfg.post_decoded_cbk;
103   - dec_cfg.dev_id = cfg.gpuid;
104   - dec_cfg.force_tcp = cfg.force_tcp;
105   - dec_cfg.skip_frame = cfg.skip_frame;
106   - dec_cfg.profile = avctx->profile;
107   - dec_cfg.pktQueueptr = m_pktQueueptr;
108   - dec_cfg.width = avctx->width;
109   - dec_cfg.height = avctx->height;
110   - bool bRet = m_decoder.init_vdpp(dec_cfg);
111   - if(!bRet){
112   - return false;
113   - }
114   -
115   - m_cfg = cfg;
116   -
117   - decode_finished_cbk = cfg.decode_finished_cbk;
118   -
119   - return true;
120   -}
121   -
122   -bool DvppDecoder2::isSurport(FFDecConfig& cfg){
123   - return true;
124   -}
125   -
126   -bool DvppDecoder2::start(){
127   - m_receiver.start();
128   - m_decoder.start();
129   - return true;
130   -}
131   -
132   -void DvppDecoder2::close(){
133   - m_receiver.close();
134   -}
135   -
136   -void DvppDecoder2::setPostDecArg(const void* postDecArg){
137   - m_decoder.setPostDecArg(postDecArg);
138   -}
139   -
140   -void DvppDecoder2::setFinishedDecArg(const void* finishedDecArg){
141   - m_finishedDecArg = finishedDecArg;
142   -}
143   -
144   -void DvppDecoder2::pause(){
145   - m_receiver.pause();
146   -}
147   -
148   -void DvppDecoder2::resume(){
149   - m_receiver.resume();
150   -}
151   -
152   -void DvppDecoder2::setDecKeyframe(bool bKeyframe){
153   - m_receiver.setDecKeyframe(bKeyframe);
154   -}
155   -
156   -bool DvppDecoder2::isRunning(){
157   - return m_receiver.isRunning();
158   -}
159   -
160   -bool DvppDecoder2::isFinished(){
161   - return m_receiver.isFinished();
162   -}
163   -
164   -bool DvppDecoder2::isPausing(){
165   - return m_receiver.isPausing();
166   -}
167   -
168   -bool DvppDecoder2::getResolution(int &width, int &height){
169   - return m_receiver.getResolution(width, height);
170   -}
171   -
172   -float DvppDecoder2::fps(){
173   - return m_receiver.fps();
174   -}
175   -
176   -FFImgInfo* DvppDecoder2::snapshot(){
177   - // TODO
178   - return nullptr;
179   -}
180   -
181   -int DvppDecoder2::getCachedQueueLength(){
182   - return 0;
183   -}
184   -
185   -void DvppDecoder2::taskFinishing(){
186   - // receiver 中读取线程结束时执行
187   - m_decoder.close();
188   - decode_finished_cbk(m_finishedDecArg);
189   -
190   - LOG_INFO("[{}]- task finished.", m_dec_name);
191   -
192   -}
193 0 \ No newline at end of file
src/dvpp/DvppDecoderApi.cpp
1 1 #include "DvppDecoderApi.h"
2   -#include "DvppDecoder2.h"
  2 +#include "DvppDecoder.h"
3 3  
4 4 DvppDecoderApi::DvppDecoderApi(){
5 5 m_pDecoder = nullptr;
... ... @@ -13,7 +13,7 @@ DvppDecoderApi::~DvppDecoderApi(){
13 13 }
14 14  
15 15 bool DvppDecoderApi::init(FFDecConfig& cfg){
16   - m_pDecoder = new DvppDecoder2();
  16 + m_pDecoder = new DvppDecoder();
17 17 if(m_pDecoder != nullptr){
18 18 return m_pDecoder->init(cfg);
19 19 }
... ...
src/dvpp/DvppDecoderApi.h
... ... @@ -6,7 +6,7 @@
6 6  
7 7 using namespace std;
8 8  
9   -class DvppDecoder2;
  9 +class DvppDecoder;
10 10  
11 11 class DvppDecoderApi : public AbstractDecoder{
12 12 public:
... ... @@ -40,5 +40,5 @@ public:
40 40 void setPostDecArg(const void* postDecArg);
41 41 void setFinishedDecArg(const void* finishedDecArg);
42 42 private:
43   - DvppDecoder2* m_pDecoder;
  43 + DvppDecoder* m_pDecoder;
44 44 };
45 45 \ No newline at end of file
... ...
src/dvpp/DvppSourceManager.cpp
... ... @@ -59,5 +59,8 @@ int DvppSourceManager::getChannel(int devId){
59 59  
60 60 void DvppSourceManager::releaseChannel(int devId, int iChannel){
61 61 string channelKey = "channel_" + to_string(devId) + "_" + to_string(iChannel) ;
62   - channelMap.erase(channelKey);
  62 + auto it = channelMap.find(channelKey);
  63 + if(it != channelMap.end()){
  64 + channelMap.erase(channelKey);
  65 + }
63 66 }
64 67 \ No newline at end of file
... ...
src/dvpp/FFReceiver.cpp
... ... @@ -26,6 +26,12 @@ FFReceiver::FFReceiver(/* args */)
26 26 FFReceiver::~FFReceiver()
27 27 {
28 28 releaseFFmpeg();
  29 +
  30 + // 这个只能放在析构函数中,因为会影响到解码类中的m_pktQueueptr队列
  31 + // 所以应当确保在所有工作线程都退出后才释放
  32 + for(int i = 0; i < m_vec_pkt.size(); i++){
  33 + av_packet_free(&m_vec_pkt[i]);
  34 + }
29 35 }
30 36  
31 37 AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){
... ... @@ -131,8 +137,6 @@ AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){
131 137  
132 138 LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name);
133 139  
134   - releaseFFmpeg();
135   -
136 140 return nullptr;
137 141 }
138 142  
... ... @@ -150,10 +154,6 @@ void FFReceiver::releaseFFmpeg(){
150 154 avcodec_free_context(&avctx);
151 155 avctx = nullptr;
152 156 }
153   -
154   - for(int i = 0; i < m_vec_pkt.size(); i++){
155   - av_packet_free(&m_vec_pkt[i]);
156   - }
157 157 }
158 158  
159 159 void FFReceiver::read_thread(){
... ... @@ -214,6 +214,7 @@ void FFReceiver::read_thread(){
214 214 }
215 215  
216 216 LOG_INFO("[{}]- read thread exit.", m_dec_name);
  217 + m_bFinished = true;
217 218  
218 219 receiver_finished_cbk(m_finishedReceiveArg);
219 220 }
... ...
src/dvpp/VpcPicConverter.cpp
... ... @@ -3,35 +3,40 @@
3 3  
4 4 #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
5 5  
6   -bool VpcPicConverter::init(aclrtContext context){
  6 +VpcPicConverter::VpcPicConverter(){
7 7  
8   - aclrtSetCurrentContext(context);
9   - aclrtCreateStream(&stream_);
10   -
11   - // 3. 创建图片数据处理通道时的通道描述信息,dvppChannelDesc_是acldvppChannelDesc类型
12   - dvppChannelDesc_ = acldvppCreateChannelDesc();
  8 +}
13 9  
14   - // 4. 创建图片数据处理的通道。
15   - int ret = acldvppCreateChannel(dvppChannelDesc_);
16   - if(ret != ACL_ERROR_NONE){
17   - LOG_ERROR("acldvppCreateChannel failed !");
18   - return false;
  10 +VpcPicConverter::~VpcPicConverter(){
  11 + if(nullptr == stream_){
  12 + aclrtDestroyStream(stream_);
19 13 }
  14 +}
20 15  
21   - ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);
22   - if(ret != ACL_ERROR_NONE){
23   - LOG_ERROR("acldvppSetChannelDescMode failed !");
24   - return false;
25   - }
  16 +int VpcPicConverter::init(aclrtContext context, string dec_name){
  17 +
  18 + m_dec_name = dec_name;
  19 +
  20 + CHECK_AND_RETURN(aclrtSetCurrentContext(context), "aclrtSetCurrentContext failed");
  21 + CHECK_AND_RETURN(aclrtCreateStream(&stream_), "aclrtCreateStream failed! ");
26 22  
27   - return true;
  23 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  24 +
  25 + int ret = ACL_ERROR_NONE;
  26 + do
  27 + {
  28 + ret = acldvppCreateChannel(dvppChannelDesc_);
  29 + CHECK_AND_BREAK(ret, "acldvppCreateChannel failed !");
  30 +
  31 + ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);
  32 + CHECK_AND_BREAK(ret, "acldvppSetChannelDescMode failed !");
  33 + } while (0);
  34 +
  35 + return ret;
28 36 }
29 37  
30 38 DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){
31 39  
32   - // 8. 创建色域转换的输出图片的描述信息,并设置各属性值, 输出的宽和高要求和输入一致
33   - // 如果色域转换的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致
34   - // outputDesc_是acldvppPicDesc类型
35 40 int out_buf_width = ALIGN_UP(out_width, 16) * 3;
36 41 int out_buf_height = ALIGN_UP(out_height, 2);
37 42 int out_buf_size = out_buf_width * out_buf_height;
... ... @@ -48,8 +53,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
48 53 acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
49 54 acldvppSetPicDescSize(outputDesc_, out_buf_size);
50 55  
51   -
52   -
53 56 aclError ret = ACL_ERROR_NONE;
54 57 do{
55 58 // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
... ... @@ -65,8 +68,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
65 68 }
66 69 }while(0);
67 70  
68   - // 10. 色域转换结束后,释放资源,包括输入/输出图片的描述信息、输入/输出内存
69   - // acldvppDestroyPicDesc(inputDesc_);
70 71 acldvppDestroyPicDesc(outputDesc_);
71 72  
72 73 if(ret != ACL_ERROR_NONE){
... ... @@ -75,9 +76,4 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
75 76 }
76 77  
77 78 return rgbMem;
78   -}
79   -
80   -void VpcPicConverter::release(){
81   - aclrtDestroyStream(stream_);
82   - // aclrtDestroyContext(context_);
83 79 }
84 80 \ No newline at end of file
... ...
src/dvpp/VpcPicConverter.h
... ... @@ -5,15 +5,16 @@
5 5  
6 6 class VpcPicConverter{
7 7 public:
8   - bool init(aclrtContext context);
  8 + VpcPicConverter();
  9 + ~VpcPicConverter();
  10 + int init(aclrtContext context, string dec_name);
9 11  
10 12 DvppRgbMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame);
11 13  
12   - void release();
13   -
14 14 private:
15 15 aclrtContext context_;
16 16 aclrtStream stream_;
17 17 int m_devId;
18 18 acldvppChannelDesc *dvppChannelDesc_ ;
  19 + string m_dec_name;
19 20 };
20 21 \ No newline at end of file
... ...
src/dvpp/dvpp_headers.h
... ... @@ -27,5 +27,14 @@
27 27 #include "acl/ops/acl_dvpp.h"
28 28  
29 29  
  30 +#define CHECK_AND_RETURN(ret, message) \
  31 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}
  32 +#define CHECK_NOT_RETURN(ret, message) \
  33 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
  34 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  35 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
  36 +#define CHECK_AND_BREAK(ret, message) \
  37 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
  38 +
30 39 #endif
31 40  
... ...
src/interface/FFNvDecoderManager.cpp
... ... @@ -52,10 +52,10 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){
52 52 return nullptr;
53 53 }
54 54  
  55 + config.cfg.dec_name = config.name;
55 56 bool bRet= dec->init(config.cfg);
56 57 if (bRet)
57 58 {
58   - dec->setName(config.name) ;
59 59 decoderMap[config.name] = dec;
60 60  
61 61 LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri);
... ...