Commit 25a4a27747c9010d59f34e921f83f250f86f47ea

Authored by Hu Chunming
1 parent 7c962865

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

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/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,136 +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   - 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 425 [](void* arg)
341 426 {
342 427 DvppDecoder* a=(DvppDecoder*)arg;
343   - a->decode_thread();
  428 + a->display_thread();
344 429 return (void*)0;
345 430 }
346 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 491 av_packet_free(&pkt);
390 492 pkt = nullptr;
391 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 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 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 565 m_recoderManager.close();
  566 +
  567 + release_ffmpeg();
  568 + release_dvpp();
  569 +
  570 + m_bFinished = true;
452 571  
453 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 660 void DvppDecoder::doProcessReport(){
... ... @@ -481,9 +674,6 @@ void DvppDecoder::doProcessReport(){
481 674 return ;
482 675 }
483 676  
484   - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");
485   - // 阻塞等待vdec线程开始
486   -
487 677 while (!m_bExitReportThd) {
488 678 aclrtProcessReport(1000);
489 679 }
... ... @@ -495,40 +685,14 @@ void DvppDecoder::doProcessReport(){
495 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 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 697 void *outputDataDev = acldvppGetPicDescData(output);
534 698 uint32_t outputSize = acldvppGetPicDescSize(output);
... ... @@ -547,35 +711,16 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
547 711 }
548 712  
549 713 bool bCached = false;
550   -
551 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 715 // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl;
567 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 725 if(m_bSnapShoting){
581 726 // 缓存snapshot
... ... @@ -604,246 +749,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o
604 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 752 bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
848 753 // create stream desc
849 754 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
... ... @@ -872,7 +777,7 @@ bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
872 777  
873 778 void DvppDecoder::display_thread(){
874 779 LOG_INFO("[{}]- display_thread start...", m_dec_name);
875   - while(m_bRunning) {
  780 + while(!m_bExitDisplayThd) {
876 781 m_decoded_data_queue_mtx.lock();
877 782 if(m_decoded_data_queue.size() <= 0) {
878 783 m_decoded_data_queue_mtx.unlock();
... ... @@ -898,7 +803,7 @@ void DvppDecoder::display_thread(){
898 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 809 void DvppDecoder::release_dvpp(){
... ...
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;
... ... @@ -84,6 +85,7 @@ private:
84 85 bool m_bRunning{false};
85 86 bool m_bPause{false};
86 87 bool m_bExitReportThd{false};
  88 + bool m_bExitDisplayThd{false};
87 89  
88 90 // 读取数据
89 91 AVStream* stream{nullptr};
... ... @@ -102,17 +104,11 @@ private:
102 104  
103 105 bool m_dec_keyframe;
104 106  
105   - mutex m_pktQueue_mutex;
106   - queue<DataPacket*> m_pktQueue;
107   -
108 107 // 解码
109 108 int m_dvpp_deviceId {-1};
110 109 int m_dvpp_channel {-1};
111 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 113 const void * m_postDecArg;
118 114 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
... ...