Commit 746db74ca9f8f19a4d907c2c8b7f806a4f42118e

Authored by Hu Chunming
1 parent 09c2d08c

实现recode

.gitignore 0 → 100644
  1 +bin/test_recoder
  2 +.vscode/launch.json
  3 +bin/logs/*
  4 +bin/res/*
0 5 \ No newline at end of file
... ...
.vscode/launch.json 0 → 100644
  1 +{
  2 + // 使用 IntelliSense 了解相关属性。
  3 + // 悬停以查看现有属性的描述。
  4 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  5 + "version": "0.2.0",
  6 + "configurations": [
  7 + {
  8 + "name": "dvpp",
  9 + "type": "cppdbg",
  10 + "request": "launch",
  11 + "program": "${workspaceFolder}/bin/vpt_proj",
  12 + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "1"],
  13 + "stopAtEntry": false,
  14 + "cwd": "${workspaceFolder}/bin",
  15 + "environment": [],
  16 + "externalConsole": false,
  17 + "MIMode": "gdb",
  18 + "setupCommands": [
  19 + {
  20 + "description": "Enable pretty-printing for gdb",
  21 + "text": "-enable-pretty-printing",
  22 + "ignoreFailures": true
  23 + }
  24 + ]
  25 + },{
  26 + "name": "test",
  27 + "type": "cppdbg",
  28 + "request": "launch",
  29 + "program": "${workspaceFolder}/bin/test",
  30 + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"],
  31 + "stopAtEntry": false,
  32 + "cwd": "${workspaceFolder}/bin",
  33 + "environment": [],
  34 + "externalConsole": false,
  35 + "MIMode": "gdb",
  36 + "setupCommands": [
  37 + {
  38 + "description": "Enable pretty-printing for gdb",
  39 + "text": "-enable-pretty-printing",
  40 + "ignoreFailures": true
  41 + }
  42 + ]
  43 + },{
  44 + "name": "test_recoder",
  45 + "type": "cppdbg",
  46 + "request": "launch",
  47 + "program": "${workspaceFolder}/bin/test_recoder",
  48 + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"],
  49 + "stopAtEntry": false,
  50 + "cwd": "${workspaceFolder}/bin",
  51 + "environment": [],
  52 + "externalConsole": false,
  53 + "MIMode": "gdb",
  54 + "setupCommands": [
  55 + {
  56 + "description": "Enable pretty-printing for gdb",
  57 + "text": "-enable-pretty-printing",
  58 + "ignoreFailures": true
  59 + }
  60 + ]
  61 + }
  62 + ]
  63 +}
0 64 \ No newline at end of file
... ...
.vscode/settings.json 0 → 100644
  1 +{
  2 + "files.associations": {
  3 + "thread": "cpp",
  4 + "chrono": "cpp",
  5 + "array": "cpp",
  6 + "atomic": "cpp",
  7 + "bit": "cpp",
  8 + "*.tcc": "cpp",
  9 + "bitset": "cpp",
  10 + "cctype": "cpp",
  11 + "clocale": "cpp",
  12 + "cmath": "cpp",
  13 + "complex": "cpp",
  14 + "condition_variable": "cpp",
  15 + "cstdarg": "cpp",
  16 + "cstddef": "cpp",
  17 + "cstdint": "cpp",
  18 + "cstdio": "cpp",
  19 + "cstdlib": "cpp",
  20 + "cstring": "cpp",
  21 + "ctime": "cpp",
  22 + "cwchar": "cpp",
  23 + "cwctype": "cpp",
  24 + "deque": "cpp",
  25 + "list": "cpp",
  26 + "map": "cpp",
  27 + "set": "cpp",
  28 + "unordered_map": "cpp",
  29 + "vector": "cpp",
  30 + "exception": "cpp",
  31 + "algorithm": "cpp",
  32 + "functional": "cpp",
  33 + "iterator": "cpp",
  34 + "memory": "cpp",
  35 + "memory_resource": "cpp",
  36 + "numeric": "cpp",
  37 + "optional": "cpp",
  38 + "random": "cpp",
  39 + "ratio": "cpp",
  40 + "regex": "cpp",
  41 + "string": "cpp",
  42 + "string_view": "cpp",
  43 + "system_error": "cpp",
  44 + "tuple": "cpp",
  45 + "type_traits": "cpp",
  46 + "utility": "cpp",
  47 + "fstream": "cpp",
  48 + "future": "cpp",
  49 + "initializer_list": "cpp",
  50 + "iomanip": "cpp",
  51 + "iosfwd": "cpp",
  52 + "iostream": "cpp",
  53 + "istream": "cpp",
  54 + "limits": "cpp",
  55 + "mutex": "cpp",
  56 + "new": "cpp",
  57 + "ostream": "cpp",
  58 + "shared_mutex": "cpp",
  59 + "sstream": "cpp",
  60 + "stdexcept": "cpp",
  61 + "streambuf": "cpp",
  62 + "cfenv": "cpp",
  63 + "cinttypes": "cpp",
  64 + "typeinfo": "cpp",
  65 + "variant": "cpp"
  66 + }
  67 +}
0 68 \ No newline at end of file
... ...
src/ai_platform/common_header.h
... ... @@ -3,6 +3,7 @@
3 3  
4 4 #include <cmath>
5 5 #include <type_traits>
  6 +#include <string>
6 7  
7 8 struct point_t {
8 9 int x, y;
... ... @@ -31,9 +32,10 @@ struct box_t {
31 32 };
32 33  
33 34 struct RecoderInfo {
34   - string task_id;
35   - string object_id;
36   - bool bSave;
  35 + std::string recoderDir;
  36 + std::string task_id;
  37 + std::string object_id;
  38 + unsigned long long frame_nb;
37 39 };
38 40  
39 41 #endif // ___COMMON_HEADER_H__
40 42 \ No newline at end of file
... ...
src/decoder/AbstractDecoder.o deleted
No preview for this file type
src/decoder/Makefile
1 1 XX = g++
2 2  
3 3  
4   -PROJECT_ROOT= /opt/cmhu/vpt_ascend
  4 +PROJECT_ROOT= /opt/cmhu/vpt_ascend_arm
5 5  
6 6 DEPEND_DIR = $(PROJECT_ROOT)/bin
7 7 SRC_ROOT = $(PROJECT_ROOT)/src
8 8  
9   -TARGET= $(PROJECT_ROOT)/bin/test_face.so
  9 +TARGET= $(PROJECT_ROOT)/bin/test_recoder
10 10  
11 11 THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
12 12 SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release
... ... @@ -32,8 +32,7 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
32 32 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 \
33 33 -lplatform -lgraph_base -lqos_manager
34 34  
35   -LIBS= -L $(DEPEND_DIR) -lface_det_arm_with_log1\
36   - -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
  35 +LIBS= -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
37 36  
38 37 CXXFLAGS= -g -O0 -fPIC $(include_dir) $(lib_dir) $(lib) $(LIBS) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -fvisibility=hidden -Wall -Wno-deprecated -Wdeprecated-declarations -Wl,-Bsymbolic -ldl
39 38  
... ...
src/decoder/dvpp/DvppDataMemory.hpp
... ... @@ -7,8 +7,8 @@ using namespace std;
7 7 class DvppDataMemory : public DeviceMemory
8 8 {
9 9 public:
10   - DvppDataMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame)
11   - :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){
  10 + 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 + :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){
12 12 data_size = _size;
13 13 int ret = acldvppMalloc((void **)&pHwRgb, data_size);
14 14 if(ret != ACL_ERROR_NONE){
... ... @@ -16,8 +16,8 @@ public:
16 16 }
17 17 }
18 18  
19   - DvppDataMemory( int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned char * pHwData)
20   - :DeviceMemory(3, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){
  19 + DvppDataMemory( 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, unsigned char * pHwData)
  20 + :DeviceMemory(3, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){
21 21 data_size = _size;
22 22 data_type = 1;
23 23 pHwRgb = pHwData;
... ...
src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -4,12 +4,14 @@
4 4  
5 5 struct Vdec_CallBack_UserData {
6 6 uint64_t frameId;
  7 + unsigned long long frame_nb;
7 8 long startTime;
8 9 long sendTime;
9 10 // void* vdecOutputBuf;
10 11 DvppDecoder* self;
11 12 Vdec_CallBack_UserData() {
12 13 frameId = 0;
  14 + frame_nb = 0;
13 15 }
14 16 };
15 17  
... ... @@ -148,6 +150,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
148 150 pix_fmt = (AVPixelFormat)codecpar->format;
149 151 m_fps = av_q2d(stream ->avg_frame_rate);
150 152  
  153 + m_recoderManager.init(stream->time_base, avctx);
  154 +
151 155 LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps);
152 156  
153 157 return avctx;
... ... @@ -336,6 +340,7 @@ void DvppDecoder::read_thread() {
336 340 ,this);
337 341  
338 342 AVPacket* pkt = nullptr;
  343 + unsigned long long frame_nb = 0;
339 344 while (m_bRunning){
340 345  
341 346 if (!m_bReal){
... ... @@ -372,6 +377,9 @@ void DvppDecoder::read_thread() {
372 377  
373 378 if (video_index == pkt->stream_index){
374 379  
  380 + frame_nb++;
  381 + m_recoderManager.cache_pkt(pkt, frame_nb);
  382 +
375 383 ret = av_bsf_send_packet(h264bsfc, pkt);
376 384 if(ret < 0) {
377 385 LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
... ... @@ -392,7 +400,10 @@ void DvppDecoder::read_thread() {
392 400 }
393 401  
394 402 m_pktQueue_mutex.lock();
395   - m_pktQueue.push(pkt);
  403 + DataPacket* data_pkt = new DataPacket();
  404 + data_pkt->pkt = pkt;
  405 + data_pkt->frame_nb = frame_nb;
  406 + m_pktQueue.push(data_pkt);
396 407 m_pktQueue_mutex.unlock();
397 408  
398 409 bPushed = true;
... ... @@ -418,9 +429,9 @@ void DvppDecoder::read_thread() {
418 429  
419 430 m_pktQueue_mutex.lock();
420 431 while(m_pktQueue.size() > 0){
421   - pkt = m_pktQueue.front();
422   - av_packet_free(&pkt);
423   - pkt = nullptr;
  432 + DataPacket* data_pkt = m_pktQueue.front();
  433 + delete data_pkt;
  434 + data_pkt = nullptr;
424 435 m_pktQueue.pop();
425 436 }
426 437 m_pktQueue_mutex.unlock();
... ... @@ -481,14 +492,14 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void
481 492 DvppDecoder* self = userData->self;
482 493 if(self != nullptr){
483 494  
484   - self->doVdppVdecCallBack(input, output);
  495 + self->doVdppVdecCallBack(input, output, userData->frame_nb);
485 496 }
486 497 delete userData;
487 498 userData = nullptr;
488 499 }
489 500 }
490 501  
491   -void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){
  502 +void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){
492 503  
493 504 m_vdecQueue_mutex.lock();
494 505 if(m_vdecQueue.size() > 0){
... ... @@ -519,7 +530,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
519 530 }
520 531  
521 532 if(width > 0 && height > 0 && outputSize > 0){
522   - DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, (unsigned char *)outputDataDev);
  533 + 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);
523 534 if(mem){
524 535 if(post_decoded_cbk) {
525 536 post_decoded_cbk(m_postDecArg, mem);
... ... @@ -532,7 +543,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
532 543 // 缓存snapshot
533 544 std::unique_lock<std::mutex> locker(m_cached_mutex);
534 545  
535   - m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false);
  546 + m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, 0);
536 547 if(m_cached_mem != nullptr){
537 548 aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
538 549 }
... ... @@ -698,12 +709,12 @@ void DvppDecoder::decode_thread(){
698 709 LOG_INFO("[{}]- decode thread exit.", m_dec_name);
699 710 }
700 711  
701   -#include <fstream>
702   -#include <iostream>
703   -#include <cstring>
  712 +// #include <fstream>
  713 +// #include <iostream>
  714 +// #include <cstring>
704 715  
705   -static int nRecoder = 0;
706   -std::ofstream outfile;
  716 +// static int nRecoder = 0;
  717 +// std::ofstream outfile;
707 718  
708 719 int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
709 720  
... ... @@ -716,14 +727,14 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
716 727 }
717 728 m_vdecQueue_mutex.unlock();
718 729  
719   - AVPacket * pkt = nullptr;
  730 + DataPacket * data_pkt = nullptr;
720 731 m_pktQueue_mutex.lock();
721 732 if(m_pktQueue.size() <= 0){
722 733 m_pktQueue_mutex.unlock();
723 734 std::this_thread::sleep_for(std::chrono::milliseconds(10));
724 735 return 1;
725 736 }
726   - pkt = m_pktQueue.front();
  737 + data_pkt = m_pktQueue.front();
727 738 m_pktQueue.pop();
728 739 m_pktQueue_mutex.unlock();
729 740  
... ... @@ -732,8 +743,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
732 743 int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
733 744 if(ACL_ERROR_NONE != ret){
734 745 LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
735   - av_packet_free(&pkt);
736   - pkt = nullptr;
  746 + delete data_pkt;
  747 + data_pkt = nullptr;
737 748 return 2;
738 749 }
739 750  
... ... @@ -754,12 +765,12 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
754 765 // }
755 766  
756 767  
757   -
  768 + AVPacket* pkt = data_pkt->pkt;
758 769 ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
759 770 if(ACL_ERROR_NONE != ret){
760 771 LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
761   - av_packet_free(&pkt);
762   - pkt = nullptr;
  772 + delete data_pkt;
  773 + data_pkt = nullptr;
763 774 return 2;
764 775 }
765 776  
... ... @@ -767,8 +778,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
767 778 ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
768 779 if(ret != ACL_ERROR_NONE){
769 780 LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
770   - av_packet_free(&pkt);
771   - pkt = nullptr;
  781 + delete data_pkt;
  782 + data_pkt = nullptr;
772 783 return 2;
773 784 }
774 785  
... ... @@ -793,12 +804,13 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
793 804 Vdec_CallBack_UserData *user_data = NULL;
794 805 user_data = new Vdec_CallBack_UserData;
795 806 user_data->frameId = frame_count;
  807 + user_data->frame_nb = data_pkt->frame_nb;
796 808 // user_data->startTime = startTime;
797 809 user_data->sendTime = UtilTools::get_cur_time_ms();
798 810 user_data->self = this;
799 811 ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
800   - av_packet_free(&pkt);
801   - pkt = nullptr;
  812 + delete data_pkt;
  813 + data_pkt = nullptr;
802 814 if(ret != ACL_ERROR_NONE){
803 815 delete user_data;
804 816 user_data = nullptr;
... ... @@ -813,9 +825,9 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c
813 825 return 0;
814 826 }while (0);
815 827  
816   - if(pkt != nullptr){
817   - av_packet_free(&pkt);
818   - pkt = nullptr;
  828 + if(data_pkt != nullptr){
  829 + delete data_pkt;
  830 + data_pkt = nullptr;
819 831 }
820 832  
821 833 // 报错情形
... ... @@ -870,4 +882,8 @@ void DvppDecoder::release_dvpp(){
870 882  
871 883 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
872 884 pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  885 +}
  886 +
  887 +void DvppDecoder::doRecode(RecoderInfo& recoderInfo) {
  888 + m_recoderManager.create_recode_task2(recoderInfo);
873 889 }
874 890 \ No newline at end of file
... ...
src/decoder/dvpp/DvppDecoder.h
... ... @@ -8,6 +8,7 @@
8 8 #include <mutex>
9 9 #include <condition_variable>
10 10  
  11 +#include "FFRecoderTaskManager.h"
11 12  
12 13 using namespace std;
13 14  
... ... @@ -51,8 +52,10 @@ public:
51 52  
52 53 int getCachedQueueLength();
53 54  
  55 + void doRecode(RecoderInfo& recoderInfo);
  56 +
54 57 public:
55   - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output);
  58 + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb);
56 59 void doProcessReport();
57 60  
58 61 private:
... ... @@ -96,7 +99,7 @@ private:
96 99 bool m_dec_keyframe;
97 100  
98 101 mutex m_pktQueue_mutex;
99   - queue<AVPacket*> m_pktQueue;
  102 + queue<DataPacket*> m_pktQueue;
100 103  
101 104 // 解码
102 105 int m_dvpp_deviceId {-1};
... ... @@ -118,4 +121,6 @@ private:
118 121 DvppDataMemory* m_cached_mem{nullptr};
119 122 mutex m_cached_mutex;
120 123 condition_variable m_cached_cond;
  124 +
  125 + FFRecoderTaskManager m_recoderManager;
121 126 };
122 127 \ No newline at end of file
... ...
src/decoder/dvpp/DvppDecoderApi.cpp
... ... @@ -130,4 +130,10 @@ void DvppDecoderApi::setFinishedDecArg(const void* finishedDecArg){
130 130 if(m_pDecoder != nullptr){
131 131 return m_pDecoder->setFinishedDecArg(finishedDecArg);
132 132 }
  133 +}
  134 +
  135 +void DvppDecoderApi::doRecode(RecoderInfo& recoderInfo) {
  136 + if(m_pDecoder != nullptr){
  137 + return m_pDecoder->doRecode(recoderInfo);
  138 + }
133 139 }
134 140 \ No newline at end of file
... ...
src/decoder/dvpp/DvppDecoderApi.h
... ... @@ -39,6 +39,8 @@ public:
39 39  
40 40 void setPostDecArg(const void* postDecArg);
41 41 void setFinishedDecArg(const void* finishedDecArg);
  42 +
  43 + void doRecode(RecoderInfo& recoderInfo);
42 44 private:
43 45 DvppDecoder* m_pDecoder;
44 46 };
45 47 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoder.cpp1 renamed to src/decoder/dvpp/FFRecoder.cpp
... ... @@ -3,14 +3,6 @@
3 3 #include <tuple>
4 4 #include <array>
5 5 #include <vector>
6   -extern "C" {
7   - #include <libavcodec/avcodec.h>
8   - #include <libavformat/avformat.h>
9   - #include <libavutil/opt.h>
10   - #include <libavutil/timestamp.h>
11   - #include <libavutil/imgutils.h>
12   - #include <libswscale/swscale.h>
13   -}
14 6  
15 7  
16 8 FFRecoder::FFRecoder()
... ... @@ -156,6 +148,8 @@ bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* ou
156 148 fprintf(stderr, "Write header failed!\n");
157 149 return false;
158 150 }
  151 +
  152 + return true;
159 153 }
160 154  
161 155 void FFRecoder::uninit()
... ... @@ -248,6 +242,8 @@ void FFRecoder::update_pts(AVPacket* pkt) {
248 242 }
249 243  
250 244 bool FFRecoder::write_pkt(AVPacket *pkt) {
  245 + char errbuf[64]{ 0 };
  246 +
251 247 av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base);
252 248 pkt->stream_index = out_stream_->index;
253 249 update_pts(pkt);
... ...
src/decoder/dvpp/FFRecoder.h1 renamed to src/decoder/dvpp/FFRecoder.h
1 1 #pragma once
2 2 #include <memory>
3 3  
4   -class AVFrame;
5   -class AVStream;
6   -class AVCodecContext;
7   -class AVFormatContext;
8   -struct AVRational;
9   -struct SwsContext;
10   -struct AVPacket;
  4 +extern "C" {
  5 + #include <libavcodec/avcodec.h>
  6 + #include <libavformat/avformat.h>
  7 + #include <libavutil/opt.h>
  8 + #include <libavutil/timestamp.h>
  9 + #include <libavutil/imgutils.h>
  10 + #include <libswscale/swscale.h>
  11 +}
11 12  
12 13 class FFRecoder
13 14 {
... ...
src/decoder/dvpp/FFRecoderTaskManager.cpp 0 → 100644
  1 +#include "FFRecoderTaskManager.h"
  2 +#include <chrono>
  3 +
  4 +struct RecodeThreadParam {
  5 + FFRecoderTaskManager* _this;
  6 + RecodeParam param;
  7 +};
  8 +
  9 +static long get_cur_time() {
  10 +
  11 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  12 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  13 +
  14 + return tpMicro.time_since_epoch().count();
  15 +}
  16 +
  17 +static string get_cur_datetime()
  18 +{
  19 + using namespace std;
  20 + auto t = chrono::system_clock::to_time_t(chrono::system_clock::now());
  21 +
  22 + char buffer[40];
  23 + strftime(buffer, 80, "%Y_%m_%d_%H_%M_%S", std::localtime(&t));
  24 + buffer[20] = '\0';
  25 + return buffer;
  26 +}
  27 +
  28 +static bool is_key_frame(AVPacket *pkt) {
  29 + return (pkt->flags & AV_PKT_FLAG_KEY) != 0;
  30 +}
  31 +
  32 +FFRecoderTaskManager::FFRecoderTaskManager(){
  33 +
  34 +}
  35 +
  36 +FFRecoderTaskManager::~FFRecoderTaskManager(){
  37 +
  38 +}
  39 +
  40 +bool FFRecoderTaskManager::init(AVRational time_base, AVCodecContext* avctx){
  41 + m_time_base = time_base;
  42 + m_avctx = avctx;
  43 +
  44 + m_recoder_thread = new std::thread(
  45 + [](void* arg) {
  46 + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)arg;
  47 + if(_this != nullptr) {
  48 + _this->recode_thread2();
  49 + }else{
  50 + LOG_ERROR("recode 线程启动失败 !");
  51 + }
  52 + return (void*)0;
  53 + }, this);
  54 +
  55 + return true;
  56 +}
  57 +
  58 +void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb){
  59 + std::lock_guard<std::mutex> l_pkt(m_pkt_list_mtx);
  60 +
  61 + // 考虑到一个AVPacket中的数据并不很大,为减少与解码模块的耦合度,方便管理,这里做一个clone
  62 + AVPacket *new_pkt = av_packet_clone(pkt);
  63 +
  64 + DataPacket* newDataPkt = new DataPacket();
  65 + newDataPkt->pkt = new_pkt;
  66 + newDataPkt->frame_nb = frame_nb;
  67 + m_pkt_list.emplace_back(newDataPkt);
  68 +
  69 + if(is_key_frame(pkt)){
  70 + // 越来越大的值
  71 + newDataPkt->isKeyFrame = true;
  72 + LOG_INFO("key frame_nb: {}", frame_nb);
  73 + } else {
  74 + newDataPkt->isKeyFrame = false;
  75 + }
  76 +
  77 + std::lock_guard<std::mutex> l_info(m_recoderinfo_list_mtx);
  78 + if(m_recoderinfo_list.size() <= 0){
  79 + // 没有任务的时候,维持500的长度
  80 + while(m_pkt_list.size() > 1000) {
  81 + DataPacket* dataPkt = m_pkt_list.front();
  82 + delete dataPkt;
  83 + dataPkt = nullptr;
  84 + m_pkt_list.pop_front();
  85 + }
  86 + }
  87 +}
  88 +
  89 +void FFRecoderTaskManager::save_intask_frame_nb(unsigned long long frame_nb) {
  90 + if(m_intask_frame_nb_list.size() <= 0) {
  91 + m_intask_frame_nb_list.push_back(frame_nb);
  92 + return;
  93 + }
  94 +
  95 + for(auto it = m_intask_frame_nb_list.begin(); it != m_intask_frame_nb_list.end(); it++) {
  96 + if(*it > frame_nb) {
  97 + m_intask_frame_nb_list.insert(it, frame_nb);
  98 + return;
  99 + }
  100 + }
  101 +
  102 + // 新 frame_nb 比所有的都大
  103 + m_intask_frame_nb_list.push_back(frame_nb);
  104 +}
  105 +
  106 +void FFRecoderTaskManager::save_intask_recoderinfo(RecoderInfo info) {
  107 + std::lock_guard<std::mutex> l(m_recoderinfo_list_mtx);
  108 + if(m_recoderinfo_list.size() <= 0) {
  109 + m_recoderinfo_list.push_back(info);
  110 + return;
  111 + }
  112 +
  113 + for(auto it = m_recoderinfo_list.begin(); it != m_recoderinfo_list.end(); it++) {
  114 + if(it->frame_nb > info.frame_nb) {
  115 + m_recoderinfo_list.insert(it, info);
  116 + return;
  117 + }
  118 + }
  119 +
  120 + // 新 frame_nb 比所有的都大
  121 + m_recoderinfo_list.push_back(info);
  122 +}
  123 +
  124 +list<DataPacket*>::iterator FFRecoderTaskManager::getStartIterator(unsigned long long frame_nb){
  125 + std::lock_guard<std::mutex> l(m_pkt_list_mtx);
  126 +
  127 + auto it_first = m_pkt_list.begin();
  128 +
  129 + long long start_frame_nb = (long long)(frame_nb - 375);
  130 + if(start_frame_nb <= 0) {
  131 + return it_first;
  132 + }
  133 +
  134 + auto it_second = m_pkt_list.begin();
  135 + for(;it_second != m_pkt_list.end(); it_second++) {
  136 + DataPacket* dataPkt = *it_second;
  137 + if(dataPkt->isKeyFrame) {
  138 + it_first = it_second;
  139 + }
  140 + if(start_frame_nb >= (*it_first)->frame_nb && start_frame_nb <= (*it_second)->frame_nb) {
  141 + return it_first;
  142 + }
  143 + }
  144 +
  145 + return m_pkt_list.begin();
  146 +}
  147 +
  148 +// 多线程版
  149 +void FFRecoderTaskManager::create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo){
  150 +
  151 + std::lock_guard<std::mutex> l(m_task_creat_mtx);
  152 +
  153 + RecodeParam recodeParam;
  154 + recodeParam.time_base = time_base;
  155 + recodeParam.avctx = avctx;
  156 + recodeParam.recoderInfo = recoderInfo;
  157 +
  158 + RecodeThreadParam* threadParam = new RecodeThreadParam();
  159 + threadParam->_this = this;
  160 + threadParam->param = recodeParam;
  161 + std::thread* recode_thread = new std::thread(
  162 + [](void* arg) {
  163 + RecodeThreadParam* threadParam = (RecodeThreadParam*)arg;
  164 + if(threadParam != nullptr){
  165 + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)threadParam->_this;
  166 + if(_this != nullptr) {
  167 + _this->recode_thread(threadParam->param);
  168 + }else{
  169 + LOG_ERROR("recode 线程启动失败 !");
  170 + }
  171 + }
  172 + return (void*)0;
  173 + }, threadParam);
  174 +
  175 + std::string id = recoderInfo.task_id + "_" + recoderInfo.object_id + "_" + std::to_string(recoderInfo.frame_nb);
  176 + m_id_recoderTask[id] = recode_thread;
  177 +
  178 + save_intask_frame_nb(recoderInfo.frame_nb);
  179 +}
  180 +
  181 +void FFRecoderTaskManager::create_recode_task2(RecoderInfo& recoderInfo) {
  182 + save_intask_recoderinfo(recoderInfo);
  183 +}
  184 +
  185 +// 多线程版
  186 +void FFRecoderTaskManager::recode_thread(RecodeParam recodeParam){
  187 + {
  188 + // 此处确保create_recode_task执行完成,m_id_recoderTask 已经保存当前线程信息
  189 + std::lock_guard<std::mutex> l(m_task_creat_mtx);
  190 + }
  191 +
  192 + RecoderInfo recoderInfo;
  193 + recoderInfo = recodeParam.recoderInfo;
  194 + std::string id = recoderInfo.task_id + "_" + recoderInfo.object_id + "_" + std::to_string(recoderInfo.frame_nb);
  195 + string file_name = recoderInfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
  196 + FFRecoder ffrecoder;
  197 + bool bInit = ffrecoder.init(recodeParam.time_base, recodeParam.avctx, file_name.c_str());
  198 + if (!bInit) {
  199 + LOG_ERROR("ffrecoder init error : {} {} {}", recoderInfo.task_id, recoderInfo.object_id, recoderInfo.frame_nb);
  200 + m_id_recoderTask.erase(id);
  201 + return;
  202 + }
  203 + LOG_INFO("record start, pkt_list size: {} id: {}", m_pkt_list.size(), id);
  204 +
  205 + int count = 0;
  206 + for (auto it = m_pkt_list.begin(); it != m_pkt_list.end() && count < 500; ++it) {
  207 + DataPacket* dataPkt = *it;
  208 + AVPacket* pkt = dataPkt->pkt;
  209 + ffrecoder.write_pkt(pkt);
  210 + count++;
  211 + }
  212 +
  213 + ffrecoder.flush();
  214 + ffrecoder.uninit();
  215 +
  216 + m_id_recoderTask.erase(id);
  217 +
  218 + LOG_INFO("record end : {}", file_name);
  219 +}
  220 +
  221 +void FFRecoderTaskManager::recode_thread2() {
  222 +
  223 + while(true) {
  224 + m_recoderinfo_list_mtx.lock();
  225 + if(m_recoderinfo_list.size() <= 0){
  226 + m_recoderinfo_list_mtx.unlock();
  227 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  228 + continue;
  229 + }
  230 +
  231 + auto it_param = m_recoderinfo_list.begin();
  232 + RecoderInfo recoderinfo = *it_param;
  233 + m_recoderinfo_list.pop_front();
  234 + m_recoderinfo_list_mtx.unlock();
  235 +
  236 + auto it_data = getStartIterator(recoderinfo.frame_nb);
  237 + if(it_data == m_pkt_list.end()) {
  238 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  239 + continue;
  240 + }
  241 +
  242 + LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb);
  243 +
  244 + m_pkt_list_mtx.lock();
  245 + auto it = m_pkt_list.begin();
  246 + while (it != it_data) {
  247 + DataPacket* dataPkt = m_pkt_list.front();
  248 + delete dataPkt;
  249 + dataPkt = nullptr;
  250 + m_pkt_list.pop_front();
  251 + it = m_pkt_list.begin();
  252 + }
  253 + m_pkt_list_mtx.unlock();
  254 +
  255 + std::string id = recoderinfo.task_id + "_" + recoderinfo.object_id + "_" + std::to_string(recoderinfo.frame_nb);
  256 + string file_name = recoderinfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
  257 + FFRecoder ffrecoder;
  258 + bool bInit = ffrecoder.init(m_time_base, m_avctx, file_name.c_str());
  259 + if (!bInit) {
  260 + LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb);
  261 + continue;
  262 + }
  263 + LOG_INFO("record start, pkt_list size: {} id: {}", m_pkt_list.size(), id);
  264 +
  265 + int count = 0;
  266 + auto it_save = it_data;
  267 + unsigned long long start_frame_nb = (*it_data)->frame_nb;
  268 + unsigned long long end_frame_nb = (*it_data)->frame_nb;
  269 + for (; it_save != m_pkt_list.end() && count < 500; ++it_save) {
  270 + DataPacket* dataPkt = *it_save;
  271 + AVPacket* pkt = dataPkt->pkt;
  272 + ffrecoder.write_pkt(pkt);
  273 + count++;
  274 + end_frame_nb = (*it_save)->frame_nb;
  275 + }
  276 +
  277 + // ffrecoder.flush();
  278 + ffrecoder.uninit();
  279 +
  280 + LOG_INFO("record end, total save: {} start_frame_nb: {} end_frame_nb: {} file_path: {}", count, start_frame_nb, end_frame_nb, file_name);
  281 + }
  282 +
  283 +}
0 284 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoderTaskManager.h 0 → 100644
  1 +#include "FFRecoder.h"
  2 +
  3 +#include "../../ai_platform/common_header.h"
  4 +#include "depend_headers.h"
  5 +
  6 +#include <list>
  7 +#include <queue>
  8 +#include <map>
  9 +#include <string>
  10 +#include <thread>
  11 +#include <mutex>
  12 +
  13 +using namespace std;
  14 +
  15 +struct RecodeParam {
  16 + AVRational time_base;
  17 + RecoderInfo recoderInfo;
  18 + AVCodecContext* avctx;
  19 +};
  20 +
  21 +class FFRecoderTaskManager {
  22 +public:
  23 + FFRecoderTaskManager();
  24 + virtual ~FFRecoderTaskManager();
  25 +
  26 + void cache_pkt(AVPacket* pkt, long long frame_nb);
  27 + void create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo);
  28 +
  29 + bool init(AVRational time_base, AVCodecContext* avctx);
  30 + void create_recode_task2(RecoderInfo& recoderInfo);
  31 +
  32 +public:
  33 + void recode_thread(RecodeParam param);
  34 + list<DataPacket*>::iterator getStartIterator(unsigned long long frame_nb);
  35 +
  36 + void recode_thread2();
  37 +
  38 +private:
  39 + void save_intask_frame_nb(unsigned long long frame_nb);
  40 + void save_intask_recoderinfo(RecoderInfo info);
  41 +
  42 +private:
  43 + std::queue<int> m_key_frame_interval;
  44 + std::list<unsigned long long> m_keyframe_nb_list;
  45 + std::list<DataPacket*> m_pkt_list;
  46 + mutex m_pkt_list_mtx;
  47 + unsigned long long m_last_key_frame_nb;
  48 +
  49 + std::list<unsigned long long> m_intask_frame_nb_list;
  50 +
  51 + std::list<RecoderInfo> m_recoderinfo_list;
  52 + mutex m_recoderinfo_list_mtx;
  53 +
  54 + bool m_bExit{false};
  55 +
  56 + map<string, thread*> m_id_recoderTask;
  57 + mutex m_task_creat_mtx;
  58 +
  59 + AVRational m_time_base;
  60 + AVCodecContext* m_avctx;
  61 +
  62 + thread* m_recoder_thread {nullptr};
  63 +};
0 64 \ No newline at end of file
... ...
src/decoder/dvpp/VpcPicConverter.cpp
... ... @@ -41,7 +41,7 @@ DvppDataMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out
41 41 int out_buf_height = ALIGN_UP(out_height, 2);
42 42 int out_buf_size = out_buf_width * out_buf_height;
43 43  
44   - DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame);
  44 + DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame, 0);
45 45 void *outBufferDev_ = (void*)rgbMem->getMem();
46 46  
47 47 acldvppPicDesc *outputDesc_= acldvppCreatePicDesc();
... ...
src/decoder/dvpp/depend_headers.h
... ... @@ -35,4 +35,18 @@ extern &quot;C&quot; {
35 35 #include "../interface/interface_headers.h"
36 36 #include "../interface/utiltools.hpp"
37 37  
  38 +
  39 +struct DataPacket {
  40 + AVPacket* pkt {nullptr};
  41 + unsigned long long frame_nb{0};
  42 + bool isKeyFrame{false};
  43 +
  44 + ~DataPacket(){
  45 + if(pkt != nullptr) {
  46 + av_packet_free(&pkt);
  47 + pkt = nullptr;
  48 + }
  49 + }
  50 +};
  51 +
38 52 #endif
39 53 \ No newline at end of file
... ...
src/decoder/interface/AbstractDecoder.h
... ... @@ -3,6 +3,8 @@
3 3  
4 4 #include "interface_headers.h"
5 5  
  6 +#include "../../ai_platform/common_header.h"
  7 +
6 8 using namespace std;
7 9  
8 10 class AbstractDecoder{
... ... @@ -38,6 +40,8 @@ public:
38 40 virtual void setPostDecArg(const void* postDecArg) = 0;
39 41 virtual void setFinishedDecArg(const void* finishedDecArg) = 0;
40 42  
  43 + virtual void doRecode(RecoderInfo& recoderInfo) = 0;
  44 +
41 45 public:
42 46 bool isSnapTime();
43 47  
... ...
src/decoder/interface/DecoderManager.cpp
... ... @@ -517,3 +517,23 @@ DeviceMemory* DecoderManager::snapshot_out_task(string&amp; uri, int devId) {
517 517  
518 518 return devMem;
519 519 }
  520 +
  521 +
  522 +void DecoderManager::doRecode(RecoderInfo& recoderInfo) {
  523 + string name = recoderInfo.task_id;
  524 + if (name.empty()){
  525 + LOG_ERROR("name 为空!");
  526 + return;
  527 + }
  528 +
  529 + std::lock_guard<std::mutex> l(m_mutex);
  530 +
  531 + auto dec = decoderMap.find(name);
  532 + if (dec != decoderMap.end()){
  533 + dec->second->doRecode(recoderInfo);
  534 + return;
  535 + }
  536 +
  537 + LOG_ERROR("没有找到name为{}的解码器",name);
  538 + return;
  539 +}
520 540 \ No newline at end of file
... ...
src/decoder/interface/DecoderManager.h
... ... @@ -273,6 +273,8 @@ public:
273 273 **************************************************/
274 274 vector<DeviceMemory*> timing_snapshot_all();
275 275  
  276 + void doRecode(RecoderInfo& recoderInfo);
  277 +
276 278 private:
277 279 DecoderManager(){}
278 280  
... ...
src/decoder/interface/DeviceMemory.hpp
... ... @@ -10,7 +10,7 @@ using namespace std;
10 10 class DeviceMemory{
11 11  
12 12 public:
13   - DeviceMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, string _id, string _dev_id, bool _key_frame, bool _isused){
  13 + DeviceMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, string _id, string _dev_id, bool _key_frame, unsigned long long _frame_nb, bool _isused){
14 14 channel = _channel;
15 15 width = _width;
16 16 width_stride = _width_stride;
... ... @@ -21,6 +21,7 @@ public:
21 21 id = _id;
22 22 device_id = _dev_id;
23 23 key_frame = _key_frame;
  24 + frame_nb = _frame_nb;
24 25 timestamp = UtilTools::get_cur_time_ms();
25 26 }
26 27  
... ... @@ -80,6 +81,10 @@ public:
80 81 return key_frame;
81 82 }
82 83  
  84 + unsigned long long getFrameNb() {
  85 + return frame_nb;
  86 + }
  87 +
83 88 public:
84 89 int data_size;
85 90 bool isused;
... ... @@ -94,6 +99,7 @@ public:
94 99 int channel{3};
95 100 bool key_frame;
96 101 long index;
  102 + unsigned long long frame_nb;
97 103 };
98 104  
99 105 #endif
100 106 \ No newline at end of file
... ...
src/decoder/test.cpp renamed to src/decoder/test.cpp1
src/decoder/test_recoder.cpp 0 → 100644
  1 +#include "./interface/DecoderManager.h"
  2 +#include <mutex>
  3 +#include <thread>
  4 +#include <chrono>
  5 +
  6 +using namespace std;
  7 +
  8 +struct decode_cbk_userdata{
  9 + string task_id;
  10 + void* opaque;
  11 + void* opaque1;
  12 +};
  13 +
  14 +deque<DeviceMemory*> m_RgbDataList;
  15 +mutex m_DataListMtx;
  16 +
  17 +thread* m_pAlgorthimThread{nullptr};
  18 +bool m_bfinish{false};
  19 +int m_devId = 0;
  20 +const char* task_id = "test0";
  21 +int skip_frame_ = 5;
  22 +int m_batch_size = 20;
  23 +
  24 +void algorthim_process_thread();
  25 +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem);
  26 +
  27 +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
  28 + do{
  29 + if(m_bfinish){
  30 + break;
  31 + }
  32 + m_DataListMtx.lock();
  33 + if(m_RgbDataList.size() >= 30){
  34 + m_DataListMtx.unlock();
  35 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  36 + continue;
  37 + }
  38 + m_RgbDataList.push_back(devFrame);
  39 + m_DataListMtx.unlock();
  40 + break;
  41 + }while (true);
  42 +}
  43 +
  44 +void decode_finished_cbk(const void * userPtr){
  45 + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
  46 + if (ptr!= nullptr){
  47 + printf("task finished: %s \n", ptr->task_id.c_str());
  48 + }
  49 + delete ptr;
  50 + ptr = nullptr;
  51 +}
  52 +
  53 +int main(){
  54 +
  55 + // 创建解码任务
  56 + DecoderManager* pDecManager = DecoderManager::getInstance();
  57 +
  58 + MgrDecConfig config;
  59 + config.name = task_id;
  60 + config.cfg.uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0";
  61 + config.cfg.post_decoded_cbk = post_decod_cbk;
  62 + config.cfg.decode_finished_cbk = decode_finished_cbk;
  63 + config.cfg.force_tcp = true; // rtsp用tcp
  64 + config.cfg.gpuid = to_string(m_devId);
  65 + config.cfg.skip_frame = skip_frame_;
  66 +
  67 + config.dec_type = DECODER_TYPE_DVPP;
  68 +
  69 + AbstractDecoder* dec = pDecManager->createDecoder(config);
  70 + if (!dec){
  71 + printf("创建解码器失败 \n");
  72 + return false;
  73 + }
  74 +
  75 + decode_cbk_userdata* userPtr = new decode_cbk_userdata;
  76 + userPtr->task_id = string(task_id);
  77 + pDecManager->setPostDecArg(config.name, userPtr);
  78 + pDecManager->setFinishedDecArg(config.name, userPtr);
  79 +
  80 +
  81 + int input_image_width = 0;
  82 + int input_image_height = 0;
  83 + pDecManager->getResolution(config.name, input_image_width, input_image_height);
  84 +
  85 +
  86 + // 创建算法线程
  87 + m_pAlgorthimThread = new thread([](void* arg) {
  88 + algorthim_process_thread();
  89 + return (void*)0;
  90 + }
  91 + , nullptr);
  92 +
  93 + pDecManager->startDecodeByName(config.name);
  94 +
  95 + while (getchar() != 'q');
  96 +}
  97 +
  98 +void algorthim_process_thread(){
  99 +
  100 + while (true){
  101 + if(m_bfinish){
  102 + break;
  103 + }
  104 +
  105 + vector<DeviceMemory*> vec_gpuMem;
  106 + m_DataListMtx.lock();
  107 + while (!m_RgbDataList.empty()){
  108 + DeviceMemory* gpuMem = m_RgbDataList.front();
  109 + if(gpuMem->getMem() == nullptr){
  110 + // 错误数据,直接删除
  111 + delete gpuMem;
  112 + gpuMem = nullptr;
  113 + printf("mem is null \n");
  114 + } else {
  115 + vec_gpuMem.push_back(gpuMem);
  116 + }
  117 + m_RgbDataList.pop_front();
  118 + if(vec_gpuMem.size() >= m_batch_size){
  119 + break;
  120 + }
  121 + }
  122 + m_DataListMtx.unlock();
  123 +
  124 + if(vec_gpuMem.size() <= 0){
  125 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  126 + continue;
  127 + }
  128 +
  129 + algorthim_face_detect(vec_gpuMem);
  130 +
  131 + for(int i=0;i < vec_gpuMem.size(); i++){
  132 + DeviceMemory* mem = vec_gpuMem[i];
  133 + if(mem->getSize() <= 0){
  134 + continue;
  135 + }
  136 + delete mem;
  137 + mem = nullptr;
  138 + }
  139 + vec_gpuMem.clear();
  140 +
  141 + }
  142 +
  143 + printf("algorthim_process_thread exit. \n");
  144 +}
  145 +
  146 +static int interval = 0;
  147 +static int obj_id = 0;
  148 +
  149 +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem) {
  150 + interval ++ ;
  151 +
  152 + if(interval % 50 != 0) {
  153 + return;
  154 + }
  155 +
  156 + for(int i= 0; i < vec_gpuMem.size(); i++) {
  157 + DeviceMemory* mem = vec_gpuMem[i];
  158 + string task_id = mem->getId();
  159 +
  160 + RecoderInfo recoderInfo;
  161 + recoderInfo.task_id = task_id;
  162 + recoderInfo.object_id = std::to_string(obj_id);
  163 + recoderInfo.recoderDir = "./res/recode";
  164 + recoderInfo.frame_nb = mem->getFrameNb();
  165 + DecoderManager* pDecManager = DecoderManager::getInstance();
  166 + pDecManager->doRecode(recoderInfo);
  167 +
  168 + obj_id++;
  169 +
  170 + }
  171 +}
0 172 \ No newline at end of file
... ...