Commit 25a4a27747c9010d59f34e921f83f250f86f47ea

Authored by Hu Chunming
1 parent 7c962865

简化解码器线程,解决500小站上因为资源不足导致解码失败的问题

src/decoder/Makefile 100755 → 100644
1 XX = g++ 1 XX = g++
2 2
3 3
4 -PROJECT_ROOT= /opt/cmhu/vpt_ascend_arm 4 +PROJECT_ROOT= /home/cmhu/vpt_ascend_arm
5 5
6 DEPEND_DIR = $(PROJECT_ROOT)/bin 6 DEPEND_DIR = $(PROJECT_ROOT)/bin
7 SRC_ROOT = $(PROJECT_ROOT)/src 7 SRC_ROOT = $(PROJECT_ROOT)/src
8 8
9 -TARGET= $(PROJECT_ROOT)/bin/test_face 9 +TARGET= $(PROJECT_ROOT)/bin/test_dec
10 10
11 THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty 11 THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
12 SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release 12 SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release
13 OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv_4_1 13 OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv_4_1
14 JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release 14 JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release
15 FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release 15 FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release
16 -RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release  
17 16
18 -DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ 17 +DEFS = -DENABLE_DVPP_INTERFACE
19 18
20 include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ 19 include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
21 -I $(SPDLOG_ROOT)/include \ 20 -I $(SPDLOG_ROOT)/include \
@@ -23,7 +22,6 @@ include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ @@ -23,7 +22,6 @@ include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
23 -I $(OPENCV_ROOT)/include \ 22 -I $(OPENCV_ROOT)/include \
24 -I $(JSON_ROOT)/include \ 23 -I $(JSON_ROOT)/include \
25 -I $(FFMPEG_ROOT)/include \ 24 -I $(FFMPEG_ROOT)/include \
26 - -I $(RABBITMQ_CLIENT_ROOT)/include \  
27 25
28 lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ 26 lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
29 -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \ 27 -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \
@@ -31,28 +29,17 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ @@ -31,28 +29,17 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
31 -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \ 29 -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
32 -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \ 30 -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \
33 31
34 -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 \  
35 - -lplatform -lgraph_base -lqos_manager 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 -lregister -lge_common \
  33 + -lplatform -lqos_manager
36 34
37 -LIBS= -L $(SPDLOG_ROOT)/lib -l:libspdlog.a \  
38 - -L $(DEPEND_DIR) -lvpt_det_vdec -lsycheck -lface_det_vdec -lhs_tri_process -lhs_truck_process -lhs_motor_process\  
39 - -L $(OPENCV_ROOT)/lib -lopencv_world\  
40 - -L $(JSON_ROOT)/lib -ljsoncpp \  
41 - -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \  
42 - -L $(RABBITMQ_CLIENT_ROOT)/lib/aarch64-linux-gnu -lrabbitmq \ 35 +LIBS= -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
43 36
44 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 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
45 38
46 39
47 40
48 -SRCS:=$(wildcard $(SRC_ROOT)/ai_platform/*.cpp) \  
49 - $(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \ 41 +SRCS:=$(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \
50 $(wildcard $(SRC_ROOT)/decoder/dvpp/*.cpp) \ 42 $(wildcard $(SRC_ROOT)/decoder/dvpp/*.cpp) \
51 - $(wildcard $(SRC_ROOT)/ai_engine_module/sort/*.cpp) \  
52 - $(wildcard $(SRC_ROOT)/ai_engine_module/*.cpp) \  
53 - $(wildcard $(SRC_ROOT)/util/*.cpp) \  
54 - $(wildcard $(SRC_ROOT)/reprocessing_module/*.cpp) \  
55 - $(wildcard $(SRC_ROOT)/reprocessing_module/rbmq/*.cpp) \  
56 $(wildcard $(SRC_ROOT)/decoder/*.cpp) \ 43 $(wildcard $(SRC_ROOT)/decoder/*.cpp) \
57 44
58 OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS))) 45 OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
@@ -69,24 +56,6 @@ $(TARGET):$(OBJS) @@ -69,24 +56,6 @@ $(TARGET):$(OBJS)
69 %.o:$(SRC_ROOT)/decoder/interface/%.cpp 56 %.o:$(SRC_ROOT)/decoder/interface/%.cpp
70 $(XX) $(CXXFLAGS) -c $< 57 $(XX) $(CXXFLAGS) -c $<
71 58
72 -%.o:$(SRC_ROOT)/ai_platform/%.cpp  
73 - $(XX) $(CXXFLAGS) -c $<  
74 -  
75 -%.o:$(SRC_ROOT)/ai_engine_module/sort/%.cpp  
76 - $(XX) $(CXXFLAGS) -c $<  
77 -  
78 -%.o:$(SRC_ROOT)/ai_engine_module/%.cpp  
79 - $(XX) $(CXXFLAGS) -c $<  
80 -  
81 -%.o:$(SRC_ROOT)/util/%.cpp  
82 - $(XX) $(CXXFLAGS) -c $<  
83 -  
84 -%.o:$(SRC_ROOT)/reprocessing_module/%.cpp  
85 - $(XX) $(CXXFLAGS) -c $<  
86 -  
87 -%.o:$(SRC_ROOT)/reprocessing_module/rbmq/%.cpp  
88 - $(XX) $(CXXFLAGS) -c $<  
89 -  
90 %.o:$(SRC_ROOT)/decoder/%.cpp 59 %.o:$(SRC_ROOT)/decoder/%.cpp
91 $(XX) $(CXXFLAGS) -c $< 60 $(XX) $(CXXFLAGS) -c $<
92 61
src/decoder/dvpp/DvppDecoder.cpp
@@ -2,6 +2,17 @@ @@ -2,6 +2,17 @@
2 #include "DvppSourceManager.h" 2 #include "DvppSourceManager.h"
3 3
4 4
  5 +#define CHECK_AND_RETURN(ret, message) \
  6 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}
  7 +#define CHECK_NOT_RETURN(ret, message) \
  8 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
  9 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  10 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
  11 +#define CHECK_AND_BREAK(ret, message) \
  12 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
  13 +
  14 +
  15 +
5 struct Vdec_CallBack_UserData { 16 struct Vdec_CallBack_UserData {
6 uint64_t frameId; 17 uint64_t frameId;
7 unsigned long long frame_nb; 18 unsigned long long frame_nb;
@@ -15,6 +26,36 @@ struct Vdec_CallBack_UserData { @@ -15,6 +26,36 @@ struct Vdec_CallBack_UserData {
15 } 26 }
16 }; 27 };
17 28
  29 +
  30 +static long get_cur_time_ms() {
  31 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  32 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  33 + return tpMicro.time_since_epoch().count();
  34 +}
  35 +
  36 +static void *ReportThd(void *arg)
  37 +{
  38 + DvppDecoder *self = (DvppDecoder *)arg;
  39 + if(nullptr != self){
  40 + self->doProcessReport();
  41 + }
  42 + return (void *)0;
  43 +}
  44 +
  45 +static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
  46 +{
  47 + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
  48 + if(nullptr != userData){
  49 + DvppDecoder* self = userData->self;
  50 + if(self != nullptr){
  51 + self->doVdppVdecCallBack(input, output, userData->frame_nb);
  52 + }
  53 + delete userData;
  54 + userData = nullptr;
  55 + }
  56 +}
  57 +
  58 +
18 DvppDecoder::DvppDecoder(){ 59 DvppDecoder::DvppDecoder(){
19 m_read_thread = 0; 60 m_read_thread = 0;
20 m_cached_mem = nullptr; 61 m_cached_mem = nullptr;
@@ -137,6 +178,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ @@ -137,6 +178,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
137 break; 178 break;
138 } 179 }
139 180
  181 + int enType = getVdecType(codecpar->codec_id, codecpar->profile);
  182 + if(-1 == enType) {
  183 + break;
  184 + }
  185 + m_enType = static_cast<acldvppStreamFormat>(enType);
  186 +
140 int ret = av_bsf_alloc(filter, &h264bsfc); 187 int ret = av_bsf_alloc(filter, &h264bsfc);
141 if (ret < 0){ 188 if (ret < 0){
142 break; 189 break;
@@ -148,7 +195,14 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ @@ -148,7 +195,14 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
148 frame_width = codecpar->width; 195 frame_width = codecpar->width;
149 frame_height = codecpar->height; 196 frame_height = codecpar->height;
150 pix_fmt = (AVPixelFormat)codecpar->format; 197 pix_fmt = (AVPixelFormat)codecpar->format;
151 - m_fps = av_q2d(stream ->avg_frame_rate); 198 + // m_fps = av_q2d(stream ->avg_frame_rate);
  199 +
  200 + if (stream->avg_frame_rate.den) {
  201 + // m_fps = stream->avg_frame_rate.num / stream->avg_frame_rate.den;
  202 + m_fps = av_q2d(stream ->avg_frame_rate);
  203 + } else {
  204 + m_fps = 0.0;
  205 + }
152 206
153 #ifdef USE_VILLAGE 207 #ifdef USE_VILLAGE
154 bool bRet = m_recoderManager.init(stream, avctx); 208 bool bRet = m_recoderManager.init(stream, avctx);
@@ -169,28 +223,51 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ @@ -169,28 +223,51 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
169 return nullptr; 223 return nullptr;
170 } 224 }
171 225
  226 +int DvppDecoder::getVdecType(int videoType, int profile)
  227 +{
  228 + int streamFormat = H264_MAIN_LEVEL;
  229 +
  230 + // VDEC only support H265 main level,264 baseline level,main level,high level
  231 + if (videoType == AV_CODEC_ID_HEVC) {
  232 + streamFormat = H265_MAIN_LEVEL;
  233 + } else if (videoType == AV_CODEC_ID_H264) {
  234 + switch (profile) {
  235 + case FF_PROFILE_H264_BASELINE:
  236 + streamFormat = H264_BASELINE_LEVEL;
  237 + break;
  238 + case FF_PROFILE_H264_MAIN:
  239 + streamFormat = H264_MAIN_LEVEL;
  240 + break;
  241 + case FF_PROFILE_H264_HIGH:
  242 + case FF_PROFILE_H264_HIGH_10:
  243 + case FF_PROFILE_H264_HIGH_10_INTRA:
  244 + case FF_PROFILE_H264_MULTIVIEW_HIGH:
  245 + case FF_PROFILE_H264_HIGH_422:
  246 + case FF_PROFILE_H264_HIGH_422_INTRA:
  247 + case FF_PROFILE_H264_STEREO_HIGH:
  248 + case FF_PROFILE_H264_HIGH_444:
  249 + case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
  250 + case FF_PROFILE_H264_HIGH_444_INTRA:
  251 + streamFormat = H264_HIGH_LEVEL;
  252 + break;
  253 + default:
  254 + LOG_INFO("Not support h264 profile {}, use as mp", profile);
  255 + streamFormat = H264_MAIN_LEVEL;
  256 + break;
  257 + }
  258 + } else {
  259 + streamFormat = -1;
  260 + LOG_ERROR("Not support stream, type {}, profile {}", videoType, profile);
  261 + }
  262 +
  263 + return streamFormat;
  264 +}
  265 +
172 bool DvppDecoder::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) { 266 bool DvppDecoder::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) {
173 267
174 LOG_INFO("[{}]- Init device start...", m_dec_name); 268 LOG_INFO("[{}]- Init device start...", m_dec_name);
175 269
176 m_dvpp_deviceId = atoi(cfg.gpuid.c_str()); 270 m_dvpp_deviceId = atoi(cfg.gpuid.c_str());
177 -  
178 - if(avctx->codec_id == AV_CODEC_ID_H264){  
179 - // 66:Baseline,77:Main,>=100:High  
180 - if(avctx->profile == 77){  
181 - enType = H264_MAIN_LEVEL;  
182 - }else if(avctx->profile < 77){  
183 - enType = H264_BASELINE_LEVEL;  
184 - }else{  
185 - enType = H264_HIGH_LEVEL;  
186 - }  
187 - }else if(avctx->codec_id == AV_CODEC_ID_HEVC){  
188 - // h265只有main  
189 - enType = H265_MAIN_LEVEL;  
190 - }else {  
191 - LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);  
192 - return false;  
193 - }  
194 271
195 post_decoded_cbk = cfg.post_decoded_cbk; 272 post_decoded_cbk = cfg.post_decoded_cbk;
196 273
@@ -214,7 +291,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ @@ -214,7 +291,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
214 LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name); 291 LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
215 return false; 292 return false;
216 } 293 }
217 - m_vdec_out_size = avctx->width * avctx->height * 3 / 2; 294 + m_vdec_out_size = frame_width * frame_height * 3 / 2;
218 295
219 LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel); 296 LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
220 return true; 297 return true;
@@ -332,136 +409,252 @@ void DvppDecoder::release_ffmpeg() { @@ -332,136 +409,252 @@ void DvppDecoder::release_ffmpeg() {
332 409
333 void DvppDecoder::read_thread() { 410 void DvppDecoder::read_thread() {
334 411
335 - int frame_count = 0;  
336 int ret = -1; 412 int ret = -1;
337 413
338 - pthread_t m_decode_thread;  
339 - pthread_create(&m_decode_thread,0, 414 + m_bExitReportThd = false;
  415 + pthread_t report_thread;
  416 + ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
  417 + if(ret != 0){
  418 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
  419 + return;
  420 + }
  421 +
  422 + m_bExitDisplayThd = false;
  423 + pthread_t display_thread;
  424 + pthread_create(&display_thread,0,
340 [](void* arg) 425 [](void* arg)
341 { 426 {
342 DvppDecoder* a=(DvppDecoder*)arg; 427 DvppDecoder* a=(DvppDecoder*)arg;
343 - a->decode_thread(); 428 + a->display_thread();
344 return (void*)0; 429 return (void*)0;
345 } 430 }
346 ,this); 431 ,this);
347 432
348 - AVPacket* pkt = nullptr;  
349 - unsigned long long frame_nb = 0;  
350 - while (m_bRunning){  
351 433
352 - if (!m_bReal){  
353 - if (m_bPause){  
354 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
355 - continue;  
356 - }  
357 - }  
358 -  
359 - m_pktQueue_mutex.lock();  
360 - if(m_pktQueue.size() > 10){  
361 - m_pktQueue_mutex.unlock();  
362 - std::this_thread::sleep_for(std::chrono::milliseconds(5));  
363 - continue; 434 +
  435 + aclrtContext ctx = nullptr;
  436 + aclrtStream stream = nullptr;
  437 + aclvdecChannelDesc *vdecChannelDesc = nullptr;
  438 +
  439 + do {
  440 + CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
  441 + CHECK_AND_BREAK(aclrtCreateContext(&ctx, m_dvpp_deviceId), "aclrtCreateContext failed");
  442 + CHECK_AND_BREAK(aclrtCreateStream(&stream), "aclrtCreateStream failed");
  443 +
  444 + vdecChannelDesc = aclvdecCreateChannelDesc();
  445 + if (vdecChannelDesc == nullptr) {
  446 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
  447 + break;
364 } 448 }
365 - m_pktQueue_mutex.unlock();  
366 449
367 - pkt = av_packet_alloc();  
368 - av_init_packet( pkt ); 450 + // 创建 channel dec结构体
  451 + // 通道ID在dvpp层面为0~31
  452 + CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
  453 + CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
  454 + CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
  455 + CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, m_enType), "aclvdecSetChannelDescEnType failed");
  456 + CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
  457 + CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
  458 +
  459 + AVPacket* pkt = nullptr;
  460 + unsigned long long frame_nb = 0;
  461 + while (m_bRunning){
369 462
370 - int result = av_read_frame(fmt_ctx, pkt);  
371 - if (result == AVERROR_EOF || result < 0){  
372 - av_packet_free(&pkt);  
373 - pkt = nullptr;  
374 - LOG_ERROR("[{}]- Failed to read frame!", m_dec_name);  
375 - break;  
376 - } 463 + if (!m_bReal){
  464 + if (m_bPause){
  465 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  466 + continue;
  467 + }
377 468
378 - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {  
379 - av_packet_free(&pkt);  
380 - pkt = nullptr;  
381 - continue;  
382 - } 469 + // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待
  470 + m_decoded_data_queue_mtx.lock();
  471 + if(m_decoded_data_queue.size() > 5){
  472 + m_decoded_data_queue_mtx.unlock();
  473 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  474 + continue;
  475 + }
  476 + m_decoded_data_queue_mtx.unlock();
  477 + }
  478 +
  479 + pkt = av_packet_alloc();
  480 + av_init_packet( pkt );
383 481
384 - if (video_index == pkt->stream_index){ 482 + int result = av_read_frame(fmt_ctx, pkt);
  483 + if (result == AVERROR_EOF || result < 0){
  484 + av_packet_free(&pkt);
  485 + pkt = nullptr;
  486 + LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
  487 + break;
  488 + }
385 489
386 - ret = av_bsf_send_packet(h264bsfc, pkt);  
387 - if(ret < 0) {  
388 - LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); 490 + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
389 av_packet_free(&pkt); 491 av_packet_free(&pkt);
390 pkt = nullptr; 492 pkt = nullptr;
391 continue; 493 continue;
392 } 494 }
393 495
394 - bool bPushed = false;  
395 - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {  
396 - if(pkt->size > g_pkt_size){  
397 - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);  
398 - break;  
399 - } 496 + if (video_index == pkt->stream_index){
400 497
401 - if(!m_bRunning){  
402 - break;  
403 - } 498 + ret = av_bsf_send_packet(h264bsfc, pkt);
  499 + if(ret < 0) {
  500 + LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
  501 + av_packet_free(&pkt);
  502 + pkt = nullptr;
  503 + continue;
  504 + }
404 505
405 - frame_nb++;  
406 -#ifdef USE_VILLAGE  
407 - m_recoderManager.cache_pkt(pkt, frame_nb);  
408 -#endif 506 + int nSended = -1;
  507 + while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
  508 + if(pkt->size > g_pkt_size){
  509 + LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);
  510 + break;
  511 + }
409 512
410 - m_pktQueue_mutex.lock();  
411 - DataPacket* data_pkt = new DataPacket();  
412 - data_pkt->pkt = pkt;  
413 - data_pkt->frame_nb = frame_nb;  
414 - m_pktQueue.push(data_pkt);  
415 - m_pktQueue_mutex.unlock(); 513 + if(!m_bRunning){
  514 + break;
  515 + }
416 516
417 - bPushed = true;  
418 - frame_count++;  
419 - } 517 + frame_nb++;
  518 + #ifdef USE_VILLAGE
  519 + m_recoderManager.cache_pkt(pkt, frame_nb);
  520 + #endif
  521 + nSended = sendPkt(vdecChannelDesc, pkt, frame_nb);
  522 + }
420 523
421 - if(!bPushed){  
422 - av_packet_free(&pkt);  
423 - pkt = nullptr;  
424 - }  
425 - } else {  
426 - // 音频等其他分量的情形  
427 - av_packet_free(&pkt); 524 + if(nSended < 0) {
  525 + break;
  526 + }
  527 + }
  528 +
  529 + // 音频等其他分量的情形
  530 + av_packet_free(&pkt);
428 pkt = nullptr; 531 pkt = nullptr;
429 - }  
430 - } 532 + }
  533 +
  534 + while(m_bRunning && m_decoded_data_queue.size() > 0) {
  535 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  536 + }
  537 +
  538 + } while (0);
  539 +
  540 + if (vdecChannelDesc) {
  541 + sendVdecEos(vdecChannelDesc);
  542 +
  543 + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
  544 + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
  545 + vdecChannelDesc = nullptr;
  546 + }
431 547
432 m_bRunning=false; 548 m_bRunning=false;
433 549
434 - if(m_decode_thread != 0){  
435 - pthread_join(m_decode_thread,0);  
436 - } 550 + m_bExitReportThd = true;
  551 + CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed");
  552 +
  553 + m_bExitDisplayThd = true;
  554 + CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "display_thread join failed");
437 555
438 - m_pktQueue_mutex.lock();  
439 - while(m_pktQueue.size() > 0){  
440 - DataPacket* data_pkt = m_pktQueue.front();  
441 - delete data_pkt;  
442 - data_pkt = nullptr;  
443 - m_pktQueue.pop(); 556 + if(stream){
  557 + CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed");
444 } 558 }
445 - m_pktQueue_mutex.unlock();  
446 559
447 - if(decode_finished_cbk) {  
448 - decode_finished_cbk(m_finishedDecArg); 560 + if (ctx){
  561 + CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed");
449 } 562 }
  563 +
450 564
451 m_recoderManager.close(); 565 m_recoderManager.close();
  566 +
  567 + release_ffmpeg();
  568 + release_dvpp();
  569 +
  570 + m_bFinished = true;
452 571
453 LOG_INFO("[{}]- read thread exit.", m_dec_name); 572 LOG_INFO("[{}]- read thread exit.", m_dec_name);
454 - m_bFinished = true;  
455 - release_ffmpeg(); 573 +
  574 + if(decode_finished_cbk) {
  575 + decode_finished_cbk(m_finishedDecArg);
  576 + }
456 } 577 }
457 578
458 -static void *ReportThd(void *arg)  
459 -{  
460 - DvppDecoder *self = (DvppDecoder *)arg;  
461 - if(nullptr != self){  
462 - self->doProcessReport();  
463 - }  
464 - return (void *)0; 579 +int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb){
  580 +
  581 + void *vdecInputbuf = nullptr;
  582 + void *vdecOutputBuf = nullptr;
  583 + acldvppStreamDesc *input_stream_desc = nullptr;
  584 + acldvppPicDesc *output_pic_desc = nullptr;
  585 + do{
  586 + int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  587 + if(ACL_ERROR_NONE != ret){
  588 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  589 + break;
  590 + }
  591 +
  592 + ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
  593 + if(ACL_ERROR_NONE != ret){
  594 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
  595 + break;
  596 + }
  597 +
  598 + ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
  599 + if(ret != ACL_ERROR_NONE){
  600 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
  601 + break;
  602 + }
  603 +
  604 + input_stream_desc = acldvppCreateStreamDesc();
  605 + if (input_stream_desc == nullptr) {
  606 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  607 + break;
  608 + }
  609 + output_pic_desc = acldvppCreatePicDesc();
  610 + if (output_pic_desc == nullptr) {
  611 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  612 + break;
  613 + }
  614 + CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
  615 + CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
  616 + CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
  617 + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
  618 +
  619 + Vdec_CallBack_UserData *user_data = NULL;
  620 + user_data = new Vdec_CallBack_UserData;
  621 + user_data->frameId = frame_nb;
  622 + user_data->frame_nb = frame_nb;
  623 + // user_data->startTime = startTime;
  624 + user_data->sendTime = UtilTools::get_cur_time_ms();
  625 + user_data->self = this;
  626 +
  627 + ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  628 + if(ret != ACL_ERROR_NONE){
  629 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
  630 + delete user_data;
  631 + user_data = nullptr;
  632 + return 1;
  633 + }
  634 +
  635 + return 0;
  636 + }while (0);
  637 +
  638 + if (vdecInputbuf){
  639 + acldvppFree(vdecInputbuf);
  640 + vdecInputbuf = nullptr;
  641 + }
  642 +
  643 + // 报错情形
  644 + if(input_stream_desc){
  645 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
  646 + }
  647 +
  648 + if (vdecOutputBuf){
  649 + acldvppFree(vdecOutputBuf);
  650 + vdecOutputBuf = nullptr;
  651 + }
  652 +
  653 + if(output_pic_desc){
  654 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
  655 + }
  656 +
  657 + return -1;
465 } 658 }
466 659
467 void DvppDecoder::doProcessReport(){ 660 void DvppDecoder::doProcessReport(){
@@ -481,9 +674,6 @@ void DvppDecoder::doProcessReport(){ @@ -481,9 +674,6 @@ void DvppDecoder::doProcessReport(){
481 return ; 674 return ;
482 } 675 }
483 676
484 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");  
485 - // 阻塞等待vdec线程开始  
486 -  
487 while (!m_bExitReportThd) { 677 while (!m_bExitReportThd) {
488 aclrtProcessReport(1000); 678 aclrtProcessReport(1000);
489 } 679 }
@@ -495,40 +685,14 @@ void DvppDecoder::doProcessReport(){ @@ -495,40 +685,14 @@ void DvppDecoder::doProcessReport(){
495 LOG_INFO("doProcessReport exit."); 685 LOG_INFO("doProcessReport exit.");
496 } 686 }
497 687
498 -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)  
499 -{  
500 - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;  
501 - if(nullptr != userData){  
502 - DvppDecoder* self = userData->self;  
503 - if(self != nullptr){  
504 -  
505 - self->doVdppVdecCallBack(input, output, userData->frame_nb);  
506 - }  
507 - delete userData;  
508 - userData = nullptr;  
509 - }  
510 -}  
511 -  
512 -  
513 -static long get_cur_time_ms() {  
514 - chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro  
515 - = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());  
516 - return tpMicro.time_since_epoch().count();  
517 -}  
518 -  
519 void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){ 688 void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){
520 689
521 - m_vdecQueue_mutex.lock();  
522 - if(m_vdecQueue.size() > 0){  
523 - void* inputData = m_vdecQueue.front();  
524 - acldvppFree(inputData);  
525 - inputData = nullptr;  
526 - m_vdecQueue.pop();  
527 - }  
528 - m_vdecQueue_mutex.unlock(); 690 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
529 691
530 692
531 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed"); 693 + void *inputDataDev = acldvppGetStreamDescData(input);
  694 + acldvppFree(inputDataDev);
  695 + inputDataDev = nullptr;
532 696
533 void *outputDataDev = acldvppGetPicDescData(output); 697 void *outputDataDev = acldvppGetPicDescData(output);
534 uint32_t outputSize = acldvppGetPicDescSize(output); 698 uint32_t outputSize = acldvppGetPicDescSize(output);
@@ -547,35 +711,16 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o @@ -547,35 +711,16 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
547 } 711 }
548 712
549 bool bCached = false; 713 bool bCached = false;
550 -  
551 if(width > 0 && height > 0 && outputSize > 0){ 714 if(width > 0 && height > 0 && outputSize > 0){
552 - if (!m_bReal) {  
553 - while(m_bRunning) {  
554 - // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待  
555 - m_decoded_data_queue_mtx.lock();  
556 - if(m_decoded_data_queue.size() > 5){  
557 - m_decoded_data_queue_mtx.unlock();  
558 - std::this_thread::sleep_for(std::chrono::milliseconds(5));  
559 - continue;  
560 - }  
561 - m_decoded_data_queue_mtx.unlock();  
562 - break;  
563 - }  
564 - }  
565 -  
566 // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl; 715 // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl;
567 // last_ts = get_cur_time_ms(); 716 // last_ts = get_cur_time_ms();
568 717
569 // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏 718 // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏
570 - m_decoded_data_queue_mtx.lock();  
571 - if(m_decoded_data_queue.size() <= 5) {  
572 - 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);  
573 - if(mem){  
574 - m_decoded_data_queue.push(mem);  
575 - bCached = true;  
576 - } 719 + 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);
  720 + if(mem){
  721 + m_decoded_data_queue.push(mem);
  722 + bCached = true;
577 } 723 }
578 - m_decoded_data_queue_mtx.unlock();  
579 724
580 if(m_bSnapShoting){ 725 if(m_bSnapShoting){
581 // 缓存snapshot 726 // 缓存snapshot
@@ -604,246 +749,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o @@ -604,246 +749,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
604 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed"); 749 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
605 } 750 }
606 751
607 -void DvppDecoder::decode_thread(){  
608 -  
609 - long startTime = UtilTools::get_cur_time_ms();  
610 -  
611 - int ret = -1;  
612 -  
613 - m_bExitReportThd = false;  
614 - pthread_t report_thread;  
615 - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);  
616 - if(ret != 0){  
617 - LOG_ERROR("[{}]- pthread_create failed", m_dec_name);  
618 - return;  
619 - }  
620 -  
621 - pthread_t display_thread;  
622 - pthread_create(&display_thread,0,  
623 - [](void* arg)  
624 - {  
625 - DvppDecoder* a=(DvppDecoder*)arg;  
626 - a->display_thread();  
627 - return (void*)0;  
628 - }  
629 - ,this);  
630 -  
631 - aclrtSetDevice(m_dvpp_deviceId);  
632 - aclrtContext ctx;  
633 - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);  
634 - if (ret != ACL_ERROR_NONE) {  
635 - // cout << "aclrtCreateContext failed " << endl;  
636 - LOG_ERROR("aclrtCreateContext failed !");  
637 - return ;  
638 - }  
639 -  
640 - // 创建aclvdecChannelDesc类型的数据  
641 - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();  
642 - if (vdecChannelDesc == nullptr) {  
643 - LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);  
644 - return;  
645 - }  
646 - do{  
647 - // 创建 channel dec结构体  
648 - // 通道ID在dvpp层面为0~31  
649 - CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");  
650 - CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");  
651 - CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");  
652 - CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");  
653 - CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");  
654 - CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");  
655 -  
656 - uint64_t frame_count = 0;  
657 - bool bBreak = false;  
658 - while (m_bRunning) {  
659 - if (m_bPause){  
660 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
661 - continue;  
662 - }  
663 - int ret = sentFrame(vdecChannelDesc, frame_count);  
664 - if(ret == 2){  
665 - bBreak = true;  
666 - break;  
667 - }else if(ret == 1){  
668 - continue;  
669 - }  
670 -  
671 - frame_count++;  
672 - }  
673 -  
674 - // 尽量保证数据全部解码完成  
675 - int sum = 0;  
676 - if(!bBreak){  
677 - aclrtSetDevice(m_dvpp_deviceId);  
678 - aclrtSetCurrentContext(ctx);  
679 - while(m_pktQueue.size() > 0){  
680 - int ret = sentFrame(vdecChannelDesc, frame_count);  
681 - if(ret == 2){  
682 - break;  
683 - }  
684 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
685 - sum++;  
686 - if(sum > 40){  
687 - // 避免卡死  
688 - break;  
689 - }  
690 - }  
691 - }  
692 -  
693 - sendVdecEos(vdecChannelDesc);  
694 -  
695 - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");  
696 - }while(0);  
697 -  
698 - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");  
699 -  
700 - // report_thread 需后于destroy退出  
701 - m_bRunning = false;  
702 - m_bExitReportThd = true;  
703 - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");  
704 - CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "pthread_join failed");  
705 -  
706 - // 最后清理一遍未解码的数据  
707 - m_vdecQueue_mutex.lock();  
708 - if(m_vdecQueue.size() > 0){  
709 - void* inputData = m_vdecQueue.front();  
710 - acldvppFree(inputData);  
711 - inputData = nullptr;  
712 - m_vdecQueue.pop();  
713 - }  
714 - m_vdecQueue_mutex.unlock();  
715 -  
716 - release_dvpp();  
717 -  
718 - ret = aclrtDestroyContext(ctx);  
719 - if(ret != ACL_ERROR_NONE){  
720 - LOG_ERROR("aclrtDestroyContext failed !");  
721 - }  
722 -  
723 - LOG_INFO("[{}]- decode thread exit.", m_dec_name);  
724 -}  
725 -  
726 -int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){  
727 -  
728 - // 此处需要判断 m_vdecQueue 队列长度,避免占用过多显存  
729 - m_vdecQueue_mutex.lock();  
730 - if(m_vdecQueue.size() > 20){  
731 - m_vdecQueue_mutex.unlock();  
732 - std::this_thread::sleep_for(std::chrono::milliseconds(2));  
733 - return 1;  
734 - }  
735 - m_vdecQueue_mutex.unlock();  
736 -  
737 - DataPacket * data_pkt = nullptr;  
738 - m_pktQueue_mutex.lock();  
739 - if(m_pktQueue.size() <= 0){  
740 - m_pktQueue_mutex.unlock();  
741 - std::this_thread::sleep_for(std::chrono::milliseconds(10));  
742 - return 1;  
743 - }  
744 - data_pkt = m_pktQueue.front();  
745 - m_pktQueue.pop();  
746 - m_pktQueue_mutex.unlock();  
747 -  
748 - // 解码  
749 - void *vdecInputbuf = nullptr;  
750 - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);  
751 - if(ACL_ERROR_NONE != ret){  
752 - LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);  
753 - delete data_pkt;  
754 - data_pkt = nullptr;  
755 - return 2;  
756 - }  
757 -  
758 - AVPacket* pkt = data_pkt->pkt;  
759 - ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);  
760 - if(ACL_ERROR_NONE != ret){  
761 - LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);  
762 - delete data_pkt;  
763 - data_pkt = nullptr;  
764 - return 2;  
765 - }  
766 -  
767 - void *vdecOutputBuf = nullptr;  
768 - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);  
769 - if(ret != ACL_ERROR_NONE){  
770 - LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);  
771 - delete data_pkt;  
772 - data_pkt = nullptr;  
773 - return 2;  
774 - }  
775 -  
776 - acldvppStreamDesc *input_stream_desc = nullptr;  
777 - acldvppPicDesc *output_pic_desc = nullptr;  
778 - do{  
779 - input_stream_desc = acldvppCreateStreamDesc();  
780 - if (input_stream_desc == nullptr) {  
781 - LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);  
782 - break;  
783 - }  
784 - output_pic_desc = acldvppCreatePicDesc();  
785 - if (output_pic_desc == nullptr) {  
786 - LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);  
787 - break;  
788 - }  
789 - CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");  
790 - CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");  
791 - CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");  
792 - CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");  
793 -  
794 - Vdec_CallBack_UserData *user_data = NULL;  
795 - user_data = new Vdec_CallBack_UserData;  
796 - user_data->frameId = frame_count;  
797 - user_data->frame_nb = data_pkt->frame_nb;  
798 - // user_data->startTime = startTime;  
799 - user_data->sendTime = UtilTools::get_cur_time_ms();  
800 - user_data->self = this;  
801 -  
802 - m_vdecQueue_mutex.lock();  
803 - ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));  
804 - delete data_pkt;  
805 - data_pkt = nullptr;  
806 - if(ret != ACL_ERROR_NONE){  
807 - LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);  
808 - m_vdecQueue_mutex.unlock();  
809 - delete user_data;  
810 - user_data = nullptr;  
811 - break;  
812 - }  
813 -  
814 - m_vdecQueue.push(vdecInputbuf);  
815 - m_vdecQueue_mutex.unlock();  
816 -  
817 - return 0;  
818 - }while (0);  
819 -  
820 - if(data_pkt != nullptr){  
821 - delete data_pkt;  
822 - data_pkt = nullptr;  
823 - }  
824 -  
825 - if (vdecInputbuf){  
826 - acldvppFree(vdecInputbuf);  
827 - vdecInputbuf = nullptr;  
828 - }  
829 -  
830 - // 报错情形  
831 - if(input_stream_desc){  
832 - CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");  
833 - }  
834 -  
835 - if (vdecOutputBuf){  
836 - acldvppFree(vdecOutputBuf);  
837 - vdecOutputBuf = nullptr;  
838 - }  
839 -  
840 - if(output_pic_desc){  
841 - CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");  
842 - }  
843 -  
844 - return 1;  
845 -}  
846 -  
847 bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { 752 bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
848 // create stream desc 753 // create stream desc
849 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc(); 754 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
@@ -872,7 +777,7 @@ bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { @@ -872,7 +777,7 @@ bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
872 777
873 void DvppDecoder::display_thread(){ 778 void DvppDecoder::display_thread(){
874 LOG_INFO("[{}]- display_thread start...", m_dec_name); 779 LOG_INFO("[{}]- display_thread start...", m_dec_name);
875 - while(m_bRunning) { 780 + while(!m_bExitDisplayThd) {
876 m_decoded_data_queue_mtx.lock(); 781 m_decoded_data_queue_mtx.lock();
877 if(m_decoded_data_queue.size() <= 0) { 782 if(m_decoded_data_queue.size() <= 0) {
878 m_decoded_data_queue_mtx.unlock(); 783 m_decoded_data_queue_mtx.unlock();
@@ -898,7 +803,7 @@ void DvppDecoder::display_thread(){ @@ -898,7 +803,7 @@ void DvppDecoder::display_thread(){
898 mem = nullptr; 803 mem = nullptr;
899 } 804 }
900 805
901 - LOG_INFO("[{}]- display_thread end.", m_dec_name); 806 + LOG_INFO("[{}]- display_thread exit.", m_dec_name);
902 } 807 }
903 808
904 void DvppDecoder::release_dvpp(){ 809 void DvppDecoder::release_dvpp(){
src/decoder/dvpp/DvppDecoder.h
@@ -66,13 +66,14 @@ private: @@ -66,13 +66,14 @@ private:
66 void release_ffmpeg(); 66 void release_ffmpeg();
67 void read_thread(); 67 void read_thread();
68 68
69 - void decode_thread();  
70 - int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count); 69 + int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb);
71 bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc); 70 bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
72 void release_dvpp(); 71 void release_dvpp();
73 72
74 void display_thread(); 73 void display_thread();
75 74
  75 + int getVdecType(int videoType, int profile);
  76 +
76 private: 77 private:
77 FFDecConfig m_cfg; 78 FFDecConfig m_cfg;
78 string m_dec_name; 79 string m_dec_name;
@@ -84,6 +85,7 @@ private: @@ -84,6 +85,7 @@ private:
84 bool m_bRunning{false}; 85 bool m_bRunning{false};
85 bool m_bPause{false}; 86 bool m_bPause{false};
86 bool m_bExitReportThd{false}; 87 bool m_bExitReportThd{false};
  88 + bool m_bExitDisplayThd{false};
87 89
88 // 读取数据 90 // 读取数据
89 AVStream* stream{nullptr}; 91 AVStream* stream{nullptr};
@@ -102,17 +104,11 @@ private: @@ -102,17 +104,11 @@ private:
102 104
103 bool m_dec_keyframe; 105 bool m_dec_keyframe;
104 106
105 - mutex m_pktQueue_mutex;  
106 - queue<DataPacket*> m_pktQueue;  
107 -  
108 // 解码 107 // 解码
109 int m_dvpp_deviceId {-1}; 108 int m_dvpp_deviceId {-1};
110 int m_dvpp_channel {-1}; 109 int m_dvpp_channel {-1};
111 aclrtContext m_context{nullptr}; 110 aclrtContext m_context{nullptr};
112 - acldvppStreamFormat enType;  
113 -  
114 - mutex m_vdecQueue_mutex;  
115 - queue<void*> m_vdecQueue; 111 + acldvppStreamFormat m_enType;
116 112
117 const void * m_postDecArg; 113 const void * m_postDecArg;
118 POST_DECODE_CALLBACK post_decoded_cbk {nullptr}; 114 POST_DECODE_CALLBACK post_decoded_cbk {nullptr};
src/decoder/dvpp/VpcPicConverter.cpp
@@ -3,6 +3,15 @@ @@ -3,6 +3,15 @@
3 3
4 #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align))) 4 #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
5 5
  6 +#define CHECK_AND_RETURN(ret, message) \
  7 + if(ret != 0) {LOG_ERROR("{}", message); return ret;}
  8 +#define CHECK_NOT_RETURN(ret, message) \
  9 + if(ret != 0) {LOG_ERROR("{}", message);}
  10 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  11 + if(ret != 0) {LOG_ERROR("{}", message); return;}
  12 +#define CHECK_AND_BREAK(ret, message) \
  13 + if(ret != 0) {LOG_ERROR("{}", message); break;}
  14 +
6 VpcPicConverter::VpcPicConverter(){ 15 VpcPicConverter::VpcPicConverter(){
7 16
8 } 17 }
src/decoder/dvpp/dvpp_headers.h
@@ -26,15 +26,6 @@ @@ -26,15 +26,6 @@
26 #include "acl/acl.h" 26 #include "acl/acl.h"
27 #include "acl/ops/acl_dvpp.h" 27 #include "acl/ops/acl_dvpp.h"
28 28
29 -  
30 -#define CHECK_AND_RETURN(ret, message) \  
31 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}  
32 -#define CHECK_NOT_RETURN(ret, message) \  
33 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}  
34 -#define CHECK_AND_RETURN_NOVALUE(ret, message) \  
35 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}  
36 -#define CHECK_AND_BREAK(ret, message) \  
37 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}  
38 29
39 #endif 30 #endif
40 31
src/decoder/test_decoder.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 +
  19 +bool m_bfinish{false};
  20 +int m_devId = 0;
  21 +const char* task_id = "test0";
  22 +int skip_frame_ = 5;
  23 +int m_batch_size = 20;
  24 +
  25 +
  26 +void algorthim_process_thread();
  27 +
  28 +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
  29 + do{
  30 + if(m_bfinish){
  31 + break;
  32 + }
  33 + m_DataListMtx.lock();
  34 + if(m_RgbDataList.size() >= 30){
  35 + m_DataListMtx.unlock();
  36 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  37 + continue;
  38 + }
  39 + m_RgbDataList.push_back(devFrame);
  40 + m_DataListMtx.unlock();
  41 + break;
  42 + }while (true);
  43 +}
  44 +
  45 +void decode_finished_cbk(const void * userPtr){
  46 + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
  47 + if (ptr!= nullptr){
  48 + printf("task finished: %s \n", ptr->task_id.c_str());
  49 + }
  50 + delete ptr;
  51 + ptr = nullptr;
  52 +}
  53 +
  54 +int main(){
  55 +
  56 + // 创建解码任务
  57 + DecoderManager* pDecManager = DecoderManager::getInstance();
  58 +
  59 + MgrDecConfig config;
  60 + config.name = task_id;
  61 + config.cfg.uri = "/data/share/data/Street.uvf";
  62 + config.cfg.post_decoded_cbk = post_decod_cbk;
  63 + config.cfg.decode_finished_cbk = decode_finished_cbk;
  64 + config.cfg.force_tcp = true; // rtsp用tcp
  65 + config.cfg.gpuid = to_string(m_devId);
  66 + config.cfg.skip_frame = skip_frame_;
  67 +
  68 + config.dec_type = DECODER_TYPE_DVPP;
  69 +
  70 + AbstractDecoder* dec = pDecManager->createDecoder(config);
  71 + if (!dec){
  72 + printf("创建解码器失败 \n");
  73 + return false;
  74 + }
  75 +
  76 + decode_cbk_userdata* userPtr = new decode_cbk_userdata;
  77 + userPtr->task_id = string(task_id);
  78 + pDecManager->setPostDecArg(config.name, userPtr);
  79 + pDecManager->setFinishedDecArg(config.name, userPtr);
  80 +
  81 +
  82 + int input_image_width = 0;
  83 + int input_image_height = 0;
  84 + pDecManager->getResolution(config.name, input_image_width, input_image_height);
  85 +
  86 +
  87 + // 创建算法线程
  88 + m_pAlgorthimThread = new thread([](void* arg) {
  89 + algorthim_process_thread();
  90 + return (void*)0;
  91 + }
  92 + , nullptr);
  93 +
  94 + pDecManager->startDecodeByName(config.name);
  95 +
  96 + while (getchar() != 'q');
  97 +}
  98 +
  99 +void do_work(vector<DeviceMemory*> vec_gpuMem){
  100 + for(int i=0;i < vec_gpuMem.size(); i++){
  101 + DeviceMemory* mem = vec_gpuMem[i];
  102 + printf("width:%d height:%d ts:%lld \n", mem->getWidth(), mem->getHeight(), mem->getTimesstamp());
  103 + }
  104 +}
  105 +
  106 +void algorthim_process_thread(){
  107 +
  108 + while (true){
  109 + if(m_bfinish){
  110 + break;
  111 + }
  112 +
  113 + vector<DeviceMemory*> vec_gpuMem;
  114 + m_DataListMtx.lock();
  115 + while (!m_RgbDataList.empty()){
  116 + DeviceMemory* gpuMem = m_RgbDataList.front();
  117 + if(gpuMem->getMem() == nullptr){
  118 + // 错误数据,直接删除
  119 + delete gpuMem;
  120 + gpuMem = nullptr;
  121 + printf("mem is null \n");
  122 + } else {
  123 + vec_gpuMem.push_back(gpuMem);
  124 + }
  125 + m_RgbDataList.pop_front();
  126 + if(vec_gpuMem.size() >= m_batch_size){
  127 + break;
  128 + }
  129 + }
  130 + m_DataListMtx.unlock();
  131 +
  132 + if(vec_gpuMem.size() <= 0){
  133 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  134 + continue;
  135 + }
  136 +
  137 + // do work
  138 + do_work(vec_gpuMem);
  139 +
  140 + for(int i=0;i < vec_gpuMem.size(); i++){
  141 + DeviceMemory* mem = vec_gpuMem[i];
  142 + if(mem->getSize() <= 0){
  143 + continue;
  144 + }
  145 + delete mem;
  146 + mem = nullptr;
  147 + }
  148 + vec_gpuMem.clear();
  149 +
  150 + }
  151 +
  152 + printf("algorthim_process_thread exit. \n");
  153 +}
0 \ No newline at end of file 154 \ No newline at end of file
src/decoder/test_recoder.cpp0 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 +thread* m_recodeThread{nullptr};
  19 +bool m_bfinish{false};
  20 +int m_devId = 0;
  21 +const char* task_id = "test0";
  22 +int skip_frame_ = 5;
  23 +int m_batch_size = 20;
  24 +
  25 +deque<RecoderInfo> m_recoderinfo_queue;
  26 +mutex m_recoderinfo_queue_mtx;
  27 +
  28 +void algorthim_process_thread();
  29 +void recode_thread();
  30 +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem);
  31 +
  32 +void test_recode_thread();
  33 +
  34 +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
  35 + do{
  36 + if(m_bfinish){
  37 + break;
  38 + }
  39 + m_DataListMtx.lock();
  40 + if(m_RgbDataList.size() >= 30){
  41 + m_DataListMtx.unlock();
  42 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  43 + continue;
  44 + }
  45 + m_RgbDataList.push_back(devFrame);
  46 + m_DataListMtx.unlock();
  47 + break;
  48 + }while (true);
  49 +}
  50 +
  51 +void decode_finished_cbk(const void * userPtr){
  52 + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
  53 + if (ptr!= nullptr){
  54 + printf("task finished: %s \n", ptr->task_id.c_str());
  55 + }
  56 + delete ptr;
  57 + ptr = nullptr;
  58 +}
  59 +
  60 +int main(){
  61 +
  62 + // 创建解码任务
  63 + DecoderManager* pDecManager = DecoderManager::getInstance();
  64 +
  65 + MgrDecConfig config;
  66 + config.name = task_id;
  67 + config.cfg.uri = "/opt/cmhu/data/公安局老桥头_CVR15F89410_1465819864_1B.mp4";
  68 + config.cfg.post_decoded_cbk = post_decod_cbk;
  69 + config.cfg.decode_finished_cbk = decode_finished_cbk;
  70 + config.cfg.force_tcp = true; // rtsp用tcp
  71 + config.cfg.gpuid = to_string(m_devId);
  72 + config.cfg.skip_frame = skip_frame_;
  73 +
  74 + config.dec_type = DECODER_TYPE_DVPP;
  75 +
  76 + AbstractDecoder* dec = pDecManager->createDecoder(config);
  77 + if (!dec){
  78 + printf("创建解码器失败 \n");
  79 + return false;
  80 + }
  81 +
  82 + decode_cbk_userdata* userPtr = new decode_cbk_userdata;
  83 + userPtr->task_id = string(task_id);
  84 + pDecManager->setPostDecArg(config.name, userPtr);
  85 + pDecManager->setFinishedDecArg(config.name, userPtr);
  86 +
  87 +
  88 + int input_image_width = 0;
  89 + int input_image_height = 0;
  90 + pDecManager->getResolution(config.name, input_image_width, input_image_height);
  91 +
  92 +
  93 + // 创建算法线程
  94 + m_pAlgorthimThread = new thread([](void* arg) {
  95 + algorthim_process_thread();
  96 + return (void*)0;
  97 + }
  98 + , nullptr);
  99 +
  100 + // m_recodeThread = new thread([](void* arg) {
  101 + // recode_thread();
  102 + // return (void*)0;
  103 + // }
  104 + // , nullptr);
  105 +
  106 + m_recodeThread = new thread([](void* arg) {
  107 + test_recode_thread();
  108 + return (void*)0;
  109 + }
  110 + , nullptr);
  111 +
  112 + pDecManager->startDecodeByName(config.name);
  113 +
  114 + while (getchar() != 'q');
  115 +}
  116 +
  117 +void algorthim_process_thread(){
  118 +
  119 + while (true){
  120 + if(m_bfinish){
  121 + break;
  122 + }
  123 +
  124 + vector<DeviceMemory*> vec_gpuMem;
  125 + m_DataListMtx.lock();
  126 + while (!m_RgbDataList.empty()){
  127 + DeviceMemory* gpuMem = m_RgbDataList.front();
  128 + if(gpuMem->getMem() == nullptr){
  129 + // 错误数据,直接删除
  130 + delete gpuMem;
  131 + gpuMem = nullptr;
  132 + printf("mem is null \n");
  133 + } else {
  134 + vec_gpuMem.push_back(gpuMem);
  135 + }
  136 + m_RgbDataList.pop_front();
  137 + if(vec_gpuMem.size() >= m_batch_size){
  138 + break;
  139 + }
  140 + }
  141 + m_DataListMtx.unlock();
  142 +
  143 + if(vec_gpuMem.size() <= 0){
  144 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  145 + continue;
  146 + }
  147 +
  148 + algorthim_face_detect(vec_gpuMem);
  149 +
  150 + for(int i=0;i < vec_gpuMem.size(); i++){
  151 + DeviceMemory* mem = vec_gpuMem[i];
  152 + if(mem->getSize() <= 0){
  153 + continue;
  154 + }
  155 + delete mem;
  156 + mem = nullptr;
  157 + }
  158 + vec_gpuMem.clear();
  159 +
  160 + }
  161 +
  162 + printf("algorthim_process_thread exit. \n");
  163 +}
  164 +
  165 +static int interval = 0;
  166 +static int obj_id = 0;
  167 +
  168 +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem) {
  169 + interval ++ ;
  170 +
  171 + if(interval % 50 != 0) {
  172 + return;
  173 + }
  174 +
  175 + for(int i= 0; i < vec_gpuMem.size(); i++) {
  176 + DeviceMemory* mem = vec_gpuMem[i];
  177 + string task_id = mem->getId();
  178 +
  179 + RecoderInfo recoderInfo;
  180 + recoderInfo.task_id = task_id;
  181 + recoderInfo.object_id = std::to_string(obj_id);
  182 + recoderInfo.recoderPath = "./res/recode";
  183 + recoderInfo.frame_nb = mem->getFrameNb();
  184 +
  185 + m_recoderinfo_queue_mtx.lock();
  186 + m_recoderinfo_queue.push_back(recoderInfo);
  187 + m_recoderinfo_queue_mtx.unlock();
  188 +
  189 + obj_id++;
  190 +
  191 + }
  192 +}
  193 +
  194 +void test_recode_thread() {
  195 + unsigned long long frame_index = 0;
  196 + while(true) {
  197 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  198 +
  199 + DeviceMemory* mem = nullptr;
  200 + m_DataListMtx.lock();
  201 + while (!m_RgbDataList.empty()){
  202 + DeviceMemory* gpuMem = m_RgbDataList.front();
  203 + if(gpuMem->getMem() == nullptr){
  204 + // 错误数据,直接删除
  205 + delete gpuMem;
  206 + gpuMem = nullptr;
  207 + printf("mem is null \n");
  208 + } else {
  209 + frame_index ++ ;
  210 + if (frame_index % 50 == 0) {
  211 + RecoderInfo recoderInfo;
  212 + recoderInfo.task_id = gpuMem->getId();
  213 + recoderInfo.object_id = std::to_string(obj_id);
  214 + recoderInfo.recoderPath = "./res/recode";
  215 + recoderInfo.frame_nb = gpuMem->getFrameNb();
  216 +
  217 + DecoderManager* pDecManager = DecoderManager::getInstance();
  218 + pDecManager->doRecode(recoderInfo);
  219 +
  220 + obj_id++;
  221 + }
  222 + delete gpuMem;
  223 + gpuMem = nullptr;
  224 + }
  225 + m_RgbDataList.pop_front();
  226 + }
  227 + m_DataListMtx.unlock();
  228 + }
  229 +}
  230 +
  231 +void recode_thread() {
  232 + while(true) {
  233 +
  234 + m_recoderinfo_queue_mtx.lock();
  235 + if(m_recoderinfo_queue.size() <= 0) {
  236 + m_recoderinfo_queue_mtx.unlock();
  237 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  238 + continue;
  239 + }
  240 +
  241 + RecoderInfo info = m_recoderinfo_queue.front();
  242 + m_recoderinfo_queue.pop_front();
  243 + m_recoderinfo_queue_mtx.unlock();
  244 +
  245 + DecoderManager* pDecManager = DecoderManager::getInstance();
  246 + pDecManager->doRecode(info);
  247 + }
  248 +}
0 \ No newline at end of file 249 \ No newline at end of file