Commit c19334feaf50cfc9b284d34212f3a4cdd0940132

Authored by Hu Chunming
2 parents 294ef5bc c4da696c

Merge branch 'dev-shzhao' into dev-cmhu

src/decoder/Makefile 100755 → 100644
1 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 6 DEPEND_DIR = $(PROJECT_ROOT)/bin
7 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 11 THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
12 12 SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release
13 13 OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv_4_1
14 14 JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release
15 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 19 include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
21 20 -I $(SPDLOG_ROOT)/include \
... ... @@ -23,7 +22,6 @@ include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
23 22 -I $(OPENCV_ROOT)/include \
24 23 -I $(JSON_ROOT)/include \
25 24 -I $(FFMPEG_ROOT)/include \
26   - -I $(RABBITMQ_CLIENT_ROOT)/include \
27 25  
28 26 lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
29 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 29 -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
32 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 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 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 43 $(wildcard $(SRC_ROOT)/decoder/*.cpp) \
57 44  
58 45 OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
... ... @@ -69,24 +56,6 @@ $(TARGET):$(OBJS)
69 56 %.o:$(SRC_ROOT)/decoder/interface/%.cpp
70 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 59 %.o:$(SRC_ROOT)/decoder/%.cpp
91 60 $(XX) $(CXXFLAGS) -c $<
92 61  
... ...
src/decoder/Makefile_face 0 → 100755
  1 +XX = g++
  2 +
  3 +
  4 +PROJECT_ROOT= /home/cmhu/vpt_ascend_arm
  5 +
  6 +DEPEND_DIR = $(PROJECT_ROOT)/bin
  7 +SRC_ROOT = $(PROJECT_ROOT)/src
  8 +
  9 +TARGET= $(PROJECT_ROOT)/bin/test_decoder
  10 +
  11 +THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
  12 +SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release
  13 +OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv_4_1
  14 +JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release
  15 +FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release
  16 +RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release
  17 +
  18 +DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ
  19 +
  20 +include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \
  21 + -I $(SPDLOG_ROOT)/include \
  22 + -I $(SRC_ROOT)/common \
  23 + -I $(OPENCV_ROOT)/include \
  24 + -I $(JSON_ROOT)/include \
  25 + -I $(FFMPEG_ROOT)/include \
  26 + -I $(RABBITMQ_CLIENT_ROOT)/include \
  27 +
  28 +lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
  29 + -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \
  30 + -L/usr/local/Ascend/ascend-toolkit/latest/runtime/lib64 \
  31 + -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
  32 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \
  33 +
  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
  36 +
  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 \
  43 +
  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
  45 +
  46 +
  47 +
  48 +SRCS:=$(wildcard $(SRC_ROOT)/ai_platform/*.cpp) \
  49 + $(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \
  50 + $(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) \
  57 +
  58 +OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
  59 +
  60 +
  61 +$(TARGET):$(OBJS)
  62 + rm -f $(TARGET)
  63 + $(XX) -o $@ $^ $(CXXFLAGS)
  64 + rm -f *.o
  65 +
  66 +%.o:$(SRC_ROOT)/decoder/dvpp/%.cpp
  67 + $(XX) $(CXXFLAGS) -c $<
  68 +
  69 +%.o:$(SRC_ROOT)/decoder/interface/%.cpp
  70 + $(XX) $(CXXFLAGS) -c $<
  71 +
  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
  91 + $(XX) $(CXXFLAGS) -c $<
  92 +
  93 +clean:
  94 + rm -f *.o $(TARGET)
... ...
src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -2,6 +2,17 @@
2 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 16 struct Vdec_CallBack_UserData {
6 17 uint64_t frameId;
7 18 unsigned long long frame_nb;
... ... @@ -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 59 DvppDecoder::DvppDecoder(){
19 60 m_read_thread = 0;
20 61 m_cached_mem = nullptr;
... ... @@ -137,6 +178,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
137 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 187 int ret = av_bsf_alloc(filter, &h264bsfc);
141 188 if (ret < 0){
142 189 break;
... ... @@ -148,7 +195,14 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
148 195 frame_width = codecpar->width;
149 196 frame_height = codecpar->height;
150 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 207 #ifdef USE_VILLAGE
154 208 bool bRet = m_recoderManager.init(stream, avctx);
... ... @@ -169,28 +223,51 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
169 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 266 bool DvppDecoder::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) {
173 267  
174 268 LOG_INFO("[{}]- Init device start...", m_dec_name);
175 269  
176 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 272 post_decoded_cbk = cfg.post_decoded_cbk;
196 273  
... ... @@ -214,7 +291,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
214 291 LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
215 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 296 LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
220 297 return true;
... ... @@ -332,142 +409,252 @@ void DvppDecoder::release_ffmpeg() {
332 409  
333 410 void DvppDecoder::read_thread() {
334 411  
335   - int frame_count = 0;
336 412 int ret = -1;
337 413  
338   - m_bExitDecodeThd = false;
339   - pthread_t m_decode_thread;
340   - 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,
341 425 [](void* arg)
342 426 {
343 427 DvppDecoder* a=(DvppDecoder*)arg;
344   - a->decode_thread();
  428 + a->display_thread();
345 429 return (void*)0;
346 430 }
347 431 ,this);
348 432  
349   - AVPacket* pkt = nullptr;
350   - unsigned long long frame_nb = 0;
351   - while (m_bRunning){
352   -
353   - if (!m_bReal){
354   - if (m_bPause){
355   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
356   - continue;
357   - }
358   - }
359 433  
360   - m_pktQueue_mutex.lock();
361   - if(m_pktQueue.size() > 10){
362   - m_pktQueue_mutex.unlock();
363   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
364   - 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;
365 448 }
366   - m_pktQueue_mutex.unlock();
367 449  
368   - pkt = av_packet_alloc();
369   - 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");
370 458  
371   - int result = av_read_frame(fmt_ctx, pkt);
372   - if (result == AVERROR_EOF || result < 0){
373   - av_packet_free(&pkt);
374   - pkt = nullptr;
375   - LOG_ERROR("[{}]- Failed to read frame!", m_dec_name);
376   - break;
377   - }
  459 + AVPacket* pkt = nullptr;
  460 + unsigned long long frame_nb = 0;
  461 + while (m_bRunning){
378 462  
379   - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
380   - av_packet_free(&pkt);
381   - pkt = nullptr;
382   - continue;
383   - }
  463 + if (!m_bReal){
  464 + if (m_bPause){
  465 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  466 + continue;
  467 + }
  468 +
  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 );
384 481  
385   - 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 + }
386 489  
387   - ret = av_bsf_send_packet(h264bsfc, pkt);
388   - if(ret < 0) {
389   - LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
  490 + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
390 491 av_packet_free(&pkt);
391 492 pkt = nullptr;
392 493 continue;
393 494 }
394 495  
395   - bool bPushed = false;
396   - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
397   - if(pkt->size > g_pkt_size){
398   - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);
399   - break;
400   - }
  496 + if (video_index == pkt->stream_index){
401 497  
402   - if(!m_bRunning){
403   - break;
404   - }
  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 + }
405 505  
406   - frame_nb++;
407   -#ifdef USE_VILLAGE
408   - m_recoderManager.cache_pkt(pkt, frame_nb);
409   -#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 + }
410 512  
411   - m_pktQueue_mutex.lock();
412   - DataPacket* data_pkt = new DataPacket();
413   - data_pkt->pkt = pkt;
414   - data_pkt->frame_nb = frame_nb;
415   - m_pktQueue.push(data_pkt);
416   - m_pktQueue_mutex.unlock();
  513 + if(!m_bRunning){
  514 + break;
  515 + }
417 516  
418   - bPushed = true;
419   - frame_count++;
420   - }
  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 + }
421 523  
422   - if(!bPushed){
423   - av_packet_free(&pkt);
424   - pkt = nullptr;
425   - }
426   - } else {
427   - // 音频等其他分量的情形
428   - av_packet_free(&pkt);
  524 + if(nSended < 0) {
  525 + break;
  526 + }
  527 + }
  528 +
  529 + // 音频等其他分量的情形
  530 + av_packet_free(&pkt);
429 531 pkt = nullptr;
430   - }
431   - }
  532 + }
432 533  
433   - while(m_bRunning && m_pktQueue.size() > 0) {
434   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
435   - }
  534 + while(m_bRunning && m_decoded_data_queue.size() > 0) {
  535 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  536 + }
436 537  
437   - m_bExitDecodeThd = true;
438   - if(m_decode_thread != 0){
439   - pthread_join(m_decode_thread,0);
440   - }
  538 + } while (0);
  539 +
  540 + if (vdecChannelDesc) {
  541 + sendVdecEos(vdecChannelDesc);
441 542  
442   - m_pktQueue_mutex.lock();
443   - while(m_pktQueue.size() > 0){
444   - DataPacket* data_pkt = m_pktQueue.front();
445   - delete data_pkt;
446   - data_pkt = nullptr;
447   - m_pktQueue.pop();
  543 + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
  544 + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
  545 + vdecChannelDesc = nullptr;
448 546 }
449   - m_pktQueue_mutex.unlock();
450 547  
451 548 m_bRunning=false;
452 549  
453   - if(decode_finished_cbk) {
454   - decode_finished_cbk(m_finishedDecArg);
  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");
  555 +
  556 + if(stream){
  557 + CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed");
  558 + }
  559 +
  560 + if (ctx){
  561 + CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed");
455 562 }
  563 +
456 564  
457 565 m_recoderManager.close();
  566 +
  567 + release_ffmpeg();
  568 + release_dvpp();
  569 +
  570 + m_bFinished = true;
458 571  
459 572 LOG_INFO("[{}]- read thread exit.", m_dec_name);
460   - m_bFinished = true;
461   - release_ffmpeg();
  573 +
  574 + if(decode_finished_cbk) {
  575 + decode_finished_cbk(m_finishedDecArg);
  576 + }
462 577 }
463 578  
464   -static void *ReportThd(void *arg)
465   -{
466   - DvppDecoder *self = (DvppDecoder *)arg;
467   - if(nullptr != self){
468   - self->doProcessReport();
469   - }
470   - 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;
471 658 }
472 659  
473 660 void DvppDecoder::doProcessReport(){
... ... @@ -487,9 +674,6 @@ void DvppDecoder::doProcessReport(){
487 674 return ;
488 675 }
489 676  
490   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");
491   - // 阻塞等待vdec线程开始
492   -
493 677 while (!m_bExitReportThd) {
494 678 aclrtProcessReport(1000);
495 679 }
... ... @@ -501,40 +685,14 @@ void DvppDecoder::doProcessReport(){
501 685 LOG_INFO("doProcessReport exit.");
502 686 }
503 687  
504   -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
505   -{
506   - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
507   - if(nullptr != userData){
508   - DvppDecoder* self = userData->self;
509   - if(self != nullptr){
510   -
511   - self->doVdppVdecCallBack(input, output, userData->frame_nb);
512   - }
513   - delete userData;
514   - userData = nullptr;
515   - }
516   -}
517   -
518   -
519   -static long get_cur_time_ms() {
520   - chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
521   - = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
522   - return tpMicro.time_since_epoch().count();
523   -}
524   -
525 688 void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){
526 689  
527   - m_vdecQueue_mutex.lock();
528   - if(m_vdecQueue.size() > 0){
529   - void* inputData = m_vdecQueue.front();
530   - acldvppFree(inputData);
531   - inputData = nullptr;
532   - m_vdecQueue.pop();
533   - }
534   - m_vdecQueue_mutex.unlock();
  690 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
535 691  
536 692  
537   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  693 + void *inputDataDev = acldvppGetStreamDescData(input);
  694 + acldvppFree(inputDataDev);
  695 + inputDataDev = nullptr;
538 696  
539 697 void *outputDataDev = acldvppGetPicDescData(output);
540 698 uint32_t outputSize = acldvppGetPicDescSize(output);
... ... @@ -553,21 +711,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
553 711 }
554 712  
555 713 bool bCached = false;
556   -
557 714 if(width > 0 && height > 0 && outputSize > 0){
558   - if (!m_bReal) {
559   - while(m_bRunning) {
560   - // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待
561   - m_decoded_data_queue_mtx.lock();
562   - if(m_decoded_data_queue.size() > 5){
563   - m_decoded_data_queue_mtx.unlock();
564   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
565   - continue;
566   - }
567   - m_decoded_data_queue_mtx.unlock();
568   - break;
569   - }
570   - }
571 715  
572 716 // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl;
573 717 // last_ts = get_cur_time_ms();
... ... @@ -610,255 +754,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
610 754 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
611 755 }
612 756  
613   -void DvppDecoder::decode_thread(){
614   -
615   - long startTime = UtilTools::get_cur_time_ms();
616   -
617   - int ret = -1;
618   -
619   - m_bExitReportThd = false;
620   - pthread_t report_thread;
621   - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
622   - if(ret != 0){
623   - LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
624   - return;
625   - }
626   -
627   - m_bExitDisplayThd = false;
628   - pthread_t display_thread;
629   - pthread_create(&display_thread,0,
630   - [](void* arg)
631   - {
632   - DvppDecoder* a=(DvppDecoder*)arg;
633   - a->display_thread();
634   - return (void*)0;
635   - }
636   - ,this);
637   -
638   - aclrtSetDevice(m_dvpp_deviceId);
639   - aclrtContext ctx;
640   - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
641   - if (ret != ACL_ERROR_NONE) {
642   - // cout << "aclrtCreateContext failed " << endl;
643   - LOG_ERROR("aclrtCreateContext failed !");
644   - return ;
645   - }
646   -
647   - // 创建aclvdecChannelDesc类型的数据
648   - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
649   - if (vdecChannelDesc == nullptr) {
650   - LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
651   - return;
652   - }
653   - do{
654   - // 创建 channel dec结构体
655   - // 通道ID在dvpp层面为0~31
656   - CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
657   - CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
658   - CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
659   - CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");
660   - CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
661   - CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
662   -
663   - uint64_t frame_count = 0;
664   - bool bBreak = false;
665   - while (!m_bExitDecodeThd) {
666   - if (m_bPause){
667   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
668   - continue;
669   - }
670   - int ret = sentFrame(vdecChannelDesc, frame_count);
671   - if(ret == 2){
672   - bBreak = true;
673   - break;
674   - }else if(ret == 1){
675   - continue;
676   - }
677   -
678   - frame_count++;
679   - }
680   -
681   - // 尽量保证数据全部解码完成
682   - int sum = 0;
683   - if(!bBreak){
684   - aclrtSetDevice(m_dvpp_deviceId);
685   - aclrtSetCurrentContext(ctx);
686   - while(m_pktQueue.size() > 0){
687   - int ret = sentFrame(vdecChannelDesc, frame_count);
688   - if(ret == 2){
689   - break;
690   - }
691   - std::this_thread::sleep_for(std::chrono::milliseconds(3));
692   - sum++;
693   - if(sum > 40){
694   - // 避免卡死
695   - break;
696   - }
697   - }
698   - }
699   -
700   - sendVdecEos(vdecChannelDesc);
701   -
702   - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
703   - }while(0);
704   -
705   - // 退出 report thread
706   - while(m_bRunning && m_vdecQueue.size() > 0) {
707   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
708   - }
709   - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
710   - // report_thread 需后于destroy退出
711   - m_bExitReportThd = true;
712   - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed");
713   -
714   - // 退出 display thread
715   - while(m_bRunning && m_decoded_data_queue.size() > 0) {
716   - std::this_thread::sleep_for(std::chrono::milliseconds(5));
717   - }
718   - m_bExitDisplayThd = true;
719   - CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "display_thread join failed");
720   -
721   - // 最后清理一遍未解码的数据
722   - m_vdecQueue_mutex.lock();
723   - while(m_vdecQueue.size() > 0){
724   - void* inputData = m_vdecQueue.front();
725   - acldvppFree(inputData);
726   - inputData = nullptr;
727   - m_vdecQueue.pop();
728   - }
729   - m_vdecQueue_mutex.unlock();
730   -
731   - release_dvpp();
732   -
733   - ret = aclrtDestroyContext(ctx);
734   - if(ret != ACL_ERROR_NONE){
735   - LOG_ERROR("aclrtDestroyContext failed !");
736   - }
737   -
738   - LOG_INFO("[{}]- decode thread exit.", m_dec_name);
739   -}
740   -
741   -int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
742   -
743   - // 此处需要判断 m_vdecQueue 队列长度,避免占用过多显存
744   - m_vdecQueue_mutex.lock();
745   - if(m_vdecQueue.size() > 20){
746   - m_vdecQueue_mutex.unlock();
747   - std::this_thread::sleep_for(std::chrono::milliseconds(2));
748   - return 1;
749   - }
750   - m_vdecQueue_mutex.unlock();
751   -
752   - DataPacket * data_pkt = nullptr;
753   - m_pktQueue_mutex.lock();
754   - if(m_pktQueue.size() <= 0){
755   - m_pktQueue_mutex.unlock();
756   - std::this_thread::sleep_for(std::chrono::milliseconds(10));
757   - return 1;
758   - }
759   - data_pkt = m_pktQueue.front();
760   - m_pktQueue.pop();
761   - m_pktQueue_mutex.unlock();
762   -
763   - // 解码
764   - void *vdecInputbuf = nullptr;
765   - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
766   - if(ACL_ERROR_NONE != ret){
767   - LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
768   - delete data_pkt;
769   - data_pkt = nullptr;
770   - return 2;
771   - }
772   -
773   - AVPacket* pkt = data_pkt->pkt;
774   - ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
775   - if(ACL_ERROR_NONE != ret){
776   - LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
777   - delete data_pkt;
778   - data_pkt = nullptr;
779   - return 2;
780   - }
781   -
782   - void *vdecOutputBuf = nullptr;
783   - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
784   - if(ret != ACL_ERROR_NONE){
785   - LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
786   - delete data_pkt;
787   - data_pkt = nullptr;
788   - return 2;
789   - }
790   -
791   - acldvppStreamDesc *input_stream_desc = nullptr;
792   - acldvppPicDesc *output_pic_desc = nullptr;
793   - do{
794   - input_stream_desc = acldvppCreateStreamDesc();
795   - if (input_stream_desc == nullptr) {
796   - LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
797   - break;
798   - }
799   - output_pic_desc = acldvppCreatePicDesc();
800   - if (output_pic_desc == nullptr) {
801   - LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
802   - break;
803   - }
804   - CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
805   - CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
806   - CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
807   - CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
808   -
809   - Vdec_CallBack_UserData *user_data = NULL;
810   - user_data = new Vdec_CallBack_UserData;
811   - user_data->frameId = frame_count;
812   - user_data->frame_nb = data_pkt->frame_nb;
813   - // user_data->startTime = startTime;
814   - user_data->sendTime = UtilTools::get_cur_time_ms();
815   - user_data->self = this;
816   -
817   - m_vdecQueue_mutex.lock();
818   - ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
819   - delete data_pkt;
820   - data_pkt = nullptr;
821   - if(ret != ACL_ERROR_NONE){
822   - LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
823   - m_vdecQueue_mutex.unlock();
824   - delete user_data;
825   - user_data = nullptr;
826   - break;
827   - }
828   -
829   - m_vdecQueue.push(vdecInputbuf);
830   - m_vdecQueue_mutex.unlock();
831   -
832   - return 0;
833   - }while (0);
834   -
835   - if(data_pkt != nullptr){
836   - delete data_pkt;
837   - data_pkt = nullptr;
838   - }
839   -
840   - if (vdecInputbuf){
841   - acldvppFree(vdecInputbuf);
842   - vdecInputbuf = nullptr;
843   - }
844   -
845   - // 报错情形
846   - if(input_stream_desc){
847   - CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
848   - }
849   -
850   - if (vdecOutputBuf){
851   - acldvppFree(vdecOutputBuf);
852   - vdecOutputBuf = nullptr;
853   - }
854   -
855   - if(output_pic_desc){
856   - CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
857   - }
858   -
859   - return 1;
860   -}
861   -
862 757 bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
863 758 // create stream desc
864 759 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
... ...
src/decoder/dvpp/DvppDecoder.h
... ... @@ -66,13 +66,14 @@ private:
66 66 void release_ffmpeg();
67 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 70 bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
72 71 void release_dvpp();
73 72  
74 73 void display_thread();
75 74  
  75 + int getVdecType(int videoType, int profile);
  76 +
76 77 private:
77 78 FFDecConfig m_cfg;
78 79 string m_dec_name;
... ... @@ -86,7 +87,6 @@ private:
86 87  
87 88 bool m_bExitReportThd{false};
88 89 bool m_bExitDisplayThd{false};
89   - bool m_bExitDecodeThd{false};
90 90  
91 91 // 读取数据
92 92 AVStream* stream{nullptr};
... ... @@ -105,17 +105,11 @@ private:
105 105  
106 106 bool m_dec_keyframe;
107 107  
108   - mutex m_pktQueue_mutex;
109   - queue<DataPacket*> m_pktQueue;
110   -
111 108 // 解码
112 109 int m_dvpp_deviceId {-1};
113 110 int m_dvpp_channel {-1};
114 111 aclrtContext m_context{nullptr};
115   - acldvppStreamFormat enType;
116   -
117   - mutex m_vdecQueue_mutex;
118   - queue<void*> m_vdecQueue;
  112 + acldvppStreamFormat m_enType;
119 113  
120 114 const void * m_postDecArg;
121 115 POST_DECODE_CALLBACK post_decoded_cbk {nullptr};
... ...
src/decoder/dvpp/VpcPicConverter.cpp
... ... @@ -3,6 +3,15 @@
3 3  
4 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 15 VpcPicConverter::VpcPicConverter(){
7 16  
8 17 }
... ...
src/decoder/dvpp/dvpp_headers.h
... ... @@ -26,15 +26,6 @@
26 26 #include "acl/acl.h"
27 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 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 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 249 \ No newline at end of file
... ...