Commit 0b4cd5d5749641591a1bd95870832886b7437d9d

Authored by Hu Chunming
1 parent d98e0880

完成轨迹定时抓拍

Showing 90 changed files with 13620 additions and 0 deletions
doc/Atlas人车物检测SDK说明_v0.0.0.pdf 0 → 100644
No preview for this file type
src/Makefile 0 → 100644
  1 +XX = g++
  2 +
  3 +
  4 +PROJECT_ROOT= /home/cmhu/vpt_ascend
  5 +
  6 +DEPEND_DIR = $(PROJECT_ROOT)/bin
  7 +SRC_ROOT = $(PROJECT_ROOT)/src
  8 +
  9 +TARGET= $(PROJECT_ROOT)/bin/vpt_proj
  10 +
  11 +THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
  12 +SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release
  13 +OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv-4.5.4/release
  14 +JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release
  15 +FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.2.2/release
  16 +
  17 +DEFS = -DENABLE_DVPP_INTERFACE
  18 +
  19 +include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/x86_64-linux/include \
  20 + -I $(SPDLOG_ROOT)/include \
  21 + -I $(SRC_ROOT)/common \
  22 + -I $(OPENCV_ROOT)/include/opencv4 \
  23 + -I $(JSON_ROOT)/include \
  24 + -I $(FFMPEG_ROOT)/include \
  25 +
  26 +lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \
  27 + -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \
  28 + -L/usr/local/Ascend/ascend-toolkit/latest/runtime/lib64 \
  29 + -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \
  30 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \
  31 +
  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 -lopencv_dnn -lopencv_calib3d -lhybrid_executor -lregister -ldavinci_executor -lge_common -lge_common_base \
  33 + -lplatform -lgraph_base -lqos_manager
  34 +
  35 +LIBS= -L $(SPDLOG_ROOT)/lib -l:libspdlog.a \
  36 + -L $(DEPEND_DIR) -lvpt_det -lsycheck \
  37 + -L $(OPENCV_ROOT)/lib -lopencv_video -lopencv_highgui -lopencv_imgproc -lopencv_core -lopencv_features2d -lopencv_flann\
  38 + -L $(JSON_ROOT)/lib -ljsoncpp \
  39 + -L $(JSON_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
  40 +
  41 +CXXFLAGS= -g -O0 -fPIC $(include_dir) $(lib_dir) $(lib) $(LIBS) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wall -Wno-deprecated -Wdeprecated-declarations -Wl,-Bsymbolic -ldl
  42 +
  43 +
  44 +
  45 +SRCS:=$(wildcard $(SRC_ROOT)/ai_platform/*.cpp) \
  46 + $(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \
  47 + $(wildcard $(SRC_ROOT)/decoder/dvpp/*.cpp) \
  48 + $(wildcard $(SRC_ROOT)/demo/*.cpp) \
  49 + $(wildcard $(SRC_ROOT)/ai_engine_module/sort/*.cpp) \
  50 + $(wildcard $(SRC_ROOT)/ai_engine_module/*.cpp) \
  51 + $(wildcard $(SRC_ROOT)/util/*.cpp) \
  52 + $(wildcard $(SRC_ROOT)/reprocessing_module/*.cpp) \
  53 +
  54 +OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
  55 +
  56 +
  57 +$(TARGET):$(OBJS)
  58 + rm -f $(TARGET)
  59 + $(XX) -o $@ $^ $(CXXFLAGS)
  60 + rm -f *.o
  61 +
  62 +%.o:$(SRC_ROOT)/decoder/dvpp/%.cpp
  63 + $(XX) $(CXXFLAGS) -c $<
  64 +
  65 +%.o:$(SRC_ROOT)/decoder/interface/%.cpp
  66 + $(XX) $(CXXFLAGS) -c $<
  67 +
  68 +%.o:$(SRC_ROOT)/ai_platform/%.cpp
  69 + $(XX) $(CXXFLAGS) -c $<
  70 +
  71 +%.o:$(SRC_ROOT)/ai_engine_module/sort/%.cpp
  72 + $(XX) $(CXXFLAGS) -c $<
  73 +
  74 +%.o:$(SRC_ROOT)/ai_engine_module/%.cpp
  75 + $(XX) $(CXXFLAGS) -c $<
  76 +
  77 +%.o:$(SRC_ROOT)/demo/%.cpp
  78 + $(XX) $(CXXFLAGS) -c $<
  79 +
  80 +%.o:$(SRC_ROOT)/util/%.cpp
  81 + $(XX) $(CXXFLAGS) -c $<
  82 +
  83 +%.o:$(SRC_ROOT)/reprocessing_module/%.cpp
  84 + $(XX) $(CXXFLAGS) -c $<
  85 +
  86 +clean:
  87 + rm -f *.o $(TARGET)
0 \ No newline at end of file 88 \ No newline at end of file
src/ai_engine_module/VPTProcess.cpp 0 → 100644
  1 +#include "VPTProcess.h"
  2 +#include "../common/logger.hpp"
  3 +#include "../ai_platform/task_param_manager.h"
  4 +
  5 +#include <stdlib.h>
  6 +#include <time.h>
  7 +#include <fstream>
  8 +
  9 +#include "vpt.h"
  10 +#include "../ai_platform/macro_definition.h"
  11 +#include "../ai_platform/det_obj_header.h"
  12 +
  13 +#include "opencv2/opencv.hpp"
  14 +
  15 +#include "../util/vpc_util.h"
  16 +
  17 +VPTProcess::VPTProcess(){
  18 + m_max_batchsize = 16;
  19 +}
  20 +
  21 +VPTProcess::~VPTProcess(){
  22 + release();
  23 +}
  24 +
  25 +/* 算法初始化 */
  26 +int VPTProcess::init(VPTProcess_PARAM vparam){
  27 +
  28 + LOG_INFO("vpt 版本:{}", vpt_get_version());
  29 +
  30 + vpt_param param;
  31 + param.modelNames = "./models/vpt0715_310p.om";
  32 + param.threshold = vparam.threshold;
  33 + param.devId = vparam.gpuid;
  34 + param.isTrk = false;
  35 +
  36 + m_devId = param.devId;
  37 + ACL_CALL(aclrtSetDevice(m_devId), ACL_ERROR_NONE, -1);
  38 + ACL_CALL(aclrtCreateContext(&m_algorthim_ctx, m_devId), ACL_ERROR_NONE, -1);
  39 +
  40 + int ret = vpt_init(&m_det_handle, param);
  41 + if(ret != 0){
  42 + LOG_DEBUG("vpt init error.");
  43 + return -1;
  44 + }
  45 +
  46 + return 0;
  47 +}
  48 +
  49 +/* 算法计算 */
  50 +int VPTProcess::process_gpu(sy_img * batch_img, vector<string>& tasklist,
  51 + vector<onelevel_det_result>& result, vector<vector<int>>& deleteObjectID, vector<vector<onelevel_det_result>>& unUsedResult)
  52 +{
  53 + int batchsize = tasklist.size();
  54 +
  55 + if (result.empty())
  56 + result.resize(batchsize);
  57 +
  58 + /* 结果结构体初始化 */
  59 + // vpt_result *vpt_det_result = new vpt_result[batchsize];
  60 + // for (int b = 0; b < batchsize; b++){
  61 + // vpt_det_result[b].obj_count_ = 0;
  62 + // vpt_det_result[b].obj_results_ = new vpt_obj_result[MAX_DET_COUNT];
  63 + // }
  64 +
  65 + do{
  66 + /* 路数太多时 按照最大batchsize数 拆批次运行 */
  67 + // int cur_batch_size = m_max_batchsize;
  68 + // int cycleTimes = batchsize / cur_batch_size + (batchsize % cur_batch_size == 0 ? 0 : 1);
  69 +
  70 + // for (int c = 0; c < cycleTimes; c++){
  71 +
  72 + // int real_batchsize = c == cycleTimes - 1 ? (batchsize - cur_batch_size*c) : cur_batch_size;
  73 + // int startbatch = c*cur_batch_size;
  74 +
  75 + // vpt_result *real_res = vpt_det_result + startbatch;
  76 +
  77 + // aclrtSetDevice(m_devId);
  78 + // int ret = aclrtSetCurrentContext(m_algorthim_ctx);
  79 + // if(ACL_ERROR_NONE != ret){
  80 + // break;
  81 + // }
  82 + // ret = vpt_batch(m_det_handle, batch_img + startbatch, real_batchsize, &real_res);
  83 + // if(ret != 0){
  84 + // break;
  85 + // }
  86 + // }
  87 +
  88 +
  89 + aclrtSetDevice(m_devId);
  90 + int ret = aclrtSetCurrentContext(m_algorthim_ctx);
  91 + if(ACL_ERROR_NONE != ret){
  92 + break;
  93 + }
  94 + vpt_result *vpt_det_result;
  95 + ret = vpt_batch(m_det_handle, batch_img, batchsize, &vpt_det_result);
  96 + if(ret != 0){
  97 + break;
  98 + }
  99 +
  100 + vector <vector< vector <float>>> detectResult(batchsize); // sort
  101 +
  102 + /* 将检测的结果放进数组 转换为跟踪的输入需要(若为人脸 则检测结果可能跟多,比如需要带上ldmk点) */
  103 + // filter by threshold.
  104 + for (int b = 0; b < batchsize; b++)
  105 + {
  106 + vpt_result cur_result = vpt_det_result[b];
  107 +
  108 + for (int c = 0; c < cur_result.obj_count_ && c < MAX_OBJ_COUNT; c++)
  109 + {
  110 + float x1 = vpt_det_result[b].obj_results_[c].obj_rect.left_;
  111 + float y1 = vpt_det_result[b].obj_results_[c].obj_rect.top_;
  112 + float x2 = vpt_det_result[b].obj_results_[c].obj_rect.left_ + vpt_det_result[b].obj_results_[c].obj_rect.width_;
  113 + float y2 = vpt_det_result[b].obj_results_[c].obj_rect.top_ + vpt_det_result[b].obj_results_[c].obj_rect.height_;
  114 +
  115 + float class_id = vpt_det_result[b].obj_results_[c].obj_index;
  116 + float score = vpt_det_result[b].obj_results_[c].obj_score;
  117 +
  118 + if (score >= THRESHOLD)
  119 + {
  120 + vector <float> obj;
  121 + obj.push_back(x1);
  122 + obj.push_back(y1);
  123 + obj.push_back(x2);
  124 + obj.push_back(y2);
  125 + obj.push_back(score);
  126 + obj.push_back(class_id);
  127 + detectResult[b].push_back(obj);
  128 + }
  129 + }
  130 + }
  131 +
  132 + bool isUseDet = true;
  133 + for (size_t detectIndex = 0; detectIndex < batchsize; detectIndex++) {
  134 + string task_id = tasklist[detectIndex];
  135 +
  136 + if (! taskTrackers[task_id].tracker.GetState())
  137 + continue;
  138 +
  139 + Sort &cur_sort = taskTrackers[task_id].tracker;
  140 + isUseDet = true;
  141 +
  142 + const float maxLen = std::sqrt(batch_img[detectIndex].w_ * batch_img[detectIndex].w_ + batch_img[detectIndex].h_ * batch_img[detectIndex].h_); //-modified by zsh 220719
  143 + /* FusionInterval是跳帧参数,以十类人车物为例,一般跳5帧,所以第一帧检测,后续四帧纯跟踪 */
  144 + for (int j = 0; j < taskTrackers[task_id].tracker.FusionInterval; j++)
  145 + {
  146 + /* 跟踪:第一帧 带检测框信息的跟踪,取结果返回 */
  147 + if (j == 0)
  148 + {
  149 + int objCount = cur_sort.update_v2(isUseDet, /*save lk = */false, /*center_dist = */true, maxLen, detectResult[detectIndex], result[detectIndex].obj, deleteObjectID[detectIndex]);
  150 + result[detectIndex].obj_count = objCount;
  151 + result[detectIndex].task_id = task_id;
  152 +
  153 + vector<vector<float>>().swap(detectResult[detectIndex]);
  154 + detectResult[detectIndex].clear();
  155 + isUseDet = false;
  156 + } else /* 跟踪:后四帧 纯粹跟踪 纯跟踪结果不返回 */
  157 + {
  158 + onelevel_det_result un_result;
  159 + //un_result.obj_count = cur_sort.update(isUseDet, false, detectResult[detectIndex], un_result.obj, deleteObjectID[detectIndex]);
  160 + un_result.obj_count = cur_sort.update_v2(isUseDet, false, true, maxLen, detectResult[detectIndex], un_result.obj, deleteObjectID[detectIndex]);
  161 + }
  162 + }
  163 + }
  164 +
  165 + vector <vector< vector <float>>>().swap(detectResult); // free memory.
  166 + } while (0);
  167 +
  168 + // if(vpt_det_result)
  169 + // {
  170 + // for (int b = 0; b < batchsize; b++)
  171 + // {
  172 + // delete[] vpt_det_result[b].obj_results_;
  173 + // }
  174 + // delete[] vpt_det_result;
  175 + // }
  176 +
  177 + return 0;
  178 +}
  179 +
  180 +
  181 +/* 算法句柄 资源释放 */
  182 +void VPTProcess::release(){
  183 + if (m_det_handle){
  184 + vpt_release(&m_det_handle);
  185 + m_det_handle = NULL;
  186 + }
  187 + if(m_algorthim_ctx){
  188 + aclrtDestroyContext(m_algorthim_ctx);
  189 + }
  190 +}
  191 +
  192 +// 221117byzsh
  193 +void VPTProcess::addTaskTracker(const string taskID, double rWidth, double rHeight, int skip_frame)
  194 +{
  195 + TaskTracker t;
  196 + t.TaskID = taskID;
  197 + t.ratioWidth = rWidth;
  198 + t.ratioHeight = rHeight;
  199 + t.tracker.FusionInterval = skip_frame;
  200 +
  201 + taskTrackers[taskID] = t;
  202 +}
  203 +
  204 +/* 任务结束跟踪器 */
  205 +bool VPTProcess::finishTaskTracker(const string taskID)
  206 +{
  207 + taskTrackers.erase(taskID);
  208 + return true;
  209 +}
0 \ No newline at end of file 210 \ No newline at end of file
src/ai_engine_module/VPTProcess.h 0 → 100644
  1 +/*******************************************************************************************
  2 +* Version: VPT_x64_V2.0.0_20170705
  3 +* CopyRight: 中科院自动化研究所模式识别实验室图像视频组
  4 +* UpdateDate: 20170705
  5 +* Content: 人车物监测跟踪
  6 +********************************************************************************************/
  7 +#pragma once
  8 +#include <iostream>
  9 +#include <vector>
  10 +#include "sort/Sort.h"
  11 +#include "acl/acl.h"
  12 +#include "acl/ops/acl_dvpp.h"
  13 +
  14 +using namespace std;
  15 +
  16 +// #define THRESHOLD 0.45
  17 +#define THRESHOLD 0.3
  18 +
  19 +struct TaskTracker
  20 +{
  21 + string TaskID;
  22 + double ratioWidth;
  23 + double ratioHeight;
  24 + Sort tracker;
  25 +};
  26 +
  27 +
  28 +typedef struct VPTProcess_PARAM
  29 +{
  30 + int gpuid; //指定显卡id
  31 + float threshold;
  32 + int max_batch;
  33 +
  34 + char* serialize_file;
  35 + char* auth_license;
  36 + VPTProcess_PARAM() : gpuid(0), threshold(0.6), max_batch(20) {};
  37 +}VPTProcess_PARAM;
  38 +
  39 +class VPTProcess {
  40 +
  41 +public:
  42 + VPTProcess();
  43 + ~VPTProcess();
  44 + /*************************************************************************
  45 + * FUNCTION: VPT_Init
  46 + * PURPOSE: 初始化
  47 + * PARAM:
  48 + [in] vparam 参数
  49 + * RETURN: handle
  50 + * NOTES:
  51 + *************************************************************************/
  52 + int init(VPTProcess_PARAM vparam);
  53 +
  54 +
  55 + /**
  56 + * @brief 人车物检测跟踪
  57 + *
  58 + * @param handle [in]
  59 + * @param batch_img [in]
  60 + * @param batchsize [in]
  61 + * @param result [in]
  62 + * @param deleteObjectID [in]
  63 + * @param unUsedResult [in]
  64 + * @param class_label_count [in/out]
  65 + * @return int -1:图像错误; 其他:检测到的个数
  66 + */
  67 + int process_gpu(sy_img * batch_img, vector<string>& tasklist,
  68 + vector<onelevel_det_result>& result, vector<vector<int>>& deleteObjectID, vector<vector<onelevel_det_result>>& unUsedResult);
  69 +
  70 +
  71 + /*************************************************************************
  72 + * FUNCTION: VPT_Release
  73 + * PURPOSE: 资源释放
  74 + * PARAM:
  75 + [in] handle - 处理句柄
  76 + * RETURN: NULL
  77 + * NOTES:
  78 + *************************************************************************/
  79 + void release();
  80 +
  81 +
  82 + void addTaskTracker(const string taskID, double rWidth =1, double rHeight=1, int skip_frame=5); //221117byzsh
  83 + bool finishTaskTracker(const string taskID);
  84 +
  85 +private:
  86 + int m_devId;
  87 + aclrtContext m_algorthim_ctx;
  88 +
  89 + void* m_det_handle{nullptr};
  90 + float threshold{0.6};
  91 + int m_max_batchsize;
  92 + map<string, TaskTracker> taskTrackers;
  93 +};
src/ai_engine_module/sort/CycleQueue.h 0 → 100644
  1 +#include <iostream>
  2 +
  3 +using namespace std;
  4 +
  5 +#define MAX_LENGTH 100
  6 +
  7 +typedef struct TRACK_POINT
  8 +{
  9 + int x;
  10 + int y;
  11 +}TRACK_POINT;
  12 +
  13 +//template <class T>
  14 +class cycleQueue
  15 +{
  16 +private:
  17 + unsigned int m_size;
  18 + int m_front;
  19 + int m_rear;
  20 + TRACK_POINT m_data[MAX_LENGTH];
  21 +
  22 + bool firstPush;
  23 + bool full_size;
  24 +
  25 +public:
  26 +
  27 + cycleQueue() {}
  28 +
  29 + cycleQueue(unsigned size)
  30 + :m_size(size),
  31 + m_front(0),
  32 + m_rear(0)
  33 + {
  34 + //m_data = new TRACK_POINT[size];
  35 + full_size = false;
  36 + firstPush = true;
  37 + }
  38 +
  39 + void set_param(unsigned size)
  40 + {
  41 + m_size = size;
  42 + //m_data = new TRACK_POINT[size];
  43 + full_size = false;
  44 + firstPush = true;
  45 + m_front = 0;
  46 + m_rear = 0;
  47 + }
  48 +
  49 + ~cycleQueue()
  50 + {
  51 + //delete[] m_data;
  52 + }
  53 +
  54 + bool isEmpty()
  55 + {
  56 + return m_front == m_rear;
  57 + }
  58 +
  59 + bool isFull()
  60 + {
  61 + return m_front == (m_rear + 1) % m_size;
  62 + }
  63 +
  64 + int getFront()
  65 + {
  66 + return m_front;
  67 + }
  68 +
  69 + int getRear()
  70 + {
  71 + return m_rear;
  72 + }
  73 +
  74 + int size()
  75 + {
  76 + if (full_size) return m_size;
  77 + else if (m_rear == m_front && firstPush == false) return m_size;
  78 + else return m_rear - m_front;
  79 + }
  80 +
  81 + void push(TRACK_POINT ele)throw(bad_exception)
  82 + {
  83 + if (m_front == m_rear && firstPush==false)
  84 + {
  85 + m_front = (m_front + 1) % m_size;
  86 + full_size = true;
  87 + //cout << "full_size" << endl;
  88 + }
  89 +
  90 + m_data[m_rear] = ele;
  91 + m_rear = (m_rear + 1) % m_size;
  92 + firstPush = false;
  93 + }
  94 +
  95 + TRACK_POINT pop() throw(bad_exception)
  96 + {
  97 + if (isEmpty())
  98 + {
  99 + throw bad_exception();
  100 + }
  101 + TRACK_POINT tmp = m_data[m_front];
  102 + m_front = (m_front + 1) % m_size;
  103 + return tmp;
  104 + }
  105 +
  106 + TRACK_POINT& get(int i)
  107 + {
  108 + //T tmp = m_data[i];
  109 + return m_data[i];
  110 + }
  111 +};
0 \ No newline at end of file 112 \ No newline at end of file
src/ai_engine_module/sort/HungarianAlgorithm.cpp 0 → 100644
  1 +#include <vector>
  2 +#include <assert.h>
  3 +#include "HungarianAlgorithm.h"
  4 +
  5 +#include <opencv2/imgproc/types_c.h>
  6 +
  7 +using namespace std;
  8 +
  9 +
  10 +// B = A( extractRows, extractCols )
  11 +// Require:
  12 +// extractRows.size()==A.rows, extractCols.size()==A.cols
  13 +// sum(extractRows)==B.rows, sum(extractCols)==B.cols
  14 +void extractGrids(const cv::Mat &A, const vector<bool> &extractRows, const vector<bool> &extractCols, cv::Mat &B)
  15 +{
  16 + typedef float ValueType;
  17 + ValueType *pt1 = (ValueType*)A.data, *pt2 = (ValueType*)B.data, *pt3, *pt4;
  18 + const int step1 = A.step1(), rows = A.rows, cols = A.cols, step2 = B.step1();
  19 + vector<bool>::const_iterator it1, it2, it3 = extractRows.end(), it4 = extractCols.end();
  20 + for (it1 = extractRows.begin(); it1 != it3; pt1 += step1){
  21 + pt3 = pt1;
  22 + if (*(it1++)){
  23 + pt4 = pt2;
  24 + for (it2 = extractCols.begin(); it2 != it4; pt3++)
  25 + if (*(it2++))
  26 + *(pt4++) = *pt3;
  27 + pt2 += step2;
  28 + }
  29 + }
  30 +}
  31 +
  32 +// B = A( extract )
  33 +// Require:
  34 +// min(A.rows,A.cols) ==1
  35 +// if(A.rows)==1, then require: A.cols==extract.size(), B.rows==1, sum(extract)==B.cols
  36 +// if(A.cols)==1, then require: A.rows==extract.size(), B.cols==1, sum(extract)==B.rows
  37 +void extractDots(const cv::Mat &A, const vector<bool> &extract, cv::Mat &B)
  38 +{
  39 + assert(A.rows == 1 || A.cols == 1);
  40 + typedef float ValueType;
  41 + ValueType *pt1 = (ValueType*)A.data, *pt2 = (ValueType*)B.data;
  42 + vector<bool>::const_iterator it = extract.begin(), it2 = extract.end();
  43 + if (A.rows == 1){
  44 + for (; it != it2; pt1++)
  45 + if (*(it++))
  46 + *(pt2++) = *pt1;
  47 + }
  48 + else{
  49 + int step1 = A.step1(), step2 = B.step1();
  50 + for (; it != it2; pt1 += step1)
  51 + if (*(it++)){
  52 + *pt2 = *pt1;
  53 + pt2 += step2;
  54 + }
  55 + }
  56 +}
  57 +
  58 +
  59 +/* Initial Matlab code comes from:
  60 +http://www.mathworks.com/matlabcentral/fileexchange/20652-hungarian-algorithm-for-linear-assignment-problems--v2-3-
  61 +
  62 +Hungarian algorithm for matrix assignment problem.
  63 +costMat: there are (rows) works and (cols) jobs. costMat(i,j) means the cost of assigning job (j) to worker (i).
  64 +The problem is to solve a holistic optimization problem of assigning each worker a job!
  65 +The algorithm allows partial assignment - if there is no proper job for worker (i) we would set assignment(i) to -1, meaning no assignment for worker (i).
  66 +
  67 +Negatives in costMat means the corresponding assignments are forbidden.
  68 +*/
  69 +void munkres(cv::Mat &IoUMat, vector<int> &assignment)
  70 +{
  71 + assert(IoUMat.type() == CV_32FC1);
  72 + const int rows = IoUMat.rows, cols = IoUMat.cols;
  73 + assignment.assign(rows, -1);
  74 + // modify input port O - IoU = cost
  75 + cv::Mat O = cv::Mat::ones(rows, cols, CV_32FC1);
  76 + cv::Mat costMat(rows, cols, CV_32FC1);
  77 + absdiff(O, IoUMat, costMat);
  78 +
  79 + cv::Mat validMat(rows, cols, CV_8UC1);
  80 + compare(costMat, cv::Scalar(0), validMat, CV_CMP_GE);
  81 +
  82 + float *ptF, *ptF2;
  83 + uchar *ptU, *ptU2;
  84 + int stepGap;
  85 + int r, c, i;
  86 + unsigned j;
  87 + vector<bool>::iterator it1, it2;
  88 + vector<int>::iterator it3, it4;
  89 +
  90 + // validCol & validRow
  91 + vector<bool> validRow(rows, false);
  92 + ptU = validMat.data;
  93 + for (r = 0; r<rows; r++){
  94 + ptU2 = ptU;
  95 + for (c = 0; c<cols; c++) if (*(ptU2++)) break;
  96 + if (c<cols) validRow[r] = true;
  97 + ptU += validMat.step;
  98 + }
  99 + vector<bool> validCol(cols, false);
  100 + ptU = validMat.data;
  101 + for (c = 0; c<cols; c++){
  102 + ptU2 = ptU;
  103 + for (r = 0; r<rows; r++) if (*ptU2) break; else ptU2 += validMat.step;
  104 + if (r<rows) validCol[c] = true;
  105 + ptU++;
  106 + }
  107 +
  108 + // nRows & nCols
  109 + int nRows = 0, nCols = 0;
  110 + it1 = validRow.begin(), it2 = validCol.begin();
  111 + r = 0; while (r++<rows) if (*(it1++)) nRows++;
  112 + c = 0; while (c++<cols) if (*(it2++)) nCols++;
  113 + const int n = nRows>nCols ? nRows : nCols;
  114 + if (!n)
  115 + return;
  116 +
  117 + // sumValid & maxValid
  118 + float sumValid = 0, maxValid = -1.f;
  119 + ptF = (float*)costMat.data;
  120 + ptU = validMat.data;
  121 + stepGap = validMat.step - validMat.cols;
  122 + r = 0; while (r++<rows){
  123 + c = 0; while (c++<cols){
  124 + if (*(ptU++)){
  125 + float v = *(ptF++); sumValid += v;
  126 + if (v>maxValid) maxValid = v;
  127 + }
  128 + else ptF++;
  129 + } ptU += stepGap;
  130 + }
  131 +
  132 + // bigM & maxValid
  133 + maxValid *= 10.f;
  134 + float bigM = log10f(sumValid);
  135 + int power = (int)ceilf(bigM) + 1;
  136 + bigM = 1.f; //bigM = pow( 10, power );
  137 + for (i = 0; i<power; i++)
  138 + bigM *= 10;
  139 +
  140 + // costMat(~validMat) = bigM;
  141 + validMat = ~validMat; // validMat 其实已经是 invalidMat!
  142 + costMat.setTo(bigM, validMat);
  143 +
  144 + // dMat
  145 + cv::Mat dMat(n, n, CV_32FC1, cv::Scalar(maxValid));
  146 +
  147 +
  148 + cv::Mat temp = dMat(cv::Rect(0, 0, nCols, nRows)); //by zl
  149 + extractGrids(costMat, validRow, validCol, temp);
  150 +
  151 + //extractGrids(costMat, validRow, validCol, dMat(cv::Rect(0, 0, nCols, nRows)));
  152 +
  153 + //*************************************************
  154 + // Munkres' Assignment Algorithm starts here
  155 + //*************************************************
  156 +
  157 + // some storage for temporary usage
  158 + cv::Mat tmp1(n, n, CV_32FC1); // size and type accords with dMat
  159 + cv::Mat tmp2(n, n, CV_32FC1);
  160 + cv::Mat tmp3(n, n, CV_32FC1);
  161 + cv::Mat tmp4(n, n, CV_8UC1);
  162 + cv::Mat tmp5(n, 1, CV_32FC1);
  163 + cv::Mat tmp6(1, n, CV_32FC1);
  164 +
  165 + // STEP 1: Subtract the row minimum from each row.
  166 + // minR & minC
  167 + cv::Mat minR, minC;
  168 + reduce(dMat, minR, 1, CV_REDUCE_MIN);
  169 + repeat(minR, 1, n, tmp1);
  170 + tmp2 = dMat - tmp1;
  171 + reduce(tmp2, minC, 0, CV_REDUCE_MIN);
  172 + repeat(minC, n, 1, tmp2);
  173 +
  174 + // STEP 2: Find a zero of dMat. If there are no starred zeros in its column or row start the zero. Repeat for each zero
  175 + // zP
  176 + cv::Mat zP(n, n, CV_8UC1);
  177 + tmp3 = tmp1 + tmp2;
  178 + compare(dMat, tmp3, zP, CV_CMP_EQ);
  179 +
  180 + // starZ
  181 + vector<int> starZ(n, -1);
  182 + ptU = zP.data;
  183 + for (r = 0; r<n; r++){
  184 + ptU2 = ptU;
  185 + for (c = 0; c<n; c++){
  186 + if (*(ptU2++)){
  187 + starZ[r] = c;
  188 + memset(ptU, 0, r); // zP(r,:)=false;
  189 + zP.col(c) = cv::Scalar(0); // zP(:,c)=false;
  190 + break;
  191 + }
  192 + }
  193 + ptU += zP.step;
  194 + }
  195 +
  196 + int uZc, uZr;
  197 +
  198 + while (1){ // STEP 3
  199 + // Cover each column with a starred zero. If all the columns are covered then the matching is maximum
  200 + it3 = starZ.begin();
  201 + for (; it3 != starZ.end(); it3++) if (*it3<0) break;
  202 + if (it3 == starZ.end()) break;
  203 +
  204 + // validColumn & validRow & primeZ
  205 + vector<bool> noncoverColumn(n, true);
  206 + for (it3 = starZ.begin(); it3 != starZ.end(); it3++){
  207 + if (*it3<0) continue;
  208 + noncoverColumn[*it3] = false;
  209 + }
  210 + vector<bool> noncoverRow(n, true);
  211 + vector<int> primeZ(n, -1);
  212 +
  213 + // minC_uncovered & minR_uncovered
  214 + int cnt1 = 0, cnt2 = 0;
  215 + it1 = noncoverColumn.begin(), it2 = noncoverRow.begin();
  216 + i = 0; while (i++<n){
  217 + if (*(it1++)) cnt1++; // number of non-covered columns
  218 + if (*(it2++)) cnt2++; // number of non-covered rows
  219 + }
  220 + cv::Mat minR_uncovered = tmp5.rowRange(0, cnt2);
  221 + cv::Mat minC_uncovered = tmp6.colRange(0, cnt1);
  222 + extractDots(minR, noncoverRow, minR_uncovered);
  223 + extractDots(minC, noncoverColumn, minC_uncovered);
  224 +
  225 + // rIdx & cIdx
  226 + cv::Mat temp1 = tmp1(cv::Rect(0, 0, cnt1, cnt2));
  227 + cv::Mat temp2 = tmp2(cv::Rect(0, 0, cnt1, cnt2));
  228 + cv::Mat temp3 = tmp3(cv::Rect(0, 0, cnt1, cnt2));
  229 + cv::Mat temp4 = tmp4(cv::Rect(0, 0, cnt1, cnt2));
  230 + repeat(minR_uncovered, 1, cnt1, temp1);
  231 + repeat(minC_uncovered, cnt2, 1, temp2);
  232 + temp2 = temp1 + temp2;
  233 + extractGrids(dMat, noncoverRow, noncoverColumn, temp3);
  234 + compare(temp2, temp3, temp4, CV_CMP_EQ);
  235 + vector<int> rIdx, cIdx; // [rIdx,cIdx] = find(temp4);
  236 + ptU = temp4.data;
  237 + stepGap = temp4.step - temp4.cols;
  238 + for (r = 0; r<temp4.rows; r++){
  239 + for (c = 0; c<temp4.cols; c++){
  240 + if (*(ptU++)){
  241 + rIdx.push_back(r);
  242 + cIdx.push_back(c);
  243 + }
  244 + }
  245 + ptU += stepGap;
  246 + }
  247 +
  248 + while (1){ // STEP 4
  249 + // Find a non-covered zero and prime it. If there is no starred zero in the row containing this primed zero, Go to Step 5.
  250 + // Otherwise, cover this row and uncover the column containing the starred zero. Continue in this manner until there are no
  251 + // uncovered zeros left. Save the smallest uncovered value and Go to Step 6.
  252 +
  253 + // cR & cC
  254 + vector<int> cR, cC;
  255 + for (j = 0; j<noncoverRow.size(); j++)
  256 + if (noncoverRow[j])
  257 + cR.push_back(j);
  258 + for (j = 0; j<noncoverColumn.size(); j++)
  259 + if (noncoverColumn[j])
  260 + cC.push_back(j);
  261 +
  262 + // rIdx = cR(rIdx), cIdx = cC(cIdx);
  263 + for (j = 0; j<rIdx.size(); j++){
  264 + rIdx[j] = cR[rIdx[j]];
  265 + cIdx[j] = cC[cIdx[j]];
  266 + }
  267 +
  268 + int Step = 6;
  269 + while (!cIdx.empty()){
  270 + uZr = rIdx[0];
  271 + uZc = cIdx[0];
  272 + primeZ[uZr] = uZc;
  273 + int stz = starZ[uZr];
  274 + if (stz<0){
  275 + Step = 5;
  276 + break;
  277 + }
  278 + noncoverRow[uZr] = false;
  279 + noncoverColumn[stz] = true;
  280 + // rIdx(rIdx==uZr) = []
  281 + vector<int> rIdx2, cIdx2;
  282 + for (it3 = rIdx.begin(), it4 = cIdx.begin(); it3 != rIdx.end(); it3++, it4++)
  283 + if (*it3 != uZr){
  284 + rIdx2.push_back(*it3);
  285 + cIdx2.push_back(*it4);
  286 + }
  287 + rIdx = rIdx2, cIdx = cIdx2;
  288 + // cR = find(~coverRow);
  289 + cR.clear();
  290 + for (j = 0; j<noncoverRow.size(); j++)
  291 + if (noncoverRow[j])
  292 + cR.push_back(j);
  293 + // z = dMat(~coverRow,stz) == minR(~coverRow) + minC(stz);
  294 + int sz = cR.size();
  295 + minR_uncovered = tmp5.rowRange(0, sz);
  296 + extractDots(minR, noncoverRow, minR_uncovered);
  297 + minR_uncovered = minR_uncovered + cv::Scalar(minC.at<float>(stz));
  298 + temp1 = tmp1(cv::Rect(0, 0, 1, sz));
  299 + extractDots(dMat.col(stz), noncoverRow, temp1);
  300 + temp4 = tmp4(cv::Rect(0, 0, 1, sz));
  301 + compare(temp1, minR_uncovered, temp4, CV_CMP_EQ);
  302 + // rIdx = [rIdx(:);cR(z)];
  303 + for (i = 0, ptU = temp4.data; i<temp4.rows; i++, ptU += temp4.step)
  304 + if (*ptU){
  305 + rIdx.push_back(cR[i]);
  306 + cIdx.push_back(stz);
  307 + }
  308 + }
  309 +
  310 + if (Step == 6){
  311 + // STEP 6: Add the minimum uncovered value to every element of each covered
  312 + // row, and subtract it from every element of each uncovered column.
  313 + // Return to Step 4 without altering any stars, primes, or covered lines.
  314 + cnt1 = 0, cnt2 = 0;
  315 + it1 = noncoverColumn.begin(), it2 = noncoverRow.begin();
  316 + i = 0; while (i++<n){
  317 + if (*(it1++)) cnt1++; // number of non-covered columns
  318 + if (*(it2++)) cnt2++; // number of non-covered rows
  319 + }
  320 + temp1 = tmp1(cv::Rect(0, 0, cnt1, cnt2));
  321 + minR_uncovered = tmp5.rowRange(0, cnt2);
  322 + minC_uncovered = tmp6.colRange(0, cnt1);
  323 + extractGrids(dMat, noncoverRow, noncoverColumn, temp1);
  324 + extractDots(minR, noncoverRow, minR_uncovered);
  325 + extractDots(minC, noncoverColumn, minC_uncovered);
  326 +
  327 + // minVal & rIdx & cIdx
  328 + temp2 = tmp2(cv::Rect(0, 0, cnt1, cnt2));
  329 + temp3 = tmp3(cv::Rect(0, 0, cnt1, cnt2));
  330 + repeat(minR_uncovered, 1, cnt1, temp2);
  331 + repeat(minC_uncovered, cnt2, 1, temp3);
  332 + temp3 = temp1 - temp2 - temp3;
  333 + double minVal;
  334 + cv::Point minLoc;
  335 + minMaxLoc(temp3, &minVal, 0, &minLoc);
  336 + rIdx.resize(1), cIdx.resize(1);
  337 + rIdx[0] = minLoc.y, cIdx[0] = minLoc.x;
  338 +
  339 + // minC(~coverColumn) = minC(~coverColumn) + minval;
  340 + ptF = (float*)minC.data, ptF2 = (float*)minR.data;
  341 + it1 = noncoverColumn.begin(), it2 = noncoverRow.begin();
  342 + float minval = (float)minVal;
  343 + i = 0; while (i++<n) if (*(it1++)) *(ptF++) += minval; else ptF++;
  344 + // minR(coverRow) = minR(coverRow) - minval;
  345 + i = 0; while (i++<n) if (*(it2++)) ptF2++; else *(ptF2++) -= minval;
  346 + }
  347 + else
  348 + break;
  349 + }
  350 +
  351 + // STEP 5
  352 + // Construct a series of alternating primed and starred zeros as follows:
  353 + // Let Z0 represent the uncovered primed zero found in Step 4.
  354 + // Let Z1 denote the starred zero in the column of Z0 (if any).
  355 + // Let Z2 denote the primed zero in the row of Z1 (there will always
  356 + // be one). Continue until the series terminates at a primed zero
  357 + // that has no starred zero in its column. Unstar each starred
  358 + // zero of the series, star each primed zero of the series, erase
  359 + // all primes and uncover every line in the matrix. Return to Step 3.
  360 + int rowZ1;
  361 + for (j = 0; j<starZ.size(); j++)
  362 + if (starZ[j] == uZc)
  363 + break;
  364 + if (j<starZ.size())
  365 + rowZ1 = j;
  366 + else
  367 + rowZ1 = -1;
  368 + starZ[uZr] = uZc;
  369 + while (rowZ1 >= 0){
  370 + starZ[rowZ1] = -1;
  371 + uZc = primeZ[rowZ1];
  372 + uZr = rowZ1;
  373 + for (j = 0; j<starZ.size(); j++)
  374 + if (starZ[j] == uZc)
  375 + break;
  376 + if (j<starZ.size())
  377 + rowZ1 = j;
  378 + else
  379 + rowZ1 = -1;
  380 + starZ[uZr] = uZc;
  381 + }
  382 + }
  383 +
  384 + // assignment
  385 + // rowIdx = find(validRow); colIdx = find(validCol);
  386 + vector<int> rowIdx(nRows), colIdx(nCols);
  387 + it1 = validRow.begin(), it2 = validCol.begin();
  388 + for (i = 0, it3 = rowIdx.begin(); i<rows; i++) if (*(it1++)) *(it3++) = i;
  389 + for (i = 0, it3 = colIdx.begin(); i<cols; i++) if (*(it2++)) *(it3++) = i;
  390 + // vIdx = starZ(1:nRows) <= nCols;
  391 + vector<bool> vIdx(nRows, false);
  392 + it1 = vIdx.begin(), it3 = starZ.begin();
  393 + i = 0; while (i++<nRows) if (*(it3++)<nCols) *(it1++) = true; else it1++;
  394 + // assignment(rowIdx(vIdx)) = colIdx(starZ(vIdx));
  395 + for (j = 0, it1 = vIdx.begin(); j<vIdx.size(); j++){
  396 + if (*(it1++)){
  397 + r = rowIdx[j], c = starZ[j];
  398 + assignment[r] = colIdx[c];
  399 + }
  400 + }
  401 + for (j = 0; j<assignment.size(); j++){
  402 + int job = assignment[j];
  403 + if (job>-1){
  404 + uchar isInvalid = validMat.at<uchar>(j, job); // validMat is now "invalidMat"
  405 + if (isInvalid)
  406 + assignment[j] = -1;
  407 + }
  408 + }
  409 +}
0 \ No newline at end of file 410 \ No newline at end of file
src/ai_engine_module/sort/HungarianAlgorithm.h 0 → 100644
  1 +#ifndef HUNGARIANALGORITHM_H_
  2 +#define HUNGARIANALGORITHM_H_
  3 +
  4 +#include <vector>
  5 +#ifdef _MSC_VER
  6 + #include <cv.h>
  7 +#else
  8 + #include <opencv2/core/core.hpp>
  9 + #include <opencv2/highgui/highgui.hpp>
  10 + #include <opencv2/imgproc/imgproc.hpp>
  11 +#endif
  12 +
  13 +#include <assert.h>
  14 +#include <iostream>
  15 +
  16 +using namespace std;
  17 +
  18 +
  19 +
  20 +void extractGrids(const cv::Mat &A, const vector<bool> &extractRows, const vector<bool> &extractCols, cv::Mat &B);
  21 +void extractDots(const cv::Mat &A, const vector<bool> &extract, cv::Mat &B);
  22 +void munkres(cv::Mat &IoUMat, vector<int> &assignment);
  23 +
  24 +#endif
src/ai_engine_module/sort/KalmanBoxTracker.cpp 0 → 100644
  1 +#include "KalmanBoxTracker.h"
  2 +#include <cmath>
  3 +
  4 +#include "../../common/logger.hpp"
  5 +
  6 +float IoU(vector<float> &bb_test, vector<float> &bb_gt)
  7 +{
  8 + float xx1, yy1, xx2, yy2, w, h, wh, o;
  9 + xx1 = max(bb_test[0], bb_gt[0]);
  10 + yy1 = max(bb_test[1], bb_gt[1]);
  11 + xx2 = min(bb_test[2], bb_gt[2]);
  12 + yy2 = min(bb_test[3], bb_gt[3]);
  13 + w = max(float(0), (xx2 - xx1));
  14 + h = max(float(0), (yy2 - yy1));
  15 + wh = w * h;
  16 + o = wh / ((bb_test[2] - bb_test[0])*(bb_test[3] - bb_test[1])
  17 + + (bb_gt[2] - bb_gt[0])*(bb_gt[3] - bb_gt[1]) - wh);
  18 + return o;
  19 +}
  20 +
  21 +// added by zsh 220718
  22 +float center_distance(vector<float> &bb_test, vector<float> &bb_gt, float maxLength)
  23 +{
  24 + float w1 = bb_gt[2] - bb_gt[0];
  25 + float h1 = bb_gt[3] - bb_gt[1];
  26 + float bbox_cx = (bb_gt[0] + bb_gt[2]) / 2;
  27 + float bbox_cy = (bb_gt[1] + bb_gt[3]) / 2;
  28 +
  29 + float w2 = bb_test[2] - bb_test[0];
  30 + float h2 = bb_test[3] - bb_test[1];
  31 + float cx = (bb_test[0] + bb_test[2]) / 2;
  32 + float cy = (bb_test[1] + bb_test[3]) / 2;
  33 +
  34 + float scaleW = 100;
  35 + float scaleH = 100;
  36 + if (w2 != 0 && h2 != 0) {
  37 + scaleW = w1 / w2;
  38 + if (scaleW < 1) scaleW = 1. / scaleW;
  39 + scaleH = h1 / h2;
  40 + if (scaleH < 1) scaleH = 1. / scaleH;
  41 + }
  42 +
  43 + float res = std::sqrt((cx - bbox_cx)*(cx - bbox_cx)+(cy - bbox_cy)*(cy - bbox_cy)) / maxLength *
  44 + scaleW * scaleH;
  45 + //std::cout << res << std::endl;
  46 + return res;
  47 +}
  48 +
  49 +void convert_bbox_to_z(vector<float> &bbox, vector<float> &z)
  50 +{
  51 + if(bbox.size() <= 0){
  52 + LOG_ERROR("convert_bbox_to_z - bbox.size() 小于0");
  53 + return;
  54 + }
  55 + float w, h, x, y, s, r;
  56 + w = bbox[2] - bbox[0];
  57 + h = bbox[3] - bbox[1];
  58 + x = bbox[0] + w / 2;
  59 + y = bbox[1] + h / 2;
  60 + if(fabs(h) < 1e-6){
  61 + LOG_ERROR("convert_bbox_to_z - h小于0");
  62 + return;
  63 + }
  64 + s = w * h; //scale is just area
  65 + r = w / h;
  66 + z.push_back(x);
  67 + z.push_back(y);
  68 + z.push_back(s);
  69 + z.push_back(r);
  70 +
  71 +}
  72 +
  73 +void convert_x_to_bbox(cv::Mat &x, vector<float> &bbox)
  74 +{
  75 + float w, h;
  76 + w = sqrt(x.at<float>(2) * x.at<float>(3));
  77 + h = x.at<float>(2) / w;
  78 + //bbox[x1,y1,x2,y2];
  79 + bbox.push_back(x.at<float>(0) - w / 2);
  80 + bbox.push_back(x.at<float>(1) - h / 2);
  81 + bbox.push_back(x.at<float>(0) + w / 2);
  82 + bbox.push_back(x.at<float>(1) + h / 2);
  83 +}
  84 +
  85 +
  86 +
  87 +KalmanBoxTracker::KalmanBoxTracker(vector<float> &bbox, int trackLength)
  88 +{
  89 + KF.init(7, 4, 0); //初始化卡尔曼滤波器对象KF
  90 + state = cv::Mat::zeros(7, 1, CV_32F);
  91 + processNoise = cv::Mat::zeros(7, 1, CV_32F);
  92 + measurement = cv::Mat::zeros(4, 1, CV_32F); //定义测量值
  93 +
  94 + KF.transitionMatrix = (cv::Mat_<float>(7, 7) << \
  95 + 1, 0, 0, 0, 1, 0, 0, \
  96 + 0, 1, 0, 0, 0, 1, 0, \
  97 + 0, 0, 1, 0, 0, 0, 1, \
  98 + 0, 0, 0, 1, 0, 0, 0, \
  99 + 0, 0, 0, 0, 1, 0, 0, \
  100 + 0, 0, 0, 0, 0, 1, 0, \
  101 + 0, 0, 0, 0, 0, 0, 1); //状态转移矩阵A
  102 +
  103 + KF.measurementMatrix = (cv::Mat_<float>(4, 7) << \
  104 + 1, 0, 0, 0, 0, 0, 0, \
  105 + 0, 1, 0, 0, 0, 0, 0, \
  106 + 0, 0, 1, 0, 0, 0, 0, \
  107 + 0, 0, 0, 1, 0, 0, 0); //测量矩阵H
  108 +
  109 + KF.measurementNoiseCov = (cv::Mat_<float>(4, 4) << \
  110 + 1, 0, 0, 0, \
  111 + 0, 1, 0, 0, \
  112 + 0, 0, 10, 0, \
  113 + 0, 0, 0, 10); //测量噪声方差矩阵R
  114 +
  115 + KF.errorCovPost = (cv::Mat_<float>(7, 7) << \
  116 + 10, 0, 0, 0, 0, 0, 0, \
  117 + 0, 10, 0, 0, 0, 0, 0, \
  118 + 0, 0, 10, 0, 0, 0, 0, \
  119 + 0, 0, 0, 10, 0, 0, 0, \
  120 + 0, 0, 0, 0, 10000, 0, 0, \
  121 + 0, 0, 0, 0, 0, 10000, 0, \
  122 + 0, 0, 0, 0, 0, 0, 10000); //后验错误估计协方差矩阵P
  123 +
  124 + KF.processNoiseCov = (cv::Mat_<float>(7, 7) << \
  125 + 1, 0, 0, 0, 0, 0, 0, \
  126 + 0, 1, 0, 0, 0, 0, 0, \
  127 + 0, 0, 1, 0, 0, 0, 0, \
  128 + 0, 0, 0, 1, 0, 0, 0, \
  129 + 0, 0, 0, 0, 0.01, 0, 0, \
  130 + 0, 0, 0, 0, 0, 0.01, 0, \
  131 + 0, 0, 0, 0, 0, 0, 0.0001); //系统噪声方差矩阵Q
  132 +
  133 + vector<float> z;
  134 + convert_bbox_to_z(bbox, z);
  135 + KF.statePost = (cv::Mat_<float>(7, 1) << z[0], z[1], z[2], z[3], 0, 0, 0); //corrected state
  136 + state = (cv::Mat_<float>(7, 1) << z[0], z[1], z[2], z[3], 0, 0, 0);
  137 + time_since_update = 0;
  138 + cls = bbox[5];
  139 + //history
  140 + //hits = 0;
  141 + hit_streak = 0;
  142 + age = 0;
  143 +
  144 + m_trackLength = trackLength;
  145 + //history = new cycleQueue<vector<float>>(trackLength);
  146 + history.set_param(trackLength);
  147 +}
  148 +
  149 +KalmanBoxTracker::~KalmanBoxTracker()
  150 +{
  151 +
  152 + /*int trackerSize = history.size();
  153 +
  154 + for (int i = 0; i < trackerSize; i++)
  155 + {
  156 + history.get(i).clear();
  157 + vector<float>().swap(history.get(i));
  158 +
  159 + }*/
  160 +
  161 + /*if (history != NULL)
  162 + {
  163 + delete history;
  164 + history = NULL;
  165 + }*/
  166 +}
  167 +
  168 +void KalmanBoxTracker::update(vector<float> &bbox)
  169 +{
  170 + time_since_update = 0;
  171 + //history
  172 + //hits += 1;
  173 + hit_streak += 1;
  174 + vector<float> z;
  175 + convert_bbox_to_z(bbox, z);
  176 + measurement = (cv::Mat_<float>(4, 1) << z[0], z[1], z[2], z[3]);
  177 + KF.correct(measurement);
  178 + frame_count++;
  179 +}
  180 +
  181 +vector<float> KalmanBoxTracker::predict()
  182 +{
  183 + if ((KF.statePost.at<float>(6) + KF.statePost.at<float>(2)) <= 0)
  184 + KF.statePost.at<float>(6) *= 0.0;
  185 +
  186 + KF.predict();
  187 +
  188 + age += 1;
  189 + if (time_since_update >= FusionInterval)
  190 + hit_streak = 0;
  191 + time_since_update += 1;
  192 + vector<float> bbox;
  193 + convert_x_to_bbox(KF.statePost, bbox);
  194 + //history.push_back(bbox);
  195 +
  196 + TRACK_POINT tmp_point;
  197 + tmp_point.x = bbox[0] + (bbox[2] - bbox[0]) / 2;
  198 + tmp_point.y = bbox[1] + (bbox[3] - bbox[1]) / 2;
  199 + history.push(tmp_point);
  200 +
  201 + return bbox;
  202 +}
  203 +
  204 +vector<float> KalmanBoxTracker::get_state()
  205 +{
  206 + vector<float> bbox;
  207 + convert_x_to_bbox(KF.statePost, bbox);
  208 + return bbox;
  209 +}
  210 +
src/ai_engine_module/sort/KalmanBoxTracker.h 0 → 100644
  1 +#ifndef KALMANBOXTRACKER_H_
  2 +#define KALMANBOXTRACKER_H_
  3 +
  4 +#include <opencv2/opencv.hpp>
  5 +#include <iostream>
  6 +#include <stdio.h>
  7 +#include <math.h>
  8 +#include <vector>
  9 +#include "CycleQueue.h"
  10 +
  11 +using namespace std;
  12 +
  13 +// #define FusionInterval 5 //控制算法跳帧
  14 +class KalmanBoxTracker
  15 +{
  16 +public:
  17 + //int count = 0;
  18 + int time_since_update = 0;
  19 + int FusionInterval = 5; //控制算法跳帧 221117
  20 + int id = 0;
  21 + int cls = 0;
  22 + float score = 0.00;
  23 + std::vector<float> ldmk;
  24 + //-added by zsh 220719 人脸姿态角-
  25 + float roll = 0.0;
  26 + float yaw = 0.0;
  27 + float pitch = 0.0;
  28 + //-------------------------------
  29 +
  30 + //vector< vector<float> > history;
  31 +
  32 + cycleQueue history; //固定大小的轨迹
  33 + //int hits;
  34 + int hit_streak = 0;
  35 + int age = 0;
  36 + int m_trackLength = 0;
  37 +
  38 + int frame_count {1};
  39 +
  40 +public:
  41 + KalmanBoxTracker(vector<float> &bbox, int trackLength);
  42 + ~KalmanBoxTracker();
  43 + void update(vector<float> &bbox);
  44 + vector<float> predict();
  45 + vector<float> get_state();
  46 +private:
  47 + cv::KalmanFilter KF; //创建卡尔曼滤波器对象KF
  48 + cv::Mat measurement;
  49 + cv::Mat state;// (7, 1, CV_32F); //state = x
  50 + cv::Mat processNoise;
  51 +};
  52 +
  53 +float IoU(vector<float> &bb_test, vector<float> &bb_gt);
  54 +float center_distance(vector<float> &bb_test, vector<float> &bb_gt, float maxLength); // added by zsh 220718
  55 +void convert_bbox_to_z(vector<float> &bbox, vector<float> &z);
  56 +void convert_x_to_bbox(cv::Mat &x, vector<float> &bbox);
  57 +
  58 +
  59 +#endif
0 \ No newline at end of file 60 \ No newline at end of file
src/ai_engine_module/sort/Sort.cpp 0 → 100644
  1 +#include "Sort.h"
  2 +#include <opencv2/opencv.hpp>
  3 +#include <opencv2/imgproc/types_c.h>
  4 +
  5 +#ifdef _MSC_VER
  6 +#include <io.h>
  7 +#include <direct.h>
  8 +#define _ACCESS _access
  9 +#define _MKDIR(a) _mkdir((a))
  10 +#else
  11 +#include <unistd.h>
  12 +#include <stdarg.h>
  13 +#include <sys/stat.h>
  14 +#define _ACCESS access
  15 +#define _MKDIR(a) mkdir((a),0755)
  16 +#endif
  17 +#include <time.h>
  18 +
  19 +const int color[11][3] = { { 255, 0, 0 }, { 255, 128, 255 }, { 255, 128, 0 }, { 255, 215, 0 }, { 154, 205, 50 }, { 0, 128, 0 }, \
  20 +{0, 128, 255}, { 186, 85, 211 }, { 91, 46, 0 }, { 0, 0, 0 }, { 255, 255, 255 }
  21 +};
  22 +
  23 +
  24 +
  25 +Sort::Sort()
  26 +{
  27 + // max_age = 10;
  28 + max_age = 15; // 221103
  29 + min_hits = 3;
  30 + frame_count = 0;
  31 + WORK = true;
  32 + //-----------------by zl---------------------//
  33 + istraffic = false; //by zl 不统计交通量
  34 + trackcount = 0;
  35 + //-----------------by zl---------------------//
  36 +
  37 + max_track_length = MAX_LENGTH;
  38 +}
  39 +
  40 +int Sort::update(bool isUseDet, bool copy_ldmk, vector< vector<float> > &dets, det_objinfo *result, vector<int> &deleteObjectID)
  41 +{
  42 + //get predicted locations from existing trackers.
  43 + vector< vector<float> > trks;
  44 + vector<float> pos;
  45 + int ObjCount = 0; //by zl 本帧图像中的有效前景个数
  46 + vector<float> bbox;
  47 +
  48 + for (int i = 0; i < trackers.size(); i++ )
  49 + {
  50 + pos = trackers[i].predict(); // 对跟踪列表中的框进行预测(包含初始化的和匹配后update的)
  51 + pos.push_back(1);
  52 + pos.push_back(trackers[i].cls);
  53 + trks.push_back(pos);
  54 + pos.clear();
  55 + }
  56 +
  57 + if (isUseDet == true)
  58 + {
  59 + vector< vector<int> > matched;
  60 + vector<int> unmatched_dets;
  61 + vector<int> unmatched_trks;
  62 +
  63 + Sort::associate_detections_to_trackers(matched, unmatched_dets, unmatched_trks, dets, trks, 0.3);
  64 + //update matched trackers with assigned detections----匹配上的更新跟踪信息
  65 + for (int matched_number = 0; matched_number < matched.size(); matched_number++)
  66 + {
  67 + trackers[matched[matched_number][1]].update(dets[matched[matched_number][0]]);
  68 + trackers[matched[matched_number][1]].score = dets[matched[matched_number][0]][4];
  69 + trackers[matched[matched_number][1]].cls = dets[matched[matched_number][0]][5];
  70 + if (copy_ldmk)//存入关键点信息
  71 + {
  72 + for (int m = 0; m < 50; ++m)
  73 + {
  74 + trackers[matched[matched_number][1]].ldmk.push_back(dets[matched[matched_number][0]][m + 6]);
  75 + }
  76 + }
  77 + }
  78 +
  79 + //create and initialise new trackers for unmatched detections----为未匹配上的检测框分配新tracker
  80 + for (int unmatched_dets_number = 0; unmatched_dets_number < unmatched_dets.size(); unmatched_dets_number++)
  81 + {
  82 + KalmanBoxTracker tracker = KalmanBoxTracker(dets[unmatched_dets[unmatched_dets_number]], max_track_length);
  83 + tracker.id = -1;
  84 + tracker.FusionInterval = FusionInterval; //221117byzsh
  85 + trackers.push_back(tracker);
  86 + trackers[trackers.size() - 1].score = dets[unmatched_dets[unmatched_dets_number]][4];//by zl 20170525 解决第一次检测时置信度为0问题
  87 +
  88 + if (copy_ldmk)//存入关键点信息
  89 + {
  90 + for (int m = 0; m < 50; ++m)
  91 + {
  92 + trackers[trackers.size() - 1].ldmk.push_back(dets[unmatched_dets[unmatched_dets_number]][m + 6]);
  93 + }
  94 + }
  95 +
  96 + // cout << "trackers size: " << trackers.size() << endl;
  97 +
  98 + }
  99 +
  100 + for (int trackers_number = 0; trackers_number < trackers.size();)
  101 + {
  102 + // cout << trackers[trackers_number].id << " " <<trackers[trackers_number].time_since_update << " " << trackers[trackers_number].hit_streak << " " << min_hits << " " << frame_count << endl;
  103 + if (trackers[trackers_number].time_since_update > max_age) // 失配次数超过max_age,放入轨迹消失列表,从跟踪列表中删除
  104 + {
  105 + if (trackers[trackers_number].id != -1)
  106 + {
  107 + deleteObjectID.push_back(trackers[trackers_number].id);
  108 + }
  109 +
  110 + trackcount++;
  111 + std::vector<float>().swap(trackers[trackers_number].ldmk);
  112 + trackers.erase(trackers.begin() + trackers_number);
  113 + continue;
  114 + }
  115 + // 失配次数小于FusionInterval且满足最小匹配次数则返回
  116 + if (ObjCount < MAX_OBJ_COUNT && (trackers[trackers_number].time_since_update < FusionInterval) && ((trackers[trackers_number].hit_streak >= min_hits) || (frame_count <= (min_hits * FusionInterval))))
  117 + {
  118 +
  119 + if (trackers[trackers_number].id == -1)
  120 + trackers[trackers_number].id = trackcount++;
  121 + result[ObjCount].id = trackers[trackers_number].id;
  122 +
  123 + bbox = trackers[trackers_number].get_state();
  124 + result[ObjCount].left = bbox[0]; // bbout[i][0];
  125 + result[ObjCount].top = bbox[1]; //bbout[i][1];
  126 + result[ObjCount].right = bbox[2]; //bbout[i][2];
  127 + result[ObjCount].bottom = bbox[3]; //bbout[i][3];
  128 + result[ObjCount].confidence = trackers[trackers_number].score; // bbout[i][4];
  129 + result[ObjCount].index = trackers[trackers_number].cls; // bbout[i][5] - 1;
  130 + result[ObjCount].center_x = result[ObjCount].left + (result[ObjCount].right - result[ObjCount].left) * 0.5; // 中心点 add by 20170227
  131 + result[ObjCount].center_y = result[ObjCount].top + (result[ObjCount].bottom - result[ObjCount].top) * 0.5; // 中心点
  132 + if (trackers[trackers_number].age == 2 * FusionInterval)
  133 + {
  134 + result[ObjCount].snap_flag = 1; // 中心点
  135 + }
  136 + else
  137 + {
  138 + result[ObjCount].snap_flag = 0; // 中心点
  139 + }
  140 +
  141 + if (copy_ldmk) // 存入关键点信息
  142 + {
  143 + for (int m = 0; m < 25; ++m)
  144 + {
  145 + result[ObjCount].landmark_point[m].x_ = trackers[trackers_number].ldmk[2 * m];
  146 + result[ObjCount].landmark_point[m].y_ = trackers[trackers_number].ldmk[2 * m + 1];
  147 + }
  148 + }
  149 +#if _Debug
  150 + printf("trackers_number = %d, trackers.size() = %d, update: index = %d, id = %d, (%d, %d), (%d, %d)\n", trackers_number, trackers.size(), result[ObjCount].index, result[ObjCount].id, result[ObjCount].left, result[ObjCount].top, result[ObjCount].right, result[ObjCount].bottom);
  151 +#endif
  152 + ObjCount++;
  153 + }
  154 + trackers_number++;//共多少条轨迹
  155 + }
  156 + }
  157 + else
  158 + {
  159 + for (int trackers_number = 0; trackers_number < trackers.size() && ObjCount < MAX_OBJ_COUNT; trackers_number++)
  160 + {
  161 + if (trackers[trackers_number].id == -1)
  162 + trackers[trackers_number].id = trackcount++;
  163 + bbox = trackers[trackers_number].get_state();
  164 + result[trackers_number].id = trackers[trackers_number].id;
  165 + result[trackers_number].left = bbox[0]; // bbout[i][0];
  166 + result[trackers_number].top = bbox[1]; //bbout[i][1];
  167 + result[trackers_number].right = bbox[2]; //bbout[i][2];
  168 + result[trackers_number].bottom = bbox[3]; //bbout[i][3];
  169 + result[trackers_number].confidence = trackers[trackers_number].score; // bbout[i][4];
  170 + result[trackers_number].index = trackers[trackers_number].cls;//bbox[5] - 1;// trackers[trackers_number].cls - 1; // bbout[i][5] - 1;
  171 + result[trackers_number].center_x = (int)(result[trackers_number].left + (result[trackers_number].right - result[trackers_number].left) * 0.5); // 中心点 add by 20170227
  172 + result[trackers_number].center_y = (int)(result[trackers_number].top + (result[trackers_number].bottom - result[trackers_number].top) * 0.5); // 中心点
  173 +
  174 + if (copy_ldmk)//存入关键点信息
  175 + {
  176 + for (int m = 0; m < 25; ++m)
  177 + {
  178 + result[trackers_number].landmark_point[m].x_ = trackers[trackers_number].ldmk[2 * m];
  179 + result[trackers_number].landmark_point[m].y_ = trackers[trackers_number].ldmk[2 * m + 1];
  180 + }
  181 + }
  182 +
  183 + result[ObjCount].snap_flag = 0; // 中心点
  184 +
  185 + ObjCount++;
  186 + }
  187 + }
  188 +
  189 + //---------------------------注释掉了这步操作 用了新的绘制轨迹的函数 需要绘制调用addTracker(Mat *img)方法 by lm---------------------------------------------/
  190 + //addTracker(result, ObjCount);
  191 +
  192 + frame_count += 1; //帧数加一
  193 + return ObjCount;
  194 +
  195 +}
  196 +
  197 +
  198 +// added by zsh 220719
  199 +int Sort::update_v2(bool isUseDet, bool copy_ldmk, bool center_dist, float maxLen, vector< vector<float> > &dets, det_objinfo *result, vector<int> &deleteObjectID)
  200 +{
  201 + //get predicted locations from existing trackers.
  202 + vector< vector<float> > trks;
  203 + vector<float> pos;
  204 + int ObjCount = 0; //by zl 本帧图像中的有效前景个数
  205 + vector<float> bbox;
  206 +
  207 + for (int i = 0; i < trackers.size(); i++ )
  208 + {
  209 + pos = trackers[i].predict(); // 对跟踪列表中的框进行预测(包含初始化的和匹配后update的)
  210 + pos.push_back(1);
  211 + pos.push_back(trackers[i].cls);
  212 + trks.push_back(pos);
  213 + pos.clear();
  214 + }
  215 +
  216 + if (isUseDet == true)
  217 + {
  218 + vector< vector<int> > matched;
  219 + vector<int> unmatched_dets;
  220 + vector<int> unmatched_trks;
  221 +
  222 + if(center_dist) {
  223 + Sort::associate_detections_to_trackers_v2(matched, unmatched_dets, unmatched_trks, dets, trks, maxLen); // 中心距离匹配
  224 + }
  225 + else {
  226 + Sort::associate_detections_to_trackers(matched, unmatched_dets, unmatched_trks, dets, trks, 0.3); // iou匹配
  227 + }
  228 + //update matched trackers with assigned detections----匹配上的更新跟踪信息
  229 + for (int matched_number = 0; matched_number < matched.size(); matched_number++)
  230 + {
  231 + trackers[matched[matched_number][1]].update(dets[matched[matched_number][0]]);
  232 + trackers[matched[matched_number][1]].score = dets[matched[matched_number][0]][4];
  233 + trackers[matched[matched_number][1]].cls = dets[matched[matched_number][0]][5];
  234 + if (copy_ldmk)//存入关键点信息
  235 + {
  236 + for (int m = 0; m < 50; ++m)
  237 + {
  238 + trackers[matched[matched_number][1]].ldmk.push_back(dets[matched[matched_number][0]][m + 6]);
  239 + }
  240 + // added by zsh 姿态角信息--------------------------------------------------------
  241 + trackers[matched[matched_number][1]].roll = dets[matched[matched_number][0]][56];
  242 + trackers[matched[matched_number][1]].yaw = dets[matched[matched_number][0]][57];
  243 + trackers[matched[matched_number][1]].pitch = dets[matched[matched_number][0]][58];
  244 + //--------------------------------------------------------------------------------
  245 + }
  246 + }
  247 +
  248 + //create and initialise new trackers for unmatched detections----为未匹配上的检测框分配新tracker
  249 + for (int unmatched_dets_number = 0; unmatched_dets_number < unmatched_dets.size(); unmatched_dets_number++)
  250 + {
  251 + KalmanBoxTracker tracker = KalmanBoxTracker(dets[unmatched_dets[unmatched_dets_number]], max_track_length);
  252 + tracker.id = -1;
  253 + tracker.FusionInterval = FusionInterval; //221117byzsh
  254 + trackers.push_back(tracker);
  255 + trackers[trackers.size() - 1].score = dets[unmatched_dets[unmatched_dets_number]][4];//by zl 20170525 解决第一次检测时置信度为0问题
  256 +
  257 + if (copy_ldmk)//存入关键点信息
  258 + {
  259 + for (int m = 0; m < 50; ++m)
  260 + {
  261 + trackers[trackers.size() - 1].ldmk.push_back(dets[unmatched_dets[unmatched_dets_number]][m + 6]);
  262 + }
  263 + // added by zsh 姿态角信息------------------------------------------------------------
  264 + trackers[trackers.size() - 1].roll = dets[unmatched_dets[unmatched_dets_number]][56];
  265 + trackers[trackers.size() - 1].yaw = dets[unmatched_dets[unmatched_dets_number]][57];
  266 + trackers[trackers.size() - 1].pitch = dets[unmatched_dets[unmatched_dets_number]][58];
  267 + //-----------------------------------------------------------------------------------
  268 + }
  269 +
  270 + // cout << "trackers size: " << trackers.size() << endl;
  271 +
  272 + }
  273 +
  274 + for (int trackers_number = 0; trackers_number < trackers.size();)
  275 + {
  276 + // cout << trackers[trackers_number].id << " " <<trackers[trackers_number].time_since_update << " " << trackers[trackers_number].hit_streak << " " << min_hits << " " << frame_count << endl;
  277 + if (trackers[trackers_number].time_since_update > max_age) // 失配次数超过max_age,放入轨迹消失列表,从跟踪列表中删除
  278 + {
  279 + if (trackers[trackers_number].id != -1)
  280 + {
  281 + deleteObjectID.push_back(trackers[trackers_number].id);
  282 + }
  283 +
  284 + trackcount++;
  285 + std::vector<float>().swap(trackers[trackers_number].ldmk);
  286 + trackers.erase(trackers.begin() + trackers_number);
  287 + continue;
  288 + }
  289 + // 失配次数小于FusionInterval且满足最小匹配次数则返回
  290 + if (ObjCount < MAX_OBJ_COUNT && (trackers[trackers_number].time_since_update < FusionInterval) && ((trackers[trackers_number].hit_streak >= min_hits) || (frame_count <= (min_hits * FusionInterval))))
  291 + {
  292 +
  293 + if (trackers[trackers_number].id == -1)
  294 + trackers[trackers_number].id = trackcount++;
  295 + result[ObjCount].id = trackers[trackers_number].id;
  296 + result[ObjCount].num = trackers[trackers_number].frame_count;
  297 +
  298 + bbox = trackers[trackers_number].get_state();
  299 + result[ObjCount].left = bbox[0]; // bbout[i][0];
  300 + result[ObjCount].top = bbox[1]; //bbout[i][1];
  301 + result[ObjCount].right = bbox[2]; //bbout[i][2];
  302 + result[ObjCount].bottom = bbox[3]; //bbout[i][3];
  303 + result[ObjCount].confidence = trackers[trackers_number].score; // bbout[i][4];
  304 + result[ObjCount].index = trackers[trackers_number].cls; // bbout[i][5] - 1;
  305 + result[ObjCount].center_x = result[ObjCount].left + (result[ObjCount].right - result[ObjCount].left) * 0.5; // 中心点 add by 20170227
  306 + result[ObjCount].center_y = result[ObjCount].top + (result[ObjCount].bottom - result[ObjCount].top) * 0.5; // 中心点
  307 + if (trackers[trackers_number].age == 2 * FusionInterval)
  308 + {
  309 + result[ObjCount].snap_flag = 1; // 中心点
  310 + }
  311 + else
  312 + {
  313 + result[ObjCount].snap_flag = 0; // 中心点
  314 + }
  315 +
  316 + if (copy_ldmk) // 存入关键点信息
  317 + {
  318 + for (int m = 0; m < 25; ++m)
  319 + {
  320 + result[ObjCount].landmark_point[m].x_ = trackers[trackers_number].ldmk[2 * m];
  321 + result[ObjCount].landmark_point[m].y_ = trackers[trackers_number].ldmk[2 * m + 1];
  322 + }
  323 + // added by zsh 姿态角信息--------------------------------
  324 + result[ObjCount].roll = trackers[trackers_number].roll;
  325 + result[ObjCount].yaw = trackers[trackers_number].yaw;
  326 + result[ObjCount].pitch = trackers[trackers_number].pitch;
  327 + //--------------------------------------------------------
  328 + }
  329 +#if _Debug
  330 + printf("trackers_number = %d, trackers.size() = %d, update: index = %d, id = %d, (%d, %d), (%d, %d)\n", trackers_number, trackers.size(), result[ObjCount].index, result[ObjCount].id, result[ObjCount].left, result[ObjCount].top, result[ObjCount].right, result[ObjCount].bottom);
  331 +#endif
  332 + ObjCount++;
  333 + }
  334 + trackers_number++;//共多少条轨迹
  335 + }
  336 + }
  337 + else
  338 + {
  339 + for (int trackers_number = 0; trackers_number < trackers.size() && ObjCount < MAX_OBJ_COUNT; trackers_number++)
  340 + {
  341 + if (trackers[trackers_number].id == -1)
  342 + trackers[trackers_number].id = trackcount++;
  343 + result[trackers_number].num = trackers[trackers_number].frame_count;
  344 + bbox = trackers[trackers_number].get_state();
  345 + result[trackers_number].id = trackers[trackers_number].id;
  346 + result[trackers_number].left = bbox[0]; // bbout[i][0];
  347 + result[trackers_number].top = bbox[1]; //bbout[i][1];
  348 + result[trackers_number].right = bbox[2]; //bbout[i][2];
  349 + result[trackers_number].bottom = bbox[3]; //bbout[i][3];
  350 + result[trackers_number].confidence = trackers[trackers_number].score; // bbout[i][4];
  351 + result[trackers_number].index = trackers[trackers_number].cls;//bbox[5] - 1;// trackers[trackers_number].cls - 1; // bbout[i][5] - 1;
  352 + result[trackers_number].center_x = (int)(result[trackers_number].left + (result[trackers_number].right - result[trackers_number].left) * 0.5); // 中心点 add by 20170227
  353 + result[trackers_number].center_y = (int)(result[trackers_number].top + (result[trackers_number].bottom - result[trackers_number].top) * 0.5); // 中心点
  354 +
  355 + if (copy_ldmk)//存入关键点信息
  356 + {
  357 + for (int m = 0; m < 25; ++m)
  358 + {
  359 + result[trackers_number].landmark_point[m].x_ = trackers[trackers_number].ldmk[2 * m];
  360 + result[trackers_number].landmark_point[m].y_ = trackers[trackers_number].ldmk[2 * m + 1];
  361 + }
  362 + // added by zsh 姿态角信息---------------------------------------
  363 + result[trackers_number].roll = trackers[trackers_number].roll;
  364 + result[trackers_number].yaw = trackers[trackers_number].yaw;
  365 + result[trackers_number].pitch = trackers[trackers_number].pitch;
  366 + //--------------------------------------------------------------
  367 + }
  368 +
  369 + result[ObjCount].snap_flag = 0; // 中心点
  370 +
  371 + ObjCount++;
  372 + }
  373 + }
  374 +
  375 + //---------------------------注释掉了这步操作 用了新的绘制轨迹的函数 需要绘制调用addTracker(Mat *img)方法 by lm---------------------------------------------/
  376 + //addTracker(result, ObjCount);
  377 +
  378 + frame_count += 1; //帧数加一
  379 + return ObjCount;
  380 +
  381 +}
  382 +
  383 +
  384 +//---------------------------利用trackers中的history 绘制路径 -by lm ---------------------------------------------/
  385 +//固定长度的轨迹,采用循环队列,仅保存目前最前N length的轨迹,避免对于停留在画面中目标 导致的内存一直增长
  386 +int Sort::addTracker(cv::Mat *img)
  387 +{
  388 + map<int, pair<int, int>> tracker;
  389 + vector<float> bbox;
  390 +
  391 +
  392 + int x_1, y_1, x_2, y_2;
  393 + for (auto iter : trackers)
  394 + {
  395 + if (iter.time_since_update < FusionInterval)
  396 + {
  397 + int index = iter.history.getFront();
  398 + int trackerSize = iter.history.size();
  399 +
  400 + for (int i = 0; i < trackerSize; i++)
  401 + {
  402 + if (i == 0)
  403 + {
  404 + x_1 = iter.history.get(index).x;
  405 + y_1 = iter.history.get(index).y;
  406 + }
  407 + else
  408 + {
  409 + x_2 = iter.history.get(index).x;
  410 + y_2 = iter.history.get(index).y;
  411 + int colorIndex = iter.id % 11;
  412 + cv::line(*img, cvPoint(x_1, y_1), cvPoint(x_2, y_2), cvScalar(color[colorIndex][0], color[colorIndex][1], color[colorIndex][2]), 1);
  413 +
  414 + //drawLineOnGPU()
  415 +
  416 + x_1 = x_2;
  417 + y_1 = y_2;
  418 + }
  419 +
  420 + index = (index + 1) % trackerSize;
  421 + }
  422 + }
  423 +
  424 + }
  425 +
  426 + return 1;
  427 +}
  428 +
  429 +//不固定长度的轨迹版本 采用vector,轨迹一直保留,对于停留在画面中的物体,会有内存一直增长的隐患
  430 +//int Sort::addTracker(cv::Mat *img)
  431 +//{
  432 +// map<int, pair<int, int>> tracker;
  433 +// vector<float> bbox;
  434 +//
  435 +//
  436 +// int x_1, y_1, x_2, y_2;
  437 +// for (auto iter : trackers)
  438 +// {
  439 +// if (iter.time_since_update < FusionInterval)
  440 +// {
  441 +// for (int i = 0; i < iter.history.size(); i++)
  442 +// {
  443 +//
  444 +// if (i == 0)
  445 +// {
  446 +// x_1 = iter.history[i][0] + (iter.history[i][2] - iter.history[i][0]) / 2;
  447 +// y_1 = iter.history[i][1] + (iter.history[i][3] - iter.history[i][1]) / 2;
  448 +// }
  449 +// else
  450 +// {
  451 +// x_2 = iter.history[i][0] + (iter.history[i][2] - iter.history[i][0]) / 2;
  452 +// y_2 = iter.history[i][1] + (iter.history[i][3] - iter.history[i][1]) / 2;
  453 +// int colorIndex = iter.id % 11;
  454 +// cv::line(*img, cvPoint(x_1, y_1), cvPoint(x_2, y_2), cvScalar(color[colorIndex][0], color[colorIndex][1], color[colorIndex][2]), 1);
  455 +//
  456 +// //drawLineOnGPU()
  457 +//
  458 +// x_1 = x_2;
  459 +// y_1 = y_2;
  460 +// }
  461 +// }
  462 +// }
  463 +//
  464 +// }
  465 +//
  466 +// return 1;
  467 +//}
  468 +
  469 +void Sort::Release()
  470 +{
  471 + //tracker.clear();
  472 + //vector <mylist>().swap(tracker);
  473 + trackers.clear();
  474 + vector<KalmanBoxTracker>().swap(trackers);
  475 +}
  476 +bool Sort::GetState()
  477 +{
  478 + return WORK;
  479 +}
  480 +
  481 +void Sort::Pause()
  482 +{
  483 + WORK = false;
  484 +}
  485 +
  486 +void Sort::ReSet()
  487 +{
  488 + WORK = true;
  489 + //Release();
  490 + //max_age = 1;
  491 + //min_hits = 3;
  492 + //frame_count = 0;
  493 +
  494 + ////-----------------by zl---------------------//
  495 + //istraffic = false; //by zl 不统计交通量
  496 + //trackcount = 0;
  497 + ////-----------------by zl---------------------//
  498 +}
  499 +
  500 +//---------------------------by zl ---------------------------------------------/
  501 +bool line_rect_intersection(cv::Point start_p, cv::Point end_p, int left, int top, int right, int bottom)
  502 +{
  503 + int a = start_p.y - end_p.y;
  504 + int b = end_p.x - start_p.x;
  505 + int c = start_p.x* end_p.y - end_p.x* start_p.y;
  506 +
  507 + ////思路:先看线段所在直线是否与矩形相交,如果不相交则必为 “F”,
  508 + ////如果相交,则看线段的两个点是否在矩形的同一边(即两点的 x(y) 坐标都比矩形的小 x(y) 坐标小,或者大),
  509 + ////若在同一边则为“F”,否则就是相交的情况。
  510 + if ((a* left + b*top + c >= 0 && a* right + b* bottom + c <= 0) ||
  511 + (a* left + b*top + c <= 0 && a* right + b* bottom + c >= 0) ||
  512 + (a* left + b*bottom + c >= 0 && a* right + b* top + c <= 0) ||
  513 + (a* left + b*bottom + c >= 0 && a* right + b* top + c <= 0))
  514 +
  515 + {
  516 + if (left > right)
  517 + {
  518 + swap(left, right);
  519 + }
  520 + if (top < bottom)
  521 + {
  522 + swap(top, bottom);
  523 + }
  524 + if ((start_p.x < left && end_p.x < left) ||
  525 + (start_p.x > right && end_p.x < left) ||
  526 + (start_p.y > top && end_p.y > top) ||
  527 + (start_p.y < bottom && end_p.y < bottom)) ///判断线段是否在矩形一侧
  528 + {
  529 + return false;
  530 + }
  531 + else
  532 + {
  533 + return true;
  534 + }
  535 + }
  536 + else
  537 + {
  538 + return false;
  539 + }
  540 +}
  541 +
  542 +void RectboundCheck(int Width, int Height, det_objinfo * result) //防止坐标越界 by zl
  543 +{
  544 + if (result->left < 0)
  545 + result->left = 0;
  546 + if (result->left >= Width)
  547 + result->left = Width;
  548 +
  549 + if (result->top < 0)
  550 + result->top = 0;
  551 + if (result->top >= Height)
  552 + result->top = Height;
  553 +
  554 + if (result->right <= result->left)
  555 + result->right = result->left + 1;
  556 + if (result->right >= Width)
  557 + result->right = Width;
  558 +
  559 + if (result->bottom < result->top)
  560 + result->bottom = result->top + 1;
  561 + if (result->bottom >= Height)
  562 + result->bottom = Height;
  563 +
  564 +
  565 +}
  566 +//------------------------------------其他函数----------------------------------------//
  567 +void Sort::associate_detections_to_trackers(vector< vector<int> > &matched, vector<int> &unmatched_dets, vector<int> &unmatched_trks, vector< vector<float> > &dets, vector< vector<float> > &trks, float iou_threshold)
  568 +{
  569 +
  570 + if (0 == trks.size())
  571 + {
  572 + for (int x = 0; x < dets.size(); x++)
  573 + {
  574 + unmatched_dets.push_back(x);
  575 + }
  576 + }
  577 + else if (0 == dets.size())
  578 + {
  579 + for (int x = 0; x < trks.size(); x++)
  580 + {
  581 + unmatched_trks.push_back(x);
  582 + }
  583 + }
  584 + else
  585 + {
  586 + cv::Mat IoUMat(dets.size(), trks.size(), CV_32FC1);
  587 + for (int i = 0; i < dets.size(); i++)
  588 + for (int j = 0; j < trks.size(); j++)
  589 + {
  590 + //cls区分
  591 + if (1)
  592 + //if (dets[i][5] == trks[j][5])
  593 + {
  594 + IoUMat.at<float>(i, j) = IoU(dets[i], trks[j]);
  595 + }
  596 + else
  597 + {
  598 + IoUMat.at<float>(i, j) = 0;
  599 + }
  600 +
  601 + }
  602 +
  603 + //匈牙利算法
  604 + vector<int> assignment;
  605 + munkres(IoUMat, assignment);
  606 +
  607 + vector<int>::iterator iter;
  608 + for (int trackers_indices = 0; trackers_indices < trks.size(); trackers_indices++)
  609 + {
  610 + iter = find(assignment.begin(), assignment.end(), trackers_indices);
  611 + if (iter == assignment.end())
  612 + {
  613 + //assignment中不存在trackers_indices值
  614 + unmatched_trks.push_back(trackers_indices);
  615 + }
  616 + }
  617 +
  618 + vector<int> matched_row_col;
  619 + for (int detections_indices = 0; detections_indices < assignment.size(); detections_indices++)
  620 + {
  621 + if (assignment[detections_indices] == -1)
  622 + {
  623 + unmatched_dets.push_back(detections_indices);
  624 + }
  625 + else if (IoUMat.at<float>(detections_indices, assignment[detections_indices]) > iou_threshold)
  626 + {
  627 + matched_row_col.push_back(detections_indices);
  628 + matched_row_col.push_back(assignment[detections_indices]);
  629 + matched.push_back(matched_row_col);
  630 + matched_row_col.clear();
  631 + }
  632 + else
  633 + {
  634 + unmatched_dets.push_back(detections_indices);
  635 + unmatched_trks.push_back(assignment[detections_indices]);
  636 + }
  637 + }
  638 + }
  639 +}
  640 +
  641 +
  642 +// added by zsh 220719 人脸等小目标采取中心距离匹配
  643 +void Sort::associate_detections_to_trackers_v2(vector< vector<int> > &matched, vector<int> &unmatched_dets, vector<int> &unmatched_trks, vector< vector<float> > &dets, vector< vector<float> > &trks, float maxLen)
  644 +{
  645 +
  646 + if (0 == trks.size())
  647 + {
  648 + for (int x = 0; x < dets.size(); x++)
  649 + {
  650 + unmatched_dets.push_back(x);
  651 + }
  652 + }
  653 + else if (0 == dets.size())
  654 + {
  655 + for (int x = 0; x < trks.size(); x++)
  656 + {
  657 + unmatched_trks.push_back(x);
  658 + }
  659 + }
  660 + else
  661 + {
  662 + // ---------------------------------------------------------------------------
  663 +#if 1
  664 + static bool firstRun = 1;
  665 + float distanceWeight = 1;
  666 + float disNorm = 0;
  667 + float updateSpeed = 0.2;
  668 + float max_distance = 0.5;
  669 + for (auto& det : dets) {
  670 + float w1 = det[2] - det[0];
  671 + float h1 = det[3] - det[1];
  672 + disNorm += sqrt(w1 * w1 + h1 * h1) /maxLen;
  673 + }
  674 + disNorm = disNorm / dets.size();
  675 + if (firstRun) {
  676 + max_distance = disNorm * distanceWeight; // face & hs
  677 + // max_distance = disNorm * 1.5; // car for gaoxinxing
  678 + firstRun = 0;
  679 + } else {
  680 + max_distance = disNorm * distanceWeight * updateSpeed + max_distance * (1 - updateSpeed); // face & hs
  681 + // max_distance = disNorm * 1.5 * updateSpeed + max_distance * (1 - updateSpeed); // car for gaoxinxing
  682 + }
  683 +#endif
  684 + // -------------------------------------------------------------------------
  685 + cv::Mat IoUMat(dets.size(), trks.size(), CV_32FC1);
  686 + for (int i = 0; i < dets.size(); i++)
  687 + for (int j = 0; j < trks.size(); j++)
  688 + {
  689 + //cls区分
  690 + if (1)
  691 + //if (dets[i][5] == trks[j][5])
  692 + {
  693 + // IoUMat.at<float>(i, j) = IoU(dets[i], trks[j]);
  694 + // -----------------------------------------------------------------
  695 + IoUMat.at<float>(i, j) = center_distance(dets[i], trks[j], maxLen);
  696 + float tmp = IoUMat.at<float>(i, j);
  697 + if(tmp > max_distance) IoUMat.at<float>(i, j) = max_distance + 1e-5;
  698 + // -----------------------------------------------------------------
  699 + }
  700 + else
  701 + {
  702 + IoUMat.at<float>(i, j) = 0;
  703 + }
  704 +
  705 + }
  706 +
  707 + //匈牙利算法
  708 + vector<int> assignment;
  709 + //-----------------------------------------------
  710 + const int rows = IoUMat.rows, cols = IoUMat.cols;
  711 + cv::Mat O = cv::Mat::ones(rows, cols, CV_32FC1);
  712 + cv::Mat costMat(rows, cols, CV_32FC1);
  713 + absdiff(O, IoUMat, costMat);
  714 + munkres(costMat, assignment);
  715 + //-----------------------------------------------
  716 + // munkres(IoUMat, assignment);
  717 +
  718 + vector<int>::iterator iter;
  719 + for (int trackers_indices = 0; trackers_indices < trks.size(); trackers_indices++)
  720 + {
  721 + iter = find(assignment.begin(), assignment.end(), trackers_indices);
  722 + if (iter == assignment.end())
  723 + {
  724 + //assignment中不存在trackers_indices值
  725 + unmatched_trks.push_back(trackers_indices);
  726 + }
  727 + }
  728 +
  729 + vector<int> matched_row_col;
  730 + for (int detections_indices = 0; detections_indices < assignment.size(); detections_indices++)
  731 + {
  732 + if (assignment[detections_indices] == -1)
  733 + {
  734 + unmatched_dets.push_back(detections_indices);
  735 + }
  736 + // else if (IoUMat.at<float>(detections_indices, assignment[detections_indices]) > iou_threshold)
  737 + else if (IoUMat.at<float>(detections_indices, assignment[detections_indices]) <= max_distance)
  738 + {
  739 + matched_row_col.push_back(detections_indices);
  740 + matched_row_col.push_back(assignment[detections_indices]);
  741 + matched.push_back(matched_row_col);
  742 + matched_row_col.clear();
  743 + }
  744 + else
  745 + {
  746 + unmatched_dets.push_back(detections_indices);
  747 + unmatched_trks.push_back(assignment[detections_indices]);
  748 + }
  749 + }
  750 + }
  751 +}
  752 +//判断两条线是否相交
  753 +
  754 +///------------alg 2------------
  755 +//叉积
  756 +double mult(cv::Point a, cv::Point b, cv::Point c)
  757 +{
  758 + return (a.x - c.x)*(b.y - c.y) - (b.x - c.x)*(a.y - c.y);
  759 +}
  760 +
  761 +//aa, bb为一条线段两端点 cc, dd为另一条线段的两端点 相交返回true, 不相交返回false
  762 +bool intersect(cv::Point aa, cv::Point bb, cv::Point cc, cv::Point dd)
  763 +{
  764 + if (max(aa.x, bb.x)<min(cc.x, dd.x))
  765 + {
  766 + return false;
  767 + }
  768 + if (max(aa.y, bb.y)<min(cc.y, dd.y))
  769 + {
  770 + return false;
  771 + }
  772 + if (max(cc.x, dd.x)<min(aa.x, bb.x))
  773 + {
  774 + return false;
  775 + }
  776 + if (max(cc.y, dd.y)<min(aa.y, bb.y))
  777 + {
  778 + return false;
  779 + }
  780 + if (mult(cc, bb, aa)*mult(bb, dd, aa)<0)
  781 + {
  782 + return false;
  783 + }
  784 + if (mult(aa, dd, cc)*mult(dd, bb, cc)<0)
  785 + {
  786 + return false;
  787 + }
  788 + return true;
  789 +}
  790 +
  791 +///------------alg 2------------
  792 +
src/ai_engine_module/sort/Sort.h 0 → 100644
  1 +#ifndef SORT_H_
  2 +#define SORT_H_
  3 +
  4 +#include "KalmanBoxTracker.h"
  5 +#include "HungarianAlgorithm.h"
  6 +#include <opencv2/video/tracking.hpp>
  7 +// #include <highgui.h>
  8 +#include "opencv2/opencv.hpp"
  9 +#include <iostream>
  10 +#include <stdio.h>
  11 +#include <math.h>
  12 +#include<vector>
  13 +
  14 +#include "../../ai_platform/det_obj_header.h"
  15 +
  16 +using namespace std;
  17 +
  18 +
  19 +#define LOSTMAXFRAMECCOUNT 5 //by zl
  20 +#define SNAPSHOTFRAMECOUNT 24 //下标从0开始 取第十帧为快照帧
  21 +
  22 +struct TrackerResult
  23 +{
  24 + vector< vector<float> > trackers_box;
  25 + vector< vector< vector<float> > > trackers_history;
  26 +};
  27 +
  28 +
  29 +typedef struct mylist
  30 +{
  31 + vector <det_objinfo> listinfo;
  32 + int lost; //丢失的帧数 >LOSTMAXFRAMECCOUNT 则认为彻底丢失目标
  33 + long id;
  34 + bool isupdate;
  35 + bool istraffic;
  36 + int index;// 行人类别
  37 + int num; // 该ID序列下的第num帧 20170306 从0开始计数
  38 + int startframe; //轨迹开始帧
  39 + int endframe; //轨迹结束帧
  40 +}mylist;
  41 +
  42 +
  43 +
  44 +class Sort
  45 +{
  46 +public:
  47 + Sort();
  48 + int update(bool isUseDet, bool copy_ldmk, vector< vector<float> > &dets, det_objinfo *result, vector<int> &deleteObjectID);
  49 + int update_v2(bool isUseDet, bool copy_ldmk, bool center_dist, float maxLen, vector< vector<float> > &dets, det_objinfo *result, vector<int> &deleteObjectID); // added by zsh 220719
  50 + void Release();
  51 + void ReSet();
  52 + void Pause();
  53 + bool GetState();
  54 + int addTracker(cv::Mat *img);
  55 +public:
  56 + vector<KalmanBoxTracker> trackers;
  57 + int FusionInterval = 5; //221117
  58 + int max_age = 0;
  59 + int min_hits = 0;
  60 + int frame_count =0;
  61 + int trackcount = 0;
  62 + int max_track_length = 0;
  63 +
  64 +private:
  65 + int linecount = 0;
  66 + bool istraffic = 0; //by zl 是否统计交通量
  67 + //vector <mylist> tracker;
  68 + bool WORK = false;
  69 +
  70 +private:
  71 + void associate_detections_to_trackers(vector< vector<int> > &matched, vector<int> &unmatched_dets, vector<int> &unmatched_trks, vector< vector<float> > &dets, vector< vector<float> > &trks, float iou_threshold = 0.3);
  72 + void associate_detections_to_trackers_v2(vector< vector<int> > &matched, vector<int> &unmatched_dets, vector<int> &unmatched_trks, vector< vector<float> > &dets, vector< vector<float> > &trks, float maxLen); //added by zsh 220719
  73 + //int addTracker(VPT_ObjInfo *result, int resultcount);
  74 + int Traffic();
  75 +};
  76 +//辅助函数
  77 +void RectboundCheck(int Width, int Height, det_objinfo * result); //防止坐标越界 by zl
  78 +bool intersect(cv::Point aa, cv::Point bb, cv::Point cc, cv::Point dd); //判断两个线条是否相交 暂时未用到
  79 +bool line_rect_intersection(cv::Point start_p, cv::Point end_p, int left, int top, int right, int bottom); //判断矩形框与线条是否相交
  80 +#endif
0 \ No newline at end of file 81 \ No newline at end of file
src/ai_engine_module/vpt.h 0 → 100644
  1 +/*******************************************************************************************
  2 +* Version: vpt_det_v0.0.0
  3 +* CopyRight: 中科院自动化研究所模式识别实验室图像视频组
  4 +* UpdateDate: 20190327
  5 +* Content: 人车物检测
  6 +********************************************************************************************/
  7 +
  8 +#ifndef VPT_DET_H_
  9 +#define VPT_DET_H_
  10 +
  11 +#ifdef _MSC_VER
  12 +#ifdef VPT_DET_EXPORTS
  13 +#define VPT_DET_API __declspec(dllexport)
  14 +#else
  15 +#define VPT_DET_API __declspec(dllimport)
  16 +#endif
  17 +#else
  18 +#define VPT_DET_API __attribute__ ((visibility ("default")))
  19 +#endif
  20 +
  21 +#include "sy_common.h"
  22 +
  23 +//extern "C"
  24 +//{
  25 +
  26 +#ifndef MAX_BATCH_SIZE
  27 +#define MAX_BATCH_SIZE 16
  28 +#endif
  29 +
  30 +#define MAX_DET_COUNT 50
  31 +
  32 + //Utools Obj Results
  33 +#ifndef __VPT_OBJ_RESULT__
  34 +#define __VPT_OBJ_RESULT__
  35 + typedef struct vpt_obj_result
  36 + {
  37 + int obj_id; //不开启跟踪时对应batch输入顺序,开启后对应目标的id
  38 + sy_rect obj_rect; //位置
  39 + int obj_index;
  40 + float obj_score;
  41 + }vpt_obj_result;
  42 +#endif
  43 +
  44 + //Utools Results
  45 +#ifndef __VPT_RESULT__
  46 +#define __VPT_RESULT__
  47 + typedef struct vpt_result
  48 + {
  49 + int obj_count_; //返回特征数组总个数 < 检测中:单batch检测总数 / 分类中:Multi数 >
  50 + vpt_obj_result *obj_results_; //单batch中 所有的结果 batch size <= MAX_BATCH_SIZE
  51 + }vpt_result;
  52 +#endif //by Junlin 190121
  53 +
  54 +#ifndef __VPT_PARAM__
  55 +#define __VPT_PARAM__
  56 + typedef struct vpt_param
  57 + {
  58 + // int mode; //运行模式(DEVICE_GPU / DEVICE_CPU)
  59 + int devId; //ָ指定显卡id
  60 + char* modelNames;
  61 + // char* modelNames_b10;
  62 + float threshold;
  63 + bool isTrk; //是否开启跟踪
  64 + //vpt_param() :mode(DEVICE_GPU), gpuid(0), threshold(0.6) {};
  65 + }vpt_param;
  66 +#endif
  67 +
  68 + /*************************************************************************
  69 + * FUNCTION: hcp_init
  70 + * PURPOSE: 初始化
  71 + * PARAM:
  72 + [out] tools - 句柄
  73 + [in] param - 初始化参数
  74 + * RETURN:
  75 + [out] int - 初始化是否成功(SUCCEEDED表示成功,FAILED表示失败)
  76 + * NOTES:
  77 + *************************************************************************/
  78 + VPT_DET_API int vpt_init(void **handle, vpt_param param);
  79 +
  80 + /*************************************************************************
  81 + * FUNCTION: hcp_process
  82 + * PURPOSE: 人骑车属性检测
  83 + * PARAM:
  84 + [in] tools - 句柄
  85 + [in] img_data - 检测图像数据
  86 + [in] width - 检测图像宽度
  87 + [in] height - 检测图像高度
  88 + [in] channels - 检测图像通道数
  89 + [in] result - 检测结果
  90 + * RETURN:
  91 + [out] int - 检测是否成功(SUCCEEDED表示成功,FAILED表示失败)
  92 + * NOTES:
  93 + *************************************************************************/
  94 + // VPT_DET_API int vpt_process(void * handle, sy_img img, vpt_result *result);
  95 +
  96 +
  97 + VPT_DET_API int vpt_batch(void * handle, sy_img *batch_img, int batchsize, vpt_result **result);
  98 +
  99 + // VPT_DET_API int vpt_batch10(void * handle, sy_img *batch_img, int batchsize, vpt_result **result);
  100 +
  101 + /*************************************************************************
  102 + * FUNCTION: hcp_release
  103 + * PURPOSE: 资源释放
  104 + * PARAM:
  105 + [in] tools - 处理句柄
  106 + * RETURN: NULL
  107 + * NOTES:
  108 + *************************************************************************/
  109 + VPT_DET_API void vpt_release(void **handle);
  110 +
  111 +
  112 + /*************************************************************************
  113 + * FUNCTION: hcp_get_version
  114 + * PURPOSE:
  115 + * PARAM: NULL
  116 + * RETURN: 版本号
  117 + * NOTES:
  118 + *************************************************************************/
  119 + VPT_DET_API const char * vpt_get_version();
  120 +//}
  121 +#endif
src/ai_platform/ErrorInfo.h 0 → 100644
  1 +#ifndef ERRORINFO_H_
  2 +#define ERRPRINFO_H_
  3 +
  4 +
  5 +//--------------------------------通用------------------------------------//
  6 +
  7 +#define SUCCESS 0 //成功
  8 +#define FAILED -1 //失败
  9 +
  10 +//1.通用错误 预留编号:(-199) - (-100)
  11 +#define PARAMS_NULL_ERROR -100 //参数为空
  12 +#define FILE_NOTFOUND_ERROR -101 //文件找不到
  13 +#define HANDLE_NULL_ERROR -102 //句柄为空
  14 +#define TYPE_UNKNOWN -103 //未知类型
  15 +#define IMG_DATA_ERROR -104 //图像数据错误
  16 +#define IMG_PARAMS_ERROR -105 //图像参数(宽 高 或者 通道数)有错误
  17 +#define AUTHOR_ERROR -106 //授权失败
  18 +#define VERSION_EXPIRED -107 //时间限制下的版本过期
  19 +#define VIDEOFILEERROR -108 //视频打开失败
  20 +#define BUFFNOTENOUGH -109 //缓冲区太小
  21 +
  22 +#define MEAN_ERROR -110 //均值错误
  23 +#define MODEL_IMG_PARAMS_ERROR -111 //
  24 +#define GPU_DEVICE_ERROR -112 //GPU显卡参数错误
  25 +
  26 +#define CONFIG_FILE_NOTFOUND_ERROR -117 //配置文件找不到
  27 +#define TIMEOUT_ERROR -118 //等待超时
  28 +
  29 +//------------------------------------------------------------------------//
  30 +
  31 +
  32 +//-----------------------------深度学习相关-------------------------------//
  33 +
  34 +//1.通用模块 预留编号:(-299) - (-200)
  35 +
  36 +//a. caffe部分 预留编号:(-239) - (-200)
  37 +#define BATCH_SIZE_NO_EQUAL_INPUT -200 //BATCH_SIZE不匹配
  38 +#define LAYER_NO_REGISTER -201 //层未注册
  39 +
  40 +//b. 网络和模型部分 预留编号:(-279) - (-240)
  41 +#define PROTOFILE_MODEL_MISMATCH -240 //网络和模型不匹配
  42 +#define PROTOFILEORVECTOR_NOTFOUND -241 //网络文件或者数组找不到
  43 +#define PROTOFILE_NOTFOUND -242 //网络文件找不到
  44 +#define PROTOVECTOR_NOTFOUND -243 //网络数组找不到
  45 +#define MODELFILE_NOTFOUND -244 //模型文件找不到
  46 +#define MODELLENGTH_ERROE -245 //模型数组长度错误
  47 +#define MODELVECTOR_ERROE -246 //模型数组错误
  48 +
  49 +//c. 其他深度学习通用错误 预留编号:(-299) - (-280)
  50 +
  51 +
  52 +//----------------------------------------//
  53 +
  54 +
  55 +//2.人脸模块 预留编号:(-349) - (-300)
  56 +
  57 +
  58 +#define QUALITY_INIT_ERROR -300 //质量检测初始化失败
  59 +#define ROTATIONCUT_INIT_ERROR -301 //切割旋转初始化失败
  60 +#define FACERECG_INITFAILD_ERROR -302 //人脸识别初始化失败
  61 +#define FACECUT_INITFAILD_ERROR -303 //人脸切割旋转初始化失败
  62 +#define LDMK_INIT_ERROR -304 //关键点检测初始化失败
  63 +#define FACEDETECT_INIT_ERROR -305 //人脸检测初始化失败
  64 +
  65 +
  66 +
  67 +//----------------------------------------//
  68 +
  69 +
  70 +//3.跟踪模块 预留编号:(-399) - (-350)
  71 +#define TRACKER_INIT_ERROR -350 //轨迹跟踪初始化失败
  72 +
  73 +
  74 +//----------------------------------------//
  75 +
  76 +
  77 +//4.快照模块 预留编号:(-449) - (-400)
  78 +#define SHAPSHOT_INIT_ERROR -400 //快照初始化失败
  79 +
  80 +
  81 +//----------------------------------------//
  82 +
  83 +
  84 +//5.流量统计模块 预留编号:(-499) - (-450)
  85 +#define TRAFFICSTATISTICS_INIT_ERROR -450 //流量统计初始化失败
  86 +
  87 +
  88 +
  89 +
  90 +//------------------------------------------------------------------------//
  91 +
  92 +
  93 +//-----------------------------授权部分相关-------------------------------//
  94 +
  95 +//1.授权通用模块 预留编号:(-600) - (-500)
  96 +#define AUTHOR_TIMEEXPIRED_ERROR -500 //超出有效期
  97 +#define AUTHOR_SERVER_ERROR -501 //服务器出错
  98 +#define AUTHOR_NOAUTHORIZATION_ERROR -502 //未注册且没有装机剩余量
  99 +#define AUTHOR_NOCOMMUNICATION_ERROR -503 //无法通信
  100 +#define AUTHOR_NET_ERROR -504 //网络出错
  101 +
  102 +
  103 +
  104 +// mq 预留编号:(-650) - (-600)
  105 +#define MQ_CONN_ERROR -601
  106 +
  107 +
  108 +
  109 +
  110 +#endif
0 \ No newline at end of file 111 \ No newline at end of file
src/ai_platform/Makefile 0 → 100644
  1 +# 各项目录
  2 +LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
  3 +DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
  4 +OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
  5 +SRC_DIR:=$(TOP_DIR)/$(MODULE)
  6 +
  7 +# 源文件以及中间目标文件和依赖文件
  8 +SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
  9 +OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
  10 +DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
  11 +
  12 +# 自动生成头文件依赖选项
  13 +DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
  14 +
  15 +DEFS = -DENABLE_DVPP_INTERFACE
  16 +
  17 +# 最终目标文件
  18 +TARGET:=$(BUILD_DIR)/bin/demo
  19 +
  20 +
  21 +include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/include
  22 +
  23 +lib_dir=-L/usr/lib \
  24 + -L/usr/local/lib \
  25 + -L/usr/local/Ascend/driver/lib64 \
  26 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/atc/lib64\
  27 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64 \
  28 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64/stub \
  29 + -L/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/lib64 \
  30 + -L/usr/local/Ascend/driver/lib64/driver
  31 +
  32 +lib=-lacl_dvpp -lascendcl -lmmpa -lglog -lgflags -lpthread -lz -lacl_dvpp_mpi -lruntime -lascendalog -lc_sec -lmsprofiler -lgert -lge_executor -lge_common \
  33 + -lgraph -lascend_protobuf -lprofapi -lerror_manager -lexe_graph -lregister -lplatform
  34 +
  35 +INCLUDE= -I $(TOP_DIR)/interface \
  36 +
  37 +LIBSPATH= -L $(BUILD_DIR)/interface/lib -l:interface.a \
  38 + -L $(BUILD_DIR)/dvpp/lib -l:dvpp.a
  39 +
  40 +CXXFLAGS= -g -O0 -fPIC $(INCLUDE) $(include_dir) $(LIBSPATH) $(INCS) $(LIBS) $(lib_dir) $(lib) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
  41 + # -DUNICODE -D_UNICODE
  42 +
  43 +# 默认最终目标
  44 +.PHONY:all
  45 +all:$(TARGET)
  46 +
  47 +# 生成最终目标
  48 +$(TARGET): $(OBJS) | $(LIB_DIR)
  49 + @echo -e "\e[32m""Linking static library $(TARGET)""\e[0m"
  50 + @echo -e "$(CXX) -o $@ $^ $(DEPFLAGS) $(CXXFLAGS) $(MACROS)"
  51 + $(CXX) -o $@ $^ $(DEPFLAGS) $(CXXFLAGS) $(MACROS)
  52 +
  53 +# 若没有lib目录则自动生成
  54 +$(LIB_DIR):
  55 + @mkdir -p $@
  56 +
  57 +# 生成中间目标文件
  58 +$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
  59 + @echo -e "\e[33m""Building object $@""\e[0m"
  60 + @echo -e "$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<"
  61 + $(CXX) -c $(DEPFLAGS) $(CXXFLAGS) -o $@ $<
  62 +
  63 +# 若没有obj目录则自动生成
  64 +$(OBJ_DIR):
  65 + @mkdir -p $@
  66 +
  67 +# 若没有.dep目录则自动生成
  68 +$(DEP_DIR):
  69 + @mkdir -p $@
  70 +
  71 +# 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
  72 +$(DEPS):
  73 +
  74 +# 引入中间目标文件头文件依赖关系
  75 +include $(wildcard $(DEPS))
  76 +
  77 +# 直接删除组件build目录
  78 +.PHONY:clean
  79 +clean:
  80 + @rm -rf $(BUILD_DIR)/$(MODULE)
src/ai_platform/MultiSourceProcess.cpp 0 → 100644
  1 +#include "MultiSourceProcess.h"
  2 +#include "../common/logger.hpp"
  3 +
  4 +#include <string>
  5 +#include <queue>
  6 +#include <mutex>
  7 +#include <chrono>
  8 +#include <thread>
  9 +
  10 +#include "../decoder/interface/DecoderManager.h"
  11 +#include "../decoder/interface/utiltools.hpp"
  12 +#include "../util/vpc_util.h"
  13 +#include "../util/crop_process.h"
  14 +#include "../helpers/time_helper.hpp"
  15 +#include "../helpers/os_helper.hpp"
  16 +#include "../helpers/gen_json.hpp"
  17 +#include "../reprocessing_module/save_snapshot_reprocessing.h"
  18 +
  19 +#include "macro_definition.h"
  20 +
  21 +#define VEHICLE_MULTI_BOXES
  22 +
  23 +using namespace std;
  24 +
  25 +
  26 +struct decode_cbk_userdata{
  27 + string task_id;
  28 + void* opaque;
  29 + void* opaque1;
  30 +};
  31 +
  32 +
  33 +
  34 +/**
  35 + * 注意: gpuFrame 在解码器设置的显卡上,后续操作要十分注意这一点,尤其是多线程情况
  36 + * */
  37 +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
  38 + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
  39 + if (ptr!= nullptr)
  40 + {
  41 + CMultiSourceProcess* _this = (CMultiSourceProcess*)ptr->opaque;
  42 + if(nullptr != _this){
  43 + _this->decoded_cbk(devFrame);
  44 + }
  45 + }
  46 +}
  47 +
  48 +void decode_finished_cbk(const void * userPtr){
  49 + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr;
  50 + if (ptr!= nullptr)
  51 + {
  52 + CMultiSourceProcess* _this = (CMultiSourceProcess*)ptr->opaque;
  53 + if(nullptr != _this){
  54 + _this->task_finished(ptr->task_id);
  55 + }
  56 + }
  57 + delete ptr;
  58 + ptr = nullptr;
  59 +}
  60 +
  61 +CMultiSourceProcess::CMultiSourceProcess(){
  62 + aclInit(nullptr);
  63 +}
  64 +
  65 +CMultiSourceProcess::~CMultiSourceProcess(){
  66 + dvpp_crop_release();
  67 + aclFinalize();
  68 +}
  69 +
  70 +int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam){
  71 +
  72 + set_default_logger(LogLevel(vptParam.log_level), "multi_source_process", vptParam.log_path, vptParam.log_mem, vptParam.log_mem);
  73 + LOG_INFO("编译时间:{} {}", __DATE__, __TIME__);
  74 +
  75 + skip_frame_ = 5;
  76 + m_batch_size = 16;
  77 +
  78 + m_devId = vptParam.gpuid;
  79 +
  80 + VPTProcess_PARAM vparam;
  81 + vparam.gpuid = m_devId;
  82 + vparam.max_batch = m_batch_size;
  83 + vparam.threshold = 0.4;
  84 +
  85 + aclrtSetDevice(m_devId);
  86 +
  87 + int ret = vpt_process.init(vparam);
  88 + if (ret < 0){
  89 + return ret;
  90 + }
  91 +
  92 + m_task_param_manager = task_param_manager::getInstance();
  93 + m_snapshot_reprocessing = snapshot_reprocessing::getInstance();
  94 + m_save_snapshot_reprocessing = new save_snapshot_reprocessing(m_devId);
  95 +
  96 + dvpp_crop_init(m_devId);
  97 +
  98 + m_pAlgorthimThread = new thread([](void* arg) {
  99 + CMultiSourceProcess* process = (CMultiSourceProcess*)arg ;
  100 + process->algorthim_process_thread();
  101 + return (void*)0;
  102 + }
  103 + , this);
  104 +
  105 + return 0;
  106 +}
  107 +
  108 +#ifdef POST_USE_RABBITMQ
  109 +/* MQ队列的初始化 */
  110 +int CMultiSourceProcess::AddMqConn(mq_type_t mq_type, rabbitmq_conn_params_t mq_conn_param) {
  111 + /* 初始化MQ队列 */
  112 + if (!mq_manager_->add_conn(mq_type, mq_conn_param)) {
  113 + LOG_ERROR("Connection MQ failed, ip: {} port: {} uname: {} passwd: {}", mq_conn_param.ip, mq_conn_param.port,
  114 + mq_conn_param.uname, mq_conn_param.passwd);
  115 + return MQ_CONN_ERROR;
  116 + }
  117 +
  118 + /* 为报警类 绑定回调 传入mq_manager_.publish 内部直接调用*/
  119 + if (mq_type_t::ALARM_MQ == mq_type)
  120 + m_save_snapshot_reprocessing->set_callback(
  121 + std::bind(&mq::Manager::publish, mq_manager_, mq_type, std::placeholders::_1, true));
  122 +
  123 + return SUCCESS;
  124 +}
  125 +
  126 +/* 获取任务的状态 MQ返回 */
  127 +int CMultiSourceProcess::GetTaskStatus(const string taskID) {
  128 +
  129 + DecoderManager* pDecManager = DecoderManager::getInstance();
  130 +
  131 + std::vector<std::string> taskids;
  132 + std::vector<int> statues;
  133 + if(pDecManager->isPausing(taskID)){
  134 + taskids.emplace_back(taskID);
  135 + statues.emplace_back(2);
  136 + }else if(pDecManager->isRunning(taskID)){
  137 + taskids.emplace_back(taskID);
  138 + statues.emplace_back(1);
  139 + }
  140 +
  141 + if (!taskids.empty()) {
  142 + auto json_str = helpers::gen_json::gen_task_status_json(taskids, statues);
  143 + mq_manager_->publish(mq_type_t::GET_TASK_MQ, json_str.c_str(),true);
  144 + }
  145 +
  146 + return SUCCESS;
  147 +}
  148 +#endif
  149 +
  150 +bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
  151 + DecoderManager* pDecManager = DecoderManager::getInstance();
  152 +
  153 + const char* task_id = _cur_task_param.task_id;
  154 +
  155 + MgrDecConfig config;
  156 + config.name = task_id;
  157 + config.cfg.uri = _cur_task_param.ipc_url;
  158 + config.cfg.post_decoded_cbk = post_decod_cbk;
  159 + config.cfg.decode_finished_cbk = decode_finished_cbk;
  160 + config.cfg.force_tcp = true; // rtsp用tcp
  161 + config.cfg.gpuid = to_string(m_devId);
  162 + config.cfg.skip_frame = skip_frame_;
  163 +
  164 + if (1 == _cur_task_param.dec_type){
  165 + config.cfg.port = _cur_task_param.port;
  166 + config.dec_type = DECODER_TYPE_GB28181;
  167 + config.cfg.uri = task_id;
  168 + if(_cur_task_param.protocal == 0){
  169 + // 指定用udp协议
  170 + config.cfg.force_tcp = false;
  171 + }
  172 + config.cfg.request_stream_cbk = _cur_task_param.gb28181_request_stream_callback ;
  173 + }else if (2 == _cur_task_param.dec_type){
  174 + config.dec_type = DECODER_TYPE_DVPP;
  175 + }else {
  176 + config.dec_type = DECODER_TYPE_FFMPEG;
  177 + }
  178 +
  179 + AbstractDecoder* dec = pDecManager->createDecoder(config);
  180 + if (!dec)
  181 + {
  182 + return false;
  183 + }
  184 +
  185 + decode_cbk_userdata* userPtr = new decode_cbk_userdata;
  186 + userPtr->task_id = string(task_id);
  187 + userPtr->opaque = this;
  188 + userPtr->opaque1 = dec;
  189 + pDecManager->setPostDecArg(config.name, userPtr);
  190 + pDecManager->setFinishedDecArg(config.name, userPtr);
  191 +
  192 + // pDecManager->setDecKeyframe(config.name, true); // 只对关键帧解码
  193 +
  194 +
  195 + // 保存新添加任务的配置参数
  196 + m_task_param_manager->add_task_param(task_id, _cur_task_param);
  197 +
  198 + int input_image_width = 0;
  199 + int input_image_height = 0;
  200 + pDecManager->getResolution(config.name, input_image_width, input_image_height);
  201 + LOG_INFO("task_id: {} width: {} height:{}", task_id, input_image_width, input_image_height);
  202 +
  203 + // 所有参数都准备好之后再启动解码
  204 + bool bStart = pDecManager->startDecodeByName(config.name);
  205 + if (!bStart){
  206 + LOG_INFO("started task {} failed!", config.name);
  207 + pDecManager->closeDecoderByName(config.name);
  208 + return false;
  209 + }
  210 +
  211 + // 人车物跟踪
  212 + if (task_has_vpt_algor(task_id))
  213 + vpt_process.addTaskTracker(task_id, 1, 1, skip_frame_);
  214 +
  215 + m_FinishedTaskMtx.lock();
  216 + m_FinishedTaskMap[task_id] = false;
  217 + m_FinishedTaskMtx.unlock();
  218 +
  219 + LOG_INFO("started task {} successed!", config.name);
  220 +
  221 + return true;
  222 +}
  223 +
  224 +bool CMultiSourceProcess::task_has_vpt_algor(const std::string &task_id){
  225 + //! TODO: create enum iterator.
  226 + auto algor_map = m_task_param_manager->get_task_other_param(task_id);
  227 + if (algor_map == nullptr)
  228 + return false;
  229 +
  230 + return (algor_map->find(algorithm_type_t::HUMAN_GATHER) != algor_map->end() ||
  231 + algor_map->find(algorithm_type_t::HUMAN_SNAPSHOT) != algor_map->end() ||
  232 + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != algor_map->end() ||
  233 + algor_map->find(algorithm_type_t::SMOKING_DET) != algor_map->end() ||
  234 + algor_map->find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != algor_map->end() ||
  235 + algor_map->find(algorithm_type_t::NO_SAFETY_HELMET) != algor_map->end() ||
  236 + algor_map->find(algorithm_type_t::CALL_PHONE_DET) != algor_map->end() ||
  237 + algor_map->find(algorithm_type_t::VEHICLE_SNAPSHOT) != algor_map->end() ||
  238 + algor_map->find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) != algor_map->end() ||
  239 + algor_map->find(algorithm_type_t::PEDESTRIAN_FALL) != algor_map->end() ||
  240 + algor_map->find(algorithm_type_t::PEDESTRIAN_FIGHT) != algor_map->end() ||
  241 + algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() ||
  242 + algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end() ||
  243 + algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() ||
  244 + algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end());
  245 +}
  246 +
  247 +void CMultiSourceProcess::decoded_cbk(DeviceMemory* devFrame){
  248 + do{
  249 + if(m_bfinish){
  250 + break;
  251 + }
  252 + m_DataListMtx.lock();
  253 + if(m_RgbDataList.size() >= 30){
  254 + m_DataListMtx.unlock();
  255 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  256 + continue;
  257 + }
  258 + m_RgbDataList.push_back(devFrame);
  259 + m_DataListMtx.unlock();
  260 + break;
  261 + }while (true);
  262 +}
  263 +
  264 +void CMultiSourceProcess::task_finished(const string task_id){
  265 +
  266 + std::lock_guard<std::mutex> l(m_FinishedTaskMtx);
  267 +
  268 + m_FinishedTaskMap[task_id] = true;
  269 +
  270 + LOG_INFO("task {} finished!", task_id);
  271 +}
  272 +
  273 +bool CMultiSourceProcess::PauseTask(const string taskID){
  274 + return false;
  275 +}
  276 +
  277 +bool CMultiSourceProcess::RestartTask(const string taskID){
  278 + return false;
  279 +}
  280 +
  281 +bool CMultiSourceProcess::FinishTask(const string taskID){
  282 + DecoderManager* pDecManager = DecoderManager::getInstance();
  283 + return pDecManager->closeDecoderByName(taskID);
  284 +}
  285 +
  286 +int CMultiSourceProcess::SnapShot(task_param param){
  287 + return 0;
  288 +}
  289 +
  290 +void CMultiSourceProcess::CloseAllTask(){
  291 + m_bfinish = true;
  292 +
  293 + DecoderManager* pDecManager = DecoderManager::getInstance();
  294 + pDecManager->closeAllDecoder();
  295 +
  296 + if(m_pAlgorthimThread){
  297 + m_pAlgorthimThread->join();
  298 + m_pAlgorthimThread = nullptr;
  299 + }
  300 +
  301 + m_DataListMtx.lock();
  302 + while (!m_RgbDataList.empty()){
  303 + DeviceMemory* gpuMem = m_RgbDataList.front();
  304 + delete gpuMem;
  305 + gpuMem = nullptr;
  306 + m_RgbDataList.pop_front();
  307 + }
  308 + m_DataListMtx.unlock();
  309 +
  310 + int size = m_RgbDataList.size();
  311 + bool bEmpty = m_RgbDataList.empty();
  312 +
  313 + LOG_INFO("CloseAllTask exit.");
  314 +}
  315 +
  316 +void CMultiSourceProcess::clear_finished_task(){// 清理已经结束的任务
  317 +
  318 + std::lock_guard<std::mutex> l1(m_FinishedTaskMtx);
  319 + std::lock_guard<std::mutex> l2(m_DataListMtx);
  320 +
  321 + for (auto iter_finished = m_FinishedTaskMap.begin(); iter_finished!=m_FinishedTaskMap.end(); ){
  322 + if(iter_finished->second){
  323 + // 解码已经结束
  324 + // 判断数据对列中是否还有数据
  325 + string task_id = iter_finished->first;
  326 + bool bFinished = true;
  327 + for (auto iter = m_RgbDataList.begin(); iter!=m_RgbDataList.end(); ++ iter){
  328 + DeviceMemory* gpuMem = *iter;
  329 + if(task_id == gpuMem->getId()){
  330 + bFinished = false;
  331 + break;
  332 + }
  333 + }
  334 +
  335 + if (bFinished){
  336 + // 解码器已经结束,且数据队列中没有改任务的数据,则做最后任务清理工作
  337 + finish_task(task_id,false);
  338 + iter_finished = m_FinishedTaskMap.erase(iter_finished);
  339 + continue;
  340 + }
  341 + }
  342 +
  343 + ++ iter_finished;
  344 + }
  345 +}
  346 +
  347 +bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_snapshot){
  348 +
  349 + // 任务结束,关闭跟踪
  350 + if (!vpt_process.finishTaskTracker(taskID))
  351 + LOG_ERROR("Finish VPT Tracker failed, task_id: {}", taskID);
  352 +
  353 +#ifdef POST_USE_RABBITMQ
  354 + auto json_str = helpers::gen_json::gen_office_task_heart_beat_json({taskID});
  355 + mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true);
  356 +#endif
  357 +
  358 + m_task_param_manager->delete_task_param(taskID);
  359 +
  360 + return true;
  361 +}
  362 +
  363 +int CMultiSourceProcess::algorthim_process_thread(){
  364 + LOG_INFO("algorthim_process_thread start...");
  365 +
  366 + ACL_CALL(aclrtSetDevice(m_devId), ACL_ERROR_NONE, 1);
  367 + aclrtContext ctx;
  368 + ACL_CALL(aclrtCreateContext(&ctx, m_devId), ACL_ERROR_NONE, 1);
  369 +
  370 + while (true){
  371 + if(m_bfinish){
  372 + break;
  373 + }
  374 +
  375 + clear_finished_task();
  376 +
  377 + vector<DeviceMemory*> vec_gpuMem;
  378 + m_DataListMtx.lock();
  379 + while (!m_RgbDataList.empty()){
  380 + DeviceMemory* gpuMem = m_RgbDataList.front();
  381 + vec_gpuMem.push_back(gpuMem);
  382 + m_RgbDataList.pop_front();
  383 + if(vec_gpuMem.size() >= m_batch_size){
  384 + break;
  385 + }
  386 + }
  387 + m_DataListMtx.unlock();
  388 +
  389 + if(vec_gpuMem.size() <= 0){
  390 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  391 + continue;
  392 + }
  393 +
  394 + ACL_CALL(aclrtSetCurrentContext(ctx), ACL_ERROR_NONE, 1);
  395 + algorthim_vpt(vec_gpuMem);
  396 +
  397 + for(int i=0;i < vec_gpuMem.size(); i++){
  398 + DeviceMemory* mem = vec_gpuMem[i];
  399 + if(mem->getSize() <= 0){
  400 + continue;
  401 + }
  402 + delete mem;
  403 + mem = nullptr;
  404 + }
  405 + vec_gpuMem.clear();
  406 +
  407 + }
  408 +
  409 + LOG_INFO("algorthim_process_thread exit.");
  410 +
  411 + return 0;
  412 +}
  413 +
  414 +int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){
  415 +
  416 + vector<string> vpt_interest_task_id;
  417 + vector<sy_img> vpt_interest_imgs(0);
  418 + vector<DeviceMemory*> vec_vptMem;
  419 + for (int i = 0; i < vec_gpuMem.size(); i++) {
  420 + DeviceMemory* mem = vec_gpuMem[i];
  421 + if (!task_has_vpt_algor(mem->getId())){
  422 + continue;
  423 + }
  424 +
  425 + sy_img img;
  426 + img.w_ = mem->getWidth();
  427 + img.h_ = mem->getHeight();
  428 + img.data_ = mem->getMem();
  429 + vpt_interest_imgs.push_back(img);
  430 + vpt_interest_task_id.push_back(mem->getId());
  431 + vec_vptMem.push_back(mem);
  432 + }
  433 +
  434 + /* 待检测的图片不为空 开始检测 */
  435 + if (!vpt_interest_imgs.empty()) {
  436 + vector<vector<int>> deleteObjectID;
  437 + deleteObjectID.resize(vpt_interest_task_id.size());
  438 + vector<vector<onelevel_det_result>> unUsedResult;
  439 + vector<onelevel_det_result> vptResult(0);
  440 +
  441 + /* 一级检测器,内部已完成跟踪操作 */
  442 + vpt_process.process_gpu(vpt_interest_imgs.data(), vpt_interest_task_id, vptResult, deleteObjectID, unUsedResult); // do det & track.
  443 +
  444 + m_snapshot_reprocessing->screen_effective_snapshot(vpt_interest_task_id, vptResult);
  445 +
  446 +#ifndef VEHICLE_MULTI_BOXES
  447 + /* 快照优选(内部可实现不同的快照优选策略) */
  448 + m_snapshot_reprocessing->update_bestsnapshot(vpt_interest_task_id, vpt_interest_imgs.data(), vptResult, deleteObjectID);
  449 +#else
  450 + algorithm_vehicle_relult(vec_vptMem, vptResult, deleteObjectID);
  451 +
  452 + // send_locus_finished_msg(vpt_interest_task_id, deleteObjectID);
  453 +#endif
  454 +
  455 + if(vptResult.size() > 0){
  456 + cout << vptResult[0].obj_count<< endl;
  457 + }
  458 + }
  459 +
  460 + return 0;
  461 +}
  462 +
  463 +int CMultiSourceProcess::algorithm_vehicle_relult(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result>& vptResult, vector<vector<int>>& delete_object_id) {
  464 +
  465 + vector<multi_obj_data_t> results = m_snapshot_reprocessing->get_vehicle_snapshot(vec_devMem, vptResult, skip_frame_);
  466 +
  467 + for (auto &result : results) {
  468 + if(result.objs.size() <= 0){
  469 + continue;
  470 + }
  471 + auto task_id = result.task_id;
  472 + auto task_other_params = m_task_param_manager->get_task_other_param(task_id);
  473 + const auto &algor_other_params = task_other_params->find(algorithm_type_t::VEHICLE_SNAPSHOT);
  474 + if (algor_other_params == task_other_params->end()) {
  475 + LOG_ERROR("[Error] taskId {} not found algor {}", task_id.c_str(), (int)algorithm_type_t::VEHICLE_SNAPSHOT);
  476 + continue;
  477 + }
  478 + const algor_basic_config_param_t *basic_param = algor_other_params->second->basic_param;
  479 +
  480 + std::string cur_timestamp_ms = std::to_string(helpers::timer::get_cur_time_ms());
  481 + const std::string fpath_origin = basic_param->result_folder + helpers::os::sep + task_id + "_" +
  482 + std::to_string(result.objs.size()) + "_" + std::to_string(result.id) + "_" + cur_timestamp_ms + ".jpg";
  483 +
  484 + ImgSaveInfo saveInfo;
  485 + saveInfo.file_path = fpath_origin;
  486 + saveInfo.img_info = dvpp_devMem2vpcImg(result.memPtr);
  487 + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(saveInfo);
  488 +
  489 + vector<vpc_img_info> vec_obj_info_list = dvpp_crop_batch(result.memPtr, result.objs);
  490 + if(vec_obj_info_list.size() != result.objs.size()){
  491 + LOG_ERROR("vpc_crop size error !");
  492 + dvpp_imgList_release(vec_obj_info_list);
  493 + continue;
  494 + }
  495 +
  496 + // 保存抠图并发MQ
  497 + for(int i =0; i < result.objs.size(); i++){
  498 + video_object_info obj = result.objs[i];
  499 +
  500 + std::string cur_timestamp_ms = std::to_string(helpers::timer::get_cur_time_ms());
  501 + const std::string fpath_roi = basic_param->result_folder_little + helpers::os::sep + task_id + "_" +
  502 + std::to_string(obj.object_id) + "_" + cur_timestamp_ms + ".jpg";
  503 +
  504 + video_object_snapshot new_obj_ss_info;
  505 + new_obj_ss_info.analysisRes = nullptr;
  506 + new_obj_ss_info.object_id = obj.object_id;
  507 + new_obj_ss_info.obj_info.set_data(obj.index, obj.confidence, obj.left, obj.top, obj.right, obj.bottom);
  508 + strcpy(new_obj_ss_info.task_id, task_id.c_str());
  509 + strcpy(new_obj_ss_info.video_image_path, fpath_origin.c_str());
  510 + strcpy(new_obj_ss_info.snapshot_image_path, fpath_roi.c_str());
  511 + new_obj_ss_info.nFinished = 0;
  512 + string json_str = "1111";//helpers::gen_json::gen_multi_obj_json(algorithm_type_t::VEHICLE_SNAPSHOT, new_obj_ss_info);
  513 +
  514 + ImgSaveInfo save_info;
  515 + save_info.file_path = fpath_roi;
  516 + save_info.img_info = vec_obj_info_list[i];
  517 + save_info.json_str = json_str;
  518 + m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(save_info);
  519 + }
  520 +
  521 + vec_obj_info_list.clear();
  522 + }
  523 +
  524 + return 0;
  525 +}
  526 +
  527 +void CMultiSourceProcess::send_locus_finished_msg(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID){
  528 + auto task_iter = vpt_interest_task_id.begin();
  529 +
  530 + for (int i = 0; i < deleteObjectID.size(); i++, ++task_iter) // loop taskId.
  531 + {
  532 + string task_id = *task_iter;
  533 + for (int &j : deleteObjectID[i]) // loop algor type.
  534 + {
  535 + OBJ_KEY obj_key = {task_id, j};
  536 +
  537 + auto task_param_ptr = m_task_param_manager->get_task_algor_param(task_id);
  538 + auto task_other_param_ptr = m_task_param_manager->get_task_other_param(task_id);
  539 +
  540 + // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源
  541 + // if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_SNAPSHOT) != task_param_ptr->vehicle_algors.end()) {
  542 + // std::lock_guard<std::mutex> l(m_total_mutex);
  543 + // if (m_total_snapshot_info_multi_object.find(obj_key) != m_total_snapshot_info_multi_object.end()) {
  544 + // video_object_snapshot new_obj_ss_info;
  545 + // new_obj_ss_info.object_id = j;
  546 + // new_obj_ss_info.nFinished = 1;
  547 + // strcpy(new_obj_ss_info.task_id, task_id.c_str());
  548 + // string json_str = helpers::gen_json::gen_multi_obj_json(algorithm_type_t::VEHICLE_SNAPSHOT, new_obj_ss_info);
  549 + // // 通知结束的轨迹
  550 + // m_save_snapshot_reprocessing->reprocessing_finish_locus_async(obj_key,json_str);
  551 +
  552 + // m_total_snapshot_info_multi_object.erase(obj_key);
  553 + // }
  554 + // }
  555 + }
  556 + }
  557 +}
0 \ No newline at end of file 558 \ No newline at end of file
src/ai_platform/MultiSourceProcess.h 0 → 100644
  1 +#include "header.h"
  2 +#include "acl/acl.h"
  3 +#include "acl/ops/acl_dvpp.h"
  4 +#include "task_param_manager.h"
  5 +#include "../ai_engine_module/VPTProcess.h"
  6 +#include "../reprocessing_module/snapshot_reprocessing.h"
  7 +#include "../reprocessing_module/save_snapshot_reprocessing.h"
  8 +
  9 +#include <map>
  10 +#include <mutex>
  11 +#include <thread>
  12 +#include <list>
  13 +#include <vector>
  14 +#include <deque>
  15 +
  16 +
  17 +
  18 +using namespace std;
  19 +
  20 +class DeviceMemory;
  21 +
  22 +class CMultiSourceProcess {
  23 +public:
  24 + CMultiSourceProcess();
  25 + ~CMultiSourceProcess();
  26 +
  27 + int InitAlgorthim(tsl_aiplatform_param vptParam);
  28 + bool AddTask(task_param _cur_task_param);
  29 + bool PauseTask(const string taskID);
  30 + bool RestartTask(const string taskID);
  31 + bool FinishTask(const string taskID);
  32 + void CloseAllTask();
  33 + int SnapShot(task_param param);
  34 +
  35 +#ifdef POST_USE_RABBITMQ
  36 + int AddMqConn(mq_type_t mq_type, rabbitmq_conn_params_t mq_conn_param);
  37 + int GetTaskStatus(const string taskID);
  38 +#endif
  39 +
  40 +public:
  41 + int algorthim_process_thread(); // 算法处理线程
  42 + void task_finished(const string task_id);
  43 + void decoded_cbk(DeviceMemory* devFrame);
  44 +
  45 +private:
  46 + // 算法相关
  47 + int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem);
  48 +
  49 +private:
  50 + // 工具处理函数
  51 + bool task_has_vpt_algor(const std::string &task_id);
  52 + void clear_finished_task();
  53 + bool finish_task(const string taskID, const bool delete_snapshot);
  54 + int algorithm_vehicle_relult(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result>& vptResult, vector<vector<int>>& delete_object_id);
  55 + void send_locus_finished_msg(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID);
  56 +
  57 +private:
  58 + int m_devId;
  59 +
  60 + snapshot_reprocessing *m_snapshot_reprocessing{nullptr};
  61 + task_param_manager *m_task_param_manager{nullptr};
  62 + save_snapshot_reprocessing *m_save_snapshot_reprocessing{nullptr};
  63 +
  64 + VPTProcess vpt_process;
  65 + int skip_frame_ = 5; // 控制跳帧参数
  66 +
  67 + deque<DeviceMemory*> m_RgbDataList;
  68 + mutex m_DataListMtx;
  69 +
  70 + mutex m_FinishedTaskMtx;
  71 + map<string,bool> m_FinishedTaskMap;
  72 +
  73 + thread* m_pAlgorthimThread;
  74 + bool m_bfinish{false};
  75 +
  76 + int m_batch_size{1};
  77 +
  78 +#ifdef POST_USE_RABBITMQ
  79 + mq::Manager *mq_manager_{nullptr};
  80 +#endif
  81 +
  82 +};
0 \ No newline at end of file 83 \ No newline at end of file
src/ai_platform/common_header.h 0 → 100644
  1 +#ifndef ___COMMON_HEADER_H__
  2 +#define ___COMMON_HEADER_H__
  3 +
  4 +#include <cmath>
  5 +#include <type_traits>
  6 +
  7 +struct point_t {
  8 + int x, y;
  9 +};
  10 +
  11 +struct box_t {
  12 + long id; // -1: placeholder.
  13 + float score;
  14 + int top, left, right, bottom, cls;
  15 +
  16 + int width() const {
  17 + return std::max(0, right - left);
  18 + }
  19 +
  20 + int height() const {
  21 + return std::max(0, bottom - top);
  22 + }
  23 +
  24 + int cx() const {
  25 + return std::max(0, int((left + right) * 0.5f));
  26 + }
  27 +
  28 + int cy() const {
  29 + return std::max(0, int((top + bottom) * 0.5f));
  30 + }
  31 +};
  32 +
  33 +#endif // ___COMMON_HEADER_H__
0 \ No newline at end of file 34 \ No newline at end of file
src/ai_platform/det_obj_header.h 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-11-24 11:39:57
  4 + */
  5 +
  6 +#pragma once
  7 +
  8 +#include "header.h"
  9 +#include <string.h>
  10 +#include <set>
  11 +#include <bitset>
  12 +
  13 +using namespace std;
  14 +
  15 +#define VTTYPECOUNT 10 //支持的最大类别数
  16 +#define MAX_OBJ_COUNT 100
  17 +
  18 +//设置最小检测框,直接指定sy_rect的宽高即可,各种类目标小于最小检测框大小时不进行快照的保存和后续二次属性分析
  19 +//sy_rect m_boxsize[DETECTTYPE] = { sy_rect(0,0,40, 90), sy_rect(0,0,50, 80), sy_rect(0,0,50, 80), sy_rect(0,0,60, 80), sy_rect(0,0,80, 80), sy_rect(0,0,90, 90), sy_rect(0,0,100, 100), sy_rect(0,0,100, 100), sy_rect(0,0,100, 100) }; //行人 自行�?摩托�?三轮�?小型�?大车 卡车 拖拉�?中巴
  20 +
  21 +struct OBJ_INDEX {
  22 + int index;
  23 + int count; //用于对index的计数
  24 + OBJ_INDEX() : count(0), index(0) {}
  25 +};
  26 +
  27 +// 0-行人 1-自行车 2-摩托车 3-三轮车 4-小型车 5-大车 6-卡车 7-拖拉机 8-中巴
  28 +enum class det_class_label_t
  29 +{
  30 + HUMAN = 0,
  31 +
  32 + BICYCLE = 1,
  33 + MOTOCYCLE = 2,
  34 + TRICYCLE = 3,
  35 +
  36 + SMALL_CAR = 4,
  37 + LARGE_CAR = 5,
  38 + TRUCK = 6,
  39 + TRACTOR = 7,
  40 + MEDIUM_BUS = 8,
  41 +};
  42 +
  43 +typedef struct det_objinfo //结果结构体
  44 +{
  45 + int left;
  46 + int top;
  47 + int right;
  48 + int bottom;
  49 + int center_x;
  50 + int center_y;
  51 +
  52 + int index; // 行人/车辆类别,支持10类
  53 + long id; // 目标唯一ID,同一ID为同一目标
  54 + int num; // 该ID序列下的第num帧
  55 + double confidence; // 置信度
  56 + int snap_flag;
  57 + sy_point landmark_point[25];//人脸关键点位置信息
  58 + //-added by zsh 220719 人脸姿态角-
  59 + float roll = 0.0;
  60 + float yaw = 0.0;
  61 + float pitch = 0.0;
  62 + //-------------------------------
  63 +}det_objinfo;
  64 +
  65 +typedef struct onelevel_det_result
  66 +{
  67 + string task_id;
  68 + int obj_count;
  69 + det_objinfo obj[MAX_OBJ_COUNT];
  70 +}onelevel_det_result;
  71 +
  72 +
  73 +struct OBJ_KEY {
  74 + string video_id;
  75 + int obj_id;
  76 +
  77 + bool operator< (OBJ_KEY const& _A) const
  78 + {
  79 + if (strcmp(video_id.c_str(), _A.video_id.c_str()) < 0) return true;
  80 + if (strcmp(video_id.c_str(), _A.video_id.c_str()) == 0) return obj_id < _A.obj_id;
  81 +
  82 + return false;
  83 + }
  84 + bool operator== (OBJ_KEY const& _A) const
  85 + {
  86 + if (strcmp(video_id.c_str(), _A.video_id.c_str())==0 && obj_id == _A.obj_id)
  87 + return true;
  88 + else
  89 + return false;
  90 + }
  91 +};
  92 +
  93 +#define EDGESIZE 4
  94 +#define SCALE_OUT 10 // 外扩信息
  95 +
  96 +const sy_rect m_boxsize[DETECTTYPE] = { sy_rect(0, 0, 40, 90), sy_rect(0, 0, 50, 80), sy_rect(0, 0, 50, 80), sy_rect(0, 0, 60, 80), sy_rect(0, 0, 80, 80),
  97 +sy_rect(0, 0, 90, 90), sy_rect(0, 0, 100, 100), sy_rect(0, 0, 100, 100), sy_rect(0, 0, 100, 100) }; //行人 自行车 摩托车 三轮车 小型车 大车 卡车 拖拉机 中巴
  98 +// const int minDistance[EDGESIZE] = { 35, 50, 35, 50 };
  99 +const int minDistance[EDGESIZE] = { 80, 100, 80, 100 };
src/ai_platform/header.h 0 → 100644
  1 +#pragma once
  2 +
  3 +#ifdef _MSC_VER
  4 +#include <windows.h>
  5 +#else
  6 +
  7 +#include <cstddef>
  8 +
  9 +#endif
  10 +
  11 +#include "sy_common.h"
  12 +#include <map>
  13 +#include <vector>
  14 +
  15 +#define DETECTTYPE 9
  16 +// #define MTASK_DEBUG_
  17 +
  18 +enum class algorithm_type_t {
  19 + PLACEHOLDER = -2,
  20 + UNKNOWN = -1,
  21 + VIDEO_SNAPSHOT = 100, // 220802byzsh 视频快照
  22 + FACE_SNAPSHOT = 101,
  23 + VIDEO_TIMING_SNAPSHOT = 102, // 230220byzsh 视频定时抓拍
  24 + HUMAN_SNAPSHOT = 201,
  25 +
  26 + PEDESTRIAN_FALL = 202,
  27 + PEDESTRIAN_FIGHT = 203,
  28 + HUMAN_GATHER = 204,
  29 + SMOKING_DET = 206,
  30 + CALL_PHONE_DET = 207,
  31 + NO_REFLECTIVE_CLOTHING = 208,
  32 + NO_SAFETY_HELMET = 209,
  33 + PEDESTRIAN_RETROGRADE = 210,
  34 + PEDESTRIAN_TRESPASS = 211,
  35 + ROAD_WORK_DET = 212, // 221026byzsh施工占道
  36 +
  37 + VEHICLE_SNAPSHOT = 301,
  38 + VEHICLE_RETROGRADE = 310,
  39 + VEHICLE_TRESPASS = 311,
  40 +
  41 + NONMOTOR_VEHICLE_SNAPSHOT = 401,
  42 + TAKEAWAY_MEMBER_CLASSIFICATION = 402,
  43 +};
  44 +
  45 +
  46 +typedef algorithm_type_t algo_type;
  47 +
  48 +
  49 +static bool is_support_algorithm_type(int algor_type) {
  50 + return (int) algorithm_type_t::FACE_SNAPSHOT <= algor_type &&
  51 + (int) algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION >= algor_type;
  52 +};
  53 +
  54 +static bool is_support_algorithm_type(algorithm_type_t algor_type) {
  55 + return is_support_algorithm_type((int) algor_type);
  56 +};
  57 +
  58 +
  59 +//二次属性分析结果结构体
  60 +#ifndef __CLASSIFY_OBJ_RESULT__
  61 +#define __CLASSIFY_OBJ_RESULT__
  62 +typedef struct classify_obj_res //分类结果结构体
  63 +{
  64 + int res_index; //分类结果
  65 + float res_prob; //分类结构体
  66 + classify_obj_res() : res_index(0), res_prob(0) {};
  67 +} classify_obj_res;
  68 +#endif
  69 +
  70 +//检测结果结构体
  71 +#ifndef __DETECTION_OBJ_RESULT__
  72 +#define __DETECTION_OBJ_RESULT__
  73 +typedef struct detection_obj_res //分类结果结构体
  74 +{
  75 + int res_index;
  76 + float res_prob;
  77 + int res_left;
  78 + int res_top;
  79 + int res_right;
  80 + int res_bottom;
  81 +
  82 + detection_obj_res() : res_index(0), res_prob(0), res_left(0), res_top(0), res_right(0), res_bottom(0) {};
  83 +
  84 + void set_data(int _res_index, float _res_prob, int _res_left, int _res_top, int _res_right, int _res_bottom) {
  85 + res_index = _res_index;
  86 + res_prob = _res_prob;
  87 + res_left = _res_left;
  88 + res_top = _res_top;
  89 + res_right = _res_right;
  90 + res_bottom = _res_bottom;
  91 + }
  92 +} detection_obj_res;
  93 +#endif
  94 +
  95 +
  96 +//行人二次属性分析结构 + 特征结果
  97 +#ifndef __HP_OBJ_RESULT__
  98 +#define __HP_OBJ_RESULT__
  99 +const int HP_FIR_INDEX_SIZE = 16;
  100 +const int HF_FEA_SIZE = 128;
  101 +typedef struct hp_res {
  102 + classify_obj_res res_objs[HP_FIR_INDEX_SIZE]{}; //分类结果
  103 +} hp_res;
  104 +
  105 +#ifndef __INT8__
  106 +#define __INT8__
  107 +typedef unsigned char int8;
  108 +#endif
  109 +
  110 +typedef struct hp_result {
  111 + hp_res res_objs{}; //分类结果
  112 + int8 feature[HF_FEA_SIZE]{}; //特征
  113 +} hp_result;
  114 +#endif
  115 +
  116 +//行人打架/跌倒结果
  117 +#ifndef __HP_FALLFIGHT_RESULT__
  118 +#define __HP_FALLFIGHT_RESULT__
  119 +typedef struct hp_fallfight_result {
  120 + float fall_score; //跌倒得分
  121 + float fight_score; //打架得分
  122 + float background_score; //背景得分
  123 +} hp_fallfight_result;
  124 +#endif
  125 +
  126 +
  127 +//人骑车二次属性分析结构 + 特征结果
  128 +#ifndef __HCP_OBJ_RESULT__
  129 +#define __HCP_OBJ_RESULT__
  130 +const int HCP_FIR_INDEX_SIZE = 14;
  131 +const int HCF_FEA_SIZE = 128;
  132 +typedef struct hcp_res {
  133 + classify_obj_res res_objs[HCP_FIR_INDEX_SIZE]{}; //分类结果
  134 +} hcp_res;
  135 +
  136 +typedef struct hcp_result //人骑车二次属性分析以及特征结果
  137 +{
  138 + hcp_res res_objs{}; //分类结果
  139 + int8 feature[HCF_FEA_SIZE]{}; //特征
  140 + classify_obj_res kuaidiyuan_res; //快递员识别结果
  141 + classify_obj_res waimaiyuan_res; //外卖员识别结果
  142 +} hcp_result;
  143 +
  144 +#endif
  145 +
  146 +
  147 +#define VEHICLE_FEA_SIZE 128
  148 +#define PLATENUM 8 //车牌号码位数
  149 +#define MAX_PALTE_COUNT 10 //每张图片中最多检测出10个车牌
  150 +
  151 +#define SINGLETYPE_BLUE 0 //单排蓝色
  152 +#define SINGLETYPE_YELLOW 1 //单排黄色
  153 +#define SINGLETYPE_WHITE 2 //单排白色
  154 +#define SINGLETYPE_BLACK 3 //单排黑色
  155 +#define DOUBLETYPE_YELLOW 4 //双排黄色
  156 +#define DOUBLETYPE_WHITE 5 //双排白色
  157 +#define NEWENERGYTYPE_YELLOWGREEN 6 //新能源黄绿色
  158 +#define NEWENERGYTYPE_WHITEGRA 7 //新能源白绿色
  159 +
  160 +//车牌号码
  161 +#ifndef VPLATENUM_RESULT_
  162 +#define VPLATENUM_RESULT_
  163 +typedef struct vplate_num {
  164 + char character[4];
  165 + float maxprob;
  166 +} vplate_num;
  167 +#endif
  168 +
  169 +#ifndef VP_RESULT_
  170 +#define VP_RESULT_
  171 +typedef struct vplate_result {
  172 + sy_rect rect;
  173 + float detect_score;
  174 + vplate_num recg[PLATENUM];
  175 + float num_score;
  176 + int type; //车牌类型
  177 +} vplate_result;
  178 +#endif
  179 +
  180 +
  181 +#ifndef VR_RESULT_
  182 +#define VR_RESULT_
  183 +typedef struct vr_result //结果
  184 +{
  185 + char vehicle_brand[260]; //车辆品牌
  186 + char vehicle_subbrand[260]; //车辆子品牌
  187 + char vehicle_issue_year[260]; //车辆年款
  188 + char vehicle_type[260]; //车辆类型
  189 + char freight_ton[260]; //货车吨级
  190 + float name_score; //识别置信度
  191 +} vr_result;
  192 +#endif
  193 +
  194 +#ifndef VC_RESULT_
  195 +#define VC_RESULT_
  196 +typedef struct vc_result {
  197 + int res_index; //车颜色结果index
  198 + float res_prob; //识别置信度
  199 + vc_result() : res_index(0), res_prob(0) {};
  200 +} vc_result;
  201 +#endif
  202 +
  203 +//VEHICLE
  204 +#ifndef __VEHICLE_OBJ_RESULT__
  205 +#define __VEHICLE_OBJ_RESULT__
  206 +typedef struct vehicle_result //车二次属性分析结果
  207 +{
  208 + vr_result vr_res; //车型识别结果
  209 + vc_result vc_res; //车颜色识别结果
  210 + vplate_result vp_res; //车牌检测结果
  211 + int8 feature[VEHICLE_FEA_SIZE]{}; //车辆特征
  212 +} vehicle_result;
  213 +#endif
  214 +
  215 +//返回的检测物体快照结果
  216 +#ifndef __VIDEO_OBJECT_SNAPSHOT__
  217 +#define __VIDEO_OBJECT_SNAPSHOT__
  218 +typedef struct video_object_snapshot {
  219 + char task_id[128]; //该物体属于的任务ID号
  220 + int object_id; //该物体的ID号
  221 + char video_image_path[256]; //该物体快照的视频截图保存路径
  222 + char snapshot_image_path[256]; //该物体快照抠图保存路径
  223 +
  224 + detection_obj_res obj_info;
  225 + void *analysisRes; //二次属性分析结果
  226 + int nFinished; // 轨迹是否已经结束
  227 +} video_object_snapshot;
  228 +#endif
  229 +
  230 +//返回的检测物体结果信息
  231 +#ifndef __VIDEO_OBJECT_INFO__
  232 +#define __VIDEO_OBJECT_INFO__
  233 +typedef struct video_object_info {
  234 + int task_id; //该物体属于的任务ID号
  235 + int task_frame_count; //该物体当前出现的帧号
  236 + int object_id; //该物体的ID号
  237 + int left; //该物体位置的左坐标
  238 + int top; //该物体位置的上坐标
  239 + int right; //该物体位置的右坐标
  240 + int bottom; //该物体位置的下坐标
  241 + int index; //该物体所属类别的编号
  242 + double confidence; //该物体的置信度
  243 +} video_object_info;
  244 +#endif
  245 +
  246 +// 人员聚集参数结构体
  247 +#ifndef ___HUMAN_GATHER_ALGOR_CONFIG_PARAM__
  248 +#define ___HUMAN_GATHER_ALGOR_CONFIG_PARAM__
  249 +typedef struct algor_config_param_human_gather {
  250 + int frame_stride; //人数推送间隔(实际间隔 = frame_stride * 内部跳帧数)
  251 + int human_count_threshold; //人数报警阈值
  252 + algor_config_param_human_gather()
  253 + : frame_stride(1), human_count_threshold(0) {}
  254 +} algor_config_param_human_gather;
  255 +#endif // #ifndef ___HUMAN_GATHER_ALGOR_CONFIG_PARAM__
  256 +
  257 +
  258 +
  259 +// 施工占道参数结构体 221026byzsh
  260 +#ifndef ___ROAD_WORK_ALGOR_CONFIG_PARAM__
  261 +#define ___ROAD_WORK_ALGOR_CONFIG_PARAM__
  262 +typedef struct algor_config_param_road_work {
  263 + int frame_stride; //推送间隔(实际间隔 = frame_stride * 内部跳帧数)
  264 + int rblock_count_threshold; //报警阈值
  265 + algor_config_param_road_work()
  266 + : frame_stride(1), rblock_count_threshold(3) {}
  267 +} algor_config_param_road_work;
  268 +#endif // #ifndef ___ROAD_WORK_ALGOR_CONFIG_PARAM__
  269 +
  270 +
  271 +// 视频定时抓拍参数结构体 230220byzsh
  272 +#ifndef ___VIDEO_TIMING_SNAPSHOT_CONFIG_PARAM__
  273 +#define ___VIDEO_TIMING_SNAPSHOT_CONFIG_PARAM__
  274 +typedef struct algor_config_video_timing_snapshot {
  275 + int frame_stride; //推送间隔(实际间隔 = frame_stride * 内部跳帧数)
  276 + algor_config_video_timing_snapshot()
  277 + : frame_stride(150) {}
  278 +} algor_config_video_timing_snapshot;
  279 +#endif // #ifndef ___VIDEO_TIMING_SNAPSHOT_CONFIG_PARAM__
  280 +
  281 +
  282 +// 人员跌倒参数结构体
  283 +#ifndef ___PEDESTRIAN_FALL_ALGOR_CONFIG_PARAM__
  284 +#define ___PEDESTRIAN_FALL_ALGOR_CONFIG_PARAM__
  285 +typedef struct algor_config_param_pedestrian_fall {
  286 + float threshold;
  287 + int pedestrian_min_height, pedestrian_min_width, pedestrian_confidence_threshold;
  288 +
  289 + algor_config_param_pedestrian_fall()
  290 + : threshold(0.8), pedestrian_min_width(0), pedestrian_min_height(0),
  291 + pedestrian_confidence_threshold(0.0f) {}
  292 +} algor_config_param_pedestrian_fall;
  293 +#endif // #ifndef ___PEDESTRIAN_FALL_ALGOR_CONFIG_PARAM__
  294 +
  295 +
  296 +// 人员跌倒参数结构体
  297 +#ifndef ___PEDESTRIAN_FIGHT_ALGOR_CONFIG_PARAM__
  298 +#define ___PEDESTRIAN_FIGHT_ALGOR_CONFIG_PARAM__
  299 +typedef struct algor_config_param_pedestrian_fight {
  300 + float threshold;
  301 + float iou_threshold;
  302 + int pedestrian_min_height, pedestrian_min_width, pedestrian_confidence_threshold;
  303 +
  304 + algor_config_param_pedestrian_fight()
  305 + : threshold(0.8), iou_threshold(0.1), pedestrian_min_width(0), pedestrian_min_height(0),
  306 + pedestrian_confidence_threshold(0.0f) {}
  307 +} algor_config_param_pedestrian_fight;
  308 +#endif // #ifndef ___PEDESTRIAN_FIGHT_ALGOR_CONFIG_PARAM__
  309 +
  310 +
  311 +
  312 +// 外卖员识别参数结构体
  313 +#ifndef ___TAKEAWAY_MEMBER_CLASSIFICATION_ALGOR_CONFIG_PARAM__
  314 +#define ___TAKEAWAY_MEMBER_CLASSIFICATION_ALGOR_CONFIG_PARAM__
  315 +typedef struct algor_config_param_takeaway_member_classification {
  316 + int m, n;
  317 + float threshold;
  318 + int pedestrian_min_height, pedestrian_min_width, pedestrian_confidence_threshold;
  319 +
  320 + algor_config_param_takeaway_member_classification()
  321 + : m(10), n(8), threshold(0.7), pedestrian_min_width(0), pedestrian_min_height(0),
  322 + pedestrian_confidence_threshold(0.0f) {}
  323 +} algor_config_param_takeaway_member_classification;
  324 +#endif // #ifndef ___TAKEAWAY_MEMBER_CLASSIFICATION_ALGOR_CONFIG_PARAM__
  325 +
  326 +
  327 +
  328 +// 行人安全检测参数
  329 +#ifndef ___PEDESTRIAN_SAFETY_DETECTOR_ALGOR_CONFIG_PARAM__
  330 +#define ___PEDESTRIAN_SAFETY_DETECTOR_ALGOR_CONFIG_PARAM__
  331 +
  332 +typedef struct algor_config_param_pedestrian_safety_detector_basic {
  333 + unsigned m, n;
  334 + float conf_threshold;
  335 + float pedestrian_confidence_threshold;
  336 + unsigned pedestrian_min_height, pedestrian_min_width;
  337 +
  338 + algor_config_param_pedestrian_safety_detector_basic()
  339 + : m(10), n(8), conf_threshold(0.0f), pedestrian_min_width(0), pedestrian_min_height(0),
  340 + pedestrian_confidence_threshold(0.0f) {}
  341 +} algor_config_param_pedestrian_safety_detector_basic;
  342 +
  343 +
  344 +//! C style.
  345 +typedef algor_config_param_pedestrian_safety_detector_basic algor_config_param_smoking;
  346 +typedef algor_config_param_pedestrian_safety_detector_basic algor_config_param_call_phone;
  347 +typedef algor_config_param_pedestrian_safety_detector_basic algor_config_param_no_reflective_clothing;
  348 +typedef algor_config_param_pedestrian_safety_detector_basic algor_config_param_no_safety_helmet;
  349 +
  350 +// using algor_config_param_no_safety_helmet = algor_config_param_pedestrian_safety_detector_basic;
  351 +
  352 +#endif // #ifndef ___PEDESTRIAN_SAFETY_DETECTOR_ALGOR_CONFIG_PARAM__
  353 +
  354 +
  355 +
  356 +// 行人安全检测参数
  357 +#ifndef ___RETROGRADE_ALGOR_CONFIG_PARAM__
  358 +#define ___RETROGRADE_ALGOR_CONFIG_PARAM__
  359 +
  360 +typedef struct algor_config_param_retrograde_basic {
  361 + int direction;
  362 + float conf_threshold;
  363 + unsigned px1, py1, px2, py2;
  364 + unsigned minmum_height, minmum_width;
  365 +
  366 + algor_config_param_retrograde_basic()
  367 + : direction(0), px1(0), py1(0), px2(0), py2(0), conf_threshold(0.0f), minmum_height(0), minmum_width(0) {
  368 +
  369 + }
  370 +
  371 +} algor_config_param_retrograde_basic;
  372 +
  373 +
  374 +typedef algor_config_param_retrograde_basic algor_config_param_pedestrian_retrograde;
  375 +typedef algor_config_param_retrograde_basic algor_config_param_vehicle_retrograde;
  376 +
  377 +#endif // #ifndef ___RETROGRADE_ALGOR_CONFIG_PARAM__
  378 +
  379 +
  380 +// 行人安全检测参数
  381 +#ifndef ___TRESPASS_ALGOR_CONFIG_PARAM__
  382 +#define ___TRESPASS_ALGOR_CONFIG_PARAM__
  383 +#define TRESPASS_MAX_POINT 24
  384 +
  385 +typedef struct algor_config_param_trespass_basic {
  386 + float conf_threshold;
  387 + unsigned minmum_height, minmum_width;
  388 + sy_point points[TRESPASS_MAX_POINT];
  389 + int points_count;
  390 +
  391 + algor_config_param_trespass_basic()
  392 + : points_count(0), conf_threshold(0.0f), minmum_height(0), minmum_width(0) {
  393 + }
  394 +
  395 +} algor_config_param_trespass_basic;
  396 +
  397 +typedef algor_config_param_trespass_basic algor_config_param_pedestrian_trespass;
  398 +typedef algor_config_param_trespass_basic algor_config_param_vehicle_trespass;
  399 +
  400 +#endif // #ifndef ___RETROGRADE_ALGOR_CONFIG_PARAM__
  401 +
  402 +
  403 +// 抓拍算法配置参数(所有抓拍算法共享该参数)
  404 +#ifndef __SNAPSHOT_ALGOR_CONFIG_PARAM__
  405 +#define __SNAPSHOT_ALGOR_CONFIG_PARAM__
  406 +typedef struct algor_config_param_snapshot {
  407 + float threshold;
  408 + int snap_frame_interval;
  409 + algor_config_param_snapshot()
  410 + : threshold(.6f) , snap_frame_interval(0){}
  411 +} algor_config_param_snapshot;
  412 +#endif
  413 +
  414 +
  415 +
  416 +// 算法的初始化参数
  417 +#ifndef __ALGOR_CONFIG_PARAM__BASIC__
  418 +#define __ALGOR_CONFIG_PARAM__BASIC__
  419 +typedef struct algor_basic_config_param_t {
  420 + sy_rect algor_valid_rect;
  421 + char *result_folder_little; //目标快照抠图保存地址
  422 + char *result_folder; //目标快照大图保存地址
  423 + explicit algor_basic_config_param_t()
  424 + : result_folder_little(nullptr), result_folder(nullptr) {}
  425 +} algor_basic_config_param_t;
  426 +#endif // #ifndef __ALGOR_CONFIG_PARAM__BASIC__
  427 +
  428 +
  429 +
  430 +
  431 +//算法的初始化参数
  432 +#ifndef __ALGOR_CONFIG_PARAM__
  433 +#define __ALGOR_CONFIG_PARAM__
  434 +
  435 +typedef struct algor_init_config_param_t {
  436 + void *algor_param; //此处只传入针对该路的定制化参数
  437 + algor_basic_config_param_t *basic_param;
  438 +} algor_init_config_param_t;
  439 +
  440 +typedef struct algor_config_param {
  441 + algo_type algor_type; //算法类型()
  442 + algor_init_config_param_t *algor_init_config_param;
  443 +} algor_config_param;
  444 +#endif
  445 +
  446 +
  447 +// TASK初始化参数
  448 +#ifndef __TASK_PARAM__
  449 +#define __TASK_PARAM__
  450 +
  451 +typedef bool(*GB28181_REQUEST_STREAM_CALLBACK)(const char*);
  452 +
  453 +typedef struct task_param {
  454 + const char *ipc_url; //rtsp流地址
  455 + const char *task_id; //外部传入任务id
  456 + algor_config_param *algor_config_params; //该路rtsp流配置的所有算法参数
  457 + int algor_counts; //该路rtsp流共配置几种算法
  458 +
  459 + int dec_type{0}; // 0: ffmpeg 1: gb28181 2:dvpp
  460 + int port; // gb28181时port为必填
  461 + int protocal; // gb28181 数据接收协议 0 : udp 1: tcp
  462 + GB28181_REQUEST_STREAM_CALLBACK gb28181_request_stream_callback;
  463 +
  464 + int result_output_interval{0}; // 同一目标保存结果的帧间隔
  465 +} task_param;
  466 +#endif
  467 +
  468 +#ifndef __AI_LOG_LEVEL__
  469 +#define __AI_LOG_LEVEL__
  470 +enum ai_log_level {
  471 + AI_LOG_LEVEL_CLOSE = -1, // 关闭日志
  472 + AI_LOG_LEVEL_TRACE = 0, // 跟踪变量
  473 + AI_LOG_LEVEL_DEBUG = 1, // 调试日志
  474 + AI_LOG_LEVEL_INFO = 2, // 普通日志信息 (如:无关紧要的信息输出)
  475 + AI_LOG_LEVEL_WARNING = 3, // 警告日志通知,模块一切正常(如:重要流程通知)
  476 + AI_LOG_LEVEL_ERROR = 4, // 重要日志,如结果和严重错误
  477 +};
  478 +#endif
  479 +
  480 +
  481 +// #define POST_USE_RABBITMQ
  482 +
  483 +#ifdef POST_USE_RABBITMQ
  484 +/**
  485 + * @brief rabbit MQ params define here.
  486 + */
  487 +#ifndef __TSL_AIPLATFORM_RABBITMQ_PARAM__
  488 +#define __TSL_AIPLATFORM_RABBITMQ_PARAM__
  489 +
  490 +
  491 +enum class mq_type_t {
  492 + DEL_TASK_MQ = 0,
  493 + GET_TASK_MQ = 1,
  494 + HEART_BEAT_MQ = 2,
  495 + ALARM_MQ = 3,
  496 + SCREENSHORT_TASK_MQ = 4, // 220809 视频截图队列
  497 + TIMING_SCREENSHORT_TASK_MQ = 5, // 230809 定时视频截图队列
  498 + // DEL_TASK = 0,
  499 + // GET_TASK = 1,
  500 + // HEART_BEAT = 2,
  501 + // GET_ALARM = 3,
  502 +
  503 +
  504 +};
  505 +
  506 +
  507 +#if 1
  508 +#define MQ_MAX_CHAR_SIZE 256
  509 +typedef struct rabbitmq_conn_params_t {
  510 + int port;
  511 + // char *ip[12+3+1];
  512 + char ip[MQ_MAX_CHAR_SIZE];
  513 + char uname[MQ_MAX_CHAR_SIZE];
  514 + char passwd[MQ_MAX_CHAR_SIZE];
  515 + char vhost[MQ_MAX_CHAR_SIZE];
  516 +
  517 + char exchange[MQ_MAX_CHAR_SIZE];
  518 + char exchange_type[MQ_MAX_CHAR_SIZE];
  519 + char queue[MQ_MAX_CHAR_SIZE];
  520 + char routing_key[MQ_MAX_CHAR_SIZE];
  521 +
  522 + bool durable_exchange, durable_queue;
  523 +} rabbitmq_conn_params_t;
  524 +#else
  525 +
  526 +typedef struct rabbitmq_conn_params_t
  527 +{
  528 + int port;
  529 + // char *ip[12+3+1];
  530 + const char* ip;
  531 + const char* uname;
  532 + const char* passwd;
  533 + const char* vhost;
  534 +
  535 + const char* exchange;
  536 + const char* exchange_type;
  537 + const char* queue;
  538 + const char* routing_key;
  539 +
  540 + bool durable_exchange, durable_queue;
  541 +} rabbitmq_conn_params_t;
  542 +
  543 +#endif
  544 +
  545 +
  546 +#endif // #ifndef __TSL_AIPLATFORM_RABBITMQ_PARAM__
  547 +#endif //#ifdef POST_USE_RABBITMQ
  548 +
  549 +
  550 +//VPT初始化参数
  551 +#ifndef __TSL_AIPLATFORM_PARAM__
  552 +#define __TSL_AIPLATFORM_PARAM__
  553 +typedef struct tsl_aiplatform_param {
  554 + int gpuid; //指定显卡id
  555 + char *trt_serialize_file; //缓存文件保存路径
  556 +
  557 + ai_log_level log_level;
  558 + char *log_path; //日志文件路径
  559 + int log_days; //日志保存周期
  560 + double log_mem; //每个日志最大大小
  561 + float vpt_thred = 0.45; //一级检测器阈值 221216add
  562 + float rblock_thred = 0.4; //安全锥检测阈值 221216add
  563 + /********************************************************************/
  564 +} tsl_aiplatform_param;
  565 +#endif
  566 +
  567 +
  568 +#ifndef _MSC_VER
  569 +
  570 +#include <sys/time.h>
  571 +
  572 +#define MACRO_COUNT_TIME_START struct timeval macro_tv_start;\
  573 + struct timeval macro_tv_end;\
  574 + gettimeofday(&macro_tv_start,NULL);
  575 +
  576 +#define MACRO_COUNT_TIME_END(___total_count___) gettimeofday(&macro_tv_end,NULL);\
  577 + if(___total_count___<=0)\
  578 + printf("time cost: %.2f ms \n", ( (double)(macro_tv_end.tv_sec-macro_tv_start.tv_sec)*1000000+(double)(macro_tv_end.tv_usec-macro_tv_start.tv_usec) )/1000);\
  579 + else\
  580 + printf("time cost: %.2f ms \n", ( (double)(macro_tv_end.tv_sec-macro_tv_start.tv_sec)*1000000+(double)(macro_tv_end.tv_usec-macro_tv_start.tv_usec) )/1000/___total_count___);
  581 +#endif
0 \ No newline at end of file 582 \ No newline at end of file
src/ai_platform/macro_definition.h 0 → 100644
  1 +#ifndef __MACRO_DEFINITION_H__
  2 +#define __MACRO_DEFINITION_H__
  3 +
  4 +
  5 +#define ACL_CALL(ret, expect, errCode)\
  6 + do {\
  7 + if (ret != expect) {\
  8 + if (errCode == 0)\
  9 + return ret;\
  10 + else\
  11 + return errCode;\
  12 + }\
  13 + } while(0)
  14 +
  15 +#endif
0 \ No newline at end of file 16 \ No newline at end of file
src/ai_platform/mvpt_process_assist.cpp 0 → 100644
  1 +#include "mvpt_process_assist.h"
  2 +#include "../common/logger.hpp"
  3 +
  4 +
  5 +//******** 判断位置是否合法函数 **********//
  6 +// 目的:剔除掉靠近摄像头时,面积最大,但是检测物体已经不完整的情况
  7 +// 1. 设定阈值,靠近边缘不要了(阈值目前设定为自身宽高的20%)
  8 +//bool sy_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int img_height, int img_width)
  9 +//{
  10 +// int pos[4] = { left, top, right, bottom };
  11 +// int edges[4] = { 0, 0, img_width, img_height };
  12 +//
  13 +// for (int i = 0; i < EDGESIZE; i++)
  14 +// {
  15 +// if (flags[i]) //是需要判断的边
  16 +// {
  17 +// if (abs(pos[i] - edges[i]) < minDistance[i])
  18 +// return false;
  19 +// }
  20 +// }
  21 +// return true;
  22 +//}
  23 +
  24 +bool LegalMinArea(int width, int height, sy_rect min_box)
  25 +{
  26 + return (width >= min_box.width_ && height >= min_box.height_);
  27 +}
  28 +
  29 +//******** 判断面积是否合法函数 **********//
  30 +// 目的:选取框最大最完整的那帧
  31 +// 1. 比之前面积小的不要
  32 +// 2. 突变的面积不要
  33 +bool LegalArea(int maxArea, int lastArea, int left, int top, int right, int bottom)
  34 +{
  35 + //不需要通过MINBOX来判断,直接返回true
  36 +
  37 + int newArea = (bottom - top)*(right - left);
  38 +
  39 + if (lastArea == 0)
  40 + return true;
  41 +
  42 + if (newArea < maxArea)
  43 + return false;
  44 +
  45 + else if ((newArea - lastArea) / lastArea > 0.5) //阈值测试之后再确定,看是否需要分种类来确定不同的阈值
  46 + return false;
  47 + else return true;
  48 +}
  49 +
  50 +
  51 +//******** 辅助函数:根据目标运动的轨迹,判断需要特别外扩的方向 **********//
  52 +// 目的:因为跳帧的存在,目标运动较快时,框会有一定的滞后的情况(车向前运动,车头被裁掉的情况尤其明显),框滞后的方向需要额外外扩
  53 +void ExpandMargin(int direction_x, int direction_y, int boundary_w, int boundary_h,
  54 + int &boundary_left, int &boundary_right, int &boundary_top, int &boundary_bottom)
  55 +{
  56 + if (abs(direction_x) > abs(direction_y))
  57 + {
  58 + if (direction_x > 0)
  59 + {
  60 + boundary_right = 2.5 * boundary_w;
  61 + }
  62 + else
  63 + {
  64 + boundary_left = 2.5 * boundary_w;
  65 + }
  66 + }
  67 + else
  68 + {
  69 + if (direction_y > 0)
  70 + {
  71 + boundary_bottom = 2.5 * boundary_h;
  72 + }
  73 + else
  74 + {
  75 + boundary_top = 2.5 * boundary_h;
  76 + }
  77 + }
  78 + /*int max_dis = max(max(max(dis_left, dis_right), dis_top), dis_bottom);
  79 +
  80 + if (max_dis == dis_left)
  81 + boundary_left = 3 * boundary_w;
  82 + else if (max_dis == dis_right)
  83 + boundary_right = 3 * boundary_w;
  84 + else if (max_dis == dis_top)
  85 + boundary_top = 3 * boundary_h;
  86 + else
  87 + boundary_bottom = 3 * boundary_h;*/
  88 +}
  89 +
  90 +int CreateDir(char *pszDir)
  91 +{
  92 + int i = 0;
  93 + int iRet;
  94 + int iLen = strlen(pszDir);
  95 + if (pszDir[iLen - 1] != '\\' && pszDir[iLen - 1] != '/')
  96 + {
  97 + pszDir[iLen] = '/';
  98 + pszDir[iLen + 1] = '\0';
  99 + }
  100 + iLen = strlen(pszDir);
  101 +
  102 + if (iLen > 2 && ((pszDir[i] == '\\' && pszDir[i + 1] == '\\') || (pszDir[i] == '/' && pszDir[i + 1] == '/')))
  103 + {
  104 + i = 2;
  105 + for (; i <= iLen; i++)
  106 + if (pszDir[i] == '\\' || pszDir[i] == '/')
  107 + break;
  108 +
  109 + i++;
  110 +
  111 + for (; i <= iLen; i++)
  112 + {
  113 + if (pszDir[i] == '\\' || pszDir[i] == '/')
  114 + {
  115 + pszDir[i] = '\0';
  116 + //printf("file access %s\n", pszDir);
  117 + iRet = ACCESS(pszDir, 0);
  118 + //printf("file access %d\n", iRet);
  119 + if (iRet != 0)
  120 + {
  121 + //printf("file mkdir %s\n", pszDir);
  122 + iRet = MKDIR(pszDir);
  123 + //printf("file mkdir %d\n", iRet);
  124 + if (iRet != 0)
  125 + {
  126 + LOG_ERROR("Create Folder Failed!");
  127 + return -1;
  128 + }
  129 + }
  130 + pszDir[i] = '/';
  131 +
  132 + }
  133 + }
  134 + return 0;
  135 + }
  136 +
  137 + if (pszDir[i] != '\\' && pszDir[i] != '/')
  138 + i = 0;
  139 + else
  140 + i = 1;
  141 + for (; i <= iLen; i++)
  142 + {
  143 + if (pszDir[i] == '\\' || pszDir[i] == '/')
  144 + {
  145 + pszDir[i] = '\0';
  146 + iRet = ACCESS(pszDir, 0);
  147 + if (iRet != 0)
  148 + {
  149 + iRet = MKDIR(pszDir);
  150 + if (iRet != 0)
  151 + {
  152 + return -1;
  153 + }
  154 + }
  155 + pszDir[i] = '/';
  156 +
  157 + }
  158 + }
  159 + return 0;
  160 +}
  161 +
  162 +
  163 +void CreateResultFolder(char* resultFolder, const char* jointFolder)
  164 +{
  165 + if (strlen(resultFolder) > 240) //?too long
  166 + {
  167 + LOG_ERROR("Folder Name is too Long!");
  168 + return;
  169 + }
  170 + else if (strlen(resultFolder) < 1) //?too short
  171 + {
  172 + LOG_ERROR("Folder Name is too Short!");
  173 + return;
  174 + }
  175 +
  176 + char dir[260];
  177 +
  178 + sprintf(dir, "%s%s/", resultFolder, jointFolder);
  179 + if (CreateDir(dir) != 0)
  180 + {
  181 + LOG_ERROR("Create Folder Failed!");
  182 + return;
  183 + }
  184 +}
  185 +
  186 +
  187 +bool best_snapshot_judge_algor(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height)
  188 +{
  189 + return snapshot_legal_pos(obj_value.flags, left, top, left + width, top + height, image_width, image_height)
  190 + && snapshot_legal_minarea(obj_value.index.index, width, height)
  191 + && snapshot_legal_inarea(width, height)
  192 + && snapshot_legal_area(obj_value.max_area, obj_value.last_area, left, top, left + width, top + height);
  193 + return true;
  194 +}
  195 +
  196 +bool snapshot_judge_algor(int index, int width, int height)
  197 +{
  198 + return snapshot_legal_minarea(index, width, height) //判断最小面积
  199 + && snapshot_legal_inarea(width, height); //判断在有效区域
  200 + //&& snapshot_algor_open_config(obj_key); //判断算法开启,调整不用在此处判断,检测出来会进行过滤
  201 +}
  202 +
  203 +bool snapshot_legal_minarea(int index, int width, int height)
  204 +{
  205 + return (width >= m_boxsize[index].width_ && height >= m_boxsize[index].height_);
  206 +}
  207 +
  208 +bool snapshot_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int image_width, int image_height)
  209 +{
  210 + int pos[4] = { left, top, right, bottom };
  211 + int edges[4] = { 0, 0, image_width, image_height };
  212 +
  213 + for (int i = 0; i < EDGESIZE; i++)
  214 + {
  215 + if (flags[i]) //是需要判断的边
  216 + {
  217 + if (abs(pos[i] - edges[i]) < minDistance[i])
  218 + return false;
  219 + }
  220 + }
  221 + return true;
  222 +}
  223 +
  224 +//******** 判断面积是否合法函数 **********//
  225 +// 目的:选取框最大最完整的那帧
  226 +// 1. 比之前面积小的不要
  227 +// 2. 突变的面积不要
  228 +bool snapshot_legal_area(int max_area, int last_area, int left, int top, int right, int bottom)
  229 +{
  230 + //不需要通过MINBOX来判断,直接返回true
  231 + int new_area = (bottom - top)*(right - left);
  232 + if (last_area == 0)
  233 + return true;
  234 +
  235 + if (new_area < max_area)
  236 + return false;
  237 + // else if ((new_area - last_area) / last_area > 0.5) //阈值测试之后再确定,看是否需要分种类来确定不同的阈值
  238 + else if ((new_area - max_area) / max_area > 0.5) //阈值测试之后再确定,看是否需要分种类来确定不同的阈值 modified by zsh
  239 + return false;
  240 + else return true;
  241 +}
  242 +
  243 +bool snapshot_legal_inarea(sy_rect algor_area, int left, int top, int right, int bottom)
  244 +{
  245 + if (left < algor_area.left_ || top < algor_area.top_ || right>(algor_area.left_ + algor_area.width_) || bottom >(algor_area.top_ + algor_area.height_))
  246 + return false;
  247 +
  248 + return true;
  249 +}
  250 +
  251 +bool snapshot_legal_inarea(int width, int height)
  252 +{
  253 + return true;
  254 +}
  255 +
  256 +// added by zsh 220719 判断人脸姿态角是否满足要求
  257 +float convert_score(float attitude_angle) {
  258 + if(fabs(attitude_angle) > 30) // 超过设置角度则过滤---暂未用到
  259 + return 180;
  260 + else
  261 + return fabs(attitude_angle);
  262 +}
  263 +
  264 +bool snapshot_legal_pose(float last_roll, float last_yaw, float last_pitch, float roll, float yaw, float pitch)
  265 +{
  266 + if(fabs(roll) > 30 || fabs(yaw) > 30 || fabs(pitch) > 30)
  267 + return false;
  268 + float last_score = convert_score(last_roll) + convert_score(last_yaw) + convert_score(last_pitch);
  269 + float cur_score = convert_score(roll) + convert_score(yaw) + convert_score(pitch);
  270 + if(last_score > cur_score)
  271 + return false;
  272 + return true;
  273 +}
0 \ No newline at end of file 274 \ No newline at end of file
src/ai_platform/mvpt_process_assist.h 0 → 100644
  1 +#ifndef __MVPT_PROCESS_ASSIST_H__
  2 +#define __MVPT_PROCESS_ASSIST_H__
  3 +
  4 +#include <bitset>
  5 +#include "sy_common.h"
  6 +#include "det_obj_header.h"
  7 +#include <stdio.h>
  8 +
  9 +
  10 +#ifdef _MSC_VER
  11 +#include <direct.h>
  12 +#include <io.h>
  13 +#define ACCESS _access
  14 +#define MKDIR(a) _mkdir((a))
  15 +#else
  16 +#include <unistd.h>
  17 +#include <stdarg.h>
  18 +#include <sys/stat.h>
  19 +#define ACCESS access
  20 +#define MKDIR(a) mkdir((a),0755)
  21 +#endif
  22 +
  23 +using namespace std;
  24 +
  25 +typedef struct DxGPUFrame
  26 +{
  27 + void * frame;
  28 + unsigned int size;
  29 + unsigned int width;
  30 + unsigned int height;
  31 + unsigned long long timestamp;
  32 +}DxGPUFrame;
  33 +
  34 +struct OBJ_VALUE {
  35 + bool finishTracker; //轨迹结束可以保存了
  36 + int frameCount;
  37 + bool isupdate;
  38 + int lost;
  39 + DxGPUFrame snapShot;
  40 + DxGPUFrame snapShotLittle;
  41 + sy_rect obj_pos;
  42 + double confidence; // 置信度
  43 + float last_area;
  44 + float max_area;
  45 + OBJ_INDEX index;
  46 +
  47 + bitset< EDGESIZE > flags; //标志位,标记快照框应该如何判断,left:0 top:1 right:2 bottom:3
  48 + sy_point landmark_point[25];//人脸关键点位置信息
  49 + sy_rect position; //检测实际目标框
  50 + //-added by zsh 220719 人脸姿态角-
  51 + float roll = 0.0;
  52 + float yaw = 0.0;
  53 + float pitch = 0.0;
  54 + //-------------------------------
  55 +
  56 +};
  57 +
  58 +
  59 +int CreateDir(char *pszDir);
  60 +void CreateResultFolder(char* resultFolder, const char* jointFolder);
  61 +//bool sy_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int imgHeight, int imgWidth);
  62 +bool LegalArea(int maxArea, int lastArea, int left, int top, int right, int bottom);
  63 +bool LegalMinArea(int width, int height, sy_rect min_box);
  64 +void ExpandMargin(int direction_x, int direction_y, int boundary_w, int boundary_h,
  65 + int &boundary_left, int &boundary_right, int &boundary_top, int &boundary_bottom);
  66 +void CreateResultFolder(char* resultFolder, const char* jointFolder);
  67 +
  68 +bool snapshot_legal_inarea(int width, int height);
  69 +bool snapshot_legal_inarea(sy_rect algor_area, int left, int top, int right, int bottom);
  70 +bool snapshot_legal_minarea(int index, int width, int height);
  71 +bool snapshot_algor_open_config(const OBJ_KEY& obj_key);
  72 +bool snapshot_legal_pos(bitset<EDGESIZE> flags, int left, int top, int right, int bottom, int image_width, int image_height);
  73 +bool snapshot_legal_area(int max_area, int last_area, int left, int top, int right, int bottom);
  74 +bool snapshot_legal_pose(float last_roll, float last_yaw, float last_pitch, float roll, float yaw, float pitch); // added by zsh 220719 判断人脸姿态角
  75 +
  76 +
  77 +
  78 +#endif // __MVPT_PROCESS_ASSIST_H__
0 \ No newline at end of file 79 \ No newline at end of file
src/ai_platform/stl_aiplatform.cpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-15 17:59:50
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#include "stl_aiplatform.h"
  9 +#include "MultiSourceProcess.h"
  10 +#include "ErrorInfo.h"
  11 +
  12 +
  13 +int tsl_aiplatform_init(void **handle, tsl_aiplatform_param param)
  14 +{
  15 + *handle = new CMultiSourceProcess();
  16 + CMultiSourceProcess* tools = (CMultiSourceProcess*)*handle;
  17 + return tools->InitAlgorthim(param);
  18 +}
  19 +
  20 +
  21 +#ifdef POST_USE_RABBITMQ
  22 +int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_param)
  23 +{
  24 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  25 + return tools->AddMqConn(tstatus, mq_conn_param);
  26 +}
  27 +
  28 +int get_task_status(void *handle, char *task_id)
  29 +{
  30 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  31 + return tools->GetTaskStatus(task_id);
  32 +}
  33 +
  34 +#endif
  35 +
  36 +int add_task(void *handle, task_param param)
  37 +{
  38 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  39 + int error_code = FAILED;
  40 + if (tools->AddTask(param)){
  41 + error_code = SUCCESS;
  42 + }
  43 + return error_code;
  44 +}
  45 +
  46 +
  47 +int pause_task(void *handle, char * task_id, const int max_timeout_ms)
  48 +{
  49 + int error_code = FAILED;
  50 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  51 + if (tools->PauseTask(task_id)){
  52 + error_code = SUCCESS;
  53 + }
  54 + return error_code;
  55 +}
  56 +
  57 +
  58 +int restart_task(void *handle, char * task_id, const int max_timeout_ms)
  59 +{
  60 + int error_code = FAILED;
  61 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  62 + if (tools->RestartTask(task_id)){
  63 + error_code = SUCCESS;
  64 + }
  65 + return error_code;
  66 +}
  67 +
  68 +int finish_task(void *handle, char * task_id, const int max_timeout_ms)
  69 +{
  70 + int error_code = FAILED;
  71 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  72 + if (tools->FinishTask(task_id)){
  73 + error_code = SUCCESS;
  74 + }
  75 + return error_code;
  76 +}
  77 +
  78 +// added by zsh 220801
  79 +int screenshot_task(void *handle, task_param param)
  80 +{
  81 + CMultiSourceProcess* tools = (CMultiSourceProcess*)handle;
  82 + return tools->SnapShot(param);
  83 +}
  84 +
  85 +int tsl_aiplatform_release(void **handle)
  86 +{
  87 + if (*handle)
  88 + {
  89 + CMultiSourceProcess* tools = (CMultiSourceProcess*)*handle;
  90 + tools->CloseAllTask();
  91 +
  92 + delete tools;
  93 + tools = NULL;
  94 + }
  95 + return SUCCESS;
  96 +}
  97 +
  98 +
  99 +const char* get_tsl_aiplatform_version()
  100 +{
  101 + return "sy_stl_aiplatform_version:0.0.0.221202.gpu.x64";
  102 +}
0 \ No newline at end of file 103 \ No newline at end of file
src/ai_platform/stl_aiplatform.h 0 → 100644
  1 +/*******************************************************************************************
  2 +* Version: tsl_aipaltform_v0.0.0
  3 +* CopyRight:中科视语(北京)科技有限公司
  4 +* UpdateDate: 20210918
  5 +* Content: 特斯联-AI视频智能SAAS平台
  6 +********************************************************************************************/
  7 +
  8 +#ifndef TSL_AIPLATFORM_H_
  9 +#define TSL_AIPLATFORM_H_
  10 +#ifdef _MSC_VER
  11 +#ifdef TSL_AIPLATFORM_EXPORTS
  12 +#define TSL_AIPLATFORM_API __declspec(dllexport)
  13 +#else
  14 +#define TSL_AIPLATFORM_API __declspec(dllimport)
  15 +#endif
  16 +#else
  17 +#define TSL_AIPLATFORM_API __attribute__ ((visibility ("default")))
  18 +#endif
  19 +#include "header.h"
  20 +
  21 +
  22 +extern "C"
  23 +{
  24 + /*************************************************************************
  25 + * FUNCTION: tsl_aiplatform_init
  26 + * PURPOSE: 初始化
  27 + * PARAM:
  28 + [out] handle - 句柄
  29 + [in] param - 初始化参数
  30 + * RETURN:
  31 + * NOTES:
  32 + *************************************************************************/
  33 + TSL_AIPLATFORM_API int tsl_aiplatform_init(void **handle, tsl_aiplatform_param param);
  34 +
  35 +#ifdef POST_USE_RABBITMQ
  36 + /**
  37 + * @brief add new rabbitmq connection
  38 + *
  39 + * @param handle
  40 + * @param tstatus
  41 + * @param mq_conn_param
  42 + * @return TSL_AIPLATFORM_API
  43 + */
  44 + TSL_AIPLATFORM_API int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_param);
  45 +
  46 +
  47 +
  48 + TSL_AIPLATFORM_API int get_task_status(void *handle, char *task_id);
  49 +
  50 +#endif
  51 +
  52 + /*************************************************************************
  53 + * FUNCTION: add_task
  54 + * PURPOSE: 添加任务
  55 + * PARAM:
  56 + [in] handle - 句柄
  57 + [in] param - 添加任务初始化参数
  58 + * RETURN: 成功/失败
  59 + * NOTES:
  60 + *************************************************************************/
  61 + TSL_AIPLATFORM_API int add_task(void *handle, task_param param);
  62 +
  63 +
  64 + /*************************************************************************
  65 + * FUNCTION: pause_task
  66 + * PURPOSE: 暂停任务
  67 + * PARAM:
  68 + [in] handle - 句柄
  69 + [in] task_id - 暂停任务ID号
  70 + * RETURN:
  71 + * NOTES:
  72 + *************************************************************************/
  73 + TSL_AIPLATFORM_API int pause_task(void *handle, char * task_id, const int max_timeout_ms);
  74 +
  75 +
  76 + /*************************************************************************
  77 + * FUNCTION: restart_task
  78 + * PURPOSE: 重启任务
  79 + * PARAM:
  80 + [in] handle - 句柄
  81 + [in] task_id - 重启任务ID号
  82 + * RETURN:
  83 + * NOTES:
  84 + *************************************************************************/
  85 + TSL_AIPLATFORM_API int restart_task(void *handle, char * task_id, const int max_timeout_ms);
  86 +
  87 +
  88 + /*************************************************************************
  89 + * FUNCTION: finish_task
  90 + * PURPOSE: 结束任务
  91 + * PARAM:
  92 + [in] handle - 句柄
  93 + [in] task_id - 结束任务ID号
  94 + * RETURN:
  95 + * NOTES:
  96 + *************************************************************************/
  97 + TSL_AIPLATFORM_API int finish_task(void *handle, char * task_id, const int max_timeout_ms);
  98 +
  99 +
  100 + /*************************************************************************
  101 + * FUNCTION: screenshot_task --added by zsh 220801
  102 + * PURPOSE: 视频截图-截取视频首帧
  103 + * PARAM:
  104 + [in] handle - 句柄
  105 + [in] param - 添加任务初始化参数
  106 + * RETURN: 成功/失败
  107 + * NOTES:
  108 + *************************************************************************/
  109 + TSL_AIPLATFORM_API int screenshot_task(void *handle, task_param param);
  110 +
  111 +
  112 + /*************************************************************************
  113 + * FUNCTION: tsl_aiplatform_release
  114 + * PURPOSE: 资源释放
  115 + * PARAM:
  116 + [in] handle - 处理句柄
  117 + * RETURN:
  118 + * NOTES:
  119 + *************************************************************************/
  120 + TSL_AIPLATFORM_API int tsl_aiplatform_release(void **handle);
  121 +
  122 +
  123 + /*************************************************************************
  124 + * FUNCTION: get_tsl_aiplatform_version
  125 + * PURPOSE: 获取SDK版本号
  126 + * PARAM:
  127 + * RETURN: sdk版本号
  128 + * NOTES:
  129 + *************************************************************************/
  130 + TSL_AIPLATFORM_API const char* get_tsl_aiplatform_version();
  131 +}
  132 +#endif
src/ai_platform/task_param_manager.cpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-08 17:45:57
  4 + * @Last Modified by: yangzilong
  5 + * @Last Modified time: Do not edit
  6 + * @Email: yangzilong@objecteye.com
  7 + * @Description:
  8 + */
  9 +
  10 +#include "task_param_manager.h"
  11 +#include "header.h"
  12 +#include "mvpt_process_assist.h"
  13 +
  14 +#include "../common/logger.hpp"
  15 +
  16 +// ############################################################ //
  17 +// ! Auxiliary Function ! //
  18 +// ############################################################ //
  19 +
  20 +/* 任务配置参数的深拷贝 添加新算法 添加新case拷贝后续需要的参数 */
  21 +bool copy_algor_param_aux(const algorithm_type_t &algor_type, const std::string &task_id,
  22 + task_param_manager::algo_param_type_t_ *&copied_algor_param, void *&algor_param,
  23 + map<string, algor_open_config_param> &m_algor_config_params) {
  24 + //! Check.
  25 + if (!copied_algor_param || !algor_param)
  26 + return false;
  27 +
  28 + switch (algor_type) {
  29 + case algorithm_type_t::FACE_SNAPSHOT:
  30 + m_algor_config_params[task_id].human_face_algors.insert(algor_type);
  31 + goto _snapshot_param_copy;
  32 + case algorithm_type_t::HUMAN_SNAPSHOT:
  33 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  34 + goto _snapshot_param_copy;
  35 + case algorithm_type_t::VEHICLE_SNAPSHOT:
  36 + m_algor_config_params[task_id].vehicle_algors.insert(algor_type);
  37 + goto _snapshot_param_copy;
  38 + case algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT: {
  39 + m_algor_config_params[task_id].nonmotor_vehicle_algors.insert(algor_type);
  40 + _snapshot_param_copy : {
  41 + using algor_config_param_type = algor_config_param_snapshot;
  42 + copied_algor_param->algor_param = new algor_config_param_type;
  43 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  44 + *((algor_config_param_type *)algor_param); // deep copy.
  45 + }
  46 + } break;
  47 +
  48 + case algorithm_type_t::HUMAN_GATHER: {
  49 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  50 + using algor_config_param_type = algor_config_param_human_gather;
  51 + copied_algor_param->algor_param = new algor_config_param_type;
  52 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  53 + *((algor_config_param_type *)algor_param); // deep copy.
  54 + } break;
  55 +
  56 +
  57 + //221026byzsh---------------------------------------------------------
  58 + case algorithm_type_t::ROAD_WORK_DET: {
  59 + m_algor_config_params[task_id].vehicle_algors.insert(algor_type);
  60 + using algor_config_param_type = algor_config_param_road_work;
  61 + copied_algor_param->algor_param = new algor_config_param_type;
  62 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  63 + *((algor_config_param_type *)algor_param); // deep copy.
  64 + } break;
  65 + //--------------------------------------------------------------------
  66 +
  67 + //230220byzsh---------------------------------------------------------
  68 + case algorithm_type_t::VIDEO_TIMING_SNAPSHOT: {
  69 + m_algor_config_params[task_id].vehicle_algors.insert(algor_type);
  70 + using algor_config_param_type = algor_config_video_timing_snapshot;
  71 + copied_algor_param->algor_param = new algor_config_param_type;
  72 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  73 + *((algor_config_param_type *)algor_param); // deep copy.
  74 + } break;
  75 + //--------------------------------------------------------------------
  76 +
  77 + case algorithm_type_t::PEDESTRIAN_FALL: {
  78 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  79 + using algor_config_param_type = algor_config_param_pedestrian_fall;
  80 + copied_algor_param->algor_param = new algor_config_param_type;
  81 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  82 + *((algor_config_param_type *)algor_param); // deep copy.
  83 + } break;
  84 +
  85 + case algorithm_type_t::PEDESTRIAN_FIGHT: {
  86 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  87 + using algor_config_param_type = algor_config_param_pedestrian_fight;
  88 + copied_algor_param->algor_param = new algor_config_param_type;
  89 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  90 + *((algor_config_param_type *)algor_param); // deep copy.
  91 + } break;
  92 +
  93 + case algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION: {
  94 + m_algor_config_params[task_id].nonmotor_vehicle_algors.insert(algor_type);
  95 + using algor_config_param_type = algor_config_param_takeaway_member_classification;
  96 + copied_algor_param->algor_param = new algor_config_param_type;
  97 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  98 + *((algor_config_param_type *)algor_param); // deep copy.
  99 + } break;
  100 +
  101 + case algorithm_type_t::SMOKING_DET: {
  102 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  103 + using algor_config_param_type = algor_config_param_smoking;
  104 + copied_algor_param->algor_param = new algor_config_param_type;
  105 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  106 + *((algor_config_param_type *)algor_param); // deep copy.
  107 + } break;
  108 +
  109 + case algorithm_type_t::CALL_PHONE_DET: {
  110 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  111 + using algor_config_param_type = algor_config_param_call_phone;
  112 + copied_algor_param->algor_param = new algor_config_param_type;
  113 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  114 + *((algor_config_param_type *)algor_param); // deep copy.
  115 + } break;
  116 +
  117 + case algorithm_type_t::NO_REFLECTIVE_CLOTHING: {
  118 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  119 + using algor_config_param_type = algor_config_param_no_reflective_clothing;
  120 + copied_algor_param->algor_param = new algor_config_param_type;
  121 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  122 + *((algor_config_param_type *)algor_param); // deep copy.
  123 + } break;
  124 +
  125 + case algorithm_type_t::NO_SAFETY_HELMET: {
  126 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  127 + using algor_config_param_type = algor_config_param_no_safety_helmet;
  128 + copied_algor_param->algor_param = new algor_config_param_type;
  129 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  130 + *((algor_config_param_type *)algor_param); // deep copy.
  131 + } break;
  132 +
  133 + case algorithm_type_t::PEDESTRIAN_RETROGRADE: {
  134 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  135 + using algor_config_param_type = algor_config_param_pedestrian_retrograde;
  136 + copied_algor_param->algor_param = new algor_config_param_type;
  137 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  138 + *((algor_config_param_type *)algor_param); // deep copy.
  139 + } break;
  140 +
  141 + case algorithm_type_t::VEHICLE_RETROGRADE: {
  142 + m_algor_config_params[task_id].vehicle_algors.insert(algor_type);
  143 + using algor_config_param_type = algor_config_param_vehicle_retrograde;
  144 + copied_algor_param->algor_param = new algor_config_param_type;
  145 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  146 + *((algor_config_param_type *)algor_param); // deep copy.
  147 + } break;
  148 +
  149 + case algorithm_type_t::PEDESTRIAN_TRESPASS: {
  150 + m_algor_config_params[task_id].human_algors.insert(algor_type);
  151 + using algor_config_param_type = algor_config_param_pedestrian_trespass;
  152 + copied_algor_param->algor_param = new algor_config_param_type;
  153 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  154 + *((algor_config_param_type *)algor_param); // deep copy.
  155 + } break;
  156 +
  157 + case algorithm_type_t::VEHICLE_TRESPASS: {
  158 + m_algor_config_params[task_id].vehicle_algors.insert(algor_type);
  159 + using algor_config_param_type = algor_config_param_vehicle_trespass;
  160 + copied_algor_param->algor_param = new algor_config_param_type;
  161 + *((algor_config_param_type *)(copied_algor_param->algor_param)) =
  162 + *((algor_config_param_type *)algor_param); // deep copy.
  163 + } break;
  164 +
  165 + default: {
  166 + LOG_WARN("Not Support Algorithm type {} Task id {}", int(algor_type), task_id);
  167 + return false;
  168 + } break;
  169 + }
  170 +
  171 + return true;
  172 +}
  173 +
  174 +task_param_manager::task_param_manager() {
  175 +}
  176 +
  177 +/* 保存新添加任务的配置参数 */
  178 +void task_param_manager::add_task_param(string task_id, task_param task_param) {
  179 + const int task_algor_count = task_param.algor_counts;
  180 + printf("task_algor_count: %d\n", task_algor_count);
  181 + for (int idx = 0; idx < task_algor_count; idx++) // loop every algor param.
  182 + {
  183 + algo_param_type_t_ *copied_algor_param = new algo_param_type_t_;
  184 + auto &algor_config_param = task_param.algor_config_params[idx];
  185 + auto &algor_param = algor_config_param.algor_init_config_param->algor_param;
  186 + auto &algor_type = algor_config_param.algor_type;
  187 +
  188 + /* 拷贝该算法特定的算法参数 */
  189 + if (!copy_algor_param_aux(algor_type, task_id, copied_algor_param, algor_param, m_algor_config_params)) {
  190 + if (copied_algor_param != nullptr) {
  191 + delete copied_algor_param;
  192 + copied_algor_param = nullptr;
  193 + }
  194 + LOG_ERROR("copy param faileure task_id {} algor_type {}", task_id, int(algor_type));
  195 + continue;
  196 + }
  197 +
  198 + /* 拷贝通用的算法参数 */
  199 + /* copy public param. */
  200 + copied_algor_param->basic_param = new algor_basic_config_param_t;
  201 +
  202 + auto src_basic_param = algor_config_param.algor_init_config_param->basic_param;
  203 + auto dst_basic_param = ((algor_init_config_param_t *)copied_algor_param)->basic_param;
  204 +
  205 + if (src_basic_param->result_folder_little) {
  206 + dst_basic_param->result_folder_little = new char[strlen(src_basic_param->result_folder_little) + 1];
  207 + strcpy(dst_basic_param->result_folder_little, src_basic_param->result_folder_little);
  208 + CreateResultFolder(dst_basic_param->result_folder_little, "");
  209 + } else
  210 + dst_basic_param->result_folder_little = nullptr;
  211 +
  212 + if (src_basic_param->result_folder) {
  213 + dst_basic_param->result_folder = new char[strlen(src_basic_param->result_folder) + 1];
  214 + strcpy(dst_basic_param->result_folder, src_basic_param->result_folder);
  215 + CreateResultFolder(dst_basic_param->result_folder, "");
  216 + } else
  217 + dst_basic_param->result_folder = nullptr;
  218 +
  219 + dst_basic_param->algor_valid_rect.left_ = src_basic_param->algor_valid_rect.left_;
  220 + dst_basic_param->algor_valid_rect.top_ = src_basic_param->algor_valid_rect.top_;
  221 + dst_basic_param->algor_valid_rect.width_ = src_basic_param->algor_valid_rect.width_;
  222 + dst_basic_param->algor_valid_rect.height_ = src_basic_param->algor_valid_rect.height_;
  223 +
  224 + copied_algor_param->basic_param = dst_basic_param;
  225 + m_task_params[task_id][algor_config_param.algor_type] = copied_algor_param;
  226 + }
  227 +}
  228 +
  229 +/* 删除结束任务的配置参数 */
  230 +void task_param_manager::delete_task_param(string task_id) {
  231 + auto it = m_task_params.find(task_id);
  232 + if(it == m_task_params.end()){
  233 + return;
  234 + }
  235 +
  236 + for (auto iter : m_task_params[task_id]) // 依次删除算法配置参数
  237 + {
  238 + algor_basic_config_param_t *cur_param =
  239 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->basic_param;
  240 + if (cur_param->result_folder_little) {
  241 + delete[] cur_param->result_folder_little;
  242 + cur_param->result_folder_little = nullptr;
  243 + }
  244 + if (cur_param->result_folder) {
  245 + delete[] cur_param->result_folder;
  246 + cur_param->result_folder = nullptr;
  247 + }
  248 + if (cur_param) {
  249 + delete ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->basic_param;
  250 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->basic_param = nullptr;
  251 + }
  252 +
  253 + switch (iter.first) {
  254 + case algorithm_type_t::PEDESTRIAN_FALL: {
  255 + algor_config_param_pedestrian_fall *algor_param =
  256 + (algor_config_param_pedestrian_fall *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  257 + ->algor_param;
  258 + if (algor_param) {
  259 + delete (algor_config_param_pedestrian_fall *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  260 + ->algor_param;
  261 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  262 + }
  263 + break;
  264 + }
  265 + case algorithm_type_t::PEDESTRIAN_FIGHT: {
  266 + algor_config_param_pedestrian_fight *algor_param =
  267 + (algor_config_param_pedestrian_fight *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  268 + ->algor_param;
  269 + if (algor_param) {
  270 + delete (algor_config_param_pedestrian_fight *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  271 + ->algor_param;
  272 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  273 + }
  274 + break;
  275 + }
  276 + case algorithm_type_t::HUMAN_GATHER: {
  277 + algor_config_param_human_gather *algor_param =
  278 + (algor_config_param_human_gather *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  279 + ->algor_param;
  280 + if (algor_param) {
  281 + delete (algor_config_param_human_gather *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  282 + ->algor_param;
  283 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  284 + }
  285 + break;
  286 + }
  287 +
  288 +
  289 + //221026byzsh---------------------------------------------------------
  290 + case algorithm_type_t::ROAD_WORK_DET: {
  291 + algor_config_param_road_work *algor_param =
  292 + (algor_config_param_road_work *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  293 + ->algor_param;
  294 + if (algor_param) {
  295 + delete (algor_config_param_road_work *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  296 + ->algor_param;
  297 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  298 + }
  299 + break;
  300 + }
  301 + //--------------------------------------------------------------------
  302 +
  303 + //230220byzsh---------------------------------------------------------
  304 + case algorithm_type_t::VIDEO_TIMING_SNAPSHOT: {
  305 + algor_config_video_timing_snapshot *algor_param =
  306 + (algor_config_video_timing_snapshot *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  307 + ->algor_param;
  308 + if (algor_param) {
  309 + delete (algor_config_video_timing_snapshot *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])
  310 + ->algor_param;
  311 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  312 + }
  313 + break;
  314 + }
  315 + //--------------------------------------------------------------------
  316 +
  317 + case algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION: {
  318 + algor_config_param_takeaway_member_classification *algor_param =
  319 + (algor_config_param_takeaway_member_classification *)((algor_init_config_param_t *)
  320 + m_task_params[task_id][iter.first])
  321 + ->algor_param;
  322 + if (algor_param) {
  323 + delete (algor_config_param_takeaway_member_classification *)((algor_init_config_param_t *)
  324 + m_task_params[task_id][iter.first])
  325 + ->algor_param;
  326 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  327 + }
  328 + break;
  329 + }
  330 + case algorithm_type_t::NO_REFLECTIVE_CLOTHING: {
  331 + using ptr_t = algor_config_param_no_reflective_clothing;
  332 + ptr_t *algor_param = (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  333 + if (algor_param) {
  334 + delete (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  335 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  336 + }
  337 + break;
  338 + }
  339 + case algorithm_type_t::NO_SAFETY_HELMET: {
  340 + using ptr_t = algor_config_param_no_safety_helmet;
  341 + ptr_t *algor_param = (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  342 + if (algor_param) {
  343 + delete (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  344 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  345 + }
  346 + break;
  347 + }
  348 + case algorithm_type_t::CALL_PHONE_DET: {
  349 + using ptr_t = algor_config_param_call_phone;
  350 + ptr_t *algor_param = (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  351 + if (algor_param) {
  352 + delete (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  353 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  354 + }
  355 + break;
  356 + }
  357 + case algorithm_type_t::SMOKING_DET: {
  358 + using ptr_t = algor_config_param_smoking;
  359 + ptr_t *algor_param = (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  360 + if (algor_param) {
  361 + delete (ptr_t *)((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param;
  362 + ((algor_init_config_param_t *)m_task_params[task_id][iter.first])->algor_param = nullptr;
  363 + }
  364 + break;
  365 + }
  366 + default:
  367 + break;
  368 + }
  369 +
  370 + if ((algor_init_config_param_t *)m_task_params[task_id][iter.first]) {
  371 + delete (algor_init_config_param_t *)m_task_params[task_id][iter.first];
  372 + m_task_params[task_id][iter.first] = nullptr;
  373 + }
  374 + }
  375 + m_task_params.erase(task_id);
  376 +}
  377 +
  378 +void task_param_manager::task_param_manager_release() {
  379 + for (auto iter : m_task_params)
  380 + delete_task_param(iter.first);
  381 +}
  382 +
  383 +/* 获取指定任务的算法配置参数 */
  384 +const algor_open_config_param *const task_param_manager::get_task_algor_param(const string &task_id) {
  385 + auto res = m_algor_config_params.find(task_id);
  386 + if (res == m_algor_config_params.end())
  387 + return nullptr;
  388 + return &res->second;
  389 +}
  390 +
  391 +/* 获取指定任务&指定算法的配置参数 */
  392 +const task_param_manager::algo_param_type_t_ *const
  393 +task_param_manager::get_task_other_param(const string &task_id, const algo_type &_algo_type) {
  394 + auto task_algor_param = get_task_other_param(task_id);
  395 + if (task_algor_param != nullptr){
  396 + auto res = task_algor_param->find(_algo_type);
  397 + if (res != task_algor_param->end())
  398 + return res->second;
  399 + }
  400 +
  401 + return nullptr;
  402 +}
  403 +
  404 +/* 获取指定任务的任务配置参数 */
  405 +const map<algo_type, task_param_manager::algo_param_type_t_ *> *const
  406 +task_param_manager::get_task_other_param(const string &task_id) {
  407 + auto res = m_task_params.find(task_id);
  408 + if (res == m_task_params.end())
  409 + return nullptr;
  410 + return &res->second;
  411 +}
  412 +
  413 +/* 获取所有任务的算法配置参数 */
  414 +map<string, algor_open_config_param> task_param_manager::get_task_algor_params() {
  415 + return m_algor_config_params;
  416 +}
  417 +
  418 +/* 获取所有任务的其他配置参数 */
  419 +map<string, map<algo_type, task_param_manager::algo_param_type_t_ *>> task_param_manager::get_task_other_params() {
  420 + return m_task_params;
  421 +}
src/ai_platform/task_param_manager.h 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-11-30 18:58:46
  4 + * @Last Modified by: yangzilong
  5 + * @Last Modified time: Do not edit
  6 + * @Email: yangzilong@objecteye.com
  7 + * @Description:
  8 + */
  9 +#pragma once
  10 +#include "header.h"
  11 +#include "det_obj_header.h"
  12 +
  13 +#include <map>
  14 +#include <set>
  15 +using namespace std;
  16 +
  17 +struct algor_open_config_param
  18 +{
  19 + set<algo_type> human_face_algors;
  20 + set<algo_type> human_algors;
  21 + set<algo_type> nonmotor_vehicle_algors;
  22 + set<algo_type> vehicle_algors;
  23 +};
  24 +
  25 +class task_param_manager
  26 +{
  27 +public:
  28 + using algo_param_type_t_ = algor_init_config_param_t;
  29 +
  30 + static task_param_manager* getInstance()
  31 + {
  32 + static task_param_manager task_param_instance;
  33 + return &task_param_instance;
  34 + }
  35 +
  36 + void add_task_param(string task_id, task_param task_param);
  37 + void delete_task_param(string task_id);
  38 + const algor_open_config_param *const get_task_algor_param(const string &task_id);
  39 + const map<algo_type, algo_param_type_t_*> *const get_task_other_param(const string& task_id);
  40 + const algo_param_type_t_ *const get_task_other_param(const string& task_id, const algo_type &_algo_type);
  41 +
  42 + map<string, algor_open_config_param> get_task_algor_params();
  43 + map<string, map<algo_type, algo_param_type_t_*>> get_task_other_params();
  44 + void task_param_manager_release();
  45 +
  46 +private:
  47 + task_param_manager();
  48 + task_param_manager(const task_param_manager& other);
  49 +
  50 + map<string, map<algo_type, algo_param_type_t_*>> m_task_params;
  51 + map<string, algor_open_config_param> m_algor_config_params;
  52 +};
0 \ No newline at end of file 53 \ No newline at end of file
src/ai_platform/vpt_proj.cpp1 0 → 100644
  1 +#include <iostream>
  2 +#include <string>
  3 +#include <queue>
  4 +#include <mutex>
  5 +#include <chrono>
  6 +#include <thread>
  7 +
  8 +#include "vpt.h"
  9 +
  10 +#include "acl/acl.h"
  11 +#include "acl/ops/acl_dvpp.h"
  12 +
  13 +#include "../decoder/interface/DecoderManager.h"
  14 +#include "../decoder/interface/utiltools.hpp"
  15 +
  16 +using namespace std;
  17 +
  18 +#define ACL_CALL(ret, expect, errCode)\
  19 + do {\
  20 + if (ret != expect) {\
  21 + if (errCode == 0)\
  22 + return ret;\
  23 + else\
  24 + return errCode;\
  25 + }\
  26 + } while(0)
  27 +
  28 +
  29 +string test_uri = "/home/huchunming/data/caishenkezhan.mp4";
  30 +
  31 +queue<DeviceMemory*> memQueue;
  32 +mutex mem_mutex;
  33 +
  34 +static void postDecoded(const void * userPtr, DeviceMemory* devFrame){
  35 + AbstractDecoder* decoder = (AbstractDecoder*)userPtr;
  36 + if (decoder!= nullptr)
  37 + {
  38 + }
  39 +
  40 + std::lock_guard<std::mutex> l(mem_mutex);
  41 + memQueue.push(devFrame);
  42 +
  43 + // if(devFrame){
  44 + // delete devFrame;
  45 + // devFrame = nullptr;
  46 + // }
  47 +}
  48 +
  49 +static void decode_finished_cbk(const void* userPtr){
  50 + cout << "当前时间戳: " << UtilTools::get_cur_time_ms() << endl;
  51 +}
  52 +
  53 +static void createDvppDecoder(int index, char* devId){
  54 + DecoderManager* pDecManager = DecoderManager::getInstance();
  55 + MgrDecConfig config;
  56 + config.name = "dec" + to_string(index);
  57 + config.cfg.uri = test_uri;
  58 + config.cfg.post_decoded_cbk = postDecoded;
  59 + config.cfg.decode_finished_cbk = decode_finished_cbk;
  60 + config.cfg.force_tcp = true;
  61 + config.dec_type = DECODER_TYPE_DVPP;
  62 +
  63 + config.cfg.gpuid = devId;
  64 +
  65 + AbstractDecoder* decoder = pDecManager->createDecoder(config);
  66 + if (!decoder)
  67 + {
  68 + cout << "创建解码器失败" << endl;
  69 + return ;
  70 + }
  71 + pDecManager->setPostDecArg(config.name, decoder);
  72 + pDecManager->setFinishedDecArg(config.name, decoder);
  73 + pDecManager->startDecodeByName(config.name);
  74 +}
  75 +
  76 +
  77 +int main(){
  78 + cout << vpt_get_version() << endl;
  79 +
  80 + vpt_param param;
  81 +
  82 + // param.modelNames = "vtp0716x.om";
  83 + param.modelNames = "../models/vpt0715_310p.om";
  84 + param.threshold = 0.4;
  85 + param.devId = 0;
  86 + param.isTrk = false;
  87 +
  88 + ACL_CALL(aclInit(nullptr), ACL_ERROR_NONE, 1);
  89 + ACL_CALL(aclrtSetDevice(param.devId), ACL_ERROR_NONE, 1);
  90 + aclrtContext ctx;
  91 + ACL_CALL(aclrtCreateContext(&ctx, param.devId), ACL_ERROR_NONE, 1);
  92 +
  93 + void* handle = nullptr;
  94 + int ret = vpt_init(&handle, param);
  95 + if(ret != 0){
  96 + printf("init error \n");
  97 + return -1;
  98 + }
  99 +
  100 + createDvppDecoder(0,"0");
  101 +
  102 + DecoderManager* pDecManager = DecoderManager::getInstance();
  103 + const int batchsize = 1;
  104 + int index = 0;
  105 + while (pDecManager->isRunning("dec0"))
  106 + {
  107 + if(index > 30){
  108 + break;
  109 + }
  110 + if(memQueue.size() <= 0){
  111 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  112 + continue;
  113 + }
  114 +
  115 + vector<DeviceMemory*> vec_mem;
  116 +
  117 + vector<sy_img> imgs;
  118 +
  119 + std::lock_guard<std::mutex> l(mem_mutex);
  120 + for (int b = 0; b < batchsize; b++) {
  121 + DeviceMemory* mem = memQueue.front();
  122 + sy_img img;
  123 + img.w_ = mem->getWidth();
  124 + img.h_ = mem->getHeight();
  125 + img.data_ = mem->getMem();
  126 + imgs.push_back(img);
  127 + vec_mem.push_back(mem);
  128 + memQueue.pop();
  129 + }
  130 +
  131 + if(vec_mem.size() <= 0){
  132 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  133 + continue;
  134 + }
  135 +
  136 + ACL_CALL(aclrtSetCurrentContext(ctx), ACL_ERROR_NONE, 1);
  137 + vpt_result* results;
  138 + int ret = vpt_batch(handle, imgs.data(), imgs.size(), &results);
  139 +
  140 + for(int batchIdx = 0; batchIdx < batchsize; batchIdx ++){
  141 + printf("debug det num:%d\n",results[batchIdx].obj_count_);
  142 + }
  143 +
  144 + for(int i=0;i < vec_mem.size(); i++){
  145 + DeviceMemory* mem = vec_mem[i];
  146 + delete mem;
  147 + mem = nullptr;
  148 + }
  149 + vec_mem.clear();
  150 +
  151 + index ++;
  152 + }
  153 +
  154 + pDecManager->closeDecoderByName("dec0");
  155 +
  156 + pDecManager->closeAllDecoder();
  157 +
  158 + ret = aclrtDestroyContext(ctx);
  159 + if(ret != ACL_ERROR_NONE){
  160 + printf("aclrtDestroyContext failed ! \n");
  161 + }
  162 +
  163 +
  164 +
  165 + aclFinalize();
  166 +}
0 \ No newline at end of file 167 \ No newline at end of file
src/common/SimpleList.hpp 0 → 100644
  1 +#ifndef __LIST_HPP__
  2 +#define __LIST_HPP__
  3 +
  4 +#include<iostream>
  5 +
  6 +
  7 +// 先声明链表类,便于node将其声明为友元
  8 +template<typename T> class SimpleList;
  9 +
  10 +// 链表节点类
  11 +template<typename T>
  12 +class node
  13 +{
  14 +public:
  15 + node() : next(nullptr){}
  16 + node(T val) : data(val), next(nullptr) {}
  17 +private:
  18 + T data;
  19 + node* next;
  20 + friend class SimpleList<T>;
  21 +};
  22 +
  23 +/*
  24 +链表操作
  25 +1、删除节点
  26 +2、添加节点
  27 +3、
  28 +*/
  29 +
  30 +template<typename T>
  31 +class SimpleList
  32 +{
  33 +public:
  34 + SimpleList(); // 构造函数
  35 + SimpleList(const SimpleList<T>& l); // 拷贝构造
  36 + ~SimpleList(); // 析构函数
  37 + SimpleList<T>& operator= (const SimpleList<T>& l); // 拷贝赋值
  38 + void insert(int index, T val); // 在index处插入结点
  39 + void remove(int index); // 删除index处结点
  40 + T get_node(int index); // 获取index处结点值
  41 + int find(int value); // 查找值value,找到返回index,找不到返回-1
  42 + int size(); // 获取链表长度
  43 + void push_back(T val); // 在链表尾部插入数据
  44 + T front(); // 获取第一个
  45 + void pop_front(); // 删除第一个
  46 + void clear(); // 清空
  47 + bool empty();
  48 + T begin(); // 第一个
  49 +
  50 +private:
  51 + node<T>* head_ptr; // 链表头指针
  52 + int length; // 链表长度
  53 +};
  54 +
  55 + // 构造函数
  56 +template<typename T>
  57 +SimpleList<T>::SimpleList()
  58 +{
  59 + this->head_ptr = nullptr;
  60 + this->length = 0;
  61 +}
  62 +
  63 +// 拷贝构造
  64 +template<typename T>
  65 +SimpleList<T>::SimpleList(const SimpleList<T>& l)
  66 +{
  67 + if(l.head_ptr == nullptr)
  68 + {
  69 + this->head_ptr = nullptr;
  70 + this->length = 0;
  71 + }
  72 + else
  73 + {
  74 + this->head_ptr = new node<T>;
  75 + node<T>* p1 = this->head_ptr;
  76 + node<T>* p2 = nullptr;
  77 + // 拷贝链表
  78 + for(p2 = l.head_ptr; p2->next != nullptr; p2 = p2->next)
  79 + {
  80 + p1->data = p2->data;
  81 + p1->next = new node<T>;
  82 + p1 = p1->next;
  83 + }
  84 + p1->data = p2->data;
  85 + p1->next = nullptr;
  86 + this->length = l.length;
  87 + }
  88 +
  89 +
  90 +}
  91 +
  92 +// 拷贝赋值
  93 +template<typename T>
  94 +SimpleList<T>& SimpleList<T>::operator= (const SimpleList<T>& l)
  95 +{
  96 + if(this->head_ptr == nullptr) // 原链表空
  97 + {
  98 + if(l.head_ptr == nullptr)
  99 + {
  100 + this->head_ptr = nullptr;
  101 + this->length = 0;
  102 + }
  103 + else
  104 + {
  105 + this->head_ptr = new node<T>;
  106 + node<T>* p1 = this->head_ptr;
  107 + node<T>* p2 = nullptr;
  108 + // 拷贝链表
  109 + for(p2 = l.head_ptr; p2->next != nullptr; p2 = p2->next)
  110 + {
  111 + p1->data = p2->data;
  112 + p1->next = new node<T>;
  113 + p1 = p1->next;
  114 + }
  115 + p1->data = p2->data;
  116 + p1->next = nullptr;
  117 + this->length = l.length;
  118 + }
  119 + }
  120 + else // 原链表非空
  121 + {
  122 + if(l.head_ptr == nullptr)
  123 + {
  124 + // 清空链表
  125 + node<T>* p1 = this->head_ptr;
  126 + node<T>* p2 = p1->next;
  127 + while(p2 != nullptr)
  128 + {
  129 + delete p1;
  130 + p1 = p2;
  131 + p2 = p2->next;
  132 + }
  133 + delete p1;
  134 + this->length = 0;
  135 + }
  136 + else
  137 + {
  138 + if(l.length > this->length) // 待复制的链表更长,先将原链表填满再申请空间
  139 + {
  140 + node<T>* p1 = this->head_ptr;
  141 + node<T>* p2 = l.head_ptr;
  142 + for(int i = 0; i < this->length - 1; i++)
  143 + {
  144 + p1->data = p2->data;
  145 + p1 = p1->next;
  146 + p2 = p2->next;
  147 + }
  148 + p1->next = new node<T>;
  149 + for(int i = this->length - 1; i < l.length - 1; i++)
  150 + {
  151 + p1->data = p2->data;
  152 + p1->next = new node<T>;
  153 + p1 = p1->next;
  154 + p2 = p2->next;
  155 + }
  156 + p1->data = p2->data;
  157 + p1->next = nullptr;
  158 + }
  159 + else // 待复制的链表更短或相等,更短时需要释放原链表多余空间
  160 + {
  161 + node<T>* p1 = this->head_ptr;
  162 + node<T>* p2 = l.head_ptr;
  163 + // 复制数据
  164 + for(int i = 0; i < l.length; i++)
  165 + {
  166 + p1->data = p2->data;
  167 + p1 = p1->next;
  168 + p2 = p2->next;
  169 + }
  170 + // 删除多余结点
  171 + while(p1 != nullptr)
  172 + {
  173 + p2 = p1->next;
  174 + delete p1;
  175 + p1 = p2;
  176 + }
  177 + }
  178 + }
  179 + this->length = l.length;
  180 + }
  181 +
  182 + return *this;
  183 +}
  184 +
  185 +// 在index处插入结点
  186 +template<typename T>
  187 +void SimpleList<T>::insert(int index, T val)
  188 +{
  189 + if((index > this->length)) // 超过索引,最多可以插到当前结点的下一个结点,否则就是超过索引
  190 + {
  191 + throw runtime_error("index out of this SimpleList`s range");
  192 + }
  193 + else if((this->head_ptr == nullptr) && (index == 0)) // 插在空链表的头
  194 + {
  195 + this->head_ptr = new node<T>;
  196 + this->head_ptr->next = nullptr;
  197 + this->head_ptr->data = val;
  198 + this->length++;
  199 + }
  200 + else // 一般情况
  201 + {
  202 + node<T>* p1 = this->head_ptr;
  203 + node<T>* p2 = new node<T>;
  204 + for(int i = 0; i < index - 1; i++)
  205 + {
  206 + p1 = p1->next;
  207 + }
  208 + p2->data = val;
  209 + p2->next = p1->next;
  210 + p1->next = p2;
  211 + this->length++;
  212 + }
  213 +}
  214 +
  215 +// 删除index处结点
  216 +template<typename T>
  217 +void SimpleList<T>::remove(int index)
  218 +{
  219 + node<T>* p1 = this->head_ptr;
  220 + node<T>* p2 = nullptr;
  221 + for(int i = 0; i < index - 1; i++)
  222 + {
  223 + p1 = p1->next;
  224 + }
  225 + p2 = p1->next->next;
  226 + delete p1->next;
  227 + p1->next = p2;
  228 + this->length--;
  229 +}
  230 +
  231 +
  232 +// 获取index处结点值
  233 +template<typename T>
  234 +T SimpleList<T>::get_node(int index)
  235 +{
  236 + if(index > this->length - 1) // 超过索引
  237 + {
  238 + throw runtime_error("index out of this SimpleList`s range");
  239 + }
  240 +
  241 + node<T>* p1 = this->head_ptr;
  242 + for(int i = 0; i < index; i++){
  243 + p1 = p1->next;
  244 + }
  245 +
  246 + return p1->data;
  247 +}
  248 +
  249 +// 获取第一个
  250 +template<typename T>
  251 +T SimpleList<T>::front()
  252 +{
  253 + return get_node(0);
  254 +}
  255 +
  256 +// 删除index处结点
  257 +template<typename T>
  258 +void SimpleList<T>::pop_front()
  259 +{
  260 + remove(0);
  261 +}
  262 +
  263 +// 删除index处结点
  264 +template<typename T>
  265 +void SimpleList<T>::clear()
  266 +{
  267 + node<T>* p;
  268 + while (head_ptr != NULL)
  269 + {
  270 + p = head_ptr;
  271 + head_ptr = head_ptr->next;
  272 + delete p;
  273 + p = nullptr;
  274 + }
  275 +}
  276 +
  277 +// 删除index处结点
  278 +template<typename T>
  279 +T SimpleList<T>::begin(){
  280 + return head_ptr;
  281 +}
  282 +
  283 +// 查找值value,找到返回index,找不到返回-1
  284 +template<typename T>
  285 +int SimpleList<T>::find(int value)
  286 +{
  287 + node<T>* p1 = this->head_ptr;
  288 + for(int i = 0; i < this->length; i++)
  289 + {
  290 + if(p1->data == value)
  291 + {
  292 + return i;
  293 + }
  294 + p1 = p1->next;
  295 + }
  296 +
  297 + return -1;
  298 +}
  299 +
  300 +// 获取链表长度
  301 +template<typename T>
  302 +int SimpleList<T>::size()
  303 +{
  304 + return this->length;
  305 +}
  306 +
  307 +// 链表是否为空
  308 +template<typename T>
  309 +bool SimpleList<T>::empty()
  310 +{
  311 + return size() == 0 ? true : false ;
  312 +}
  313 +
  314 +// 在链表尾部插入数据
  315 +template<typename T>
  316 +void SimpleList<T>::push_back(T val)
  317 +{
  318 + if(this->head_ptr == nullptr) // 链表为空
  319 + {
  320 + this->head_ptr = new node<T>;
  321 + this->head_ptr->data = val;
  322 + this->head_ptr->next = nullptr;
  323 + }
  324 + else
  325 + {
  326 + node<T>* p1 = this->head_ptr;
  327 + node<T>* p2 = new node<T>;
  328 + p2->data = val;
  329 + p2->next = nullptr;
  330 + while(p1->next != nullptr)
  331 + {
  332 + p1 = p1->next;
  333 + }
  334 + p1->next = p2;
  335 + }
  336 + this->length++;
  337 +}
  338 +
  339 +// 析构函数
  340 +template<typename T>
  341 +SimpleList<T>::~SimpleList(){
  342 + // 清空链表
  343 + clear();
  344 +}
  345 +
  346 +#endif
0 \ No newline at end of file 347 \ No newline at end of file
src/common/dvpp/dvpp_cropandpaste.cpp 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.cpp
  17 +* Description: handle dvpp process
  18 +*/
  19 +
  20 +#include <iostream>
  21 +#include "acl/acl.h"
  22 +#include "utils.h"
  23 +#include "dvpp_cropandpaste.h"
  24 +#include "sy_errorinfo.h"
  25 +using namespace std;
  26 +
  27 +DvppCropAndPaste::DvppCropAndPaste(aclrtStream& stream, acldvppChannelDesc *dvppChannelDesc,
  28 + uint32_t width, uint32_t height)
  29 +: stream_(stream), dvppChannelDesc_(dvppChannelDesc),
  30 +vpcInputDesc_(nullptr), vpcOutputDesc_(nullptr),
  31 +vpcOutBufferDev_(nullptr),vpcOutBufferSize_(0){
  32 + size_.width = width;
  33 + size_.height = height;
  34 +}
  35 +
  36 +DvppCropAndPaste::~DvppCropAndPaste()
  37 +{
  38 + DestroyCropAndPasteResource();
  39 +}
  40 +
  41 +int DvppCropAndPaste::InitCropAndPasteInputDesc(ImageData& inputImage)
  42 +{
  43 + originalImageWidth_ = inputImage.width;
  44 + originalImageHeight_ = inputImage.height;
  45 + uint32_t alignWidth = inputImage.alignWidth;
  46 + uint32_t alignHeight = inputImage.alignHeight;
  47 + // printf("image w %d, h %d, align w%d, h%d",inputImage.width, inputImage.height, alignWidth, alignHeight);
  48 + if (alignWidth == 0 || alignHeight == 0) {
  49 + ERROR_LOG("InitResizeInputDesc AlignmentHelper failed. image w %d, h %d, align w%d, h%d",
  50 + inputImage.width, inputImage.height, alignWidth, alignHeight);
  51 + return SY_FAILED;
  52 + }
  53 + uint32_t inputBufferSize = YUV420SP_SIZE(alignWidth, alignHeight);
  54 + vpcInputDesc_ = acldvppCreatePicDesc();
  55 + if (vpcInputDesc_ == nullptr) {
  56 + ERROR_LOG("acldvppCreatePicDesc vpcInputDesc_ failed");
  57 + return SY_FAILED;
  58 + }
  59 +
  60 + acldvppSetPicDescData(vpcInputDesc_, inputImage.data.get()); // JpegD . vpcResize
  61 + acldvppSetPicDescFormat(vpcInputDesc_, format_);
  62 + acldvppSetPicDescWidth(vpcInputDesc_, inputImage.width);
  63 + acldvppSetPicDescHeight(vpcInputDesc_, inputImage.height);
  64 + acldvppSetPicDescWidthStride(vpcInputDesc_, alignWidth);
  65 + acldvppSetPicDescHeightStride(vpcInputDesc_, alignHeight);
  66 + acldvppSetPicDescSize(vpcInputDesc_, inputBufferSize);
  67 + return SY_SUCCESS;
  68 +}
  69 +
  70 +int DvppCropAndPaste::InitCropAndPasteOutputDesc()
  71 +{
  72 + int resizeOutWidth = size_.width;
  73 + int resizeOutHeight = size_.height;
  74 + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth);
  75 + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight);
  76 +
  77 + if (resizeOutWidthStride == 0 || resizeOutHeightStride == 0) {
  78 + ERROR_LOG("InitResizeOutputDesc AlignmentHelper failed");
  79 + return SY_FAILED;
  80 + }
  81 +
  82 + vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride);
  83 + aclError aclRet = acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_);
  84 + //debug========================================================================
  85 + uint32_t size = ALIGN_UP(vpcOutBufferSize_,32) + 32;
  86 + aclRet = aclrtMemset(vpcOutBufferDev_,size, 128, size);
  87 + // aclRet = aclrtMemset(vpcOutBufferDev_,vpcOutBufferSize_, 0, vpcOutBufferSize_);
  88 + //debug end====================================================================
  89 + if (aclRet != ACL_SUCCESS) {
  90 + ERROR_LOG("acldvppMalloc vpcOutBufferDev_ failed, aclRet = %d", aclRet);
  91 + return SY_FAILED;
  92 + }
  93 +
  94 + vpcOutputDesc_ = acldvppCreatePicDesc();
  95 + if (vpcOutputDesc_ == nullptr) {
  96 + ERROR_LOG("acldvppCreatePicDesc vpcOutputDesc_ failed");
  97 + return SY_FAILED;
  98 + }
  99 + acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_);
  100 + acldvppSetPicDescFormat(vpcOutputDesc_, format_);
  101 + acldvppSetPicDescWidth(vpcOutputDesc_, resizeOutWidth);
  102 + acldvppSetPicDescHeight(vpcOutputDesc_, resizeOutHeight);
  103 + acldvppSetPicDescWidthStride(vpcOutputDesc_, resizeOutWidthStride);
  104 + acldvppSetPicDescHeightStride(vpcOutputDesc_, resizeOutHeightStride);
  105 + acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_);
  106 +
  107 + return SY_SUCCESS;
  108 +}
  109 +
  110 +int DvppCropAndPaste::InitRightCropAndPasteOutputDesc()
  111 +{
  112 + int resizeOutWidth = size_.width;
  113 + int resizeOutHeight = size_.height;
  114 + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth);
  115 + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight);
  116 + if (resizeOutWidthStride == 0 || resizeOutHeightStride == 0) {
  117 + ERROR_LOG("InitResizeOutputDesc AlignmentHelper failed");
  118 + return SY_FAILED;
  119 + }
  120 +
  121 + vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride);
  122 + //aclError aclRet = acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_);
  123 + // if (aclRet != ACL_SUCCESS) {
  124 + // ERROR_LOG("acldvppMalloc vpcOutBufferDev_ failed, aclRet = %d", aclRet);
  125 + // return SY_FAILED;
  126 + // }
  127 + vpcOutputDesc_ = acldvppCreatePicDesc();
  128 + if (vpcOutputDesc_ == nullptr) {
  129 + ERROR_LOG("acldvppCreatePicDesc vpcOutputDesc_ failed");
  130 + return SY_FAILED;
  131 + }
  132 + acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_ + vpcOutBufferSize_);
  133 + acldvppSetPicDescFormat(vpcOutputDesc_, format_);
  134 + acldvppSetPicDescWidth(vpcOutputDesc_, resizeOutWidth);
  135 + acldvppSetPicDescHeight(vpcOutputDesc_, resizeOutHeight);
  136 + acldvppSetPicDescWidthStride(vpcOutputDesc_, resizeOutWidthStride);
  137 + acldvppSetPicDescHeightStride(vpcOutputDesc_, resizeOutHeightStride);
  138 + acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_);
  139 +
  140 + return SY_SUCCESS;
  141 +}
  142 +
  143 +
  144 +// IN/OUT Desc
  145 +int DvppCropAndPaste::InitCropAndPasteResource(ImageData& inputImage) {
  146 + format_ = static_cast<acldvppPixelFormat>(PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  147 + if (SY_SUCCESS != InitCropAndPasteInputDesc(inputImage)) {
  148 + ERROR_LOG("InitCropAndPasteInputDesc failed");
  149 + return SY_FAILED;
  150 + }
  151 +
  152 + if (SY_SUCCESS != InitCropAndPasteOutputDesc()) {
  153 + ERROR_LOG("InitCropAndPasteOutputDesc failed");
  154 + return SY_FAILED;
  155 + }
  156 +
  157 + return SY_SUCCESS;
  158 +}
  159 +
  160 +int DvppCropAndPaste::InitRightCropAndPasteResource(ImageData& inputImage) {
  161 + format_ = static_cast<acldvppPixelFormat>(PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  162 + if (SY_SUCCESS != InitCropAndPasteInputDesc(inputImage)) {
  163 + ERROR_LOG("InitCropAndPasteInputDesc failed");
  164 + return SY_FAILED;
  165 + }
  166 +
  167 + if (SY_SUCCESS != InitRightCropAndPasteOutputDesc()) {
  168 + ERROR_LOG("InitCropAndPasteOutputDesc failed");
  169 + return SY_FAILED;
  170 + }
  171 +
  172 + return SY_SUCCESS;
  173 +}
  174 +
  175 +int DvppCropAndPaste::ResizeWithPadding(ImageData& resizedImage, ImageData& srcImage)
  176 +{
  177 + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) {
  178 + ERROR_LOG("Dvpp cropandpaste failed for init error");
  179 + return SY_FAILED;
  180 + }
  181 +
  182 + uint32_t cropLeftOffset = 0; // must even
  183 + uint32_t cropTopOffset = 0; // must even
  184 + uint32_t cropRightOffset = (((cropLeftOffset + originalImageWidth_) >> 1) << 1) -1; // must odd
  185 + uint32_t cropBottomOffset = (((cropTopOffset + originalImageHeight_) >> 1) << 1) -1; // must odd
  186 +
  187 + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset,
  188 + cropTopOffset, cropBottomOffset);
  189 + if (cropArea_ == nullptr) {
  190 + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed");
  191 + return SY_FAILED;
  192 + }
  193 + // cout << "====================================================" << endl;
  194 + // printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset);
  195 +
  196 + bool widthRatioSmaller = true;
  197 + // The scaling ratio is based on the smaller ratio to ensure the smallest edge to fill the targe edge
  198 + float resizeRatio = static_cast<float>(size_.width) / srcImage.width;
  199 + if (resizeRatio > (static_cast<float>(size_.height) / srcImage.height)) {
  200 + resizeRatio = static_cast<float>(size_.height) / srcImage.height;
  201 + widthRatioSmaller = false;
  202 + }
  203 +
  204 + const int halfValue = 2;
  205 + uint32_t pasteLeftOffset = 0;
  206 + uint32_t pasteRightOffset = 0;
  207 + uint32_t pasteTopOffset = 0;
  208 + uint32_t pasteBottomOffset = 0;
  209 + // The left and up must be even, right and down must be odd which is required by acl
  210 + if (widthRatioSmaller) { //宽较长
  211 + pasteLeftOffset = 0; // must even
  212 + pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd
  213 + // pasteTopOffset = ((static_cast<uint32_t>((size_.height - srcImage.height * resizeRatio) / halfValue) >> 1) << 1); // must even
  214 + // pasteBottomOffset = (((size_.height - pasteTopOffset) >> 1) << 1) -1; // must odd
  215 + //debug===============================================================================================
  216 + float pady = ((size_.height - srcImage.height * resizeRatio) / halfValue);
  217 + pasteTopOffset = ((static_cast<uint32_t>(pady) >> 1) << 1); // must even
  218 + pasteBottomOffset = ((static_cast<uint32_t>(size_.height - pady) >> 1) << 1) -1; // must odd
  219 + // if((int)(size_.height - srcImage.height * resizeRatio) % 2 ==0){
  220 + // pasteBottomOffset = ((static_cast<uint32_t>(size_.height - pady) >> 1) << 1) -1; // must odd
  221 + // }else{
  222 + // pasteBottomOffset = ((static_cast<uint32_t>(size_.height - pady + 1) >> 1) << 1) -1; // must odd
  223 + // }
  224 + //debug end============================================================================================
  225 + }else{ //高较长
  226 + uint32_t pad = (static_cast<uint32_t>((size_.width - srcImage.width * resizeRatio) / halfValue));
  227 + // printf("debug pad:%d\n",pad);
  228 + pasteLeftOffset = (pad + 8) / 16 * 16; // must even,作贴图区域时,需16对齐
  229 + // pasteLeftOffset = ALIGN_UP16(pad); // must even,作贴图区域时,需16对齐
  230 + pasteRightOffset = (((size_.width - pad) >> 1) << 1) -1; // must odd
  231 + pasteTopOffset = 0; // must even
  232 + pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd
  233 +
  234 + }
  235 +
  236 + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset,
  237 + pasteTopOffset, pasteBottomOffset);
  238 + if (pasteArea_ == nullptr) {
  239 + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed");
  240 + return SY_FAILED;
  241 + }
  242 + // printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset);
  243 + // crop and patse pic
  244 + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
  245 + vpcOutputDesc_, cropArea_, pasteArea_, stream_);
  246 + //printf("debug crop line:%d\n",__LINE__);
  247 + if (aclRet != ACL_SUCCESS) {
  248 + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet);
  249 + return SY_FAILED;
  250 + }
  251 + aclRet = aclrtSynchronizeStream(stream_);
  252 + if (aclRet != ACL_SUCCESS) {
  253 + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  254 + return SY_FAILED;
  255 + }
  256 +
  257 + resizedImage.width = size_.width;
  258 + resizedImage.height = size_.height;
  259 + resizedImage.alignWidth = ALIGN_UP16(size_.width);
  260 + resizedImage.alignHeight = ALIGN_UP2(size_.height);
  261 + resizedImage.size = vpcOutBufferSize_;
  262 + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  263 +
  264 + DestroyCropAndPasteResource();
  265 +
  266 + return SY_SUCCESS;
  267 +}
  268 +
  269 +
  270 +
  271 +int DvppCropAndPaste::PatchProcess(ImageData& resizedImage, ImageData& srcImage, uint32_t xmin, uint32_t ymin,
  272 + uint32_t xmax, uint32_t ymax)
  273 +{
  274 + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) {
  275 + ERROR_LOG("Dvpp cropandpaste failed for init error");
  276 + return SY_FAILED;
  277 + }
  278 +
  279 + uint32_t cropLeftOffset = ((xmin >> 1) << 1); // must even
  280 + uint32_t cropTopOffset = ((ymin >> 1) << 1); // must even
  281 + uint32_t cropRightOffset = ((xmax >> 1) << 1) -1; // must odd
  282 + uint32_t cropBottomOffset = ((ymax >> 1) << 1) -1; // must odd
  283 +
  284 + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset,
  285 + cropTopOffset, cropBottomOffset);
  286 + if (cropArea_ == nullptr) {
  287 + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed");
  288 + return SY_FAILED;
  289 + }
  290 + //printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset);
  291 +
  292 + uint32_t pasteLeftOffset = 0; // must even
  293 + uint32_t pasteTopOffset = 0; // must even
  294 + uint32_t pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd
  295 + uint32_t pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd
  296 +
  297 + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset,
  298 + pasteTopOffset, pasteBottomOffset);
  299 + if (pasteArea_ == nullptr) {
  300 + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed");
  301 + return SY_FAILED;
  302 + }
  303 + //printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset);
  304 +
  305 + // crop and patse pic
  306 + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
  307 + vpcOutputDesc_, cropArea_, pasteArea_, stream_);
  308 + //printf("debug crop line:%d\n",__LINE__);
  309 + if (aclRet != ACL_SUCCESS) {
  310 + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet);
  311 + return SY_FAILED;
  312 + }
  313 +
  314 + aclRet = aclrtSynchronizeStream(stream_);
  315 + if (aclRet != ACL_SUCCESS) {
  316 + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  317 + return SY_FAILED;
  318 + }
  319 +
  320 + resizedImage.width = size_.width;
  321 + resizedImage.height = size_.height;
  322 + resizedImage.alignWidth = ALIGN_UP16(size_.width);
  323 + resizedImage.alignHeight = ALIGN_UP2(size_.height);
  324 + resizedImage.size = vpcOutBufferSize_;
  325 + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  326 +
  327 + DestroyCropAndPasteResource();
  328 +
  329 + return SY_SUCCESS;
  330 +}
  331 +
  332 +int DvppCropAndPaste::Crop2Process(ImageData& resizedImage, ImageData& leftImage, ImageData& rightImage, ImageData& srcImage)
  333 +{
  334 + //left
  335 + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) {
  336 + ERROR_LOG("Dvpp cropandpaste failed for init error");
  337 + return SY_FAILED;
  338 + }
  339 + uint32_t lcropLeftOffset = 0; // must even
  340 + uint32_t lcropTopOffset = 0; // must even
  341 + uint32_t lcropRightOffset = ((srcImage.width/2 >> 1) << 1) -1; // must odd
  342 + uint32_t lcropBottomOffset = ((srcImage.height >> 1) << 1) -1; // must odd
  343 + cropArea_ = acldvppCreateRoiConfig(lcropLeftOffset, lcropRightOffset,lcropTopOffset, lcropBottomOffset);
  344 + if (cropArea_ == nullptr) {
  345 + ERROR_LOG("left acldvppCreateRoiConfig cropArea_ failed");
  346 + return SY_FAILED;
  347 + }
  348 + //printf("debug left crop area: %d %d %d %d\n", lcropLeftOffset, lcropTopOffset, lcropRightOffset, lcropBottomOffset);
  349 +
  350 + uint32_t lpasteLeftOffset = 0; // must even
  351 + uint32_t lpasteTopOffset = 0; // must even
  352 + uint32_t lpasteRightOffset = (((lpasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd
  353 + uint32_t lpasteBottomOffset = (((lpasteTopOffset + size_.height) >> 1) << 1) -1; // must odd
  354 + pasteArea_ = acldvppCreateRoiConfig(lpasteLeftOffset, lpasteRightOffset,lpasteTopOffset, lpasteBottomOffset);
  355 + if (pasteArea_ == nullptr) {
  356 + ERROR_LOG("left acldvppCreateRoiConfig pasteArea_ failed");
  357 + return SY_FAILED;
  358 + }
  359 + //printf("debug left paste area: %d %d %d %d\n", lpasteLeftOffset, lpasteTopOffset, lpasteRightOffset, lpasteBottomOffset);
  360 +
  361 + // crop and patse pic
  362 + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
  363 + vpcOutputDesc_, cropArea_, pasteArea_, stream_);
  364 + if (aclRet != ACL_SUCCESS) {
  365 + ERROR_LOG("left acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet);
  366 + return SY_FAILED;
  367 + }
  368 +
  369 + aclRet = aclrtSynchronizeStream(stream_);
  370 + if (aclRet != ACL_SUCCESS) {
  371 + ERROR_LOG("left crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  372 + return SY_FAILED;
  373 + }
  374 +
  375 + leftImage.width = size_.width;
  376 + leftImage.height = size_.height;
  377 + leftImage.alignWidth = ALIGN_UP16(size_.width);
  378 + leftImage.alignHeight = ALIGN_UP2(size_.height);
  379 + leftImage.size = vpcOutBufferSize_;
  380 + leftImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  381 +
  382 + DestroyCropAndPasteResource();
  383 +
  384 + //right
  385 + if (SY_SUCCESS != InitRightCropAndPasteResource(srcImage)) {
  386 + ERROR_LOG("Dvpp cropandpaste failed for init error");
  387 + return SY_FAILED;
  388 + }
  389 +
  390 + uint32_t rcropLeftOffset = ((srcImage.width/2 >> 1) << 1); // must even
  391 + uint32_t rcropTopOffset = 0; // must even
  392 + uint32_t rcropRightOffset = ((srcImage.width >> 1) << 1) -1; // must odd
  393 + uint32_t rcropBottomOffset = ((srcImage.height >> 1) << 1) -1; // must odd
  394 + cropArea_ = acldvppCreateRoiConfig(rcropLeftOffset, rcropRightOffset, rcropTopOffset, rcropBottomOffset);
  395 + if (cropArea_ == nullptr) {
  396 + ERROR_LOG("right acldvppCreateRoiConfig cropArea_ failed");
  397 + return SY_FAILED;
  398 + }
  399 + //printf("debug right crop area: %d %d %d %d\n", rcropLeftOffset, rcropTopOffset, rcropRightOffset, rcropBottomOffset);
  400 +
  401 + uint32_t rpasteLeftOffset = 0; // must even
  402 + uint32_t rpasteTopOffset = 0; // must even
  403 + uint32_t rpasteRightOffset = (((rpasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd
  404 + uint32_t rpasteBottomOffset = (((rpasteTopOffset + size_.height) >> 1) << 1) -1; // must odd
  405 + pasteArea_ = acldvppCreateRoiConfig(rpasteLeftOffset, rpasteRightOffset, rpasteTopOffset, rpasteBottomOffset);
  406 + if (pasteArea_ == nullptr) {
  407 + ERROR_LOG("right acldvppCreateRoiConfig pasteArea_ failed");
  408 + return SY_FAILED;
  409 + }
  410 + //printf("debug right paste area: %d %d %d %d\n", rpasteLeftOffset, rpasteTopOffset, rpasteRightOffset, rpasteBottomOffset);
  411 +
  412 + // crop and patse pic
  413 + aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
  414 + vpcOutputDesc_, cropArea_, pasteArea_, stream_);
  415 + if (aclRet != ACL_SUCCESS) {
  416 + ERROR_LOG("right acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet);
  417 + return SY_FAILED;
  418 + }
  419 +
  420 + aclRet = aclrtSynchronizeStream(stream_);
  421 + if (aclRet != ACL_SUCCESS) {
  422 + ERROR_LOG("right crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  423 + return SY_FAILED;
  424 + }
  425 +
  426 + rightImage.width = size_.width;
  427 + rightImage.height = size_.height;
  428 + rightImage.alignWidth = ALIGN_UP16(size_.width);
  429 + rightImage.alignHeight = ALIGN_UP2(size_.height);
  430 + rightImage.size = vpcOutBufferSize_;
  431 + rightImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  432 + // rightImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_ + vpcOutBufferSize_);
  433 +
  434 + DestroyCropAndPasteResource();
  435 +
  436 + resizedImage.size = leftImage.size + rightImage.size;
  437 + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  438 +
  439 + return SY_SUCCESS;
  440 +}
  441 +
  442 +
  443 +int DvppCropAndPaste::Process(ImageData& resizedImage, ImageData& srcImage)
  444 +{
  445 + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) {
  446 + ERROR_LOG("Dvpp cropandpaste failed for init error");
  447 + return SY_FAILED;
  448 + }
  449 +
  450 + uint32_t cropLeftOffset = 0; // must even
  451 + uint32_t cropTopOffset = 0; // must even
  452 + uint32_t cropRightOffset = (((cropLeftOffset + originalImageWidth_) >> 1) << 1) -1; // must odd
  453 + uint32_t cropBottomOffset = (((cropTopOffset + originalImageHeight_) >> 1) << 1) -1; // must odd
  454 +
  455 + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset,
  456 + cropTopOffset, cropBottomOffset);
  457 + if (cropArea_ == nullptr) {
  458 + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed");
  459 + return SY_FAILED;
  460 + }
  461 + //printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset);
  462 +
  463 + uint32_t pasteLeftOffset = 0; // must even
  464 + uint32_t pasteTopOffset = 0; // must even
  465 + uint32_t pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd
  466 + uint32_t pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd
  467 +
  468 + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset,
  469 + pasteTopOffset, pasteBottomOffset);
  470 + if (pasteArea_ == nullptr) {
  471 + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed");
  472 + return SY_FAILED;
  473 + }
  474 + //printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset);
  475 +
  476 + // crop and patse pic
  477 + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_,
  478 + vpcOutputDesc_, cropArea_, pasteArea_, stream_);
  479 + //printf("debug crop line:%d\n",__LINE__);
  480 + if (aclRet != ACL_SUCCESS) {
  481 + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet);
  482 + return SY_FAILED;
  483 + }
  484 +
  485 + aclRet = aclrtSynchronizeStream(stream_);
  486 + if (aclRet != ACL_SUCCESS) {
  487 + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  488 + return SY_FAILED;
  489 + }
  490 +
  491 + resizedImage.width = size_.width;
  492 + resizedImage.height = size_.height;
  493 + resizedImage.alignWidth = ALIGN_UP16(size_.width);
  494 + resizedImage.alignHeight = ALIGN_UP2(size_.height);
  495 + resizedImage.size = vpcOutBufferSize_;
  496 + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_);
  497 +
  498 + DestroyCropAndPasteResource();
  499 +
  500 + return SY_SUCCESS;
  501 +}
  502 +
  503 +
  504 +void DvppCropAndPaste::DestroyCropAndPasteResource()
  505 +{
  506 + if (cropArea_ != nullptr) {
  507 + (void)acldvppDestroyRoiConfig(cropArea_);
  508 + cropArea_ = nullptr;
  509 + }
  510 +
  511 + if (pasteArea_ != nullptr) {
  512 + (void)acldvppDestroyRoiConfig(pasteArea_);
  513 + pasteArea_ = nullptr;
  514 + }
  515 +
  516 + if (vpcInputDesc_ != nullptr) {
  517 + (void)acldvppDestroyPicDesc(vpcInputDesc_);
  518 + vpcInputDesc_ = nullptr;
  519 + }
  520 +
  521 + if (vpcOutputDesc_ != nullptr) {
  522 + (void)acldvppDestroyPicDesc(vpcOutputDesc_);
  523 + vpcOutputDesc_ = nullptr;
  524 + }
  525 +}
src/common/dvpp/dvpp_cropandpaste.h 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.h
  17 +* Description: handle dvpp process
  18 +*/
  19 +#pragma once
  20 +#include <cstdint>
  21 +
  22 +#include "acl/acl.h"
  23 +#include "acl/ops/acl_dvpp.h"
  24 +#include "utils.h"
  25 +
  26 +class DvppCropAndPaste {
  27 +public:
  28 + /**
  29 + * @brief Constructor
  30 + * @param [in] stream: stream
  31 + */
  32 + DvppCropAndPaste(aclrtStream &stream, acldvppChannelDesc *dvppChannelDesc,
  33 + uint32_t width, uint32_t height);
  34 +
  35 + /**
  36 + * @brief Destructor
  37 + */
  38 + ~DvppCropAndPaste();
  39 +
  40 + /**
  41 + * @brief dvpp global init
  42 + * @return result
  43 + */
  44 + int InitResource();
  45 +
  46 + /**
  47 + * @brief init dvpp output para
  48 + * @param [in] modelInputWidth: model input width
  49 + * @param [in] modelInputHeight: model input height
  50 + * @return result
  51 + */
  52 + int InitOutputPara(int modelInputWidth, int modelInputHeight);
  53 +
  54 + /**
  55 + * @brief dvpp process
  56 + * @return result
  57 + */
  58 + int Process(ImageData& resizedImage, ImageData& srcImage);
  59 + int Crop2Process(ImageData& resizedImage, ImageData& leftImage, ImageData& rightImage, ImageData& srcImage);
  60 + int PatchProcess(ImageData& resizedImage, ImageData& srcImage, uint32_t xmin, uint32_t ymin,
  61 + uint32_t xmax, uint32_t ymax);
  62 +
  63 + int ResizeWithPadding(ImageData& resizedImage, ImageData& srcImage);
  64 +
  65 +private:
  66 + int InitCropAndPasteResource(ImageData& inputImage);
  67 + int InitCropAndPasteInputDesc(ImageData& inputImage);
  68 + int InitCropAndPasteOutputDesc();
  69 +
  70 + int InitRightCropAndPasteResource(ImageData& inputImage);
  71 + int InitRightCropAndPasteOutputDesc();
  72 +
  73 + void DestroyCropAndPasteResource();
  74 +
  75 + aclrtStream stream_;
  76 + acldvppChannelDesc *dvppChannelDesc_;
  77 +
  78 +
  79 + // IN/OUT Desc
  80 + acldvppPicDesc *vpcInputDesc_;
  81 + acldvppPicDesc *vpcOutputDesc_;
  82 +
  83 + uint32_t originalImageWidth_;
  84 + uint32_t originalImageHeight_;
  85 +
  86 + acldvppRoiConfig *cropArea_;
  87 + acldvppRoiConfig *pasteArea_;
  88 +
  89 + // output buffer
  90 + void *vpcOutBufferDev_;
  91 + uint32_t vpcOutBufferSize_;
  92 +
  93 + //model [W][H]
  94 + Resolution size_;
  95 + acldvppPixelFormat format_;
  96 +};
  97 +
src/common/dvpp/dvpp_jpegd.cpp 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.cpp
  17 +* Description: handle dvpp process
  18 +*/
  19 +
  20 +#include <iostream>
  21 +#include "acl/acl.h"
  22 +#include "dvpp_jpegd.h"
  23 +#include "utils.h"
  24 +#include "sy_errorinfo.h"
  25 +using namespace std;
  26 +
  27 +DvppJpegD::DvppJpegD(aclrtStream& stream, acldvppChannelDesc *dvppChannelDesc)
  28 + : stream_(stream), dvppChannelDesc_(dvppChannelDesc),
  29 + decodeOutBufferDev_(nullptr), decodeOutputDesc_(nullptr),
  30 + decodeOutWidthStride_(0), decodeOutHeightStride_(0)
  31 +{
  32 +}
  33 +
  34 +DvppJpegD::~DvppJpegD()
  35 +{
  36 + DestroyDecodeResource();
  37 +}
  38 +
  39 +
  40 +int DvppJpegD::InitDecodeOutputDesc(ImageData& inputImage)
  41 +{
  42 + //230316 ascend310p兼容=================================================
  43 + auto socVersion = aclrtGetSocName();
  44 + if (strncmp(socVersion, "Ascend310P3", sizeof("Ascend310P3") - 1) == 0) {
  45 + decodeOutWidth_ = ALIGN_UP2(inputImage.width);
  46 + decodeOutHeight_ = ALIGN_UP2(inputImage.height);
  47 + decodeOutWidthStride_ = ALIGN_UP64(inputImage.width); // 64-byte alignment
  48 + decodeOutHeightStride_ = ALIGN_UP16(inputImage.height); // 16-byte alignment
  49 + } else {
  50 + decodeOutWidth_ = inputImage.width;
  51 + decodeOutHeight_ = inputImage.height;
  52 + decodeOutWidthStride_ = ALIGN_UP128(inputImage.width); // 128-byte alignment
  53 + decodeOutHeightStride_ = ALIGN_UP16(inputImage.height); // 16-byte alignment
  54 + }
  55 + if (decodeOutWidthStride_ == 0 || decodeOutHeightStride_ == 0) {
  56 + ERROR_LOG("InitDecodeOutputDesc AlignmentHelper failed");
  57 + return SY_FAILED;
  58 + }
  59 + //=====================================================================
  60 +
  61 + acldvppJpegPredictDecSize(inputImage.data.get(), inputImage.size,
  62 + PIXEL_FORMAT_YUV_SEMIPLANAR_420, &decodeOutBufferSize_);
  63 +
  64 + aclError aclRet = acldvppMalloc(&decodeOutBufferDev_, decodeOutBufferSize_);
  65 + //debug========================================================================
  66 + uint32_t size = ALIGN_UP(decodeOutBufferSize_,32) + 32;
  67 + aclRet = aclrtMemset(decodeOutBufferDev_,size, 128, size);
  68 + // aclRet = aclrtMemset(decodeOutBufferDev_,decodeOutBufferSize_, 0, decodeOutBufferSize_);
  69 + //debug end====================================================================
  70 + if (aclRet != ACL_SUCCESS) {
  71 + ERROR_LOG("acldvppMalloc decodeOutBufferDev_ failed, aclRet = %d", aclRet);
  72 + return SY_FAILED;
  73 + }
  74 +
  75 + decodeOutputDesc_ = acldvppCreatePicDesc();
  76 + if (decodeOutputDesc_ == nullptr) {
  77 + ERROR_LOG("acldvppCreatePicDesc decodeOutputDesc_ failed");
  78 + return SY_FAILED;
  79 + }
  80 +
  81 + acldvppSetPicDescData(decodeOutputDesc_, decodeOutBufferDev_);
  82 + acldvppSetPicDescFormat(decodeOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  83 + acldvppSetPicDescWidth(decodeOutputDesc_, decodeOutWidth_);
  84 + acldvppSetPicDescHeight(decodeOutputDesc_, decodeOutHeight_);
  85 + acldvppSetPicDescWidthStride(decodeOutputDesc_, decodeOutWidthStride_);
  86 + acldvppSetPicDescHeightStride(decodeOutputDesc_, decodeOutHeightStride_);
  87 + acldvppSetPicDescSize(decodeOutputDesc_, decodeOutBufferSize_);
  88 + return SY_SUCCESS;
  89 +}
  90 +
  91 +
  92 +int DvppJpegD::Process(ImageData& dest, ImageData& src)
  93 +{
  94 + int ret = InitDecodeOutputDesc(src);
  95 + if (ret != SY_SUCCESS) {
  96 + ERROR_LOG("InitDecodeOutputDesc failed");
  97 + return SY_FAILED;
  98 + }
  99 +
  100 + ImageData imageDevice;
  101 + Utils::CopyImageDataToDvpp(imageDevice, src);
  102 +
  103 + //TODO:
  104 + aclError aclRet = acldvppJpegDecodeAsync(dvppChannelDesc_, reinterpret_cast<void *>(imageDevice.data.get()),
  105 + imageDevice.size, decodeOutputDesc_, stream_);
  106 + if (aclRet != ACL_SUCCESS) {
  107 + ERROR_LOG("acldvppJpegDecodeAsync failed, aclRet = %d", aclRet);
  108 + return SY_FAILED;
  109 + }
  110 +
  111 + aclRet = aclrtSynchronizeStream(stream_);
  112 + if (aclRet != ACL_SUCCESS) {
  113 + ERROR_LOG("decode aclrtSynchronizeStream failed, aclRet = %d", aclRet);
  114 + return SY_FAILED;
  115 + }
  116 +
  117 + dest.width = decodeOutWidth_;
  118 + dest.height = decodeOutHeight_;
  119 + dest.alignWidth = decodeOutWidthStride_;
  120 + dest.alignHeight = decodeOutHeightStride_;
  121 + dest.size = YUV420SP_SIZE(dest.alignWidth, dest.alignHeight);
  122 + dest.data = SHARED_PRT_DVPP_BUF(decodeOutBufferDev_);
  123 + // cout << "dvpp w:" << dest.width << " h:" << dest.height << " alignw:" << dest.alignWidth <<" alignh:" <<dest.alignHeight << " size: " << dest.size << endl;
  124 + // INFO_LOG("convert image success");
  125 +
  126 + return SY_SUCCESS;
  127 +}
  128 +
  129 +void DvppJpegD::DestroyDecodeResource()
  130 +{
  131 + if (decodeOutputDesc_ != nullptr) {
  132 + acldvppDestroyPicDesc(decodeOutputDesc_);
  133 + decodeOutputDesc_ = nullptr;
  134 + }
  135 +}
src/common/dvpp/dvpp_jpegd.h 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.h
  17 +* Description: handle dvpp process
  18 +*/
  19 +#pragma once
  20 +#include <cstdint>
  21 +#include <string.h>
  22 +#include "acl/acl.h"
  23 +#include "acl/ops/acl_dvpp.h"
  24 +#include "utils.h"
  25 +
  26 +
  27 +/**
  28 + * DvppProcess
  29 + */
  30 +class DvppJpegD {
  31 +public:
  32 + /**
  33 + * @brief Constructor
  34 + * @param [in] stream: stream
  35 + */
  36 + DvppJpegD(aclrtStream &stream, acldvppChannelDesc *dvppChannelDesc);
  37 +
  38 + /**
  39 + * @brief Destructor
  40 + */
  41 + ~DvppJpegD();
  42 +
  43 + /**
  44 + * @brief dvpp global init
  45 + * @return result
  46 + */
  47 + int InitResource();
  48 +
  49 + /**
  50 + * @brief init dvpp output para
  51 + * @param [in] modelInputWidth: model input width
  52 + * @param [in] modelInputHeight: model input height
  53 + * @return result
  54 + */
  55 + int InitOutputPara(int modelInputWidth, int modelInputHeight);
  56 +
  57 + /**
  58 + * @brief set jpegd input
  59 + * @param [in] inDevBuffer: device buffer of input pic
  60 + * @param [in] inDevBufferSize: device buffer size of input pic
  61 + * @param [in] inputWidth:width of pic
  62 + * @param [in] inputHeight:height of pic
  63 + */
  64 + void SetInput4JpegD(uint8_t* inDevBuffer, int inDevBufferSize, int inputWidth, int inputHeight);
  65 + int InitDecodeOutputDesc(ImageData& inputImage);
  66 + /**
  67 + * @brief gett dvpp output
  68 + * @param [in] outputBuffer: pointer which points to dvpp output buffer
  69 + * @param [out] outputSize: output size
  70 + */
  71 + void GetOutput(void **outputBuffer, int &outputSize);
  72 + int Process(ImageData& dest, ImageData& src);
  73 + /**
  74 + * @brief release encode resource
  75 + */
  76 + void DestroyEncodeResource();
  77 +
  78 +private:
  79 + void DestroyDecodeResource();
  80 + void DestroyResource();
  81 + void DestroyOutputPara();
  82 +
  83 + aclrtStream stream_;
  84 + acldvppChannelDesc *dvppChannelDesc_;
  85 +
  86 + void* decodeOutBufferDev_; // decode output buffer
  87 + acldvppPicDesc *decodeOutputDesc_; //decode output desc
  88 +
  89 + uint8_t *inDevBuffer_; // input pic dev buffer
  90 + uint32_t inDevBufferSizeD_; // input pic size for decode
  91 +
  92 + void *vpcOutBufferDev_; // vpc output buffer
  93 + uint32_t vpcOutBufferSize_; // vpc output size
  94 + //230316added
  95 + uint32_t decodeOutWidth_;
  96 + uint32_t decodeOutHeight_;
  97 + uint32_t decodeOutWidthStride_;
  98 + uint32_t decodeOutHeightStride_;
  99 + uint32_t decodeOutBufferSize_;
  100 +};
  101 +
src/common/dvpp/dvpp_process.cpp 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.cpp
  17 +* Description: handle dvpp process
  18 +*/
  19 +
  20 +#include <iostream>
  21 +#include "acl/acl.h"
  22 +#include "dvpp_cropandpaste.h"
  23 +#include "dvpp_jpegd.h"
  24 +#include "dvpp_process.h"
  25 +#include "sy_errorinfo.h"
  26 +
  27 +using namespace std;
  28 +
  29 +DvppProcess::DvppProcess()
  30 + : isInitOk_(false), dvppChannelDesc_(nullptr) {
  31 + isGlobalContext_ = false;
  32 +}
  33 +
  34 +DvppProcess::~DvppProcess()
  35 +{
  36 + DestroyResource();
  37 +}
  38 +
  39 +void DvppProcess::DestroyResource()
  40 +{
  41 + aclError aclRet;
  42 + if (dvppChannelDesc_ != nullptr) {
  43 + aclRet = acldvppDestroyChannel(dvppChannelDesc_);
  44 + if (aclRet != ACL_SUCCESS) {
  45 + ERROR_LOG("acldvppDestroyChannel failed, aclRet = %d", aclRet);
  46 + }
  47 +
  48 + (void)acldvppDestroyChannelDesc(dvppChannelDesc_);
  49 + dvppChannelDesc_ = nullptr;
  50 + }
  51 +
  52 + //INFO_LOG("end to destroy context");
  53 +}
  54 +
  55 +int DvppProcess::InitResource(aclrtStream& stream)
  56 +{
  57 + aclError aclRet;
  58 +
  59 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  60 + if (dvppChannelDesc_ == nullptr) {
  61 + ERROR_LOG("acldvppCreateChannelDesc failed");
  62 + return SY_FAILED;
  63 + }
  64 +
  65 + aclRet = acldvppCreateChannel(dvppChannelDesc_);
  66 + if (aclRet != ACL_SUCCESS) {
  67 + ERROR_LOG("acldvppCreateChannel failed, aclRet = %d", aclRet);
  68 + return SY_FAILED;
  69 + }
  70 + stream_ = stream;
  71 + isInitOk_ = true;
  72 + //INFO_LOG("dvpp init resource ok");
  73 + return SY_SUCCESS;
  74 +}
  75 +
  76 +// int DvppProcess::CropAndPaste(ImageData& dest, ImageData& src,
  77 +// uint32_t width, uint32_t height) {
  78 +// DvppCropAndPaste cropandpasteOp(stream_, dvppChannelDesc_, width, height);
  79 +// return cropandpasteOp.Process(dest, src);
  80 +// }
  81 +
  82 +// int DvppProcess::Crop2Paste(ImageData& dest, ImageData& leftImage, ImageData& rightImage,
  83 +// ImageData& src,uint32_t width, uint32_t height) {
  84 +// DvppCropAndPaste cropandpasteOp(stream_, dvppChannelDesc_, width, height);
  85 +// return cropandpasteOp.Crop2Process(dest, leftImage, rightImage, src);
  86 +// }
  87 +
  88 +// int DvppProcess::CropAndPadding(ImageData& dest, ImageData& src,
  89 +// uint32_t width, uint32_t height) {
  90 +// DvppCropAndPaste cropandpasteOp(stream_, dvppChannelDesc_, width, height);
  91 +// return cropandpasteOp.ResizeWithPadding(dest, src);
  92 +// }
  93 +
  94 +// int DvppProcess::PatchCropAndPaste(ImageData& dest, ImageData& src, uint32_t xmin, uint32_t ymin,
  95 +// uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height) {
  96 +// DvppCropAndPaste cropandpasteOp(stream_, dvppChannelDesc_, width, height);
  97 +// return cropandpasteOp.PatchProcess(dest, src, xmin, ymin, xmax, ymax);
  98 +// }
  99 +
  100 +// int DvppProcess::CvtJpegToYuv420sp(ImageData& dest, ImageData& src) {
  101 +// DvppJpegD jpegD(stream_, dvppChannelDesc_);
  102 +// return jpegD.Process(dest, src);
  103 +// }
  104 +
  105 +
  106 +int DvppProcess::CropAndPaste(ImageData& dest, ImageData& src,
  107 + uint32_t width, uint32_t height) {
  108 + DvppCropAndPaste cropandpasteOp(stream_, dvppChannelDesc_, width, height);
  109 + return cropandpasteOp.Process(dest, src);
  110 +}
  111 +
  112 +int DvppProcess::Crop2Paste(ImageData& dest, ImageData& leftImage, ImageData& rightImage,
  113 + ImageData& src,uint32_t width, uint32_t height) {
  114 + DvppCropAndPaste cro2pasteOp(stream_, dvppChannelDesc_, width, height);
  115 + return cro2pasteOp.Crop2Process(dest, leftImage, rightImage, src);
  116 +}
  117 +
  118 +
  119 +int DvppProcess::CropAndPadding(ImageData& dest, ImageData& src,
  120 + uint32_t width, uint32_t height) {
  121 + DvppCropAndPaste cropandpaddingOp(stream_, dvppChannelDesc_, width, height);
  122 + return cropandpaddingOp.ResizeWithPadding(dest, src);
  123 +}
  124 +
  125 +
  126 +int DvppProcess::PatchCropAndPaste(ImageData& dest, ImageData& src, uint32_t xmin, uint32_t ymin,
  127 + uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height) {
  128 + DvppCropAndPaste patchcropandpasteOp(stream_, dvppChannelDesc_, width, height);
  129 + return patchcropandpasteOp.PatchProcess(dest, src, xmin, ymin, xmax, ymax);
  130 +}
  131 +
  132 +int DvppProcess::CvtJpegToYuv420sp(ImageData& dest, ImageData& src) {
  133 + DvppJpegD jpegD(stream_, dvppChannelDesc_);
  134 + return jpegD.Process(dest, src);
  135 +}
  136 +
src/common/dvpp/dvpp_process.h 0 → 100644
  1 +/**
  2 +* Copyright 2020 Huawei Technologies Co., Ltd
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +
  16 +* File dvpp_process.h
  17 +* Description: handle dvpp process
  18 +*/
  19 +#pragma once
  20 +#include <cstdint>
  21 +
  22 +#include "acl/acl.h"
  23 +#include "acl/ops/acl_dvpp.h"
  24 +#include "utils.h"
  25 +
  26 +/**
  27 + * DvppProcess
  28 + */
  29 +class DvppProcess {
  30 +public:
  31 + DvppProcess();
  32 +
  33 + ~DvppProcess();
  34 +
  35 + int CropAndPadding(ImageData& src, ImageData& dest,
  36 + uint32_t width, uint32_t height);
  37 + int CropAndPaste(ImageData& src, ImageData& dest,
  38 + uint32_t width, uint32_t height);
  39 + int PatchCropAndPaste(ImageData& dest, ImageData& src, uint32_t xmin, uint32_t ymin,
  40 + uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height);
  41 + int Crop2Paste(ImageData& dest, ImageData& leftImage, ImageData& rightImage,
  42 + ImageData& src,uint32_t width, uint32_t height);
  43 + int CvtJpegToYuv420sp(ImageData& src, ImageData& dest);
  44 + int InitResource(aclrtStream& stream);
  45 + void DestroyResource();
  46 +
  47 +protected:
  48 + int isInitOk_;
  49 + aclrtStream stream_;
  50 + acldvppChannelDesc *dvppChannelDesc_;
  51 + bool isGlobalContext_;
  52 +
  53 +};
  54 +
src/common/logger.hpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-21 11:07:11
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +
  9 +#pragma once
  10 +
  11 +// #include "define.hpp"
  12 +#include <spdlog/spdlog.h>
  13 +#include <spdlog/common.h>
  14 +#include <spdlog/details/file_helper.h>
  15 +#include <spdlog/details/null_mutex.h>
  16 +#include <spdlog/fmt/fmt.h>
  17 +#include <spdlog/sinks/base_sink.h>
  18 +#include <spdlog/details/os.h>
  19 +#include <spdlog/details/circular_q.h>
  20 +#include <spdlog/details/synchronous_factory.h>
  21 +
  22 +#include <set>
  23 +#include <chrono>
  24 +#include <cstdio>
  25 +#include <ctime>
  26 +#include <mutex>
  27 +#include <string>
  28 +#include <memory>
  29 +#include <vector>
  30 +
  31 +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
  32 +
  33 +#define LOG_TRACE_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_TRACE(logger, __VA_ARGS__);}
  34 +#define LOG_DEBUG_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_DEBUG(logger, __VA_ARGS__);}
  35 +#define LOG_WARN_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_WARN(logger, __VA_ARGS__);}
  36 +#define LOG_ERROR_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_ERROR(logger, __VA_ARGS__);}
  37 +#define LOG_INFO_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_INFO(logger, __VA_ARGS__);}
  38 +#define LOG_CRITICAL_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_CRITICAL(logger, __VA_ARGS__);}
  39 +
  40 +
  41 +// use fmt lib, e.g. LOG_WARN("warn log, {1}, {1}, {2}", 1, 2);
  42 +#define LOG_TRACE(msg, ...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::trace, msg, ##__VA_ARGS__)
  43 +#define LOG_DEBUG(msg, ...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::debug, msg, ##__VA_ARGS__)
  44 +#define LOG_INFO(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::info, msg, ##__VA_ARGS__)
  45 +#define LOG_WARN(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::warn, msg, ##__VA_ARGS__)
  46 +#define LOG_ERROR(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::err, msg, ##__VA_ARGS__)
  47 +#define LOG_FATAL(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::critical, msg, ##__VA_ARGS__)
  48 +
  49 +
  50 +
  51 +namespace spdlog
  52 +{
  53 + namespace sinks
  54 + {
  55 + template<typename Mutex>
  56 + class easy_file_sink final : public base_sink<Mutex>
  57 + {
  58 + public:
  59 + easy_file_sink(filename_t base_filename, size_t max_size, size_t max_keep_days = 0)
  60 + : base_filename_(std::move(base_filename))
  61 + , max_size_(max_size)
  62 + , max_keep_days_(max_keep_days)
  63 + {
  64 + auto now = log_clock::now();
  65 + auto filename = gen_filename_by_daliy(base_filename_, now_tm(now));
  66 +
  67 + file_helper_.open(filename, false);
  68 + current_size_ = file_helper_.size();
  69 + rotation_tp_ = next_rotation_tp_();
  70 +
  71 + if (max_keep_days_ > 0)
  72 + {
  73 + filespath_q_.push_back(std::move(std::set<filename_t>()));
  74 + filespath_q_[filespath_q_.size() - 1].insert(filename);
  75 + }
  76 + }
  77 +
  78 + filename_t filename()
  79 + {
  80 + std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
  81 + return file_helper_.filename();
  82 + }
  83 +
  84 + protected:
  85 + void sink_it_(const details::log_msg &msg) override
  86 + {
  87 + memory_buf_t formatted;
  88 + base_sink<Mutex>::formatter_->format(msg, formatted);
  89 + current_size_ += formatted.size();
  90 +
  91 + auto time = msg.time;
  92 + if (time >= rotation_tp_)
  93 + {
  94 + file_helper_.close();
  95 + auto filename = gen_filename_by_daliy(base_filename_, now_tm(time));
  96 + file_helper_.open(filename, false);
  97 + current_size_ = file_helper_.size();
  98 + rotation_tp_ = next_rotation_tp_();
  99 +
  100 + {
  101 + filespath_q_.push_back(std::move(std::set<filename_t>()));
  102 + filespath_q_[filespath_q_.size() - 1].emplace(filename);
  103 + }
  104 +
  105 + // Do the cleaning only at the end because it might throw on failure.
  106 + if (max_keep_days_ > 0 && filespath_q_.size() > max_keep_days_)
  107 + delete_old_();
  108 + }
  109 + else if (current_size_ >= max_size_)
  110 + {
  111 + file_helper_.close();
  112 + auto src_name = gen_filename_by_daliy(base_filename_, now_tm(time));
  113 + auto target_name = gen_filename_by_filesize(base_filename_, now_tm(time), filespath_q_[filespath_q_.size() - 1].size());
  114 +
  115 + // rename file if failed then us `target_name` as src_name.
  116 + if (!rename_file_(src_name, target_name))
  117 + {
  118 + details::os::sleep_for_millis(200);
  119 + if (!rename_file_(src_name, target_name))
  120 + {
  121 + fprintf(stderr, "%s:%d rename %s to %s failed\n", __FILENAME__, __LINE__, src_name.c_str(), target_name.c_str());
  122 + src_name = target_name;
  123 + }
  124 + }
  125 +
  126 + filespath_q_[filespath_q_.size() - 1].emplace(src_name);
  127 + if (src_name != target_name)
  128 + filespath_q_[filespath_q_.size() - 1].emplace(target_name);
  129 +
  130 + file_helper_.open(src_name, false);
  131 + current_size_ = file_helper_.size();
  132 + rotation_tp_ = next_rotation_tp_();
  133 + }
  134 +
  135 + file_helper_.write(formatted);
  136 +
  137 +
  138 + }
  139 +
  140 + void flush_() override
  141 + {
  142 + file_helper_.flush();
  143 + }
  144 +
  145 + private:
  146 +
  147 + tm now_tm(log_clock::time_point tp)
  148 + {
  149 + time_t tnow = log_clock::to_time_t(tp);
  150 + return spdlog::details::os::localtime(tnow);
  151 + }
  152 +
  153 + /**
  154 + * @brief Get next day tm.
  155 + *
  156 + * @return log_clock::time_point
  157 + */
  158 + log_clock::time_point next_rotation_tp_()
  159 + {
  160 + auto now = log_clock::now();
  161 + tm date = now_tm(now);
  162 + date.tm_hour = 0;
  163 + date.tm_min = 0;
  164 + date.tm_sec = 0;
  165 + auto rotation_time = log_clock::from_time_t(std::mktime(&date));
  166 + if (rotation_time > now)
  167 + return rotation_time;
  168 + return {rotation_time + std::chrono::hours(24)};
  169 + }
  170 +
  171 + // Delete the file N rotations ago.
  172 + // Throw spdlog_ex on failure to delete the old file.
  173 + void delete_old_()
  174 + {
  175 + for (auto iter = filespath_q_.begin(); iter != filespath_q_.end();)
  176 + {
  177 + if (filespath_q_.size() <= max_keep_days_)
  178 + break;
  179 +
  180 + for (auto it = iter->begin(); it != iter->end(); ++it)
  181 + {
  182 + bool ok = details::os::remove_if_exists(*it) == 0;
  183 + if (!ok)
  184 + throw_spdlog_ex("Failed removing daily file " + details::os::filename_to_str(*it), errno);
  185 + }
  186 + filespath_q_.erase(iter);
  187 + }
  188 + }
  189 +
  190 + /* */
  191 + static filename_t gen_filename_by_daliy(const filename_t &filename, const tm &now_tm)
  192 + {
  193 + filename_t basename, ext;
  194 + std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
  195 + return fmt::format(SPDLOG_FILENAME_T("{}_{:04d}_{:02d}_{:02d}{}"),
  196 + basename,
  197 + now_tm.tm_year + 1900,
  198 + now_tm.tm_mon + 1,
  199 + now_tm.tm_mday,
  200 + ext);
  201 + }
  202 +
  203 + //
  204 + static filename_t gen_filename_by_filesize(const filename_t &filename, const tm &now_tm, const int &idx)
  205 + {
  206 + filename_t basename, ext;
  207 + std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
  208 + return fmt::format(SPDLOG_FILENAME_T("{}_{:04d}_{:02d}_{:02d}_{:02d}{:02d}{:02d}.{:d}{}"),
  209 + basename,
  210 + now_tm.tm_year + 1900,
  211 + now_tm.tm_mon + 1,
  212 + now_tm.tm_mday,
  213 + now_tm.tm_hour,
  214 + now_tm.tm_min,
  215 + now_tm.tm_sec,
  216 + idx,
  217 + ext);
  218 + }
  219 +
  220 + static bool rename_file_(const filename_t &src_filename, const filename_t &target_filename)
  221 + {
  222 + (void)details::os::remove(target_filename);
  223 + return details::os::rename(src_filename, target_filename) == 0;
  224 + }
  225 +
  226 + filename_t base_filename_;
  227 + log_clock::time_point rotation_tp_;
  228 + details::file_helper file_helper_;
  229 + std::size_t max_size_;
  230 + std::size_t max_keep_days_;
  231 + std::size_t current_size_;
  232 + // std::vector<<std::set<filename_t>> filespath_q_;
  233 + std::vector<std::set<filename_t>> filespath_q_;
  234 + };
  235 +
  236 + using easy_file_sink_mt = easy_file_sink<std::mutex>;
  237 + using easy_file_sink_st = easy_file_sink<details::null_mutex>;
  238 +
  239 + } // namespace sinks
  240 +
  241 + template<typename Factory = spdlog::synchronous_factory>
  242 + inline std::shared_ptr<logger> easy_logger_mt(
  243 + const std::string &logger_name, const filename_t &filename, size_t max_size, size_t max_keep_days = -1)
  244 + {
  245 + return Factory::template create<sinks::easy_file_sink_mt>(logger_name, filename, max_size, max_keep_days);
  246 + }
  247 +
  248 + template<typename Factory = spdlog::synchronous_factory>
  249 + inline std::shared_ptr<logger> easy_logger_st(
  250 + const std::string &logger_name, const filename_t &filename, size_t max_size, size_t max_keep_days = -1)
  251 + {
  252 + return Factory::template create<sinks::easy_file_sink_st>(logger_name, filename, max_size, max_keep_days);
  253 + }
  254 +
  255 +} // namespace spdlog
  256 +
  257 +
  258 +enum class LogLevel
  259 +{
  260 + CLOSE = -1,
  261 + TRACE = 0,
  262 + DEBUG = 1,
  263 + INFO = 2,
  264 + WARN = 3,
  265 + ERROR = 4,
  266 + FATAL = 5,
  267 +};
  268 +
  269 +
  270 +class LoggerGenerator
  271 +{
  272 +public:
  273 + static LoggerGenerator* get_instance()
  274 + {
  275 + static LoggerGenerator logger;
  276 + return &logger;
  277 + }
  278 +
  279 + void destory(LoggerGenerator *ptr)
  280 + {
  281 + if (ptr != nullptr)
  282 + {
  283 + delete ptr;
  284 + ptr = nullptr;
  285 + }
  286 + }
  287 +
  288 + std::shared_ptr<spdlog::logger> gen_logger(const LogLevel &level, const std::string &logger_name,
  289 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  290 + {
  291 + spdlog::level::level_enum spd_level;
  292 + if (LogLevel::TRACE == level)
  293 + spd_level = spdlog::level::trace;
  294 + else if (LogLevel::DEBUG == level)
  295 + spd_level = spdlog::level::debug;
  296 + else if (LogLevel::INFO == level)
  297 + spd_level = spdlog::level::info;
  298 + else if (LogLevel::WARN == level)
  299 + spd_level = spdlog::level::warn;
  300 + else if (LogLevel::ERROR == level)
  301 + spd_level = spdlog::level::err;
  302 + else if (LogLevel::FATAL == level)
  303 + spd_level = spdlog::level::critical;
  304 + else if (LogLevel::CLOSE == level)
  305 + spd_level = spdlog::level::off;
  306 +
  307 + auto sink_ptr = std::make_shared<spdlog::sinks::easy_file_sink_mt>(file_path, max_file_size, max_keep_days);
  308 + auto logger = std::make_shared<spdlog::logger>(logger_name, sink_ptr);
  309 + logger->set_level(spd_level);
  310 + logger->set_pattern("%s(%#): [%L %D %T.%e %P %t %!] %v");
  311 +
  312 + return logger;
  313 + }
  314 +
  315 + void set_default_logger(const LogLevel &level, const std::string &logger_name,
  316 + const std::string &file_name, size_t max_file_size, size_t max_keep_days)
  317 + {
  318 +
  319 + auto logger = gen_logger(level, logger_name, file_name, max_file_size, max_keep_days);
  320 + spdlog::set_default_logger(logger);
  321 + spdlog::set_level(logger->level());
  322 + spdlog::set_pattern("%s(%#): [%L %D %T.%e %P %t %!] %v");
  323 +
  324 + spdlog::flush_on(spdlog::level::trace);
  325 + spdlog::flush_every(std::chrono::seconds(1));
  326 + }
  327 +
  328 +};
  329 +
  330 +
  331 +static void set_default_logger(const LogLevel &level, const std::string &logger_name,
  332 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  333 +{
  334 + static LoggerGenerator loggerGenerator;
  335 + loggerGenerator.set_default_logger(level, logger_name, file_path, max_file_size, max_keep_days);
  336 +}
  337 +
  338 +
  339 +static std::shared_ptr<spdlog::logger> get_simple_logger(const LogLevel &level, const std::string &logger_name,
  340 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  341 +{
  342 + static LoggerGenerator loggerGenerator;
  343 + return loggerGenerator.gen_logger(level, logger_name, file_path, max_file_size, max_keep_days);
  344 +}
src/common/stream_data.h 0 → 100644
  1 +#ifndef _STREAM_DATA_H_
  2 +#define _STREAM_DATA_H_
  3 +
  4 +#include <memory>
  5 +
  6 +struct ImageData {
  7 + uint32_t width = 0;
  8 + uint32_t height = 0;
  9 + uint32_t alignWidth = 0;
  10 + uint32_t alignHeight = 0;
  11 + uint32_t size = 0;
  12 + std::shared_ptr<uint8_t> data;
  13 +};
  14 +
  15 +#endif
0 \ No newline at end of file 16 \ No newline at end of file
src/common/sy_common.h 0 → 100644
  1 +#ifndef __SY_COMMON_H__
  2 +#define __SY_COMMON_H__
  3 +
  4 +#define DEVICE_GPU 10
  5 +#define DEVICE_CPU 11
  6 +
  7 +
  8 +#define MODEL_SSD 100
  9 +#define MODEL_FPN 101
  10 +#define MODEL_CLASSFY 102
  11 +#define MODEL_CRNN 103
  12 +#define MODEL_SSD_FACE 104
  13 +#define MODEL_POSE_COCO 105
  14 +#define MODEL_RFCN 106
  15 +#define MODEL_CRNN_CNW 107
  16 +#define MODEL_SSD_LDMK 109
  17 +#define MODEL_CTDET 110
  18 +#define MODEL_CTDET_FEATURE 111
  19 +
  20 +#define ENGINE_MCAFFE2 200
  21 +#define ENGINE_TENSORRT 201
  22 +
  23 +
  24 +//��Զ๦��SDK�����ڳ�ʼ���������ã����ݸò������ж�����Ӧ�Ĺ���ģ���Ƿ���������
  25 +#ifndef __SY_COMMAND__
  26 +#define __SY_COMMAND__
  27 +typedef enum sy_command {
  28 + SY_CONFIG_OPEN, //�ù�������
  29 + SY_CONFIG_CLOSE //�ù��ܲ�����
  30 +};
  31 +#endif
  32 +
  33 +
  34 +//����ָ�������ͼ�����ݵĸ�ʽ
  35 +#ifndef __SY_FORMAT__
  36 +#define __SY_FORMAT__
  37 +typedef enum sy_format {
  38 + SY_FORMAT_BGR888, //Ŀǰֻ֧�ָ��ֽ����ʽ
  39 + SY_FORMAT_BGRA888,
  40 + SY_FORMAT_GRAY8,
  41 + SY_FORMAT_YUV4420P,
  42 + SY_FORMAT_NV12,
  43 + SY_FORMAT_NV21
  44 +};
  45 +#endif
  46 +
  47 +//Point
  48 +#ifndef __SY_POINT__
  49 +#define __SY_POINT__
  50 +typedef struct sy_point
  51 +{
  52 + int x_;
  53 + int y_;
  54 + sy_point(int m_x, int m_y) :x_(m_x), y_(m_y) {};
  55 + sy_point() {};
  56 +} sy_point;
  57 +#endif
  58 +
  59 +
  60 +//Rect
  61 +#ifndef __SY_RECT__
  62 +#define __SY_RECT__
  63 +typedef struct sy_rect
  64 +{
  65 + int left_;
  66 + int top_;
  67 + int width_;
  68 + int height_;
  69 + sy_rect(int m_left, int m_top, int m_width, int m_height) :left_(m_left), top_(m_top), width_(m_width), height_(m_height) {};
  70 + sy_rect() {};
  71 +} sy_rect;
  72 +#endif
  73 +
  74 +
  75 +//ImgData
  76 +#ifndef __SY_IMG__
  77 +#define __SY_IMG__
  78 +typedef struct sy_img
  79 +{
  80 + unsigned char * data_;
  81 + int w_;
  82 + int h_;
  83 + int c_;
  84 + void set_data(int m_w, int m_h, int m_c, unsigned char * m_data)
  85 + {
  86 + w_ = m_w;
  87 + h_ = m_h;
  88 + c_ = m_c;
  89 + data_ = m_data; //Shallow copy
  90 + }
  91 +} sy_img;
  92 +#endif
  93 +
  94 +
  95 +#endif //__SY_COMMON_H__
src/common/sy_errorinfo.h 0 → 100644
  1 +#ifndef __SY_ERRORINFO_H__
  2 +#define __SY_ERRORINFO_H__
  3 +
  4 +
  5 +//--------------------------------通用------------------------------------//
  6 +
  7 +#define SY_SUCCESS 0 //成功
  8 +#define SY_FAILED -1 //失败
  9 +
  10 +//1.通用错误 预留编号:(-199) - (-100)
  11 +#define SY_PARAMS_NULL_ERROR -100 //参数为空
  12 +#define SY_FILE_NOTFOUND_ERROR -101 //文件找不到
  13 +#define SY_HANDLE_NULL_ERROR -102 //句柄为空
  14 +#define SY_TYPE_UNKNOWN -103 //未知类型
  15 +#define SY_IMG_DATA_ERROR -104 //图像数据错误
  16 +#define SY_IMG_PARAMS_ERROR -105 //图像参数(宽 高 或者 通道数)有错误
  17 +#define SY_AUTHOR_ERROR -106 //授权失败
  18 +#define SY_VERSION_EXPIRED -107 //时间限制下的版本过期
  19 +#define SY_VIDEOFILEERROR -108 //视频打开失败
  20 +#define SY_BUFFNOTENOUGH -109 //缓冲区太小
  21 +
  22 +#define SY_MEAN_ERROR -110 //均值错误
  23 +#define SY_MODEL_IMG_PARAMS_ERROR -111 //
  24 +#define SY_NEW_MEM_ERROR -112 //内存申请失败
  25 +#define SY_GPUID_PARAM_ERROR -113 //gpu id param error
  26 +#define SY_CODEC_FORMAT_ERROR -114 //codec format error
  27 +#define SY_PARAMS_INVALID_ERROR -115 //参数值无效
  28 +#define SY_FEATURE_ERROR -116 //特征无效
  29 +//hisi img process error, added by jinxin
  30 +#define SY_IMG_RESIZE_ERROR -117 // image resize error
  31 +#define SY_IMG_CSC_ERROR -118 // image csc error
  32 +//------------------------------------------------------------------------//
  33 +
  34 +
  35 +//-----------------------------深度学习相关-------------------------------//
  36 +
  37 +//1.通用模块 预留编号:(-299) - (-200)
  38 +
  39 +//a. caffe部分 预留编号:(-239) - (-200)
  40 +#define SY_BATCH_SIZE_NO_EQUAL_INPUT -200 //BATCH_SIZE不匹配
  41 +#define SY_LAYER_NO_REGISTER -201 //层未注册
  42 +
  43 +//b. 网络和模型部分 预留编号:(-279) - (-240)
  44 +#define SY_PROTOFILE_MODEL_MISMATCH -240 //网络和模型不匹配
  45 +#define SY_PROTOFILEORVECTOR_NOTFOUND -241 //网络文件或者数组找不到
  46 +#define SY_PROTOFILE_NOTFOUND -242 //网络文件找不到
  47 +#define SY_PROTOVECTOR_NOTFOUND -243 //网络数组找不到
  48 +#define SY_MODELFILE_NOTFOUND -244 //模型文件找不到
  49 +#define SY_MODELLENGTH_ERROR -245 //模型数组长度错误
  50 +#define SY_MODELVECTOR_ERROR -246 //模型数组错误
  51 +// hisi added by jinxin
  52 +#define SY_MODEL_LOAD_ERROR -247 // load model failed
  53 +#define SY_MODELPARAMS_INIT_ERROR -248 // model params init failed
  54 +#define SY_MODELPARAMS_RELEASE_ERROR -249 // model params release failed
  55 +#define SY_MODEL_FORWARD_ERROR -250 // model forward failed
  56 +#define SY_MODEL_FORWARD_TIMEOUT -251 // model forward timeout
  57 +#define SY_MODEL_GETRESULT_ERROR -252 // model get results failed
  58 +
  59 +//c. 其他深度学习通用错误 预留编号:(-299) - (-280)
  60 +
  61 +//----------------------------------------//
  62 +
  63 +
  64 +//2.人脸模块 预留编号:(-349) - (-300)
  65 +
  66 +//a. 人脸检测错误返回 预留编号:(-319) - (-300)
  67 +#define SY_QUALITY_INIT_ERROR -300 //质量检测初始化失败
  68 +#define SY_ROTATIONCUT_INIT_ERROR -301 //切割旋转初始化失败
  69 +#define SY_FACERECG_INITFAILD_ERROR -302 //人脸识别初始化失败
  70 +#define SY_FACECUT_INITFAILD_ERROR -303 //人脸切割旋转初始化失败
  71 +#define SY_LDMK_INIT_ERROR -304 //关键点检测初始化失败
  72 +#define SY_FACEDETECT_INIT_ERROR -305 //人脸检测初始化失败
  73 +#define SY_POSE_INIT_ERROR -306 //人脸角度初始化失败
  74 +#define SY_SCORE_INIT_ERROR -307 //人脸置信度初始化失败
  75 +#define SY_DB_OPEN_DB_ERROR -308 //数据库打开失败(数据库错误)
  76 +#define SY_DB_OPEN_SYS_ERROR -309 //数据库打开失败(程序内部错误)
  77 +#define SY_DB_ADD_DATA_EXIST_ERROR -310 //数据库插入数据失败(已存在)
  78 +#define SY_DB_ADD_DATA_NOTFOUND -311 //数据库插入数据失败
  79 +#define SY_FACEATTRIBUTES_INITFAILD_ERROR -312 //人脸属性初始化失败
  80 +
  81 +
  82 +//c. 其他人脸模块错误 预留编号:(-349) - (-340)
  83 +
  84 +
  85 +//----------------------------------------//
  86 +
  87 +
  88 +//3.跟踪模块 预留编号:(-399) - (-350)
  89 +#define SY_TRACKER_INIT_ERROR -350 //轨迹跟踪初始化失败
  90 +
  91 +
  92 +//----------------------------------------//
  93 +
  94 +
  95 +//4.快照模块 预留编号:(-449) - (-400)
  96 +#define SY_SHAPSHOT_INIT_ERROR -400 //快照初始化失败
  97 +
  98 +
  99 +//----------------------------------------//
  100 +
  101 +
  102 +//5.流量统计模块 预留编号:(-499) - (-450)
  103 +#define SY_TRAFFICSTATISTICS_INIT_ERROR -450 //流量统计初始化失败
  104 +
  105 +//------------------------------------------------------------------------//
  106 +
  107 +
  108 +//-----------------------------授权部分相关-------------------------------//
  109 +
  110 +//1.授权通用模块 预留编号:(-600) - (-500)
  111 +#define SY_AUTHOR_TIMEEXPIRED_ERROR -500 //超出有效期
  112 +#define SY_AUTHOR_SERVER_ERROR -501 //服务器出错
  113 +#define SY_AUTHOR_NOAUTHORIZATION_ERROR -502 //未注册且没有装机剩余量
  114 +#define SY_AUTHOR_NOCOMMUNICATION_ERROR -503 //无法通信
  115 +#define SY_AUTHOR_NET_ERROR -504 //网络出错
  116 +#define SY_LICENCE_SERVICECHECK_ERROR -505 //服务检查未成功
  117 +#define SY_LICENCE_SERVICENOTRUNNING_ERROR -506 //服务未开启
  118 +#define SY_LICENCE_LICENCEDATA_ERROR -507 //授权文件数据错误
  119 +#define SY_LICENCE_LICENCEINVALID_ERROR -508 //授权文件无效
  120 +#define SY_LICENCE_LICENCENOTEXIST_ERROR -509 //授权文件不存在
  121 +
  122 +//------------------------------------------------------------------------//
  123 +
  124 +
  125 +//--------------------------------sdk相关---------------------------------//
  126 +
  127 +//1.视频结构化模块 预留编号:(-699) - (-600)
  128 +
  129 +
  130 +//a.二次属性错误返回 预留编号:(-649) - (-600)
  131 +
  132 +#define SY_HUMANPARSING_INIT_ERROR -600 //行人结构化初始化失败
  133 +#define SY_HUMANCARPARSING_INIT_ERROR -601 //人骑车结构化初始化失败
  134 +#define SY_VEHICLECOLOR_INIT_ERROR -602 //车颜色识别初始化失败
  135 +#define SY_VEHICLEPLATEDETECT_INIT_ERROR -603 //车牌检测初始化失败
  136 +#define SY_VEHICLEPLATERECOG_INIT_ERROR -604 //车牌识别初始化失败
  137 +#define SY_VEHICLERECOG_INIT_ERROR -605 //车型识别初始化失败
  138 +#define SY_VPT_DET_INIT_ERROR -606 //人车物检测初始化失败
  139 +#define SY_VEHICLE_FEA_INIT_ERROR -607 //车型特征初始化失败
  140 +//c.其他模块错误 预留编号:(-699) - (-650)
  141 +
  142 +//------------------------------------------------------------------------//
  143 +
  144 +//------------------------------rtsp--------------------------------------//
  145 +#define SY_STREAM_NOT_FIND_ERROR -700 //流获取失败
  146 +#define SY_STREAM_END_ERROR -701 //流异常结束
  147 +#define SY_STREAM_BLOCK_ERROR -702 //流发送阻塞
  148 +#define SY_STREAM_END -703 //流正常结束
  149 +#define SY_STREAM_MEMORYOUT_ERROR -704 //流内存不足
  150 +
  151 +
  152 +#endif // __SY_ERRORINFO_H__
src/common/utils.cpp 0 → 100644
  1 +#include "utils.h"
  2 +#include <map>
  3 +#include <iostream>
  4 +#include <fstream>
  5 +#include <unistd.h>
  6 +#include <cstring>
  7 +#include <dirent.h>
  8 +#include <vector>
  9 +#include <string.h>
  10 +#include <sys/stat.h>
  11 +#include <sys/types.h>
  12 +#include "sy_errorinfo.h"
  13 +#include "acl/acl.h"
  14 +#include "acl/ops/acl_dvpp.h"
  15 +#include <algorithm>
  16 +#include <math.h>
  17 +
  18 +using namespace std;
  19 +aclrtRunMode Utils::runMode_ = ACL_DEVICE;
  20 +
  21 +void* Utils::CopyDataHostToDvpp(void* data, int size) {
  22 + void* buffer = nullptr;
  23 + auto aclRet = acldvppMalloc(&buffer, size);
  24 + //debug====================================================
  25 + aclrtMemset(buffer,size, 0, size);
  26 + //debug end================================================
  27 + if (aclRet != ACL_SUCCESS) {
  28 + ERROR_LOG("acl malloc dvpp data failed, dataSize=%u, ret=%d",
  29 + size, aclRet);
  30 + return nullptr;
  31 + }
  32 + // INFO_LOG("malloc dvpp memory size %d ok", size);
  33 + // copy input to device memory
  34 + aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_HOST_TO_DEVICE);
  35 + if (aclRet != ACL_SUCCESS) {
  36 + ERROR_LOG("acl memcpy data to dvpp failed, size %u, error %d", size, aclRet);
  37 + acldvppFree(buffer);
  38 + return nullptr;
  39 + }
  40 + //INFO_LOG("copy data to dvpp ok");
  41 +
  42 + return buffer;
  43 +}
  44 +
  45 +void* Utils::CopyDataDeviceToDvpp(void* data, int size) {
  46 + void* buffer = nullptr;
  47 + auto aclRet = acldvppMalloc(&buffer, size);
  48 + //debug====================================================
  49 + aclrtMemset(buffer,size, 0, size);
  50 + //debug end================================================
  51 + if (aclRet != ACL_SUCCESS) {
  52 + ERROR_LOG("acl malloc dvpp data failed, dataSize=%u, ret=%d",
  53 + size, aclRet);
  54 + return nullptr;
  55 + }
  56 + // INFO_LOG("malloc dvpp memory size %d ok", size);
  57 + // copy input to device memory
  58 + aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_DEVICE_TO_DEVICE);
  59 + if (aclRet != ACL_SUCCESS) {
  60 + ERROR_LOG("acl memcpy data to dvpp failed, size %u, error %d", size, aclRet);
  61 + acldvppFree(buffer);
  62 + return nullptr;
  63 + }
  64 + //INFO_LOG("copy data to dvpp ok");
  65 +
  66 + return buffer;
  67 +}
  68 +
  69 +
  70 +int Utils::CopysyImageDataToDvpp(ImageData& imageDevice, sy_img srcImage) {
  71 + aclError ret = aclrtGetRunMode(&runMode_);
  72 + if (ret != ACL_SUCCESS) {
  73 + ERROR_LOG("acl get run mode failed");
  74 + return SY_FAILED;
  75 + }
  76 +
  77 + void* buffer = nullptr;
  78 + //230316 ascend310p兼容=================================================
  79 + uint32_t alignWidth = 0, alignHeight = 0;
  80 + auto socVersion = aclrtGetSocName();
  81 + if (strncmp(socVersion, "Ascend310P3", sizeof("Ascend310P3") - 1) == 0) {
  82 + alignWidth = ALIGN_UP64(srcImage.w_); // 64-byte alignment
  83 + alignHeight = ALIGN_UP16(srcImage.h_); // 16-byte alignment
  84 + } else {
  85 + alignWidth = ALIGN_UP128(srcImage.w_); // 128-byte alignment
  86 + alignHeight = ALIGN_UP16(srcImage.h_); // 16-byte alignment
  87 + }
  88 + if (alignWidth == 0 || alignHeight == 0) {
  89 + ERROR_LOG("Input image width %d or height %d invalid",srcImage.w_, srcImage.h_);
  90 + return SY_FAILED;
  91 + }
  92 + //=====================================================================
  93 + uint32_t size = YUV420SP_SIZE(alignWidth, alignHeight);
  94 + // cout << srcImage.w_ << " " << srcImage.h_ << " "<< alignWidth << " "<< alignHeight << " " << size << endl;
  95 + if (runMode_ == ACL_HOST){
  96 + // printf("1111111111\n");
  97 + buffer = Utils::CopyDataHostToDvpp(srcImage.data_, size);
  98 + if (buffer == nullptr) {
  99 + ERROR_LOG("Copy image to device failed");
  100 + return SY_FAILED;
  101 + }
  102 + }
  103 + else{
  104 + // printf("2222222222\n");
  105 + buffer = Utils::CopyDataDeviceToDvpp(srcImage.data_, size);
  106 + if (buffer == nullptr) {
  107 + ERROR_LOG("Copy image to device failed");
  108 + return SY_FAILED;
  109 + }
  110 + }
  111 +
  112 + imageDevice.width = srcImage.w_;
  113 + imageDevice.height = srcImage.h_;
  114 + imageDevice.alignWidth = alignWidth;
  115 + imageDevice.alignHeight = alignHeight;
  116 + imageDevice.size = size;
  117 + imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { acldvppFree((void *)p); });
  118 +
  119 + return SY_SUCCESS;
  120 +}
  121 +
  122 +int Utils::CopyImageDataToDvpp(ImageData& imageDevice, ImageData srcImage) {
  123 + aclError ret = aclrtGetRunMode(&runMode_);
  124 + if (ret != ACL_SUCCESS) {
  125 + ERROR_LOG("acl get run mode failed");
  126 + return SY_FAILED;
  127 + }
  128 +
  129 + void* buffer = nullptr;
  130 + if (runMode_ == ACL_HOST){
  131 + buffer = Utils::CopyDataHostToDvpp(srcImage.data.get(), srcImage.size);
  132 + if (buffer == nullptr) {
  133 + ERROR_LOG("Copy image to device failed");
  134 + return SY_FAILED;
  135 + }
  136 + }
  137 + else{
  138 + buffer = Utils::CopyDataDeviceToDvpp(srcImage.data.get(), srcImage.size);
  139 + if (buffer == nullptr) {
  140 + ERROR_LOG("Copy image to device failed");
  141 + return SY_FAILED;
  142 + }
  143 + }
  144 +
  145 + imageDevice.width = srcImage.width;
  146 + imageDevice.height = srcImage.height;
  147 + imageDevice.size = srcImage.size;
  148 + imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { acldvppFree((void *)p); });
  149 + return SY_SUCCESS;
  150 +}
  151 +
  152 +void* Utils::CopyDataDeviceToLocal(void* deviceData, uint32_t dataSize) {
  153 + uint8_t* buffer = new uint8_t[dataSize];
  154 + if (buffer == nullptr) {
  155 + ERROR_LOG("New malloc memory failed");
  156 + return nullptr;
  157 + }
  158 +
  159 + aclError aclRet = aclrtMemcpy(buffer, dataSize, deviceData, dataSize, ACL_MEMCPY_DEVICE_TO_HOST);
  160 + if (aclRet != ACL_SUCCESS) {
  161 + ERROR_LOG("Copy device data to local failed, aclRet is %d", aclRet);
  162 + delete[](buffer);
  163 + return nullptr;
  164 + }
  165 +
  166 + return (void*)buffer;
  167 +}
  168 +
  169 +void* Utils::CopyDataToDevice(void* data, uint32_t dataSize, aclrtMemcpyKind policy) {
  170 + void* buffer = nullptr;
  171 + aclError aclRet = aclrtMalloc(&buffer, dataSize, ACL_MEM_MALLOC_HUGE_FIRST);
  172 + if (aclRet != ACL_SUCCESS) {
  173 + ERROR_LOG("malloc device data buffer failed, aclRet is %d", aclRet);
  174 + return nullptr;
  175 + }
  176 +
  177 + aclRet = aclrtMemcpy(buffer, dataSize, data, dataSize, policy);
  178 + if (aclRet != ACL_SUCCESS) {
  179 + ERROR_LOG("Copy data to device failed, aclRet is %d", aclRet);
  180 + (void)aclrtFree(buffer);
  181 + return nullptr;
  182 + }
  183 +
  184 + return buffer;
  185 +}
  186 +
  187 +void* Utils::CopyDataDeviceToDevice(void* deviceData, uint32_t dataSize) {
  188 + return CopyDataToDevice(deviceData, dataSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
  189 +}
  190 +
  191 +void* Utils::CopyDataHostToDevice(void* deviceData, uint32_t dataSize) {
  192 + return CopyDataToDevice(deviceData, dataSize, ACL_MEMCPY_HOST_TO_DEVICE);
  193 +}
  194 +
  195 +int Utils::CopyImageDataToDevice(ImageData& imageDevice, ImageData srcImage, aclrtRunMode mode) {
  196 + void * buffer;
  197 + if (mode == ACL_HOST)
  198 + buffer = Utils::CopyDataHostToDevice(srcImage.data.get(), srcImage.size);
  199 + else
  200 + buffer = Utils::CopyDataDeviceToDevice(srcImage.data.get(), srcImage.size);
  201 +
  202 + if (buffer == nullptr) {
  203 + ERROR_LOG("Copy image to device failed");
  204 + return SY_FAILED;
  205 + }
  206 +
  207 + imageDevice.width = srcImage.width;
  208 + imageDevice.height = srcImage.height;
  209 + imageDevice.size = srcImage.size;
  210 + imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { aclrtFree((void *)p); });
  211 +
  212 + return SY_SUCCESS;
  213 +}
  214 +
  215 +
  216 +int Utils::ReadImageFile(ImageData& image, std::string fileName) {
  217 + struct stat sBuf;
  218 + int fileStatus = stat(fileName.data(), &sBuf);
  219 + if (fileStatus == -1) {
  220 + ERROR_LOG("failed to get file");
  221 + return SY_FAILED;
  222 + }
  223 + if (S_ISREG(sBuf.st_mode) == 0) {
  224 + ERROR_LOG("%s is not a file, please enter a file", fileName.c_str());
  225 + return SY_FAILED;
  226 + }
  227 + std::ifstream binFile(fileName, std::ifstream::binary);
  228 + if (binFile.is_open() == false) {
  229 + ERROR_LOG("open file %s failed", fileName.c_str());
  230 + return SY_FAILED;
  231 + }
  232 +
  233 + binFile.seekg(0, binFile.end);
  234 + uint32_t binFileBufferLen = binFile.tellg();
  235 + if (binFileBufferLen == 0) {
  236 + ERROR_LOG("binfile is empty, filename is %s", fileName.c_str());
  237 + binFile.close();
  238 + return SY_FAILED;
  239 + }
  240 +
  241 + binFile.seekg(0, binFile.beg);
  242 +
  243 + uint8_t* binFileBufferData = new(std::nothrow) uint8_t[binFileBufferLen];
  244 + if (binFileBufferData == nullptr) {
  245 + ERROR_LOG("malloc binFileBufferData failed");
  246 + binFile.close();
  247 + return SY_FAILED;
  248 + }
  249 + binFile.read((char *)binFileBufferData, binFileBufferLen);
  250 + binFile.close();
  251 +
  252 + int32_t ch = 0;
  253 + acldvppJpegGetImageInfo(binFileBufferData, binFileBufferLen,
  254 + &(image.width), &(image.height), &ch);
  255 + image.data.reset(binFileBufferData, [](uint8_t* p) { delete[](p); });
  256 + image.size = binFileBufferLen;
  257 +
  258 + return SY_SUCCESS;
  259 +}
  260 +
  261 +
  262 +float Utils::sigmoid(float val){
  263 + return 1.0/(1.0+exp(-val));
  264 +}
  265 +
  266 +
  267 +// double Power(double base, int n) {
  268 +// double res = 1,curr = base;
  269 +// int exponent;
  270 +// if(n>0){
  271 +// exponent = n;
  272 +// }else if(n==0){
  273 +// return 1;
  274 +// }else{
  275 +// exponent = -n;
  276 +// }
  277 +// while(exponent!=0){
  278 +// if((exponent&1)==1)
  279 +// res*=curr;
  280 +// curr*=curr;// 翻倍
  281 +// exponent>>=1;// 右移一位
  282 +// }
  283 +// return n>=0?res:(1/res);
  284 +// }
  285 +
  286 +
  287 +// float Utils::sigmoid1(float val){
  288 +// return 1.0/(1.0+Power(exp(1.),-val));
  289 +// }
  290 +
  291 +float FastExp(float x) {
  292 + float d;
  293 + //将尾数后32位抹零
  294 + *(reinterpret_cast<short*>(&d) + 0) = 0;
  295 + //计算指数位
  296 + *(reinterpret_cast<short*>(&d) + 1) = static_cast<short>(184 * x + (16256-7));
  297 + return d;
  298 +}
  299 +
  300 +float Utils::FastSigmoid(float x) {
  301 + // float x_ = x / 4096.; //int32
  302 + float x_ = x;
  303 + return 1. / (FastExp(0 - x_) + 1.);
  304 +}
  305 +
  306 +
src/common/utils.h 0 → 100644
  1 +#ifndef _UTILS_H_
  2 +#define _UTILS_H_
  3 +
  4 +#include <iostream>
  5 +#include <fstream>
  6 +#include <vector>
  7 +#include "acl/acl.h"
  8 +#include "stream_data.h"
  9 +#include "sy_common.h"
  10 +
  11 +// #include "opencv2/opencv.hpp"
  12 +// #include "opencv2/imgcodecs/legacy/constants_c.h"
  13 +// #include "opencv2/imgproc/types_c.h"
  14 +
  15 +using namespace std;
  16 +
  17 +#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
  18 +#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
  19 +#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
  20 +
  21 +#define RGBU8_IMAGE_SIZE(width, height) ((width) * (height) * 3)
  22 +#define YUV420SP_SIZE(width, height) ((width) * (height) * 3 / 2)
  23 +
  24 +#define ALIGN_UP(num, align) (((num) + (align) - 1) & ~((align) - 1))
  25 +#define ALIGN_UP2(num) ALIGN_UP(num, 2)
  26 +#define ALIGN_UP16(num) ALIGN_UP(num, 16)
  27 +#define ALIGN_UP64(num) ALIGN_UP(num, 64) //230316added
  28 +#define ALIGN_UP128(num) ALIGN_UP(num, 128)
  29 +
  30 +#define SHARED_PRT_DVPP_BUF(buf) (shared_ptr<uint8_t>((uint8_t *)(buf), [](uint8_t* p) { acldvppFree(p); }))
  31 +#define SHARED_PRT_U8_BUF(buf) (shared_ptr<uint8_t>((uint8_t *)(buf), [](uint8_t* p) { delete[](p); }))
  32 +
  33 +#define ACL_CALL(ret, expect, errCode)\
  34 + do {\
  35 + if (ret != expect) {\
  36 + if (errCode == 0)\
  37 + return ret;\
  38 + else\
  39 + return errCode;\
  40 + }\
  41 + } while(0)
  42 +
  43 +template<class Type>
  44 +std::shared_ptr<Type> MakeSharedNoThrow() {
  45 + try {
  46 + return std::make_shared<Type>();
  47 + }
  48 + catch (...) {
  49 + return nullptr;
  50 + }
  51 +}
  52 +
  53 +#define MAKE_SHARED_NO_THROW(memory, memory_type) \
  54 + do { \
  55 + memory = MakeSharedNoThrow<memory_type>(); \
  56 + }while(0);
  57 +
  58 +struct Resolution {
  59 + uint32_t width = 0;
  60 + uint32_t height = 0;
  61 +};
  62 +
  63 +/**
  64 + * Utils
  65 + */
  66 +class Utils {
  67 +public:
  68 + static aclrtRunMode runMode_;
  69 +
  70 + static void* CopyDataToDevice(void* data, uint32_t dataSize, aclrtMemcpyKind policy);
  71 + static void* CopyDataDeviceToLocal(void* deviceData, uint32_t dataSize);
  72 + static void* CopyDataHostToDevice(void* deviceData, uint32_t dataSize);
  73 + static void* CopyDataDeviceToDevice(void* deviceData, uint32_t dataSize);
  74 + static int ReadImageFile(ImageData& image, std::string fileName);
  75 + static int CopyImageDataToDevice(ImageData& imageDevice, ImageData srcImage, aclrtRunMode mode);
  76 + static int CopyImageDataToDvpp(ImageData& imageDevice, ImageData srcImage);
  77 + static int CopysyImageDataToDvpp(ImageData& imageDevice, sy_img srcImage);
  78 + static void* CopyDataHostToDvpp(void* data, int size);
  79 + static bool CreateFolder(std::string folderPath, mode_t mode = 0700);
  80 + static bool WriteImage(unsigned char* data, int32_t size, const char* filename);
  81 + static void* CopyDataDeviceToDvpp(void* data, int size);
  82 + // static float sigmoid1(float val);
  83 + static float sigmoid(float val);
  84 + static float FastSigmoid(float x);
  85 +};
  86 +
  87 +
  88 +#endif
0 \ No newline at end of file 89 \ No newline at end of file
src/decoder/dvpp/CircularQueue.hpp 0 → 100644
  1 +#ifndef __CIRCULAR_QUEUE_HPP__
  2 +#define __CIRCULAR_QUEUE_HPP__
  3 +
  4 +#include <iostream>
  5 +#include <atomic>
  6 +#include <vector>
  7 +#include <mutex>
  8 +
  9 +using namespace std;
  10 +
  11 +
  12 +// 循环队列
  13 +template <typename T>
  14 +class CircularQueue
  15 +{
  16 +private:
  17 + /* data */
  18 +public:
  19 + CircularQueue();
  20 + ~CircularQueue();
  21 +
  22 + bool init(vector<T> data);
  23 + T getTail();
  24 + void addTail();
  25 + T deQueue();
  26 + T getHead();
  27 + void addHead();
  28 + void clearQueue();
  29 +
  30 + int length();
  31 + bool isEmpty();
  32 +
  33 +private:
  34 + vector<T> base;
  35 + atomic<int> front;
  36 + atomic<int> rear;
  37 + mutex m_mutex;
  38 + int max_size;
  39 +};
  40 +
  41 +
  42 +template <typename T>
  43 +CircularQueue<T>::CircularQueue()
  44 +{
  45 + front = rear = 0;//头指针和尾指针置为零,队列为空
  46 +}
  47 +
  48 +template <typename T>
  49 +CircularQueue<T>::~CircularQueue()
  50 +{
  51 + base.clear();
  52 + rear = front = 0;
  53 +}
  54 +
  55 +template <typename T>
  56 +bool CircularQueue<T>::init(vector<T> data){
  57 + base = data;
  58 + front = rear = 0;//头指针和尾指针置为零,队列为空
  59 + max_size = data.size();
  60 +
  61 + return true;
  62 +}
  63 +
  64 +//循环队列的入队
  65 +template <typename T>
  66 +T CircularQueue<T>::getTail()
  67 +{
  68 + std::lock_guard<std::mutex> l(m_mutex);
  69 + //插入一个元素e为Q的新的队尾元素
  70 + if ((rear + 1) % max_size == front)
  71 + return nullptr;//队满
  72 + return base[rear];//获取队尾元素
  73 +}
  74 +
  75 +// 将队尾元素添加到队列中
  76 +template <typename T>
  77 +void CircularQueue<T>::addTail()
  78 +{
  79 + std::lock_guard<std::mutex> l(m_mutex);
  80 + rear = (rear + 1) % max_size;//队尾指针加1
  81 +}
  82 +
  83 +//循环队列的出队
  84 +template <typename T>
  85 +T CircularQueue<T>::deQueue()
  86 +{
  87 + std::lock_guard<std::mutex> l(m_mutex);
  88 + //删除Q的队头元素,用e返回其值
  89 + if (front == rear)
  90 + return nullptr;//队空
  91 + T e = base[front];//保存队头元素
  92 + front = (front + 1) % max_size;//队头指针加1
  93 + return e;
  94 +}
  95 +
  96 +//取循环队列的队头元素
  97 +template <typename T>
  98 +T CircularQueue<T>::getHead()
  99 +{
  100 + std::lock_guard<std::mutex> l(m_mutex);
  101 + //返回Q的队头元素,不修改队头指针
  102 + if (front == rear)
  103 + return nullptr;//队列为空,取元素失败
  104 + return base[front];
  105 +}
  106 +
  107 +template <typename T>
  108 +void CircularQueue<T>::addHead()
  109 +{
  110 + std::lock_guard<std::mutex> l(m_mutex);
  111 + front = (front + 1) % max_size;//队头指针加1
  112 +}
  113 +
  114 +template <typename T>
  115 +int CircularQueue<T>::length()
  116 +{
  117 + std::lock_guard<std::mutex> l(m_mutex);
  118 + return (rear - front + max_size) % max_size;
  119 +}
  120 +
  121 +template <typename T>
  122 +bool CircularQueue<T>::isEmpty()
  123 +{
  124 + std::lock_guard<std::mutex> l(m_mutex);
  125 + if (front == rear)
  126 + return true;
  127 +
  128 + return false;
  129 +}
  130 +
  131 +template <typename T>
  132 +void CircularQueue<T>::clearQueue()
  133 +{
  134 + std::lock_guard<std::mutex> l(m_mutex);
  135 + rear = front = 0;
  136 +}
  137 +
  138 +#endif
0 \ No newline at end of file 139 \ No newline at end of file
src/decoder/dvpp/DvppDataMemory.hpp 0 → 100644
  1 +#include<string>
  2 +
  3 +#include "dvpp_headers.h"
  4 +
  5 +using namespace std;
  6 +
  7 +class DvppDataMemory : public DeviceMemory
  8 +{
  9 +public:
  10 + DvppDataMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame)
  11 + :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){
  12 + data_size = _size;
  13 + int ret = acldvppMalloc((void **)&pHwRgb, data_size);
  14 + if(ret != ACL_ERROR_NONE){
  15 + cout << "acldvppMalloc failed" << endl;
  16 + }
  17 + }
  18 +
  19 + DvppDataMemory( int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned char * pHwData)
  20 + :DeviceMemory(3, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){
  21 + data_size = _size;
  22 + data_type = 1;
  23 + pHwRgb = pHwData;
  24 + }
  25 +
  26 + ~DvppDataMemory(){
  27 + if (pHwRgb) {
  28 + int ret = acldvppFree((uint8_t*)pHwRgb);
  29 + if(ret != ACL_ERROR_NONE){
  30 + cout << "acldvppFree failed" << endl;
  31 + }
  32 + pHwRgb = nullptr;
  33 + }
  34 + }
  35 +
  36 +public:
  37 + int data_type; // 0: rgb , 1: NV12
  38 +};
0 \ No newline at end of file 39 \ No newline at end of file
src/decoder/dvpp/DvppDec.cpp 0 → 100644
  1 +#include "DvppDec.h"
  2 +#include "DvppSourceManager.h"
  3 +
  4 +#include "../../util/vpc_util.h"
  5 +
  6 +struct Vdec_CallBack_UserData {
  7 + uint64_t frameId;
  8 + long startTime;
  9 + long sendTime;
  10 + // void* vdecOutputBuf;
  11 + DvppDec* self;
  12 + shared_ptr<MemNode> inBufNode;
  13 + Vdec_CallBack_UserData() {
  14 + frameId = 0;
  15 + }
  16 +};
  17 +
  18 +static const int g_pkt_size = 1024 * 1024;
  19 +
  20 + DvppDec::DvppDec(){
  21 + m_decode_thread = 0;
  22 + }
  23 +
  24 + DvppDec::~DvppDec(){
  25 + releaseResource();
  26 + }
  27 +
  28 + bool DvppDec::init_vdpp(DvppDecConfig cfg){
  29 +
  30 + m_dec_name = cfg.dec_name;
  31 +
  32 + LOG_INFO("[{}]- Init device start...", m_dec_name);
  33 +
  34 + m_dvpp_deviceId = atoi(cfg.dev_id.c_str());
  35 +
  36 + if(cfg.codec_id == 0){
  37 + // 66:Baseline,77:Main,>=100:High
  38 + if(cfg.profile == 77){
  39 + enType = H264_MAIN_LEVEL;
  40 + }else if(cfg.profile < 77){
  41 + enType = H264_BASELINE_LEVEL;
  42 + }else{
  43 + enType = H264_HIGH_LEVEL;
  44 + }
  45 + }else if(cfg.codec_id == 1){
  46 + // h265只有main
  47 + enType = H265_MAIN_LEVEL;
  48 + }else {
  49 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
  50 + return false;
  51 + }
  52 +
  53 + post_decoded_cbk = cfg.post_decoded_cbk;
  54 + m_pktQueueptr = cfg.pktQueueptr;
  55 +
  56 + // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
  57 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  58 + m_context = pSrcMgr->getContext(m_dvpp_deviceId);
  59 + m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
  60 + if(m_dvpp_channel < 0){
  61 + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
  62 + return false;
  63 + }
  64 +
  65 + do
  66 + {
  67 + CHECK_AND_BREAK(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed !");
  68 +
  69 + int ret = 0;
  70 + // int ret = picConverter.init(m_context, m_dec_name);
  71 + // if(ret != ACL_ERROR_NONE){
  72 + // LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  73 + // break;
  74 + // }
  75 +
  76 + // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死
  77 + for (size_t i = 0; i < 20; i++){
  78 + void *vdecInputbuf = nullptr;
  79 + ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  80 + if(ret != ACL_ERROR_NONE){
  81 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  82 + // 析构函数中有对channel 的补救性释放,所以这里可以直接return
  83 + return false;;
  84 + }
  85 + m_vec_vdec.push_back(vdecInputbuf);
  86 + }
  87 +
  88 + if(!m_vdecQueue.init(m_vec_vdec)){
  89 + break;
  90 + }
  91 +
  92 + m_vdec_out_size = cfg.width * cfg.height * 3 / 2;
  93 +
  94 + LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
  95 + return true;
  96 +
  97 + } while (0);
  98 +
  99 + LOG_INFO("[{}]- init vdpp failed!", m_dec_name);
  100 + // 初始化失败,释放channel
  101 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  102 + return false;
  103 +}
  104 +
  105 +bool DvppDec::start(){
  106 + m_bRunning = true;
  107 +
  108 + pthread_create(&m_decode_thread,0,
  109 + [](void* arg)
  110 + {
  111 + DvppDec* a=(DvppDec*)arg;
  112 + a->decode_thread();
  113 + return (void*)0;
  114 + }
  115 + ,this);
  116 +
  117 + return true;
  118 +}
  119 +
  120 +static void *ReportThd(void *arg)
  121 +{
  122 + DvppDec *self = (DvppDec *)arg;
  123 + if(nullptr != self){
  124 + self->doProcessReport();
  125 + }
  126 + return (void *)0;
  127 +}
  128 +
  129 +void DvppDec::doProcessReport(){
  130 +
  131 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
  132 + if(ret != ACL_ERROR_NONE){
  133 + // cout << "aclrtSetDevice failed" << endl;
  134 + LOG_ERROR("aclrtSetDevice failed !");
  135 + return ;
  136 + }
  137 +
  138 + aclrtContext ctx;
  139 + ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  140 + if (ret != ACL_ERROR_NONE) {
  141 + // cout << "aclrtCreateContext failed " << endl;
  142 + LOG_ERROR("aclrtCreateContext failed !");
  143 + return ;
  144 + }
  145 +
  146 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");
  147 + // 阻塞等待vdec线程开始
  148 +
  149 + while (!m_bExitReportThd) {
  150 + aclrtProcessReport(1000);
  151 + }
  152 +
  153 + ret = aclrtDestroyContext(ctx);
  154 + if(ret != ACL_ERROR_NONE){
  155 + LOG_ERROR("aclrtDestroyContext failed !");
  156 + }
  157 + LOG_INFO("doProcessReport exit.");
  158 +}
  159 +
  160 +static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
  161 +{
  162 + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
  163 + if(nullptr != userData){
  164 + DvppDec* self = userData->self;
  165 + if(self != nullptr){
  166 +
  167 + self->doVdppVdecCallBack(input, output);
  168 + }
  169 + delete userData;
  170 + userData = nullptr;
  171 + }
  172 +}
  173 +
  174 +void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){
  175 +
  176 + // dvpp_crop(output);
  177 +
  178 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  179 +
  180 + void *inputDataDev = acldvppGetStreamDescData(input);
  181 + void *outputDataDev = acldvppGetPicDescData(output);
  182 + uint32_t outputSize = acldvppGetPicDescSize(output);
  183 + uint32_t width = acldvppGetPicDescWidth(output);
  184 + uint32_t width_stride = acldvppGetPicDescWidthStride(output);
  185 + uint32_t height = acldvppGetPicDescHeight(output);
  186 + uint32_t height_stride = acldvppGetPicDescHeightStride(output);
  187 +
  188 + DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, (unsigned char *)outputDataDev);
  189 + post_decoded_cbk(m_postDecArg, mem);
  190 +
  191 +// DvppDataMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
  192 +// if(rgbMem != nullptr){
  193 +// #ifdef TEST_DECODER
  194 +// // D2H
  195 +// if(vdecHostAddr == nullptr){
  196 +// CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");
  197 +// }
  198 +// uint32_t data_size = rgbMem->getSize();
  199 +// CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
  200 +
  201 +// // 保存vdec结果
  202 +// if(count_frame > 45 && count_frame < 50)
  203 +// {
  204 +// string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;
  205 +// FILE *outputFile = fopen(file_name.c_str(), "a");
  206 +// if(outputFile){
  207 +// fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
  208 +// fclose(outputFile);
  209 +// }
  210 +// }
  211 +// else if(count_frame > 50 && vdecHostAddr != nullptr){
  212 +// CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
  213 +// vdecHostAddr = nullptr;
  214 +// }
  215 +// count_frame++;
  216 +// #endif
  217 +// post_decoded_cbk(m_postDecArg, rgbMem);
  218 +// }else{
  219 +// LOG_ERROR("[{}]- convert2bgr failed !", m_dec_name);
  220 +// }
  221 +
  222 +// acldvppFree(outputDataDev);
  223 +// outputDataDev = nullptr;
  224 +
  225 + m_vdecQueue.addHead();
  226 +
  227 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  228 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  229 +}
  230 +
  231 +void DvppDec::close(){
  232 + m_bRunning=false;
  233 +
  234 + if(m_decode_thread != 0){
  235 + pthread_join(m_decode_thread,0);
  236 + }
  237 +}
  238 +
  239 +bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
  240 + // create stream desc
  241 + acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
  242 + if (streamInputDesc == nullptr) {
  243 + LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
  244 + return false;
  245 + }
  246 + aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
  247 + if (ret != ACL_SUCCESS) {
  248 + LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
  249 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  250 + return false;
  251 + }
  252 +
  253 + // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
  254 + LOG_INFO("[{}]- send eos", m_dec_name);
  255 + ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
  256 + if (ret != ACL_SUCCESS) {
  257 + LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
  258 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  259 + return false;
  260 + }
  261 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  262 +
  263 + return true;
  264 +}
  265 +
  266 +void DvppDec::releaseResource(){
  267 + for(int i = 0; i < m_vec_vdec.size(); i++){
  268 + if(m_vec_vdec[i] != nullptr){
  269 + acldvppFree(m_vec_vdec[i]);
  270 + m_vec_vdec[i] = nullptr;
  271 + }
  272 + }
  273 + m_vec_vdec.clear();
  274 +
  275 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  276 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  277 +}
  278 +
  279 +void DvppDec::decode_thread(){
  280 +
  281 + long startTime = UtilTools::get_cur_time_ms();
  282 +
  283 + int ret = -1;
  284 +
  285 + // // dvpp解码参数
  286 + // CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  287 +
  288 + m_bExitReportThd = false;
  289 + pthread_t report_thread;
  290 + ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
  291 + if(ret != 0){
  292 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
  293 + return;
  294 + }
  295 +
  296 + aclrtSetDevice(m_dvpp_deviceId);
  297 + aclrtContext ctx;
  298 + ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  299 + if (ret != ACL_ERROR_NONE) {
  300 + // cout << "aclrtCreateContext failed " << endl;
  301 + LOG_ERROR("aclrtCreateContext failed !");
  302 + return ;
  303 + }
  304 +
  305 + // 创建aclvdecChannelDesc类型的数据
  306 + aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
  307 + if (vdecChannelDesc == nullptr) {
  308 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
  309 + return;
  310 + }
  311 + do{
  312 + // 创建 channel dec结构体
  313 + // 通道ID在dvpp层面为0~31
  314 + CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
  315 + CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
  316 + CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
  317 + CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");
  318 + CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
  319 + CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
  320 +
  321 + uint64_t frame_count = 0;
  322 + bool bBreak = false;
  323 + while (m_bRunning)
  324 + {
  325 + if (m_bPause){
  326 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  327 + continue;
  328 + }
  329 + int ret = sentFrame(vdecChannelDesc, frame_count);
  330 + if(ret == 2){
  331 + break;
  332 + bBreak = true;
  333 + }else if(ret == 1){
  334 + continue;
  335 + }
  336 +
  337 + frame_count++;
  338 + }
  339 +
  340 + // 尽量保证数据全部解码完成
  341 + int sum = 0;
  342 + if(!bBreak){
  343 + aclrtSetDevice(m_dvpp_deviceId);
  344 + aclrtSetCurrentContext(ctx);
  345 + while(!m_pktQueueptr->isEmpty()){
  346 + int ret = sentFrame(vdecChannelDesc, frame_count);
  347 + if(ret == 2){
  348 + break;
  349 + }
  350 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  351 + sum++;
  352 + if(sum > 40){
  353 + // 避免卡死
  354 + break;
  355 + }
  356 + }
  357 + }
  358 +
  359 + sendVdecEos(vdecChannelDesc);
  360 +
  361 + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
  362 + }while(0);
  363 +
  364 + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
  365 +
  366 + // report_thread 需后于destroy退出
  367 + m_bRunning = false;
  368 + m_bExitReportThd = true;
  369 + CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");
  370 +
  371 + releaseResource();
  372 + LOG_INFO("[{}]- decode thread exit.", m_dec_name);
  373 +}
  374 +
  375 +int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
  376 +
  377 + AVPacket * pkt = m_pktQueueptr->getHead();
  378 + if(pkt == nullptr){
  379 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  380 + return 1;
  381 + }
  382 + // 解码
  383 + void *vdecInputbuf = m_vdecQueue.getTail();
  384 + if(vdecInputbuf == nullptr){
  385 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  386 + return 1;
  387 + }
  388 +
  389 + int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
  390 + if(ACL_ERROR_NONE != ret){
  391 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
  392 + return 2;
  393 + }
  394 +
  395 + void *vdecOutputBuf = nullptr;
  396 + ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
  397 + if(ret != ACL_ERROR_NONE){
  398 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
  399 + return 2;
  400 + }
  401 +
  402 + acldvppStreamDesc *input_stream_desc = nullptr;
  403 + acldvppPicDesc *output_pic_desc = nullptr;
  404 + do{
  405 + input_stream_desc = acldvppCreateStreamDesc();
  406 + if (input_stream_desc == nullptr) {
  407 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  408 + break;
  409 + }
  410 + output_pic_desc = acldvppCreatePicDesc();
  411 + if (output_pic_desc == nullptr) {
  412 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  413 + break;
  414 + }
  415 + CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
  416 + CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
  417 + CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
  418 + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
  419 +
  420 + Vdec_CallBack_UserData *user_data = NULL;
  421 + user_data = new Vdec_CallBack_UserData;
  422 + user_data->frameId = frame_count;
  423 + // user_data->startTime = startTime;
  424 + user_data->sendTime = UtilTools::get_cur_time_ms();
  425 + user_data->self = this;
  426 + ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  427 + av_packet_unref(pkt);
  428 + m_pktQueueptr->addHead();
  429 + if(ret != ACL_ERROR_NONE){
  430 + delete user_data;
  431 + user_data = nullptr;
  432 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
  433 + break;
  434 + }
  435 +
  436 + m_vdecQueue.addTail();
  437 +
  438 + return 0;
  439 + }while (0);
  440 +
  441 + // 报错情形
  442 + if(input_stream_desc){
  443 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
  444 + }
  445 + if(output_pic_desc){
  446 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
  447 + }
  448 +
  449 + acldvppFree(vdecOutputBuf);
  450 + vdecOutputBuf = nullptr;
  451 +
  452 + return 1;
  453 +}
  454 +
  455 +
  456 +void DvppDec::setPostDecArg(const void* postDecArg){
  457 + m_postDecArg = postDecArg;
  458 +}
  459 +
  460 +void DvppDec::pause(){
  461 + m_bPause = true;
  462 +}
  463 +
  464 +void DvppDec::resume(){
  465 + m_bPause = false;
  466 +}
0 \ No newline at end of file 467 \ No newline at end of file
src/decoder/dvpp/DvppDec.h 0 → 100644
  1 +#include<string>
  2 +#include <pthread.h>
  3 +
  4 +#include "dvpp_headers.h"
  5 +#include "depend_headers.h"
  6 +#include "user_mem.h"
  7 +#include "CircularQueue.hpp"
  8 +#include "VpcPicConverter.h"
  9 +#include "FFReceiver.h"
  10 +
  11 +#include <queue>
  12 +
  13 +using namespace std;
  14 +
  15 +#define TEST_DECODER
  16 +
  17 +struct DvppDecConfig{
  18 + string dec_name;
  19 + POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
  20 + string dev_id; // gpu id
  21 + bool force_tcp{true}; // 是否指定使用tcp连接
  22 + int skip_frame{1}; // 跳帧数
  23 + int codec_id; // 0 : h264 1:h265
  24 + int profile;
  25 + CircularQueue<AVPacket*> *pktQueueptr;
  26 +
  27 + int width;
  28 + int height;
  29 +};
  30 +
  31 +
  32 +class DvppDec {
  33 +public:
  34 + DvppDec();
  35 + ~DvppDec();
  36 + bool init_vdpp(DvppDecConfig cfg);
  37 + void setPostDecArg(const void* postDecArg);
  38 + bool start();
  39 + void close();
  40 + void pause();
  41 + void resume();
  42 +
  43 +public:
  44 + void doProcessReport();
  45 + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output);
  46 +
  47 +private:
  48 + void decode_thread();
  49 + void releaseResource();
  50 + bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
  51 + int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count);
  52 +
  53 +private:
  54 +
  55 + bool m_bRunning{false};
  56 + bool m_bPause{false};
  57 + bool m_bExitReportThd{false};
  58 +
  59 + int m_dvpp_deviceId {-1};
  60 + int m_dvpp_channel {-1};
  61 + aclrtContext m_context;
  62 + acldvppStreamFormat enType;
  63 +
  64 + pthread_t m_decode_thread;
  65 +
  66 + DvppDecConfig m_cfg;
  67 + string m_dec_name;
  68 +
  69 + vector<void*> m_vec_vdec;
  70 + CircularQueue<void *> m_vdecQueue;
  71 + CircularQueue<AVPacket *> *m_pktQueueptr;
  72 +
  73 + const void * m_postDecArg;
  74 + POST_DECODE_CALLBACK post_decoded_cbk;
  75 +
  76 + VpcPicConverter picConverter;
  77 +
  78 + int m_vdec_out_size {-1};
  79 +
  80 +#ifdef TEST_DECODER
  81 + void *vdecHostAddr = nullptr;
  82 + int count_frame = 0;
  83 +#endif
  84 +
  85 +};
0 \ No newline at end of file 86 \ No newline at end of file
src/decoder/dvpp/DvppDecoder.cpp 0 → 100644
  1 +#include "DvppDecoder.h"
  2 +
  3 +void receiver_finish_cbk(const void* userPtr){
  4 + if(userPtr != nullptr){
  5 + DvppDecoder* self = (DvppDecoder*)userPtr;
  6 + self->taskFinishing();
  7 + }
  8 +}
  9 +
  10 +DvppDecoder::DvppDecoder(){
  11 + m_pktQueueptr = new CircularQueue<AVPacket *>();
  12 +}
  13 +
  14 +DvppDecoder::~DvppDecoder(){
  15 + delete m_pktQueueptr;
  16 + m_pktQueueptr = nullptr;
  17 +}
  18 +
  19 +bool DvppDecoder::init(FFDecConfig cfg){
  20 +
  21 + m_dec_name = cfg.dec_name;
  22 +
  23 + ReceiverConfig receiver_config;
  24 + receiver_config.uri = cfg.uri.c_str();
  25 + receiver_config.dec_name = cfg.dec_name;
  26 + receiver_config.force_tcp = cfg.force_tcp;
  27 + receiver_config.pktQueueptr = m_pktQueueptr;
  28 + receiver_config.receiver_finished_cbk = receiver_finish_cbk;
  29 + AVCodecContext* avctx = m_receiver.init_FFmpeg(receiver_config);
  30 + if(avctx == nullptr){
  31 + return false;
  32 + }
  33 + m_receiver.setFinishCbkArg(this);
  34 +
  35 + DvppDecConfig dec_cfg;
  36 + if(avctx->codec_id == AV_CODEC_ID_H264){
  37 + dec_cfg.codec_id = 0;
  38 + }else if(avctx->codec_id == AV_CODEC_ID_HEVC){
  39 + dec_cfg.codec_id = 1;
  40 + }else {
  41 + return false;
  42 + }
  43 + dec_cfg.dec_name = cfg.dec_name;
  44 + dec_cfg.post_decoded_cbk = cfg.post_decoded_cbk;
  45 + dec_cfg.dev_id = cfg.gpuid;
  46 + dec_cfg.force_tcp = cfg.force_tcp;
  47 + dec_cfg.skip_frame = cfg.skip_frame;
  48 + dec_cfg.profile = avctx->profile;
  49 + dec_cfg.pktQueueptr = m_pktQueueptr;
  50 + dec_cfg.width = avctx->width;
  51 + dec_cfg.height = avctx->height;
  52 + bool bRet = m_decoder.init_vdpp(dec_cfg);
  53 + if(!bRet){
  54 + return false;
  55 + }
  56 +
  57 + m_cfg = cfg;
  58 +
  59 + decode_finished_cbk = cfg.decode_finished_cbk;
  60 +
  61 + m_bFinished = false;
  62 +
  63 + return true;
  64 +}
  65 +
  66 +bool DvppDecoder::isSurport(FFDecConfig& cfg){
  67 + return true;
  68 +}
  69 +
  70 +bool DvppDecoder::start(){
  71 + m_receiver.start();
  72 + m_decoder.start();
  73 + return true;
  74 +}
  75 +
  76 +void DvppDecoder::close(){
  77 + m_receiver.close();
  78 +}
  79 +
  80 +void DvppDecoder::setPostDecArg(const void* postDecArg){
  81 + m_decoder.setPostDecArg(postDecArg);
  82 +}
  83 +
  84 +void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
  85 + m_finishedDecArg = finishedDecArg;
  86 +}
  87 +
  88 +void DvppDecoder::pause(){
  89 + m_receiver.pause();
  90 +}
  91 +
  92 +void DvppDecoder::resume(){
  93 + m_receiver.resume();
  94 +}
  95 +
  96 +void DvppDecoder::setDecKeyframe(bool bKeyframe){
  97 + m_receiver.setDecKeyframe(bKeyframe);
  98 +}
  99 +
  100 +bool DvppDecoder::isRunning(){
  101 + return m_receiver.isRunning();
  102 +}
  103 +
  104 +bool DvppDecoder::isFinished(){
  105 + return m_bFinished;
  106 +}
  107 +
  108 +bool DvppDecoder::isPausing(){
  109 + return m_receiver.isPausing();
  110 +}
  111 +
  112 +bool DvppDecoder::getResolution(int &width, int &height){
  113 + return m_receiver.getResolution(width, height);
  114 +}
  115 +
  116 +float DvppDecoder::fps(){
  117 + return m_receiver.fps();
  118 +}
  119 +
  120 +FFImgInfo* DvppDecoder::snapshot(){
  121 + // TODO
  122 + return nullptr;
  123 +}
  124 +
  125 +int DvppDecoder::getCachedQueueLength(){
  126 + return 0;
  127 +}
  128 +
  129 +void DvppDecoder::taskFinishing(){
  130 + // receiver 中读取线程结束时执行
  131 + m_decoder.close();
  132 + decode_finished_cbk(m_finishedDecArg);
  133 +
  134 + m_bFinished = true;
  135 +
  136 + LOG_INFO("[{}]- task finished.", m_dec_name);
  137 +}
0 \ No newline at end of file 138 \ No newline at end of file
src/decoder/dvpp/DvppDecoder.h 0 → 100644
  1 +#include<string>
  2 +
  3 +#include "depend_headers.h"
  4 +#include "CircularQueue.hpp"
  5 +#include "FFReceiver.h"
  6 +#include "DvppDec.h"
  7 +
  8 +using namespace std;
  9 +
  10 +class DvppDecoder{
  11 +public:
  12 + DvppDecoder();
  13 + ~DvppDecoder();
  14 + bool init(FFDecConfig cfg);
  15 + void close();
  16 + bool start();
  17 + void pause();
  18 + void resume();
  19 +
  20 + void setDecKeyframe(bool bKeyframe);
  21 +
  22 + bool isRunning();
  23 + bool isFinished();
  24 + bool isPausing();
  25 + bool getResolution( int &width, int &height );
  26 +
  27 + bool isSurport(FFDecConfig& cfg);
  28 +
  29 + float fps();
  30 +
  31 + void setName(string nm){
  32 + m_dec_name = nm;
  33 + }
  34 +
  35 + string getName(){
  36 + return m_dec_name;
  37 + }
  38 +
  39 + FFImgInfo* snapshot();
  40 +
  41 + void setPostDecArg(const void* postDecArg);
  42 + void setFinishedDecArg(const void* finishedDecArg);
  43 +
  44 + int getCachedQueueLength();
  45 +
  46 +public:
  47 + void taskFinishing();
  48 +
  49 +private:
  50 + FFDecConfig m_cfg;
  51 + string m_dec_name;
  52 +
  53 + CircularQueue<AVPacket *> *m_pktQueueptr;
  54 + FFReceiver m_receiver;
  55 + DvppDec m_decoder;
  56 +
  57 + const void * m_finishedDecArg;
  58 + DECODE_FINISHED_CALLBACK decode_finished_cbk;
  59 +
  60 + bool m_bFinished{false};
  61 +
  62 +};
0 \ No newline at end of file 63 \ No newline at end of file
src/decoder/dvpp/DvppDecoderApi.cpp 0 → 100644
  1 +#include "DvppDecoderApi.h"
  2 +#include "DvppDecoder.h"
  3 +
  4 +DvppDecoderApi::DvppDecoderApi(){
  5 + m_pDecoder = nullptr;
  6 +}
  7 +
  8 +DvppDecoderApi::~DvppDecoderApi(){
  9 + if(m_pDecoder != nullptr){
  10 + delete m_pDecoder;
  11 + m_pDecoder = nullptr;
  12 + }
  13 +}
  14 +
  15 +bool DvppDecoderApi::init(FFDecConfig& cfg){
  16 + m_pDecoder = new DvppDecoder();
  17 + if(m_pDecoder != nullptr){
  18 + return m_pDecoder->init(cfg);
  19 + }
  20 + return false;
  21 +}
  22 +
  23 +void DvppDecoderApi::close(){
  24 + if(m_pDecoder != nullptr){
  25 + return m_pDecoder->close();
  26 + }
  27 +}
  28 +
  29 +bool DvppDecoderApi::start(){
  30 + if(m_pDecoder != nullptr){
  31 + return m_pDecoder->start();
  32 + }
  33 + return false;
  34 +}
  35 +
  36 +void DvppDecoderApi::pause(){
  37 + if(m_pDecoder != nullptr){
  38 + return m_pDecoder->pause();
  39 + }
  40 +}
  41 +
  42 +void DvppDecoderApi::resume(){
  43 + if(m_pDecoder != nullptr){
  44 + return m_pDecoder->resume();
  45 + }
  46 +}
  47 +
  48 +void DvppDecoderApi::setDecKeyframe(bool bKeyframe){
  49 + if(m_pDecoder != nullptr){
  50 + return m_pDecoder->setDecKeyframe(bKeyframe);
  51 + }
  52 +}
  53 +
  54 +bool DvppDecoderApi::isRunning(){
  55 + if(m_pDecoder != nullptr){
  56 + return m_pDecoder->isRunning();
  57 + }
  58 + return false;
  59 +}
  60 +
  61 +bool DvppDecoderApi::isFinished(){
  62 + if(m_pDecoder != nullptr){
  63 + return m_pDecoder->isFinished();
  64 + }
  65 + return false;
  66 +}
  67 +
  68 +bool DvppDecoderApi::isPausing(){
  69 + if(m_pDecoder != nullptr){
  70 + return m_pDecoder->isPausing();
  71 + }
  72 + return false;
  73 +}
  74 +
  75 +bool DvppDecoderApi::getResolution(int &width, int &height){
  76 + if(m_pDecoder != nullptr){
  77 + return m_pDecoder->getResolution(width, height);
  78 + }
  79 + return false;
  80 +}
  81 +
  82 +bool DvppDecoderApi::isSurport(FFDecConfig& cfg){
  83 + if(m_pDecoder != nullptr){
  84 + return m_pDecoder->isSurport(cfg);
  85 + }
  86 + return false;
  87 +}
  88 +
  89 +float DvppDecoderApi::fps(){
  90 + if(m_pDecoder != nullptr){
  91 + return m_pDecoder->fps();
  92 + }
  93 + return 0.0;
  94 +}
  95 +
  96 +int DvppDecoderApi::getCachedQueueLength(){
  97 + if(m_pDecoder != nullptr){
  98 + return m_pDecoder->getCachedQueueLength();
  99 + }
  100 + return 0;
  101 +}
  102 +
  103 +void DvppDecoderApi::setName(string nm){
  104 + if(m_pDecoder != nullptr){
  105 + return m_pDecoder->setName(nm);
  106 + }
  107 +}
  108 +
  109 +string DvppDecoderApi::getName(){
  110 + if(m_pDecoder != nullptr){
  111 + return m_pDecoder->getName();
  112 + }
  113 + return nullptr;
  114 +}
  115 +
  116 +FFImgInfo* DvppDecoderApi::snapshot(){
  117 + if(m_pDecoder != nullptr){
  118 + return m_pDecoder->snapshot();
  119 + }
  120 + return nullptr;
  121 +}
  122 +
  123 +void DvppDecoderApi::setPostDecArg(const void* postDecArg){
  124 + if(m_pDecoder != nullptr){
  125 + return m_pDecoder->setPostDecArg(postDecArg);
  126 + }
  127 +}
  128 +
  129 +void DvppDecoderApi::setFinishedDecArg(const void* finishedDecArg){
  130 + if(m_pDecoder != nullptr){
  131 + return m_pDecoder->setFinishedDecArg(finishedDecArg);
  132 + }
  133 +}
0 \ No newline at end of file 134 \ No newline at end of file
src/decoder/dvpp/DvppDecoderApi.h 0 → 100644
  1 +#include<string>
  2 +#include <pthread.h>
  3 +
  4 +#include "depend_headers.h"
  5 +#include "../interface/AbstractDecoder.h"
  6 +
  7 +using namespace std;
  8 +
  9 +class DvppDecoder;
  10 +
  11 +class DvppDecoderApi : public AbstractDecoder {
  12 +public:
  13 + DvppDecoderApi();
  14 + ~DvppDecoderApi();
  15 + bool init(FFDecConfig& cfg);
  16 + void close();
  17 + bool start();
  18 + void pause();
  19 + void resume();
  20 +
  21 + void setDecKeyframe(bool bKeyframe);
  22 +
  23 + bool isRunning();
  24 + bool isFinished();
  25 + bool isPausing();
  26 + bool getResolution( int &width, int &height );
  27 +
  28 + bool isSurport(FFDecConfig& cfg);
  29 +
  30 + int getCachedQueueLength();
  31 +
  32 + float fps();
  33 +
  34 + FFImgInfo* snapshot();
  35 +
  36 + DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP; }
  37 + void setName(string nm);
  38 + string getName();
  39 +
  40 + void setPostDecArg(const void* postDecArg);
  41 + void setFinishedDecArg(const void* finishedDecArg);
  42 +private:
  43 + DvppDecoder* m_pDecoder;
  44 +};
0 \ No newline at end of file 45 \ No newline at end of file
src/decoder/dvpp/DvppSourceManager.cpp 0 → 100644
  1 +#include "DvppSourceManager.h"
  2 +
  3 +#include "dvpp_headers.h"
  4 +#include "depend_headers.h"
  5 +
  6 +using namespace std;
  7 +
  8 +DvppSourceManager::~DvppSourceManager()
  9 +{
  10 + for(auto iter = ctxMap.begin(); iter != ctxMap.end(); iter++){
  11 + aclError ret = aclrtDestroyContext(iter->second);
  12 + if(ret != ACL_ERROR_NONE){
  13 + LOG_ERROR("aclrtDestroyContext failed !");
  14 + continue;
  15 + }
  16 + }
  17 + ctxMap.clear();
  18 + channelMap.clear();
  19 +
  20 + // aclFinalize();
  21 +}
  22 +
  23 +aclrtContext DvppSourceManager::getContext(int devId)
  24 +{
  25 + aclrtContext ctx = ctxMap[devId];
  26 + if (ctx == nullptr)
  27 + {
  28 + // 初始化硬件解码器
  29 + aclError ret = aclrtSetDevice(devId);
  30 + if(ret != ACL_ERROR_NONE){
  31 + // cout << "aclrtSetDevice failed" << endl;
  32 + LOG_ERROR("aclrtSetDevice failed !");
  33 + return nullptr;
  34 + }
  35 +
  36 + ret = aclrtCreateContext(&ctx, devId);
  37 + if (ret != ACL_ERROR_NONE) {
  38 + // cout << "aclrtCreateContext failed " << endl;
  39 + LOG_ERROR("aclrtCreateContext failed !");
  40 + return nullptr;
  41 + }
  42 + ctxMap[devId] = ctx;
  43 + }
  44 + return ctx;
  45 +}
  46 +
  47 +int DvppSourceManager::getChannel(int devId){
  48 + // channel 最大值暂定为32, 华为没有接口获取最大channel,只有文档说明
  49 + for(int iChannel = 0; iChannel < 32; iChannel++){
  50 + string channelKey = "channel_" + to_string(devId) + "_" + to_string(iChannel) ;
  51 + auto it = channelMap.find(channelKey);
  52 + if(it == channelMap.end()){
  53 + channelMap[channelKey] = iChannel;
  54 + return iChannel;
  55 + }
  56 + }
  57 + return -1;
  58 +}
  59 +
  60 +void DvppSourceManager::releaseChannel(int devId, int iChannel){
  61 + string channelKey = "channel_" + to_string(devId) + "_" + to_string(iChannel) ;
  62 + auto it = channelMap.find(channelKey);
  63 + if(it != channelMap.end()){
  64 + channelMap.erase(channelKey);
  65 + }
  66 +}
0 \ No newline at end of file 67 \ No newline at end of file
src/decoder/dvpp/DvppSourceManager.h 0 → 100644
  1 +
  2 +#include<map>
  3 +#include<string>
  4 +
  5 +#include "dvpp_headers.h"
  6 +
  7 +using namespace std;
  8 +
  9 +class DvppSourceManager{
  10 +public:
  11 + static DvppSourceManager* getInstance(){
  12 + static DvppSourceManager* singleton = nullptr;
  13 + if (singleton == nullptr){
  14 + singleton = new DvppSourceManager();
  15 + // int ret = aclInit(nullptr);
  16 + // if (ret != ACL_ERROR_NONE) {
  17 + // cout << "aclInit failed" << endl;
  18 + // return nullptr;
  19 + // }
  20 + }
  21 + return singleton;
  22 + }
  23 +
  24 + aclrtContext getContext(int devId);
  25 +
  26 + int getChannel(int devId);
  27 + void releaseChannel(int devId, int channel);
  28 +
  29 +private:
  30 + DvppSourceManager(){}
  31 + ~DvppSourceManager();
  32 +
  33 +private:
  34 + map<int, aclrtContext> ctxMap;
  35 + map<string, int> channelMap;
  36 +};
0 \ No newline at end of file 37 \ No newline at end of file
src/decoder/dvpp/FFReceiver.cpp 0 → 100644
  1 +#include "FFReceiver.h"
  2 +#include <fstream>
  3 +
  4 +const int g_pkt_size = 1024 * 1024; // 单个AVPacket大小的最大值
  5 +
  6 +FFReceiver::FFReceiver(/* args */)
  7 +{
  8 + fmt_ctx = nullptr;
  9 + m_bRunning = false;
  10 +
  11 + stream = nullptr;
  12 + stream_index = -1;
  13 + pix_fmt = AV_PIX_FMT_NONE;
  14 + m_dec_name = "";
  15 +
  16 + m_bPause = false;
  17 + m_bReal = true;
  18 +
  19 + m_bFinished = false;
  20 + m_dec_keyframe = false;
  21 + m_fps = 0.0;
  22 +
  23 + m_read_thread = 0;
  24 +}
  25 +
  26 +FFReceiver::~FFReceiver()
  27 +{
  28 + releaseFFmpeg();
  29 +
  30 + // 这个只能放在析构函数中,因为会影响到解码类中的m_pktQueueptr队列
  31 + // 所以应当确保在所有工作线程都退出后才释放
  32 + for(int i = 0; i < m_vec_pkt.size(); i++){
  33 + av_packet_free(&m_vec_pkt[i]);
  34 + }
  35 +}
  36 +
  37 +AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){
  38 +
  39 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
  40 + av_register_all();
  41 +#endif
  42 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
  43 + avcodec_register_all();
  44 +#endif
  45 +
  46 + avformat_network_init();
  47 +
  48 + const char* uri = config.uri;
  49 + fstream infile(uri);
  50 + if (infile.is_open()){
  51 + m_bReal = false;
  52 + infile.close();
  53 + }else {
  54 + m_bReal = true;
  55 + }
  56 +
  57 + m_dec_name = config.dec_name;
  58 + m_pktQueueptr = config.pktQueueptr;
  59 + receiver_finished_cbk = config.receiver_finished_cbk;
  60 +
  61 + // 打开输入视频文件
  62 + AVDictionary *options = nullptr;
  63 + av_dict_set( &options, "bufsize", "655360", 0 );
  64 + av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 );
  65 + av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
  66 +
  67 + fmt_ctx = avformat_alloc_context();
  68 + const char* input_file = uri;
  69 + if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
  70 + LOG_ERROR("[{}]- Cannot open input file: {}", m_dec_name, input_file);
  71 + return nullptr;
  72 + }
  73 + av_dump_format(fmt_ctx, 0, input_file, 0);
  74 +
  75 + // 查找流信息
  76 + if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
  77 + LOG_ERROR("[{}]- Cannot find input stream information!", m_dec_name);
  78 + return nullptr;
  79 + }
  80 +
  81 + // 查找视频流信息
  82 + AVCodec *decoder = nullptr;
  83 + stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
  84 + if (stream_index < 0) {
  85 + LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
  86 + return nullptr;
  87 + }
  88 + AVCodec *vcodec = avcodec_find_decoder(decoder->id);
  89 +
  90 + avctx = avcodec_alloc_context3(vcodec);
  91 + if(avctx == nullptr){
  92 + LOG_ERROR("[{}]- alloc AVCodecContext failed!", m_dec_name);
  93 + return nullptr;
  94 + }
  95 +
  96 + do{
  97 + // 得到视频流对象
  98 + AVStream* stream = fmt_ctx->streams[stream_index];
  99 + AVCodecParameters *codecpar = stream->codecpar;
  100 + if (avcodec_parameters_to_context(avctx, codecpar) < 0)
  101 + break;
  102 +
  103 + const AVBitStreamFilter * filter = nullptr;
  104 + if(codecpar->codec_id == AV_CODEC_ID_H264){
  105 + filter = av_bsf_get_by_name("h264_mp4toannexb");
  106 + }else if(codecpar->codec_id == AV_CODEC_ID_HEVC){
  107 + filter = av_bsf_get_by_name("hevc_mp4toannexb");
  108 + }else {
  109 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
  110 + break;
  111 + }
  112 +
  113 + int ret = av_bsf_alloc(filter, &h264bsfc);
  114 + if (ret < 0){
  115 + break;
  116 + }
  117 +
  118 + avcodec_parameters_copy(h264bsfc->par_in, codecpar);
  119 + av_bsf_init(h264bsfc);
  120 +
  121 + frame_width = codecpar->width;
  122 + frame_height = codecpar->height;
  123 + pix_fmt = (AVPixelFormat)codecpar->format;
  124 + m_fps = av_q2d(stream ->avg_frame_rate);
  125 +
  126 + LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps);
  127 +
  128 + for(int i = 0; i<5; i++){
  129 + AVPacket* pkt = av_packet_alloc();
  130 + av_init_packet( pkt );
  131 + m_vec_pkt.push_back(pkt);
  132 + }
  133 + m_pktQueueptr->init(m_vec_pkt);
  134 +
  135 + return avctx;
  136 + }while(0);
  137 +
  138 + LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name);
  139 +
  140 + return nullptr;
  141 +}
  142 +
  143 +void FFReceiver::releaseFFmpeg(){
  144 + m_dec_keyframe = false;
  145 + if(h264bsfc){
  146 + av_bsf_free(&h264bsfc);
  147 + h264bsfc = nullptr;
  148 + }
  149 + if (fmt_ctx){
  150 + avformat_close_input(&fmt_ctx);
  151 + fmt_ctx = nullptr;
  152 + }
  153 + if(avctx){
  154 + avcodec_free_context(&avctx);
  155 + avctx = nullptr;
  156 + }
  157 +}
  158 +
  159 +void FFReceiver::read_thread(){
  160 +
  161 + int frame_count = 0;
  162 + int ret = -1;
  163 + while (m_bRunning)
  164 + {
  165 + if (!m_bReal)
  166 + {
  167 + if (m_bPause)
  168 + {
  169 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  170 + continue;
  171 + }
  172 + }
  173 +
  174 + AVPacket* pkt = m_pktQueueptr->getTail();
  175 + if(pkt == nullptr){
  176 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  177 + continue;
  178 + }
  179 +
  180 + int result = av_read_frame(fmt_ctx, pkt);
  181 + if (result == AVERROR_EOF || result < 0)
  182 + {
  183 + LOG_ERROR("[{}]- Failed to read frame!", m_dec_name);
  184 + break;
  185 + }
  186 +
  187 + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
  188 + av_packet_unref(pkt);
  189 + continue;
  190 + }
  191 +
  192 + if (stream_index == pkt->stream_index){
  193 +
  194 + ret = av_bsf_send_packet(h264bsfc, pkt);
  195 + if(ret < 0) {
  196 + LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
  197 + }
  198 +
  199 + while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
  200 + if(pkt->size > g_pkt_size){
  201 + LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);
  202 + break;
  203 + }
  204 +
  205 + if(!m_bRunning){
  206 + break;
  207 + }
  208 +
  209 + m_pktQueueptr->addTail();
  210 +
  211 + frame_count++;
  212 + }
  213 + }
  214 + }
  215 +
  216 + LOG_INFO("[{}]- read thread exit.", m_dec_name);
  217 + m_bFinished = true;
  218 +
  219 + receiver_finished_cbk(m_finishedReceiveArg);
  220 +}
  221 +
  222 +bool FFReceiver::start(){
  223 + m_bRunning = true;
  224 +
  225 + pthread_create(&m_read_thread,0,
  226 + [](void* arg)
  227 + {
  228 + FFReceiver* a=(FFReceiver*)arg;
  229 + a->read_thread();
  230 + return (void*)0;
  231 + }
  232 + ,this);
  233 +
  234 + return true;
  235 +}
  236 +
  237 +void FFReceiver::close(){
  238 + m_bRunning=false;
  239 +
  240 + if(m_read_thread != 0){
  241 + pthread_join(m_read_thread,0);
  242 + }
  243 +}
  244 +
  245 +float FFReceiver::fps(){
  246 + return m_fps;
  247 +}
  248 +
  249 +bool FFReceiver::getResolution( int &width, int &height ){
  250 + width = frame_width;
  251 + height = frame_height;
  252 + return true;
  253 +}
  254 +
  255 +void FFReceiver::pause(){
  256 + m_bPause = true;
  257 +}
  258 +
  259 +void FFReceiver::resume(){
  260 + m_bPause = false;
  261 +}
  262 +
  263 +void FFReceiver::setDecKeyframe(bool bKeyframe)
  264 +{
  265 + m_dec_keyframe = bKeyframe;
  266 +}
  267 +
  268 +bool FFReceiver::isRunning(){
  269 + return m_bRunning;
  270 +}
  271 +
  272 +bool FFReceiver::isFinished(){
  273 + return m_bFinished;
  274 +}
  275 +
  276 +bool FFReceiver::isPausing(){
  277 + return m_bPause;
  278 +}
  279 +
  280 +void FFReceiver::setFinishCbkArg(const void* userPtr){
  281 + m_finishedReceiveArg = userPtr;
  282 +}
0 \ No newline at end of file 283 \ No newline at end of file
src/decoder/dvpp/FFReceiver.h 0 → 100644
  1 +#ifndef __FFRECEIVER_H__
  2 +#define __FFRECEIVER_H__
  3 +
  4 +#include "depend_headers.h"
  5 +#include "CircularQueue.hpp"
  6 +
  7 +typedef void(*RECEIVER_FINISHED_CALLBACK)(const void* userPtr);
  8 +
  9 +struct ReceiverConfig{
  10 + const char* uri;
  11 + string dec_name;
  12 + bool force_tcp;
  13 + CircularQueue<AVPacket*> *pktQueueptr;
  14 + RECEIVER_FINISHED_CALLBACK receiver_finished_cbk; // 解码线程结束后的回调接口
  15 +};
  16 +
  17 +class FFReceiver
  18 +{
  19 +public:
  20 + FFReceiver(/* args */);
  21 + ~FFReceiver();
  22 +
  23 + AVCodecContext* init_FFmpeg(ReceiverConfig config);
  24 + void releaseFFmpeg();
  25 + void close();
  26 + bool start();
  27 +
  28 + void pause();
  29 + void resume();
  30 + void setDecKeyframe(bool bKeyframe);
  31 + bool isRunning();
  32 + bool isFinished();
  33 + bool isPausing();
  34 + bool getResolution( int &width, int &height );
  35 + float fps();
  36 +
  37 + void setName(string nm){
  38 + m_dec_name = nm;
  39 + }
  40 +
  41 + void setFinishCbkArg(const void* userPtr);
  42 +
  43 +private:
  44 + void read_thread();
  45 +
  46 +private:
  47 + string m_dec_name;
  48 +
  49 + AVStream* stream;
  50 + int stream_index;
  51 + AVFormatContext *fmt_ctx;
  52 + AVPixelFormat pix_fmt;
  53 + int frame_width{0};
  54 + int frame_height{0};
  55 +
  56 + pthread_t m_read_thread;
  57 +
  58 + bool m_bRunning;
  59 + bool m_bFinished;
  60 +
  61 + bool m_bPause;
  62 +
  63 + bool m_bReal; // 是否实时流
  64 +
  65 + float m_fps;
  66 +
  67 + FFDecConfig m_cfg;
  68 + bool m_dec_keyframe;
  69 +
  70 + AVCodecContext *avctx{nullptr};
  71 + AVBSFContext * h264bsfc{nullptr};
  72 +
  73 + vector<AVPacket*> m_vec_pkt;
  74 + CircularQueue<AVPacket *> *m_pktQueueptr;
  75 +
  76 + const void * m_finishedReceiveArg;
  77 + RECEIVER_FINISHED_CALLBACK receiver_finished_cbk;
  78 +};
  79 +
  80 +
  81 +#endif
0 \ No newline at end of file 82 \ No newline at end of file
src/decoder/dvpp/Makefile 0 → 100644
  1 +# 各项目录
  2 +LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
  3 +DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
  4 +OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
  5 +SRC_DIR:=$(TOP_DIR)/$(MODULE)
  6 +
  7 +# 源文件以及中间目标文件和依赖文件
  8 +SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
  9 +OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
  10 +DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
  11 +
  12 +# 自动生成头文件依赖选项
  13 +DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
  14 +
  15 +DEFS = -DENABLE_DVPP_INTERFACE
  16 +
  17 +# 最终目标文件
  18 +TARGET:=$(LIB_DIR)/$(MODULE).a
  19 +
  20 +export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/runtime/lib64:$LD_LIBRARY_PATH
  21 +export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/6.3.RC1.alpha001/lib64:$LD_LIBRARY_PATH
  22 +export LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64/driver:$LD_LIBRARY_PATH
  23 +
  24 +include_dir=-I/usr/local/Ascend/ascend-toolkit/latest/acllib/include
  25 +lib_dir=-L/usr/lib -L/usr/local/lib -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 -L/usr/local/Ascend/driver/lib64 -L/usr/local/Ascend/ascend-toolkit/latest/atc/lib64
  26 +lib=-lacl_dvpp -lascendcl -lmmpa -lglog -lgflags -lpthread -lz
  27 +
  28 +CXXFLAGS= -g -O0 -fPIC $(include_dir) $(INCS) $(LIBS) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
  29 + # -DUNICODE -D_UNICODE
  30 +
  31 +# 默认最终目标
  32 +.PHONY:all
  33 +all:$(TARGET)
  34 +
  35 +# 生成最终目标
  36 +$(TARGET):$(OBJS) | $(LIB_DIR)
  37 + @echo -e "\e[32m""Linking static library $(TARGET)""\e[0m"
  38 + @ar -rc $@ $^
  39 +
  40 +# 若没有lib目录则自动生成
  41 +$(LIB_DIR):
  42 + @mkdir -p $@
  43 +
  44 +# 生成中间目标文件
  45 +$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
  46 + @echo -e "\e[33m""Building object $@""\e[0m"
  47 + @$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(lib_dir) $(lib) $(MACROS) -o $@ $<
  48 +
  49 +# 若没有obj目录则自动生成
  50 +$(OBJ_DIR):
  51 + @mkdir -p $@
  52 +
  53 +# 若没有.dep目录则自动生成
  54 +$(DEP_DIR):
  55 + @mkdir -p $@
  56 +
  57 +# 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
  58 +$(DEPS):
  59 +
  60 +# 引入中间目标文件头文件依赖关系
  61 +include $(wildcard $(DEPS))
  62 +
  63 +# 直接删除组件build目录
  64 +.PHONY:clean
  65 +clean:
  66 + @rm -rf $(BUILD_DIR)/$(MODULE)
src/decoder/dvpp/VpcPicConverter.cpp 0 → 100644
  1 +#include "VpcPicConverter.h"
  2 +#include "depend_headers.h"
  3 +
  4 +#define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
  5 +
  6 +VpcPicConverter::VpcPicConverter(){
  7 +
  8 +}
  9 +
  10 +VpcPicConverter::~VpcPicConverter(){
  11 + if(nullptr == stream_){
  12 + aclrtDestroyStream(stream_);
  13 + }
  14 +}
  15 +
  16 +int VpcPicConverter::init(aclrtContext context, string dec_name){
  17 +
  18 + m_dec_name = dec_name;
  19 +
  20 + CHECK_AND_RETURN(aclrtSetCurrentContext(context), "aclrtSetCurrentContext failed");
  21 + CHECK_AND_RETURN(aclrtCreateStream(&stream_), "aclrtCreateStream failed! ");
  22 +
  23 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  24 +
  25 + int ret = ACL_ERROR_NONE;
  26 + do
  27 + {
  28 + ret = acldvppCreateChannel(dvppChannelDesc_);
  29 + CHECK_AND_BREAK(ret, "acldvppCreateChannel failed !");
  30 +
  31 + ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);
  32 + CHECK_AND_BREAK(ret, "acldvppSetChannelDescMode failed !");
  33 + } while (0);
  34 +
  35 + return ret;
  36 +}
  37 +
  38 +DvppDataMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){
  39 +
  40 + int out_buf_width = ALIGN_UP(out_width, 16) * 3;
  41 + int out_buf_height = ALIGN_UP(out_height, 2);
  42 + int out_buf_size = out_buf_width * out_buf_height;
  43 +
  44 + DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame);
  45 + void *outBufferDev_ = (void*)rgbMem->getMem();
  46 +
  47 + acldvppPicDesc *outputDesc_= acldvppCreatePicDesc();
  48 + acldvppSetPicDescData(outputDesc_, outBufferDev_);
  49 + acldvppSetPicDescFormat(outputDesc_, PIXEL_FORMAT_BGR_888);
  50 + acldvppSetPicDescWidth(outputDesc_, out_width);
  51 + acldvppSetPicDescHeight(outputDesc_, out_height);
  52 + acldvppSetPicDescWidthStride(outputDesc_, out_buf_width);
  53 + acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
  54 + acldvppSetPicDescSize(outputDesc_, out_buf_size);
  55 +
  56 + aclError ret = ACL_ERROR_NONE;
  57 + do{
  58 + // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  59 + ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc_, outputDesc_, stream_);
  60 + if(ret != ACL_ERROR_NONE){
  61 + LOG_ERROR("acldvppVpcConvertColorAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  62 + break;
  63 + }
  64 + ret = aclrtSynchronizeStream(stream_);
  65 + if(ret != ACL_ERROR_NONE){
  66 + LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size);
  67 + break;
  68 + }
  69 + }while(0);
  70 +
  71 + acldvppDestroyPicDesc(outputDesc_);
  72 +
  73 + if(ret != ACL_ERROR_NONE){
  74 + delete rgbMem;
  75 + rgbMem = nullptr;
  76 + }
  77 +
  78 + return rgbMem;
  79 +}
0 \ No newline at end of file 80 \ No newline at end of file
src/decoder/dvpp/VpcPicConverter.h 0 → 100644
  1 +#include "dvpp_headers.h"
  2 +#include "depend_headers.h"
  3 +#include "DvppDataMemory.hpp"
  4 +
  5 +
  6 +class VpcPicConverter{
  7 +public:
  8 + VpcPicConverter();
  9 + ~VpcPicConverter();
  10 + int init(aclrtContext context, string dec_name);
  11 +
  12 + DvppDataMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame);
  13 +
  14 +private:
  15 + aclrtContext context_;
  16 + aclrtStream stream_;
  17 + int m_devId;
  18 + acldvppChannelDesc *dvppChannelDesc_ ;
  19 + string m_dec_name;
  20 +};
0 \ No newline at end of file 21 \ No newline at end of file
src/decoder/dvpp/depend_headers.h 0 → 100644
  1 +#ifndef __DEPEND_HEADERS_H__
  2 +#define __DEPEND_HEADERS_H__
  3 +
  4 +#include <iostream>
  5 +#include <utility>
  6 +#include <chrono>
  7 +#include <thread>
  8 +#include <functional>
  9 +#include <atomic>
  10 +#include <fstream>
  11 +#include <signal.h>
  12 +#include <time.h>
  13 +#include <unistd.h>
  14 +#include <set>
  15 +#include <mutex>
  16 +#include <vector>
  17 +#include <condition_variable>
  18 +
  19 +/*
  20 +* 依赖模块外部的代码或库
  21 +* 不要在此处添加模块内部的头文件
  22 +*/
  23 +
  24 +// ffmpeg 是c库 所以编译的时候要加入从 extern导入的C 来声明否则连接失败
  25 +extern "C" {
  26 + #include "libavutil/imgutils.h"
  27 + #include "libavutil/samplefmt.h"
  28 + #include "libavformat/avformat.h"
  29 + #include "libavcodec/avcodec.h"
  30 +}
  31 +
  32 +
  33 +#include "../interface/logger.hpp"
  34 +#include "../interface/DeviceMemory.hpp"
  35 +#include "../interface/interface_headers.h"
  36 +#include "../interface/utiltools.hpp"
  37 +
  38 +#endif
0 \ No newline at end of file 39 \ No newline at end of file
src/decoder/dvpp/dvpp_headers.h 0 → 100644
  1 +/*
  2 +* 模块内部的头文件请在此处添加
  3 +*/
  4 +
  5 +#ifndef __DVPP_HEADERS_H__
  6 +#define __DVPP_HEADERS_H__
  7 +
  8 +#include <iostream>
  9 +#include <utility>
  10 +#include <chrono>
  11 +#include <thread>
  12 +#include <functional>
  13 +#include <atomic>
  14 +#include <fstream>
  15 +#include <signal.h>
  16 +#include <time.h>
  17 +#include <unistd.h>
  18 +#include <set>
  19 +#include <mutex>
  20 +#include <vector>
  21 +#include <condition_variable>
  22 +
  23 +#include "acl/acl_mdl.h"
  24 +#include "acl/acl_base.h"
  25 +#include "acl/acl_rt.h"
  26 +#include "acl/acl.h"
  27 +#include "acl/ops/acl_dvpp.h"
  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 +
  39 +#endif
  40 +
src/decoder/dvpp/threadsafe_queue.h 0 → 100644
  1 +
  2 +#ifndef __THREADSAFE_QUEUE_H__
  3 +#define __THREADSAFE_QUEUE_H__
  4 +
  5 +#include <queue>
  6 +#include <mutex>
  7 +#include <condition_variable>
  8 +#include <initializer_list>
  9 +
  10 +#include <pthread.h>
  11 +using std::queue;
  12 +using namespace std;
  13 +
  14 +template <typename T>
  15 +class ThreadedQueue : public queue<T> {
  16 +public:
  17 + ThreadedQueue();
  18 + ~ThreadedQueue();
  19 + bool empty() const;
  20 + size_t size() const;
  21 + void push(const T& val);
  22 + void push(T& val);
  23 + bool pop();
  24 + T& front();
  25 + const T& front() const;
  26 + T& back();
  27 + const T& back() const;
  28 +
  29 + void Put(T &data);
  30 +
  31 + T Take();
  32 + void Get(T &data);
  33 + bool GetEmpty();
  34 +
  35 + condition_variable *condition;
  36 + mutex *lock;
  37 +};
  38 +
  39 +template <typename T>
  40 +ThreadedQueue<T>::ThreadedQueue() {
  41 + lock = new mutex;
  42 + condition = new condition_variable;
  43 +}
  44 +
  45 +template <typename T>
  46 +ThreadedQueue<T>::~ThreadedQueue() {
  47 + if(condition != nullptr){
  48 + delete condition;
  49 + condition = nullptr;
  50 + }
  51 + if(lock != nullptr){
  52 + delete lock;
  53 + lock = nullptr;
  54 + }
  55 +}
  56 +
  57 +template <typename T>
  58 +T ThreadedQueue<T>:: Take()
  59 +{
  60 + std::unique_lock<std::mutex> lk(this->lock);
  61 + this->condition->wait(lk, [this]{return !this->empty();});
  62 + T val = this->front();
  63 + this->pop();
  64 + return val;
  65 +}
  66 +
  67 +template <typename T>
  68 +void ThreadedQueue<T>:: Put(T &data)
  69 +{
  70 + std::unique_lock<std::mutex> lk(*lock);
  71 + this->push(data);
  72 + this->condition->notify_one();
  73 + return;
  74 +}
  75 +
  76 +template <typename T>
  77 +void ThreadedQueue<T>:: Get(T &data)
  78 +{
  79 + std::unique_lock<std::mutex> lk(*lock);
  80 + this->condition->wait(lk, [this]{return !this->empty();});
  81 + data = this->front();
  82 + this->pop();
  83 +}
  84 +
  85 +template <typename T>
  86 +bool ThreadedQueue<T>::GetEmpty()
  87 +{
  88 + std::unique_lock<std::mutex> lk(*lock);
  89 + this->condition->wait(lk, [this]{return !this->empty();});
  90 + return true;
  91 +}
  92 +
  93 +
  94 +template <typename T>
  95 +bool ThreadedQueue<T>::empty() const {
  96 + bool result = queue<T>::empty();
  97 + return result;
  98 +}
  99 +
  100 +template <typename T>
  101 +size_t ThreadedQueue<T>::size() const {
  102 + size_t result = queue<T>::size();
  103 + return result;
  104 +}
  105 +
  106 +template <typename T>
  107 +void ThreadedQueue<T>::push(T& val) {
  108 + queue<T>::push(val);
  109 +}
  110 +
  111 +
  112 +template <typename T>
  113 +T& ThreadedQueue<T>::front() {
  114 + T& result = queue<T>::front();
  115 + return result;
  116 +}
  117 +
  118 +template <typename T>
  119 +bool ThreadedQueue<T>::pop() {
  120 + bool result = false;
  121 + if(!queue<T>::empty()) {
  122 + queue<T>::pop();
  123 + result = true;
  124 + }
  125 + return result;
  126 +}
  127 +
  128 +#endif
src/decoder/dvpp/user_mem.h 0 → 100644
  1 +#ifndef __USER_MEM_H__
  2 +#define __USER_MEM_H__
  3 +
  4 +#include <mutex>
  5 +#include <memory>
  6 +#include <iostream>
  7 +#include <condition_variable>
  8 +#include "threadsafe_queue.h"
  9 +
  10 +#define ALIGN_MEM(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
  11 +
  12 +using namespace std;
  13 +
  14 +typedef enum {
  15 + RTSP_MEM,
  16 + VDEC_MEM,
  17 +} MemType;
  18 +
  19 +class MemNode{
  20 +public:
  21 + uint8_t *bufAddr;
  22 + MemType memType;
  23 +
  24 + MemNode(){
  25 + std::cout << "构造" << endl;
  26 + }
  27 +
  28 + ~MemNode(){
  29 + std::cout << "析构" << std::endl;
  30 + }
  31 +} ;
  32 +
  33 +#endif
0 \ No newline at end of file 34 \ No newline at end of file
src/decoder/interface/AbstractDecoder.cpp 0 → 100644
  1 +#include "AbstractDecoder.h"
  2 +
  3 +#include "logger.hpp"
  4 +#include "utiltools.hpp"
  5 +
  6 +
  7 +bool AbstractDecoder::isSnapTime(){
  8 + if(m_snap_time_interval <= 0){
  9 + return false;
  10 + }
  11 + long cur_time = UtilTools::get_cur_time_ms();
  12 + if(cur_time - m_last_snap_time > m_snap_time_interval){
  13 + return true;
  14 + }
  15 + return false;
  16 +}
  17 +
  18 +void AbstractDecoder::updateLastSnapTime(){
  19 + m_last_snap_time = UtilTools::get_cur_time_ms();
  20 +}
  21 +
  22 +void AbstractDecoder::setSnapTimeInterval(long interval){
  23 + m_snap_time_interval = interval;
  24 + m_last_snap_time = UtilTools::get_cur_time_ms();
  25 +}
0 \ No newline at end of file 26 \ No newline at end of file
src/decoder/interface/AbstractDecoder.h 0 → 100644
  1 +#ifndef _ABSTRACT_DECODER_H_
  2 +#define _ABSTRACT_DECODER_H_
  3 +
  4 +#include "interface_headers.h"
  5 +
  6 +using namespace std;
  7 +
  8 +class AbstractDecoder{
  9 +public:
  10 + virtual ~AbstractDecoder(){};
  11 + virtual bool init(FFDecConfig& cfg) = 0;
  12 + virtual void close() = 0;
  13 + virtual bool start() = 0;
  14 + virtual void pause() = 0;
  15 + virtual void resume() = 0;
  16 +
  17 + virtual void setDecKeyframe(bool bKeyframe) = 0;
  18 +
  19 + virtual bool isRunning() = 0;
  20 + virtual bool isFinished() = 0;
  21 + virtual bool isPausing() = 0;
  22 + virtual bool getResolution( int &width, int &height ) = 0;
  23 +
  24 + virtual bool isSurport(FFDecConfig& cfg) = 0;
  25 +
  26 + virtual int getCachedQueueLength() = 0;
  27 +
  28 + virtual float fps() = 0;
  29 +
  30 + virtual DECODER_TYPE getDecoderType() = 0;
  31 +
  32 + virtual FFImgInfo* snapshot() = 0;
  33 +
  34 + virtual void setName(string nm) = 0;
  35 +
  36 + virtual string getName() = 0;
  37 +
  38 + virtual void setPostDecArg(const void* postDecArg) = 0;
  39 + virtual void setFinishedDecArg(const void* finishedDecArg) = 0;
  40 +
  41 +public:
  42 + bool isSnapTime();
  43 +
  44 + void updateLastSnapTime();
  45 +
  46 + void setSnapTimeInterval(long interval);
  47 +
  48 +public:
  49 + long m_snap_time_interval{-1};
  50 + long m_last_snap_time;
  51 + long m_index{0};
  52 +};
  53 +
  54 +#endif // _ABSTRACT_DECODER_H_
0 \ No newline at end of file 55 \ No newline at end of file
src/decoder/interface/DecoderManager.cpp 0 → 100644
  1 +#include "DecoderManager.h"
  2 +
  3 +#ifdef USE_NVDEC
  4 +#include "../nvdec/FFNvDecoder.h"
  5 +#include "../gb28181/FFGB28181Decoder.h"
  6 +#endif
  7 +
  8 +#ifdef USE_DVPP
  9 +#include "../dvpp/DvppDecoderApi.h"
  10 +#endif
  11 +
  12 +#include "logger.hpp"
  13 +
  14 +using namespace std;
  15 +
  16 +
  17 +AbstractDecoder* DecoderManager::createDecoder(MgrDecConfig config){
  18 +
  19 + closeAllFinishedDecoder();
  20 +
  21 + if (config.cfg.post_decoded_cbk == nullptr || config.cfg.decode_finished_cbk== nullptr){
  22 + return nullptr;
  23 + }
  24 +
  25 + std::lock_guard<std::mutex> l(m_mutex);
  26 +
  27 + auto it = decoderMap.find(config.name);
  28 + if (it != decoderMap.end()){
  29 + LOG_ERROR("已存在name为{}的解码器", config.name);
  30 + return nullptr;
  31 + }
  32 +
  33 + AbstractDecoder* dec = nullptr;
  34 +#ifdef USE_NVDEC
  35 + if(DECODER_TYPE_FFMPEG == config.dec_type){
  36 + dec = new FFNvDecoder();
  37 + }
  38 +
  39 + if(DECODER_TYPE_GB28181 == config.dec_type){
  40 + dec = new FFGB28181Decoder();
  41 + }
  42 +#endif
  43 +
  44 +#ifdef USE_DVPP
  45 + if(DECODER_TYPE_DVPP == config.dec_type){
  46 + dec = new DvppDecoderApi();
  47 + }
  48 +#endif
  49 +
  50 + if (dec == nullptr){
  51 + LOG_ERROR("没有指定解码器类型");
  52 + return nullptr;
  53 + }
  54 +
  55 + config.cfg.dec_name = config.name;
  56 + bool bRet= dec->init(config.cfg);
  57 + if (bRet)
  58 + {
  59 + decoderMap[config.name] = dec;
  60 +
  61 + LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri);
  62 + return dec;
  63 + }
  64 +
  65 + // 创建失败,关闭解码器
  66 + dec->close();
  67 + delete dec;
  68 +
  69 + LOG_ERROR("[{}][{}]- 解码器初始化失败!",config.name, config.cfg.uri);
  70 + return nullptr;
  71 +}
  72 +
  73 +bool DecoderManager::setPostDecArg(const string name, const void * userPtr)
  74 +{
  75 + if (name.empty())
  76 + {
  77 + LOG_ERROR("name 为空!");
  78 + return false;
  79 + }
  80 +
  81 + std::lock_guard<std::mutex> l(m_mutex);
  82 +
  83 + auto dec = decoderMap.find(name);
  84 + if (dec != decoderMap.end())
  85 + {
  86 + dec->second->setPostDecArg(userPtr);
  87 + return true;
  88 + }
  89 +
  90 + LOG_ERROR("没有找到name为{}的解码器",name);
  91 + return false;
  92 +}
  93 +
  94 +bool DecoderManager::setFinishedDecArg(const string name, const void * userPtr)
  95 +{
  96 + if (name.empty())
  97 + {
  98 + LOG_ERROR("name 为空!");
  99 + return false;
  100 + }
  101 +
  102 + std::lock_guard<std::mutex> l(m_mutex);
  103 +
  104 + auto dec = decoderMap.find(name);
  105 + if (dec != decoderMap.end())
  106 + {
  107 + dec->second->setFinishedDecArg(userPtr);
  108 + return true;
  109 + }
  110 +
  111 + LOG_ERROR("没有找到name为{}的解码器",name);
  112 + return false;
  113 +}
  114 +
  115 +AbstractDecoder* DecoderManager::getDecoderByName(const string name)
  116 +{
  117 + if (name.empty())
  118 + {
  119 + LOG_ERROR("name 为空!");
  120 + return nullptr;
  121 + }
  122 +
  123 + std::lock_guard<std::mutex> l(m_mutex);
  124 +
  125 + auto dec = decoderMap.find(name);
  126 + if (dec != decoderMap.end())
  127 + {
  128 + return dec->second;
  129 + }
  130 +
  131 + LOG_ERROR("没有找到name为{}的解码器",name);
  132 + return nullptr;
  133 +}
  134 +
  135 +bool DecoderManager::startDecode(AbstractDecoder* dec){
  136 + if (dec != nullptr && !dec->isRunning())
  137 + {
  138 + return dec->start();
  139 + }
  140 + return false;
  141 +}
  142 +
  143 +bool DecoderManager::startDecodeByName(const string name){
  144 + if (name.empty())
  145 + {
  146 + LOG_ERROR("name 为空!");
  147 + return false;
  148 + }
  149 +
  150 + std::lock_guard<std::mutex> l(m_mutex);
  151 +
  152 + auto dec = decoderMap.find(name);
  153 + if (dec != decoderMap.end())
  154 + {
  155 + return dec->second->start();
  156 + }
  157 +
  158 + LOG_ERROR("没有找到name为{}的解码器",name);
  159 + return false;
  160 +}
  161 +
  162 +void DecoderManager::startAllDecode(){
  163 +
  164 + std::lock_guard<std::mutex> l(m_mutex);
  165 +
  166 + for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){
  167 + if (!iter->second->isRunning())
  168 + {
  169 + iter->second->start();
  170 + }
  171 + }
  172 +}
  173 +
  174 +bool DecoderManager::closeDecoderByName(const string name){
  175 + if (name.empty())
  176 + {
  177 + LOG_ERROR("name 为空!");
  178 + return false;
  179 + }
  180 +
  181 + std::lock_guard<std::mutex> l(m_mutex);
  182 +
  183 + auto dec = decoderMap.find(name);
  184 + if (dec != decoderMap.end())
  185 + {
  186 + dec->second->close();
  187 + delete dec->second;
  188 + dec->second = nullptr;
  189 + decoderMap.erase(dec);
  190 +
  191 + return true;
  192 + }
  193 +
  194 + LOG_ERROR("没有找到name为{}的解码器",name);
  195 + return false;
  196 +}
  197 +
  198 +void DecoderManager::closeAllDecoder()
  199 +{
  200 + std::lock_guard<std::mutex> l(m_mutex);
  201 +
  202 + for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){
  203 + iter->second->close();
  204 + delete iter->second;
  205 + iter->second = nullptr;
  206 + }
  207 + decoderMap.clear();
  208 +}
  209 +
  210 +void DecoderManager::closeAllFinishedDecoder()
  211 +{
  212 + std::lock_guard<std::mutex> l(m_mutex);
  213 +
  214 + for(auto iter = decoderMap.begin(); iter != decoderMap.end(); ){
  215 + if (iter->second->isFinished())
  216 + {
  217 + delete iter->second;
  218 + iter->second = nullptr;
  219 + iter = decoderMap.erase(iter);
  220 + }
  221 + else
  222 + {
  223 + iter++ ;
  224 + }
  225 + }
  226 +}
  227 +
  228 +int DecoderManager::count()
  229 +{
  230 + closeAllFinishedDecoder();
  231 +
  232 + std::lock_guard<std::mutex> l(m_mutex);
  233 + return decoderMap.size();
  234 +}
  235 +
  236 +bool DecoderManager::pauseDecoder(const string name)
  237 +{
  238 + if (name.empty())
  239 + {
  240 + LOG_ERROR("name 为空!");
  241 + return false;
  242 + }
  243 +
  244 + std::lock_guard<std::mutex> l(m_mutex);
  245 +
  246 + auto dec = decoderMap.find(name);
  247 + if (dec != decoderMap.end())
  248 + {
  249 + dec->second->pause();
  250 + return true;
  251 + }
  252 +
  253 + LOG_ERROR("没有找到name为{}的解码器",name);
  254 + return false;
  255 +}
  256 +
  257 +bool DecoderManager::resumeDecoder(const string name)
  258 +{
  259 + if (name.empty())
  260 + {
  261 + LOG_ERROR("name 为空!");
  262 + return false;
  263 + }
  264 +
  265 + std::lock_guard<std::mutex> l(m_mutex);
  266 +
  267 + auto dec = decoderMap.find(name);
  268 + if (dec != decoderMap.end())
  269 + {
  270 + dec->second->resume();
  271 + return true;
  272 + }
  273 +
  274 + LOG_ERROR("没有找到name为{}的解码器",name);
  275 + return false;
  276 +}
  277 +
  278 +bool DecoderManager::isSurport(MgrDecConfig& config)
  279 +{
  280 + {
  281 + std::lock_guard<std::mutex> l(m_mutex);
  282 +
  283 + auto it = decoderMap.find(config.name);
  284 + if (it != decoderMap.end()){
  285 + LOG_ERROR("已存在name所标记的解码器");
  286 + return false;
  287 + }
  288 + }
  289 +
  290 + AbstractDecoder* dec = nullptr;
  291 +#ifdef USE_NVDEC
  292 + if(DECODER_TYPE_FFMPEG == config.dec_type){
  293 + dec = new FFNvDecoder();
  294 + }
  295 +
  296 + if(DECODER_TYPE_GB28181 == config.dec_type){
  297 + dec = new FFGB28181Decoder();
  298 + }
  299 +#endif
  300 +
  301 +#ifdef USE_DVPP
  302 + if(DECODER_TYPE_DVPP == config.dec_type){
  303 + dec = new DvppDecoderApi();
  304 + }
  305 +#endif
  306 +
  307 + if (dec == nullptr){
  308 + LOG_ERROR("没有指定解码器类型");
  309 + return false;
  310 + }
  311 +
  312 + bool bRet = dec->isSurport(config.cfg);
  313 + delete dec;
  314 + dec = nullptr;
  315 +
  316 + return bRet;
  317 +}
  318 +
  319 +bool DecoderManager::isRunning(const string name){
  320 + if (name.empty())
  321 + {
  322 + LOG_ERROR("name 为空!");
  323 + return false;
  324 + }
  325 +
  326 + std::lock_guard<std::mutex> l(m_mutex);
  327 +
  328 + auto dec = decoderMap.find(name);
  329 + if (dec != decoderMap.end())
  330 + {
  331 + return dec->second->isRunning();
  332 + }
  333 +
  334 + LOG_ERROR("没有找到name为{}的解码器",name);
  335 + return false;
  336 +}
  337 +
  338 +bool DecoderManager::isFinished(const string name){
  339 + if (name.empty())
  340 + {
  341 + LOG_ERROR("name 为空!");
  342 + return false;
  343 + }
  344 +
  345 + std::lock_guard<std::mutex> l(m_mutex);
  346 +
  347 + auto dec = decoderMap.find(name);
  348 + if (dec != decoderMap.end())
  349 + {
  350 + return dec->second->isFinished();
  351 + }
  352 +
  353 + LOG_ERROR("没有找到name为{}的解码器",name);
  354 + return false;
  355 +}
  356 +
  357 +bool DecoderManager::isPausing(const string name){
  358 + if (name.empty())
  359 + {
  360 + LOG_ERROR("name 为空!");
  361 + return false;
  362 + }
  363 +
  364 + std::lock_guard<std::mutex> l(m_mutex);
  365 +
  366 + auto dec = decoderMap.find(name);
  367 + if (dec != decoderMap.end())
  368 + {
  369 + return dec->second->isPausing();
  370 + }
  371 +
  372 + LOG_ERROR("没有找到name为{}的解码器",name);
  373 + return false;
  374 +}
  375 +
  376 +bool DecoderManager::setDecKeyframe(const string name, bool bKeyframe)
  377 +{
  378 + if (name.empty())
  379 + {
  380 + LOG_ERROR("name 为空!");
  381 + return false;
  382 + }
  383 +
  384 + std::lock_guard<std::mutex> l(m_mutex);
  385 +
  386 + auto dec = decoderMap.find(name);
  387 + if (dec != decoderMap.end())
  388 + {
  389 + dec->second->setDecKeyframe(bKeyframe);
  390 + return true;
  391 + }
  392 +
  393 + LOG_ERROR("没有找到name为{}的解码器",name);
  394 + return false;
  395 +}
  396 +
  397 +bool DecoderManager::getResolution(const string name, int &width, int &height)
  398 +{
  399 + if (name.empty())
  400 + {
  401 + LOG_ERROR("name 为空!");
  402 + return false;
  403 + }
  404 +
  405 + std::lock_guard<std::mutex> l(m_mutex);
  406 +
  407 + auto dec = decoderMap.find(name);
  408 + if (dec != decoderMap.end())
  409 + {
  410 + dec->second->getResolution(width, height);
  411 + return true;
  412 + }
  413 +
  414 + LOG_ERROR("没有找到name为{}的解码器",name);
  415 + return false;
  416 +}
  417 +
  418 +vector<string> DecoderManager::getAllDecodeName(){
  419 +
  420 + closeAllFinishedDecoder();
  421 +
  422 + std::lock_guard<std::mutex> l(m_mutex);
  423 +
  424 + vector<string> decode_names;
  425 + for(auto it = decoderMap.begin(); it != decoderMap.end(); ++it){
  426 + decode_names.push_back(it->first);
  427 + }
  428 + return decode_names;
  429 +}
  430 +
  431 +int DecoderManager::getCachedQueueLength(const string name){
  432 + if (name.empty()){
  433 + LOG_ERROR("name 为空!");
  434 + return -1;
  435 + }
  436 +
  437 + std::lock_guard<std::mutex> l(m_mutex);
  438 +
  439 + auto dec = decoderMap.find(name);
  440 + if (dec != decoderMap.end()){
  441 + return dec->second->getCachedQueueLength();
  442 + }
  443 +
  444 + LOG_ERROR("没有找到name为{}的解码器",name);
  445 + return -1;
  446 +}
  447 +
  448 +void DecoderManager::releaseFFImgInfo(FFImgInfo* info){
  449 + if(nullptr != info){
  450 + if(info->pData != nullptr){
  451 + free(info->pData);
  452 + info->pData = nullptr;
  453 + }
  454 + delete info;
  455 + info = nullptr;
  456 + }
  457 +}
  458 +
  459 +FFImgInfo* DecoderManager::snapshot_in_task(const string name){
  460 + if (name.empty()){
  461 + LOG_ERROR("name 为空!");
  462 + return nullptr;
  463 + }
  464 +
  465 + std::lock_guard<std::mutex> l(m_mutex);
  466 +
  467 + auto dec = decoderMap.find(name);
  468 + if (dec != decoderMap.end()){
  469 + return dec->second->snapshot();
  470 + }
  471 +
  472 + LOG_ERROR("没有找到name为{}的解码器",name);
  473 + return nullptr;
  474 +}
  475 +
  476 +vector<FFImgInfo*> DecoderManager::timing_snapshot_all(){
  477 +
  478 + closeAllFinishedDecoder();
  479 +
  480 + std::lock_guard<std::mutex> l(m_mutex);
  481 +
  482 + vector<FFImgInfo*> vec;
  483 + for(auto it = decoderMap.begin(); it != decoderMap.end(); ++it){
  484 + if(it->second->isSnapTime()){
  485 + FFImgInfo* imginfo = it->second->snapshot();
  486 + if(imginfo != nullptr){
  487 + vec.push_back(imginfo);
  488 + }
  489 + it->second->updateLastSnapTime();
  490 + }
  491 + }
  492 +
  493 + return vec;
  494 +}
0 \ No newline at end of file 495 \ No newline at end of file
src/decoder/interface/DecoderManager.h 0 → 100644
  1 +#include "AbstractDecoder.h"
  2 +#include<iostream>
  3 +#include<vector>
  4 +#include<map>
  5 +
  6 +#include <mutex>
  7 +
  8 +using namespace std;
  9 +
  10 +struct MgrDecConfig
  11 +{
  12 + DECODER_TYPE dec_type; // 解码器类型
  13 + FFDecConfig cfg; // 解码器配置
  14 + string name{""}; // 解码器名称
  15 +};
  16 +
  17 +// #define USE_NVDEC
  18 +#define USE_DVPP
  19 +/**
  20 + * 解码器管理类,单例类
  21 + * 谨防死锁
  22 + **/
  23 +class DecoderManager {
  24 +public:
  25 + /**************************************************
  26 + * 接口:getInstance
  27 + * 功能:获取解码器管理者实例
  28 + * 参数:无
  29 + * 返回:成功返回 解码器管理者实例, 失败返回 nullptr
  30 + * 备注:调用其他接口前,需要先调用该接口获取管理者实例
  31 + **************************************************/
  32 + static DecoderManager* getInstance(){
  33 + static DecoderManager* singleton = nullptr;
  34 + if (singleton == nullptr){
  35 + singleton = new DecoderManager();
  36 + }
  37 + return singleton;
  38 + }
  39 +
  40 + ~DecoderManager()
  41 + {
  42 + closeAllDecoder();
  43 + }
  44 +
  45 + /**************************************************
  46 + * 接口:createDecoder
  47 + * 功能:根据配置信息创建解码器
  48 + * 参数:MgrDecConfig& config 解码器配置信息
  49 + * 返回:成功返回解码器, 失败返回 nullptr
  50 + * 备注:
  51 + **************************************************/
  52 + AbstractDecoder* createDecoder(MgrDecConfig config);
  53 +
  54 + /**************************************************
  55 + * 接口:setPostDecArg
  56 + * 功能:设置解码数据回调接口的用户自定义参数
  57 + * 参数:string name 解码器名称
  58 + * const void * userPtr 用户自定义的要传到解码数据回调接口的数据
  59 + * 返回:设置成功返回true,失败返回false
  60 + * 备注:
  61 + **************************************************/
  62 + bool setPostDecArg(const string name, const void * userPtr);
  63 +
  64 + /**************************************************
  65 + * 接口:setFinishedDecArg
  66 + * 功能:设置解码结束回调接口的用户自定义参数
  67 + * 参数:string name 解码器名称
  68 + * const void * userPtr 用户自定义的要传到解码数据回调接口的数据
  69 + * 返回:设置成功返回true,失败返回false
  70 + * 备注:
  71 + **************************************************/
  72 + bool setFinishedDecArg(const string name, const void * userPtr);
  73 +
  74 + /**************************************************
  75 + * 接口:getDecoderByName
  76 + * 功能:根据解码器名称返回解码器对象指针
  77 + * 参数:const string name 解码器名称
  78 + * 返回:成功返回对应的解码器对象的指针,失败返回nullptr
  79 + * 备注:
  80 + **************************************************/
  81 + AbstractDecoder* getDecoderByName(const string name);
  82 +
  83 + /**************************************************
  84 + * 接口:startDecode
  85 + * 功能:启动解码
  86 + * 参数:FFNvDecoder* 解码器指针
  87 + * 返回:void
  88 + * 备注:
  89 + **************************************************/
  90 + bool startDecode(AbstractDecoder*);
  91 +
  92 + /**************************************************
  93 + * 接口:startAllDecode
  94 + * 功能:启动全部解码
  95 + * 参数:void
  96 + * 返回:void
  97 + * 备注:
  98 + **************************************************/
  99 + void startAllDecode();
  100 +
  101 + /**************************************************
  102 + * 接口:startDecodeByName
  103 + * 功能:启动名称对应的解码器
  104 + * 参数:string name 解码器名称
  105 + * 返回:成功返回true,失败返回false
  106 + * 备注:
  107 + **************************************************/
  108 + bool startDecodeByName(const string name);
  109 +
  110 + /**************************************************
  111 + * 接口:closeDecoderByName
  112 + * 功能:关闭解码器名称对应的解码
  113 + * 参数:const string name 解码器名称
  114 + * 返回:成功返回true,失败返回false
  115 + * 备注:
  116 + **************************************************/
  117 + bool closeDecoderByName(const string name);
  118 +
  119 + /**************************************************
  120 + * 接口:closeAllDecoder
  121 + * 功能:关闭全部解码器
  122 + * 参数:void
  123 + * 返回:void
  124 + * 备注:
  125 + **************************************************/
  126 + void closeAllDecoder();
  127 +
  128 + /**************************************************
  129 + * 接口:closeAllDecoderByGpuid
  130 + * 功能:关闭某张显卡撒花姑娘的全部解码器
  131 + * 参数:const string gpuid gpu的id
  132 + * 返回:void
  133 + * 备注:
  134 + **************************************************/
  135 + void closeAllDecoderByGpuid(const string gpuid);
  136 +
  137 + /**************************************************
  138 + * 接口:pauseDecoder
  139 + * 功能:暂停指定名称的解码器
  140 + * 参数:const string name 解码器名称
  141 + * 返回:成功返回true,失败返回false
  142 + * 备注:
  143 + **************************************************/
  144 + bool pauseDecoder(const string name);
  145 +
  146 + /**************************************************
  147 + * 接口:pauseDecoder
  148 + * 功能:恢复指定名称的解码器
  149 + * 参数:const string name 解码器名称
  150 + * 返回:成功返回true,失败返回false
  151 + * 备注:
  152 + **************************************************/
  153 + bool resumeDecoder(const string name);
  154 +
  155 + /**************************************************
  156 + * 接口:isSurport
  157 + * 功能:是否支持指定配置的解码
  158 + * 参数:FFDecConfig& cfg 解码器配置
  159 + * 返回:支持返回true,不支持返回false
  160 + * 备注:
  161 + **************************************************/
  162 + bool isSurport(MgrDecConfig& config);
  163 +
  164 + /**************************************************
  165 + * 接口:isRunning
  166 + * 功能:根据解码器名称判断解码器是否正在运行
  167 + * 参数:const string name 解码器名称
  168 + * 返回:正在运行返回true,否则返回false
  169 + * 备注:
  170 + **************************************************/
  171 + bool isRunning(const string name);
  172 +
  173 + /**************************************************
  174 + * 接口:isFinished
  175 + * 功能:根据解码器名称判断解码器是否已经结束
  176 + * 参数:const string name 解码器名称
  177 + * 返回:正在运行返回true,否则返回false
  178 + * 备注:
  179 + **************************************************/
  180 + bool isFinished(const string name);
  181 +
  182 + /**************************************************
  183 + * 接口:isPausing
  184 + * 功能:根据解码器名称判断解码器是否暂停
  185 + * 参数:const string name 解码器名称
  186 + * 返回:正在运行返回true,否则返回false
  187 + * 备注:
  188 + **************************************************/
  189 + bool isPausing(const string name);
  190 +
  191 + /**************************************************
  192 + * 接口:count
  193 + * 功能:获取正在运行的解码器数量
  194 + * 参数:void
  195 + * 返回:正在运行的解码器数量
  196 + * 备注:
  197 + **************************************************/
  198 + int count();
  199 +
  200 + /**************************************************
  201 + * 接口:setDecKeyframe
  202 + * 功能:设置是否只解码关键帧。默认全解
  203 + * 参数:const string name 解码器名称
  204 + * bool bKeyframe 是否只解码关键帧。true,只解码关键帧;false,普通的全解码
  205 + * 返回:bool 成功返回true,失败返回false
  206 + * 备注:
  207 + **************************************************/
  208 + bool setDecKeyframe(const string name, bool bKeyframe);
  209 +
  210 + /**************************************************
  211 + * 接口:getResolution
  212 + * 功能:获取视频分辨率
  213 + * 参数:const string name 解码器名称
  214 + * int &width 从 width 返回视频宽度
  215 + * int &height 从 height 返回视频高度
  216 + * 返回:bool 成功获取返回true,失败返回false
  217 + * 备注:
  218 + **************************************************/
  219 + bool getResolution(const string name, int &width, int &height);
  220 +
  221 + /**************************************************
  222 + * 接口:getAllDecodeName
  223 + * 功能:获取全部解码器名称
  224 + * 参数:void
  225 + * 返回:vector<string> 返回全部解码器名称
  226 + * 备注:
  227 + **************************************************/
  228 + vector<string> getAllDecodeName();
  229 +
  230 + /**************************************************
  231 + * 接口:getCachedQueueLength
  232 + * 功能:获取解码缓冲队列当前长度
  233 + * 参数:const string name 解码器名称
  234 + * 返回:int 解码缓冲队列当前长度
  235 + * 备注:
  236 + **************************************************/
  237 + int getCachedQueueLength(const string name);
  238 +
  239 + /**************************************************
  240 + * 接口:releaseFFImgInfo
  241 + * 功能:释放视频快照信息
  242 + * 参数:FFImgInfo* info 视频快照信息
  243 + * 返回:void
  244 + * 备注:
  245 + **************************************************/
  246 + void releaseFFImgInfo(FFImgInfo* info);
  247 +
  248 + FFImgInfo* snapshot_in_task(const string name);
  249 +
  250 + vector<FFImgInfo*> timing_snapshot_all();
  251 +
  252 +private:
  253 + DecoderManager(){}
  254 +
  255 + void closeAllFinishedDecoder();
  256 +
  257 +private:
  258 + map<string, AbstractDecoder*> decoderMap;
  259 +
  260 + mutex m_mutex;
  261 +};
0 \ No newline at end of file 262 \ No newline at end of file
src/decoder/interface/DeviceMemory.hpp 0 → 100644
  1 +#ifndef __DEVICE_RGB_MEMORY_H__
  2 +#define __DEVICE_RGB_MEMORY_H__
  3 +
  4 +#include<string>
  5 +
  6 +#include "utiltools.hpp"
  7 +
  8 +using namespace std;
  9 +
  10 +class DeviceMemory{
  11 +
  12 +public:
  13 + DeviceMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, string _id, string _dev_id, bool _key_frame, bool _isused){
  14 + channel = _channel;
  15 + width = _width;
  16 + width_stride = _width_stride;
  17 + height = _height;
  18 + height_stride = _height_stride;
  19 + data_size = channel * width * height;
  20 + isused = _isused;
  21 + id = _id;
  22 + device_id = _dev_id;
  23 + key_frame = _key_frame;
  24 + timestamp = UtilTools::get_cur_time_ms();
  25 + }
  26 +
  27 + virtual ~DeviceMemory(){}
  28 +
  29 + int getSize() {
  30 + return data_size;
  31 + }
  32 +
  33 + bool isIsused() {
  34 + return isused;
  35 + }
  36 +
  37 + void setIsused(bool _isused) {
  38 + isused = _isused;
  39 + // 更新时间戳
  40 + timestamp = UtilTools::get_cur_time_ms();
  41 + }
  42 +
  43 + string getId() {
  44 + return id;
  45 + }
  46 +
  47 + string getDeviceId() {
  48 + return device_id;
  49 + }
  50 +
  51 + unsigned char* getMem(){
  52 + return pHwRgb;
  53 + }
  54 +
  55 + long long getTimesstamp(){
  56 + return timestamp;
  57 + }
  58 +
  59 + int getWidth(){
  60 + return width;
  61 + }
  62 +
  63 + int getWidthStride(){
  64 + return width_stride;
  65 + }
  66 +
  67 + int getHeight(){
  68 + return height;
  69 + }
  70 +
  71 + int getHeightStride(){
  72 + return height_stride;
  73 + }
  74 +
  75 + int getChannel(){
  76 + return channel;
  77 + }
  78 +
  79 + bool isKeyFrame(){
  80 + return key_frame;
  81 + }
  82 +
  83 +public:
  84 + int data_size;
  85 + bool isused;
  86 + string id;
  87 + string device_id;
  88 + unsigned char * pHwRgb{nullptr};
  89 + long long timestamp;
  90 + int width{0};
  91 + int width_stride{0};
  92 + int height{0};
  93 + int height_stride{0};
  94 + int channel{3};
  95 + bool key_frame;
  96 +};
  97 +
  98 +#endif
0 \ No newline at end of file 99 \ No newline at end of file
src/decoder/interface/Makefile 0 → 100644
  1 +# 各项目录
  2 +LIB_DIR:=$(BUILD_DIR)/$(MODULE)/lib
  3 +DEP_DIR:=$(BUILD_DIR)/$(MODULE)/.dep
  4 +OBJ_DIR:=$(BUILD_DIR)/$(MODULE)/obj
  5 +SRC_DIR:=$(TOP_DIR)/$(MODULE)
  6 +
  7 +# 源文件以及中间目标文件和依赖文件
  8 +SRCS:=$(notdir $(wildcard $(SRC_DIR)/*.cpp))
  9 +OBJS:=$(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRCS)))
  10 +DEPS:=$(addprefix $(DEP_DIR)/, $(patsubst %.cpp, %.d,a $(SRCS)))
  11 +
  12 +# 自动生成头文件依赖选项
  13 +DEPFLAGS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d
  14 +
  15 +JRTP_ROOT = $(THIRDPARTY_ROOT)/jrtp_export
  16 +
  17 +INCLUDE= -I $(TOP_DIR)/common/inc \
  18 + -I $(TOP_DIR)/common/UtilNPP \
  19 + -I $(TOP_DIR)/ \
  20 + -I $(JRTP_ROOT)/jrtplib/include/jrtplib3 \
  21 + -I $(JRTP_ROOT)/jthread/include/jthread \
  22 + -I $(TOP_DIR)/src/gb28181 \
  23 + -I $(TOP_DIR)/src/nvdec \
  24 + -I $(CUDA_ROOT)/include \
  25 +
  26 +LIBSPATH= -L $(JRTP_ROOT)/jthread/lib -l:libjthread.a \
  27 + -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a \
  28 + -L $(CUDA_ROOT)/lib64 -lcuda -lcudart -lnvcuvid -lcurand -lcublas -lnvjpeg \
  29 +
  30 +
  31 +CXXFLAGS= -g -O0 -fPIC $(INCLUDE) $(LIBSPATH) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl -Wwrite-strings
  32 +
  33 +
  34 +# 最终目标文件
  35 +TARGET:=$(LIB_DIR)/$(MODULE).a
  36 +
  37 +
  38 +# 默认最终目标
  39 +.PHONY:all
  40 +all:$(TARGET)
  41 +
  42 +# 生成最终目标
  43 +$(TARGET):$(OBJS) | $(LIB_DIR)
  44 + @echo -e "\e[32m""Linking static library $(TARGET)""\e[0m"
  45 + @echo -e "ar -rc $@ $^"
  46 + @ar -rc $@ $^
  47 +
  48 +# 若没有lib目录则自动生成
  49 +$(LIB_DIR):
  50 + @mkdir -p $@
  51 +
  52 +# 生成中间目标文件
  53 +$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp $(DEP_DIR)/%.d | $(OBJ_DIR) $(DEP_DIR)
  54 + @echo -e "\e[33m""Building object $@""\e[0m"
  55 + @echo -e "$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) $(INCS) $(LIBS) $(MACROS) -o $@ $<"
  56 +# @$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) $(INCS) $(LIBSPATH) $(MACROS) -o $@ $(MODULE_LIBS) $<
  57 + @$(CXX) -c $(DEPFLAGS) $(CXXFLAGS) $(INCS) $(LIBS) $(MACROS) -o $@ $<
  58 +
  59 +# 若没有obj目录则自动生成
  60 +$(OBJ_DIR):
  61 + @mkdir -p $@
  62 +
  63 +# 若没有.dep目录则自动生成
  64 +$(DEP_DIR):
  65 + @mkdir -p $@
  66 +
  67 +# 依赖文件会在生成中间文件的时候自动生成,这里只是为了防止报错
  68 +$(DEPS):
  69 +
  70 +# 引入中间目标文件头文件依赖关系
  71 +include $(wildcard $(DEPS))
  72 +
  73 +# 直接删除组件build目录
  74 +.PHONY:clean
  75 +clean:
  76 + @rm -rf $(BUILD_DIR)/$(MODULE)
src/decoder/interface/interface_headers.h 0 → 100644
  1 +#ifndef _INTERFACE_HEADERS_H_
  2 +#define _INTERFACE_HEADERS_H_
  3 +
  4 +
  5 +#include<string>
  6 +#include <queue>
  7 +#include <mutex>
  8 +
  9 +#include "DeviceMemory.hpp"
  10 +
  11 +using namespace std;
  12 +
  13 +/**************************************************
  14 +* 接口:DXDECODER_CALLBACK
  15 +* 功能:解码数据回调接口
  16 +* 参数:const dx_void * userPtr 用户自定义数据
  17 +* AVFrame * gpuFrame 解码结果帧数据,在设置的对应的gpu上,要十分注意这一点,尤其是多线程情况
  18 +* 返回:无
  19 +* 备注:当解码库数据源为实时流时(RTSP/GB28181),本接
  20 +* 口内不可进行阻塞/耗时操作。当解码库数据源为
  21 +* 非实时流时(本地/网络文件),本接口可以进行
  22 +* 阻塞/耗时操作
  23 +**************************************************/
  24 +typedef void(*POST_DECODE_CALLBACK)(const void * userPtr, DeviceMemory* devFrame);
  25 +
  26 +typedef void(*DECODE_FINISHED_CALLBACK)(const void* userPtr);
  27 +
  28 +typedef bool(*DECODE_REQUEST_STREAM_CALLBACK)(const char* deviceId);
  29 +
  30 +struct FFDecConfig{
  31 + string uri; // 视频地址
  32 + POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
  33 + DECODE_FINISHED_CALLBACK decode_finished_cbk; // 解码线程结束后的回调接口
  34 + string gpuid; // gpu id
  35 + bool force_tcp{true}; // 是否指定使用tcp连接
  36 + int skip_frame{1}; // 跳帧数
  37 + string dec_name;
  38 +
  39 + int port; // gb28181接收数据的端口号
  40 + DECODE_REQUEST_STREAM_CALLBACK request_stream_cbk; // gb28181请求流
  41 +};
  42 +
  43 +enum DECODER_TYPE{
  44 + DECODER_TYPE_GB28181,
  45 + DECODER_TYPE_FFMPEG,
  46 + DECODER_TYPE_DVPP
  47 +};
  48 +
  49 +struct FFImgInfo{
  50 + string dec_name;
  51 + int width;
  52 + int height;
  53 + unsigned char * pData;
  54 + int data_type; // 默认0=rgb, 1=nv12
  55 + long timestamp;
  56 + long index;
  57 +};
  58 +
  59 +#endif
0 \ No newline at end of file 60 \ No newline at end of file
src/decoder/interface/logger.hpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-21 11:07:11
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +
  9 +#pragma once
  10 +
  11 +// #include "define.hpp"
  12 +#include <spdlog/spdlog.h>
  13 +#include <spdlog/common.h>
  14 +#include <spdlog/details/file_helper.h>
  15 +#include <spdlog/details/null_mutex.h>
  16 +#include <spdlog/fmt/fmt.h>
  17 +#include <spdlog/sinks/base_sink.h>
  18 +#include <spdlog/details/os.h>
  19 +#include <spdlog/details/circular_q.h>
  20 +#include <spdlog/details/synchronous_factory.h>
  21 +
  22 +#include <set>
  23 +#include <chrono>
  24 +#include <cstdio>
  25 +#include <ctime>
  26 +#include <mutex>
  27 +#include <string>
  28 +#include <memory>
  29 +#include <vector>
  30 +
  31 +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
  32 +
  33 +#define LOG_TRACE_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_TRACE(logger, __VA_ARGS__);}
  34 +#define LOG_DEBUG_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_DEBUG(logger, __VA_ARGS__);}
  35 +#define LOG_WARN_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_WARN(logger, __VA_ARGS__);}
  36 +#define LOG_ERROR_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_ERROR(logger, __VA_ARGS__);}
  37 +#define LOG_INFO_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_INFO(logger, __VA_ARGS__);}
  38 +#define LOG_CRITICAL_WITH_LOGGER(logger, ...) {SPDLOG_LOGGER_CRITICAL(logger, __VA_ARGS__);}
  39 +
  40 +
  41 +// use fmt lib, e.g. LOG_WARN("warn log, {1}, {1}, {2}", 1, 2);
  42 +#define LOG_TRACE(msg, ...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::trace, msg, ##__VA_ARGS__)
  43 +#define LOG_DEBUG(msg, ...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::debug, msg, ##__VA_ARGS__)
  44 +#define LOG_INFO(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::info, msg, ##__VA_ARGS__)
  45 +#define LOG_WARN(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::warn, msg, ##__VA_ARGS__)
  46 +#define LOG_ERROR(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::err, msg, ##__VA_ARGS__)
  47 +#define LOG_FATAL(msg,...) spdlog::log({__FILENAME__, __LINE__, __FUNCTION__}, spdlog::level::critical, msg, ##__VA_ARGS__)
  48 +
  49 +
  50 +
  51 +namespace spdlog
  52 +{
  53 + namespace sinks
  54 + {
  55 + template<typename Mutex>
  56 + class easy_file_sink final : public base_sink<Mutex>
  57 + {
  58 + public:
  59 + easy_file_sink(filename_t base_filename, size_t max_size, size_t max_keep_days = 0)
  60 + : base_filename_(std::move(base_filename))
  61 + , max_size_(max_size)
  62 + , max_keep_days_(max_keep_days)
  63 + {
  64 + auto now = log_clock::now();
  65 + auto filename = gen_filename_by_daliy(base_filename_, now_tm(now));
  66 +
  67 + file_helper_.open(filename, false);
  68 + current_size_ = file_helper_.size();
  69 + rotation_tp_ = next_rotation_tp_();
  70 +
  71 + if (max_keep_days_ > 0)
  72 + {
  73 + filespath_q_.push_back(std::move(std::set<filename_t>()));
  74 + filespath_q_[filespath_q_.size() - 1].insert(filename);
  75 + }
  76 + }
  77 +
  78 + filename_t filename()
  79 + {
  80 + std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
  81 + return file_helper_.filename();
  82 + }
  83 +
  84 + protected:
  85 + void sink_it_(const details::log_msg &msg) override
  86 + {
  87 + memory_buf_t formatted;
  88 + base_sink<Mutex>::formatter_->format(msg, formatted);
  89 + current_size_ += formatted.size();
  90 +
  91 + auto time = msg.time;
  92 + if (time >= rotation_tp_)
  93 + {
  94 + file_helper_.close();
  95 + auto filename = gen_filename_by_daliy(base_filename_, now_tm(time));
  96 + file_helper_.open(filename, false);
  97 + current_size_ = file_helper_.size();
  98 + rotation_tp_ = next_rotation_tp_();
  99 +
  100 + {
  101 + filespath_q_.push_back(std::move(std::set<filename_t>()));
  102 + filespath_q_[filespath_q_.size() - 1].emplace(filename);
  103 + }
  104 +
  105 + // Do the cleaning only at the end because it might throw on failure.
  106 + if (max_keep_days_ > 0 && filespath_q_.size() > max_keep_days_)
  107 + delete_old_();
  108 + }
  109 + else if (current_size_ >= max_size_)
  110 + {
  111 + file_helper_.close();
  112 + auto src_name = gen_filename_by_daliy(base_filename_, now_tm(time));
  113 + auto target_name = gen_filename_by_filesize(base_filename_, now_tm(time), filespath_q_[filespath_q_.size() - 1].size());
  114 +
  115 + // rename file if failed then us `target_name` as src_name.
  116 + if (!rename_file_(src_name, target_name))
  117 + {
  118 + details::os::sleep_for_millis(200);
  119 + if (!rename_file_(src_name, target_name))
  120 + {
  121 + fprintf(stderr, "%s:%d rename %s to %s failed\n", __FILENAME__, __LINE__, src_name.c_str(), target_name.c_str());
  122 + src_name = target_name;
  123 + }
  124 + }
  125 +
  126 + filespath_q_[filespath_q_.size() - 1].emplace(src_name);
  127 + if (src_name != target_name)
  128 + filespath_q_[filespath_q_.size() - 1].emplace(target_name);
  129 +
  130 + file_helper_.open(src_name, false);
  131 + current_size_ = file_helper_.size();
  132 + rotation_tp_ = next_rotation_tp_();
  133 + }
  134 +
  135 + file_helper_.write(formatted);
  136 +
  137 +
  138 + }
  139 +
  140 + void flush_() override
  141 + {
  142 + file_helper_.flush();
  143 + }
  144 +
  145 + private:
  146 +
  147 + tm now_tm(log_clock::time_point tp)
  148 + {
  149 + time_t tnow = log_clock::to_time_t(tp);
  150 + return spdlog::details::os::localtime(tnow);
  151 + }
  152 +
  153 + /**
  154 + * @brief Get next day tm.
  155 + *
  156 + * @return log_clock::time_point
  157 + */
  158 + log_clock::time_point next_rotation_tp_()
  159 + {
  160 + auto now = log_clock::now();
  161 + tm date = now_tm(now);
  162 + date.tm_hour = 0;
  163 + date.tm_min = 0;
  164 + date.tm_sec = 0;
  165 + auto rotation_time = log_clock::from_time_t(std::mktime(&date));
  166 + if (rotation_time > now)
  167 + return rotation_time;
  168 + return {rotation_time + std::chrono::hours(24)};
  169 + }
  170 +
  171 + // Delete the file N rotations ago.
  172 + // Throw spdlog_ex on failure to delete the old file.
  173 + void delete_old_()
  174 + {
  175 + for (auto iter = filespath_q_.begin(); iter != filespath_q_.end();)
  176 + {
  177 + if (filespath_q_.size() <= max_keep_days_)
  178 + break;
  179 +
  180 + for (auto it = iter->begin(); it != iter->end(); ++it)
  181 + {
  182 + bool ok = details::os::remove_if_exists(*it) == 0;
  183 + if (!ok)
  184 + throw_spdlog_ex("Failed removing daily file " + details::os::filename_to_str(*it), errno);
  185 + }
  186 + filespath_q_.erase(iter);
  187 + }
  188 + }
  189 +
  190 + /* */
  191 + static filename_t gen_filename_by_daliy(const filename_t &filename, const tm &now_tm)
  192 + {
  193 + filename_t basename, ext;
  194 + std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
  195 + return fmt::format(SPDLOG_FILENAME_T("{}_{:04d}_{:02d}_{:02d}{}"),
  196 + basename,
  197 + now_tm.tm_year + 1900,
  198 + now_tm.tm_mon + 1,
  199 + now_tm.tm_mday,
  200 + ext);
  201 + }
  202 +
  203 + //
  204 + static filename_t gen_filename_by_filesize(const filename_t &filename, const tm &now_tm, const int &idx)
  205 + {
  206 + filename_t basename, ext;
  207 + std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
  208 + return fmt::format(SPDLOG_FILENAME_T("{}_{:04d}_{:02d}_{:02d}_{:02d}{:02d}{:02d}.{:d}{}"),
  209 + basename,
  210 + now_tm.tm_year + 1900,
  211 + now_tm.tm_mon + 1,
  212 + now_tm.tm_mday,
  213 + now_tm.tm_hour,
  214 + now_tm.tm_min,
  215 + now_tm.tm_sec,
  216 + idx,
  217 + ext);
  218 + }
  219 +
  220 + static bool rename_file_(const filename_t &src_filename, const filename_t &target_filename)
  221 + {
  222 + (void)details::os::remove(target_filename);
  223 + return details::os::rename(src_filename, target_filename) == 0;
  224 + }
  225 +
  226 + filename_t base_filename_;
  227 + log_clock::time_point rotation_tp_;
  228 + details::file_helper file_helper_;
  229 + std::size_t max_size_;
  230 + std::size_t max_keep_days_;
  231 + std::size_t current_size_;
  232 + // std::vector<<std::set<filename_t>> filespath_q_;
  233 + std::vector<std::set<filename_t>> filespath_q_;
  234 + };
  235 +
  236 + using easy_file_sink_mt = easy_file_sink<std::mutex>;
  237 + using easy_file_sink_st = easy_file_sink<details::null_mutex>;
  238 +
  239 + } // namespace sinks
  240 +
  241 + template<typename Factory = spdlog::synchronous_factory>
  242 + inline std::shared_ptr<logger> easy_logger_mt(
  243 + const std::string &logger_name, const filename_t &filename, size_t max_size, size_t max_keep_days = -1)
  244 + {
  245 + return Factory::template create<sinks::easy_file_sink_mt>(logger_name, filename, max_size, max_keep_days);
  246 + }
  247 +
  248 + template<typename Factory = spdlog::synchronous_factory>
  249 + inline std::shared_ptr<logger> easy_logger_st(
  250 + const std::string &logger_name, const filename_t &filename, size_t max_size, size_t max_keep_days = -1)
  251 + {
  252 + return Factory::template create<sinks::easy_file_sink_st>(logger_name, filename, max_size, max_keep_days);
  253 + }
  254 +
  255 +} // namespace spdlog
  256 +
  257 +
  258 +enum class LogLevel
  259 +{
  260 + CLOSE = -1,
  261 + TRACE = 0,
  262 + DEBUG = 1,
  263 + INFO = 2,
  264 + WARN = 3,
  265 + ERROR = 4,
  266 + FATAL = 5,
  267 +};
  268 +
  269 +
  270 +class LoggerGenerator
  271 +{
  272 +public:
  273 + static LoggerGenerator* get_instance()
  274 + {
  275 + static LoggerGenerator logger;
  276 + return &logger;
  277 + }
  278 +
  279 + void destory(LoggerGenerator *ptr)
  280 + {
  281 + if (ptr != nullptr)
  282 + {
  283 + delete ptr;
  284 + ptr = nullptr;
  285 + }
  286 + }
  287 +
  288 + std::shared_ptr<spdlog::logger> gen_logger(const LogLevel &level, const std::string &logger_name,
  289 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  290 + {
  291 + spdlog::level::level_enum spd_level;
  292 + if (LogLevel::TRACE == level)
  293 + spd_level = spdlog::level::trace;
  294 + else if (LogLevel::DEBUG == level)
  295 + spd_level = spdlog::level::debug;
  296 + else if (LogLevel::INFO == level)
  297 + spd_level = spdlog::level::info;
  298 + else if (LogLevel::WARN == level)
  299 + spd_level = spdlog::level::warn;
  300 + else if (LogLevel::ERROR == level)
  301 + spd_level = spdlog::level::err;
  302 + else if (LogLevel::FATAL == level)
  303 + spd_level = spdlog::level::critical;
  304 + else if (LogLevel::CLOSE == level)
  305 + spd_level = spdlog::level::off;
  306 +
  307 + auto sink_ptr = std::make_shared<spdlog::sinks::easy_file_sink_mt>(file_path, max_file_size, max_keep_days);
  308 + auto logger = std::make_shared<spdlog::logger>(logger_name, sink_ptr);
  309 + logger->set_level(spd_level);
  310 + logger->set_pattern("%s(%#): [%L %D %T.%e %P %t %!] %v");
  311 +
  312 + return logger;
  313 + }
  314 +
  315 + void set_default_logger(const LogLevel &level, const std::string &logger_name,
  316 + const std::string &file_name, size_t max_file_size, size_t max_keep_days)
  317 + {
  318 +
  319 + auto logger = gen_logger(level, logger_name, file_name, max_file_size, max_keep_days);
  320 + spdlog::set_default_logger(logger);
  321 + spdlog::set_level(logger->level());
  322 + spdlog::set_pattern("%s(%#): [%L %D %T.%e %P %t %!] %v");
  323 +
  324 + spdlog::flush_on(spdlog::level::trace);
  325 + spdlog::flush_every(std::chrono::seconds(1));
  326 + }
  327 +
  328 +};
  329 +
  330 +
  331 +static void set_default_logger(const LogLevel &level, const std::string &logger_name,
  332 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  333 +{
  334 + static LoggerGenerator loggerGenerator;
  335 + loggerGenerator.set_default_logger(level, logger_name, file_path, max_file_size, max_keep_days);
  336 +}
  337 +
  338 +
  339 +static std::shared_ptr<spdlog::logger> get_simple_logger(const LogLevel &level, const std::string &logger_name,
  340 + const std::string &file_path, size_t max_file_size, size_t max_keep_days)
  341 +{
  342 + static LoggerGenerator loggerGenerator;
  343 + return loggerGenerator.gen_logger(level, logger_name, file_path, max_file_size, max_keep_days);
  344 +}
src/decoder/interface/utiltools.hpp 0 → 100644
  1 +#ifndef _UTIL_TOOLS_HPP_
  2 +#define _UTIL_TOOLS_HPP_
  3 +
  4 +#include <chrono>
  5 +
  6 +using namespace std;
  7 +
  8 +namespace UtilTools{
  9 +
  10 + static long get_cur_time_ms() {
  11 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  12 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  13 + return tpMicro.time_since_epoch().count();
  14 + }
  15 +
  16 +}
  17 +
  18 +#endif
0 \ No newline at end of file 19 \ No newline at end of file
src/demo/demo.cpp 0 → 100644
  1 +#include "../ai_platform/stl_aiplatform.h"
  2 +#include <chrono>
  3 +
  4 +using namespace std;
  5 +
  6 +
  7 +void set_task_params(task_param &tparam, const unsigned &idx, const algorithm_type_t &algor_type) {
  8 + auto algor_init_params = new algor_init_config_param_t;
  9 + switch (algor_type) {
  10 + case algorithm_type_t::FACE_SNAPSHOT: {
  11 + auto basic_params = new algor_basic_config_param_t;
  12 + {
  13 + basic_params->algor_valid_rect.top_ = 0;
  14 + basic_params->algor_valid_rect.left_ = 0;
  15 + basic_params->algor_valid_rect.width_ = 1920;
  16 + basic_params->algor_valid_rect.height_ = 1080;
  17 +
  18 + basic_params->result_folder = "res/face";
  19 + ;
  20 + basic_params->result_folder_little = "res/face_little";
  21 + ;
  22 + }
  23 + auto algor_params = new algor_config_param_snapshot;
  24 + { algor_params->threshold = 0.5f; }
  25 +
  26 + algor_init_params->algor_param = algor_params;
  27 + algor_init_params->basic_param = basic_params;
  28 + } break;
  29 +
  30 + case algorithm_type_t::HUMAN_SNAPSHOT: {
  31 + auto basic_params = new algor_basic_config_param_t;
  32 + {
  33 + basic_params->algor_valid_rect.top_ = 0;
  34 + basic_params->algor_valid_rect.left_ = 0;
  35 + basic_params->algor_valid_rect.width_ = 1920;
  36 + basic_params->algor_valid_rect.height_ = 1080;
  37 +
  38 + basic_params->result_folder = "res/human";
  39 + basic_params->result_folder_little = "res/human_little";
  40 + }
  41 + auto algor_params = new algor_config_param_snapshot;
  42 + { algor_params->threshold = 0.5f; }
  43 +
  44 + algor_init_params->algor_param = algor_params;
  45 + algor_init_params->basic_param = basic_params;
  46 + } break;
  47 +
  48 + case algorithm_type_t::PEDESTRIAN_FALL: {
  49 + auto algor_params = new algor_config_param_pedestrian_fall;
  50 + { algor_params->threshold = 0.7f; }
  51 +
  52 + auto basic_params = new algor_basic_config_param_t;
  53 + {
  54 + basic_params->algor_valid_rect.top_ = 0;
  55 + basic_params->algor_valid_rect.left_ = 0;
  56 + basic_params->algor_valid_rect.width_ = 1920;
  57 + basic_params->algor_valid_rect.height_ = 1080;
  58 +
  59 + basic_params->result_folder = "res/fall";
  60 + basic_params->result_folder_little = "res/fall_little";
  61 + }
  62 +
  63 + algor_init_params->algor_param = algor_params;
  64 + algor_init_params->basic_param = basic_params;
  65 + } break;
  66 +
  67 + case algorithm_type_t::PEDESTRIAN_FIGHT: {
  68 + auto algor_params = new algor_config_param_pedestrian_fight;
  69 + {
  70 + algor_params->threshold = 0.7f;
  71 + algor_params->iou_threshold = 0.1f;
  72 + }
  73 +
  74 + auto basic_params = new algor_basic_config_param_t;
  75 + {
  76 +
  77 + basic_params->algor_valid_rect.top_ = 0;
  78 + basic_params->algor_valid_rect.left_ = 0;
  79 + basic_params->algor_valid_rect.width_ = 1920;
  80 + basic_params->algor_valid_rect.height_ = 1080;
  81 + basic_params->result_folder = "res/fight";
  82 + basic_params->result_folder_little = "res/fight_little";
  83 + }
  84 +
  85 + algor_init_params->algor_param = algor_params;
  86 + algor_init_params->basic_param = basic_params;
  87 + } break;
  88 +
  89 + case algorithm_type_t::HUMAN_GATHER: {
  90 +
  91 + auto algor_params = new algor_config_param_human_gather;
  92 + {
  93 + algor_params->frame_stride = 1;
  94 + // algor_params->human_count_threshold = 3;
  95 + algor_params->human_count_threshold = 1;
  96 + }
  97 +
  98 + auto basic_params = new algor_basic_config_param_t;
  99 + {
  100 + basic_params->algor_valid_rect.top_ = 0;
  101 + basic_params->algor_valid_rect.left_ = 0;
  102 + basic_params->algor_valid_rect.width_ = 1920;
  103 + basic_params->algor_valid_rect.height_ = 1080;
  104 + basic_params->result_folder = "res/gather";
  105 + basic_params->result_folder_little = "res/gather_little";
  106 + }
  107 +
  108 + algor_init_params->algor_param = algor_params;
  109 + algor_init_params->basic_param = basic_params;
  110 + } break;
  111 +
  112 + case algorithm_type_t::NO_REFLECTIVE_CLOTHING: {
  113 + auto algor_params = new algor_config_param_no_reflective_clothing;
  114 + {
  115 + algor_params->conf_threshold = 0.3f;
  116 + algor_params->m = 10;
  117 + algor_params->n = 6;
  118 + algor_params->pedestrian_confidence_threshold = 0.3f;
  119 + algor_params->pedestrian_min_height = 0;
  120 + algor_params->pedestrian_min_width = 0;
  121 + }
  122 +
  123 + auto basic_params = new algor_basic_config_param_t;
  124 + {
  125 + basic_params->algor_valid_rect.top_ = 0;
  126 + basic_params->algor_valid_rect.left_ = 0;
  127 + basic_params->algor_valid_rect.width_ = 1920;
  128 + basic_params->algor_valid_rect.height_ = 1080;
  129 + basic_params->result_folder = "res/no_reflective_clothing";
  130 + basic_params->result_folder_little = "res/no_reflective_clothing_little";
  131 + }
  132 +
  133 + algor_init_params->algor_param = algor_params;
  134 + algor_init_params->basic_param = basic_params;
  135 + } break;
  136 +
  137 + case algorithm_type_t::NO_SAFETY_HELMET: {
  138 + auto algor_params = new algor_config_param_no_safety_helmet;
  139 + {
  140 + algor_params->conf_threshold = 0.3f;
  141 + algor_params->m = 10;
  142 + algor_params->n = 6;
  143 + algor_params->pedestrian_confidence_threshold = 0.3f;
  144 + algor_params->pedestrian_min_height = 0;
  145 + algor_params->pedestrian_min_width = 0;
  146 + }
  147 +
  148 + auto basic_params = new algor_basic_config_param_t;
  149 + {
  150 + basic_params->algor_valid_rect.top_ = 0;
  151 + basic_params->algor_valid_rect.left_ = 0;
  152 + basic_params->algor_valid_rect.width_ = 1920;
  153 + basic_params->algor_valid_rect.height_ = 1080;
  154 + basic_params->result_folder = "res/no_safety_helmet";
  155 + basic_params->result_folder_little = "res/no_safety_helmet_little";
  156 + }
  157 +
  158 + algor_init_params->algor_param = algor_params;
  159 + algor_init_params->basic_param = basic_params;
  160 + } break;
  161 +
  162 + case algorithm_type_t::CALL_PHONE_DET: {
  163 + auto algor_params = new algor_config_param_call_phone;
  164 + {
  165 + algor_params->conf_threshold = 0.3f;
  166 + algor_params->m = 2;
  167 + algor_params->n = 1;
  168 + algor_params->pedestrian_confidence_threshold = 0.1f;
  169 + algor_params->pedestrian_min_height = 0;
  170 + algor_params->pedestrian_min_width = 0;
  171 + }
  172 +
  173 + auto basic_params = new algor_basic_config_param_t;
  174 + {
  175 + basic_params->algor_valid_rect.top_ = 0;
  176 + basic_params->algor_valid_rect.left_ = 0;
  177 + basic_params->algor_valid_rect.width_ = 1920;
  178 + basic_params->algor_valid_rect.height_ = 1080;
  179 + basic_params->result_folder = "res/call_phone";
  180 + basic_params->result_folder_little = "res/call_phone_little";
  181 + }
  182 +
  183 + algor_init_params->algor_param = algor_params;
  184 + algor_init_params->basic_param = basic_params;
  185 + } break;
  186 +
  187 + case algorithm_type_t::SMOKING_DET: {
  188 + auto algor_params = new algor_config_param_smoking;
  189 + {
  190 + algor_params->conf_threshold = 0.3f;
  191 + algor_params->m = 10;
  192 + algor_params->n = 1;
  193 + algor_params->pedestrian_confidence_threshold = 0.3f;
  194 + algor_params->pedestrian_min_height = 0;
  195 + algor_params->pedestrian_min_width = 0;
  196 + }
  197 +
  198 + auto basic_params = new algor_basic_config_param_t;
  199 + {
  200 + basic_params->algor_valid_rect.top_ = 0;
  201 + basic_params->algor_valid_rect.left_ = 0;
  202 + basic_params->algor_valid_rect.width_ = 1920;
  203 + basic_params->algor_valid_rect.height_ = 1080;
  204 + basic_params->result_folder = "res/smoking";
  205 + basic_params->result_folder_little = "res/smoking_little";
  206 + }
  207 +
  208 + algor_init_params->algor_param = algor_params;
  209 + algor_init_params->basic_param = basic_params;
  210 + } break;
  211 +
  212 + case algorithm_type_t::VEHICLE_SNAPSHOT: {
  213 +
  214 + auto basic_params = new algor_basic_config_param_t;
  215 + {
  216 + basic_params->algor_valid_rect.top_ = 0;
  217 + basic_params->algor_valid_rect.left_ = 0;
  218 + basic_params->algor_valid_rect.width_ = 1920;
  219 + basic_params->algor_valid_rect.height_ = 1080;
  220 + basic_params->result_folder = "res/vehicle";
  221 + basic_params->result_folder_little = "res/vehicle_little";
  222 + }
  223 +
  224 + auto algor_params = new algor_config_param_snapshot;
  225 + algor_params->threshold = 0.5f;
  226 + algor_params->snap_frame_interval = 5;
  227 +
  228 + algor_init_params->algor_param = algor_params;
  229 + algor_init_params->basic_param = basic_params;
  230 + } break;
  231 +
  232 + case algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT: {
  233 +
  234 + auto basic_params = new algor_basic_config_param_t;
  235 + {
  236 + basic_params->algor_valid_rect.top_ = 0;
  237 + basic_params->algor_valid_rect.left_ = 0;
  238 + basic_params->algor_valid_rect.width_ = 1920;
  239 + basic_params->algor_valid_rect.height_ = 1080;
  240 + basic_params->result_folder = "res/nonmotor";
  241 + basic_params->result_folder_little = "res/nonmotor_little";
  242 + }
  243 +
  244 + auto algor_params = new algor_config_param_snapshot;
  245 + { algor_params->threshold = 0.5f; }
  246 +
  247 + algor_init_params->algor_param = algor_params;
  248 + algor_init_params->basic_param = basic_params;
  249 + } break;
  250 +
  251 + case algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION: {
  252 + auto algor_params = new algor_config_param_takeaway_member_classification;
  253 + {
  254 + algor_params->m = 10;
  255 + algor_params->n = 2;
  256 + algor_params->threshold = 0.7f;
  257 + }
  258 +
  259 + auto basic_params = new algor_basic_config_param_t;
  260 + {
  261 + basic_params->algor_valid_rect.top_ = 0;
  262 + basic_params->algor_valid_rect.left_ = 0;
  263 + basic_params->algor_valid_rect.width_ = 1920;
  264 + basic_params->algor_valid_rect.height_ = 1080;
  265 + basic_params->result_folder = "res/takeaway";
  266 + basic_params->result_folder_little = "res/takeaway_little";
  267 + }
  268 +
  269 + algor_init_params->algor_param = algor_params;
  270 + algor_init_params->basic_param = basic_params;
  271 + } break;
  272 +
  273 + case algorithm_type_t::PEDESTRIAN_RETROGRADE: {
  274 + // 578 1300 600
  275 + auto algor_params = new algor_config_param_pedestrian_retrograde;
  276 + {
  277 + algor_params->conf_threshold = 0.5f;
  278 + algor_params->minmum_height = 10;
  279 + algor_params->minmum_width = 10;
  280 + algor_params->direction = 0;
  281 +
  282 + algor_params->px1 = 578;
  283 + algor_params->py1 = 600;
  284 +
  285 + algor_params->px2 = 1300;
  286 + algor_params->py2 = 600;
  287 + }
  288 +
  289 + auto basic_params = new algor_basic_config_param_t;
  290 + {
  291 + basic_params->algor_valid_rect.top_ = 0;
  292 + basic_params->algor_valid_rect.left_ = 0;
  293 + basic_params->algor_valid_rect.width_ = 1920;
  294 + basic_params->algor_valid_rect.height_ = 1080;
  295 + basic_params->result_folder = "res/pedestrian_retrograde";
  296 + basic_params->result_folder_little = "res/pedestrian_retrograde_little";
  297 + }
  298 +
  299 + algor_init_params->algor_param = algor_params;
  300 + algor_init_params->basic_param = basic_params;
  301 +
  302 + } break;
  303 +
  304 + case algorithm_type_t::VEHICLE_RETROGRADE: {
  305 + // 578 1300 600
  306 + auto algor_params = new algor_config_param_pedestrian_retrograde;
  307 + {
  308 + algor_params->conf_threshold = 0.5f;
  309 + algor_params->minmum_height = 10;
  310 + algor_params->minmum_width = 10;
  311 + algor_params->direction = 0;
  312 +
  313 + algor_params->px1 = 578;
  314 + algor_params->py1 = 600;
  315 +
  316 + algor_params->px2 = 1300;
  317 + algor_params->py2 = 600;
  318 + }
  319 +
  320 + auto basic_params = new algor_basic_config_param_t;
  321 + {
  322 + basic_params->algor_valid_rect.top_ = 0;
  323 +
  324 + basic_params->algor_valid_rect.left_ = 0;
  325 + basic_params->algor_valid_rect.width_ = 1920;
  326 + basic_params->algor_valid_rect.height_ = 1080;
  327 + basic_params->result_folder = "res/vehicle_retrograde";
  328 + basic_params->result_folder_little = "res/vehicle_retrograde_little";
  329 + }
  330 +
  331 + algor_init_params->algor_param = algor_params;
  332 + algor_init_params->basic_param = basic_params;
  333 +
  334 + } break;
  335 +
  336 + case algorithm_type_t::PEDESTRIAN_TRESPASS: {
  337 + // 578 1300 600
  338 + auto algor_params = new algor_config_param_pedestrian_trespass;
  339 + {
  340 + algor_params->conf_threshold = 0.5f;
  341 + algor_params->minmum_height = 64;
  342 + algor_params->minmum_width = 32;
  343 + algor_params->points_count = 4;
  344 +
  345 + algor_params->points[0].x_ = 200;
  346 + algor_params->points[0].y_ = 200;
  347 +
  348 + algor_params->points[1].x_ = 600;
  349 + algor_params->points[1].y_ = 200;
  350 +
  351 + algor_params->points[2].x_ = 600;
  352 + algor_params->points[2].y_ = 500;
  353 +
  354 + algor_params->points[3].x_ = 200;
  355 + algor_params->points[3].y_ = 500;
  356 + }
  357 +
  358 + auto basic_params = new algor_basic_config_param_t;
  359 + {
  360 + basic_params->algor_valid_rect.top_ = 0;
  361 + basic_params->algor_valid_rect.left_ = 0;
  362 + basic_params->algor_valid_rect.width_ = 1920;
  363 + basic_params->algor_valid_rect.height_ = 1080;
  364 + basic_params->result_folder = "res/pedestrian_trespass";
  365 + basic_params->result_folder_little = "res/pedestrian_trespass_little";
  366 + }
  367 +
  368 + algor_init_params->algor_param = algor_params;
  369 + algor_init_params->basic_param = basic_params;
  370 +
  371 + } break;
  372 +
  373 + case algorithm_type_t::VEHICLE_TRESPASS: {
  374 + // 578 1300 600
  375 + auto algor_params = new algor_config_param_vehicle_trespass;
  376 + {
  377 + algor_params->conf_threshold = 0.5f;
  378 + algor_params->minmum_height = 64;
  379 + algor_params->minmum_width = 64;
  380 + algor_params->points_count = 4;
  381 +
  382 + algor_params->points[0].x_ = 500;
  383 + algor_params->points[0].y_ = 500;
  384 +
  385 + algor_params->points[1].x_ = 1500;
  386 + algor_params->points[1].y_ = 500;
  387 +
  388 + algor_params->points[2].x_ = 1500;
  389 + algor_params->points[2].y_ = 900;
  390 +
  391 + algor_params->points[3].x_ = 500;
  392 + algor_params->points[3].y_ = 900;
  393 + }
  394 +
  395 + auto basic_params = new algor_basic_config_param_t;
  396 + {
  397 + basic_params->algor_valid_rect.top_ = 0;
  398 + basic_params->algor_valid_rect.left_ = 0;
  399 + basic_params->algor_valid_rect.width_ = 1920;
  400 + basic_params->algor_valid_rect.height_ = 1080;
  401 + basic_params->result_folder = "res/vehicle_trespass";
  402 + basic_params->result_folder_little = "res/vehicle_trespass_little";
  403 + }
  404 +
  405 + algor_init_params->algor_param = algor_params;
  406 + algor_init_params->basic_param = basic_params;
  407 +
  408 + } break;
  409 +
  410 + case algorithm_type_t::VIDEO_SNAPSHOT: {
  411 + auto basic_params = new algor_basic_config_param_t;
  412 + { basic_params->result_folder = "res/video_snapshot"; }
  413 + algor_init_params->basic_param = basic_params;
  414 + } break;
  415 +
  416 +
  417 + case algorithm_type_t::ROAD_WORK_DET: {
  418 +
  419 + auto algor_params = new algor_config_param_road_work;
  420 + {
  421 + algor_params->frame_stride = 5;
  422 + algor_params->rblock_count_threshold = 3;
  423 + // algor_params->frame_stride = 1;
  424 + // algor_params->rblock_count_threshold = 1;
  425 + }
  426 +
  427 + auto basic_params = new algor_basic_config_param_t;
  428 + {
  429 + basic_params->algor_valid_rect.top_ = 0;
  430 + basic_params->algor_valid_rect.left_ = 0;
  431 + // basic_params->algor_valid_rect.width_ = 1920;
  432 + // basic_params->algor_valid_rect.height_ = 1080;
  433 + basic_params->algor_valid_rect.width_ = 2560;
  434 + basic_params->algor_valid_rect.height_ = 1440;
  435 + basic_params->result_folder = "res/road_work";
  436 + basic_params->result_folder_little = "res/road_work_little";
  437 + }
  438 +
  439 + algor_init_params->algor_param = algor_params;
  440 + algor_init_params->basic_param = basic_params;
  441 + } break;
  442 +
  443 + case algorithm_type_t::VIDEO_TIMING_SNAPSHOT: {
  444 +
  445 + auto algor_params = new algor_config_param_road_work;
  446 + {
  447 + algor_params->frame_stride = 5;
  448 + }
  449 +
  450 + auto basic_params = new algor_basic_config_param_t;
  451 + {
  452 + basic_params->result_folder = "res/video_timing_snapshot";
  453 + }
  454 +
  455 + algor_init_params->algor_param = algor_params;
  456 + algor_init_params->basic_param = basic_params;
  457 + } break;
  458 +
  459 + default: {
  460 + if (algor_init_params != nullptr) {
  461 + delete algor_init_params;
  462 + algor_init_params = nullptr;
  463 + }
  464 + return;
  465 + } break;
  466 + }
  467 +
  468 + tparam.algor_config_params[idx].algor_type = algor_type;
  469 + tparam.algor_config_params[idx].algor_init_config_param = algor_init_params;
  470 +}
  471 +
  472 +static long long get_cur_time(){
  473 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  474 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  475 + return tpMicro.time_since_epoch().count();
  476 +}
  477 +
  478 +string createTask(void *handle, std::vector<algorithm_type_t> algor_vec, int gi){
  479 + task_param tparam;
  480 + // tparam.ipc_url = "rtsp://admin:ad123456@192.168.60.108:554/cam/realmonitor?channel=1&subtype=0";
  481 + // tparam.ipc_url = "/home/huchunming/data/caishenkezhan.mp4";
  482 + tparam.ipc_url = "/home/cmhu/data/Street.uvf";
  483 + // tparam.ipc_url = "rtsp://122.97.218.170:8604/openUrl/V5nXRHa?params=eyJwcm90b2NhbCI6InJ0c3AiLCJjbGllbnRUeXBlIjoib3Blbl9hcGkiLCJleHByaWVUaW1lIjotMSwicHJvdG9jb2wiOiJydHNwIiwiZXhwaXJlVGltZSI6MzAwLCJlbmFibGVNR0MiOnRydWUsImV4cGFuZCI6InN0YW5kYXJkPXJ0c3Amc3RyZWFtZm9ybT1ydHAiLCJhIjoiMTBjZjM4N2JjY2Y5NDg3YzhjNWYzNjE2M2ViMWUyNTJ8MXwwfDEiLCJ0IjoxfQ==";
  484 + tparam.algor_counts = algor_vec.size();
  485 + tparam.dec_type = 2;
  486 +
  487 + std::string task_id_str = "test_task_id_" + std::to_string(gi);
  488 + tparam.task_id = task_id_str.c_str();
  489 +
  490 + tparam.algor_config_params = new algor_config_param[tparam.algor_counts];
  491 +
  492 + for (size_t idx = 0; idx < algor_vec.size(); ++idx)
  493 + set_task_params(tparam, idx, algor_vec.at(idx));
  494 +
  495 + const int result_code = add_task(handle, tparam);
  496 + if (result_code != 0)
  497 + printf("[Error]: ");
  498 + printf("--- task_id: %s result code: %d\n", tparam.task_id, result_code);
  499 + return task_id_str;
  500 +}
  501 +
  502 +int main(int argc, char *argv[]) {
  503 + printf("new test\n");
  504 +
  505 + if (argc < 4) {
  506 + fprintf(stderr, "./xxx 0 2 10 1 ## [start_ai_id, end_ai_id) repeat_num gpu_id\n");
  507 + return -1;
  508 + }
  509 +
  510 + //! load params.
  511 + int start_id = atoi(argv[1]);
  512 + int end_id = atoi(argv[2]);
  513 + int repeat_num = atoi(argv[3]);
  514 + int gpuID = atoi(argv[4]);
  515 +
  516 + tsl_aiplatform_param vptParam;
  517 + vptParam.gpuid = gpuID;
  518 + vptParam.trt_serialize_file = "";
  519 +
  520 + vptParam.log_days = 1;
  521 + vptParam.log_level = AI_LOG_LEVEL_TRACE;
  522 + // vptParam.log_level = AI_LOG_LEVEL_DEBUG;
  523 + vptParam.log_mem = 64 * 1024 * 1024; // 64MB.
  524 + vptParam.log_path = "logs/main.log";
  525 + vptParam.vpt_thred = 0.45;
  526 + vptParam.rblock_thred = 0.4;
  527 +
  528 + void *handle;
  529 + int flag = tsl_aiplatform_init(&handle, vptParam);
  530 + if (0 != flag) {
  531 + printf("Init Failed! Error Code: %d\n", flag);
  532 + system("pause");
  533 + return 0;
  534 + } else {
  535 + printf("Init Success\n");
  536 + }
  537 +
  538 + std::vector<algorithm_type_t> algor_vec = {algorithm_type_t::FACE_SNAPSHOT, algorithm_type_t::HUMAN_SNAPSHOT,algorithm_type_t::ROAD_WORK_DET,
  539 + algorithm_type_t::VEHICLE_SNAPSHOT, algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT, algorithm_type_t::VIDEO_TIMING_SNAPSHOT};
  540 +
  541 + string task_id = createTask(handle, algor_vec, 0);
  542 +
  543 + while (getchar() != 'q');
  544 +
  545 + finish_task(handle, (char*)task_id.data(), 0);
  546 +
  547 + tsl_aiplatform_release(&handle);
  548 + printf("Done.\n");
  549 +
  550 + return 0;
  551 +}
0 \ No newline at end of file 552 \ No newline at end of file
src/helpers/gen_json.hpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Last Modified by: yangzilong
  4 + * @Date: 2021-11-24 18:25:14
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +
  9 +#pragma once
  10 +
  11 +#include <string>
  12 +#include "json/json.h"
  13 +#include "time_helper.hpp"
  14 +#include "../common/logger.hpp"
  15 +#include "../ai_platform/header.h"
  16 +#include "../ai_platform/common_header.h"
  17 +
  18 +namespace helpers
  19 +{
  20 + namespace gen_json
  21 + {
  22 +
  23 + static std::string ORI_IMAGE_PATH_PLACEHOLDER = "___ORI_IMAGE_PATH_PLACEHOLDER___";
  24 + static std::string ROI_IMAGE_PATH_PLACEHOLDER = "___ROI_IMAGE_PATH_PLACEHOLDER___";
  25 +
  26 + static auto get_builder(const int float_precision = 5) -> Json::StreamWriterBuilder
  27 + {
  28 + Json::StreamWriterBuilder builder;
  29 + builder["indentation" ] = "";
  30 + builder["emitUTF8" ] = true;
  31 + builder["precision"] = float_precision;
  32 + builder["precisionType"] = "decimal";
  33 + return builder;
  34 + }
  35 +
  36 + static std::string gen_delete_task_json(const std::string &taskid, int error_code)
  37 + {
  38 + Json::Value root;
  39 + root["task_id"] = taskid;
  40 + root["code"] = std::to_string(error_code);
  41 + return Json::writeString(get_builder(), root);
  42 + }
  43 +
  44 + static std::string gen_task_status_json(const std::vector<std::string> &taskids, const std::vector<int> &statues)
  45 + {
  46 + if (taskids.size() != statues.size())
  47 + {
  48 + LOG_ERROR("number of task_id must equal number of statues\n");
  49 + return "";
  50 + }
  51 +
  52 + Json::Value root;
  53 + for (int i = 0; i < taskids.size(); ++i)
  54 + {
  55 + Json::Value item;
  56 + item["task_id"] = taskids[i];
  57 + item["status"] = std::to_string(statues[i]);
  58 + root.append(item);
  59 + }
  60 +
  61 + return Json::writeString(get_builder(), root);
  62 + };
  63 +
  64 + static std::string gen_office_task_heart_beat_json(const std::vector<std::string> &taskids)
  65 + {
  66 + Json::Value root;
  67 + for (int i = 0; i < taskids.size(); ++i)
  68 + {
  69 + Json::Value item;
  70 + item["task_id"] = taskids[i];
  71 + root.append(item);
  72 + }
  73 +
  74 + return Json::writeString(get_builder(), root);
  75 + };
  76 +
  77 +
  78 + static std::string gen_face_detection_json(const std::string &taskid,
  79 + const int &objid, const std::string &roi_fpath, const std::string &ori_fpath,
  80 + const sy_rect &box, const float &score, const sy_point *kpts,
  81 + const int &n_kpts = 25)
  82 + {
  83 + Json::Value root;
  84 + root["task_id"] = taskid;
  85 + root["object_id"] = objid;
  86 + root["algor_type"] = (int)algorithm_type_t::FACE_SNAPSHOT;
  87 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  88 + {
  89 + Json::Value data;
  90 + data["snapshot_image_path"] = roi_fpath;
  91 + data["video_image_path"] = ori_fpath;
  92 +
  93 +
  94 + {
  95 + Json::Value boxes;
  96 + {
  97 + Json::Value boxNode;
  98 + boxNode["top"] = box.top_;
  99 + boxNode["left"] = box.left_;
  100 + boxNode["right"] = box.left_ + box.width_;
  101 + boxNode["bottom"] = box.top_ + box.height_;
  102 + boxNode["score"] = score;
  103 + {
  104 +
  105 + Json::Value kptsNode;
  106 + for (int i = 0; i < n_kpts; ++i)
  107 + {
  108 + Json::Value kp;
  109 + kp.append(kpts[i].x_);
  110 + kp.append(kpts[i].y_);
  111 + kptsNode.append(kp);
  112 + }
  113 + boxNode["ldmk"] = kptsNode;
  114 + }
  115 + boxes.append(boxNode);
  116 + }
  117 + data["box"] = boxes;
  118 + }
  119 + root["data"] = data;
  120 + }
  121 +
  122 + return Json::writeString(get_builder(), root);
  123 + };
  124 +
  125 + static std::string gen_snapshot_json(const algorithm_type_t &algor_type, video_object_snapshot const &algo_result)
  126 + {
  127 + Json::Value root;
  128 + root["task_id"] = algo_result.task_id;
  129 + root["algor_type"] = (int)algor_type;
  130 + root["object_id"] = algo_result.object_id;
  131 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  132 +
  133 + {
  134 + Json::Value dataNode;
  135 + Json::Value boxNode;
  136 + {
  137 + Json::Value boxNodeItem;
  138 + boxNodeItem["top"] = algo_result.obj_info.res_top;
  139 + boxNodeItem["left"] = algo_result.obj_info.res_left;
  140 + boxNodeItem["right"] = algo_result.obj_info.res_right;
  141 + boxNodeItem["bottom"] = algo_result.obj_info.res_bottom;
  142 + boxNodeItem["score"] = algo_result.obj_info.res_prob;
  143 + boxNodeItem["index"] = algo_result.obj_info.res_index; //221212byzsh
  144 +
  145 + boxNode.append(boxNodeItem);
  146 + dataNode["box"] = boxNode;
  147 + }
  148 + dataNode["video_image_path"] = algo_result.video_image_path;
  149 + dataNode["snapshot_image_path"] = algo_result.snapshot_image_path;
  150 + root["data"] = dataNode;
  151 +
  152 + }
  153 + return Json::writeString(get_builder(), root);
  154 + };
  155 +
  156 + static std::string gen_multi_obj_json(const algorithm_type_t &algor_type, video_object_snapshot const &algo_result)
  157 + {
  158 + Json::Value root;
  159 + root["task_id"] = algo_result.task_id;
  160 + root["algor_type"] = (int)algor_type;
  161 + root["object_id"] = algo_result.object_id;
  162 + root["bfinished"] = algo_result.nFinished;
  163 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  164 +
  165 + if(algo_result.nFinished == 0){
  166 + Json::Value dataNode;
  167 + Json::Value boxNode;
  168 +
  169 + Json::Value boxNodeItem;
  170 + boxNodeItem["top"] = algo_result.obj_info.res_top;
  171 + boxNodeItem["left"] = algo_result.obj_info.res_left;
  172 + boxNodeItem["right"] = algo_result.obj_info.res_right;
  173 + boxNodeItem["bottom"] = algo_result.obj_info.res_bottom;
  174 + boxNodeItem["score"] = algo_result.obj_info.res_prob;
  175 + boxNodeItem["index"] = algo_result.obj_info.res_index; //221212byzsh
  176 + boxNode.append(boxNodeItem);
  177 +
  178 + dataNode["box"] = boxNode;
  179 +
  180 + dataNode["video_image_path"] = algo_result.video_image_path;
  181 + dataNode["snapshot_image_path"] = algo_result.snapshot_image_path;
  182 + root["data"] = dataNode;
  183 + }
  184 +
  185 + return Json::writeString(get_builder(), root);
  186 + };
  187 +
  188 + static std::string gen_generic_json(const std::string& taskId, long object_id,
  189 + const box_t &box,
  190 + const algorithm_type_t &algor_type,
  191 + const std::string &image_path)
  192 + {
  193 + Json::Value root;
  194 + root["task_id"] = taskId;
  195 + root["object_id"] = int(object_id);
  196 + root["algor_type"] = static_cast<int>(algor_type);
  197 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  198 + {
  199 + Json::Value dataNode;
  200 + Json::Value boxNode;
  201 + {
  202 + Json::Value boxNodeItem;
  203 + boxNodeItem["top"] = box.top;
  204 + boxNodeItem["left"] = box.left;
  205 + boxNodeItem["right"] = box.right;
  206 + boxNodeItem["bottom"] = box.bottom;
  207 + boxNodeItem["score"] = box.score;
  208 +
  209 + boxNode.append(boxNodeItem);
  210 + dataNode["box"] = boxNode;
  211 + }
  212 +
  213 + dataNode["video_image_path"] = ORI_IMAGE_PATH_PLACEHOLDER;
  214 + dataNode["snapshot_image_path"] = ("" == image_path) ? ROI_IMAGE_PATH_PLACEHOLDER : image_path;
  215 + root["data"] = dataNode;
  216 + }
  217 +
  218 +
  219 + return Json::writeString(get_builder(), root);
  220 + }
  221 +
  222 +
  223 + static std::string gen_retrograde_json(const std::string& taskId, int object_id,
  224 + const box_t &box,
  225 + const algorithm_type_t &algor_type,
  226 + const std::string &image_path = "")
  227 + {
  228 + return gen_generic_json(taskId, object_id, box, algor_type, image_path);
  229 + }
  230 +
  231 + static std::string gen_pedestrian_safety_json(const std::string& taskId, int object_id,
  232 + const box_t &box,
  233 + const algorithm_type_t &algor_type,
  234 + const std::string &image_path = "")
  235 + {
  236 + return gen_generic_json(taskId, object_id, box, algor_type, image_path);
  237 + }
  238 +
  239 +
  240 + static std::string gen_takeaway_member_cls_json(const std::string& taskId, int object_id,
  241 + const box_t &box, const int &category,
  242 + const std::string &image_path = "")
  243 + {
  244 + return gen_generic_json(taskId, object_id, box, algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION, image_path);
  245 + }
  246 +
  247 + static std::string gen_human_gather_json(const std::string& taskId, std::vector<box_t> boxes, const std::string &image_path)
  248 + {
  249 + Json::Value root;
  250 + root["task_id"] = taskId;
  251 + root["algor_type"] = (int)algorithm_type_t::HUMAN_GATHER;
  252 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  253 + {
  254 + Json::Value dataNode;
  255 + dataNode["snapshot_image_path"] = "";
  256 + dataNode["video_image_path"] = ("" == image_path) ? ORI_IMAGE_PATH_PLACEHOLDER : image_path;
  257 +
  258 + {
  259 + Json::Value boxesNode;
  260 + for (auto &box: boxes)
  261 + {
  262 + Json::Value boxNode;
  263 + boxNode["top"] = box.top;
  264 + boxNode["left"] = box.left;
  265 + boxNode["right"] = box.right;
  266 + boxNode["bottom"] = box.bottom;
  267 + boxNode["score"] = box.score;
  268 + boxesNode.append(boxNode);
  269 + }
  270 + dataNode["box"] = boxesNode;
  271 + }
  272 + root["data"] = dataNode;
  273 + }
  274 + return Json::writeString(get_builder(), root);
  275 + }
  276 +
  277 + // added by zsh 220802 用于视频快照接口
  278 + static std::string gen_screen_json(const std::string &taskid, const std::string &ori_fpath)
  279 + {
  280 + Json::Value root;
  281 + root["task_id"] = taskid;
  282 + root["algor_type"] = (int)algorithm_type_t::VIDEO_SNAPSHOT;
  283 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  284 + root["video_snapshot_path"] = ori_fpath;
  285 + return Json::writeString(get_builder(), root);
  286 + };
  287 +
  288 + static std::string gen_boxes_json(const std::string& taskId, int algorithm_type, std::vector<box_t> boxes, const std::string &image_path){
  289 + Json::Value root;
  290 + root["task_id"] = taskId;
  291 + root["algor_type"] = algorithm_type;
  292 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  293 + {
  294 + Json::Value dataNode;
  295 + dataNode["snapshot_image_path"] = "";
  296 + dataNode["video_image_path"] = ("" == image_path) ? ORI_IMAGE_PATH_PLACEHOLDER : image_path;
  297 +
  298 + {
  299 + Json::Value boxesNode;
  300 + for (auto &box: boxes)
  301 + {
  302 + Json::Value boxNode;
  303 + boxNode["top"] = box.top;
  304 + boxNode["left"] = box.left;
  305 + boxNode["right"] = box.right;
  306 + boxNode["bottom"] = box.bottom;
  307 + boxNode["score"] = box.score;
  308 + boxesNode.append(boxNode);
  309 + }
  310 + dataNode["box"] = boxesNode;
  311 + }
  312 + root["data"] = dataNode;
  313 + }
  314 + return Json::writeString(get_builder(), root);
  315 + }
  316 +
  317 + // 221026byzsh 施工占道
  318 + static std::string gen_road_work_json(const std::string& taskId, std::vector<box_t> boxes, const std::string &image_path)
  319 + {
  320 + return gen_boxes_json(taskId, (int)algorithm_type_t::ROAD_WORK_DET, boxes, image_path);
  321 + }
  322 +
  323 + // added by zsh 230220 用于视频定时抓拍
  324 + static std::string gen_vtsnapshot_json(const std::string &taskid, const std::string &ori_fpath)
  325 + {
  326 + Json::Value root;
  327 + root["task_id"] = taskid;
  328 + root["algor_type"] = (int)algorithm_type_t::VIDEO_TIMING_SNAPSHOT;
  329 + root["timestamp_ms"] = std::to_string(timer::get_timestamp<std::chrono::milliseconds>());
  330 + root["video_snapshot_path"] = ori_fpath;
  331 + return Json::writeString(get_builder(), root);
  332 + };
  333 +
  334 + } // namespace gen_json
  335 +
  336 +} // namespace helpers
src/helpers/os_helper.hpp 0 → 100644
  1 +
  2 +#pragma once
  3 +#include <mutex>
  4 +#include <queue>
  5 +#include <memory>
  6 +#include <condition_variable>
  7 +
  8 +
  9 +namespace helpers
  10 +{
  11 + namespace os
  12 + {
  13 +
  14 +#if defined(_WIN32)
  15 + static std::string sep = "\\";
  16 +#else
  17 + static std::string sep = "/";
  18 +#endif
  19 +
  20 +
  21 + } // namespace buffer
  22 +} // namespace helpers
  23 +
src/helpers/time_helper.hpp 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-17 17:45:43
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#ifndef __OLFIELD_UTILS_TIMER_HPP__
  9 +#define __OLFIELD_UTILS_TIMER_HPP__
  10 +
  11 +
  12 +#include <chrono>
  13 +#include <string>
  14 +
  15 +#include <mutex>
  16 +#include <atomic>
  17 +#include <thread>
  18 +#include <unordered_map>
  19 +#include <spdlog/spdlog.h>
  20 +
  21 +using namespace std;
  22 +
  23 +namespace helpers
  24 +{
  25 + namespace timer
  26 + {
  27 +
  28 + template <typename T = std::chrono::seconds>
  29 + static inline long long get_timestamp()
  30 + {
  31 + auto now = std::chrono::system_clock::now();
  32 + return std::chrono::duration_cast<T>(now.time_since_epoch()).count();
  33 + }
  34 +
  35 + static long long get_cur_time_ms(){
  36 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  37 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  38 +
  39 + return tpMicro.time_since_epoch().count();
  40 + }
  41 +
  42 + static std::string get_date(bool with_time = false)
  43 + {
  44 + std::chrono::system_clock::time_point t = std::chrono::system_clock::now();
  45 + auto as_time_t = std::chrono::system_clock::to_time_t(t);
  46 + struct tm tm;
  47 + #if defined(WIN32) || defined(_WINDLL)
  48 + localtime_s(&tm, &as_time_t); // win api thread safe, but std::localtime can't thread safe.
  49 + #else
  50 + localtime_r(&as_time_t, &tm); // linux api thread safe.
  51 + #endif
  52 + char buf[256]{0};
  53 + if (with_time)
  54 + snprintf(buf, sizeof(buf), "%04d%02d%02d_%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
  55 + else
  56 + snprintf(buf, sizeof(buf), "%04d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
  57 + return std::string(buf);
  58 + }
  59 +
  60 + } // namespace timer
  61 +} // namespace helpers
  62 +
  63 +
  64 +
  65 +#endif // __OLFIELD_UTILS_TIMER_HPP__
  66 +
src/linux/test/Makefile 0 → 100644
  1 +CC = gcc
  2 +XX = c++
  3 +
  4 +TARGET = start
  5 +
  6 +PROJ_ALL_PATH = $(PWD)/../../..
  7 +CUR_PROJ_PATH = $(PWD)/../..
  8 +OPENCV_PATH = $(PROJ_ALL_PATH)/third_party/opencv_4_1
  9 +ACL_PATH = $(ASCEND_AICPU_PATH)/acllib
  10 +
  11 +INCLUDES = -I$(PROJ_ALL_PATH)/common \
  12 + -I$(PROJ_ALL_PATH)/common/dvpp \
  13 + -I$(CUR_PROJ_PATH)/src \
  14 + -I$(OPENCV_PATH)/include \
  15 + -I$(OPENCV_PATH)/include/opencv2 \
  16 + -I$(ACL_PATH)/include \
  17 +
  18 +CFLAGS = -O3 -std=c++11 $(INCLUDES) -DENABLE_DVPP_INTERFACE -D_GLIBCXX_USE_CXX11_ABI=0
  19 +
  20 +local_shared_libs_dirs := \
  21 + $(OPENCV_PATH)/lib \
  22 + $(CUR_PROJ_PATH)/linux \
  23 + $(ACL_PATH)/lib64 \
  24 +
  25 +local_shared_libs := \
  26 + opencv_world \
  27 + vpt_det \
  28 + ascendcl \
  29 + acl_dvpp \
  30 +
  31 +SHARED_LIBRARIES := $(foreach shared_lib, $(local_shared_libs), -l$(shared_lib))
  32 +SHARED_LIBRARIES_DIRS := $(foreach shared_lib_dir, $(local_shared_libs_dirs), -L$(shared_lib_dir) -Wl,-z,relro,-z,now,-z,noexecstack,-rpath-link,$(shared_lib_dir))
  33 +
  34 +SRCS := $(wildcard $(CUR_PROJ_PATH)/src/test/*.cpp)
  35 +SRCS += $(wildcard $(PROJ_ALL_PATH)/common/dvpp/*.cpp)
  36 +
  37 +DIRS := $(notdir $(SRCS))
  38 +OBJS := $(patsubst %cpp, %o, $(DIRS))
  39 +
  40 +all: $(TARGET)
  41 +
  42 +$(TARGET):$(OBJS)
  43 + $(XX) $(CFLAGS) -o $@ $^ $(SHARED_LIBRARIES_DIRS) $(SHARED_LIBRARIES)
  44 +%.o:$(CUR_PROJ_PATH)/src/test/%.cpp
  45 + $(XX) $(CFLAGS) -c $<
  46 +%.o:$(PROJ_ALL_PATH)/common/dvpp/%.cpp
  47 + $(XX) $(CFLAGS) -c $<
  48 +
  49 +clean:
  50 + @rm -f $(TARGET)
  51 + @rm -f $(OBJS)
src/readme.txt 0 → 100644
  1 +人车物检测_x86_310p_v0.0.1.20230316_without_timelimit
  2 +
  3 +支持系统:
  4 + Atlas x86 linux
  5 +文件清单:
  6 + vpt.h: 接口文件
  7 + libvpt_det.so: 依赖库文件
  8 + models/vpt0715_310p.om: 模型文件
  9 + test/: 测试文件
  10 + test.cpp: 调用示例
  11 + 0_38863.jpg,datacasia_20160821_003198.jpg:测试数据
  12 + list.txt: 测试图片列表
  13 + Atlas人车物检测SDK说明_v0.0.0.pdf: SDK说明文档
  14 +
  15 +更新内容:
  16 + -2023.03.16 编译ascend310p x86版本
  17 +
  18 +注意事项说明:
  19 + - 当前版本跟踪前三帧无结果输出
  20 +
  21 +中科院自动化所 模式识别实验室图像视频组
  22 +
  23 +2023年03月16日
0 \ No newline at end of file 24 \ No newline at end of file
src/reprocessing_module/save_snapshot_reprocessing.cpp 0 → 100644
  1 +#include "save_snapshot_reprocessing.h"
  2 +#include <thread>
  3 +
  4 +#include "opencv2/opencv.hpp"
  5 +#include <opencv2/imgproc/types_c.h>
  6 +#include <algorithm>
  7 +#include "../common/logger.hpp"
  8 +#include "../util/JpegUtil.h"
  9 +#include "../util/vpc_util.h"
  10 +
  11 +const bool DRAW_ON_IMG = false;
  12 +
  13 +int save_img_thread_process(void* param) {
  14 + save_snapshot_reprocessing *pThreadParam = (save_snapshot_reprocessing *)param;
  15 + if (pThreadParam != nullptr){
  16 + pThreadParam->save_img_process();
  17 + }
  18 + return 0;
  19 +}
  20 +
  21 +// 初始化快照保存模块 开启图片保存线程
  22 +save_snapshot_reprocessing::save_snapshot_reprocessing(int devId) {
  23 +#ifdef POST_USE_RABBITMQ
  24 + callback_ = nullptr;
  25 +#endif
  26 +
  27 + bFinish = false;
  28 + m_save_img_thread = std::thread(save_img_thread_process, this);
  29 +
  30 + m_devId = devId;
  31 + DVPP_UTIL::dvpp_jpeg_init(m_devId);
  32 +}
  33 +
  34 +save_snapshot_reprocessing::~save_snapshot_reprocessing(){
  35 + // 结束线程
  36 + bFinish = true;
  37 + m_save_img_thread.join();
  38 + DVPP_UTIL::dvpp_jpeg_release();
  39 +}
  40 +
  41 +// 释放资源
  42 +void save_snapshot_reprocessing::save_snapshot_reprocessing_release() {
  43 +
  44 + std::unique_lock<std::mutex> l(waitforsave_img_queue_mutex);
  45 +
  46 + while (!waitforsave_img_queue.empty()) {
  47 + ImgSaveInfo cur_image = waitforsave_img_queue.front();
  48 + waitforsave_img_queue.pop();
  49 +
  50 + if(!cur_image.file_path.empty()){
  51 + dvpp_img_release(cur_image.img_info);
  52 + }
  53 + }
  54 +
  55 + l.unlock();
  56 +}
  57 +
  58 +#ifdef POST_USE_RABBITMQ
  59 +
  60 +// 设置MQ返回回调函数 方便内部调用MQ推送结果
  61 +void save_snapshot_reprocessing::set_callback(callback_t cb) {
  62 + callback_ = cb;
  63 +}
  64 +
  65 +#endif // #ifdef POST_USE_RABBITMQ
  66 +
  67 +
  68 +void save_snapshot_reprocessing::reprocessing_process_wo_locus_async(ImgSaveInfo saveInfo){
  69 +
  70 + // dvpp_img_release(saveInfo.img_info);
  71 + // return;
  72 +
  73 + while(!bFinish){
  74 + waitforsave_img_queue_mutex.lock();
  75 + if(waitforsave_img_queue.size() > 100){
  76 + waitforsave_img_queue_mutex.unlock();
  77 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  78 + continue;
  79 + }
  80 + waitforsave_img_queue.push(saveInfo);
  81 + waitforsave_img_queue_mutex.unlock();
  82 + break;
  83 + }
  84 +
  85 +}
  86 +
  87 +void save_snapshot_reprocessing::save_img_process() {
  88 + while (true) {
  89 + if (bFinish){
  90 + break;
  91 + }
  92 +
  93 + std::this_thread::sleep_for(std::chrono::milliseconds(2));
  94 + std::unique_lock<std::mutex> l(waitforsave_img_queue_mutex);
  95 + if (!waitforsave_img_queue.empty()) {
  96 + LOG_DEBUG("waitforsave_image_queue size: {}", waitforsave_img_queue.size());
  97 + ImgSaveInfo cur_image = waitforsave_img_queue.front();
  98 + waitforsave_img_queue.pop();
  99 + l.unlock();
  100 +
  101 + if(!cur_image.file_path.empty()){
  102 + DVPP_UTIL::dvpp_jpeg_encode(cur_image.img_info.pic_desc, cur_image.file_path);
  103 + }
  104 + dvpp_img_release(cur_image.img_info);
  105 +
  106 +#ifdef POST_USE_RABBITMQ
  107 + if (callback_ != nullptr && cur_image.json_str.length() > 0) {
  108 + // LOG_DEBUG("mq publish process 00000000000000000");
  109 + callback_(cur_image.json_str.c_str());
  110 + // LOG_DEBUG("mq publish process 11111111111111111");
  111 + }
  112 +#endif
  113 +
  114 + } else {
  115 + l.unlock();
  116 + }
  117 +
  118 + }
  119 +}
src/reprocessing_module/save_snapshot_reprocessing.h 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-14 17:51:04
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#pragma once
  9 +#include "opencv2/opencv.hpp"
  10 +#include "opencv2/highgui/highgui.hpp"
  11 +#include <string.h>
  12 +#include <queue>
  13 +#include <mutex>
  14 +#include <condition_variable>
  15 +#include <thread>
  16 +
  17 +#include "../ai_platform/det_obj_header.h"
  18 +#include "../util/vpc_util.h"
  19 +
  20 +#ifdef POST_USE_RABBITMQ
  21 +#include "post_reprocessing.hpp"
  22 +#include <memory>
  23 +#endif // #ifdef POST_USE_RABBITMQ
  24 +
  25 +using namespace std;
  26 +
  27 +class DeviceMemory;
  28 +
  29 +struct ImgSaveInfo{
  30 + string file_path {""};
  31 + vpc_img_info img_info;
  32 + string json_str {""};
  33 +};
  34 +
  35 +class save_snapshot_reprocessing
  36 +{
  37 +public:
  38 + save_snapshot_reprocessing(int devId);
  39 + ~save_snapshot_reprocessing();
  40 + void save_snapshot_reprocessing_release();
  41 +
  42 +#ifdef POST_USE_RABBITMQ
  43 + void set_callback(callback_t cb);
  44 +#endif
  45 +
  46 + void reprocessing_process_wo_locus_async(ImgSaveInfo saveInfo);
  47 +
  48 +public:
  49 + void save_img_process();
  50 +
  51 +private:
  52 +
  53 + queue<ImgSaveInfo> waitforsave_img_queue;
  54 + mutable std::mutex waitforsave_img_queue_mutex;
  55 + std::thread m_save_img_thread;
  56 +
  57 + bool bFinish = false;
  58 + int m_devId;
  59 +
  60 +#ifdef POST_USE_RABBITMQ
  61 + callback_t callback_;
  62 + std::shared_ptr<mq::post_rabbitmq_reprocessing> rbmq_handler_;
  63 +#endif
  64 +};
src/reprocessing_module/snapshot_reprocessing.cpp 0 → 100644
  1 +#include "snapshot_reprocessing.h"
  2 +
  3 +#include "../common/logger.hpp"
  4 +#include "../ai_platform/mvpt_process_assist.h"
  5 +#include "../decoder/interface/DeviceMemory.hpp"
  6 +
  7 +
  8 +snapshot_reprocessing::snapshot_reprocessing()
  9 +{
  10 + m_task_param_manager = task_param_manager::getInstance();
  11 +
  12 + algor_index_table["human"] = { (int)det_class_label_t::HUMAN };
  13 + algor_index_table["nonmotor_vehicle"] = { (int)det_class_label_t::BICYCLE, (int)det_class_label_t::MOTOCYCLE, (int)det_class_label_t::TRICYCLE };
  14 + algor_index_table["vehicle"] = { (int)det_class_label_t::SMALL_CAR, (int)det_class_label_t::LARGE_CAR, (int)det_class_label_t::TRUCK, (int)det_class_label_t::TRACTOR, (int)det_class_label_t::MEDIUM_BUS };
  15 +}
  16 +
  17 +static void box_expansion(video_object_info& obj_info, float expand_ratio, int frame_width, int frame_height){
  18 + int origin_width = obj_info.right - obj_info.left;
  19 + int origin_height = obj_info.bottom - obj_info.top;
  20 +
  21 + int expansion_width = origin_width * expand_ratio;
  22 + int expansion_height = origin_height * expand_ratio;
  23 +
  24 + obj_info.left = max(obj_info.left - expansion_width, 0);
  25 + obj_info.top = max(obj_info.top - expansion_height, 0);
  26 + obj_info.right = min(obj_info.right + expansion_width, frame_width - 1);
  27 + obj_info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
  28 +}
  29 +
  30 +/* 获取人车物目标快照图 */
  31 +vector<multi_obj_data_t> snapshot_reprocessing::get_vehicle_snapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result>& ol_det_result, int skip_frame)
  32 +{
  33 + vector<string> task_in_play_id;
  34 + sy_img* images;
  35 +
  36 + // 过滤出车辆
  37 + filter_vehicle(vec_devMem, ol_det_result);
  38 +
  39 + map<string, algor_open_config_param> && algor_config_param = m_task_param_manager->get_task_algor_params();
  40 + map<string, map<algo_type, task_param_manager::algo_param_type_t_*>> && algor_param = m_task_param_manager->get_task_other_params();
  41 +
  42 + vector<multi_obj_data_t> results;
  43 + int idx = 0;
  44 + for (auto memPtr : vec_devMem)
  45 + {
  46 + string task_id = memPtr->getId();
  47 + map<string, std::vector<video_object_info>> taskid_to_obj;
  48 + if (algor_config_param.count(task_id) && algor_config_param[task_id].vehicle_algors.count(algorithm_type_t::VEHICLE_SNAPSHOT))
  49 + {
  50 + task_param_manager::algo_param_type_t_* cur_task_params = algor_param[task_id][algorithm_type_t::VEHICLE_SNAPSHOT];
  51 +
  52 + // 同一目标间隔多少帧保存
  53 + int snap_frame_interval = ((algor_config_param_snapshot*)cur_task_params->algor_param)->snap_frame_interval;
  54 +
  55 + onelevel_det_result &cur_task_ol_detres = ol_det_result[idx];
  56 +
  57 + for (int c = 0; c < cur_task_ol_detres.obj_count; c++)
  58 + {
  59 + det_objinfo det_obj = cur_task_ol_detres.obj[c];
  60 + if(snap_frame_interval > 0 && det_obj.num % snap_frame_interval >= skip_frame){
  61 + continue;
  62 + }
  63 + int type_index = det_obj.index;
  64 + if ((type_index == 4 || type_index == 5 || type_index == 6 || type_index ==7 || type_index ==8)
  65 + && snapshot_legal_inarea(cur_task_params->basic_param->algor_valid_rect, det_obj.left, det_obj.top, det_obj.right, det_obj.bottom))
  66 + {
  67 + video_object_info obj_info;
  68 + obj_info.top = det_obj.top;
  69 + obj_info.left = det_obj.left;
  70 + obj_info.right = det_obj.right;
  71 + obj_info.bottom = det_obj.bottom;
  72 + obj_info.confidence = det_obj.confidence;
  73 + obj_info.index = type_index;
  74 + obj_info.object_id = det_obj.id;
  75 +
  76 + int frame_height = memPtr->getHeight();
  77 + int frame_width = memPtr->getWidth();
  78 + box_expansion(obj_info, EXPANSION_PROPORTION, frame_width, frame_height);
  79 +
  80 + taskid_to_obj[task_id].emplace_back(std::move(obj_info));
  81 + }
  82 + }
  83 +
  84 + if (taskid_to_obj.size() > 0)
  85 + {
  86 + static long long gid_ = 0;
  87 +
  88 + multi_obj_data_t data;
  89 + data.memPtr = memPtr; // modified byzsh
  90 + data.task_id = task_id;
  91 + data.objs = std::move(taskid_to_obj[task_id]);
  92 + data.id = gid_++;
  93 + results.emplace_back(std::move(data));
  94 + LOG_TRACE("{} {} snap_frame_interval:{}", task_id.c_str(), (int)algorithm_type_t::VEHICLE_SNAPSHOT, snap_frame_interval);
  95 + }
  96 + }
  97 +
  98 + idx++;
  99 + }
  100 + return results;
  101 +}
  102 +
  103 +void snapshot_reprocessing::screen_effective_snapshot(const vector<string> &taskid_inplay, vector<onelevel_det_result> &_onelevel_det_result){
  104 + map<string, algor_open_config_param> algor_param = m_task_param_manager->get_task_algor_params();
  105 +
  106 + int task_count = _onelevel_det_result.size();
  107 +
  108 + int task_idx = 0;
  109 +
  110 + for (auto taskid : taskid_inplay)
  111 + {
  112 + int effective_count = 0;
  113 + int effective_idx = 0;
  114 +
  115 + det_objinfo *tmp_det_objinfo = _onelevel_det_result[task_idx].obj;
  116 +
  117 + for (int c = 0; c < _onelevel_det_result[task_idx].obj_count; c++)
  118 + {
  119 + // if (algor_index_table["human"].find(tmp_det_objinfo[c].index) != algor_index_table["human"].end()
  120 + // && (!algor_param[taskid].human_algors.empty() || !algor_param[taskid].human_face_algors.empty())) // 此处行人和人脸存在耦合,若同一路任务配置了人脸没有配置行人,存抓拍图时会出错
  121 + if (algor_index_table["human"].find(tmp_det_objinfo[c].index) != algor_index_table["human"].end()
  122 + && (!algor_param[taskid].human_algors.empty())) // modified by zsh 220714
  123 + {
  124 + tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
  125 + effective_count++;
  126 + }
  127 +
  128 + if (algor_index_table["nonmotor_vehicle"].find(tmp_det_objinfo[c].index) != algor_index_table["nonmotor_vehicle"].end()
  129 + && !algor_param[taskid].nonmotor_vehicle_algors.empty())
  130 + {
  131 + tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
  132 + effective_count++;
  133 + }
  134 +
  135 + if (algor_index_table["vehicle"].find(tmp_det_objinfo[c].index) != algor_index_table["vehicle"].end()
  136 + && !algor_param[taskid].vehicle_algors.empty())
  137 + {
  138 + tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
  139 + effective_count++;
  140 + }
  141 + }
  142 +
  143 + _onelevel_det_result[task_idx++].obj_count = effective_count;
  144 + }
  145 +}
  146 +
  147 +void snapshot_reprocessing::filter_vehicle(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &_onelevel_det_result){
  148 + map<string, algor_open_config_param> algor_param = m_task_param_manager->get_task_algor_params();
  149 +
  150 + int task_idx = 0;
  151 +
  152 + for (auto memPtr : vec_devMem){
  153 + string taskid = memPtr ->getId();
  154 +
  155 + int effective_count = 0;
  156 + int effective_idx = 0;
  157 +
  158 + det_objinfo *tmp_det_objinfo = _onelevel_det_result[task_idx].obj;
  159 +
  160 + for (int c = 0; c < _onelevel_det_result[task_idx].obj_count; c++)
  161 + {
  162 + if (algor_index_table["vehicle"].find(tmp_det_objinfo[c].index) != algor_index_table["vehicle"].end()
  163 + && !algor_param[taskid].vehicle_algors.empty())
  164 + {
  165 + tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
  166 + effective_count++;
  167 + }
  168 + }
  169 +
  170 + _onelevel_det_result[task_idx].obj_count = effective_count;
  171 + task_idx++;
  172 + }
  173 +}
0 \ No newline at end of file 174 \ No newline at end of file
src/reprocessing_module/snapshot_reprocessing.h 0 → 100644
  1 +/*
  2 + * @Author: yangzilong
  3 + * @Date: 2021-12-17 20:27:57
  4 + * @Last Modified by: yangzilong
  5 + * @Email: yangzilong@objecteye.com
  6 + * @Description:
  7 + */
  8 +#pragma once
  9 +
  10 +#include "../ai_platform/det_obj_header.h"
  11 +#include <vector>
  12 +#include <set>
  13 +#include <string>
  14 +#include <map>
  15 +#include <bitset>
  16 +#include "../ai_platform/task_param_manager.h"
  17 +#include "../ai_platform/header.h"
  18 +
  19 +// #define EXPANSION_PROPORTION 0.1
  20 +#define EXPANSION_PROPORTION 0.25
  21 +#define FACE_EXPANSION_PROPORTION 0.5
  22 +#define IMG_CHANNELS 3
  23 +
  24 +// using namespace std;
  25 +using std::vector;
  26 +using std::map;
  27 +using std::set;
  28 +
  29 +class DeviceMemory;
  30 +
  31 +typedef struct multi_obj_data_t{
  32 + long long id;
  33 + DeviceMemory *memPtr;
  34 + std::vector<video_object_info> objs;
  35 + string task_id;
  36 +} multi_obj_data_t;
  37 +
  38 +class snapshot_reprocessing
  39 +{
  40 +public:
  41 + //更新最优快照
  42 + static snapshot_reprocessing* getInstance()
  43 + {
  44 + static snapshot_reprocessing snapshot_reprocessing_instance;
  45 + return &snapshot_reprocessing_instance;
  46 + }
  47 +
  48 + vector<multi_obj_data_t> get_vehicle_snapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result>& ol_det_result, int skip_frame);
  49 +
  50 +private:
  51 + snapshot_reprocessing();
  52 +
  53 + map<string, set<int>> algor_index_table;
  54 + task_param_manager *m_task_param_manager;
  55 +
  56 +public:
  57 +
  58 + void screen_effective_snapshot(const vector<string> &taskid_inplay, vector<onelevel_det_result> &_onelevel_det_result);
  59 + void filter_vehicle(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &_onelevel_det_result);
  60 +
  61 +};
0 \ No newline at end of file 62 \ No newline at end of file
src/test/0_38863.jpg 0 → 100644

303 KB

src/test/datacasia_20160821_003198.jpg 0 → 100644

268 KB

src/test/list.txt 0 → 100644
  1 +0_38863.jpg
  2 +datacasia_20160821_003198.jpg
0 \ No newline at end of file 3 \ No newline at end of file
src/test/test.cpp 0 → 100644
  1 +#include <iostream>
  2 +#include <sstream>
  3 +#include <fstream>
  4 +#include "vpt.h"
  5 +#include "opencv2/opencv.hpp"
  6 +#include "opencv2/imgcodecs/legacy/constants_c.h"
  7 +#include "opencv2/imgproc/types_c.h"
  8 +#include "time.h"
  9 +#include "sys/time.h"
  10 +#include "sy_errorinfo.h"
  11 +#include "utils.h"
  12 +#include "dvpp_process.h"
  13 +
  14 +#include <chrono>
  15 +#include <dirent.h>
  16 +
  17 +using namespace std;
  18 +using namespace cv;
  19 +
  20 +double msecond() {
  21 + struct timeval tv;
  22 + gettimeofday(&tv, 0);
  23 + return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
  24 +}
  25 +
  26 +
  27 +void getAllNm(std::string pthNm, std::vector<std::string>& fileList)
  28 +{
  29 + DIR *dir;
  30 + struct dirent *ptr;
  31 + dir = opendir(pthNm.c_str()); ///open the dir
  32 + int filenum = 0;
  33 + while((ptr = readdir(dir)) != NULL) ///read the list of this dir
  34 + {
  35 + // char* to string
  36 + std::string curNm = ptr->d_name;
  37 + if(curNm != "." && curNm != "..")
  38 + {
  39 + filenum++;
  40 + fileList.push_back(curNm);
  41 + //printf("file %d name: %s\n", filenum, curNm.c_str());
  42 + }
  43 + }
  44 + closedir(dir);
  45 +}
  46 +
  47 +
  48 +int main() {
  49 + cout << vpt_get_version() << endl;
  50 +
  51 + vpt_param param;
  52 +
  53 + // param.modelNames = "vtp0716x.om";
  54 + param.modelNames = "vpt0715_310p.om";
  55 + param.threshold = 0.4;
  56 + param.devId = 0;
  57 + param.isTrk = false;
  58 +
  59 +
  60 + void* handle = nullptr;
  61 + cout << "init start " << endl;
  62 + ACL_CALL(aclInit(nullptr), ACL_ERROR_NONE, SY_FAILED);
  63 + ACL_CALL(aclrtSetDevice(param.devId), ACL_ERROR_NONE, SY_FAILED);
  64 + aclrtContext ctx;
  65 + ACL_CALL(aclrtCreateContext(&ctx, param.devId), ACL_ERROR_NONE, SY_FAILED);
  66 + aclrtStream stream = nullptr;
  67 + ACL_CALL(aclrtCreateStream(&stream), ACL_ERROR_NONE, SY_FAILED);
  68 + DvppProcess* dvpp = new DvppProcess();
  69 + dvpp->InitResource(stream);
  70 + int ret = vpt_init(&handle, param);
  71 +
  72 +
  73 + if (ret == 0) {
  74 + cout << "init success " << endl;
  75 +
  76 + ifstream infile("list.txt");
  77 + string file;
  78 + if(1) {
  79 + //while (infile >> file) {
  80 + // string filename = "700W/" + file;
  81 + // string filename = "imgs/" + file;
  82 + // const char* img_file_path="examples/";
  83 + const char* img_file_path="imgs/";
  84 + std::vector<std::string> fileList;
  85 +
  86 + getAllNm(img_file_path,fileList);
  87 + if (fileList.empty()) throw std::logic_error("No suitable images were found");
  88 +
  89 + double t3 = 0;
  90 + for (auto & file : fileList) {
  91 + string filename = img_file_path + file;
  92 +
  93 + cout << "img path: " << filename << endl;
  94 + const int batchsize = 1;
  95 + sy_img imgs[batchsize];
  96 + //debug====================================================================
  97 + double pt1,pt2,st1,st2;
  98 + st1 = msecond();
  99 + ImageData src[batchsize], dvpp_data[batchsize];
  100 + for (int b = 0; b < batchsize; b++) {
  101 + Utils::ReadImageFile(src[b], filename); //将二进制图像读入内存,并读取宽高信息
  102 + pt1 = msecond();
  103 + ACL_CALL(dvpp->CvtJpegToYuv420sp(dvpp_data[b], src[b]), SY_SUCCESS, SY_FAILED); //解码
  104 + pt2 = msecond();
  105 + printf("debug decode time: %.2f\n", pt2 - pt1);
  106 + imgs[b].w_ = dvpp_data[b].width;//dvpp_data[b].alignWidth;
  107 + imgs[b].h_ = dvpp_data[b].height;//dvpp_data[b].alignHeight;
  108 + imgs[b].data_ = dvpp_data[b].data.get();
  109 + }
  110 + st2 = msecond();
  111 + printf("debug dvpp process time: %.2f\n", (st2 - st1)/batchsize);
  112 + // printf("debug:%d\n",__LINE__);
  113 + //debug end================================================================
  114 + vpt_result* results;
  115 + double t1,t2;
  116 + t1 = msecond();
  117 + int ret = vpt_batch(handle, imgs, batchsize, &results);
  118 + t2 = msecond();
  119 + printf("debug mean process time: %.2f\n", (t2 - t1)/batchsize);
  120 + t3 = t3 + t2-t1;
  121 +
  122 + //debug==========================================================
  123 + // vpt_result* results_b10;
  124 + // t1 = msecond();
  125 + // ret = vpt_batch10(handle, imgs, batchsize, &results_b10);
  126 + // t2 = msecond();
  127 + // printf("debug mean batch process time: %.2f\n", (t2 - t1)/batchsize);
  128 + //debug end======================================================
  129 +
  130 +
  131 + // draw results
  132 + Mat cvImg = imread(filename.c_str());
  133 + for(int batchIdx = 0; batchIdx < batchsize; batchIdx ++) {
  134 + printf("debug det num:%d\n",results[batchIdx].obj_count_);
  135 + for (int i = 0; i < results[batchIdx].obj_count_; i++) {
  136 + // record===============================================================================================================
  137 + float xmin = results[batchIdx].obj_results_[i].obj_rect.left_;
  138 + float ymin = results[batchIdx].obj_results_[i].obj_rect.top_;
  139 + float xmax = results[batchIdx].obj_results_[i].obj_rect.width_ + results[batchIdx].obj_results_[i].obj_rect.left_;
  140 + float ymax = results[batchIdx].obj_results_[i].obj_rect.height_ + results[batchIdx].obj_results_[i].obj_rect.top_;
  141 + float txc = (xmin + xmax) / 2.0; // x center
  142 + float tyc = (ymin + ymax) / 2.0; // y center
  143 + float tw = results[batchIdx].obj_results_[i].obj_rect.width_;
  144 + float th = results[batchIdx].obj_results_[i].obj_rect.height_;
  145 + int label = results[batchIdx].obj_results_[i].obj_index;
  146 + float score = results[batchIdx].obj_results_[i].obj_score;
  147 + //printf("=====:%d %8.12f %8.12f %8.12f %8.12f %8.12f\n",label, xmin/cvImg.cols,ymin/cvImg.rows,xmax/cvImg.cols,ymax/cvImg.rows, score);
  148 + //printf("%%%%%:%d %8.12f %8.12f %8.12f %8.12f %8.12f\n",label, txc/cvImg.cols,tyc/cvImg.rows,tw/cvImg.cols,th/cvImg.rows, score);
  149 + // record end===========================================================================================================
  150 + Point lt(results[batchIdx].obj_results_[i].obj_rect.left_, results[batchIdx].obj_results_[i].obj_rect.top_);
  151 + Point rb((results[batchIdx].obj_results_[i].obj_rect.left_ +
  152 + results[batchIdx].obj_results_[i].obj_rect.width_), (results[batchIdx].obj_results_[i].obj_rect.top_ +
  153 + results[batchIdx].obj_results_[i].obj_rect.height_));
  154 + rectangle(cvImg, lt, rb, cv::Scalar(0, 0, 255), 4);
  155 + // cout << results[batchIdx].obj_results_[i].obj_rect.left_ << " "<< results[batchIdx].obj_results_[i].obj_rect.top_ <<" " << results[batchIdx].obj_results_[i].obj_rect.width_ << " " << results[batchIdx].obj_results_[i].obj_rect.height_ << endl;
  156 +
  157 + char buffer[50];
  158 + int fontface = cv::FONT_HERSHEY_SIMPLEX;
  159 + double scale = 0.8;
  160 + int thickness = 2;
  161 + int baseline = 0;
  162 + snprintf(buffer, sizeof(buffer), "%d:%.2f", results[batchIdx].obj_results_[i].obj_index,results[batchIdx].obj_results_[i].obj_score);
  163 + cv::Size text = cv::getTextSize(buffer, fontface, scale, thickness, &baseline);
  164 + cv::putText(cvImg, buffer, lt - cv::Point(0, baseline), fontface,
  165 + scale, cv::Scalar(0, 0, 255), thickness, 4);
  166 +
  167 + }
  168 +
  169 + string jpgSaveName = "result/" + file;
  170 + cv::imwrite(jpgSaveName, cvImg);
  171 + }
  172 +
  173 + // for(int batchIdx = 0; batchIdx < batchsize; batchIdx ++){
  174 + // printf("debug det_b10 num:%d\n",results_b10[batchIdx].obj_count_);
  175 + // for (int i = 0; i < results_b10[batchIdx].obj_count_; i++) {
  176 + // Point lt(results_b10[batchIdx].obj_results_[i].obj_rect.left_, results_b10[batchIdx].obj_results_[i].obj_rect.top_);
  177 + // Point rb((results_b10[batchIdx].obj_results_[i].obj_rect.left_ +
  178 + // results_b10[batchIdx].obj_results_[i].obj_rect.width_), (results_b10[batchIdx].obj_results_[i].obj_rect.top_ +
  179 + // results_b10[batchIdx].obj_results_[i].obj_rect.height_));
  180 + // rectangle(cvImg, lt, rb, cv::Scalar(0, 0, 255), 4);
  181 + // // cout << results[batchIdx].obj_results_[i].obj_rect.left_ << " "<< results[batchIdx].obj_results_[i].obj_rect.top_ <<" " << results[batchIdx].obj_results_[i].obj_rect.width_ << " " << results[batchIdx].obj_results_[i].obj_rect.height_ << endl;
  182 +
  183 + // char buffer[50];
  184 + // int fontface = cv::FONT_HERSHEY_SIMPLEX;
  185 + // double scale = 0.8;
  186 + // int thickness = 2;
  187 + // int baseline = 0;
  188 + // snprintf(buffer, sizeof(buffer), "%d:%.2f", results_b10[batchIdx].obj_results_[i].obj_index,results_b10[batchIdx].obj_results_[i].obj_score);
  189 + // cv::Size text = cv::getTextSize(buffer, fontface, scale, thickness, &baseline);
  190 + // cv::putText(cvImg, buffer, lt - cv::Point(0, baseline), fontface,
  191 + // scale, cv::Scalar(0, 0, 255), thickness, 4);
  192 +
  193 + // }
  194 +
  195 + // string jpgSaveName = "result/" + file;
  196 + // cv::imwrite(jpgSaveName, cvImg);
  197 + // }
  198 +
  199 + }
  200 + printf("mean time cost:%f\n",t3/fileList.size());
  201 + }
  202 +
  203 +
  204 + if(0) {
  205 + const int batchsize = 10;
  206 + sy_img imgs[batchsize];
  207 + ImageData src[batchsize], dvpp_data[batchsize];
  208 + int b = 0;
  209 + const char* img_file_path="imgs/";
  210 + std::vector<std::string> fileList;
  211 +
  212 + getAllNm(img_file_path,fileList);
  213 + if (fileList.empty()) throw std::logic_error("No suitable images were found");
  214 + for (auto & file : fileList) {
  215 + string filename = img_file_path + file;
  216 + cout << "img path: " << filename << endl;
  217 +
  218 + //debug====================================================================
  219 + if(b < batchsize) {
  220 + Utils::ReadImageFile(src[b], filename); //将二进制图像读入内存,并读取宽高信息
  221 + ACL_CALL(dvpp->CvtJpegToYuv420sp(dvpp_data[b], src[b]), SY_SUCCESS, SY_FAILED); //解码
  222 + imgs[b].w_ = dvpp_data[b].width;
  223 + imgs[b].h_ = dvpp_data[b].height;
  224 + imgs[b].data_ = dvpp_data[b].data.get();
  225 + b ++;
  226 + }
  227 + if(b == batchsize) {
  228 + b = 0;
  229 + vpt_result* results;
  230 + double t1,t2;
  231 + t1 = msecond();
  232 + int ret = vpt_batch(handle, imgs, batchsize, &results);
  233 + t2 = msecond();
  234 + printf("debug mean process time: %.2f\n", (t2 - t1)/batchsize);
  235 + //debug==========================================================
  236 + // vpt_result* results_b10;
  237 + // t1 = msecond();
  238 + // ret = vpt_batch10(handle, imgs, batchsize, &results_b10);
  239 + // t2 = msecond();
  240 + // printf("debug mean batch process time: %.2f\n", (t2 - t1)/batchsize);
  241 + //debug end======================================================
  242 +
  243 + //draw results
  244 + for(int batchIdx = 0; batchIdx < batchsize; batchIdx ++){
  245 + printf("debug det num:%d\n",results[batchIdx].obj_count_);
  246 + // printf("debug det_b10 num:%d\n",results_b10[batchIdx].obj_count_);
  247 + }
  248 +
  249 + // debug================================
  250 + // for (int b = 0; b < batchsize; b++) {
  251 + // delete [] src[b].data.get();
  252 + // delete [] dvpp_data[b].data.get();
  253 + // // delete[] imgs[b].data_ ;
  254 + // imgs[b].data_ = NULL;
  255 + // }
  256 + // debug end============================
  257 +
  258 + }
  259 + } }
  260 +
  261 + }
  262 +
  263 + vpt_release(&handle);
  264 + aclrtDestroyStream(stream);
  265 + aclrtDestroyContext(ctx);
  266 + aclrtResetDevice(param.devId);
  267 + aclFinalize();
  268 +
  269 +
  270 + return 0;
  271 +}
src/util/JpegUtil.cpp 0 → 100644
  1 +#include <cstdio>
  2 +#include <cstdlib>
  3 +#include <memory>
  4 +#include "JpegUtil.h"
  5 +
  6 +using namespace std;
  7 +
  8 +namespace DVPP_UTIL {
  9 +
  10 + int32_t deviceId_;
  11 + aclrtContext context_;
  12 + aclrtStream stream_;
  13 + acldvppChannelDesc *dvppChannelDesc_;
  14 +
  15 + int dvpp_jpeg_init(int32_t devId){
  16 + deviceId_ = devId;
  17 +
  18 + aclError ret;
  19 + /* 2.Run the management resource application, including Device, Context, Stream */
  20 + aclrtSetDevice(deviceId_);
  21 + aclrtCreateContext(&context_, deviceId_);
  22 + aclrtCreateStream(&stream_);
  23 +
  24 + // channel 准备
  25 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  26 + ret = acldvppCreateChannel(dvppChannelDesc_);
  27 + }
  28 +
  29 + void dvpp_jpeg_release(){
  30 + aclError ret;
  31 + ret = aclrtSetDevice(deviceId_);
  32 + aclrtSetCurrentContext(context_);
  33 +
  34 + ret = acldvppDestroyChannel(dvppChannelDesc_);
  35 + ret = acldvppDestroyChannelDesc(dvppChannelDesc_);
  36 + dvppChannelDesc_ = nullptr;
  37 +
  38 + if (stream_ != nullptr) {
  39 + ret = aclrtDestroyStream(stream_);
  40 + if (ret != ACL_SUCCESS) {
  41 + printf("destroy stream failed");
  42 + }
  43 + stream_ = nullptr;
  44 + }
  45 + printf("end to destroy stream");
  46 +
  47 + if (context_ != nullptr) {
  48 + ret = aclrtDestroyContext(context_);
  49 + if (ret != ACL_SUCCESS) {
  50 + printf("destroy context failed");
  51 + }
  52 + context_ = nullptr;
  53 + }
  54 + printf("end to destroy context");
  55 +
  56 + ret = aclrtResetDevice(deviceId_);
  57 + if (ret != ACL_SUCCESS) {
  58 + printf("reset device failed");
  59 + }
  60 + printf("end to reset device is %d", deviceId_);
  61 + }
  62 +
  63 + int32_t dvpp_jpege_save(char* pcData , uint32_t dataLen, string out_file_name)
  64 + {
  65 + FILE* fd = nullptr;
  66 + fd = fopen(out_file_name.c_str(), "wb");
  67 + if (fd == nullptr) {
  68 + printf("open output file err\n");
  69 + return 1;
  70 + }
  71 +
  72 + fwrite(pcData, dataLen, 1, fd);
  73 + fflush(fd);
  74 +
  75 + fclose(fd);
  76 + return 0;
  77 + }
  78 +
  79 + void dvpp_jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name){
  80 +
  81 + aclError aclRet ;
  82 + aclRet = aclrtSetDevice(deviceId_);
  83 + aclrtSetCurrentContext(context_);
  84 +
  85 + // 7. 创建图片编码配置数据,设置编码质量
  86 + // 编码质量范围[0, 100],其中level 0编码质量与level 100差不多,而在[1, 100]内数值越小输出图片质量越差。
  87 + acldvppJpegeConfig *jpegeConfig_ = acldvppCreateJpegeConfig();
  88 + acldvppSetJpegeConfigLevel(jpegeConfig_, 100);
  89 +
  90 + // 8. 申请输出内存,申请Device内存encodeOutBufferDev_,存放编码后的输出数据
  91 + uint32_t outBufferSize= 0;
  92 + int ret = acldvppJpegPredictEncSize(encodeInputDesc_, jpegeConfig_, &outBufferSize);
  93 + void *encodeOutBufferDev_ = nullptr;
  94 + ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize);
  95 +
  96 + // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  97 + aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_, &outBufferSize, jpegeConfig_, stream_);
  98 + aclRet = aclrtSynchronizeStream(stream_);
  99 +
  100 + // 该模式下,由于处理结果在Device侧,因此需要调用内存复制接口传输结果数据后,再释放Device侧内存
  101 + // 申请Host内存outputHostBuffer
  102 + void* outputHostBuffer = malloc(outBufferSize);
  103 + // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
  104 + aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
  105 + // 释放掉输入输出的device内存
  106 + (void)acldvppFree(encodeOutBufferDev_);
  107 + encodeOutBufferDev_ = nullptr;
  108 + // 数据使用完成后,释放内存
  109 + dvpp_jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
  110 + free(outputHostBuffer);
  111 + outputHostBuffer = nullptr;
  112 + }
  113 +
  114 +}
0 \ No newline at end of file 115 \ No newline at end of file
src/util/JpegUtil.h 0 → 100644
  1 +#ifndef __JPEG_UTIL_H__
  2 +#define __JPEG_UTIL_H__
  3 +
  4 +#include <string>
  5 +
  6 +#include "acl/acl.h"
  7 +#include "acl/ops/acl_dvpp.h"
  8 +#include "acl/dvpp/hi_dvpp.h"
  9 +
  10 +using namespace std;
  11 +
  12 +namespace DVPP_UTIL {
  13 +
  14 + int dvpp_jpeg_init(int32_t deviceId_);
  15 +
  16 + void dvpp_jpeg_release();
  17 +
  18 + void dvpp_jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name);
  19 +}
  20 +
  21 +#endif // __JPEG_UTIL_H__
0 \ No newline at end of file 22 \ No newline at end of file
src/util/crop_process.cpp 0 → 100644
  1 +/**
  2 +* @file dvpp_process.cpp
  3 +*
  4 +* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
  5 +*
  6 +* This program is distributed in the hope that it will be useful,
  7 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  8 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9 +*/
  10 +#include "crop_process.h"
  11 +#include <stdio.h>
  12 +#include <vector>
  13 +#include <string>
  14 +#include <memory>
  15 +#include <stdlib.h>
  16 +#include "utils.h"
  17 +#include "acl/acl_base.h"
  18 +#include "acl/acl_rt.h"
  19 +#include "acl/acl_op.h"
  20 +#include "acl/acl_mdl.h"
  21 +#include "acl/ops/acl_dvpp.h"
  22 +#include "acl/ops/acl_cblas.h"
  23 +#include "../decoder/interface/DeviceMemory.hpp"
  24 +
  25 +using namespace std;
  26 +
  27 +namespace {
  28 + uint32_t AlignSize(uint32_t origSize, uint32_t alignment)
  29 + {
  30 + if (alignment == 0) {
  31 + return 0;
  32 + }
  33 + uint32_t alignmentH = alignment - 1;
  34 + return (origSize + alignmentH) / alignment * alignment;
  35 + }
  36 +}
  37 +
  38 +DvppCropProcess::DvppCropProcess()
  39 + : dvppChannelDesc_(nullptr), inputBatchPicDesc_(nullptr),
  40 + outputBatchPicDesc_(nullptr), inputBatchSize_(0), outputBatchSize_(0)
  41 +{
  42 +}
  43 +
  44 +DvppCropProcess::~DvppCropProcess()
  45 +{
  46 + DestroyBatchCropResource();
  47 +}
  48 +
  49 +Result DvppCropProcess::InitProcess()
  50 +{
  51 + // create vpc channel description
  52 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  53 + if (dvppChannelDesc_ == nullptr) {
  54 + ERROR_LOG("acldvppCreateChannelDesc failed");
  55 + return FAILED;
  56 + }
  57 +
  58 + // create vpc channel
  59 + aclError aclRet = acldvppCreateChannel(dvppChannelDesc_);
  60 + if (aclRet != ACL_SUCCESS) {
  61 + ERROR_LOG("acldvppCreateChannel failed, errorCode = %d", static_cast<int32_t>(aclRet));
  62 + return FAILED;
  63 + }
  64 +
  65 + // create dvpp resize config
  66 + resizeConfig_ = acldvppCreateResizeConfig();
  67 + if (resizeConfig_ == nullptr) {
  68 + ERROR_LOG("acldvppCreateResizeConfig failed");
  69 + return FAILED;
  70 + }
  71 +
  72 + INFO_LOG("dvpp init resource success");
  73 + return SUCCESS;
  74 +}
  75 +
  76 +Result DvppCropProcess::InitBatchCropInputDesc(DeviceMemory *devMem)
  77 +{
  78 + inputBatchPicDesc_ = acldvppCreateBatchPicDesc(inputBatchSize_);
  79 + if (inputBatchPicDesc_ == nullptr) {
  80 + ERROR_LOG("InitBatchCropInputDesc inBatchPicDesc failed");
  81 + return FAILED;
  82 + }
  83 +
  84 + acldvppBatchPicDesc *inputBatchPicDesc_ = acldvppCreateBatchPicDesc(1);
  85 + acldvppPicDesc *vpcInputDesc_ = acldvppGetPicDesc(inputBatchPicDesc_, 0);
  86 + acldvppSetPicDescData(vpcInputDesc_, devMem->getMem());
  87 + acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  88 + acldvppSetPicDescWidth(vpcInputDesc_, devMem->getWidth());
  89 + acldvppSetPicDescHeight(vpcInputDesc_, devMem->getHeight());
  90 + acldvppSetPicDescWidthStride(vpcInputDesc_, devMem->getWidthStride());
  91 + acldvppSetPicDescHeightStride(vpcInputDesc_, devMem->getHeightStride());
  92 + acldvppSetPicDescSize(vpcInputDesc_, devMem->getSize());
  93 +
  94 + // if (inputBatchSize_ > batchInput_.size()) {
  95 + // inputBatchSize_ = batchInput_.size();
  96 + // }
  97 + // uint32_t inputWidth = devMem->getWidth();
  98 + // for (uint32_t i = 0; i < inputBatchSize_; i++) {
  99 + // vecInPtr_.push_back(inputBufferDev);
  100 + // acldvppPicDesc *vpcInputDesc = acldvppGetPicDesc(inputBatchPicDesc_, i);
  101 + // (void)acldvppSetPicDescData(vpcInputDesc, devMem->getMem());
  102 + // (void)acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  103 + // (void)acldvppSetPicDescWidth(vpcInputDesc, batchInput_[i].inputWidth);
  104 + // (void)acldvppSetPicDescHeight(vpcInputDesc, batchInput_[i].inputHeight);
  105 + // (void)acldvppSetPicDescWidthStride(vpcInputDesc, inputWidthStride_);
  106 + // (void)acldvppSetPicDescHeightStride(vpcInputDesc, inputHeightStride_);
  107 + // (void)acldvppSetPicDescSize(vpcInputDesc, inputBufferSize);
  108 + // INFO_LOG("set inputDesc success.");
  109 + // }
  110 + return SUCCESS;
  111 +}
  112 +
  113 +Result DvppCropProcess::InitBatchCropOutputDesc(vector<video_object_info> objs)
  114 +{
  115 + const uint32_t widthAlignment = 16;
  116 + const uint32_t heightAlignment = 16;
  117 + const uint32_t sizeAlignment = 3;
  118 + const uint32_t sizeNum = 2;
  119 +
  120 + outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_);
  121 + if (outputBatchPicDesc_ == nullptr) {
  122 + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed");
  123 + return FAILED;
  124 + }
  125 + acldvppPicDesc *vpcOutputDesc = nullptr;
  126 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  127 + video_object_info obj = objs[i];
  128 +
  129 + int outputWidth_ = obj.right - obj.left;
  130 + int outputHeight_ = obj.bottom - obj.top;
  131 + int modelInputLeft = obj.left;
  132 + int modelInputTop = obj.top;
  133 +
  134 + uint32_t outputWidthStride = AlignSize(outputWidth_, widthAlignment);
  135 + uint32_t outputHeightStride = AlignSize(outputHeight_, heightAlignment);
  136 + uint32_t outputBufferSize = outputWidthStride * outputHeightStride * sizeAlignment / sizeNum;
  137 +
  138 + void *vpcBatchOutputBufferDev = nullptr;
  139 + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, outputBufferSize);
  140 + if (ret != ACL_SUCCESS) {
  141 + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.",
  142 + outputBufferSize, static_cast<int32_t>(ret));
  143 + return FAILED;
  144 + }
  145 + vecOutPtr_.push_back(vpcBatchOutputBufferDev);
  146 + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i);
  147 + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev);
  148 + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  149 + (void)acldvppSetPicDescWidth(vpcOutputDesc, outputWidth_);
  150 + (void)acldvppSetPicDescHeight(vpcOutputDesc, outputHeight_);
  151 + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, outputWidthStride);
  152 + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, outputHeightStride);
  153 + (void)acldvppSetPicDescSize(vpcOutputDesc, outputBufferSize);
  154 + }
  155 + return SUCCESS;
  156 +}
  157 +
  158 +static Result dvpp_jpege_save(char* pcData , uint32_t dataLen, string out_file_name)
  159 +{
  160 + FILE* fd = nullptr;
  161 + fd = fopen(out_file_name.c_str(), "wb");
  162 + if (fd == nullptr) {
  163 + printf("open output file err\n");
  164 + return FAILED;
  165 + }
  166 +
  167 + fwrite(pcData, dataLen, 1, fd);
  168 + fflush(fd);
  169 +
  170 + fclose(fd);
  171 + return SUCCESS;
  172 +}
  173 +
  174 +static void dvpp_jpeg_encode(acldvppPicDesc *encodeInputDesc_, string out_file_name){
  175 +
  176 + // 2.运行管理资源申请(依次申请Device、Context、Stream)
  177 + aclrtContext context_;
  178 + aclrtStream stream_;
  179 + aclrtSetDevice(0);
  180 + aclrtCreateContext(&context_, 0);
  181 + aclrtCreateStream(&stream_);
  182 +
  183 + // 3.创建图片数据处理通道时的通道描述信息,dvppChannelDesc_是acldvppChannelDesc类型
  184 + acldvppChannelDesc *dvppChannelDesc_ = acldvppCreateChannelDesc();
  185 +
  186 + // 4.创建图片数据处理的通道
  187 + aclError aclRet = acldvppCreateChannel(dvppChannelDesc_);
  188 +
  189 + // 7. 创建图片编码配置数据,设置编码质量
  190 + // 编码质量范围[0, 100],其中level 0编码质量与level 100差不多,而在[1, 100]内数值越小输出图片质量越差。
  191 + acldvppJpegeConfig *jpegeConfig_ = acldvppCreateJpegeConfig();
  192 + acldvppSetJpegeConfigLevel(jpegeConfig_, 100);
  193 +
  194 + // 8. 申请输出内存,申请Device内存encodeOutBufferDev_,存放编码后的输出数据
  195 + uint32_t outBufferSize= 0;
  196 + int ret = acldvppJpegPredictEncSize(encodeInputDesc_, jpegeConfig_, &outBufferSize);
  197 + void *encodeOutBufferDev_ = nullptr;
  198 + ret = acldvppMalloc(&encodeOutBufferDev_, outBufferSize);
  199 +
  200 + // 9. 执行异步编码,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
  201 + aclRet = acldvppJpegEncodeAsync(dvppChannelDesc_, encodeInputDesc_, encodeOutBufferDev_,
  202 + &outBufferSize, jpegeConfig_, stream_);
  203 + aclRet = aclrtSynchronizeStream(stream_);
  204 +
  205 + // 该模式下,由于处理结果在Device侧,因此需要调用内存复制接口传输结果数据后,再释放Device侧内存
  206 + // 申请Host内存outputHostBuffer
  207 + void* outputHostBuffer = malloc(outBufferSize);
  208 + // 通过aclrtMemcpy接口将Device的处理结果数据传输到Host
  209 + aclRet = aclrtMemcpy(outputHostBuffer, outBufferSize, encodeOutBufferDev_, outBufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
  210 + // 释放掉输入输出的device内存
  211 + (void)acldvppFree(encodeOutBufferDev_);
  212 + // 数据使用完成后,释放内存
  213 + dvpp_jpege_save((char*)outputHostBuffer, outBufferSize, out_file_name);
  214 + free(outputHostBuffer);
  215 +
  216 + acldvppDestroyChannel(dvppChannelDesc_);
  217 + (void)acldvppDestroyChannelDesc(dvppChannelDesc_);
  218 + dvppChannelDesc_ = nullptr;
  219 +
  220 + // 11. 释放运行管理资源(依次释放Stream、Context、Device)
  221 + aclrtDestroyStream(stream_);
  222 + aclrtDestroyContext(context_);
  223 + aclrtResetDevice(0);
  224 +}
  225 +
  226 +Result DvppCropProcess::ProcessBatchCrop(DeviceMemory *devMem, vector<video_object_info> objs)
  227 +{
  228 + inputBatchSize_ = 1;
  229 + outputBatchSize_ = objs.size();
  230 +
  231 + INFO_LOG("ProcessBatchCrop start.");
  232 + const uint32_t oddNum = 1;
  233 +
  234 + std::unique_ptr<acldvppRoiConfig *[]>
  235 + cropArea(new(std::nothrow) acldvppRoiConfig *[outputBatchSize_ * sizeof(acldvppRoiConfig *)]);
  236 +
  237 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  238 + video_object_info obj = objs[i];
  239 + cropArea[i] = acldvppCreateRoiConfig(obj.left, obj.right, obj.top, obj.bottom);
  240 + if (cropArea[i] == nullptr) {
  241 + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed");
  242 + return FAILED;
  243 + }
  244 + }
  245 + Result ret = InitBatchCropInputDesc(devMem);
  246 + if (ret != SUCCESS) {
  247 + ERROR_LOG("InitBatchCropInputDesc failed");
  248 + return FAILED;
  249 + }
  250 +
  251 + ret = InitBatchCropOutputDesc(objs);
  252 + if (ret != SUCCESS) {
  253 + ERROR_LOG("InitBatchCropOutputDesc failed");
  254 + return FAILED;
  255 + }
  256 +
  257 + // calculate total number of crop image
  258 + uint32_t totalNum = 0;
  259 + std::unique_ptr<uint32_t[]> roiNums(new (std::nothrow) uint32_t[inputBatchSize_]);
  260 + if (roiNums != nullptr){
  261 + for (int i = 0; i < inputBatchSize_; i++) {
  262 + // crop number of images from one source image is outputBatchSize_ / inputBatchSize_
  263 + roiNums[i] = outputBatchSize_ / inputBatchSize_;
  264 + totalNum += roiNums[i];
  265 + }
  266 + }
  267 + // crop number of images from last source image is
  268 + // outputBatchSize_ / inputBatchSize_ + outputBatchSize_ % inputBatchSize_
  269 + if (outputBatchSize_ % inputBatchSize_ != 0) {
  270 + roiNums[inputBatchSize_ - 1] = (outputBatchSize_ - totalNum) + roiNums[inputBatchSize_ - 1];
  271 + }
  272 +
  273 + aclError aclRet = acldvppSetResizeConfigInterpolation(resizeConfig_, 0);
  274 + aclRet = acldvppVpcBatchCropResizeAsync(dvppChannelDesc_, inputBatchPicDesc_,
  275 + roiNums.get(), inputBatchSize_,
  276 + outputBatchPicDesc_, cropArea.get(), resizeConfig_, stream_);
  277 + if (aclRet != ACL_SUCCESS) {
  278 + ERROR_LOG("acldvppVpcBatchCropAsync failed, errorCode = %d", static_cast<int32_t>(aclRet));
  279 + return FAILED;
  280 + }
  281 +
  282 + aclRet = aclrtSynchronizeStream(stream_);
  283 + if (aclRet != ACL_SUCCESS) {
  284 + ERROR_LOG("crop aclrtSynchronizeStream failed, errorCode = %d", static_cast<int32_t>(aclRet));
  285 + return FAILED;
  286 + }
  287 +
  288 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  289 + acldvppPicDesc *vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i);
  290 + string file_name = "output";
  291 + file_name = file_name + to_string(i) + ".jpg";
  292 + dvpp_jpeg_encode(vpcOutputDesc, file_name);
  293 + }
  294 +
  295 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  296 + if (cropArea[i] != nullptr) {
  297 + (void)acldvppDestroyRoiConfig(cropArea[i]);
  298 + cropArea[i] = nullptr;
  299 + }
  300 + }
  301 + INFO_LOG("ProcessBatchCrop success.");
  302 + return SUCCESS;
  303 +}
  304 +
  305 +void DvppCropProcess::DestroyBatchCropResource()
  306 +{
  307 + INFO_LOG("DestroyBatchCropResource start.");
  308 +
  309 + if (inputBatchPicDesc_ != nullptr) {
  310 + (void)acldvppDestroyBatchPicDesc(inputBatchPicDesc_);
  311 + inputBatchPicDesc_ = nullptr;
  312 + }
  313 + for (auto ptr : vecOutPtr_) {
  314 + if (ptr != nullptr) {
  315 + (void)acldvppFree(ptr);
  316 + }
  317 + }
  318 + vecOutPtr_.clear();
  319 + if (outputBatchPicDesc_ != nullptr) {
  320 + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_);
  321 + outputBatchPicDesc_ = nullptr;
  322 + }
  323 + if (dvppChannelDesc_ != nullptr) {
  324 + aclError aclRet = acldvppDestroyChannel(dvppChannelDesc_);
  325 + if (aclRet != ACL_SUCCESS) {
  326 + ERROR_LOG("acldvppDestroyChannel failed, errorCode = %d", static_cast<int32_t>(aclRet));
  327 + }
  328 + (void)acldvppDestroyChannelDesc(dvppChannelDesc_);
  329 + dvppChannelDesc_ = nullptr;
  330 + }
  331 +
  332 + if (resizeConfig_ != nullptr) {
  333 + (void)acldvppDestroyResizeConfig(resizeConfig_);
  334 + resizeConfig_ = nullptr;
  335 + }
  336 +
  337 + INFO_LOG("DestroyBatchCropResource end.");
  338 + return;
  339 +}
  340 +
  341 +Result DvppCropProcess::init(int deviceId)
  342 +{
  343 + deviceId_ = deviceId;
  344 +
  345 + aclError ret;
  346 + // ret = aclInit(NULL);
  347 + // if (ret != ACL_SUCCESS) {
  348 + // ERROR_LOG("acl init failed, errorCode = %d", static_cast<int32_t>(ret));
  349 + // return FAILED;
  350 + // }
  351 + // INFO_LOG("acl init success");
  352 +
  353 + // set device
  354 + ret = aclrtSetDevice(deviceId_);
  355 + if (ret != ACL_SUCCESS) {
  356 + ERROR_LOG("acl set device %d failed, errorCode = %d", deviceId_, static_cast<int32_t>(ret));
  357 + return FAILED;
  358 + }
  359 + INFO_LOG("set device %d success", deviceId_);
  360 +
  361 + // create context (set current)
  362 + ret = aclrtCreateContext(&context_, deviceId_);
  363 + if (ret != ACL_SUCCESS) {
  364 + ERROR_LOG("acl create context failed, deviceId = %d, errorCode = %d",
  365 + deviceId_, static_cast<int32_t>(ret));
  366 + return FAILED;
  367 + }
  368 + INFO_LOG("create context success");
  369 +
  370 + // create stream
  371 + ret = aclrtCreateStream(&stream_);
  372 + if (ret != ACL_SUCCESS) {
  373 + ERROR_LOG("acl create stream failed, deviceId = %d, errorCode = %d",
  374 + deviceId_, static_cast<int32_t>(ret));
  375 + return FAILED;
  376 + }
  377 + INFO_LOG("create stream success");
  378 +
  379 + InitProcess();
  380 +
  381 + return SUCCESS;
  382 +}
  383 +
  384 +void DvppCropProcess::DestroyResource()
  385 +{
  386 + aclError ret;
  387 + if (stream_ != nullptr) {
  388 + ret = aclrtDestroyStream(stream_);
  389 + if (ret != ACL_SUCCESS) {
  390 + ERROR_LOG("destroy stream failed, errorCode = %d", static_cast<int32_t>(ret));
  391 + }
  392 + stream_ = nullptr;
  393 + }
  394 + INFO_LOG("end to destroy stream");
  395 +
  396 + if (context_ != nullptr) {
  397 + ret = aclrtDestroyContext(context_);
  398 + if (ret != ACL_SUCCESS) {
  399 + ERROR_LOG("destroy context failed, errorCode = %d", static_cast<int32_t>(ret));
  400 + }
  401 + context_ = nullptr;
  402 + }
  403 + INFO_LOG("end to destroy context");
  404 +
  405 + ret = aclrtResetDevice(deviceId_);
  406 + if (ret != ACL_SUCCESS) {
  407 + ERROR_LOG("reset device %d failed, errorCode = %d", deviceId_, static_cast<int32_t>(ret));
  408 + }
  409 + INFO_LOG("end to reset device %d", deviceId_);
  410 +
  411 + ret = aclFinalize();
  412 + if (ret != ACL_SUCCESS) {
  413 + ERROR_LOG("finalize acl failed, errorCode = %d", static_cast<int32_t>(ret));
  414 + }
  415 + INFO_LOG("end to finalize acl");
  416 +}
src/util/crop_process.h 0 → 100644
  1 +#ifndef ___CROP_PROCESS_H__
  2 +#define ___CROP_PROCESS_H__
  3 +
  4 +#include <vector>
  5 +#include "acl/ops/acl_dvpp.h"
  6 +#include "../ai_platform/header.h"
  7 +
  8 +using namespace std;
  9 +
  10 +class DeviceMemory;
  11 +
  12 +typedef enum Result {
  13 + SUCCESS = 0,
  14 + FAILED = 1
  15 +} Result;
  16 +
  17 +class DvppCropProcess {
  18 +public:
  19 + /**
  20 + * @brief Constructor
  21 + * @param [in] stream: stream
  22 + */
  23 + DvppCropProcess();
  24 +
  25 + /**
  26 + * @brief Destructor
  27 + */
  28 + ~DvppCropProcess();
  29 +
  30 +public:
  31 + /**
  32 + * @brief Process Batch Crop
  33 + * @return result
  34 + */
  35 + Result ProcessBatchCrop(DeviceMemory *devMem, vector<video_object_info> objs);
  36 +
  37 + /**
  38 + * @brief init reousce
  39 + * @return result
  40 + */
  41 + Result init(int deviceId);
  42 +
  43 +
  44 +private:
  45 + /**
  46 + * @brief InitBatchCropInputDesc
  47 + * @return Result
  48 + */
  49 + Result InitBatchCropInputDesc(DeviceMemory *devMem);
  50 +
  51 + /**
  52 + * @brief InitBatchCropOutputDesc
  53 + * @return Result
  54 + */
  55 + Result InitBatchCropOutputDesc(vector<video_object_info> objs);
  56 +
  57 + /**
  58 + * @brief DestroyBatchCropResource
  59 + */
  60 + void DestroyBatchCropResource();
  61 +
  62 +
  63 + void DestroyResource();
  64 +
  65 + /**
  66 + * @brief init reousce
  67 + * @return result
  68 + */
  69 + Result InitProcess();
  70 +
  71 +private:
  72 + int32_t deviceId_;
  73 + aclrtContext context_;
  74 + aclrtStream stream_;
  75 +
  76 + acldvppChannelDesc *dvppChannelDesc_;
  77 + acldvppResizeConfig *resizeConfig_;
  78 +
  79 + std::vector<void *> vecOutPtr_;
  80 +
  81 + acldvppBatchPicDesc *inputBatchPicDesc_; // vpc input desc
  82 + acldvppBatchPicDesc *outputBatchPicDesc_; // vpc output desc
  83 +
  84 + uint32_t inputBatchSize_;
  85 + uint32_t outputBatchSize_;
  86 +};
  87 +
  88 +#endif // ___CROP_PROCESS_H__
0 \ No newline at end of file 89 \ No newline at end of file
src/util/util_tools.cpp 0 → 100644
  1 +#include "util_tools.h"
  2 +
  3 +using namespace std;
  4 +
  5 +namespace UtilTools{
  6 + long long get_cur_time_ms(){
  7 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  8 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  9 +
  10 + return tpMicro.time_since_epoch().count();
  11 + }
  12 +}
0 \ No newline at end of file 13 \ No newline at end of file
src/util/util_tools.h 0 → 100644
  1 +#include <chrono>
  2 +
  3 +
  4 +namespace UtilTools{
  5 + long long get_cur_time_ms();
  6 +}
src/util/vpc_util.cpp 0 → 100644
  1 +
  2 +#include <cstdlib>
  3 +#include <iostream>
  4 +#include <unistd.h>
  5 +#include <dirent.h>
  6 +#include <fstream>
  7 +#include <cstring>
  8 +#include <vector>
  9 +#include <sys/types.h>
  10 +#include <sys/stat.h>
  11 +#include <map>
  12 +#include <cstdint>
  13 +#include "acl/acl.h"
  14 +#include "acl/ops/acl_dvpp.h"
  15 +
  16 +#include "vpc_util.h"
  17 +#include "JpegUtil.h"
  18 +#include "../decoder/interface/DeviceMemory.hpp"
  19 +
  20 +#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
  21 +#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
  22 +#define ERROR_LOG(fmt, args...) fprintf(stderr, "[ERROR] " fmt "\n", ##args)
  23 +
  24 +typedef enum Result {
  25 + SUCCESS = 0,
  26 + FAILED = 1
  27 +} Result;
  28 +
  29 +typedef struct PicDesc {
  30 + std::string picName;
  31 + int width;
  32 + int height;
  33 +}PicDesc;
  34 +
  35 +typedef struct CropPicDesc {
  36 + std::string picName;
  37 + int left;
  38 + int top;
  39 + int width;
  40 + int height;
  41 +}CropPicDesc;
  42 +
  43 +int32_t deviceId_;
  44 +aclrtContext context_;
  45 +aclrtStream stream_;
  46 +
  47 +aclvdecChannelDesc *vdecChannelDesc_;
  48 +acldvppStreamDesc *streamInputDesc_;
  49 +acldvppPicDesc *picOutputDesc_;
  50 +acldvppChannelDesc *dvppChannelDesc_;
  51 +uint32_t inBufferSize;
  52 +uint32_t inputWidth;
  53 +uint32_t inputHeight;
  54 +aclrtRunMode runMode;
  55 +
  56 +PicDesc inPicDesc;
  57 +CropPicDesc outPicDesc;
  58 +
  59 +
  60 +
  61 +uint32_t AlignmentHelper(uint32_t origSize, uint32_t alignment)
  62 +{
  63 + if (alignment == 0) {
  64 + return 0;
  65 + }
  66 + uint32_t alignmentH = alignment - 1;
  67 + return (origSize + alignmentH) / alignment * alignment;
  68 +}
  69 +
  70 +
  71 +void dvpp_crop_release()
  72 +{
  73 + aclError ret;
  74 + // ret = aclrtSetDevice(deviceId_);
  75 + // aclrtSetCurrentContext(context_);
  76 +
  77 + ret = acldvppDestroyChannel(dvppChannelDesc_);
  78 + ret = acldvppDestroyChannelDesc(dvppChannelDesc_);
  79 +
  80 + if (stream_ != nullptr) {
  81 + ret = aclrtDestroyStream(stream_);
  82 + if (ret != ACL_SUCCESS) {
  83 + ERROR_LOG("destroy stream failed");
  84 + }
  85 + stream_ = nullptr;
  86 + }
  87 + INFO_LOG("end to destroy stream");
  88 +
  89 + if (context_ != nullptr) {
  90 + ret = aclrtDestroyContext(context_);
  91 + if (ret != ACL_SUCCESS) {
  92 + ERROR_LOG("destroy context failed");
  93 + }
  94 + context_ = nullptr;
  95 + }
  96 + INFO_LOG("end to destroy context");
  97 +
  98 + ret = aclrtResetDevice(deviceId_);
  99 + if (ret != ACL_SUCCESS) {
  100 + ERROR_LOG("reset device failed");
  101 + }
  102 + INFO_LOG("end to reset device is %d", deviceId_);
  103 +}
  104 +
  105 +
  106 +int dvpp_crop(acldvppPicDesc *input_pic_desc)
  107 +{
  108 + /* 1.ACL initialization */
  109 + // aclInit(nullptr);
  110 +
  111 + /* 2.Run the management resource application, including Device, Context, Stream */
  112 + aclrtSetDevice(deviceId_);
  113 + aclrtCreateContext(&context_, deviceId_);
  114 + aclrtCreateStream(&stream_);
  115 + aclrtGetRunMode(&runMode);
  116 +
  117 + /* 3.Initialization parameters: width and height of the original image, crop width and height.
  118 + * Initialize folder: Output folder */
  119 +
  120 + outPicDesc={"output.jpg", 100, 100, 300, 300};
  121 +
  122 + const int orimodelInputWidth = outPicDesc.width; // cur model shape is 224 * 224
  123 + const int orimodelInputHeight = outPicDesc.height;
  124 + const int modelInputLeft = outPicDesc.left; // cur model shape is 224 * 224
  125 + const int modelInputTop = outPicDesc.top;
  126 +
  127 + /* 4. Channel description information when creating image data processing channels,
  128 + * dvppChannelDesc_ is acldvppChannelDesc type */
  129 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  130 +
  131 + /* 5. Create the image data processing channel. */
  132 + acldvppCreateChannel(dvppChannelDesc_);
  133 +
  134 + // GetPicDevBuffer4JpegD
  135 + int modelInputWidth = (orimodelInputWidth + 15) / 16 * 16;
  136 + int modelInputHeight = (orimodelInputHeight + 1) / 2 * 2;
  137 +
  138 + uint32_t oddNum = 1;
  139 + uint32_t cropSizeWidth = modelInputWidth;
  140 + uint32_t cropSizeHeight = modelInputHeight;
  141 + uint32_t cropLeftOffset = modelInputLeft; // must even
  142 + uint32_t cropRightOffset = cropLeftOffset + cropSizeWidth - oddNum; // must odd
  143 + uint32_t cropTopOffset = modelInputTop; // must even
  144 + uint32_t cropBottomOffset = cropTopOffset + cropSizeHeight - oddNum; // must odd
  145 + acldvppRoiConfig *cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset);
  146 +
  147 + /* processdecode */
  148 + uint32_t vpcOutBufferSize_ = modelInputWidth * modelInputHeight * 3 / 2;
  149 + void *vpcOutBufferDev_ = nullptr;
  150 + acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_);
  151 + acldvppPicDesc *vpcOutputDesc_ = acldvppCreatePicDesc();
  152 + acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_);
  153 + acldvppSetPicDescFormat(vpcOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  154 + acldvppSetPicDescWidth(vpcOutputDesc_, modelInputWidth);
  155 + acldvppSetPicDescHeight(vpcOutputDesc_, modelInputHeight);
  156 + acldvppSetPicDescWidthStride(vpcOutputDesc_, modelInputWidth);
  157 + acldvppSetPicDescHeightStride(vpcOutputDesc_, modelInputHeight);
  158 + acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_);
  159 +
  160 + int ret = acldvppVpcCropAsync(dvppChannelDesc_, input_pic_desc, vpcOutputDesc_, cropArea_, stream_);
  161 +
  162 + ret = aclrtSynchronizeStream(stream_);
  163 +
  164 + DVPP_UTIL::dvpp_jpeg_encode(vpcOutputDesc_, "output.jpg");
  165 +
  166 + /* DestroycropResource */
  167 + (void)acldvppDestroyRoiConfig(cropArea_);
  168 + cropArea_ = nullptr;
  169 + (void)acldvppDestroyPicDesc(vpcOutputDesc_);
  170 + vpcOutputDesc_ = nullptr;
  171 +
  172 + if (vpcOutBufferDev_ != nullptr) {
  173 + (void)acldvppFree(vpcOutBufferDev_);
  174 + vpcOutBufferDev_ = nullptr;
  175 + }
  176 +
  177 + return SUCCESS;
  178 +}
  179 +
  180 +int dvpp_crop_init(int32_t devId){
  181 + deviceId_ = devId;
  182 +
  183 + aclError ret;
  184 + /* 2.Run the management resource application, including Device, Context, Stream */
  185 + aclrtSetDevice(deviceId_);
  186 + aclrtCreateContext(&context_, deviceId_);
  187 + aclrtCreateStream(&stream_);
  188 + aclrtGetRunMode(&runMode);
  189 +
  190 + // channel 准备
  191 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  192 + ret = acldvppCreateChannel(dvppChannelDesc_);
  193 +
  194 +}
  195 +
  196 +void check_coordinate(uint32_t& cropLeftOffset, uint32_t& cropRightOffset, uint32_t& cropTopOffset, uint32_t& cropBottomOffset, uint32_t width, uint32_t height){
  197 + if (cropLeftOffset < 0){
  198 + cropLeftOffset = 0;
  199 + }
  200 + if (cropTopOffset < 0){
  201 + cropTopOffset = 0;
  202 + }
  203 + if(cropRightOffset > width){
  204 + cropRightOffset = width;
  205 + }
  206 + if(cropBottomOffset > height){
  207 + cropBottomOffset = height;
  208 + }
  209 +
  210 +}
  211 +
  212 +vector<vpc_img_info> dvpp_crop_batch(DeviceMemory *devMem, vector<video_object_info> objs){
  213 +
  214 + vector<vpc_img_info> vec_img_info;
  215 +
  216 + /* 1.ACL initialization */
  217 + // aclInit(nullptr);
  218 + aclError ret;
  219 + aclrtSetDevice(deviceId_);
  220 + ret = aclrtSetCurrentContext(context_);
  221 +
  222 + // 输入
  223 + acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(1);
  224 + acldvppPicDesc *vpcInputDesc_ = acldvppGetPicDesc(vpcInputBatchDesc_, 0);
  225 + acldvppSetPicDescData(vpcInputDesc_, devMem->getMem());
  226 + acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  227 + acldvppSetPicDescWidth(vpcInputDesc_, devMem->getWidth());
  228 + acldvppSetPicDescHeight(vpcInputDesc_, devMem->getHeight());
  229 + acldvppSetPicDescWidthStride(vpcInputDesc_, devMem->getWidthStride());
  230 + acldvppSetPicDescHeightStride(vpcInputDesc_, devMem->getHeightStride());
  231 + acldvppSetPicDescSize(vpcInputDesc_, devMem->getSize());
  232 +
  233 + const uint32_t outputBatchSize_ = objs.size();
  234 + // 输出
  235 + acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_);
  236 + if (outputBatchPicDesc_ == nullptr) {
  237 + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed");
  238 + return vec_img_info;
  239 + }
  240 + vector<void *> vecOutPtr_;
  241 + acldvppPicDesc *vpcOutputDesc = nullptr;
  242 + // acldvppRoiConfig cropAreas[outputBatchSize_];
  243 + // std::unique_ptr<acldvppRoiConfig *[]>
  244 + // cropAreas(new(std::nothrow) acldvppRoiConfig *[outputBatchSize_ * sizeof(acldvppRoiConfig *)]);
  245 + acldvppRoiConfig *cropAreas[outputBatchSize_];
  246 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  247 + video_object_info obj = objs[i];
  248 +
  249 + int orimodelInputWidth = obj.right - obj.left;
  250 + int orimodelInputHeight = obj.bottom - obj.top;
  251 + // GetPicDevBuffer4JpegD
  252 + int modelInputWidth = (orimodelInputWidth + 15) / 16 * 16;
  253 + int modelInputHeight = (orimodelInputHeight + 1) / 2 * 2;
  254 +
  255 + uint32_t oddNum = 1;
  256 + uint32_t cropSizeWidth = modelInputWidth;
  257 + uint32_t cropSizeHeight = modelInputHeight;
  258 + uint32_t cropLeftOffset = obj.left; // must even
  259 + uint32_t cropRightOffset = obj.right;//cropLeftOffset + cropSizeWidth - oddNum; // must odd
  260 + uint32_t cropTopOffset = obj.top; // must even
  261 + uint32_t cropBottomOffset = obj.bottom;//cropTopOffset + cropSizeHeight - oddNum; // must odd
  262 +
  263 + check_coordinate(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset, devMem->getWidth(), devMem->getHeight());
  264 +
  265 + cropAreas[i] = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset);
  266 +
  267 + uint32_t vpcOutBufferSize_ = modelInputWidth * modelInputHeight * 3 / 2;
  268 + void *vpcBatchOutputBufferDev = nullptr;
  269 + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, vpcOutBufferSize_);
  270 + if (ret != ACL_SUCCESS) {
  271 + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.", vpcOutBufferSize_, static_cast<int32_t>(ret));
  272 + // 释放之前成功的部分 再退出
  273 + for(int i = 0; i < vecOutPtr_.size(); i++){
  274 + if (vecOutPtr_[i] != nullptr){
  275 + acldvppFree(vecOutPtr_[i]);
  276 + }
  277 + }
  278 + return vec_img_info;
  279 + }
  280 + vecOutPtr_.push_back(vpcBatchOutputBufferDev);
  281 + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i);
  282 + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev);
  283 + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  284 + (void)acldvppSetPicDescWidth(vpcOutputDesc, modelInputWidth);
  285 + (void)acldvppSetPicDescHeight(vpcOutputDesc, modelInputHeight);
  286 + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, modelInputWidth);
  287 + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, modelInputHeight);
  288 + (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_);
  289 + }
  290 +
  291 + uint32_t roiNums[] = { outputBatchSize_ };
  292 + ret = acldvppVpcBatchCropAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums, 1, outputBatchPicDesc_, cropAreas, stream_);
  293 + ret = aclrtSynchronizeStream(stream_);
  294 +
  295 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  296 + video_object_info obj = objs[i];
  297 +
  298 + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i);
  299 + void *outputDataDev = acldvppGetPicDescData(vpcOutputDesc);
  300 + uint32_t outputSize = acldvppGetPicDescSize(vpcOutputDesc);
  301 + uint32_t width = acldvppGetPicDescWidth(vpcOutputDesc);
  302 + uint32_t width_stride = acldvppGetPicDescWidthStride(vpcOutputDesc);
  303 + uint32_t height = acldvppGetPicDescHeight(vpcOutputDesc);
  304 + uint32_t height_stride = acldvppGetPicDescHeightStride(vpcOutputDesc);
  305 + acldvppPixelFormat fmt = acldvppGetPicDescFormat(vpcOutputDesc);
  306 +
  307 + acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc();
  308 + acldvppSetPicDescData(vpcInputDesc_, vecOutPtr_[i]);
  309 + acldvppSetPicDescFormat(vpcInputDesc_, fmt);
  310 + acldvppSetPicDescWidth(vpcInputDesc_, width);
  311 + acldvppSetPicDescHeight(vpcInputDesc_, height);
  312 + acldvppSetPicDescWidthStride(vpcInputDesc_, width_stride);
  313 + acldvppSetPicDescHeightStride(vpcInputDesc_, height_stride);
  314 + acldvppSetPicDescSize(vpcInputDesc_, outputSize);
  315 +
  316 + vpc_img_info img_info ;
  317 + img_info.pic_desc = vpcInputDesc_;
  318 + img_info.object_id = obj.object_id;
  319 + img_info.task_id = obj.task_id; //该物体属于的任务ID号
  320 + img_info.task_frame_count = obj.task_frame_count; //该物体当前出现的帧号
  321 + img_info.index = obj.index; //该物体所属类别的编号
  322 + img_info.confidence = obj.confidence; //该物体的置信度
  323 + vec_img_info.push_back(img_info);
  324 + // vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i);
  325 + // string file_name = "output";
  326 + // file_name = file_name + to_string(i) + ".jpg";
  327 + // dvpp_jpeg_encode(vpcOutputDesc, file_name);
  328 + }
  329 +
  330 + aclrtSetCurrentContext(context_);
  331 +
  332 + if (vpcInputBatchDesc_ != nullptr) {
  333 + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_);
  334 + vpcInputBatchDesc_ = nullptr;
  335 + }
  336 +
  337 + // for(int i = 0; i < vecOutPtr_.size(); i++){
  338 + // if (vecOutPtr_[i] != nullptr){
  339 + // acldvppFree(vecOutPtr_[i]);
  340 + // }
  341 + // }
  342 +
  343 + if (outputBatchPicDesc_ != nullptr) {
  344 + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_);
  345 + outputBatchPicDesc_ = nullptr;
  346 + }
  347 +
  348 + // for (size_t i = 0; i < vec_img_info.size(); i++)
  349 + // {
  350 + // if(vec_img_info[i].pic_desc != nullptr){
  351 + // void *outputDataDev = acldvppGetPicDescData(vec_img_info[i].pic_desc);
  352 + // acldvppFree(outputDataDev);
  353 + // acldvppDestroyPicDesc(vec_img_info[i].pic_desc);
  354 + // }
  355 + // }
  356 +
  357 +
  358 + for (uint32_t i = 0; i < outputBatchSize_; i++) {
  359 + if (cropAreas[i] != nullptr) {
  360 + (void)acldvppDestroyRoiConfig(cropAreas[i]);
  361 + cropAreas[i] = nullptr;
  362 + }
  363 + }
  364 +
  365 + return vec_img_info;
  366 +}
  367 +
  368 +vpc_img_info dvpp_devMem2vpcImg(DeviceMemory *devMem){
  369 + vpc_img_info img_info ;
  370 +
  371 + int nBufferSize = devMem->getSize();
  372 +
  373 + void *devBuffer = nullptr;
  374 + auto ret = acldvppMalloc(&devBuffer, nBufferSize);
  375 + if (ret != ACL_SUCCESS) {
  376 + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.", nBufferSize, static_cast<int32_t>(ret));
  377 + // 这里应释放之前成功的部分 再退出
  378 + return img_info;
  379 + }
  380 +
  381 + aclrtMemcpy(devBuffer, nBufferSize, devMem->getMem(), nBufferSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
  382 +
  383 + acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc();
  384 + acldvppSetPicDescData(vpcInputDesc_, devBuffer);
  385 + acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
  386 + acldvppSetPicDescWidth(vpcInputDesc_, devMem->getWidth());
  387 + acldvppSetPicDescHeight(vpcInputDesc_, devMem->getHeight());
  388 + acldvppSetPicDescWidthStride(vpcInputDesc_, devMem->getWidthStride());
  389 + acldvppSetPicDescHeightStride(vpcInputDesc_, devMem->getHeightStride());
  390 + acldvppSetPicDescSize(vpcInputDesc_, devMem->getSize());
  391 +
  392 + img_info.pic_desc = vpcInputDesc_;
  393 + img_info.object_id = -1;
  394 + img_info.task_id = devMem->getId(); //该物体属于的任务ID号
  395 + img_info.index = -1; //该物体所属类别的编号
  396 + img_info.confidence = 0.0; //该物体的置信度
  397 +
  398 + return img_info;
  399 +}
  400 +
  401 +void dvpp_img_release(vpc_img_info img_info){
  402 + if(img_info.pic_desc != nullptr){
  403 + void *outputDataDev = acldvppGetPicDescData(img_info.pic_desc);
  404 + acldvppFree(outputDataDev);
  405 + acldvppDestroyPicDesc(img_info.pic_desc);
  406 + }
  407 +}
  408 +
  409 +void dvpp_imgList_release(vector<vpc_img_info>& imgList){
  410 + for(int i=0; i < imgList.size(); i++){
  411 + dvpp_img_release(imgList[i]);
  412 + }
  413 + imgList.clear();
  414 +}
0 \ No newline at end of file 415 \ No newline at end of file
src/util/vpc_util.h 0 → 100644
  1 +#ifndef ___VPC_UTIL_H__
  2 +#define ___VPC_UTIL_H__
  3 +
  4 +#include "acl/acl.h"
  5 +#include "acl/ops/acl_dvpp.h"
  6 +#include "acl/dvpp/hi_dvpp.h"
  7 +#include "../ai_platform/header.h"
  8 +
  9 +#include <string>
  10 +#include <vector>
  11 +
  12 +using namespace std;
  13 +
  14 +struct vpc_img_info{
  15 + acldvppPicDesc* pic_desc{nullptr};
  16 + string task_id; //该物体属于的任务ID号
  17 + int task_frame_count; //该物体当前出现的帧号
  18 + int object_id; //该物体的ID号
  19 + int index; //该物体所属类别的编号
  20 + double confidence; //该物体的置信度
  21 +};
  22 +
  23 +class DeviceMemory;
  24 +
  25 +int dvpp_crop(acldvppPicDesc *input_pic_desc);
  26 +
  27 +int dvpp_crop_init(int32_t devId);
  28 +
  29 +vector<vpc_img_info> dvpp_crop_batch(DeviceMemory *devMem, vector<video_object_info> objs);
  30 +
  31 +void dvpp_img_release(vpc_img_info );
  32 +void dvpp_imgList_release(vector<vpc_img_info>& );
  33 +
  34 +void dvpp_crop_release();
  35 +
  36 +vpc_img_info dvpp_devMem2vpcImg(DeviceMemory *devMem);
  37 +
  38 +#endif //___VPC_UTIL_H__
0 \ No newline at end of file 39 \ No newline at end of file