Commit 77e1339cc5e9a80442364cb93aa76a7283171d45
1 parent
ffe81045
GB28181 补充定时抓拍接口,补充保存视频接口
Showing
16 changed files
with
639 additions
and
115 deletions
bin/sip_server_cfg.xml
0 → 100644
1 | +<?xml version="1.0" encoding="GB2312"?> | |
2 | +<ROOT> | |
3 | + <Ua>SY_Sip_Server</Ua> | |
4 | + <Nonce>12345678</Nonce> | |
5 | + <Ip>192.168.60.179</Ip> | |
6 | + <Port>15060</Port> | |
7 | + <SipId>34020000002000000002</SipId> | |
8 | + <SipRealm>3402000000</SipRealm> | |
9 | + <Password>sy123456</Password> | |
10 | + <Timeout>1800</Timeout> | |
11 | + <Expiry>3600</Expiry> | |
12 | +</ROOT> | ... | ... |
src/ai_engine_module/pedestrian_vehicle_trespass.cpp
... | ... | @@ -150,10 +150,27 @@ bool PedestrianVehicleTrespass::in_rect_analysis(const obj_key_t &id, const box_ |
150 | 150 | } |
151 | 151 | } |
152 | 152 | |
153 | +bool PedestrianVehicleTrespass::isInited(string task_id) { | |
154 | + auto it = m_task_inited.find(task_id); | |
155 | + if(it == m_task_inited.end()){ | |
156 | + return false; | |
157 | + } | |
158 | + return true; | |
159 | +} | |
160 | + | |
161 | +void PedestrianVehicleTrespass::release(string task_id) { | |
162 | + auto it = m_task_inited.find(task_id); | |
163 | + if(it != m_task_inited.end()){ | |
164 | + m_task_inited.erase(it); | |
165 | + } | |
166 | +} | |
167 | + | |
153 | 168 | /* 根据用户输入的点 初始化禁区区域mask */ |
154 | 169 | void PedestrianVehicleTrespass::pedestrianvehicletrespass_init_region(const string &task_id, |
155 | 170 | const algorithm_type_t algor_type, |
156 | 171 | const int width, const int height) { |
172 | + m_task_inited[task_id] = true; | |
173 | + | |
157 | 174 | obj_key_t obj_key = {0, task_id, algor_type}; |
158 | 175 | |
159 | 176 | auto &&algor_type_seq = task_id_to_algorithm_type_seq(task_id, task_param_manager_); | ... | ... |
src/ai_engine_module/pedestrian_vehicle_trespass.h
... | ... | @@ -34,6 +34,10 @@ public: |
34 | 34 | |
35 | 35 | ~PedestrianVehicleTrespass(); |
36 | 36 | |
37 | + bool isInited(string task_id); | |
38 | + | |
39 | + void release(string task_id); | |
40 | + | |
37 | 41 | void pedestrianvehicletrespass_init_region(const string &task_id, const algorithm_type_t algor_type, const int width, |
38 | 42 | const int height); |
39 | 43 | |
... | ... | @@ -55,6 +59,8 @@ private: |
55 | 59 | std::map<obj_key_t, vector<result_data_t> > obj_to_alarm_boxes_; |
56 | 60 | std::map<obj_key_t, box_t> obj_to_position_; // 保存物体上一帧的位置,基于非法闯入判断逻辑,上一帧在框外,下一帧闯入禁区 |
57 | 61 | std::map<obj_key_t, cv::Mat> trespass_regions; |
62 | + | |
63 | + std::map<string, bool> m_task_inited; | |
58 | 64 | }; |
59 | 65 | } // namespace pedestrian_vehicle_trespass |
60 | 66 | } // namespace ai_engine_module | ... | ... |
src/ai_platform/MultiSourceProcess.cpp
... | ... | @@ -322,7 +322,7 @@ int CMultiSourceProcess::GetTaskStatus(const string taskID) { |
322 | 322 | bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ |
323 | 323 | DecoderManager* pDecManager = DecoderManager::getInstance(); |
324 | 324 | |
325 | - const char* task_id = _cur_task_param.task_id; | |
325 | + string task_id = _cur_task_param.task_id; | |
326 | 326 | |
327 | 327 | MgrDecConfig config; |
328 | 328 | config.name = task_id; |
... | ... | @@ -360,7 +360,7 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ |
360 | 360 | } |
361 | 361 | |
362 | 362 | decode_cbk_userdata* userPtr = new decode_cbk_userdata; |
363 | - userPtr->task_id = string(task_id); | |
363 | + userPtr->task_id = task_id; | |
364 | 364 | userPtr->opaque = this; |
365 | 365 | userPtr->opaque1 = dec; |
366 | 366 | pDecManager->setPostDecArg(config.name, userPtr); |
... | ... | @@ -372,11 +372,6 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ |
372 | 372 | // 保存新添加任务的配置参数 |
373 | 373 | m_task_param_manager->add_task_param(task_id, _cur_task_param); |
374 | 374 | |
375 | - int input_image_width = 0; | |
376 | - int input_image_height = 0; | |
377 | - pDecManager->getOutResolution(config.name, input_image_width, input_image_height); | |
378 | - LOG_INFO("task_id: {} width: {} height:{}", task_id, input_image_width, input_image_height); | |
379 | - | |
380 | 375 | // 所有参数都准备好之后再启动解码 |
381 | 376 | bool bStart = pDecManager->startDecodeByName(config.name); |
382 | 377 | if (!bStart){ |
... | ... | @@ -391,12 +386,12 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ |
391 | 386 | #endif |
392 | 387 | |
393 | 388 | // 人车物跟踪 |
394 | - if (task_has_vpt_algor(task_id)) | |
389 | + if (m_task_param_manager->task_has_vpt_algor(task_id)) | |
395 | 390 | vpt_process.addTaskTracker(task_id, 1, 1, skip_frame_); |
396 | 391 | |
397 | 392 | // 人脸跟踪 |
398 | 393 | #ifdef WITH_FACE_DET_SS |
399 | - if (task_has_face_algor(task_id)) | |
394 | + if (m_task_param_manager->task_has_face_algor(task_id)) | |
400 | 395 | m_face_det_ai_engine.add_tracker(task_id, skip_frame_); // 跳帧数暂时写死 |
401 | 396 | #endif |
402 | 397 | |
... | ... | @@ -404,37 +399,9 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ |
404 | 399 | m_FinishedTaskMap[task_id] = false; |
405 | 400 | m_FinishedTaskMtx.unlock(); |
406 | 401 | |
407 | - auto algor_map = m_task_param_manager->get_task_other_param(task_id); | |
408 | - if (algor_map != nullptr){ | |
409 | - /* 如果开启了行人 机动车非法闯入功能 生成闯入区域mask */ | |
410 | - if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end()) { | |
411 | - pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( | |
412 | - task_id, algorithm_type_t::PEDESTRIAN_TRESPASS, input_image_width, input_image_height); | |
413 | - } | |
414 | - | |
415 | - if (algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) { | |
416 | - pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( | |
417 | - task_id, algorithm_type_t::VEHICLE_TRESPASS, input_image_width, input_image_height); | |
418 | - } | |
419 | - | |
420 | - // 设置定时截图的时间间隔 | |
421 | - auto algor = algor_map->find(algorithm_type_t::VIDEO_TIMING_SNAPSHOT); | |
422 | - if(algor != algor_map->end()){ | |
423 | - task_param_manager::algo_param_type_t_* cur_task_params = algor->second; | |
424 | - if(cur_task_params){ | |
425 | - int frame_stride = ((algor_config_video_timing_snapshot*)cur_task_params->algor_param)->frame_stride; | |
426 | - LOG_INFO("task {} snap time interval: {} s", config.name, frame_stride); | |
427 | - // 单位是ms, 乘以 1000 编成s | |
428 | - dec->setSnapTimeInterval(frame_stride * 1000); | |
429 | - } | |
430 | - } | |
431 | - | |
432 | - // 测试代码 | |
433 | - // auto algor_face = algor_map->find(algorithm_type_t::FACE_SNAPSHOT); | |
434 | - // if(algor_face != algor_map->end()){ | |
435 | - // const algor_basic_config_param_t *cur_param = ((algor_init_config_param_t *)(algor_face->second))->basic_param; | |
436 | - // LOG_INFO("face_snapshot, result_folder: {} result_folder_little: {}", cur_param->result_folder, cur_param->result_folder_little); | |
437 | - // } | |
402 | + int time_interval = m_task_param_manager->get_video_timing_snapshot_interval(task_id); | |
403 | + if(time_interval > 0) { | |
404 | + dec->setSnapTimeInterval(time_interval); | |
438 | 405 | } |
439 | 406 | |
440 | 407 | LOG_INFO("started task {} successed!", config.name); |
... | ... | @@ -447,55 +414,6 @@ int CMultiSourceProcess::CountRunningTask() { |
447 | 414 | return pDecManager->count(); |
448 | 415 | } |
449 | 416 | |
450 | -bool CMultiSourceProcess::task_has_vpt_algor(const std::string &task_id){ | |
451 | - //! TODO: create enum iterator. | |
452 | - auto algor_map = m_task_param_manager->get_task_other_param(task_id); | |
453 | - if (algor_map == nullptr) | |
454 | - return false; | |
455 | - | |
456 | - return (algor_map->find(algorithm_type_t::HUMAN_GATHER) != algor_map->end() || | |
457 | - algor_map->find(algorithm_type_t::HUMAN_SNAPSHOT) != algor_map->end() || | |
458 | - algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != algor_map->end() || | |
459 | - algor_map->find(algorithm_type_t::SMOKING_DET) != algor_map->end() || | |
460 | - algor_map->find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != algor_map->end() || | |
461 | - algor_map->find(algorithm_type_t::NO_SAFETY_HELMET) != algor_map->end() || | |
462 | - algor_map->find(algorithm_type_t::CALL_PHONE_DET) != algor_map->end() || | |
463 | - algor_map->find(algorithm_type_t::VEHICLE_SNAPSHOT) != algor_map->end() || | |
464 | - algor_map->find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) != algor_map->end() || | |
465 | - algor_map->find(algorithm_type_t::PEDESTRIAN_FALL) != algor_map->end() || | |
466 | - algor_map->find(algorithm_type_t::PEDESTRIAN_FIGHT) != algor_map->end() || | |
467 | - algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() || | |
468 | - algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end() || | |
469 | - algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || | |
470 | - algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end() || | |
471 | - algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET) != algor_map->end() || | |
472 | - algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN) != algor_map->end() || | |
473 | - algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE) != algor_map->end() || | |
474 | - algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_REFIT) != algor_map->end() || | |
475 | - algor_map->find(algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS) != algor_map->end() || | |
476 | - algor_map->find(algorithm_type_t::NONMOTOR_CEOSSPARKLINE) != algor_map->end() || | |
477 | - algor_map->find(algorithm_type_t::NONMOTOR_IN_VEHICLELANE) != algor_map->end() || | |
478 | - algor_map->find(algorithm_type_t::NONMOTOR_WRONGDIRECTION) != algor_map->end() || | |
479 | - algor_map->find(algorithm_type_t::PERSON_IN_VEHICLELANE) != algor_map->end() || | |
480 | - algor_map->find(algorithm_type_t::PERSON_RUNNING_REDLIGHTS) != algor_map->end() || | |
481 | - algor_map->find(algorithm_type_t::PERSON_CROSS) != algor_map->end() || | |
482 | - algor_map->find(algorithm_type_t::VEHICLE_WRONGDIRECTION) != algor_map->end() || | |
483 | - algor_map->find(algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) != algor_map->end() || | |
484 | - algor_map->find(algorithm_type_t::VEHICLE_NOTGIVEWAY) != algor_map->end() || | |
485 | - algor_map->find(algorithm_type_t::VEHICLE_NOTDECELERATION) != algor_map->end() || | |
486 | - algor_map->find(algorithm_type_t::TRICYCLE_MANNED) != algor_map->end() || | |
487 | - algor_map->find(algorithm_type_t::TRUCK_MANNED) != algor_map->end()); | |
488 | -} | |
489 | - | |
490 | -bool CMultiSourceProcess::task_has_face_algor(const std::string &task_id){ | |
491 | - auto algor_map = m_task_param_manager->get_task_other_param(task_id); | |
492 | - if (nullptr != algor_map){ | |
493 | - return algor_map->find(algorithm_type_t::FACE_SNAPSHOT) != algor_map->end(); | |
494 | - } | |
495 | - | |
496 | - return false; | |
497 | -} | |
498 | - | |
499 | 417 | void CMultiSourceProcess::decoded_cbk(DeviceMemory* devFrame){ |
500 | 418 | |
501 | 419 | do{ |
... | ... | @@ -689,12 +607,13 @@ void CMultiSourceProcess::clear_finished_task(){// 清理已经结束的任务 |
689 | 607 | // 解码器已经结束,且数据队列中没有改任务的数据,则做最后任务清理工作 |
690 | 608 | finish_task(task_id,false); |
691 | 609 | iter_finished = m_FinishedTaskMap.erase(iter_finished); |
610 | + pedestrian_vehicle_trespass_.release(task_id); | |
692 | 611 | continue; |
693 | 612 | } |
694 | 613 | } |
695 | 614 | |
696 | 615 | ++ iter_finished; |
697 | - } | |
616 | + } | |
698 | 617 | } |
699 | 618 | |
700 | 619 | bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_snapshot){ |
... | ... | @@ -705,7 +624,7 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna |
705 | 624 | |
706 | 625 | #ifdef WITH_FACE_DET_SS |
707 | 626 | // 人脸任务结束 |
708 | - if (task_has_face_algor(taskID)) | |
627 | + if (m_task_param_manager->task_has_face_algor(taskID)) | |
709 | 628 | m_face_det_ai_engine.finish_task(taskID); |
710 | 629 | #endif |
711 | 630 | |
... | ... | @@ -805,6 +724,30 @@ int CMultiSourceProcess::algorthim_process_thread(){ |
805 | 724 | LOG_WARN("mem is null"); |
806 | 725 | } else { |
807 | 726 | vec_gpuMem.push_back(gpuMem); |
727 | + | |
728 | + string task_id = gpuMem->getId(); | |
729 | + if (!pedestrian_vehicle_trespass_.isInited(task_id)) { | |
730 | + auto algor_map = m_task_param_manager->get_task_other_param(task_id); | |
731 | + if (algor_map != nullptr) { | |
732 | + int input_image_width = gpuMem->getWidth(); | |
733 | + int input_image_height = gpuMem->getHeight(); | |
734 | + LOG_INFO("task_id: {} width: {} height:{}", task_id, input_image_width, input_image_height); | |
735 | + | |
736 | + /* 如果开启了行人 机动车非法闯入功能 生成闯入区域mask */ | |
737 | + if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end()) { | |
738 | + pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( | |
739 | + task_id, algorithm_type_t::PEDESTRIAN_TRESPASS, input_image_width, input_image_height); | |
740 | + } | |
741 | + | |
742 | + if (algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) { | |
743 | + pedestrian_vehicle_trespass_.pedestrianvehicletrespass_init_region( | |
744 | + task_id, algorithm_type_t::VEHICLE_TRESPASS, input_image_width, input_image_height); | |
745 | + } | |
746 | + } | |
747 | + } | |
748 | + | |
749 | + | |
750 | + | |
808 | 751 | } |
809 | 752 | |
810 | 753 | m_RgbDataList.pop_front(); |
... | ... | @@ -913,7 +856,7 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){ |
913 | 856 | vector<DeviceMemory*> vec_vptMem; |
914 | 857 | for (int i = 0; i < vec_gpuMem.size(); i++) { |
915 | 858 | DeviceMemory* mem = vec_gpuMem[i]; |
916 | - if (!task_has_vpt_algor(mem->getId())){ | |
859 | + if (!m_task_param_manager->task_has_vpt_algor(mem->getId())){ | |
917 | 860 | continue; |
918 | 861 | } |
919 | 862 | |
... | ... | @@ -2100,7 +2043,7 @@ void CMultiSourceProcess::algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem |
2100 | 2043 | vector<DeviceMemory*> vec_vptMem; |
2101 | 2044 | for (int i = 0; i < vec_gpuMem.size(); i++) { |
2102 | 2045 | DeviceMemory* mem = vec_gpuMem[i]; |
2103 | - if (!task_has_face_algor(mem->getId())){ | |
2046 | + if (!m_task_param_manager->task_has_face_algor(mem->getId())){ | |
2104 | 2047 | continue; |
2105 | 2048 | } |
2106 | 2049 | ... | ... |
src/ai_platform/MultiSourceProcess.h
... | ... | @@ -101,8 +101,6 @@ private: |
101 | 101 | |
102 | 102 | private: |
103 | 103 | // 工具处理函数 |
104 | - bool task_has_vpt_algor(const std::string &task_id); | |
105 | - bool task_has_face_algor(const std::string &task_id); | |
106 | 104 | void clear_finished_task(); |
107 | 105 | bool finish_task(const string taskID, const bool delete_snapshot); |
108 | 106 | int algorithm_vehicle_relult(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result>& vptResult, vector<vector<int>>& delete_object_id); | ... | ... |
src/ai_platform/task_param_manager.cpp
... | ... | @@ -542,3 +542,78 @@ map<string, algor_open_config_param> task_param_manager::get_task_algor_params() |
542 | 542 | map<string, map<algo_type, task_param_manager::algo_param_type_t_ *>> task_param_manager::get_task_other_params() { |
543 | 543 | return m_task_params; |
544 | 544 | } |
545 | + | |
546 | +bool task_param_manager::task_has_vpt_algor(const std::string &task_id) { | |
547 | + auto algor_map = get_task_other_param(task_id); | |
548 | + if (algor_map == nullptr) | |
549 | + return false; | |
550 | + | |
551 | + return (algor_map->find(algorithm_type_t::HUMAN_GATHER) != algor_map->end() || | |
552 | + algor_map->find(algorithm_type_t::HUMAN_SNAPSHOT) != algor_map->end() || | |
553 | + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_SNAPSHOT) != algor_map->end() || | |
554 | + algor_map->find(algorithm_type_t::SMOKING_DET) != algor_map->end() || | |
555 | + algor_map->find(algorithm_type_t::NO_REFLECTIVE_CLOTHING) != algor_map->end() || | |
556 | + algor_map->find(algorithm_type_t::NO_SAFETY_HELMET) != algor_map->end() || | |
557 | + algor_map->find(algorithm_type_t::CALL_PHONE_DET) != algor_map->end() || | |
558 | + algor_map->find(algorithm_type_t::VEHICLE_SNAPSHOT) != algor_map->end() || | |
559 | + algor_map->find(algorithm_type_t::TAKEAWAY_MEMBER_CLASSIFICATION) != algor_map->end() || | |
560 | + algor_map->find(algorithm_type_t::PEDESTRIAN_FALL) != algor_map->end() || | |
561 | + algor_map->find(algorithm_type_t::PEDESTRIAN_FIGHT) != algor_map->end() || | |
562 | + algor_map->find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != algor_map->end() || | |
563 | + algor_map->find(algorithm_type_t::VEHICLE_RETROGRADE) != algor_map->end() || | |
564 | + algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || | |
565 | + algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end() || | |
566 | + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET) != algor_map->end() || | |
567 | + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN) != algor_map->end() || | |
568 | + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE) != algor_map->end() || | |
569 | + algor_map->find(algorithm_type_t::NONMOTOR_VEHICLE_REFIT) != algor_map->end() || | |
570 | + algor_map->find(algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS) != algor_map->end() || | |
571 | + algor_map->find(algorithm_type_t::NONMOTOR_CEOSSPARKLINE) != algor_map->end() || | |
572 | + algor_map->find(algorithm_type_t::NONMOTOR_IN_VEHICLELANE) != algor_map->end() || | |
573 | + algor_map->find(algorithm_type_t::NONMOTOR_WRONGDIRECTION) != algor_map->end() || | |
574 | + algor_map->find(algorithm_type_t::PERSON_IN_VEHICLELANE) != algor_map->end() || | |
575 | + algor_map->find(algorithm_type_t::PERSON_RUNNING_REDLIGHTS) != algor_map->end() || | |
576 | + algor_map->find(algorithm_type_t::PERSON_CROSS) != algor_map->end() || | |
577 | + algor_map->find(algorithm_type_t::VEHICLE_WRONGDIRECTION) != algor_map->end() || | |
578 | + algor_map->find(algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) != algor_map->end() || | |
579 | + algor_map->find(algorithm_type_t::VEHICLE_NOTGIVEWAY) != algor_map->end() || | |
580 | + algor_map->find(algorithm_type_t::VEHICLE_NOTDECELERATION) != algor_map->end() || | |
581 | + algor_map->find(algorithm_type_t::TRICYCLE_MANNED) != algor_map->end() || | |
582 | + algor_map->find(algorithm_type_t::TRUCK_MANNED) != algor_map->end()); | |
583 | +} | |
584 | + | |
585 | +bool task_param_manager::task_has_face_algor(const std::string &task_id) { | |
586 | + auto algor_map = get_task_other_param(task_id); | |
587 | + if (nullptr != algor_map){ | |
588 | + return algor_map->find(algorithm_type_t::FACE_SNAPSHOT) != algor_map->end(); | |
589 | + } | |
590 | + | |
591 | + return false; | |
592 | +} | |
593 | + | |
594 | +int task_param_manager::get_video_timing_snapshot_interval(std::string& task_id) { | |
595 | + auto algor_map = get_task_other_param(task_id); | |
596 | + if (algor_map != nullptr) { | |
597 | + | |
598 | + // 设置定时截图的时间间隔 | |
599 | + auto algor = algor_map->find(algorithm_type_t::VIDEO_TIMING_SNAPSHOT); | |
600 | + if(algor != algor_map->end()){ | |
601 | + task_param_manager::algo_param_type_t_* cur_task_params = algor->second; | |
602 | + if(cur_task_params){ | |
603 | + int frame_stride = ((algor_config_video_timing_snapshot*)cur_task_params->algor_param)->frame_stride; | |
604 | + LOG_INFO("task {} snap time interval: {} s", task_id, frame_stride); | |
605 | + // 单位是ms, 乘以 1000 编成s | |
606 | + return frame_stride * 1000; | |
607 | + } | |
608 | + } | |
609 | + | |
610 | + // 测试代码 | |
611 | + // auto algor_face = algor_map->find(algorithm_type_t::FACE_SNAPSHOT); | |
612 | + // if(algor_face != algor_map->end()){ | |
613 | + // const algor_basic_config_param_t *cur_param = ((algor_init_config_param_t *)(algor_face->second))->basic_param; | |
614 | + // LOG_INFO("face_snapshot, result_folder: {} result_folder_little: {}", cur_param->result_folder, cur_param->result_folder_little); | |
615 | + // } | |
616 | + } | |
617 | + | |
618 | + return -1; | |
619 | +} | |
545 | 620 | \ No newline at end of file | ... | ... |
src/ai_platform/task_param_manager.h
... | ... | @@ -43,6 +43,11 @@ public: |
43 | 43 | map<string, map<algo_type, algo_param_type_t_*>> get_task_other_params(); |
44 | 44 | void task_param_manager_release(); |
45 | 45 | |
46 | + bool task_has_vpt_algor(const std::string &task_id); | |
47 | + bool task_has_face_algor(const std::string &task_id); | |
48 | + | |
49 | + int get_video_timing_snapshot_interval(std::string& task_id); | |
50 | + | |
46 | 51 | private: |
47 | 52 | task_param_manager(); |
48 | 53 | task_param_manager(const task_param_manager& other); | ... | ... |
src/decoder/dvpp/DvppStreamDecoder.cpp
... | ... | @@ -479,6 +479,10 @@ int DvppStreamDecoder::SendData(int videoType, char* data, int len, int isKey, u |
479 | 479 | |
480 | 480 | m_frame_nb++; |
481 | 481 | |
482 | + #ifdef USE_VILLAGE | |
483 | + m_recoderManager.cache_pkt(pkt, m_frame_nb); | |
484 | +#endif | |
485 | + | |
482 | 486 | // dvpp 解码 |
483 | 487 | nSended = sendPkt(vdecChannelDesc, pkt, m_frame_nb, vdec_out_size); |
484 | 488 | } |
... | ... | @@ -568,7 +572,11 @@ int DvppStreamDecoder::parse_stream_info(int videoType, AVPacket* pkt) { |
568 | 572 | av_bsf_init(h264bsfc); |
569 | 573 | } |
570 | 574 | |
571 | - m_fps = av_q2d(avctx->framerate); | |
575 | + if (avctx->framerate.den) { | |
576 | + m_fps = av_q2d(avctx->framerate); | |
577 | + } else { | |
578 | + m_fps = 0.0; | |
579 | + } | |
572 | 580 | |
573 | 581 | AVFrame* frame = av_frame_alloc(); |
574 | 582 | do |
... | ... | @@ -587,6 +595,13 @@ int DvppStreamDecoder::parse_stream_info(int videoType, AVPacket* pkt) { |
587 | 595 | m_vdec_out_size = frame->width * frame->height * 3 / 2; |
588 | 596 | } while (0); |
589 | 597 | |
598 | +#ifdef USE_VILLAGE | |
599 | + bool bRet = m_recoderManager.init2(frame->width, frame->height, m_fps, avctx->bit_rate); | |
600 | + if (!bRet){ | |
601 | + LOG_ERROR("[{}]- m_recoderManager 初始化失败!", m_dec_name); | |
602 | + } | |
603 | +#endif | |
604 | + | |
590 | 605 | av_frame_free(&frame); |
591 | 606 | frame = nullptr; |
592 | 607 | |
... | ... | @@ -629,7 +644,17 @@ void DvppStreamDecoder::Close() { |
629 | 644 | h264bsfc = nullptr; |
630 | 645 | } |
631 | 646 | |
647 | + m_recoderManager.close(); | |
648 | + | |
632 | 649 | if(decode_finished_cbk) { |
633 | 650 | decode_finished_cbk(m_finishedDecArg); |
634 | 651 | } |
652 | +} | |
653 | + | |
654 | +void DvppStreamDecoder::doRecode(RecoderInfo& recoderInfo) { | |
655 | + m_recoderManager.create_recode_task(recoderInfo); | |
656 | +} | |
657 | + | |
658 | +void DvppStreamDecoder::set_mq_callback(mq_callback_t cb) { | |
659 | + m_recoderManager.set_mq_callback(cb); | |
635 | 660 | } |
636 | 661 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/DvppStreamDecoder.h
... | ... | @@ -6,6 +6,8 @@ |
6 | 6 | |
7 | 7 | #include "VpcUtils.h" |
8 | 8 | |
9 | +#include "FFRecoderTaskManager.h" | |
10 | + | |
9 | 11 | using namespace std; |
10 | 12 | |
11 | 13 | class DvppStreamDecoder |
... | ... | @@ -22,6 +24,10 @@ public: |
22 | 24 | |
23 | 25 | DvppDataMemory* GetFrame(); |
24 | 26 | |
27 | + void doRecode(RecoderInfo& recoderInfo); | |
28 | + | |
29 | + void set_mq_callback(mq_callback_t cb); | |
30 | + | |
25 | 31 | public: |
26 | 32 | void doProcessReport(); |
27 | 33 | void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData); |
... | ... | @@ -73,6 +79,8 @@ private: |
73 | 79 | uint64_t m_out_count {0}; |
74 | 80 | |
75 | 81 | bool m_bResize {false}; |
82 | + | |
83 | + FFRecoderTaskManager m_recoderManager; | |
76 | 84 | }; |
77 | 85 | |
78 | 86 | ... | ... |
src/decoder/dvpp/FFRecoder2.cpp
0 → 100644
1 | +// FFRecoder2.cpp | |
2 | +#include "FFRecoder2.h" | |
3 | +#include <tuple> | |
4 | +#include <array> | |
5 | +#include <vector> | |
6 | + | |
7 | +extern "C" { | |
8 | +#include <libavcodec/avcodec.h> | |
9 | +#include <libavformat/avformat.h> | |
10 | +#include <libavutil/opt.h> | |
11 | +#include <libavutil/timestamp.h> | |
12 | +#include <libavutil/imgutils.h> | |
13 | +#include <libswscale/swscale.h> | |
14 | +} | |
15 | + | |
16 | + | |
17 | +FFRecoder2::FFRecoder2() | |
18 | + :width_{}, | |
19 | + height_{}, | |
20 | + y_size_{}, | |
21 | + uv_size_{}, | |
22 | + pts_{}, | |
23 | + codec_ctx_{ nullptr }, | |
24 | + fmt_ctx_{ nullptr }, | |
25 | + out_stream_{ nullptr }, | |
26 | + yuv_frame_{ nullptr } | |
27 | +{ | |
28 | +} | |
29 | + | |
30 | +FFRecoder2::~FFRecoder2() | |
31 | +{ | |
32 | + uninit(); | |
33 | +} | |
34 | + | |
35 | + | |
36 | +bool FFRecoder2::init(int w, int h, int fps, int bit_rate, const char* outfile_name) | |
37 | +{ | |
38 | + uninit(); | |
39 | + | |
40 | + width_ = w; | |
41 | + height_ = h; | |
42 | + y_size_ = w * h; | |
43 | + uv_size_ = y_size_ / 4; | |
44 | + | |
45 | + // [1] 创建解码器 | |
46 | + const AVCodec* encoder = avcodec_find_encoder(AV_CODEC_ID_H264); | |
47 | + if (!encoder) { | |
48 | + fprintf(stderr, "Find encoder AV_CODEC_ID_H264 failed!\n"); | |
49 | + return false; | |
50 | + } | |
51 | + // 获取解码器上下文 | |
52 | + codec_ctx_ = avcodec_alloc_context3(encoder); | |
53 | + if (!codec_ctx_) { | |
54 | + fprintf(stderr, "Alloc context for encoder contx failed!\n"); | |
55 | + return false; | |
56 | + } | |
57 | + // 设置解码器上下文参数 | |
58 | + codec_ctx_->bit_rate = bit_rate; | |
59 | + codec_ctx_->width = width_; | |
60 | + codec_ctx_->height = height_; | |
61 | + codec_ctx_->time_base = AVRational{ 1, fps }; | |
62 | + codec_ctx_->gop_size = 50; | |
63 | + codec_ctx_->max_b_frames = 0; | |
64 | + codec_ctx_->pix_fmt = AV_PIX_FMT_YUV420P; | |
65 | + codec_ctx_->thread_count = 4; | |
66 | + codec_ctx_->qmin = 10; | |
67 | + codec_ctx_->qmax = 51; | |
68 | + codec_ctx_->qcompress = 0.6f; | |
69 | + codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |
70 | + | |
71 | + //av_opt_set(codec_ctx_->priv_data, "preset", "ultrafast", 0); | |
72 | + av_opt_set(codec_ctx_->priv_data, "tune", "zerolatency", 0); | |
73 | + | |
74 | + // 打开解码器 | |
75 | + if (avcodec_open2(codec_ctx_, encoder, nullptr) < 0) { | |
76 | + fprintf(stderr, "Open encoder failed!\n"); | |
77 | + return false; | |
78 | + } | |
79 | + | |
80 | + // [2] 创建输出上下文 | |
81 | + avformat_alloc_output_context2(&fmt_ctx_, nullptr, nullptr, outfile_name); | |
82 | + | |
83 | + // [3] 添加输出视频流 | |
84 | + out_stream_ = avformat_new_stream(fmt_ctx_, nullptr); | |
85 | + out_stream_->id = 0; | |
86 | + out_stream_->codecpar->codec_tag = 0; | |
87 | + avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_); | |
88 | + | |
89 | + av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1); | |
90 | + | |
91 | + // 创建YUV格式帧 | |
92 | + yuv_frame_ = av_frame_alloc(); | |
93 | + yuv_frame_->format = AV_PIX_FMT_YUV420P; | |
94 | + yuv_frame_->width = width_; | |
95 | + yuv_frame_->height = height_; | |
96 | + // 为创建的YUV帧分配内存 | |
97 | + if (av_frame_get_buffer(yuv_frame_, 0) < 0) { | |
98 | + av_frame_free(&yuv_frame_); | |
99 | + yuv_frame_ = nullptr; | |
100 | + fprintf(stderr, "Frame get buffer failed!\n"); | |
101 | + return false; | |
102 | + } | |
103 | + | |
104 | + // [5] 打开输出视频文件并写入视频头信息 | |
105 | + if (avio_open(&fmt_ctx_->pb, outfile_name, AVIO_FLAG_WRITE) < 0) { | |
106 | + fprintf(stderr, "avio_open failed!\n"); | |
107 | + return false; | |
108 | + } | |
109 | + if (avformat_write_header(fmt_ctx_, nullptr) < 0) { | |
110 | + fprintf(stderr, "Write header failed!\n"); | |
111 | + return false; | |
112 | + } | |
113 | + | |
114 | + return true; | |
115 | +} | |
116 | + | |
117 | +void FFRecoder2::uninit() | |
118 | +{ | |
119 | + if (fmt_ctx_) { | |
120 | + av_write_trailer(fmt_ctx_); | |
121 | + avio_close(fmt_ctx_->pb); | |
122 | + avformat_free_context(fmt_ctx_); | |
123 | + fmt_ctx_ = nullptr; | |
124 | + } | |
125 | + | |
126 | + if (codec_ctx_) { | |
127 | + avcodec_close(codec_ctx_); | |
128 | + avcodec_free_context(&codec_ctx_); | |
129 | + codec_ctx_ = nullptr; | |
130 | + } | |
131 | + | |
132 | + if (yuv_frame_) { | |
133 | + av_frame_free(&yuv_frame_); | |
134 | + yuv_frame_ = nullptr; | |
135 | + } | |
136 | + | |
137 | + width_ = 0; | |
138 | + height_ = 0; | |
139 | + y_size_ = 0; | |
140 | + uv_size_ = 0; | |
141 | + pts_ = 0; | |
142 | +} | |
143 | + | |
144 | +bool FFRecoder2::write_image(const uint8_t* bgr) | |
145 | +{ | |
146 | + // 分配YUV格式数据的内存 | |
147 | + thread_local std::vector<uint8_t> yuv_data; | |
148 | + if (yuv_data.size() != y_size_ * 3 / 2) { | |
149 | + yuv_data.resize(y_size_ * 3 / 2); | |
150 | + } | |
151 | + // BGR格式转YUV格式 | |
152 | + bgr_to_yuv420p(bgr, yuv_data.data()); | |
153 | + | |
154 | + return write_yuv(yuv_data.data()); | |
155 | +} | |
156 | + | |
157 | +bool FFRecoder2::write_yuv(const uint8_t* yuv_data) | |
158 | +{ | |
159 | + //拷贝YUV数据到帧,由于帧数据存在内存对齐,故需逐行拷贝 | |
160 | + for (int i = 0; i < height_; i++) { | |
161 | + memcpy(yuv_frame_->data[0] + i * yuv_frame_->linesize[0], yuv_data + width_ * i, width_); | |
162 | + } | |
163 | + const int uv_stride = width_ / 2; | |
164 | + for (int i = 0; i < height_ / 2; i++) { | |
165 | + memcpy(yuv_frame_->data[1] + i * yuv_frame_->linesize[1], yuv_data + y_size_ + uv_stride * i, uv_stride); | |
166 | + memcpy(yuv_frame_->data[2] + i * yuv_frame_->linesize[2], yuv_data + y_size_ + uv_size_ + uv_stride * i, uv_stride); | |
167 | + } | |
168 | + | |
169 | + yuv_frame_->pts = pts_++; | |
170 | + | |
171 | + return write_frame(yuv_frame_); | |
172 | +} | |
173 | + | |
174 | +bool FFRecoder2::write_frame(const AVFrame* frame) | |
175 | +{ | |
176 | + char errbuf[64]{ 0 }; | |
177 | + // 将帧数据发送到编码器 | |
178 | + int ret = avcodec_send_frame(codec_ctx_, frame); | |
179 | + if (ret < 0) { | |
180 | + fprintf(stderr, "Error sending a frame to the encoder: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret)); | |
181 | + return false; | |
182 | + } | |
183 | + | |
184 | + while (true) { | |
185 | + AVPacket pkt{ 0 }; | |
186 | + // 获取编码后的数据 | |
187 | + ret = avcodec_receive_packet(codec_ctx_, &pkt); | |
188 | + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) | |
189 | + return true; | |
190 | + else if (ret < 0) { | |
191 | + fprintf(stderr, "Error encoding a frame: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret)); | |
192 | + return false; | |
193 | + } | |
194 | + // 将pts缩放到输出流的time_base上 | |
195 | + av_packet_rescale_ts(&pkt, codec_ctx_->time_base, out_stream_->time_base); | |
196 | + pkt.stream_index = out_stream_->index; | |
197 | + // 将数据写入到输出流 | |
198 | + ret = av_interleaved_write_frame(fmt_ctx_, &pkt); | |
199 | + av_packet_unref(&pkt); | |
200 | + if (ret < 0) { | |
201 | + fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret)); | |
202 | + return false; | |
203 | + } | |
204 | + } | |
205 | + | |
206 | + return true; | |
207 | +} | |
208 | + | |
209 | +bool FFRecoder2::write_pkt(AVPacket* pkt) { | |
210 | + // 将pts缩放到输出流的time_base上 | |
211 | + av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base); | |
212 | + pkt->stream_index = out_stream_->index; | |
213 | + // 将数据写入到输出流 | |
214 | + int ret = av_interleaved_write_frame(fmt_ctx_, pkt); | |
215 | + | |
216 | + char errbuf[64]{ 0 }; | |
217 | + if (ret < 0) { | |
218 | + fprintf(stderr, "Error while writing output packet: %s\n", av_make_error_string(errbuf, sizeof(errbuf), ret)); | |
219 | + return false; | |
220 | + } | |
221 | + | |
222 | + return true; | |
223 | +} | |
224 | + | |
225 | +bool FFRecoder2::flush() | |
226 | +{ | |
227 | + return write_frame(nullptr); | |
228 | +} | |
229 | + | |
230 | +bool FFRecoder2::bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p) | |
231 | +{ | |
232 | + // 分配转换上下文 | |
233 | + thread_local std::tuple<int,int,int> params{ 0, 0, 0 }; | |
234 | + thread_local std::unique_ptr<SwsContext, decltype(&sws_freeContext)> sws_context{ nullptr, &sws_freeContext }; | |
235 | + | |
236 | + std::tuple<int,int,int> new_params{ width_, height_, av_image_get_linesize(AV_PIX_FMT_YUV420P, width_, 0) }; | |
237 | + if (!sws_context || params != new_params) | |
238 | + { | |
239 | + sws_context.reset(sws_getContext(width_, height_, AV_PIX_FMT_BGR24, width_, height_, | |
240 | + AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr)); | |
241 | + params = new_params; | |
242 | + } | |
243 | + | |
244 | + // 转换格式 | |
245 | + const int stride = std::get<2>(params);//Y平面一行的数据长度 | |
246 | + const int ret = sws_scale(sws_context.get(), | |
247 | + &buf_bgr,/* bgr数据只有一个平面 */ | |
248 | + std::array<int, 1> {width_ * 3}.data(),/* BGR所以图像宽度*3 */ | |
249 | + 0, height_, | |
250 | + std::array<uint8_t* const, 3>{ buf_420p, buf_420p + y_size_, buf_420p + y_size_ + uv_size_ }.data(),/* YUV三个平面的起始地址 */ | |
251 | + std::array<int, 3>{ stride, stride / 2, stride / 2 }.data() | |
252 | + );/* YUV每个平面中一行的宽度 */ | |
253 | + | |
254 | + return ret >= 0; | |
255 | +} | |
256 | + | |
257 | +bool FFRecoder2::close() | |
258 | +{ | |
259 | + flush(); | |
260 | + uninit(); | |
261 | +} | |
0 | 262 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/FFRecoder2.h
0 → 100644
1 | +#pragma once | |
2 | +#include <memory> | |
3 | + | |
4 | +class AVFrame; | |
5 | +class AVStream; | |
6 | +class AVCodecContext; | |
7 | +class AVFormatContext; | |
8 | +class AVPacket; | |
9 | + | |
10 | +class FFRecoder2 | |
11 | +{ | |
12 | +public: | |
13 | + FFRecoder2(); | |
14 | + ~FFRecoder2(); | |
15 | + | |
16 | + bool init(int w, int h, int fps, int bit_rate, const char* outfile_name); | |
17 | + void uninit(); | |
18 | + bool write_image(const uint8_t* bgr); | |
19 | + bool write_yuv(const uint8_t* yuv_data); | |
20 | + bool write_frame(const AVFrame* frame); | |
21 | + bool write_pkt(AVPacket* pkt); | |
22 | + bool flush(); | |
23 | + bool close(); | |
24 | + | |
25 | +private: | |
26 | + bool bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p); | |
27 | + | |
28 | +private: | |
29 | + int width_; | |
30 | + int height_; | |
31 | + int y_size_; | |
32 | + int uv_size_; | |
33 | + int pts_; | |
34 | + AVCodecContext* codec_ctx_; | |
35 | + AVFormatContext* fmt_ctx_; | |
36 | + AVStream* out_stream_; | |
37 | + AVFrame* yuv_frame_; | |
38 | +}; | |
0 | 39 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/FFRecoderTaskManager.cpp
... | ... | @@ -60,6 +60,31 @@ bool FFRecoderTaskManager::init(AVStream* stream, AVCodecContext* avctx){ |
60 | 60 | return true; |
61 | 61 | } |
62 | 62 | |
63 | +bool FFRecoderTaskManager::init2(int w, int h, int fps, int bit_rate) { | |
64 | + m_width = w; | |
65 | + m_height = h; | |
66 | + m_bit_rate = bit_rate; | |
67 | + | |
68 | + if (fps > 1) { | |
69 | + m_fps = fps; | |
70 | + } else { | |
71 | + m_fps = 25; | |
72 | + } | |
73 | + | |
74 | + m_recoder_thread = new std::thread( | |
75 | + [](void* arg) { | |
76 | + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)arg; | |
77 | + if(_this != nullptr) { | |
78 | + _this->recode_thread2(); | |
79 | + }else{ | |
80 | + LOG_ERROR("recode 线程启动失败 !"); | |
81 | + } | |
82 | + return (void*)0; | |
83 | + }, this); | |
84 | + | |
85 | + return true; | |
86 | +} | |
87 | + | |
63 | 88 | static AVPacket* packet_clone(AVPacket* pkt) { |
64 | 89 | AVPacket *new_pkt = av_packet_alloc(); |
65 | 90 | av_init_packet( new_pkt ); |
... | ... | @@ -259,6 +284,102 @@ void FFRecoderTaskManager::recode_thread() { |
259 | 284 | LOG_INFO("recode_thread end."); |
260 | 285 | } |
261 | 286 | |
287 | + | |
288 | +void FFRecoderTaskManager::recode_thread2() { | |
289 | + LOG_INFO("recode_thread2 start..."); | |
290 | + while(true) { | |
291 | + if(m_bExit) { | |
292 | + break; | |
293 | + } | |
294 | + | |
295 | + m_recoderinfo_list_mtx.lock(); | |
296 | + if(m_recoderinfo_list.size() <= 0){ | |
297 | + m_recoderinfo_list_mtx.unlock(); | |
298 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
299 | + continue; | |
300 | + } | |
301 | + | |
302 | + auto it_param = m_recoderinfo_list.begin(); | |
303 | + RecoderInfo recoderinfo = *it_param; | |
304 | + m_recoderinfo_list_mtx.unlock(); | |
305 | + | |
306 | + do | |
307 | + { | |
308 | + auto it_data = getStartIterator(recoderinfo.frame_nb); | |
309 | + if(it_data == m_pkt_list.end()) { | |
310 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
311 | + break; | |
312 | + } | |
313 | + | |
314 | + LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb); | |
315 | + | |
316 | + m_pkt_list_mtx.lock(); | |
317 | + auto it = m_pkt_list.begin(); | |
318 | + while (it != it_data) { | |
319 | + DataPacket* dataPkt = m_pkt_list.front(); | |
320 | + delete dataPkt; | |
321 | + dataPkt = nullptr; | |
322 | + m_pkt_list.pop_front(); | |
323 | + it = m_pkt_list.begin(); | |
324 | + } | |
325 | + m_pkt_list_mtx.unlock(); | |
326 | + | |
327 | + string file_name = recoderinfo.recoderPath; | |
328 | + | |
329 | + FFRecoder2 ffrecoder; | |
330 | + bool bInit = ffrecoder.init(m_width, m_height, m_fps, m_bit_rate, file_name.c_str()); | |
331 | + if (!bInit) { | |
332 | + LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb); | |
333 | + ffrecoder.uninit(); | |
334 | + break; | |
335 | + } | |
336 | + LOG_DEBUG("record start, pkt_list size: {} task_id: {} object_id:{} frame_nb: {}", m_pkt_list.size(), recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb); | |
337 | + | |
338 | + int count = 0; | |
339 | + auto it_save = it_data; | |
340 | + unsigned long long start_frame_nb = (*it_data)->frame_nb; | |
341 | + unsigned long long end_frame_nb = (*it_data)->frame_nb; | |
342 | + for (; it_save != m_pkt_list.end() && count < 500; ++it_save) { | |
343 | + DataPacket* dataPkt = *it_save; | |
344 | + if(dataPkt->frame_nb > recoderinfo.frame_nb) { | |
345 | + break; | |
346 | + } | |
347 | + AVPacket* pkt = dataPkt->pkt; | |
348 | + if(pkt == nullptr) { | |
349 | + LOG_ERROR("{} pkt is nullptr", recoderinfo.task_id); | |
350 | + continue; | |
351 | + } else if (pkt->data == nullptr || pkt->size <= 0){ | |
352 | + LOG_ERROR("{} pkt data is nullptr", recoderinfo.task_id); | |
353 | + continue; | |
354 | + } | |
355 | + | |
356 | + ffrecoder.write_pkt(pkt); | |
357 | + count++; | |
358 | + end_frame_nb = (*it_save)->frame_nb; | |
359 | + } | |
360 | + | |
361 | + ffrecoder.flush(); | |
362 | + ffrecoder.uninit(); | |
363 | + | |
364 | + // 发送mq消息 | |
365 | + if(mq_publish_func && recoderinfo.mq_info.length() > 0) { | |
366 | + mq_publish_func(recoderinfo.mq_info.c_str()); | |
367 | + // LOG_INFO("record save: {}", recoderinfo.mq_info.c_str()); | |
368 | + } | |
369 | + | |
370 | + LOG_INFO("record end, total save: {} start_frame_nb: {} end_frame_nb: {} file_path: {}", count, start_frame_nb, end_frame_nb, file_name); | |
371 | + } while (0); | |
372 | + | |
373 | + // m_recoderinfo_list 为空会触发 m_pkt_list size 大于1000时的删除操作, | |
374 | + // 因此应当在本次m_pkt_list操作都完成之后再pop,避免这边在用m_pkt_list, 另一边在删除,从而导致崩溃 | |
375 | + m_recoderinfo_list_mtx.lock(); | |
376 | + m_recoderinfo_list.pop_front(); | |
377 | + m_recoderinfo_list_mtx.unlock(); | |
378 | + } | |
379 | + | |
380 | + LOG_INFO("recode_thread end."); | |
381 | +} | |
382 | + | |
262 | 383 | void FFRecoderTaskManager::close() { |
263 | 384 | m_bExit = true; |
264 | 385 | ... | ... |
src/decoder/dvpp/FFRecoderTaskManager.h
1 | 1 | #include "FFRecoder.h" |
2 | +#include "FFRecoder2.h" | |
2 | 3 | |
3 | 4 | #include "../../ai_platform/common_header.h" |
4 | 5 | #include "depend_headers.h" |
... | ... | @@ -28,6 +29,7 @@ public: |
28 | 29 | void cache_pkt(AVPacket* pkt, long long frame_nb); |
29 | 30 | |
30 | 31 | bool init(AVStream* stream, AVCodecContext* avctx); |
32 | + bool init2(int w, int h, int fps, int bit_rate); | |
31 | 33 | void create_recode_task(RecoderInfo& recoderInfo); |
32 | 34 | |
33 | 35 | void close(); |
... | ... | @@ -36,6 +38,7 @@ public: |
36 | 38 | |
37 | 39 | public: |
38 | 40 | void recode_thread(); |
41 | + void recode_thread2(); | |
39 | 42 | |
40 | 43 | private: |
41 | 44 | void save_intask_recoderinfo(RecoderInfo info); |
... | ... | @@ -59,4 +62,10 @@ private: |
59 | 62 | thread* m_recoder_thread{nullptr}; |
60 | 63 | |
61 | 64 | mq_callback_t mq_publish_func; |
65 | + | |
66 | + // FFRecoder2 | |
67 | + int m_width; | |
68 | + int m_height; | |
69 | + int m_fps; | |
70 | + int m_bit_rate; | |
62 | 71 | }; |
63 | 72 | \ No newline at end of file | ... | ... |
src/decoder/gb28181/DvppGB28181Decoder.cpp
... | ... | @@ -374,13 +374,30 @@ int DvppGB28181Decoder::getCachedQueueLength(){ |
374 | 374 | } |
375 | 375 | |
376 | 376 | DeviceMemory* DvppGB28181Decoder::snapshot() { |
377 | - return nullptr; | |
377 | + | |
378 | + DeviceMemory* snapshot_mem = nullptr; | |
379 | + int loop_times = 0; | |
380 | + while (isRunning()) { | |
381 | + snapshot_mem = streamDecoder.GetFrame(); | |
382 | + if (snapshot_mem) { | |
383 | + break; | |
384 | + } | |
385 | + | |
386 | + loop_times++; | |
387 | + if(loop_times > 100) { | |
388 | + // 1s都没截取到图,退出 | |
389 | + break; | |
390 | + } | |
391 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); | |
392 | + } | |
393 | + | |
394 | + return snapshot_mem; | |
378 | 395 | } |
379 | 396 | |
380 | 397 | void DvppGB28181Decoder::doRecode(RecoderInfo& recoderInfo) { |
381 | - | |
398 | + return streamDecoder.doRecode(recoderInfo); | |
382 | 399 | } |
383 | 400 | |
384 | 401 | void DvppGB28181Decoder::set_mq_callback(std::function<bool(const char *msg)> mq_publish) { |
385 | - | |
402 | + streamDecoder.set_mq_callback(mq_publish); | |
386 | 403 | } |
387 | 404 | \ No newline at end of file | ... | ... |
src/decoder/test_28181.cpp
... | ... | @@ -142,19 +142,8 @@ int main(){ |
142 | 142 | |
143 | 143 | printf("start... \n"); |
144 | 144 | |
145 | - ServerInfo info( | |
146 | - "SY_Sip_Server", | |
147 | - "12345678", | |
148 | - "192.168.60.179", | |
149 | - 15060, | |
150 | - "34020000002000000002", | |
151 | - "3402000000", | |
152 | - "sy123456", | |
153 | - 1800, | |
154 | - 3600); | |
155 | - | |
156 | 145 | SipServer* pSipServer = SipServer::getInstance(); |
157 | - pSipServer->Init(info); | |
146 | + pSipServer->Init(nullptr); | |
158 | 147 | |
159 | 148 | |
160 | 149 | DecoderManager* pDecManager = DecoderManager::getInstance(); | ... | ... |
src/demo/demo.cpp
... | ... | @@ -1125,7 +1125,7 @@ string createTask_dvpp28181(void *handle, std::vector<algorithm_type_t> algor_ve |
1125 | 1125 | |
1126 | 1126 | algor_init_config_param_t* config_param = tparam.algor_config_params[idx].algor_init_config_param; |
1127 | 1127 | delete config_param; |
1128 | - }else if(tparam.algor_config_params[idx].algor_type == algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) { | |
1128 | + } else if(tparam.algor_config_params[idx].algor_type == algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND) { | |
1129 | 1129 | algor_config_param_manned_incident* algor_param = (algor_config_param_manned_incident*)tparam.algor_config_params[idx].algor_init_config_param->algor_param; |
1130 | 1130 | delete algor_param; |
1131 | 1131 | algor_basic_config_param_t* basic_param = (algor_basic_config_param_t*)tparam.algor_config_params[idx].algor_init_config_param->basic_param; |
... | ... | @@ -1326,13 +1326,13 @@ while (ch != 'q') { |
1326 | 1326 | switch (ch) |
1327 | 1327 | { |
1328 | 1328 | case '0': |
1329 | - createTask_dvpp28181(handle, algor_vec2, 0, false); | |
1329 | + createTask_dvpp28181(handle, algor_vec, 0, false); | |
1330 | 1330 | break; |
1331 | 1331 | case '1': |
1332 | - createTask_dvpp28181(handle, algor_vec2, 1, false); | |
1332 | + createTask_dvpp28181(handle, algor_vec, 1, false); | |
1333 | 1333 | break; |
1334 | 1334 | case '2': |
1335 | - createTask_dvpp28181(handle, algor_vec2, 2, false); | |
1335 | + createTask_dvpp28181(handle, algor_vec, 2, false); | |
1336 | 1336 | break; |
1337 | 1337 | case 'c': |
1338 | 1338 | close_all_task(handle); | ... | ... |