Commit bf661eb0b3b0cda5a2b5a5a420de46cf311e17e7

Authored by Hu Chunming
1 parent d9fc3e82

录像文件保存优化

src/decoder/dvpp/DvppDecoder.cpp
... ... @@ -150,7 +150,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
150 150 pix_fmt = (AVPixelFormat)codecpar->format;
151 151 m_fps = av_q2d(stream ->avg_frame_rate);
152 152  
153   - m_recoderManager.init(stream->time_base, avctx);
  153 + m_recoderManager.init(stream, avctx);
154 154  
155 155 LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps);
156 156  
... ... @@ -379,9 +379,6 @@ void DvppDecoder::read_thread() {
379 379  
380 380 if (video_index == pkt->stream_index){
381 381  
382   - frame_nb++;
383   - m_recoderManager.cache_pkt(pkt, frame_nb);
384   -
385 382 ret = av_bsf_send_packet(h264bsfc, pkt);
386 383 if(ret < 0) {
387 384 LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
... ... @@ -401,6 +398,9 @@ void DvppDecoder::read_thread() {
401 398 break;
402 399 }
403 400  
  401 + frame_nb++;
  402 + m_recoderManager.cache_pkt(pkt, frame_nb);
  403 +
404 404 m_pktQueue_mutex.lock();
405 405 DataPacket* data_pkt = new DataPacket();
406 406 data_pkt->pkt = pkt;
... ...
src/decoder/dvpp/FFRecoder.cpp
... ... @@ -121,11 +121,12 @@ bool FFRecoder::init(int w, int h, AVRational time_base, AVCodecContext* avctx,
121 121 return true;
122 122 }
123 123  
124   -bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* outfile_name) {
  124 +bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfile_name) {
125 125  
126 126 codec_ctx_ = (AVCodecContext*)av_malloc(sizeof(AVCodecContext));
127 127 avcodec_copy_context(codec_ctx_, avctx);
128   - codec_ctx_->time_base = time_base;
  128 + codec_ctx_->time_base = stream->time_base;
  129 + m_inStream = stream;
129 130  
130 131 // [2] 创建输出上下文
131 132 avformat_alloc_output_context2(&fmt_ctx_, nullptr, nullptr, outfile_name);
... ... @@ -135,7 +136,8 @@ bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* ou
135 136 out_stream_->id = 0;
136 137 out_stream_->codecpar->codec_tag = 0;
137 138 avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_);
138   - out_stream_->time_base = { 1,30 };
  139 + // out_stream_->time_base = { 1,30 };
  140 + out_stream_->time_base = stream->time_base;
139 141  
140 142 av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1);
141 143  
... ... @@ -244,14 +246,32 @@ void FFRecoder::update_pts(AVPacket* pkt) {
244 246 bool FFRecoder::write_pkt(AVPacket *pkt) {
245 247 char errbuf[64]{ 0 };
246 248  
247   - // frame_number++;
248   - // pkt->pts = av_rescale_q(frame_number, codec_ctx_->time_base, out_stream_->time_base);
249   - // pkt->dts = pkt->pts;
250   - // pkt->duration = av_rescale_q(1, codec_ctx_->time_base, out_stream_->time_base);
  249 + // av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base);
  250 + // update_pts(pkt);
  251 + // pkt->stream_index = out_stream_->index;
  252 +
  253 + // if(pkt->pts==AV_NOPTS_VALUE)
  254 + {
  255 + // printf("frame_index:%d\n", frame_index);
  256 + //Write PTS
  257 + AVRational time_base1 = codec_ctx_->time_base;
  258 + //Duration between 2 frames (us)
  259 + int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(m_inStream->r_frame_rate);
  260 + //Parameters
  261 + pkt->pts = (double)(frame_index*calc_duration) / (double)(av_q2d(time_base1)*AV_TIME_BASE);
  262 + pkt->dts = pkt->pts;
  263 + pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE);
  264 + frame_index++;
  265 + }
  266 + // Convert PTS/DTS
  267 + pkt->pts = av_rescale_q_rnd(pkt->pts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  268 + pkt->dts = av_rescale_q_rnd(pkt->dts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  269 + pkt->duration = av_rescale_q(pkt->duration, codec_ctx_->time_base, out_stream_->time_base);
  270 + pkt->pos = -1;
251 271  
252   - av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base);
253 272 pkt->stream_index = out_stream_->index;
254   - update_pts(pkt);
  273 +
  274 +
255 275 // 将数据写入到输出流
256 276 int ret = av_interleaved_write_frame(fmt_ctx_, pkt);
257 277 if (ret < 0) {
... ...
src/decoder/dvpp/FFRecoder.h
... ... @@ -24,7 +24,7 @@ public:
24 24 bool flush();
25 25  
26 26 // AVPacket 方式
27   - bool init(AVRational time_base, AVCodecContext* avctx, const char* outfile_name);
  27 + bool init(AVStream* stream, AVCodecContext* avctx, const char* outfile_name);
28 28 bool write_pkt(AVPacket *pkt);
29 29  
30 30 private:
... ... @@ -50,5 +50,9 @@ private:
50 50 int64_t last_src_pts;
51 51 int64_t last_pts;
52 52  
53   - int64_t frame_number{0};
  53 + int64_t first_pts;
  54 + int64_t first_dts;
  55 +
  56 + int64_t frame_index{0};
  57 + AVStream* m_inStream;
54 58 };
55 59 \ No newline at end of file
... ...
src/decoder/dvpp/FFRecoderTaskManager.cpp
... ... @@ -37,9 +37,10 @@ FFRecoderTaskManager::~FFRecoderTaskManager(){
37 37  
38 38 }
39 39  
40   -bool FFRecoderTaskManager::init(AVRational time_base, AVCodecContext* avctx){
41   - m_time_base = time_base;
  40 +bool FFRecoderTaskManager::init(AVStream* stream, AVCodecContext* avctx){
  41 + m_time_base = stream->time_base;
42 42 m_avctx = avctx;
  43 + m_inStream = stream;
43 44  
44 45 m_recoder_thread = new std::thread(
45 46 [](void* arg) {
... ... @@ -55,6 +56,24 @@ bool FFRecoderTaskManager::init(AVRational time_base, AVCodecContext* avctx){
55 56 return true;
56 57 }
57 58  
  59 +bool FFRecoderTaskManager::init3(AVRational time_base, AVCodecContext* avctx){
  60 + m_time_base = time_base;
  61 + m_avctx = avctx;
  62 +
  63 + m_recoder_thread = new std::thread(
  64 + [](void* arg) {
  65 + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)arg;
  66 + if(_this != nullptr) {
  67 + _this->recode_thread3();
  68 + }else{
  69 + LOG_ERROR("recode 线程启动失败 !");
  70 + }
  71 + return (void*)0;
  72 + }, this);
  73 +
  74 + return true;
  75 +}
  76 +
58 77 void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb){
59 78 if(m_bExit) {
60 79 // 任务退出了就不再缓存数据了
... ... @@ -91,6 +110,42 @@ void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb){
91 110 }
92 111 }
93 112  
  113 +void FFRecoderTaskManager::cache_frame(AVFrame* frame, long long frame_nb){
  114 + if(m_bExit) {
  115 + // 任务退出了就不再缓存数据了
  116 + return;
  117 + }
  118 +
  119 + std::lock_guard<std::mutex> l_pkt(m_frame_list_mtx);
  120 +
  121 + // 考虑到一个AVPacket中的数据并不很大,为减少与解码模块的耦合度,方便管理,这里做一个clone
  122 + AVFrame *new_pkt = av_frame_clone(frame);
  123 +
  124 + DataFrame* newFrame = new DataFrame();
  125 + newFrame->frame = new_pkt;
  126 + newFrame->frame_nb = frame_nb;
  127 + m_frame_list.emplace_back(newFrame);
  128 +
  129 + // if(is_key_frame(pkt)){
  130 + // // 越来越大的值
  131 + // newFrame->isKeyFrame = true;
  132 + // LOG_INFO("key frame_nb: {}", frame_nb);
  133 + // } else {
  134 + // newFrame->isKeyFrame = false;
  135 + // }
  136 +
  137 + std::lock_guard<std::mutex> l_info(m_recoderinfo_list_mtx);
  138 + if(m_recoderinfo_list.size() <= 0){
  139 + // 没有任务的时候,维持500的长度
  140 + while(m_frame_list.size() > 1000) {
  141 + DataFrame* dataPkt = m_frame_list.front();
  142 + delete dataPkt;
  143 + dataPkt = nullptr;
  144 + m_frame_list.pop_front();
  145 + }
  146 + }
  147 +}
  148 +
94 149 void FFRecoderTaskManager::save_intask_frame_nb(unsigned long long frame_nb) {
95 150 if(m_intask_frame_nb_list.size() <= 0) {
96 151 m_intask_frame_nb_list.push_back(frame_nb);
... ... @@ -158,6 +213,43 @@ list&lt;DataPacket*&gt;::iterator FFRecoderTaskManager::getStartIterator(unsigned long
158 213 return m_pkt_list.begin();
159 214 }
160 215  
  216 +list<DataPacket*>::iterator FFRecoderTaskManager::getEndIterator(unsigned long long frame_nb){
  217 + std::lock_guard<std::mutex> l(m_pkt_list_mtx);
  218 +
  219 + auto it_first = m_pkt_list.end();
  220 +
  221 + auto it_second = m_pkt_list.begin();
  222 + for(;it_second != m_pkt_list.end(); it_second++) {
  223 + DataPacket* dataPkt = *it_second;
  224 + if (dataPkt->isKeyFrame && dataPkt->frame_nb >= frame_nb){
  225 + return it_second;
  226 + }
  227 + }
  228 +
  229 + return m_pkt_list.end();
  230 +}
  231 +
  232 +list<DataFrame*>::iterator FFRecoderTaskManager::getStartIterator3(unsigned long long frame_nb) {
  233 + std::lock_guard<std::mutex> l(m_frame_list_mtx);
  234 +
  235 + auto it_first = m_frame_list.begin();
  236 +
  237 + long long start_frame_nb = (long long)(frame_nb - 375);
  238 + if(start_frame_nb <= 0) {
  239 + return it_first;
  240 + }
  241 +
  242 + auto it_second = m_frame_list.begin();
  243 + for(;it_second != m_frame_list.end(); it_second++) {
  244 + DataFrame* dataPkt = *it_second;
  245 + if (dataPkt->frame_nb >= start_frame_nb){
  246 + return it_second;
  247 + }
  248 + }
  249 +
  250 + return m_frame_list.begin();
  251 +}
  252 +
161 253 // 多线程版
162 254 void FFRecoderTaskManager::create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo){
163 255  
... ... @@ -211,7 +303,7 @@ void FFRecoderTaskManager::recode_thread(RecodeParam recodeParam){
211 303 std::string id = recoderInfo.task_id + "_" + recoderInfo.object_id + "_" + std::to_string(recoderInfo.frame_nb);
212 304 string file_name = recoderInfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
213 305 FFRecoder ffrecoder;
214   - bool bInit = ffrecoder.init(recodeParam.time_base, recodeParam.avctx, file_name.c_str());
  306 + bool bInit = ffrecoder.init(m_inStream, recodeParam.avctx, file_name.c_str());
215 307 if (!bInit) {
216 308 LOG_ERROR("ffrecoder init error : {} {} {}", recoderInfo.task_id, recoderInfo.object_id, recoderInfo.frame_nb);
217 309 m_id_recoderTask.erase(id);
... ... @@ -260,6 +352,161 @@ void FFRecoderTaskManager::recode_thread2() {
260 352 continue;
261 353 }
262 354  
  355 + auto it_end = getEndIterator(recoderinfo.frame_nb);
  356 +
  357 + LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb);
  358 +
  359 + m_pkt_list_mtx.lock();
  360 + auto it = m_pkt_list.begin();
  361 + while (it != it_data) {
  362 + DataPacket* dataPkt = m_pkt_list.front();
  363 + delete dataPkt;
  364 + dataPkt = nullptr;
  365 + m_pkt_list.pop_front();
  366 + it = m_pkt_list.begin();
  367 + }
  368 + m_pkt_list_mtx.unlock();
  369 +
  370 + std::string id = recoderinfo.task_id + "_" + recoderinfo.object_id + "_" + std::to_string(recoderinfo.frame_nb);
  371 + string file_name = recoderinfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
  372 + FFRecoder ffrecoder;
  373 + bool bInit = ffrecoder.init(m_inStream, m_avctx, file_name.c_str());
  374 + if (!bInit) {
  375 + LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb);
  376 + ffrecoder.uninit();
  377 + continue;
  378 + }
  379 + LOG_INFO("record start, pkt_list size: {} id: {}", m_pkt_list.size(), id);
  380 +
  381 + int count = 0;
  382 + auto it_save = it_data;
  383 + unsigned long long start_frame_nb = (*it_data)->frame_nb;
  384 + unsigned long long end_frame_nb = (*it_data)->frame_nb;
  385 + for (; it_save != m_pkt_list.end() && count < 500; ++it_save) {
  386 + DataPacket* dataPkt = *it_save;
  387 + if(dataPkt->frame_nb > recoderinfo.frame_nb) {
  388 + break;
  389 + }
  390 + AVPacket* pkt = dataPkt->pkt;
  391 + ffrecoder.write_pkt(pkt);
  392 + count++;
  393 + end_frame_nb = (*it_save)->frame_nb;
  394 + }
  395 +
  396 + // ffrecoder.flush();
  397 + ffrecoder.uninit();
  398 +
  399 + // 发送mq消息
  400 + if(mq_publish_func) {
  401 + mq_publish_func(recoderinfo.mq_info.c_str());
  402 + }
  403 +
  404 + LOG_INFO("record end, total save: {} start_frame_nb: {} end_frame_nb: {} file_path: {}", count, start_frame_nb, end_frame_nb, file_name);
  405 + }
  406 +
  407 + LOG_INFO("recode_thread2 end.");
  408 +}
  409 +
  410 +void FFRecoderTaskManager::recode_thread3() {
  411 + LOG_INFO("recode_thread2 start...");
  412 + while(true) {
  413 + if(m_bExit) {
  414 + break;
  415 + }
  416 +
  417 + m_recoderinfo_list_mtx.lock();
  418 + if(m_recoderinfo_list.size() <= 0){
  419 + m_recoderinfo_list_mtx.unlock();
  420 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  421 + continue;
  422 + }
  423 +
  424 + auto it_param = m_recoderinfo_list.begin();
  425 + RecoderInfo recoderinfo = *it_param;
  426 + m_recoderinfo_list.pop_front();
  427 + m_recoderinfo_list_mtx.unlock();
  428 +
  429 + auto it_data = getStartIterator3(recoderinfo.frame_nb);
  430 + if(it_data == m_frame_list.end()) {
  431 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  432 + continue;
  433 + }
  434 +
  435 + LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb);
  436 +
  437 + m_frame_list_mtx.lock();
  438 + auto it = m_frame_list.begin();
  439 + while (it != it_data) {
  440 + DataFrame* dataPkt = m_frame_list.front();
  441 + delete dataPkt;
  442 + dataPkt = nullptr;
  443 + m_frame_list.pop_front();
  444 + it = m_frame_list.begin();
  445 + }
  446 + m_frame_list_mtx.unlock();
  447 +
  448 + std::string id = recoderinfo.task_id + "_" + recoderinfo.object_id + "_" + std::to_string(recoderinfo.frame_nb);
  449 + string file_name = recoderinfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
  450 + FFRecoder ffrecoder;
  451 + bool bInit = ffrecoder.init(m_avctx->width, m_avctx->height, m_time_base, m_avctx, file_name.c_str());
  452 + if (!bInit) {
  453 + LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb);
  454 + ffrecoder.uninit();
  455 + continue;
  456 + }
  457 + LOG_INFO("record start, pkt_list size: {} id: {}", m_frame_list.size(), id);
  458 +
  459 + int count = 0;
  460 + auto it_save = it_data;
  461 + unsigned long long start_frame_nb = (*it_data)->frame_nb;
  462 + unsigned long long end_frame_nb = (*it_data)->frame_nb;
  463 + for (; it_save != m_frame_list.end() && count < 500; ++it_save) {
  464 + DataFrame* dataPkt = *it_save;
  465 + AVFrame* pkt = dataPkt->frame;
  466 + ffrecoder.write_frame(pkt);
  467 + count++;
  468 + end_frame_nb = (*it_save)->frame_nb;
  469 + }
  470 +
  471 + // ffrecoder.flush();
  472 + ffrecoder.uninit();
  473 +
  474 + // 发送mq消息
  475 + if(mq_publish_func) {
  476 + mq_publish_func(recoderinfo.mq_info.c_str());
  477 + }
  478 +
  479 + LOG_INFO("record end, total save: {} start_frame_nb: {} end_frame_nb: {} file_path: {}", count, start_frame_nb, end_frame_nb, file_name);
  480 + }
  481 +
  482 + LOG_INFO("recode_thread2 end.");
  483 +}
  484 +
  485 +void FFRecoderTaskManager::recode_thread4() {
  486 + LOG_INFO("recode_thread2 start...");
  487 + while(true) {
  488 + if(m_bExit) {
  489 + break;
  490 + }
  491 +
  492 + m_recoderinfo_list_mtx.lock();
  493 + if(m_recoderinfo_list.size() <= 0){
  494 + m_recoderinfo_list_mtx.unlock();
  495 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  496 + continue;
  497 + }
  498 +
  499 + auto it_param = m_recoderinfo_list.begin();
  500 + RecoderInfo recoderinfo = *it_param;
  501 + m_recoderinfo_list.pop_front();
  502 + m_recoderinfo_list_mtx.unlock();
  503 +
  504 + auto it_data = getStartIterator(recoderinfo.frame_nb);
  505 + if(it_data == m_pkt_list.end()) {
  506 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  507 + continue;
  508 + }
  509 +
263 510 LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb);
264 511  
265 512 m_pkt_list_mtx.lock();
... ... @@ -276,7 +523,7 @@ void FFRecoderTaskManager::recode_thread2() {
276 523 std::string id = recoderinfo.task_id + "_" + recoderinfo.object_id + "_" + std::to_string(recoderinfo.frame_nb);
277 524 string file_name = recoderinfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4";
278 525 FFRecoder ffrecoder;
279   - bool bInit = ffrecoder.init(m_time_base, m_avctx, file_name.c_str());
  526 + bool bInit = ffrecoder.init(m_inStream, m_avctx, file_name.c_str());
280 527 if (!bInit) {
281 528 LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb);
282 529 ffrecoder.uninit();
... ...
src/decoder/dvpp/FFRecoderTaskManager.h
... ... @@ -28,18 +28,26 @@ public:
28 28 void cache_pkt(AVPacket* pkt, long long frame_nb);
29 29 void create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo);
30 30  
31   - bool init(AVRational time_base, AVCodecContext* avctx);
  31 + bool init(AVStream* stream, AVCodecContext* avctx);
32 32 void create_recode_task2(RecoderInfo& recoderInfo);
33 33  
34 34 void close();
35 35  
36 36 void set_mq_callback(mq_callback_t cb);
37 37  
  38 + bool init3(AVRational time_base, AVCodecContext* avctx);
  39 + void cache_frame(AVFrame* frame, long long frame_nb);
  40 +
38 41 public:
39 42 void recode_thread(RecodeParam param);
40 43 list<DataPacket*>::iterator getStartIterator(unsigned long long frame_nb);
  44 + list<DataPacket*>::iterator getEndIterator(unsigned long long frame_nb);
41 45  
42 46 void recode_thread2();
  47 + void recode_thread4();
  48 +
  49 + list<DataFrame*>::iterator getStartIterator3(unsigned long long frame_nb);
  50 + void recode_thread3();
43 51  
44 52 private:
45 53 void save_intask_frame_nb(unsigned long long frame_nb);
... ... @@ -64,8 +72,12 @@ private:
64 72  
65 73 AVRational m_time_base;
66 74 AVCodecContext* m_avctx;
  75 + AVStream* m_inStream;
67 76  
68 77 thread* m_recoder_thread{nullptr};
69 78  
70 79 mq_callback_t mq_publish_func;
  80 +
  81 + std::list<DataFrame*> m_frame_list;
  82 + mutex m_frame_list_mtx;
71 83 };
72 84 \ No newline at end of file
... ...
src/decoder/dvpp/depend_headers.h
... ... @@ -49,4 +49,17 @@ struct DataPacket {
49 49 }
50 50 };
51 51  
  52 +struct DataFrame {
  53 + AVFrame* frame {nullptr};
  54 + unsigned long long frame_nb{0};
  55 + bool isKeyFrame{false};
  56 +
  57 + ~DataFrame(){
  58 + if(frame != nullptr) {
  59 + av_frame_free(&frame);
  60 + frame = nullptr;
  61 + }
  62 + }
  63 +};
  64 +
52 65 #endif
53 66 \ No newline at end of file
... ...
src/decoder/test_recoder.cpp
... ... @@ -29,6 +29,8 @@ void algorthim_process_thread();
29 29 void recode_thread();
30 30 void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem);
31 31  
  32 +void test_recode_thread();
  33 +
32 34 void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){
33 35 do{
34 36 if(m_bfinish){
... ... @@ -62,7 +64,7 @@ int main(){
62 64  
63 65 MgrDecConfig config;
64 66 config.name = task_id;
65   - config.cfg.uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0";
  67 + config.cfg.uri = "rtsp://122.97.218.170:8604/openUrl/LBBYTra?params=eyJwcm90b2NhbCI6InJ0c3AiLCJjbGllbnRUeXBlIjoib3Blbl9hcGkiLCJleHByaWVUaW1lIjotMSwicHJvdG9jb2wiOiJydHNwIiwiZXhwaXJlVGltZSI6MzAwLCJlbmFibGVNR0MiOnRydWUsImV4cGFuZCI6InN0YW5kYXJkPXJ0c3Amc3RyZWFtZm9ybT1ydHAiLCJhIjoiOTgzYjRjMmUxMThlNGU1OTlkYThmMTI3NTkyMGViODV8MXwwfDEiLCJ0IjoxfQ==";
66 68 config.cfg.post_decoded_cbk = post_decod_cbk;
67 69 config.cfg.decode_finished_cbk = decode_finished_cbk;
68 70 config.cfg.force_tcp = true; // rtsp用tcp
... ... @@ -95,8 +97,14 @@ int main(){
95 97 }
96 98 , nullptr);
97 99  
  100 + // m_recodeThread = new thread([](void* arg) {
  101 + // recode_thread();
  102 + // return (void*)0;
  103 + // }
  104 + // , nullptr);
  105 +
98 106 m_recodeThread = new thread([](void* arg) {
99   - recode_thread();
  107 + test_recode_thread();
100 108 return (void*)0;
101 109 }
102 110 , nullptr);
... ... @@ -183,6 +191,43 @@ void algorthim_face_detect(vector&lt;DeviceMemory*&gt; vec_gpuMem) {
183 191 }
184 192 }
185 193  
  194 +void test_recode_thread() {
  195 + unsigned long long frame_index = 0;
  196 + while(true) {
  197 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  198 +
  199 + DeviceMemory* mem = nullptr;
  200 + m_DataListMtx.lock();
  201 + while (!m_RgbDataList.empty()){
  202 + DeviceMemory* gpuMem = m_RgbDataList.front();
  203 + if(gpuMem->getMem() == nullptr){
  204 + // 错误数据,直接删除
  205 + delete gpuMem;
  206 + gpuMem = nullptr;
  207 + printf("mem is null \n");
  208 + } else {
  209 + frame_index ++ ;
  210 + if (frame_index % 50 == 0) {
  211 + RecoderInfo recoderInfo;
  212 + recoderInfo.task_id = gpuMem->getId();
  213 + recoderInfo.object_id = std::to_string(obj_id);
  214 + recoderInfo.recoderDir = "./res/recode";
  215 + recoderInfo.frame_nb = gpuMem->getFrameNb();
  216 +
  217 + DecoderManager* pDecManager = DecoderManager::getInstance();
  218 + pDecManager->doRecode(recoderInfo);
  219 +
  220 + obj_id++;
  221 + }
  222 + delete gpuMem;
  223 + gpuMem = nullptr;
  224 + }
  225 + m_RgbDataList.pop_front();
  226 + }
  227 + m_DataListMtx.unlock();
  228 + }
  229 +}
  230 +
186 231 void recode_thread() {
187 232 while(true) {
188 233  
... ...