#include "./interface/DecoderManager.h" #include #include #include #include "./interface/logger.hpp" #include "vpt.h" #include "muxer.h" #include "acl/acl.h" #include "acl/ops/acl_dvpp.h" #include using namespace std; using namespace cv; struct decode_cbk_userdata{ string task_id; void* opaque; void* opaque1; }; deque m_RgbDataList; mutex m_DataListMtx; thread* m_pAlgorthimThread{nullptr}; bool m_bfinish{false}; int m_devId = 0; const char* task_id = "test0"; int skip_frame_ = 5; int m_batch_size = 20; void algorthim_process_thread(); void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){ do{ if(m_bfinish){ break; } m_DataListMtx.lock(); if(m_RgbDataList.size() >= 30){ m_DataListMtx.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(3)); continue; } m_RgbDataList.push_back(devFrame); m_DataListMtx.unlock(); break; }while (true); } void decode_finished_cbk(const void * userPtr){ decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr; if (ptr!= nullptr){ printf("task finished: %s \n", ptr->task_id.c_str()); delete ptr; ptr = nullptr; } } bool create_task(string task_id) { // 创建解码任务 DecoderManager* pDecManager = DecoderManager::getInstance(); MgrDecConfig config; config.name = task_id; config.cfg.uri = "/home/cmhu/data/爱剪辑-高清事件测试.mp4"; config.cfg.post_decoded_cbk = post_decod_cbk; config.cfg.decode_finished_cbk = decode_finished_cbk; config.cfg.force_tcp = true; // rtsp用tcp config.cfg.gpuid = to_string(m_devId); config.cfg.skip_frame = skip_frame_; config.dec_type = DECODER_TYPE_DVPP; AbstractDecoder* dec = pDecManager->createDecoder(config); if (!dec){ printf("创建解码器失败 \n"); return false; } // decode_cbk_userdata* userPtr = new decode_cbk_userdata; // userPtr->task_id = string(task_id); // pDecManager->setPostDecArg(config.name, userPtr); // pDecManager->setFinishedDecArg(config.name, userPtr); dec->setSnapTimeInterval(1000); int input_image_width = 0; int input_image_height = 0; pDecManager->getResolution(config.name, input_image_width, input_image_height); pDecManager->startDecodeByName(config.name); // pDecManager->closeAllDecoder(); return true; } void* handle = nullptr; aclrtContext ctx; int m_max_batchsize = 16; muxer* pEncoder = nullptr; int main(){ set_default_logger(LogLevel(0), "test_decode","logs/main.log", 64 * 1024 * 1024, 64 * 1024 * 1024); LOG_INFO("编译时间:{} {}", __DATE__, __TIME__); printf("start... \n"); vpt_param param; param.modelNames_b = "./models/vpt/vpt230323_b16_bgr_310p.om"; param.threshold = 0.35; param.devId = 0; param.max_batch = m_max_batchsize; param.isTrk = false; cout << "init start " << endl; aclInit(nullptr); aclrtSetDevice(param.devId); aclrtCreateContext(&ctx, param.devId); int ret = vpt_init(&handle, param); if (ret != 0) { cout << "init vpt failed! " << endl; return -1; } DecoderManager* pDecManager = DecoderManager::getInstance(); // 创建算法线程 m_pAlgorthimThread = new thread([](void* arg) { algorthim_process_thread(); return (void*)0; } , nullptr); char ch = 'a'; int task_id = 1; create_task(to_string(task_id)); task_id++; while (ch != 'q') { ch = getchar(); switch (ch) { case '4': for (size_t i = 0; i < 4; i++) { create_task(to_string(task_id)); task_id++; std::this_thread::sleep_for(std::chrono::seconds(1)); } break; case 'a': create_task(to_string(task_id)); task_id++; std::this_thread::sleep_for(std::chrono::seconds(1)); break; case 'c': pDecManager->closeAllDecoder(); break; default: break; } } if (pEncoder != nullptr) { pEncoder->close(); delete pEncoder; } } void do_work(vector vec_gpuMem){ int batchsize = vec_gpuMem.size(); vector >> detectResult(batchsize); int real_index = 0; int cycle_time = batchsize / m_max_batchsize; cycle_time = (batchsize % m_max_batchsize) == 0 ? cycle_time : (cycle_time + 1); vector vec_img; for (int i = 0; i < cycle_time; i++) { vec_img.clear(); int start_index = i * m_max_batchsize; int end_index = start_index + m_max_batchsize; if (end_index >= batchsize) { end_index = batchsize; } for (int j = start_index; j < end_index; j++){ DeviceMemory* gpuMem = vec_gpuMem[j]; sy_img img; img.set_data(gpuMem->getWidth(), gpuMem->getHeight(), gpuMem->getChannel(), gpuMem->getMem()); vec_img.push_back(img); } vpt_result detresult[vec_img.size()]; for (int b = 0; b < vec_img.size(); b++) { detresult[b].obj_results_ = new vpt_obj_result[MAX_DET_COUNT]; } int res_status = vpt_batchV2(handle, vec_img.data(), vec_img.size(), detresult); for (size_t b = 0; b < vec_img.size(); b++) { auto& cur_result = detresult[b]; sy_img image = vec_img[b]; int data_size = image.w_ * image.h_ * 3; unsigned char* pData = (unsigned char*) malloc (data_size); int ret = aclrtMemcpy(pData, data_size, image.data_, data_size, ACL_MEMCPY_DEVICE_TO_HOST); if(ret != ACL_ERROR_NONE){ free(pData); cout << "aclrtMemcpy failed" << endl; continue; } cv::Mat cvImg(image.h_, image.w_ , CV_8UC3, pData); for (int i = 0; i init(cvImg.cols, cvImg.rows, 25, 4992000, "./vpt.mp4"); } pEncoder->write_image(cvImg.data); free(pData); delete [] cur_result.obj_results_; real_index++; } } } void algorthim_process_thread(){ while (true){ if(m_bfinish){ break; } vector vec_gpuMem; m_DataListMtx.lock(); while (!m_RgbDataList.empty()){ DeviceMemory* gpuMem = m_RgbDataList.front(); if(gpuMem->getMem() == nullptr){ // 错误数据,直接删除 printf("mem is null \n"); } else { vec_gpuMem.push_back(gpuMem); } m_RgbDataList.pop_front(); if(vec_gpuMem.size() >= m_batch_size){ break; } } m_DataListMtx.unlock(); if(vec_gpuMem.size() <= 0){ std::this_thread::sleep_for(std::chrono::milliseconds(3)); continue; } aclrtSetDevice(0); aclrtSetCurrentContext(ctx); // do work do_work(vec_gpuMem); for (size_t i = 0; i < vec_gpuMem.size(); i++) { DeviceMemory* gpuMem = vec_gpuMem[i]; delete gpuMem; gpuMem = nullptr; } vec_gpuMem.clear(); } printf("algorthim_process_thread exit. \n"); }