Commit 01fb8719881ce2f8da02a55f148ff93e71ba36eb

Authored by Hu Chunming
1 parent 9c92d004

修复aclrtSetDevice造成的泄露

Showing 37 changed files with 254 additions and 1005 deletions
src/ai_engine_module/VPTProcess.cpp
... ... @@ -41,7 +41,6 @@ int VPTProcess::init(VPTProcess_PARAM vparam){
41 41 param.max_batch = 16;
42 42  
43 43 m_devId = param.devId;
44   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
45 44 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
46 45  
47 46 int ret = vpt_init(&m_det_handle, param);
... ... @@ -81,7 +80,6 @@ int VPTProcess::process_gpu(sy_img * batch_img, vector<string>& tasklist,
81 80  
82 81 vpt_result *real_res = vpt_det_result + startbatch;
83 82  
84   - // aclrtSetDevice(m_devId);
85 83 int ret = aclrtSetCurrentContext(m_algorthim_ctx);
86 84 if(ACL_SUCCESS != ret){
87 85 break;
... ...
src/ai_engine_module/VPTProcess.cpp_debug
... ... @@ -38,7 +38,6 @@ int VPTProcess::init(VPTProcess_PARAM vparam){
38 38 param.isTrk = false;
39 39  
40 40 m_devId = param.devId;
41   - ACL_CALL(aclrtSetDevice(m_devId), ACL_ERROR_NONE, -1);
42 41 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_ERROR_NONE, -1);
43 42  
44 43 int ret = vpt_init(&m_det_handle, param);
... ... @@ -81,7 +80,6 @@ int VPTProcess::process_gpu(sy_img * batch_img, vector<DeviceMemory*> vec_vptMem
81 80  
82 81 vpt_result *real_res = vpt_det_result + startbatch;
83 82  
84   - aclrtSetDevice(m_devId);
85 83 int ret = aclrtSetCurrentContext(m_algorthim_ctx);
86 84 if(ACL_ERROR_NONE != ret){
87 85 break;
... ...
src/ai_engine_module/face_det_ai_engine.cpp
... ... @@ -16,7 +16,6 @@ face_det_ai_engine::~face_det_ai_engine(){
16 16 clear();
17 17  
18 18 if(m_algorthim_ctx){
19   - aclrtSetDevice(m_devId);
20 19 aclrtDestroyContext(m_algorthim_ctx);
21 20 }
22 21 }
... ... @@ -27,7 +26,6 @@ int face_det_ai_engine::init_ai_engine(const facedet_ai_engine_param &ai_param/*
27 26  
28 27 m_devId = ai_param.sdk_param.devId;
29 28  
30   - ACL_CALL(aclrtSetDevice(m_devId), ACL_ERROR_NONE, -1);
31 29 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_ERROR_NONE, -1);
32 30  
33 31 return fd_init(&handle, ai_param.sdk_param);
... ... @@ -42,7 +40,6 @@ int face_det_ai_engine::ai_engine_process_batch(std::vector<std::string> &task_i
42 40 return 0;
43 41 }
44 42  
45   - aclrtSetDevice(m_devId);
46 43 int ret = aclrtSetCurrentContext(m_algorthim_ctx);
47 44 if(ACL_ERROR_NONE != ret){
48 45 return 0;
... ...
src/ai_engine_module/motocycle_hs_process.cpp
... ... @@ -99,7 +99,6 @@ namespace ai_engine_module
99 99 param.max_batch = 8;
100 100  
101 101 m_devId = param.devId;
102   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
103 102 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
104 103  
105 104 int status;
... ...
src/ai_engine_module/motocycle_phone_process.cpp
... ... @@ -102,7 +102,6 @@ namespace ai_engine_module
102 102 param.max_batch = 8;
103 103  
104 104 m_devId = param.devId;
105   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
106 105 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
107 106  
108 107 int status;
... ...
src/ai_engine_module/motocycle_refit_phone_process.cpp
... ... @@ -117,7 +117,6 @@ namespace ai_engine_module
117 117 hcp_param.max_batch = 8;
118 118  
119 119 m_devId = gpu_id;
120   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
121 120 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
122 121  
123 122 int status;
... ...
src/ai_engine_module/motocycle_refit_process.cpp
... ... @@ -103,7 +103,6 @@ namespace ai_engine_module
103 103 param.max_batch = 8;
104 104  
105 105 m_devId = param.devId;
106   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
107 106 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
108 107  
109 108 int status;
... ...
src/ai_engine_module/road_seg_3cls_statistics.cpp
... ... @@ -213,7 +213,6 @@ int Road3clsSegProcess::init(int gpu_id, string models_dir) {
213 213 param.devId = gpu_id;
214 214  
215 215 m_devId = param.devId;
216   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
217 216 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
218 217  
219 218 int ret = rs3cls_init(&m_seg_handle, param);
... ...
src/ai_engine_module/road_seg_correlation_algor.cpp
... ... @@ -545,7 +545,6 @@ namespace ai_engine_module
545 545 param.devId = gpu_id;*/
546 546  
547 547 m_devId = gpu_id;
548   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
549 548 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
550 549  
551 550 /*int status;
... ...
src/ai_engine_module/road_seg_statistics.cpp
... ... @@ -239,7 +239,6 @@ int RoadSegProcess::init(int gpu_id, string models_dir) {
239 239 param.devId = gpu_id;
240 240  
241 241 m_devId = param.devId;
242   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
243 242 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
244 243  
245 244 int ret = rs_init(&m_seg_handle, param);
... ...
src/ai_engine_module/road_seg_statistics.cpp.old
... ... @@ -241,7 +241,6 @@ int RoadSegProcess::init(int gpu_id, string models_dir) {
241 241 param.devId = gpu_id;
242 242  
243 243 m_devId = param.devId;
244   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
245 244 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
246 245  
247 246 int ret = rs_init(&m_seg_handle, param);
... ...
src/ai_engine_module/traffic_light_process.cpp
... ... @@ -281,7 +281,6 @@ namespace ai_engine_module
281 281 param.max_batch = 8;
282 282  
283 283 m_devId = param.devId;
284   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
285 284 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
286 285  
287 286 int status;
... ...
src/ai_engine_module/tricycle_manned_process.cpp
... ... @@ -47,7 +47,6 @@ namespace ai_engine_module
47 47 param.max_batch = 8;
48 48  
49 49 m_devId = param.devId;
50   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
51 50 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
52 51  
53 52 int status;
... ...
src/ai_engine_module/truck_manned_process.cpp
... ... @@ -131,7 +131,6 @@ namespace ai_engine_module
131 131 vparam.devId = gpu_id;
132 132  
133 133 m_devId = gpu_id;
134   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, -1);
135 134 ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_SUCCESS, -1);
136 135  
137 136 int status;
... ...
src/ai_platform/Makefile deleted
1   -# 各项目录
2   -LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
3   -DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
4   -OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
5   -SRC_DIR:=$(TOP_DIR)/$(MODULE)
6   -
7   -# 源文件以及中间目标文件和依赖文件
8   -SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
9   -OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
10   -DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
11   -
12   -# 自动生成头文件依赖选项
13   -DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
14   -
15   -DEFS = -DENABLE_DVPP_INTERFACE
16   -
17   -# 最终目标文件
18   -TARGET:=$(BUILD_DIR)/bin/demo
19   -
20   -
21   -include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/include
22   -
23   -lib_dir=-L/usr/lib \
24   - -L/usr/local/lib \
25   - -L/usr/local/Ascend/driver/lib64 \
26   - -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/atc/lib64\
27   - -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64 \
28   - -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64/stub \
29   - -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/lib64 \
30   - -L/usr/local/Ascend/driver/lib64/driver
31   -
32   -lib=-lacl_dvpp -lascendcl -lmmpa -lglog -lgflags -lpthread -lz -lacl_dvpp_mpi -lruntime -lascendalog -lc_sec -lmsprofiler -lgert -lge_executor -lge_common \
33   - -lgraph -lascend_protobuf -lprofapi -lerror_manager -lexe_graph -lregister -lplatform
34   -
35   -INCLUDE= -I $(TOP_DIR)/interface \
36   -
37   -LIBSPATH= -L $(BUILD_DIR)/interface/lib -l:interface.a \
38   - -L $(BUILD_DIR)/dvpp/lib -l:dvpp.a
39   -
40   -CXXFLAGS= -g -O0 -fPIC $(INCLUDE) $(include_dir) $(LIBSPATH) $(INCS) $(LIBS) $(lib_dir) $(lib) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
41   - # -DUNICODE -D_UNICODE
42   -
43   -# 默认最终目标
44   -.PHONY:all
45   -all:$(TARGET)
46   -
47   -# 生成最终目标
48   -$(TARGET): $(OBJS) | $(LIB_DIR)
49   - @echo -e "\e[32m""Linking static library $(TARGET)""\e[0m"
50   - @echo -e "$(CXX) -o $@ $^ $(DEPFLAGS) $(CXXFLAGS) $(MACROS)"
51   - $(CXX) -o $@ $^ $(DEPFLAGS) $(CXXFLAGS) $(MACROS)
52   -
53   -# 若没有lib目录则自动生成
54   -$(LIB_DIR):
55   - @mkdir -p $@
56   -
57   -# 生成中间目标文件
58   -$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
59   - @echo -e "\e[33m""Building object $@""\e[0m"
60   - @echo -e "$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<"
61   - $(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<
62   -
63   -# 若没有obj目录则自动生成
64   -$(OBJ_DIR):
65   - @mkdir -p $@
66   -
67   -# 若没有.dep目录则自动生成
68   -$(DEP_DIR):
69   - @mkdir -p $@
70   -
71   -# 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
72   -$(DEPS):
73   -
74   -# 引入中间目标文件头文件依赖关系
75   -include $(wildcard $(DEPS))
76   -
77   -# 直接删除组件build目录
78   -.PHONY:clean
79   -clean:
80   - @rm -rf $(BUILD_DIR)/$(MODULE)
src/ai_platform/MultiSourceProcess.cpp
... ... @@ -28,7 +28,7 @@
28 28  
29 29 #define WITH_FACE_DET_SS
30 30  
31   -#define AUTHORIZATION
  31 +// #define AUTHORIZATION
32 32  
33 33 #define productSN "51C4B28135604F649671727185949A91" //linux 通途抓拍引擎产品序列号
34 34  
... ... @@ -118,9 +118,6 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
118 118 vparam.max_batch = m_batch_size;
119 119 vparam.threshold = 0.4;
120 120 vparam.model_dir = models_dir;
121   -
122   - aclrtSetDevice(m_devId);
123   -
124 121 int ret = vpt_process.init(vparam);
125 122 if (ret < 0){
126 123 return ret;
... ... @@ -136,7 +133,6 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
136 133 LOG_FATAL("Init road_3clsseg failed");
137 134 return -1;
138 135 }
139   -
140 136  
141 137 //三轮车头肩检测
142 138 if (!tricycle_manned_.init(vptParam.gpuid, models_dir)) {
... ... @@ -697,7 +693,6 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
697 693 int CMultiSourceProcess::algorthim_process_thread(){
698 694 LOG_INFO("algorthim_process_thread start...");
699 695  
700   - ACL_CALL(aclrtSetDevice(m_devId), ACL_SUCCESS, 1);
701 696 aclrtContext ctx;
702 697 ACL_CALL(aclrtCreateContext(&ctx, m_devId), ACL_SUCCESS, 1);
703 698  
... ... @@ -753,9 +748,6 @@ int CMultiSourceProcess::algorthim_process_thread(){
753 748 }
754 749 }
755 750 }
756   -
757   -
758   -
759 751 }
760 752  
761 753 m_RgbDataList.pop_front();
... ...
src/ai_platform/vpt_proj.cpp1
... ... @@ -86,7 +86,6 @@ int main(){
86 86 param.isTrk = false;
87 87  
88 88 ACL_CALL(aclInit(nullptr), ACL_ERROR_NONE, 1);
89   - ACL_CALL(aclrtSetDevice(param.devId), ACL_ERROR_NONE, 1);
90 89 aclrtContext ctx;
91 90 ACL_CALL(aclrtCreateContext(&ctx, param.devId), ACL_ERROR_NONE, 1);
92 91  
... ...
src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -332,18 +332,6 @@ int DvppDecoder::getVdecType(int videoType, int profile)
332 332 post_decoded_cbk = cfg.post_decoded_cbk;
333 333  
334 334 do{
335   - aclError ret = aclrtSetDevice(m_dvpp_deviceId);
336   - if(ret != ACL_ERROR_NONE){
337   - LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
338   - break;
339   - }
340   -
341   - ret = aclrtCreateContext(&m_context, m_dvpp_deviceId);
342   - if (ret != ACL_ERROR_NONE) {
343   - LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
344   - break;
345   - }
346   -
347 335 // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
348 336 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
349 337 m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
... ... @@ -446,9 +434,9 @@ static int snap_count = 0;
446 434  
447 435 DeviceMemory* DvppDecoder::snapshot(){
448 436  
449   - int ret = aclrtSetCurrentContext(m_context);
  437 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
450 438 if(ret != ACL_ERROR_NONE){
451   - LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
  439 + LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
452 440 return nullptr;
453 441 }
454 442  
... ... @@ -477,6 +465,12 @@ DeviceMemory* DvppDecoder::snapshot(){
477 465 break;
478 466 }
479 467  
  468 + ret = aclrtResetDevice(m_dvpp_deviceId);
  469 + if(ret != ACL_ERROR_NONE){
  470 + LOG_ERROR("[{}]-aclrtResetDevice failed !", m_dec_name);
  471 + return nullptr;
  472 + }
  473 +
480 474 return snapshot_mem;
481 475 }
482 476  
... ... @@ -521,17 +515,11 @@ void DvppDecoder::read_thread() {
521 515 this
522 516 );
523 517  
524   - aclrtContext ctx = nullptr;
  518 + CHECK_AND_RETURN_NOVALUE(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed!");
  519 +
525 520 aclvdecChannelDesc *vdecChannelDesc = nullptr;
526 521  
527 522 do {
528   - CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
529   - int ret = aclrtSetCurrentContext(m_context);
530   - if(ret != ACL_ERROR_NONE){
531   - LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
532   - break;
533   - }
534   -
535 523 vdecChannelDesc = aclvdecCreateChannelDesc();
536 524 if (vdecChannelDesc == nullptr) {
537 525 LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
... ... @@ -621,16 +609,18 @@ void DvppDecoder::read_thread() {
621 609 if(nSended < 0) {
622 610 // 执行出错,强行结束整个任务
623 611 m_bRunning=false;
  612 + av_packet_free(&pkt);
  613 + pkt = nullptr;
624 614 break;
625 615 }
626 616  
627 617 #ifdef USE_VILLAGE
628 618 m_recoderManager.cache_pkt(pkt, frame_nb, m_dec_name);
629 619 #endif
630   - } else {
631   - av_packet_free(&pkt);
632   - pkt = nullptr;
633   - }
  620 + }
  621 +
  622 + av_packet_free(&pkt);
  623 + pkt = nullptr;
634 624 }
635 625  
636 626 if (vdecChannelDesc) {
... ... @@ -638,7 +628,7 @@ void DvppDecoder::read_thread() {
638 628 }
639 629  
640 630 while(m_bRunning && m_decoded_data_queue.size() > 0) {
641   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
  631 + std::this_thread::sleep_for(std::chrono::milliseconds(15));
642 632 }
643 633  
644 634 } while (0);
... ... @@ -649,6 +639,8 @@ void DvppDecoder::read_thread() {
649 639 vdecChannelDesc = nullptr;
650 640 }
651 641  
  642 + CHECK_NOT_RETURN(aclrtResetDevice(m_dvpp_deviceId), "aclrtResetDevice failed");
  643 +
652 644 m_bRunning=false;
653 645  
654 646 m_bExitReportThd = true;
... ... @@ -758,15 +750,8 @@ int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, uns
758 750  
759 751 void DvppDecoder::doProcessReport(){
760 752  
761   - aclError ret = aclrtSetDevice(m_dvpp_deviceId);
762   - if(ret != ACL_ERROR_NONE){
763   - // cout << "aclrtSetDevice failed" << endl;
764   - LOG_ERROR("aclrtSetDevice failed !");
765   - return ;
766   - }
767   -
768 753 aclrtContext ctx;
769   - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  754 + aclError ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
770 755 if (ret != ACL_ERROR_NONE) {
771 756 // cout << "aclrtCreateContext failed " << endl;
772 757 LOG_ERROR("aclrtCreateContext failed !");
... ... @@ -798,7 +783,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
798 783  
799 784 m_out_count++;
800 785  
801   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  786 + CHECK_AND_RETURN_NOVALUE(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
802 787  
803 788 void *inputDataDev = acldvppGetStreamDescData(input);
804 789 acldvppFree(inputDataDev);
... ... @@ -814,7 +799,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
814 799 do{
815 800 int ret = acldvppGetPicDescRetCode(output);
816 801 if(ret != ACL_ERROR_NONE){
817   - LOG_ERROR("[{}]- decode result error, retCode:{} ", m_dec_name, ret);
  802 + LOG_WARN("[{}]- decode result error, retCode:{} ", m_dec_name, ret);
818 803 acldvppFree(outputDataDev);
819 804 outputDataDev = nullptr;
820 805 break;
... ... @@ -870,8 +855,10 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
870 855 }
871 856 }while(0);
872 857  
873   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
874   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  858 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  859 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  860 +
  861 + CHECK_NOT_RETURN(aclrtResetDevice(m_dvpp_deviceId), "aclrtResetDevice failed");
875 862 }
876 863  
877 864 bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
... ... @@ -943,14 +930,6 @@ void DvppDecoder::display_thread() {
943 930 }
944 931  
945 932 void DvppDecoder::release_dvpp(){
946   - if(m_context){
947   - aclError ret = aclrtDestroyContext(m_context);
948   - if(ret != ACL_ERROR_NONE){
949   - LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
950   - }
951   - m_context = nullptr;
952   - }
953   -
954 933 if(m_dvpp_channel >= 0){
955 934 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
956 935 pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
... ...
src/decoder/dvpp/DvppDecoder.h
... ... @@ -117,7 +117,6 @@ private:
117 117 // 解码
118 118 int m_dvpp_deviceId {-1};
119 119 int m_dvpp_channel {-1};
120   - aclrtContext m_context{nullptr};
121 120 acldvppStreamFormat m_enType;
122 121  
123 122 const void * m_postDecArg {nullptr};
... ...
src/decoder/dvpp/DvppRtpDecoder.cpp
... ... @@ -185,18 +185,6 @@ int DvppRtpDecoder::getVdecType(int videoType, int profile)
185 185 post_decoded_cbk = cfg.post_decoded_cbk;
186 186  
187 187 do{
188   - aclError ret = aclrtSetDevice(m_dvpp_deviceId);
189   - if(ret != ACL_ERROR_NONE){
190   - LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
191   - break;
192   - }
193   -
194   - ret = aclrtCreateContext(&m_context, m_dvpp_deviceId);
195   - if (ret != ACL_ERROR_NONE) {
196   - LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
197   - break;
198   - }
199   -
200 188 // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
201 189 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
202 190 m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
... ... @@ -311,9 +299,9 @@ static int snap_count = 0;
311 299  
312 300 DeviceMemory* DvppRtpDecoder::snapshot(){
313 301  
314   - int ret = aclrtSetCurrentContext(m_context);
  302 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
315 303 if(ret != ACL_ERROR_NONE){
316   - LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
  304 + LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
317 305 return nullptr;
318 306 }
319 307  
... ... @@ -342,6 +330,12 @@ DeviceMemory* DvppRtpDecoder::snapshot(){
342 330 break;
343 331 }
344 332  
  333 + ret = aclrtResetDevice(m_dvpp_deviceId);
  334 + if(ret != ACL_ERROR_NONE){
  335 + LOG_ERROR("[{}]-aclrtResetDevice failed !", m_dec_name);
  336 + return nullptr;
  337 + }
  338 +
345 339 return snapshot_mem;
346 340 }
347 341  
... ... @@ -535,17 +529,11 @@ void DvppRtpDecoder::read_thread() {
535 529 return;
536 530 }
537 531  
538   - aclrtContext ctx = nullptr;
  532 + CHECK_AND_RETURN_NOVALUE(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed!");
  533 +
539 534 aclvdecChannelDesc *vdecChannelDesc = nullptr;
540 535  
541 536 do {
542   - CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
543   - int ret = aclrtSetCurrentContext(m_context);
544   - if(ret != ACL_ERROR_NONE){
545   - LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name);
546   - break;
547   - }
548   -
549 537 vdecChannelDesc = aclvdecCreateChannelDesc();
550 538 if (vdecChannelDesc == nullptr) {
551 539 LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
... ... @@ -624,14 +612,11 @@ void DvppRtpDecoder::read_thread() {
624 612  
625 613 #ifdef USE_VILLAGE
626 614 m_recoderManager.cache_pkt(pkt, frame_nb, m_dec_name);
627   - #else
628   - av_packet_free(&pkt);
629   - pkt = nullptr;
630 615 #endif
631   - } else {
632   - av_packet_free(&pkt);
633   - pkt = nullptr;
634 616 }
  617 +
  618 + av_packet_free(&pkt);
  619 + pkt = nullptr;
635 620 }
636 621  
637 622 if (vdecChannelDesc) {
... ... @@ -751,15 +736,8 @@ int DvppRtpDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt,
751 736  
752 737 void DvppRtpDecoder::doProcessReport(){
753 738  
754   - aclError ret = aclrtSetDevice(m_dvpp_deviceId);
755   - if(ret != ACL_ERROR_NONE){
756   - // cout << "aclrtSetDevice failed" << endl;
757   - LOG_ERROR("aclrtSetDevice failed !");
758   - return ;
759   - }
760   -
761 739 aclrtContext ctx;
762   - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  740 + aclError ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
763 741 if (ret != ACL_ERROR_NONE) {
764 742 // cout << "aclrtCreateContext failed " << endl;
765 743 LOG_ERROR("aclrtCreateContext failed !");
... ... @@ -851,8 +829,10 @@ void DvppRtpDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc
851 829 }
852 830 }while(0);
853 831  
854   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
855   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  832 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  833 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  834 +
  835 + CHECK_NOT_RETURN(aclrtResetDevice(m_dvpp_deviceId), "aclrtResetDevice failed");
856 836 }
857 837  
858 838 bool DvppRtpDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
... ... @@ -894,13 +874,6 @@ DvppDataMemory* DvppRtpDecoder::GetFrame() {
894 874 }
895 875  
896 876 void DvppRtpDecoder::release_dvpp(){
897   - if(m_context){
898   - aclError ret = aclrtDestroyContext(m_context);
899   - if(ret != ACL_ERROR_NONE){
900   - LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
901   - }
902   - m_context = nullptr;
903   - }
904 877  
905 878 if(m_dvpp_channel >= 0){
906 879 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
... ...
src/decoder/dvpp/DvppSourceManager.cpp
... ... @@ -20,30 +20,6 @@ DvppSourceManager::~DvppSourceManager()
20 20 // aclFinalize();
21 21 }
22 22  
23   -aclrtContext DvppSourceManager::getContext(int devId)
24   -{
25   - aclrtContext ctx = ctxMap[devId];
26   - if (ctx == nullptr)
27   - {
28   - // 初始化硬件解码器
29   - aclError ret = aclrtSetDevice(devId);
30   - if(ret != ACL_ERROR_NONE){
31   - // cout << "aclrtSetDevice failed" << endl;
32   - LOG_ERROR("aclrtSetDevice failed !");
33   - return nullptr;
34   - }
35   -
36   - ret = aclrtCreateContext(&ctx, devId);
37   - if (ret != ACL_ERROR_NONE) {
38   - // cout << "aclrtCreateContext failed " << endl;
39   - LOG_ERROR("aclrtCreateContext failed !");
40   - return nullptr;
41   - }
42   - ctxMap[devId] = ctx;
43   - }
44   - return ctx;
45   -}
46   -
47 23 int DvppSourceManager::getChannel(int devId){
48 24 // channel 最大值暂定为32, 华为没有接口获取最大channel,只有文档说明
49 25 for(int iChannel = 0; iChannel < 32; iChannel++){
... ...
src/decoder/dvpp/DvppSourceManager.h
... ... @@ -16,8 +16,6 @@ public:
16 16 return singleton;
17 17 }
18 18  
19   - aclrtContext getContext(int devId);
20   -
21 19 int getChannel(int devId);
22 20 void releaseChannel(int devId, int channel);
23 21  
... ...
src/decoder/dvpp/DvppStreamDecoder.cpp
... ... @@ -67,17 +67,6 @@ bool DvppStreamDecoder::Init(FFDecConfig cfg) {
67 67 m_deviceId = atoi(cfg.gpuid.c_str());
68 68  
69 69 do{
70   - aclError ret = aclrtSetDevice(m_deviceId);
71   - if(ret != ACL_ERROR_NONE){
72   - LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
73   - return false;
74   - }
75   -
76   - ret = aclrtCreateContext(&m_context, m_deviceId);
77   - if (ret != ACL_ERROR_NONE) {
78   - LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
79   - return false;
80   - }
81 70  
82 71 // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
83 72 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
... ... @@ -104,14 +93,6 @@ bool DvppStreamDecoder::Init(FFDecConfig cfg) {
104 93  
105 94 void DvppStreamDecoder::release_dvpp(){
106 95  
107   - if(m_context){
108   - aclError ret = aclrtDestroyContext(m_context);
109   - if(ret != ACL_ERROR_NONE){
110   - LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
111   - }
112   - m_context = nullptr;
113   - }
114   -
115 96 if(m_dvpp_channel >= 0){
116 97 DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
117 98 pSrcMgr->releaseChannel(m_deviceId, m_dvpp_channel);
... ... @@ -138,13 +119,6 @@ int DvppStreamDecoder::getVdecType(int videoType)
138 119  
139 120 void DvppStreamDecoder::doProcessReport(){
140 121  
141   - aclError ret = aclrtSetDevice(m_deviceId);
142   - if(ret != ACL_ERROR_NONE){
143   - // cout << "aclrtSetDevice failed" << endl;
144   - LOG_ERROR("aclrtSetDevice failed !");
145   - return ;
146   - }
147   -
148 122 aclrtContext ctx;
149 123 ret = aclrtCreateContext(&ctx, m_deviceId);
150 124 if (ret != ACL_ERROR_NONE) {
... ... @@ -178,7 +152,7 @@ void DvppStreamDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicD
178 152  
179 153 m_out_count++;
180 154  
181   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  155 + CHECK_AND_RETURN_NOVALUE(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
182 156  
183 157 void *inputDataDev = acldvppGetStreamDescData(input);
184 158 acldvppFree(inputDataDev);
... ... @@ -261,8 +235,10 @@ void DvppStreamDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicD
261 235 }
262 236 }while(0);
263 237  
264   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
265   - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  238 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  239 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  240 +
  241 + CHECK_NOT_RETURN(aclrtResetDevice(m_dvpp_deviceId), "aclrtResetDevice failed");
266 242 }
267 243  
268 244 DvppDataMemory* DvppStreamDecoder::GetFrame() {
... ...
src/decoder/dvpp/FFRecoder.cpp
  1 +// FFRecoder.cpp
1 2 #include "FFRecoder.h"
2   -
3 3 #include <tuple>
4 4 #include <array>
5 5 #include <vector>
6 6  
  7 +extern "C" {
  8 +#include <libavcodec/avcodec.h>
  9 +#include <libavformat/avformat.h>
  10 +#include <libavutil/opt.h>
  11 +#include <libavutil/timestamp.h>
  12 +#include <libavutil/imgutils.h>
  13 +#include <libswscale/swscale.h>
  14 +}
  15 +
7 16  
8 17 FFRecoder::FFRecoder()
9 18 :width_{},
... ... @@ -14,20 +23,17 @@ FFRecoder::FFRecoder()
14 23 codec_ctx_{ nullptr },
15 24 fmt_ctx_{ nullptr },
16 25 out_stream_{ nullptr },
17   - yuv_frame_{ nullptr },
18   - img_convert_ctx{nullptr}
  26 + yuv_frame_{ nullptr }
19 27 {
20   - bFirstFrame = true;
21   - last_src_pts = 0;
22   - last_pts = 0;
23 28 }
24 29  
25 30 FFRecoder::~FFRecoder()
26 31 {
  32 + uninit();
27 33 }
28 34  
29 35  
30   -bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx, const char* outfile_name)
  36 +bool FFRecoder::init(int w, int h, int fps, int bit_rate, const char* outfile_name)
31 37 {
32 38 uninit();
33 39  
... ... @@ -36,30 +42,32 @@ bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx,
36 42 y_size_ = w * h;
37 43 uv_size_ = y_size_ / 4;
38 44  
  45 + m_fps = fps;
  46 +
39 47 // [1] 创建解码器
40   - const AVCodec* encoder = avcodec_find_encoder(AV_CODEC_ID_HEVC);
  48 + const AVCodec* encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
41 49 if (!encoder) {
42   - LOG_ERROR("Find encoder AV_CODEC_ID_H264 failed!");
  50 + fprintf(stderr, "Find encoder AV_CODEC_ID_H264 failed!\n");
43 51 return false;
44 52 }
45 53 // 获取解码器上下文
46 54 codec_ctx_ = avcodec_alloc_context3(encoder);
47 55 if (!codec_ctx_) {
48   - LOG_ERROR("Alloc context for encoder contx failed!");
  56 + fprintf(stderr, "Alloc context for encoder contx failed!\n");
49 57 return false;
50 58 }
51 59 // 设置解码器上下文参数
52   - codec_ctx_->bit_rate = avctx->bit_rate;
  60 + codec_ctx_->bit_rate = bit_rate;
53 61 codec_ctx_->width = width_;
54 62 codec_ctx_->height = height_;
55   - codec_ctx_->time_base = time_base;
56   - codec_ctx_->gop_size = avctx->gop_size;
57   - codec_ctx_->max_b_frames = avctx->max_b_frames;
  63 + codec_ctx_->time_base = AVRational{ 1, fps };
  64 + codec_ctx_->gop_size = 50;
  65 + codec_ctx_->max_b_frames = 0;
58 66 codec_ctx_->pix_fmt = AV_PIX_FMT_YUV420P;
59 67 codec_ctx_->thread_count = 4;
60   - codec_ctx_->qmin = avctx->qmin;
61   - codec_ctx_->qmax = avctx->qmax;
62   - codec_ctx_->qcompress = avctx->qcompress;
  68 + codec_ctx_->qmin = 10;
  69 + codec_ctx_->qmax = 51;
  70 + codec_ctx_->qcompress = 0.6f;
63 71 codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
64 72  
65 73 av_opt_set(codec_ctx_->priv_data, "preset", "ultrafast", 0);
... ... @@ -68,7 +76,7 @@ bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx,
68 76 // 打开解码器
69 77 int ret = avcodec_open2(codec_ctx_, encoder, nullptr);
70 78 if (ret < 0) {
71   - LOG_ERROR("Open encoder failed!");
  79 + fprintf(stderr, "Open encoder failed!\n");
72 80 return false;
73 81 }
74 82  
... ... @@ -80,7 +88,6 @@ bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx,
80 88 out_stream_->id = 0;
81 89 out_stream_->codecpar->codec_tag = 0;
82 90 avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_);
83   - out_stream_->time_base = { 1,30 };
84 91  
85 92 av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1);
86 93  
... ... @@ -93,119 +100,25 @@ bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx,
93 100 if (av_frame_get_buffer(yuv_frame_, 0) < 0) {
94 101 av_frame_free(&yuv_frame_);
95 102 yuv_frame_ = nullptr;
96   - LOG_ERROR("Frame get buffer failed!");
  103 + fprintf(stderr, "Frame get buffer failed!\n");
97 104 return false;
98 105 }
99 106  
100 107 // [5] 打开输出视频文件并写入视频头信息
101 108 if (avio_open(&fmt_ctx_->pb, outfile_name, AVIO_FLAG_WRITE) < 0) {
102   - LOG_ERROR("avio_open failed!");
  109 + fprintf(stderr, "avio_open failed!\n");
103 110 return false;
104 111 }
105 112 if (avformat_write_header(fmt_ctx_, nullptr) < 0) {
106   - LOG_ERROR("Write header failed!");
  113 + fprintf(stderr, "Write header failed!\n");
107 114 return false;
108 115 }
109 116  
110   - // 计算解码后原始数据所需缓冲区大小,并分配内存空间 Determine required buffer size and allocate buffer
111   - int numBytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, w, h, 1);
112   - out_buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
113   -
114   - //pFrameOut = av_frame_alloc();
115   - //av_image_fill_arrays(pFrameOut->data, pFrameOut->linesize, buffer, AV_PIX_FMT_YUV420P, w, h, 1);
116   -
117   - img_convert_ctx = sws_getContext(avctx->width, avctx->height, avctx->pix_fmt, w, h, AV_PIX_FMT_YUV420P,
118   - SWS_BICUBIC, nullptr, nullptr, nullptr);
119   -
120 117 return true;
121 118 }
122 119  
123   -bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfile_name) {
124   -
125   - const AVCodec* encoder = avcodec_find_encoder(avctx->codec_id);
126   - if (!encoder) {
127   - LOG_ERROR("Find encoder AV_CODEC_ID_H264 failed!");
128   - return false;
129   - }
130   - // 获取解码器上下文
131   - codec_ctx_ = avcodec_alloc_context3(encoder);
132   - if (!codec_ctx_) {
133   - LOG_ERROR("Alloc context for encoder contx failed!");
134   - return false;
135   - }
136   -
137   - m_inStream = stream;
138   -
139   - int ret = avcodec_parameters_to_context(codec_ctx_, m_inStream->codecpar);
140   - if (ret < 0) {
141   - printf("Failed to copy in_stream codecpar to codec context\n");
142   - return false;
143   - }
144   -
145   - // avcodec_copy_context(codec_ctx_, avctx);
146   - codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
147   -
148   - // [2] 创建输出上下文
149   - avformat_alloc_output_context2(&fmt_ctx_, nullptr, nullptr, outfile_name);
150   -
151   - // [3] 添加输出视频流
152   - out_stream_ = avformat_new_stream(fmt_ctx_, nullptr);
153   -
154   - out_stream_->id = 0;
155   - out_stream_->codecpar->codec_tag = 0;
156   - avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_);
157   - // out_stream_->time_base = { 1,25 };
158   - out_stream_->time_base = stream->time_base;
159   - out_stream_->r_frame_rate = stream->r_frame_rate;
160   - out_stream_->avg_frame_rate = stream->r_frame_rate;
161   -
162   - codec_ctx_->time_base = out_stream_->time_base;
163   -
164   - av_opt_set(out_stream_->priv_data, "preset", "ultrafast", 0);
165   - av_opt_set(out_stream_->priv_data, "tune", "zerolatency", 0);
166   -
167   - // av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1);
168   -
169   - // [5] 打开输出视频文件并写入视频头信息
170   - if (avio_open(&fmt_ctx_->pb, outfile_name, AVIO_FLAG_WRITE) < 0) {
171   - LOG_ERROR("avio_open failed!");
172   - return false;
173   - }
174   - if (avformat_write_header(fmt_ctx_, nullptr) < 0) {
175   - LOG_ERROR("Write header failed!");
176   - return false;
177   - }
178   -
179   - return true;
180   -}
181   -
182   -void FFRecoder::release() {
183   - av_write_trailer(fmt_ctx_);
184   -
185   - avcodec_parameters_free(&fmt_ctx_->streams[0]->codecpar);
186   - av_freep(&fmt_ctx_->streams[0]);
187   -
188   - avio_close(fmt_ctx_->pb);
189   - av_free(fmt_ctx_);
190   - fmt_ctx_ = nullptr;
191   -}
192   -
193 120 void FFRecoder::uninit()
194 121 {
195   - //if (out_buffer) {
196   - // av_free(out_buffer);
197   - //}
198   -
199   - if (yuv_frame_) {
200   - av_frame_free(&yuv_frame_);
201   - yuv_frame_ = nullptr;
202   - }
203   -
204   - if (img_convert_ctx) {
205   - sws_freeContext(img_convert_ctx);
206   - img_convert_ctx = nullptr;
207   - }
208   -
209 122 if (fmt_ctx_) {
210 123 av_write_trailer(fmt_ctx_);
211 124 avio_close(fmt_ctx_->pb);
... ... @@ -219,6 +132,11 @@ void FFRecoder::uninit()
219 132 codec_ctx_ = nullptr;
220 133 }
221 134  
  135 + if (yuv_frame_) {
  136 + av_frame_free(&yuv_frame_);
  137 + yuv_frame_ = nullptr;
  138 + }
  139 +
222 140 width_ = 0;
223 141 height_ = 0;
224 142 y_size_ = 0;
... ... @@ -256,84 +174,13 @@ bool FFRecoder::write_yuv(const uint8_t* yuv_data)
256 174 return write_frame(yuv_frame_);
257 175 }
258 176  
259   -void FFRecoder::update_pts(AVPacket* pkt) {
260   - if (pkt->pts > 0) {
261   - if (bFirstFrame) {
262   - bFirstFrame = false;
263   - last_src_pts = pkt->pts;
264   - }
265   - int64_t pkt_pts = pkt->pts;
266   - pkt->pts = last_pts + (pkt_pts - last_src_pts);
267   - last_src_pts = pkt_pts;
268   - last_pts = pkt->pts;
269   - pkt->dts = pkt->pts;
270   - }
271   - else {
272   - if (bFirstFrame) {
273   - bFirstFrame = false;
274   - last_pts = 0;
275   - }
276   - pkt->pts = last_pts + 512;
277   - last_pts = pkt->pts;
278   - }
279   -
280   -}
281   -
282   -bool FFRecoder::write_pkt(AVPacket *pkt) {
283   - char errbuf[64]{ 0 };
284   -
285   - // av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base);
286   - // update_pts(pkt);
287   - // pkt->stream_index = out_stream_->index;
288   -
289   - if(pkt->pts==AV_NOPTS_VALUE) {
290   - // printf("frame_index:%d", frame_index);
291   - //Write PTS
292   - AVRational time_base1 = codec_ctx_->time_base;
293   - //Duration between 2 frames (us)
294   - int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(m_inStream->r_frame_rate);
295   - //Parameters
296   - pkt->pts = (double)(frame_index*calc_duration) / (double)(av_q2d(time_base1)*AV_TIME_BASE);
297   - pkt->dts = pkt->pts;
298   - pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE);
299   - frame_index++;
300   - }
301   - // Convert PTS/DTS
302   - pkt->pts = av_rescale_q_rnd(pkt->pts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
303   - pkt->dts = av_rescale_q_rnd(pkt->dts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
304   - pkt->duration = av_rescale_q(pkt->duration, codec_ctx_->time_base, out_stream_->time_base);
305   -
306   - pkt->pos = -1;
307   - pkt->stream_index = out_stream_->index;
308   - fmt_ctx_->duration += pkt->duration;
309   -
310   - // 将数据写入到输出流
311   - int ret = av_write_frame(fmt_ctx_, pkt);
312   - if (ret < 0) {
313   - LOG_ERROR("Error while writing output packet: {}", av_make_error_string(errbuf, sizeof(errbuf), ret));
314   - return false;
315   - }
316   - return true;
317   -}
318   -
319   -bool FFRecoder::write_frame(AVFrame* frame)
  177 +bool FFRecoder::write_frame(const AVFrame* frame)
320 178 {
321   - AVFrame *pFrameOut = nullptr;
322   - if (frame != nullptr && frame->format != AV_PIX_FMT_YUV420P) {
323   - pFrameOut = av_frame_clone(frame);
324   - pFrameOut->format = AV_PIX_FMT_YUV420P;
325   - av_image_fill_arrays(pFrameOut->data, pFrameOut->linesize, out_buffer, AV_PIX_FMT_YUV420P, frame->width, frame->height, 1);
326   - sws_scale(img_convert_ctx, (const unsigned char* const*)frame->data, frame->linesize, 0, frame->height, pFrameOut->data, pFrameOut->linesize);
327   - }
328   - else {
329   - pFrameOut = frame;
330   - }
331 179 char errbuf[64]{ 0 };
332 180 // 将帧数据发送到编码器
333   - int ret = avcodec_send_frame(codec_ctx_, pFrameOut);
334   - av_frame_free(&pFrameOut);
  181 + int ret = avcodec_send_frame(codec_ctx_, frame);
335 182 if (ret < 0) {
336   - LOG_ERROR("Error sending a frame to the encoder: {}", av_make_error_string(errbuf, sizeof(errbuf), ret));
  183 + fprintf(stderr, "Error sending a frame to the encoder: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
337 184 return false;
338 185 }
339 186  
... ... @@ -344,36 +191,85 @@ bool FFRecoder::write_frame(AVFrame* frame)
344 191 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
345 192 return true;
346 193 else if (ret < 0) {
347   - LOG_ERROR("Error encoding a frame: {}", av_make_error_string(errbuf, sizeof(errbuf), ret));
  194 + fprintf(stderr, "Error encoding a frame: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
348 195 return false;
349 196 }
350 197 // 将pts缩放到输出流的time_base上
351 198 av_packet_rescale_ts(&pkt, codec_ctx_->time_base, out_stream_->time_base);
352 199 pkt.stream_index = out_stream_->index;
353   - update_pts(&pkt);
354 200 // 将数据写入到输出流
355 201 ret = av_interleaved_write_frame(fmt_ctx_, &pkt);
356   - //ret = av_write_frame(fmt_ctx_, &pkt);
357 202 av_packet_unref(&pkt);
358 203 if (ret < 0) {
359   - LOG_ERROR("Error while writing output packet: {}", av_make_error_string(errbuf, sizeof(errbuf), ret));
  204 + fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
360 205 return false;
361 206 }
362   - /* av_interleaved_write_frame(fmt_ctx_, nullptr);
363   - avio_flush(fmt_ctx_->pb);*/
364 207 }
365 208  
366 209 return true;
367 210 }
368 211  
369   -bool FFRecoder::flush()
370   -{
371   - return write_frame(nullptr);
  212 +static double a2d(AVRational a) {
  213 + return a.den / a.num;
  214 +}
  215 +
  216 +void FFRecoder::calc_pkt_ts(AVPacket* pkt, int frame_index) {
  217 + //Duration between 2 frames (us)
  218 + int64_t calc_duration=(double)AV_TIME_BASE/m_fps;
  219 + //Parameters
  220 + pkt->pts=(double)(frame_index*calc_duration)/(double)(av_q2d(codec_ctx_->time_base)*AV_TIME_BASE);
  221 + pkt->dts=pkt->pts;
  222 + pkt->duration=(double)calc_duration/(double)(av_q2d(codec_ctx_->time_base)*AV_TIME_BASE);
372 223 }
373 224  
374   -bool FFRecoder::flush_pkt()
  225 +bool FFRecoder::write_pkt(AVPacket* new_pkt) {
  226 + frame_nb++;
  227 + calc_pkt_ts(new_pkt, frame_nb);
  228 + new_pkt->pts = av_rescale_q_rnd(new_pkt->pts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  229 + new_pkt->dts = av_rescale_q_rnd(new_pkt->dts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  230 + new_pkt->duration = av_rescale_q(new_pkt->duration, codec_ctx_->time_base, out_stream_->time_base);
  231 + new_pkt->stream_index = out_stream_->index;
  232 + // 将数据写入到输出流
  233 + int ret = av_interleaved_write_frame(fmt_ctx_, new_pkt);
  234 +
  235 + char errbuf[64]{ 0 };
  236 + if (ret < 0) {
  237 + fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
  238 + return false;
  239 + }
  240 +
  241 + return true;
  242 +}
  243 +
  244 +bool FFRecoder::write_pkt_data(const uint8_t* pkt_data, int pkt_size) {
  245 + AVPacket* new_pkt = av_packet_alloc();
  246 + av_new_packet(new_pkt, pkt_size);
  247 + memcpy(new_pkt->data, pkt_data, pkt_size);
  248 +
  249 + frame_nb++;
  250 + calc_pkt_ts(new_pkt, frame_nb);
  251 + new_pkt->pts = av_rescale_q_rnd(new_pkt->pts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  252 + new_pkt->dts = av_rescale_q_rnd(new_pkt->dts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  253 + new_pkt->duration = av_rescale_q(new_pkt->duration, codec_ctx_->time_base, out_stream_->time_base);
  254 + new_pkt->stream_index = out_stream_->index;
  255 + // 将数据写入到输出流
  256 + int ret = av_interleaved_write_frame(fmt_ctx_, new_pkt);
  257 +
  258 + av_packet_free(&new_pkt);
  259 + new_pkt = nullptr;
  260 +
  261 + char errbuf[64]{ 0 };
  262 + if (ret < 0) {
  263 + fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
  264 + return false;
  265 + }
  266 +
  267 + return true;
  268 +}
  269 +
  270 +bool FFRecoder::flush()
375 271 {
376   - return av_write_frame(fmt_ctx_, nullptr);
  272 + return write_frame(nullptr);
377 273 }
378 274  
379 275 bool FFRecoder::bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p)
... ... @@ -381,25 +277,30 @@ bool FFRecoder::bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_
381 277 // 分配转换上下文
382 278 thread_local std::tuple<int,int,int> params{ 0, 0, 0 };
383 279 thread_local std::unique_ptr<SwsContext, decltype(&sws_freeContext)> sws_context{ nullptr, &sws_freeContext };
384   -
385   - std::tuple<int, int, int> new_params{ width_, height_, av_image_get_linesize(AV_PIX_FMT_YUV420P, width_, 0) };
  280 +
  281 + std::tuple<int,int,int> new_params{ width_, height_, av_image_get_linesize(AV_PIX_FMT_YUV420P, width_, 0) };
386 282 if (!sws_context || params != new_params)
387 283 {
388 284 sws_context.reset(sws_getContext(width_, height_, AV_PIX_FMT_BGR24, width_, height_,
389 285 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr));
390 286 params = new_params;
391 287 }
  288 +
392 289 // 转换格式
393 290 const int stride = std::get<2>(params);//Y平面一行的数据长度
394   - //const int ret = sws_scale(sws_context.get(),
395   - // std::array<const uint8_t* const>{ buf_bgr }.data(),/* bgr数据只有一个平面 */
396   - // std::array{ width_ * 3 }.data(),/* BGR所以图像宽度*3 */
397   - // 0, height_,
398   - // std::array{ buf_420p, buf_420p + y_size_, buf_420p + y_size_ + uv_size_ }.data(),/* YUV三个平面的起始地址 */
399   - // std::array{ stride, stride / 2, stride / 2 }.data());/* YUV每个平面中一行的宽度 */
400   - const int rgba_linesize = width_ * 3;
401   - int yuv_linesize[3] = { stride, stride / 2, stride / 2 };
402   - int ret = sws_scale(sws_context.get(), (const uint8_t* const*)buf_bgr, &rgba_linesize, 0, height_, (uint8_t* const*)buf_420p, yuv_linesize);
403   -
404   - return 0;
  291 + const int ret = sws_scale(sws_context.get(),
  292 + &buf_bgr,/* bgr数据只有一个平面 */
  293 + std::array<int, 1> {width_ * 3}.data(),/* BGR所以图像宽度*3 */
  294 + 0, height_,
  295 + std::array<uint8_t* const, 3>{ buf_420p, buf_420p + y_size_, buf_420p + y_size_ + uv_size_ }.data(),/* YUV三个平面的起始地址 */
  296 + std::array<int, 3>{ stride, stride / 2, stride / 2 }.data()
  297 + );/* YUV每个平面中一行的宽度 */
  298 +
  299 + return ret >= 0;
  300 +}
  301 +
  302 +bool FFRecoder::close()
  303 +{
  304 + flush();
  305 + uninit();
405 306 }
406 307 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoder.h
1 1 #pragma once
2 2 #include <memory>
3 3  
4   -#include "depend_headers.h"
  4 +class AVFrame;
  5 +class AVStream;
  6 +class AVCodecContext;
  7 +class AVFormatContext;
  8 +class AVPacket;
5 9  
6 10 class FFRecoder
7 11 {
8 12 public:
9 13 FFRecoder();
10   - virtual ~FFRecoder();
  14 + ~FFRecoder();
11 15  
12   - bool init(int w, int h, AVRational time_base, AVCodecContext* avctx, const char* outfile_name);
  16 + bool init(int w, int h, int fps, int bit_rate, const char* outfile_name);
13 17 void uninit();
14 18 bool write_image(const uint8_t* bgr);
15 19 bool write_yuv(const uint8_t* yuv_data);
16   - bool write_frame(AVFrame* frame);
  20 + bool write_frame(const AVFrame* frame);
  21 + bool write_pkt(AVPacket* pkt);
  22 + bool write_pkt_data(const uint8_t* data, int size);
17 23 bool flush();
18   -
19   - // AVPacket 方式
20   - bool init(AVStream* stream, AVCodecContext* avctx, const char* outfile_name);
21   - bool write_pkt(AVPacket *pkt);
22   - bool flush_pkt();
23   - void release();
  24 + bool close();
24 25  
25 26 private:
26 27 bool bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p);
27   - void update_pts(AVPacket* pkt);
  28 + void calc_pkt_ts(AVPacket* pkt, int frame_index);
28 29  
29 30 private:
30 31 int width_;
... ... @@ -37,17 +38,7 @@ private:
37 38 AVStream* out_stream_;
38 39 AVFrame* yuv_frame_;
39 40  
40   - SwsContext * img_convert_ctx;
41   - //AVFrame* pFrameOut;
42   - uint8_t * out_buffer;
43   -
44   - bool bFirstFrame;
45   - int64_t last_src_pts;
46   - int64_t last_pts;
47   -
48   - int64_t first_pts;
49   - int64_t first_dts;
  41 + int m_fps{1};
50 42  
51   - int64_t frame_index{0};
52   - AVStream* m_inStream;
  43 + int frame_nb{0};
53 44 };
54 45 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoder2.cpp deleted
1   -// FFRecoder2.cpp
2   -#include "FFRecoder2.h"
3   -#include <tuple>
4   -#include <array>
5   -#include <vector>
6   -
7   -extern "C" {
8   -#include <libavcodec/avcodec.h>
9   -#include <libavformat/avformat.h>
10   -#include <libavutil/opt.h>
11   -#include <libavutil/timestamp.h>
12   -#include <libavutil/imgutils.h>
13   -#include <libswscale/swscale.h>
14   -}
15   -
16   -
17   -FFRecoder2::FFRecoder2()
18   - :width_{},
19   - height_{},
20   - y_size_{},
21   - uv_size_{},
22   - pts_{},
23   - codec_ctx_{ nullptr },
24   - fmt_ctx_{ nullptr },
25   - out_stream_{ nullptr },
26   - yuv_frame_{ nullptr }
27   -{
28   -}
29   -
30   -FFRecoder2::~FFRecoder2()
31   -{
32   - uninit();
33   -}
34   -
35   -
36   -bool FFRecoder2::init(int w, int h, int fps, int bit_rate, const char* outfile_name)
37   -{
38   - uninit();
39   -
40   - width_ = w;
41   - height_ = h;
42   - y_size_ = w * h;
43   - uv_size_ = y_size_ / 4;
44   -
45   - // [1] 创建解码器
46   - const AVCodec* encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
47   - if (!encoder) {
48   - fprintf(stderr, "Find encoder AV_CODEC_ID_H264 failed!\n");
49   - return false;
50   - }
51   - // 获取解码器上下文
52   - codec_ctx_ = avcodec_alloc_context3(encoder);
53   - if (!codec_ctx_) {
54   - fprintf(stderr, "Alloc context for encoder contx failed!\n");
55   - return false;
56   - }
57   - // 设置解码器上下文参数
58   - codec_ctx_->bit_rate = bit_rate;
59   - codec_ctx_->width = width_;
60   - codec_ctx_->height = height_;
61   - codec_ctx_->time_base = AVRational{ 1, fps };
62   - codec_ctx_->gop_size = 50;
63   - codec_ctx_->max_b_frames = 0;
64   - codec_ctx_->pix_fmt = AV_PIX_FMT_YUV420P;
65   - codec_ctx_->thread_count = 4;
66   - codec_ctx_->qmin = 10;
67   - codec_ctx_->qmax = 51;
68   - codec_ctx_->qcompress = 0.6f;
69   - codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
70   -
71   - //av_opt_set(codec_ctx_->priv_data, "preset", "ultrafast", 0);
72   - av_opt_set(codec_ctx_->priv_data, "tune", "zerolatency", 0);
73   -
74   - // 打开解码器
75   - int ret = avcodec_open2(codec_ctx_, encoder, nullptr);
76   - if (ret < 0) {
77   - fprintf(stderr, "Open encoder failed!\n");
78   - return false;
79   - }
80   -
81   - // [2] 创建输出上下文
82   - avformat_alloc_output_context2(&fmt_ctx_, nullptr, nullptr, outfile_name);
83   -
84   - // [3] 添加输出视频流
85   - out_stream_ = avformat_new_stream(fmt_ctx_, nullptr);
86   - out_stream_->id = 0;
87   - out_stream_->codecpar->codec_tag = 0;
88   - avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_);
89   -
90   - av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1);
91   -
92   - // 创建YUV格式帧
93   - yuv_frame_ = av_frame_alloc();
94   - yuv_frame_->format = AV_PIX_FMT_YUV420P;
95   - yuv_frame_->width = width_;
96   - yuv_frame_->height = height_;
97   - // 为创建的YUV帧分配内存
98   - if (av_frame_get_buffer(yuv_frame_, 0) < 0) {
99   - av_frame_free(&yuv_frame_);
100   - yuv_frame_ = nullptr;
101   - fprintf(stderr, "Frame get buffer failed!\n");
102   - return false;
103   - }
104   -
105   - // [5] 打开输出视频文件并写入视频头信息
106   - if (avio_open(&fmt_ctx_->pb, outfile_name, AVIO_FLAG_WRITE) < 0) {
107   - fprintf(stderr, "avio_open failed!\n");
108   - return false;
109   - }
110   - if (avformat_write_header(fmt_ctx_, nullptr) < 0) {
111   - fprintf(stderr, "Write header failed!\n");
112   - return false;
113   - }
114   -
115   - return true;
116   -}
117   -
118   -void FFRecoder2::uninit()
119   -{
120   - if (fmt_ctx_) {
121   - av_write_trailer(fmt_ctx_);
122   - avio_close(fmt_ctx_->pb);
123   - avformat_free_context(fmt_ctx_);
124   - fmt_ctx_ = nullptr;
125   - }
126   -
127   - if (codec_ctx_) {
128   - avcodec_close(codec_ctx_);
129   - avcodec_free_context(&codec_ctx_);
130   - codec_ctx_ = nullptr;
131   - }
132   -
133   - if (yuv_frame_) {
134   - av_frame_free(&yuv_frame_);
135   - yuv_frame_ = nullptr;
136   - }
137   -
138   - width_ = 0;
139   - height_ = 0;
140   - y_size_ = 0;
141   - uv_size_ = 0;
142   - pts_ = 0;
143   -}
144   -
145   -bool FFRecoder2::write_image(const uint8_t* bgr)
146   -{
147   - // 分配YUV格式数据的内存
148   - thread_local std::vector<uint8_t> yuv_data;
149   - if (yuv_data.size() != y_size_ * 3 / 2) {
150   - yuv_data.resize(y_size_ * 3 / 2);
151   - }
152   - // BGR格式转YUV格式
153   - bgr_to_yuv420p(bgr, yuv_data.data());
154   -
155   - return write_yuv(yuv_data.data());
156   -}
157   -
158   -bool FFRecoder2::write_yuv(const uint8_t* yuv_data)
159   -{
160   - //拷贝YUV数据到帧,由于帧数据存在内存对齐,故需逐行拷贝
161   - for (int i = 0; i < height_; i++) {
162   - memcpy(yuv_frame_->data[0] + i * yuv_frame_->linesize[0], yuv_data + width_ * i, width_);
163   - }
164   - const int uv_stride = width_ / 2;
165   - for (int i = 0; i < height_ / 2; i++) {
166   - memcpy(yuv_frame_->data[1] + i * yuv_frame_->linesize[1], yuv_data + y_size_ + uv_stride * i, uv_stride);
167   - memcpy(yuv_frame_->data[2] + i * yuv_frame_->linesize[2], yuv_data + y_size_ + uv_size_ + uv_stride * i, uv_stride);
168   - }
169   -
170   - yuv_frame_->pts = pts_++;
171   -
172   - return write_frame(yuv_frame_);
173   -}
174   -
175   -bool FFRecoder2::write_frame(const AVFrame* frame)
176   -{
177   - char errbuf[64]{ 0 };
178   - // 将帧数据发送到编码器
179   - int ret = avcodec_send_frame(codec_ctx_, frame);
180   - if (ret < 0) {
181   - fprintf(stderr, "Error sending a frame to the encoder: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
182   - return false;
183   - }
184   -
185   - while (true) {
186   - AVPacket pkt{ 0 };
187   - // 获取编码后的数据
188   - ret = avcodec_receive_packet(codec_ctx_, &pkt);
189   - if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
190   - return true;
191   - else if (ret < 0) {
192   - fprintf(stderr, "Error encoding a frame: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
193   - return false;
194   - }
195   - // 将pts缩放到输出流的time_base上
196   - av_packet_rescale_ts(&pkt, codec_ctx_->time_base, out_stream_->time_base);
197   - pkt.stream_index = out_stream_->index;
198   - // 将数据写入到输出流
199   - ret = av_interleaved_write_frame(fmt_ctx_, &pkt);
200   - av_packet_unref(&pkt);
201   - if (ret < 0) {
202   - fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
203   - return false;
204   - }
205   - }
206   -
207   - return true;
208   -}
209   -
210   -static double a2d(AVRational a) {
211   - return a.den / a.num;
212   -}
213   -
214   -bool FFRecoder2::write_pkt(AVPacket* pkt) {
215   - frame_nb++;
216   - pkt->duration = int(a2d(codec_ctx_->time_base));
217   - pkt->pts = frame_nb;
218   - // 将pts缩放到输出流的time_base上
219   - av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base);
220   - pkt->stream_index = out_stream_->index;
221   - // 将数据写入到输出流
222   - int ret = av_interleaved_write_frame(fmt_ctx_, pkt);
223   -
224   - char errbuf[64]{ 0 };
225   - if (ret < 0) {
226   - fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
227   - return false;
228   - }
229   -
230   - return true;
231   -}
232   -
233   -bool FFRecoder2::flush()
234   -{
235   - return write_frame(nullptr);
236   -}
237   -
238   -bool FFRecoder2::bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p)
239   -{
240   - // 分配转换上下文
241   - thread_local std::tuple<int,int,int> params{ 0, 0, 0 };
242   - thread_local std::unique_ptr<SwsContext, decltype(&sws_freeContext)> sws_context{ nullptr, &sws_freeContext };
243   -
244   - std::tuple<int,int,int> new_params{ width_, height_, av_image_get_linesize(AV_PIX_FMT_YUV420P, width_, 0) };
245   - if (!sws_context || params != new_params)
246   - {
247   - sws_context.reset(sws_getContext(width_, height_, AV_PIX_FMT_BGR24, width_, height_,
248   - AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr));
249   - params = new_params;
250   - }
251   -
252   - // 转换格式
253   - const int stride = std::get<2>(params);//Y平面一行的数据长度
254   - const int ret = sws_scale(sws_context.get(),
255   - &buf_bgr,/* bgr数据只有一个平面 */
256   - std::array<int, 1> {width_ * 3}.data(),/* BGR所以图像宽度*3 */
257   - 0, height_,
258   - std::array<uint8_t* const, 3>{ buf_420p, buf_420p + y_size_, buf_420p + y_size_ + uv_size_ }.data(),/* YUV三个平面的起始地址 */
259   - std::array<int, 3>{ stride, stride / 2, stride / 2 }.data()
260   - );/* YUV每个平面中一行的宽度 */
261   -
262   - return ret >= 0;
263   -}
264   -
265   -bool FFRecoder2::close()
266   -{
267   - flush();
268   - uninit();
269   -}
270 0 \ No newline at end of file
src/decoder/dvpp/FFRecoder2.h deleted
1   -#pragma once
2   -#include <memory>
3   -
4   -class AVFrame;
5   -class AVStream;
6   -class AVCodecContext;
7   -class AVFormatContext;
8   -class AVPacket;
9   -
10   -class FFRecoder2
11   -{
12   -public:
13   - FFRecoder2();
14   - ~FFRecoder2();
15   -
16   - bool init(int w, int h, int fps, int bit_rate, const char* outfile_name);
17   - void uninit();
18   - bool write_image(const uint8_t* bgr);
19   - bool write_yuv(const uint8_t* yuv_data);
20   - bool write_frame(const AVFrame* frame);
21   - bool write_pkt(AVPacket* pkt);
22   - bool flush();
23   - bool close();
24   -
25   -private:
26   - bool bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p);
27   -
28   -private:
29   - int width_;
30   - int height_;
31   - int y_size_;
32   - int uv_size_;
33   - int pts_;
34   - AVCodecContext* codec_ctx_;
35   - AVFormatContext* fmt_ctx_;
36   - AVStream* out_stream_;
37   - AVFrame* yuv_frame_;
38   -
39   - int frame_nb{0};
40   -};
41 0 \ No newline at end of file
src/decoder/dvpp/FFRecoderTaskManager.cpp
1 1 #include "FFRecoderTaskManager.h"
2 2 #include <chrono>
3 3  
4   -struct RecodeThreadParam {
5   - FFRecoderTaskManager* _this;
6   - RecodeParam param;
7   -};
8   -
9 4 static long get_cur_time() {
10 5  
11 6 chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
... ... @@ -69,68 +64,14 @@ bool FFRecoderTaskManager::init(int w, int h, int fps, int bit_rate) {
69 64 return true;
70 65 }
71 66  
72   -static AVPacket* packet_clone(AVPacket* pkt) {
73   - AVPacket *new_pkt = av_packet_alloc();
74   - av_init_packet( new_pkt );
75   - av_new_packet(new_pkt, pkt->size);
76   - memcpy(new_pkt->data, pkt->data, pkt->size);
77   - new_pkt->size = pkt->size;
78   - // new_pkt->pts = pkt->pts;
79   - // new_pkt->dts = pkt->dts;
80   - // new_pkt->stream_index = pkt->stream_index;
81   - // new_pkt->duration = pkt->duration;
82   - // new_pkt->pos = pkt->pos;
83   - // new_pkt->flags = pkt->flags;
84   - // av_copy_packet_side_data(new_pkt, pkt);
85   - return new_pkt;
86   -}
87   -
88   -static AVPacket* copy_packet(const AVPacket* src)
89   -{
90   - AVPacket* dst = av_packet_alloc(); // 分配内存
91   - if (!dst) {
92   - return NULL;
93   - }
94   -
95   - // 复制所有字段
96   - av_packet_ref(dst, src);
97   -
98   - // 复制音视频数据
99   - dst->data = (uint8_t*)av_malloc(src->size);
100   - memcpy(dst->data, src->data, src->size);
101   - dst->size = src->size;
102   - return dst;
103   -}
104   -
105 67 void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb, string dec_name){
106 68 if(m_bExit) {
107 69 // 任务退出了就不再缓存数据了
108 70 return;
109 71 }
110 72  
111   - // 考虑到一个AVPacket中的数据并不很大,为减少与解码模块的耦合度,方便管理,这里做一个clone
112   - // AVPacket *new_pkt = copy_packet(pkt);
113   -
114   - DataPacket* newDataPkt = new DataPacket();
115   - newDataPkt->pkt = pkt;
116   - newDataPkt->frame_nb = frame_nb;
117   -
118   - if(is_key_frame(pkt)){
119   - // 越来越大的值
120   - newDataPkt->isKeyFrame = true;
121   - LOG_INFO("[{}] - key frame_nb: {}", dec_name, frame_nb);
122   - } else {
123   - newDataPkt->isKeyFrame = false;
124   - }
125   -
126   - AVPacket* npkt = newDataPkt->pkt;
127   - if(npkt == nullptr) {
128   - return ;
129   - } else if (npkt->data == nullptr || npkt->size <= 0){
130   - return ;
131   - }
132   -
133 73 std::lock_guard<std::mutex> l_info(m_pkt_list_short_mtx);
  74 + DataPacket* newDataPkt = new DataPacket(pkt->data, pkt->size, frame_nb, is_key_frame(pkt));
134 75 m_pkt_list_short.push_back(newDataPkt);
135 76 }
136 77  
... ... @@ -277,20 +218,11 @@ void FFRecoderTaskManager::recode_thread() {
277 218 break;
278 219 }
279 220  
280   - auto it = m_pkt_list.begin();
281   - while (it != it_data) {
282   - DataPacket* dataPkt = m_pkt_list.front();
283   - delete dataPkt;
284   - dataPkt = nullptr;
285   - m_pkt_list.pop_front();
286   - it = m_pkt_list.begin();
287   - }
288   -
289 221 LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb);
290 222  
291 223 string file_name = recoderinfo.recoderPath;
292 224  
293   - FFRecoder2 ffrecoder;
  225 + FFRecoder ffrecoder;
294 226 bool bInit = ffrecoder.init(m_width, m_height, m_fps, m_bit_rate, file_name.c_str());
295 227 if (!bInit) {
296 228 LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb);
... ... @@ -308,16 +240,15 @@ void FFRecoderTaskManager::recode_thread() {
308 240 if(dataPkt->frame_nb > recoderinfo.frame_nb) {
309 241 break;
310 242 }
311   - AVPacket* pkt = dataPkt->pkt;
312   - if(pkt == nullptr) {
313   - LOG_ERROR("{} pkt is nullptr", recoderinfo.task_id);
314   - continue;
315   - } else if (pkt->data == nullptr || pkt->size <= 0){
316   - LOG_ERROR("{} pkt data is nullptr or size is {}", recoderinfo.task_id, pkt->size);
  243 +
  244 + if (dataPkt->pkt_data == nullptr || dataPkt->pkt_size <= 0){
  245 + LOG_ERROR("{} pkt data is nullptr or size is {}", recoderinfo.task_id, dataPkt->pkt_size);
317 246 continue;
318 247 }
319 248  
320   - ffrecoder.write_pkt(pkt);
  249 + // LOG_INFO("ref count: {}", av_buffer_get_ref_count(pkt->buf));
  250 +
  251 + ffrecoder.write_pkt_data(dataPkt->pkt_data, dataPkt->pkt_size);
321 252 count++;
322 253 end_frame_nb = (*it_save)->frame_nb;
323 254 }
... ...
src/decoder/dvpp/FFRecoderTaskManager.h
1   -#include "FFRecoder2.h"
  1 +#include "FFRecoder.h"
2 2  
3 3 #include "../../ai_platform/common_header.h"
4 4 #include "depend_headers.h"
... ... @@ -12,11 +12,6 @@
12 12  
13 13 using namespace std;
14 14  
15   -struct RecodeParam {
16   - AVRational time_base;
17   - RecoderInfo recoderInfo;
18   - AVCodecContext* avctx;
19   -};
20 15  
21 16 typedef std::function<bool(const char *msg)> mq_callback_t;
22 17  
... ... @@ -65,7 +60,7 @@ private:
65 60  
66 61 mq_callback_t mq_publish_func;
67 62  
68   - // FFRecoder2
  63 + // FFRecoder
69 64 int m_width;
70 65 int m_height;
71 66 int m_fps;
... ...
src/decoder/dvpp/depend_headers.h
... ... @@ -41,16 +41,28 @@ extern &quot;C&quot; {
41 41  
42 42  
43 43 struct DataPacket {
44   - AVPacket* pkt {nullptr};
  44 + uint8_t *pkt_data{nullptr};
  45 + int pkt_size{0};
45 46 unsigned long long frame_nb{0};
46 47 bool isKeyFrame{false};
47 48  
  49 + DataPacket(uint8_t *data, int size, unsigned long long frameNb, bool isKey) {
  50 + pkt_data = (uint8_t*) malloc(size);
  51 + memcpy(pkt_data, data, size);
  52 + pkt_size = size;
  53 + frame_nb = frameNb;
  54 + isKeyFrame = isKey;
  55 + }
  56 +
48 57 ~DataPacket(){
49   - if(pkt != nullptr) {
  58 + if(pkt_data != nullptr) {
50 59 // LOG_INFO("free frame_nb:{}", frame_nb);
51   - av_packet_free(&pkt);
52   - pkt = nullptr;
  60 + free(pkt_data);
  61 + pkt_data = nullptr;
53 62 }
  63 + pkt_size = 0;
  64 + frame_nb = 0;
  65 + isKeyFrame = false;
54 66 }
55 67 };
56 68  
... ...
src/decoder/gb28181/Makefile000 deleted
1   -# 各项目录
2   -LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
3   -DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
4   -OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
5   -SRC_DIR:=$(TOP_DIR)/$(MODULE)
6   -
7   -# 源文件以及中间目标文件和依赖文件
8   -SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
9   -OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
10   -DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
11   -
12   -# 自动生成头文件依赖选项
13   -DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
14   -
15   -JRTP_ROOT = $(THIRDPARTY_ROOT)/jrtp_export
16   -
17   -INCLUDE= -I $(TOP_DIR)/common/inc \
18   - -I $(TOP_DIR)/common/UtilNPP \
19   - -I $(TOP_DIR)/ \
20   - -I $(CUDA_ROOT)/include \
21   - -I $(JRTP_ROOT)/jrtplib/include/jrtplib3 \
22   - -I $(JRTP_ROOT)/jthread/include/jthread
23   -
24   -LIBSPATH= -L $(JRTP_ROOT)/jthread/lib -l:libjthread.a \
25   - -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a \
26   - -L $(CUDA_ROOT)/lib64 -lcuda -lcudart -lnvcuvid -lcurand -lcublas -lnvjpeg \
27   -
28   -
29   -CXXFLAGS= -g -O0 -fPIC $(INCLUDE) $(INCS) $(LIBS) $(LIBSPATH) $(MACROS) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl -Wwrite-strings
30   -
31   -# 最终目标文件
32   -TARGET:=$(LIB_DIR)/$(MODULE).a
33   -
34   -# 默认最终目标
35   -.PHONY:all
36   -all:$(TARGET)
37   -
38   -# 生成最终目标
39   -$(TARGET):$(OBJS) | $(LIB_DIR)
40   - @echo -e "\e[32m""Linking static library $(TARGET)""\e[0m"
41   - @echo -e "ar -rc $@ $^"
42   - @ar -rc $@ $^
43   -
44   -# 若没有lib目录则自动生成
45   -$(LIB_DIR):
46   - @mkdir -p $@
47   -
48   -# 生成中间目标文件
49   -$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
50   - @echo -e "\e[33m""Building object $@""\e[0m"
51   - @echo -e "$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<"
52   - @$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<
53   -
54   -# 若没有obj目录则自动生成
55   -$(OBJ_DIR):
56   - @mkdir -p $@
57   -
58   -# 若没有.dep目录则自动生成
59   -$(DEP_DIR):
60   - @mkdir -p $@
61   -
62   -# 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
63   -$(DEPS):
64   -
65   -# 引入中间目标文件头文件依赖关系
66   -include $(wildcard $(DEPS))
67   -
68   -# 直接删除组件build目录
69   -.PHONY:clean
70   -clean:
71   - @rm -rf $(BUILD_DIR)/$(MODULE)
src/decoder/interface/DecoderManager.cpp
... ... @@ -7,7 +7,7 @@
7 7  
8 8 #ifdef USE_DVPP
9 9 #include "../dvpp/DvppDecoderApi.h"
10   -#include "../gb28181/DvppGB28181Decoder2.h"
  10 +// #include "../gb28181/DvppGB28181Decoder2.h"
11 11 #endif
12 12  
13 13 #include "logger.hpp"
... ... @@ -61,7 +61,7 @@ AbstractDecoder* DecoderManager::createDecoder(MgrDecConfig config){
61 61 if(DECODER_TYPE_DVPP == config.dec_type){
62 62 dec = new DvppDecoderApi();
63 63 } else if(DECODER_TYPE_DVPP_GB28181 == config.dec_type){
64   - dec = new DvppGB28181Decoder2();
  64 + // dec = new DvppGB28181Decoder2();
65 65 }
66 66 #endif
67 67  
... ...
src/decoder/test_28181.cpp renamed to src/decoder/test_28181.cpp0
src/decoder/test_decoder.cpp.dvpp renamed to src/decoder/test_decoder.cpp
... ... @@ -207,22 +207,22 @@ void algorthim_process_thread(){
207 207 }
208 208  
209 209 void snap_shot_thread(){
210   - DecoderManager* pDecManager = DecoderManager::getInstance();
211   - while (true){
212   - if(m_bfinish){
213   - break;
214   - }
  210 + // DecoderManager* pDecManager = DecoderManager::getInstance();
  211 + // while (true){
  212 + // if(m_bfinish){
  213 + // break;
  214 + // }
215 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();
  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 222  
223   - vector<DeviceMemory*>().swap(vec_devMem);
  223 + // vector<DeviceMemory*>().swap(vec_devMem);
224 224  
225   - std::this_thread::sleep_for(std::chrono::milliseconds(600));
  225 + // std::this_thread::sleep_for(std::chrono::milliseconds(600));
226 226  
227   - }
  227 + // }
228 228 }
229 229 \ No newline at end of file
... ...
src/decoder/test_face.cpp1
... ... @@ -75,7 +75,6 @@ int main(){
75 75 string models_dir = ".";
76 76  
77 77 aclInit(nullptr);
78   - aclrtSetDevice(m_devId);
79 78  
80 79 // 人脸检测初始化
81 80 facedet_ai_engine_param fd_param;
... ... @@ -179,7 +178,6 @@ int main(){
179 178  
180 179 void algorthim_process_thread(){
181 180  
182   - aclrtSetDevice(m_devId);
183 181 aclrtCreateContext(&ctx, m_devId);
184 182  
185 183 while (true){
... ...
src/demo/demo.cpp
... ... @@ -1320,22 +1320,30 @@ void test_gpu(int gpuID){
1320 1320  
1321 1321 // }
1322 1322  
1323   - createTask(handle, algor_vec2, 0, false);
1324   - createTask(handle, algor_vec2, 2, false);
1325   - createTask(handle, algor_vec2, 0, false);
1326   - createTask(handle, algor_vec2, 2, false);
1327   - createTask(handle, algor_vec2, 0, false);
1328   - createTask(handle, algor_vec2, 2, false);
1329   - createTask(handle, algor_vec2, 0, false);
1330   - createTask(handle, algor_vec2, 2, false);
1331   - createTask(handle, algor_vec2, 0, false);
1332   - createTask(handle, algor_vec2, 2, false);
1333   - createTask(handle, algor_vec2, 0, false);
1334   - createTask(handle, algor_vec2, 2, false);
1335   -
1336   - while (getchar() != 'q');
1337   -
1338   - /*
  1323 + // createTask(handle, algor_vec2, 0, false);
  1324 + // createTask(handle, algor_vec2, 2, false);
  1325 + // createTask(handle, algor_vec2, 0, false);
  1326 + // createTask(handle, algor_vec2, 2, false);
  1327 + // createTask(handle, algor_vec2, 0, false);
  1328 + // createTask(handle, algor_vec2, 2, false);
  1329 + // createTask(handle, algor_vec2, 0, false);
  1330 + // createTask(handle, algor_vec2, 2, false);
  1331 + // createTask(handle, algor_vec2, 0, false);
  1332 + // createTask(handle, algor_vec2, 2, false);
  1333 + // createTask(handle, algor_vec2, 0, false);
  1334 + // createTask(handle, algor_vec2, 2, false);
  1335 +
  1336 + // createTask(handle, algor_vec2, 4, false);
  1337 + // createTask(handle, algor_vec2, 5, false);
  1338 + // createTask(handle, algor_vec2, 6, false);
  1339 + // createTask(handle, algor_vec2, 7, false);
  1340 + // createTask(handle, algor_vec2, 8, false);
  1341 + // createTask(handle, algor_vec2, 9, false);
  1342 + // createTask(handle, algor_vec2, 10, false);
  1343 +
  1344 + // while (getchar() != 'q');
  1345 +
  1346 +
1339 1347 char ch = 'a';
1340 1348 while (ch != 'q') {
1341 1349 ch = getchar();
... ... @@ -1343,12 +1351,12 @@ void test_gpu(int gpuID){
1343 1351 {
1344 1352 case 'a':
1345 1353 createTask(handle, algor_vec2, 4, false);
1346   - createTask(handle, algor_vec2, 5, false);
1347   - createTask(handle, algor_vec2, 6, false);
1348   - createTask(handle, algor_vec2, 7, false);
1349   - createTask(handle, algor_vec2, 8, false);
1350   - createTask(handle, algor_vec2, 9, false);
1351   - createTask(handle, algor_vec2, 10, false);
  1354 + // createTask(handle, algor_vec2, 5, false);
  1355 + // createTask(handle, algor_vec2, 6, false);
  1356 + // createTask(handle, algor_vec2, 7, false);
  1357 + // createTask(handle, algor_vec2, 8, false);
  1358 + // createTask(handle, algor_vec2, 9, false);
  1359 + // createTask(handle, algor_vec2, 10, false);
1352 1360 // createTask(handle, algor_vec2, 11, false);
1353 1361 // createTask(handle, algor_vec2, 12, false);
1354 1362 // createTask(handle, algor_vec2, 13, false);
... ... @@ -1365,7 +1373,7 @@ void test_gpu(int gpuID){
1365 1373 break;
1366 1374 }
1367 1375  
1368   - }*/
  1376 + }
1369 1377  
1370 1378 // finish_task(handle, (char*)task_id.data(), 0);
1371 1379  
... ... @@ -1508,12 +1516,12 @@ int main(int argc, char *argv[]) {
1508 1516 // int repeat_num = atoi(argv[3]);
1509 1517 // int gpuID = atoi(argv[4]);
1510 1518  
1511   - // test_gpu(0);
  1519 + test_gpu(0);
1512 1520 // test_gpu(1);
1513 1521 // test_gpu(2);
1514 1522 // test_gpu(3);
1515 1523  
1516   - test_dvpp28181(0);
  1524 + // test_dvpp28181(0);
1517 1525  
1518 1526 printf("Done.\n");
1519 1527  
... ...
src/test/test.cpp
... ... @@ -60,7 +60,6 @@ int main() {
60 60 void* handle = nullptr;
61 61 cout << "init start " << endl;
62 62 ACL_CALL(aclInit(nullptr), ACL_SUCCESS, SY_FAILED);
63   - ACL_CALL(aclrtSetDevice(param.devId), ACL_SUCCESS, SY_FAILED);
64 63 aclrtContext ctx;
65 64 ACL_CALL(aclrtCreateContext(&ctx, param.devId), ACL_SUCCESS, SY_FAILED);
66 65 aclrtStream stream = nullptr;
... ...