test_recoder.cpp 4.23 KB
#include "./interface/DecoderManager.h"
#include <mutex>
#include <thread>
#include <chrono>

using namespace std;

struct decode_cbk_userdata{
  string task_id;
  void* opaque;
  void* opaque1;
};

deque<DeviceMemory*> 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 algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem);

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;
}

int main(){

    // 创建解码任务
    DecoderManager* pDecManager = DecoderManager::getInstance();

    MgrDecConfig config;
    config.name = task_id;
    config.cfg.uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0";
    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);


    int input_image_width = 0;
    int input_image_height = 0;
    pDecManager->getResolution(config.name, input_image_width, input_image_height);

    
    // 创建算法线程
    m_pAlgorthimThread = new thread([](void* arg) {
      algorthim_process_thread();
      return (void*)0;
    }
    , nullptr);

    pDecManager->startDecodeByName(config.name);

    while (getchar() != 'q');
}

void algorthim_process_thread(){

    while (true){
        if(m_bfinish){
            break;
        }

        vector<DeviceMemory*> vec_gpuMem;
        m_DataListMtx.lock();
        while (!m_RgbDataList.empty()){
            DeviceMemory* gpuMem = m_RgbDataList.front();
            if(gpuMem->getMem() == nullptr){
              // 错误数据,直接删除
              delete gpuMem;
              gpuMem = 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;
        }

        algorthim_face_detect(vec_gpuMem);

        for(int i=0;i < vec_gpuMem.size(); i++){
            DeviceMemory* mem = vec_gpuMem[i];
            if(mem->getSize() <= 0){
              continue;
            }
            delete mem;
            mem = nullptr;
        }
        vec_gpuMem.clear();

    }

    printf("algorthim_process_thread exit. \n");
}

static int interval = 0;
static int obj_id = 0;

void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem) {
  interval ++ ;

  if(interval % 50 != 0) {
    return;
  }

  for(int i= 0; i < vec_gpuMem.size(); i++) {
    DeviceMemory* mem = vec_gpuMem[i];
    string task_id = mem->getId();
  
    RecoderInfo recoderInfo;
    recoderInfo.task_id = task_id;
    recoderInfo.object_id = std::to_string(obj_id);
    recoderInfo.recoderDir = "./res/recode";
    recoderInfo.frame_nb = mem->getFrameNb();
    DecoderManager* pDecManager = DecoderManager::getInstance();
    pDecManager->doRecode(recoderInfo);

    obj_id++;

  }
}