Commit bc01d0b63ee7d981449bca25d6c56a1917055dcd

Authored by Hu Chunming
1 parent cf231d0a

代码优化;主要是修改了截图逻辑,避免可能出现的内存和显存泄漏

.gitignore
... ... @@ -8,3 +8,4 @@ data/*
8 8 src/Makefile
9 9 .gitignore
10 10 src/decoder/Makefile
  11 +bin/test_dec
... ...
.vscode/launch.json
... ... @@ -58,6 +58,24 @@
58 58 "ignoreFailures": true
59 59 }
60 60 ]
  61 + },{
  62 + "name": "test_dec",
  63 + "type": "cppdbg",
  64 + "request": "launch",
  65 + "program": "${workspaceFolder}/bin/test_dec",
  66 + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"],
  67 + "stopAtEntry": false,
  68 + "cwd": "${workspaceFolder}/bin",
  69 + "environment": [],
  70 + "externalConsole": false,
  71 + "MIMode": "gdb",
  72 + "setupCommands": [
  73 + {
  74 + "description": "Enable pretty-printing for gdb",
  75 + "text": "-enable-pretty-printing",
  76 + "ignoreFailures": true
  77 + }
  78 + ]
61 79 }
62 80 ]
63 81 }
64 82 \ No newline at end of file
... ...
.vscode/settings.json
... ... @@ -62,6 +62,7 @@
62 62 "cfenv": "cpp",
63 63 "cinttypes": "cpp",
64 64 "typeinfo": "cpp",
65   - "variant": "cpp"
  65 + "variant": "cpp",
  66 + "bsf_internal.h": "c"
66 67 }
67 68 }
68 69 \ No newline at end of file
... ...
src/decoder/Makefile renamed to build/decoder/Makefile
src/demo/Makefile renamed to build/demo/Makefile
... ... @@ -15,7 +15,7 @@ JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release
15 15 FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release
16 16 RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release
17 17  
18   -DEFS = -DENABLE_DVPP_INTERFACE -DPOST_USE_RABBITMQ -DUSE_VILLAGE
  18 +DEFS = -DENABLE_DVPP_INTERFACE
19 19  
20 20 include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
21 21 -I $(SPDLOG_ROOT)/include \
... ...
src/Makefile renamed to build/src/Makefile
... ... @@ -16,8 +16,8 @@ FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release
16 16 RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release
17 17 AUTHORITY_DIR = $(THIRDPARTY_ROOT)/atlas_lic-aarch64-20220112/atlas_lic
18 18  
19   -DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ -DUSE_VILLAGE
20   -# DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ
  19 +# DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ -DUSE_VILLAGE
  20 +DEFS = -DENABLE_DVPP_INTERFACE
21 21  
22 22 include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
23 23 -I $(SPDLOG_ROOT)/include \
... ... @@ -33,7 +33,7 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
33 33 -L/usr/local/Ascend/ascend-toolkit/latest/runtime/lib64 \
34 34 -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
35 35 -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \
36   -
  36 +
37 37 lib=-lacl_dvpp -lascendcl -lacl_dvpp_mpi -lruntime -lascendalog -lc_sec -lmsprofiler -lgert -lmmpa -lascend_hal -lexe_graph -lge_executor -lgraph -lprofapi -lascend_protobuf -lerror_manager -lhybrid_executor -lregister -ldavinci_executor -lge_common -lge_common_base \
38 38 -lplatform -lgraph_base -lqos_manager
39 39  
... ...
src/ai_platform/MultiSourceProcess.cpp
... ... @@ -1316,6 +1316,7 @@ void CMultiSourceProcess::timing_snapshot_thread(){
1316 1316 jpegUtil.jpeg_encode(vpcDesc, fpath_ori);
1317 1317  
1318 1318 acldvppDestroyPicDesc(vpcDesc);
  1319 + vpcDesc = nullptr;
1319 1320  
1320 1321 #ifdef POST_USE_RABBITMQ
1321 1322 auto json_str = helpers::gen_json::gen_vtsnapshot_json(task_id, fpath_ori);
... ...
src/decoder/dvpp/DvppDataMemory.hpp
1 1 #include<string>
2 2  
  3 +#include "depend_headers.h"
3 4 #include "dvpp_headers.h"
4 5  
5 6 using namespace std;
6 7  
  8 +// static int snap_free = 0;
  9 +
7 10 class DvppDataMemory : public DeviceMemory
8 11 {
9 12 public:
10 13 DvppDataMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned long long frame_nb)
11 14 :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){
12 15 data_size = _size;
  16 + data_type = 1;
13 17 int ret = acldvppMalloc((void **)&pHwRgb, data_size);
14 18 if(ret != ACL_ERROR_NONE){
15   - cout << "acldvppMalloc failed" << endl;
  19 + LOG_ERROR("[{}]- acldvppMalloc failed", id);
16 20 }
17 21 }
18 22  
... ... @@ -23,14 +27,48 @@ public:
23 27 pHwRgb = pHwData;
24 28 }
25 29  
  30 +
  31 +
  32 + DvppDataMemory(DvppDataMemory* pSrc):DeviceMemory(-1, pSrc->getWidth(), pSrc->getWidthStride(), pSrc->getHeight(), pSrc->getHeightStride(), pSrc->getId(), pSrc->getDeviceId(), pSrc->isKeyFrame(), pSrc->getFrameNb(), false){
  33 + if(pSrc == nullptr) {
  34 + LOG_ERROR("[{}]- pSrc is nullptr", pSrc->getId());
  35 + return;
  36 + }
  37 +
  38 + data_size = pSrc->getSize();
  39 + int ret = acldvppMalloc((void **)&pHwRgb, data_size);
  40 + if(ret != ACL_ERROR_NONE){
  41 + LOG_ERROR("[{}]- acldvppMalloc failed", pSrc->getId());
  42 + return;
  43 + }
  44 +
  45 + ret = aclrtMemcpy(pHwRgb, data_size, pSrc->getMem(), pSrc->getSize(), ACL_MEMCPY_DEVICE_TO_DEVICE);
  46 + if(ret != ACL_ERROR_NONE){
  47 + acldvppFree(pHwRgb);
  48 + LOG_ERROR("[{}]- aclrtMemcpy failed", pSrc->getId());
  49 + return;
  50 + }
  51 +
  52 + data_type = 2;
  53 + timestamp = UtilTools::get_cur_time_ms();
  54 + }
  55 +
26 56 ~DvppDataMemory(){
  57 + // if (data_type == 2)
  58 + // {
  59 + // snap_free++;
  60 + // LOG_INFO("[{}]- snap_free: {}", getId(), snap_free);
  61 + // }
27 62 if (pHwRgb) {
28 63 int ret = acldvppFree(pHwRgb);
29 64 if(ret != ACL_ERROR_NONE){
30   - cout << "acldvppFree failed" << endl;
  65 + LOG_ERROR("[{}]- acldvppFree failed", id);
31 66 }
32 67 pHwRgb = nullptr;
33 68 }
  69 +
  70 +
  71 +
34 72 }
35 73  
36 74 public:
... ...
src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -13,13 +13,14 @@
13 13  
14 14  
15 15  
  16 +
16 17 struct Vdec_CallBack_UserData {
17 18 uint64_t frameId;
18 19 unsigned long long frame_nb;
19 20 long startTime;
20 21 long sendTime;
21   - // void* vdecOutputBuf;
22 22 DvppDecoder* self;
  23 +
23 24 Vdec_CallBack_UserData() {
24 25 frameId = 0;
25 26 frame_nb = 0;
... ... @@ -57,13 +58,11 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void
57 58  
58 59  
59 60 DvppDecoder::DvppDecoder(){
60   - m_read_thread = 0;
61   - m_cached_mem = nullptr;
  61 + m_read_thread = nullptr;
62 62  
63 63 fmt_ctx = nullptr;
64 64 m_bRunning = false;
65 65  
66   - stream = nullptr;
67 66 video_index = -1;
68 67 pix_fmt = AV_PIX_FMT_NONE;
69 68 m_dec_name = "";
... ... @@ -74,11 +73,12 @@ DvppDecoder::DvppDecoder(){
74 73 m_bFinished = false;
75 74 m_dec_keyframe = false;
76 75 m_fps = 0.0;
77   -
78   - m_bSnapShoting = false;
79 76 }
80 77  
81 78 DvppDecoder::~DvppDecoder(){
  79 + close();
  80 +
  81 + LOG_DEBUG("[{}]- ~DvppDecoder() in_count:{} out_count:{}", m_dec_name, m_in_count, m_out_count);
82 82 }
83 83  
84 84 bool DvppDecoder::init(FFDecConfig cfg){
... ... @@ -106,32 +106,21 @@ bool DvppDecoder::init(FFDecConfig cfg){
106 106  
107 107 AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
108 108  
109   -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
110   - av_register_all();
111   -#endif
112   -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
113   - avcodec_register_all();
114   -#endif
115   -
116   - avformat_network_init();
117   -
118   - const char* uri = config.uri.c_str();
119   - fstream infile;
120   - infile.open(uri, ios::in);
121   - if (!infile.fail()){
122   - m_bReal = false;
123   - infile.close();
124   - } else {
125   - m_bReal = true;
126   - }
  109 + const char* input_file = config.uri.c_str();
  110 + FILE* infile = fopen(input_file, "r");
  111 + if(nullptr != infile) {
  112 + m_bReal = false;
  113 + fclose(infile);
  114 + infile = nullptr;
  115 + } else {
  116 + m_bReal = true;
  117 + }
127 118  
128 119 // 打开输入视频文件
129 120 AVDictionary *options = nullptr;
130 121 av_dict_set( &options, "bufsize", "655360", 0 );
131 122 av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 );
132 123 av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
133   -
134   - const char* input_file = uri;
135 124  
136 125 do{
137 126 fmt_ctx = avformat_alloc_context();
... ... @@ -154,9 +143,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
154 143 LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
155 144 break;
156 145 }
157   - AVCodec *vcodec = avcodec_find_decoder(decoder->id);
158 146  
159   - avctx = avcodec_alloc_context3(vcodec);
  147 + avctx = avcodec_alloc_context3(decoder);
160 148 if(avctx == nullptr){
161 149 LOG_ERROR("[{}]- alloc AVCodecContext failed!", m_dec_name);
162 150 break;
... ... @@ -195,10 +183,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
195 183 frame_width = codecpar->width;
196 184 frame_height = codecpar->height;
197 185 pix_fmt = (AVPixelFormat)codecpar->format;
198   - // m_fps = av_q2d(stream ->avg_frame_rate);
199 186  
200 187 if (stream->avg_frame_rate.den) {
201   - // m_fps = stream->avg_frame_rate.num / stream->avg_frame_rate.den;
202 188 m_fps = av_q2d(stream ->avg_frame_rate);
203 189 } else {
204 190 m_fps = 0.0;
... ... @@ -309,14 +295,12 @@ bool DvppDecoder::isSurport(FFDecConfig&amp; cfg){
309 295 bool DvppDecoder::start(){
310 296 m_bRunning = true;
311 297  
312   - pthread_create(&m_read_thread,0,
313   - [](void* arg)
  298 + m_read_thread = new std::thread([](void* arg)
314 299 {
315 300 DvppDecoder* a=(DvppDecoder*)arg;
316 301 a->read_thread();
317 302 return (void*)0;
318   - }
319   - ,this);
  303 + }, this);
320 304  
321 305 return true;
322 306 }
... ... @@ -324,8 +308,10 @@ bool DvppDecoder::start(){
324 308 void DvppDecoder::close(){
325 309 m_bRunning=false;
326 310  
327   - if(m_read_thread != 0){
328   - pthread_join(m_read_thread,0);
  311 + if(m_read_thread != nullptr){
  312 + m_read_thread->join();
  313 + delete m_read_thread;
  314 + m_read_thread = nullptr;
329 315 }
330 316 }
331 317  
... ... @@ -371,20 +357,42 @@ float DvppDecoder::fps(){
371 357 return m_fps;
372 358 }
373 359  
  360 +static int snap_count = 0;
  361 +
374 362 DeviceMemory* DvppDecoder::snapshot(){
375   - // 注意内部有锁
376   - // 开始抓拍
377   - m_bSnapShoting = true;
378 363  
379   - std::unique_lock<std::mutex> locker(m_cached_mutex);
380   - while (m_cached_mem == nullptr)
381   - m_cached_cond.wait_for(locker, std::chrono::seconds(1)); // Unlock mutex and wait to be notified
382   - locker.unlock();
  364 + int ret = aclrtSetCurrentContext(m_context);
  365 + if(ret != ACL_ERROR_NONE){
  366 + LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
  367 + return nullptr;
  368 + }
383 369  
384   - DeviceMemory* mem = m_cached_mem;
385   - m_cached_mem = nullptr;
  370 + // 注意有锁
  371 + DeviceMemory* snapshot_mem = nullptr;
  372 + int loop_times = 0;
  373 + while(m_bRunning) {
  374 + m_decoded_data_queue_mtx.lock();
  375 + if(m_decoded_data_queue.size() <= 0) {
  376 + m_decoded_data_queue_mtx.unlock();
  377 + loop_times++;
  378 + if(loop_times > 100) {
  379 + // 1s都没截取到图,退出
  380 + break;
  381 + }
  382 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  383 + continue;
  384 + }
  385 +
  386 + DvppDataMemory* mem = m_decoded_data_queue.front();
  387 + snapshot_mem = new DvppDataMemory(mem);
  388 + m_decoded_data_queue_mtx.unlock();
386 389  
387   - return mem;
  390 + snap_count++;
  391 + LOG_INFO("[{}]- snap_count:{} ", m_dec_name, snap_count);
  392 + break;
  393 + }
  394 +
  395 + return snapshot_mem;
388 396 }
389 397  
390 398 int DvppDecoder::getCachedQueueLength(){
... ... @@ -397,14 +405,16 @@ void DvppDecoder::release_ffmpeg() {
397 405 av_bsf_free(&h264bsfc);
398 406 h264bsfc = nullptr;
399 407 }
400   - if (fmt_ctx){
401   - avformat_close_input(&fmt_ctx);
402   - fmt_ctx = nullptr;
403   - }
404 408 if(avctx){
405 409 avcodec_free_context(&avctx);
406 410 avctx = nullptr;
407 411 }
  412 + if (fmt_ctx){
  413 + avformat_close_input(&fmt_ctx);
  414 + fmt_ctx = nullptr;
  415 + }
  416 +
  417 + LOG_DEBUG("[{}]- release_ffmpeg", m_dec_name);
408 418 }
409 419  
410 420 void DvppDecoder::read_thread() {
... ... @@ -420,18 +430,16 @@ void DvppDecoder::read_thread() {
420 430 }
421 431  
422 432 m_bExitDisplayThd = false;
423   - pthread_t display_thread;
424   - pthread_create(&display_thread,0,
  433 + std::thread display_thread = std::thread(
425 434 [](void* arg)
426 435 {
427 436 DvppDecoder* a=(DvppDecoder*)arg;
428 437 a->display_thread();
429 438 return (void*)0;
430   - }
431   - ,this);
432   -
  439 + },
  440 + this
  441 + );
433 442  
434   -
435 443 aclrtContext ctx = nullptr;
436 444 aclrtStream stream = nullptr;
437 445 aclvdecChannelDesc *vdecChannelDesc = nullptr;
... ... @@ -456,7 +464,8 @@ void DvppDecoder::read_thread() {
456 464 CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
457 465 CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
458 466  
459   - AVPacket* pkt = nullptr;
  467 + AVPacket* pkt = av_packet_alloc();
  468 + av_init_packet( pkt );
460 469 unsigned long long frame_nb = 0;
461 470 while (m_bRunning){
462 471  
... ... @@ -476,20 +485,15 @@ void DvppDecoder::read_thread() {
476 485 m_decoded_data_queue_mtx.unlock();
477 486 }
478 487  
479   - pkt = av_packet_alloc();
480   - av_init_packet( pkt );
481   -
482 488 int result = av_read_frame(fmt_ctx, pkt);
483 489 if (result == AVERROR_EOF || result < 0){
484   - av_packet_free(&pkt);
485   - pkt = nullptr;
  490 + av_packet_unref(pkt);
486 491 LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
487 492 break;
488 493 }
489 494  
490 495 if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
491   - av_packet_free(&pkt);
492   - pkt = nullptr;
  496 + av_packet_unref(pkt);
493 497 continue;
494 498 }
495 499  
... ... @@ -498,17 +502,12 @@ void DvppDecoder::read_thread() {
498 502 ret = av_bsf_send_packet(h264bsfc, pkt);
499 503 if(ret < 0) {
500 504 LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
501   - av_packet_free(&pkt);
502   - pkt = nullptr;
  505 + av_packet_unref(pkt);
503 506 continue;
504 507 }
505 508  
506 509 int nSended = -1;
507 510 while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
508   - if(pkt->size > g_pkt_size){
509   - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);
510   - break;
511   - }
512 511  
513 512 if(!m_bRunning){
514 513 break;
... ... @@ -527,8 +526,14 @@ void DvppDecoder::read_thread() {
527 526 }
528 527  
529 528 // 音频等其他分量的情形
530   - av_packet_free(&pkt);
531   - pkt = nullptr;
  529 + av_packet_unref(pkt);
  530 + }
  531 +
  532 + av_packet_free(&pkt);
  533 + pkt = nullptr;
  534 +
  535 + if (vdecChannelDesc) {
  536 + sendVdecEos(vdecChannelDesc);
532 537 }
533 538  
534 539 while(m_bRunning && m_decoded_data_queue.size() > 0) {
... ... @@ -537,9 +542,9 @@ void DvppDecoder::read_thread() {
537 542  
538 543 } while (0);
539 544  
540   - if (vdecChannelDesc) {
541   - sendVdecEos(vdecChannelDesc);
  545 + LOG_INFO("[{}]- release.", m_dec_name);
542 546  
  547 + if (vdecChannelDesc) {
543 548 CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
544 549 CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
545 550 vdecChannelDesc = nullptr;
... ... @@ -551,16 +556,15 @@ void DvppDecoder::read_thread() {
551 556 CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed");
552 557  
553 558 m_bExitDisplayThd = true;
554   - CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "display_thread join failed");
  559 + display_thread.join();
555 560  
556   - if(stream){
  561 + if(stream){
557 562 CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed");
558 563 }
559 564  
560 565 if (ctx){
561 566 CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed");
562 567 }
563   -
564 568  
565 569 m_recoderManager.close();
566 570  
... ... @@ -583,7 +587,7 @@ int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, uns
583 587 acldvppStreamDesc *input_stream_desc = nullptr;
584 588 acldvppPicDesc *output_pic_desc = nullptr;
585 589 do{
586   - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  590 + int ret = acldvppMalloc((void **)&vdecInputbuf, pkt->size);
587 591 if(ACL_ERROR_NONE != ret){
588 592 LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
589 593 break;
... ... @@ -624,6 +628,8 @@ int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, uns
624 628 user_data->sendTime = UtilTools::get_cur_time_ms();
625 629 user_data->self = this;
626 630  
  631 + m_in_count++;
  632 +
627 633 ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
628 634 if(ret != ACL_ERROR_NONE){
629 635 LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
... ... @@ -687,8 +693,9 @@ void DvppDecoder::doProcessReport(){
687 693  
688 694 void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){
689 695  
690   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  696 + m_out_count++;
691 697  
  698 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
692 699  
693 700 void *inputDataDev = acldvppGetStreamDescData(input);
694 701 acldvppFree(inputDataDev);
... ... @@ -712,11 +719,12 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
712 719  
713 720 bool bCached = false;
714 721 if(width > 0 && height > 0 && outputSize > 0){
  722 +
715 723 if (!m_bReal) {
716   - while(m_bRunning) {
  724 + while(!m_bExitReportThd) {
717 725 // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待
718 726 m_decoded_data_queue_mtx.lock();
719   - if(m_decoded_data_queue.size() > 5){
  727 + if(m_decoded_data_queue.size() >= 5){
720 728 m_decoded_data_queue_mtx.unlock();
721 729 std::this_thread::sleep_for(std::chrono::milliseconds(5));
722 730 continue;
... ... @@ -731,7 +739,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
731 739  
732 740 // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏
733 741 m_decoded_data_queue_mtx.lock();
734   - if(m_decoded_data_queue.size() <= 25) {
  742 + if(m_decoded_data_queue.size() <= 5) {
735 743 DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, frame_nb, (unsigned char *)outputDataDev);
736 744 if(mem){
737 745 m_decoded_data_queue.push(mem);
... ... @@ -740,20 +748,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
740 748 }
741 749 m_decoded_data_queue_mtx.unlock();
742 750  
743   - if(m_bSnapShoting){
744   - // 缓存snapshot
745   - std::unique_lock<std::mutex> locker(m_cached_mutex);
746   -
747   - m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, 0);
748   - if(m_cached_mem != nullptr){
749   - aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
750   - }
751   -
752   - locker.unlock();
753   - m_cached_cond.notify_one();
754   - m_bSnapShoting = false;
755   - }
756   -
757 751 }
758 752  
759 753 if(!bCached) {
... ... @@ -802,6 +796,7 @@ void DvppDecoder::display_thread(){
802 796 std::this_thread::sleep_for(std::chrono::milliseconds(5));
803 797 continue;
804 798 }
  799 +
805 800 DvppDataMemory* mem = m_decoded_data_queue.front();
806 801 m_decoded_data_queue.pop();
807 802 m_decoded_data_queue_mtx.unlock();
... ... @@ -814,12 +809,14 @@ void DvppDecoder::display_thread(){
814 809 }
815 810 }
816 811  
  812 + m_decoded_data_queue_mtx.lock();
817 813 while (m_decoded_data_queue.size() > 0){
818 814 DvppDataMemory* mem = m_decoded_data_queue.front();
819 815 m_decoded_data_queue.pop();
820 816 delete mem;
821 817 mem = nullptr;
822 818 }
  819 + m_decoded_data_queue_mtx.unlock();
823 820  
824 821 LOG_INFO("[{}]- display_thread exit.", m_dec_name);
825 822 }
... ... @@ -830,10 +827,14 @@ void DvppDecoder::release_dvpp(){
830 827 if(ret != ACL_ERROR_NONE){
831 828 LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
832 829 }
  830 + m_context = nullptr;
833 831 }
834 832  
835   - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
836   - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  833 + if(m_dvpp_channel >= 0){
  834 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  835 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  836 + m_dvpp_channel = -1;
  837 + }
837 838 }
838 839  
839 840 void DvppDecoder::doRecode(RecoderInfo& recoderInfo) {
... ...
src/decoder/dvpp/DvppDecoder.h
... ... @@ -6,7 +6,8 @@
6 6  
7 7 #include <queue>
8 8 #include <mutex>
9   -#include <condition_variable>
  9 +#include <thread>
  10 +#include <chrono>
10 11  
11 12 #include "FFRecoderTaskManager.h"
12 13  
... ... @@ -14,7 +15,8 @@ using namespace std;
14 15  
15 16 typedef void(*RECEIVER_FINISHED_CALLBACK)(const void* userPtr);
16 17  
17   -const int g_pkt_size = 1024 * 1024; // 单个AVPacket大小的最大值
  18 +
  19 +struct Vdec_CallBack_UserData;
18 20  
19 21 class DvppDecoder{
20 22 public:
... ... @@ -78,7 +80,7 @@ private:
78 80 FFDecConfig m_cfg;
79 81 string m_dec_name;
80 82  
81   - const void * m_finishedDecArg;
  83 + const void * m_finishedDecArg {nullptr};
82 84 DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr};
83 85  
84 86 bool m_bFinished{false};
... ... @@ -89,7 +91,6 @@ private:
89 91 bool m_bExitDisplayThd{false};
90 92  
91 93 // 读取数据
92   - AVStream* stream{nullptr};
93 94 int video_index{-1};
94 95 AVFormatContext *fmt_ctx{nullptr};
95 96 AVPixelFormat pix_fmt;
... ... @@ -98,12 +99,12 @@ private:
98 99  
99 100 int frame_width{0};
100 101 int frame_height{0};
101   - bool m_bReal; // 是否实时流
  102 + bool m_bReal {false}; // 是否实时流
102 103 float m_fps{0.0};
103 104  
104   - pthread_t m_read_thread{0};
  105 + std::thread* m_read_thread{nullptr};
105 106  
106   - bool m_dec_keyframe;
  107 + bool m_dec_keyframe {false};
107 108  
108 109 // 解码
109 110 int m_dvpp_deviceId {-1};
... ... @@ -111,21 +112,18 @@ private:
111 112 aclrtContext m_context{nullptr};
112 113 acldvppStreamFormat m_enType;
113 114  
114   - const void * m_postDecArg;
  115 + const void * m_postDecArg {nullptr};
115 116 POST_DECODE_CALLBACK post_decoded_cbk {nullptr};
116 117  
117 118 int m_vdec_out_size {-1};
118 119  
119   - // 截图
120   - bool m_bSnapShoting{false};
121   - DvppDataMemory* m_cached_mem{nullptr};
122   - mutex m_cached_mutex;
123   - condition_variable m_cached_cond;
124   -
125 120 FFRecoderTaskManager m_recoderManager;
126 121  
127 122 queue<DvppDataMemory*> m_decoded_data_queue;
128 123 mutex m_decoded_data_queue_mtx;
129 124  
130 125 long long last_ts {0};
  126 +
  127 + int m_in_count {0};
  128 + int m_out_count {0};
131 129 };
132 130 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoderTaskManager.cpp
... ... @@ -34,7 +34,7 @@ FFRecoderTaskManager::FFRecoderTaskManager(){
34 34 }
35 35  
36 36 FFRecoderTaskManager::~FFRecoderTaskManager(){
37   -
  37 + LOG_DEBUG("~FFRecoderTaskManager()");
38 38 }
39 39  
40 40 bool FFRecoderTaskManager::init(AVStream* stream, AVCodecContext* avctx){
... ... @@ -264,6 +264,7 @@ void FFRecoderTaskManager::close() {
264 264  
265 265 if (m_recoder_thread) {
266 266 m_recoder_thread->join();
  267 + delete m_recoder_thread;
267 268 m_recoder_thread = nullptr;
268 269 }
269 270  
... ...
src/decoder/interface/DecoderManager.cpp
... ... @@ -13,6 +13,21 @@
13 13  
14 14 using namespace std;
15 15  
  16 +DecoderManager::~DecoderManager(){
  17 + closeAllDecoder();
  18 + avformat_network_deinit();
  19 +}
  20 +
  21 +void DecoderManager::init() {
  22 + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
  23 + av_register_all();
  24 +#endif
  25 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
  26 + avcodec_register_all();
  27 +#endif
  28 +
  29 + avformat_network_init();
  30 +}
16 31  
17 32 AbstractDecoder* DecoderManager::createDecoder(MgrDecConfig config){
18 33  
... ...
src/decoder/interface/DecoderManager.h
... ... @@ -33,14 +33,14 @@ public:
33 33 static DecoderManager* singleton = nullptr;
34 34 if (singleton == nullptr){
35 35 singleton = new DecoderManager();
  36 + singleton->init();
36 37 }
37 38 return singleton;
38 39 }
39 40  
40   - ~DecoderManager()
41   - {
42   - closeAllDecoder();
43   - }
  41 + ~DecoderManager();
  42 +
  43 + void init();
44 44  
45 45 /**************************************************
46 46 * 接口:createDecoder
... ...
src/decoder/interface/DeviceMemory.hpp
... ... @@ -26,7 +26,7 @@ public:
26 26 }
27 27  
28 28 virtual ~DeviceMemory(){}
29   -
  29 +
30 30 int getSize() {
31 31 return data_size;
32 32 }
... ...
src/decoder/test_decoder.cpp
... ... @@ -2,6 +2,7 @@
2 2 #include <mutex>
3 3 #include <thread>
4 4 #include <chrono>
  5 +#include "../common/logger.hpp"
5 6  
6 7 using namespace std;
7 8  
... ... @@ -25,16 +26,18 @@ int m_batch_size = 20;
25 26  
26 27 void algorthim_process_thread();
27 28  
  29 +void snap_shot_thread();
  30 +
28 31 void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
29 32 do{
30 33 if(m_bfinish){
31   - break;
  34 + break;
32 35 }
33 36 m_DataListMtx.lock();
34 37 if(m_RgbDataList.size() >= 30){
35   - m_DataListMtx.unlock();
36   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
37   - continue;
  38 + m_DataListMtx.unlock();
  39 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  40 + continue;
38 41 }
39 42 m_RgbDataList.push_back(devFrame);
40 43 m_DataListMtx.unlock();
... ... @@ -46,13 +49,13 @@ void decode_finished_cbk(const void * userPtr){
46 49 decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
47 50 if (ptr!= nullptr){
48 51 printf("task finished: %s \n", ptr->task_id.c_str());
  52 + delete ptr;
  53 + ptr = nullptr;
49 54 }
50   - delete ptr;
51   - ptr = nullptr;
52 55 }
53 56  
54   -int main(){
55   -
  57 +bool create_task(string task_id) {
  58 +
56 59 // 创建解码任务
57 60 DecoderManager* pDecManager = DecoderManager::getInstance();
58 61  
... ... @@ -73,17 +76,34 @@ int main(){
73 76 return false;
74 77 }
75 78  
76   - decode_cbk_userdata* userPtr = new decode_cbk_userdata;
77   - userPtr->task_id = string(task_id);
78   - pDecManager->setPostDecArg(config.name, userPtr);
79   - pDecManager->setFinishedDecArg(config.name, userPtr);
  79 + // decode_cbk_userdata* userPtr = new decode_cbk_userdata;
  80 + // userPtr->task_id = string(task_id);
  81 + // pDecManager->setPostDecArg(config.name, userPtr);
  82 + // pDecManager->setFinishedDecArg(config.name, userPtr);
  83 +
  84 + dec->setSnapTimeInterval(1000);
80 85  
81 86  
82 87 int input_image_width = 0;
83 88 int input_image_height = 0;
84 89 pDecManager->getResolution(config.name, input_image_width, input_image_height);
85 90  
86   -
  91 + pDecManager->startDecodeByName(config.name);
  92 + // pDecManager->closeAllDecoder();
  93 +
  94 + return true;
  95 +}
  96 +
  97 +int main(){
  98 +
  99 + set_default_logger(LogLevel(0), "test_decode","logs/main.log", 64 * 1024 * 1024, 64 * 1024 * 1024);
  100 + LOG_INFO("编译时间:{} {}", __DATE__, __TIME__);
  101 +
  102 + printf("start... \n");
  103 +
  104 + DecoderManager* pDecManager = DecoderManager::getInstance();
  105 +
  106 +
87 107 // 创建算法线程
88 108 m_pAlgorthimThread = new thread([](void* arg) {
89 109 algorthim_process_thread();
... ... @@ -91,15 +111,47 @@ int main(){
91 111 }
92 112 , nullptr);
93 113  
94   - pDecManager->startDecodeByName(config.name);
  114 + thread snap_thread = thread([](void* arg) {
  115 + snap_shot_thread();
  116 + return (void*)0;
  117 + }
  118 + , nullptr);
  119 +
  120 +
95 121  
96   - while (getchar() != 'q');
  122 + char ch = 'a';
  123 + int task_id = 1;
  124 +
  125 + while (ch != 'q') {
  126 + ch = getchar();
  127 + switch (ch)
  128 + {
  129 + case '4':
  130 + for (size_t i = 0; i < 4; i++)
  131 + {
  132 + create_task(to_string(task_id));
  133 + task_id++;
  134 + std::this_thread::sleep_for(std::chrono::seconds(1));
  135 + }
  136 + break;
  137 + case 'a':
  138 + create_task(to_string(task_id));
  139 + task_id++;
  140 + std::this_thread::sleep_for(std::chrono::seconds(1));
  141 + break;
  142 + case 'c':
  143 + pDecManager->closeAllDecoder();
  144 + break;
  145 + default:
  146 + break;
  147 + }
  148 + }
97 149 }
98 150  
99 151 void do_work(vector<DeviceMemory*> vec_gpuMem){
100 152 for(int i=0;i < vec_gpuMem.size(); i++){
101 153 DeviceMemory* mem = vec_gpuMem[i];
102   - printf("width:%d height:%d ts:%lld \n", mem->getWidth(), mem->getHeight(), mem->getTimesstamp());
  154 + // printf("task:%s width:%d height:%d ts:%lld \n", mem->getId().c_str(), mem->getWidth(), mem->getHeight(), mem->getTimesstamp());
103 155 }
104 156 }
105 157  
... ... @@ -145,9 +197,32 @@ void algorthim_process_thread(){
145 197 delete mem;
146 198 mem = nullptr;
147 199 }
148   - vec_gpuMem.clear();
  200 + // vec_gpuMem.clear();
  201 +
  202 + vector<DeviceMemory*>().swap(vec_gpuMem);
149 203  
150 204 }
151 205  
152 206 printf("algorthim_process_thread exit. \n");
  207 +}
  208 +
  209 +void snap_shot_thread(){
  210 + DecoderManager* pDecManager = DecoderManager::getInstance();
  211 + while (true){
  212 + if(m_bfinish){
  213 + break;
  214 + }
  215 +
  216 + vector<DeviceMemory*> vec_devMem = pDecManager->timing_snapshot_all();
  217 + for(auto devMem : vec_devMem){
  218 + delete devMem;
  219 + devMem = nullptr;
  220 + }
  221 + // vec_devMem.clear();
  222 +
  223 + vector<DeviceMemory*>().swap(vec_devMem);
  224 +
  225 + std::this_thread::sleep_for(std::chrono::milliseconds(600));
  226 +
  227 + }
153 228 }
154 229 \ No newline at end of file
... ...
src/decoder/test_recoder.cpp renamed to src/decoder/test_recoder.cpp2
src/demo/demo.cpp
... ... @@ -63,8 +63,8 @@ void init_mq_conn(void *handle) {
63 63 #endif // #ifdef POST_USE_RABBITMQ
64 64  
65 65 void set_task_params(task_param &tparam, const unsigned &idx, const algorithm_type_t &algor_type) {
66   - auto algor_init_params = new algor_init_config_param_t;
67 66 switch (algor_type) {
  67 + auto algor_init_params = new algor_init_config_param_t;
68 68  
69 69 case algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET: {
70 70 auto algor_params = new algor_config_param_manned_incident;
... ... @@ -874,7 +874,7 @@ void set_task_params(task_param &amp;tparam, const unsigned &amp;idx, const algorithm_ty
874 874  
875 875 auto algor_params = new algor_config_param_road_work;
876 876 {
877   - algor_params->frame_stride = 5;
  877 + algor_params->frame_stride = 1;
878 878 }
879 879  
880 880 auto basic_params = new algor_basic_config_param_t;
... ... @@ -1022,6 +1022,24 @@ string createTask(void *handle, std::vector&lt;algorithm_type_t&gt; algor_vec, int gi,
1022 1022 if (result_code != 0)
1023 1023 printf("[Error]: ");
1024 1024 printf("--- task_id: %s result code: %d\n", tparam.task_id, result_code);
  1025 +
  1026 +
  1027 + // 释放参数
  1028 + for (size_t idx = 0; idx < algor_vec.size(); ++idx) {
  1029 + if(tparam.algor_config_params[idx].algor_type == algorithm_type_t::VIDEO_TIMING_SNAPSHOT) {
  1030 + algor_config_param_road_work* algor_param = (algor_config_param_road_work*)tparam.algor_config_params[idx].algor_init_config_param->algor_param;
  1031 + delete algor_param;
  1032 + algor_basic_config_param_t* basic_param = (algor_basic_config_param_t*)tparam.algor_config_params[idx].algor_init_config_param->basic_param;
  1033 + delete basic_param;
  1034 +
  1035 + algor_init_config_param_t* config_param = tparam.algor_config_params[idx].algor_init_config_param;
  1036 + delete config_param;
  1037 + }
  1038 + }
  1039 + delete[] tparam.algor_config_params;
  1040 +
  1041 +
  1042 +
1025 1043 return task_id_str;
1026 1044 }
1027 1045  
... ... @@ -1083,7 +1101,7 @@ void test_gpu(int gpuID){
1083 1101 algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND, algorithm_type_t::VEHICLE_NOTDECELERATION};
1084 1102 // std::vector<algorithm_type_t> algor_vec3 = {algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET, algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN, algorithm_type_t::TRICYCLE_MANNED, algorithm_type_t::TRUCK_MANNED, algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE,
1085 1103 // algorithm_type_t::NONMOTOR_VEHICLE_REFIT, algorithm_type_t::PERSON_RUNNING_REDLIGHTS, algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS};
1086   - std::vector<algorithm_type_t> algor_vec3 = {algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND, algorithm_type_t::VEHICLE_NOTDECELERATION};
  1104 + std::vector<algorithm_type_t> algor_vec3 = {algorithm_type_t::VIDEO_TIMING_SNAPSHOT};
1087 1105  
1088 1106 /*
1089 1107 int repeat_num = 1000;
... ... @@ -1156,10 +1174,10 @@ void test_gpu(int gpuID){
1156 1174 {
1157 1175 case 'a':
1158 1176 createTask(handle, algor_vec3, 4, false);
1159   - createTask(handle, algor_vec3, 5, false);
1160   - createTask(handle, algor_vec3, 6, false);
1161   - createTask(handle, algor_vec3, 7, false);
1162   - createTask(handle, algor_vec3, 8, false);
  1177 + // createTask(handle, algor_vec3, 5, false);
  1178 + // createTask(handle, algor_vec3, 6, false);
  1179 + // createTask(handle, algor_vec3, 7, false);
  1180 + // createTask(handle, algor_vec3, 8, false);
1163 1181 break;
1164 1182 case 'c':
1165 1183 close_all_task(handle);
... ...