Commit fce4580d65558172deb944f08e65d0640546360c

Authored by Hu Chunming
1 parent b00d3d35

更新最新代码:修改解码器实现方式并修改一些bug;优化代码

src/ai_platform/MultiSourceProcess.cpp
@@ -207,8 +207,7 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ @@ -207,8 +207,7 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
207 } 207 }
208 208
209 AbstractDecoder* dec = pDecManager->createDecoder(config); 209 AbstractDecoder* dec = pDecManager->createDecoder(config);
210 - if (!dec)  
211 - { 210 + if (!dec){
212 return false; 211 return false;
213 } 212 }
214 213
@@ -417,6 +416,10 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna @@ -417,6 +416,10 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
417 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true); 416 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true);
418 #endif 417 #endif
419 418
  419 +#ifdef WITH_SECOND_PROCESS
  420 + pedestrian_vehicle_retrograde_.force_release_result(taskID); //221024 byzsh
  421 +#endif
  422 +
420 m_task_param_manager->delete_task_param(taskID); 423 m_task_param_manager->delete_task_param(taskID);
421 424
422 return true; 425 return true;
@@ -496,6 +499,7 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){ @@ -496,6 +499,7 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){
496 sy_img img; 499 sy_img img;
497 img.w_ = mem->getWidth(); 500 img.w_ = mem->getWidth();
498 img.h_ = mem->getHeight(); 501 img.h_ = mem->getHeight();
  502 + img.c_ = mem->getChannel();
499 img.data_ = mem->getMem(); 503 img.data_ = mem->getMem();
500 vpt_interest_imgs.push_back(img); 504 vpt_interest_imgs.push_back(img);
501 vpt_interest_task_id.push_back(mem->getId()); 505 vpt_interest_task_id.push_back(mem->getId());
@@ -517,7 +521,6 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){ @@ -517,7 +521,6 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){
517 #ifndef VEHICLE_MULTI_BOXES 521 #ifndef VEHICLE_MULTI_BOXES
518 /* 快照优选(内部可实现不同的快照优选策略) */ 522 /* 快照优选(内部可实现不同的快照优选策略) */
519 m_snapshot_reprocessing->update_bestsnapshot(vec_vptMem, vptResult, deleteObjectID); 523 m_snapshot_reprocessing->update_bestsnapshot(vec_vptMem, vptResult, deleteObjectID);
520 -  
521 /* for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)*/ 524 /* for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)*/
522 vehicle_snapshot(vpt_interest_task_id, deleteObjectID); 525 vehicle_snapshot(vpt_interest_task_id, deleteObjectID);
523 #else 526 #else
@@ -530,8 +533,12 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){ @@ -530,8 +533,12 @@ int CMultiSourceProcess::algorthim_vpt(vector<DeviceMemory*> vec_gpuMem){
530 /* for pedestrian safety det. 行人安全分析算法模块 */ 533 /* for pedestrian safety det. 行人安全分析算法模块 */
531 // algorthim_pedestrian_safety(vpt_interest_task_id, vpt_interest_imgs,vptResult); 534 // algorthim_pedestrian_safety(vpt_interest_task_id, vpt_interest_imgs,vptResult);
532 535
533 - /* for retrograde & trespass algor 逆行&非法闯入算法模块 */  
534 - algorthim_retrograde_trespass(vpt_interest_task_id, vec_vptMem, vptResult, deleteObjectID); 536 + // 逆行
  537 + algorthim_retrograde(vpt_interest_task_id, vec_vptMem, vptResult);
  538 + retrograde_snapshot(vpt_interest_task_id, deleteObjectID);
  539 + // 闯入
  540 + algorthim_trespass(vpt_interest_task_id, vec_vptMem, vptResult, deleteObjectID);
  541 + trespass_snapshot(vpt_interest_task_id, deleteObjectID);
535 542
536 // #endif 543 // #endif
537 544
@@ -662,21 +669,12 @@ void CMultiSourceProcess::vehicle_snapshot(vector<string>& vpt_interest_task_id, @@ -662,21 +669,12 @@ void CMultiSourceProcess::vehicle_snapshot(vector<string>& vpt_interest_task_id,
662 for (int &j : deleteObjectID[i]) // loop algor type. 669 for (int &j : deleteObjectID[i]) // loop algor type.
663 { 670 {
664 OBJ_KEY obj_key = {*task_iter, j}; 671 OBJ_KEY obj_key = {*task_iter, j};
665 - endframe_obj_process(obj_key, algorithm_type_t::PLACEHOLDER); 672 + // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源
  673 + vehicle_locus_finished(obj_key);
666 } 674 }
667 } 675 }
668 } 676 }
669 677
670 -/* 轨迹结束帧需要做的算法模块 */  
671 -int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type) {  
672 -  
673 - // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源  
674 - vehicle_locus_finished(obj_key);  
675 -  
676 - /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */  
677 - endframe_retrograde_trespass(obj_key);  
678 -}  
679 -  
680 void CMultiSourceProcess::vehicle_locus_finished(const OBJ_KEY obj_key) { 678 void CMultiSourceProcess::vehicle_locus_finished(const OBJ_KEY obj_key) {
681 auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id); 679 auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id);
682 auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id); 680 auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id);
@@ -809,16 +807,12 @@ void CMultiSourceProcess::timing_snapshot_thread(){ @@ -809,16 +807,12 @@ void CMultiSourceProcess::timing_snapshot_thread(){
809 LOG_INFO("timing_snapshot_thread end."); 807 LOG_INFO("timing_snapshot_thread end.");
810 } 808 }
811 809
812 -void CMultiSourceProcess::algorthim_retrograde_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs,  
813 - vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID){ 810 +// 逆行
  811 +void CMultiSourceProcess::algorthim_retrograde(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs,
  812 + vector<onelevel_det_result>& vptResult){
814 vector<string> interest_task_id; 813 vector<string> interest_task_id;
815 vector<onelevel_det_result> interest_vpt_result; 814 vector<onelevel_det_result> interest_vpt_result;
816 - vector<DeviceMemory*> interest_imgs;  
817 -  
818 - vector<string> trespass_interest_task_id;  
819 - vector<onelevel_det_result> trespass_interest_vpt_result;  
820 - vector<vector<int>> trespass_interest_deleteobjs;  
821 - vector<DeviceMemory*> trespass_interest_imgs; 815 + vector<DeviceMemory*> interest_imgs;
822 816
823 int _idx = 0; 817 int _idx = 0;
824 for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end(); 818 for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end();
@@ -833,6 +827,30 @@ void CMultiSourceProcess::algorthim_retrograde_trespass(vector&lt;string&gt;&amp; vpt_inte @@ -833,6 +827,30 @@ void CMultiSourceProcess::algorthim_retrograde_trespass(vector&lt;string&gt;&amp; vpt_inte
833 interest_imgs.emplace_back(vpt_interest_imgs[_idx]); 827 interest_imgs.emplace_back(vpt_interest_imgs[_idx]);
834 interest_vpt_result.emplace_back(vptResult[_idx]); 828 interest_vpt_result.emplace_back(vptResult[_idx]);
835 } 829 }
  830 + }
  831 +
  832 + LOG_DEBUG("retrograde interest_vpt_result size: {}", interest_vpt_result.size());
  833 +
  834 + if (!interest_imgs.empty()){
  835 + pedestrian_vehicle_retrograde_.update_mstreams(interest_task_id, interest_imgs, interest_vpt_result);
  836 + }
  837 +}
  838 +
  839 +// 闯入
  840 +void CMultiSourceProcess::algorthim_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs,
  841 + vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID){
  842 +
  843 + vector<string> trespass_interest_task_id;
  844 + vector<onelevel_det_result> trespass_interest_vpt_result;
  845 + vector<vector<int>> trespass_interest_deleteobjs;
  846 + vector<DeviceMemory*> trespass_interest_imgs;
  847 +
  848 + int _idx = 0;
  849 + for (auto _task_id_iter = vpt_interest_task_id.begin(); _task_id_iter != vpt_interest_task_id.end();
  850 + ++_task_id_iter, ++_idx) // loop task_id;
  851 + {
  852 + auto task_id = *_task_id_iter;
  853 + auto algor_map = m_task_param_manager->get_task_other_param(task_id);
836 854
837 if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() || 855 if (algor_map->find(algorithm_type_t::PEDESTRIAN_TRESPASS) != algor_map->end() ||
838 algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) { 856 algor_map->find(algorithm_type_t::VEHICLE_TRESPASS) != algor_map->end()) {
@@ -843,36 +861,58 @@ void CMultiSourceProcess::algorthim_retrograde_trespass(vector&lt;string&gt;&amp; vpt_inte @@ -843,36 +861,58 @@ void CMultiSourceProcess::algorthim_retrograde_trespass(vector&lt;string&gt;&amp; vpt_inte
843 } 861 }
844 } 862 }
845 863
846 - LOG_DEBUG("trespass_interest_vpt_result size: {}", trespass_interest_vpt_result.size());  
847 -  
848 - if (!interest_imgs.empty())  
849 - pedestrian_vehicle_retrograde_.update_mstreams(interest_task_id, interest_imgs,  
850 - interest_vpt_result); 864 + LOG_DEBUG("trespass interest_vpt_result size: {}", trespass_interest_vpt_result.size());
851 865
852 if (!trespass_interest_imgs.empty()) { 866 if (!trespass_interest_imgs.empty()) {
853 - pedestrian_vehicle_trespass_.update_mstreams(  
854 - trespass_interest_task_id, trespass_interest_imgs, trespass_interest_vpt_result,  
855 - trespass_interest_deleteobjs); 867 + pedestrian_vehicle_trespass_.update_mstreams( trespass_interest_task_id, trespass_interest_imgs,
  868 + trespass_interest_vpt_result, trespass_interest_deleteobjs);
856 } 869 }
857 } 870 }
858 871
859 -int CMultiSourceProcess::endframe_retrograde_trespass(const OBJ_KEY &obj_key) {  
860 - auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id);  
861 872
862 - /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */  
863 - if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_RETROGRADE) !=  
864 - task_param_ptr->human_algors.end())  
865 - retrograde_trespass_alarm(obj_key, algorithm_type_t::PEDESTRIAN_RETROGRADE); 873 +// for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)
  874 +void CMultiSourceProcess::retrograde_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID) {
  875 + auto task_iter = vpt_interest_task_id.begin();
  876 +
  877 + for (int i = 0; i < deleteObjectID.size(); i++, ++task_iter) // loop taskId.
  878 + {
  879 + for (int &j : deleteObjectID[i]) // loop algor type.
  880 + {
  881 + OBJ_KEY obj_key = {*task_iter, j};
  882 + auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id);
  883 +
  884 + /* 开启行人&机动车逆行算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */
  885 + if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_RETROGRADE) != task_param_ptr->human_algors.end()){
  886 + retrograde_trespass_alarm(obj_key, algorithm_type_t::PEDESTRIAN_RETROGRADE);
  887 + }
  888 +
  889 + if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_RETROGRADE) != task_param_ptr->vehicle_algors.end()){
  890 + retrograde_trespass_alarm(obj_key, algorithm_type_t::VEHICLE_RETROGRADE);
  891 + }
  892 + }
  893 + }
  894 +}
866 895
867 - if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_RETROGRADE) !=  
868 - task_param_ptr->vehicle_algors.end())  
869 - retrograde_trespass_alarm(obj_key, algorithm_type_t::VEHICLE_RETROGRADE); 896 +// for snapshot algorithm. 轨迹结束目标 做最后的结果返回(当前返回算法结果+快照保存路径)
  897 +void CMultiSourceProcess::trespass_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID) {
  898 + auto task_iter = vpt_interest_task_id.begin();
870 899
871 - if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_TRESPASS) != task_param_ptr->human_algors.end())  
872 - retrograde_trespass_alarm(obj_key, algorithm_type_t::PEDESTRIAN_TRESPASS); 900 + for (int i = 0; i < deleteObjectID.size(); i++, ++task_iter) // loop taskId.
  901 + {
  902 + for (int &j : deleteObjectID[i]) // loop algor type.
  903 + {
  904 + OBJ_KEY obj_key = {*task_iter, j};
  905 + auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id);
873 906
874 - if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_TRESPASS) != task_param_ptr->vehicle_algors.end())  
875 - retrograde_trespass_alarm(obj_key, algorithm_type_t::VEHICLE_TRESPASS); 907 + if (task_param_ptr->human_algors.find(algorithm_type_t::PEDESTRIAN_TRESPASS) != task_param_ptr->human_algors.end()){
  908 + retrograde_trespass_alarm(obj_key, algorithm_type_t::PEDESTRIAN_TRESPASS);
  909 + }
  910 +
  911 + if (task_param_ptr->vehicle_algors.find(algorithm_type_t::VEHICLE_TRESPASS) != task_param_ptr->vehicle_algors.end()){
  912 + retrograde_trespass_alarm(obj_key, algorithm_type_t::VEHICLE_TRESPASS);
  913 + }
  914 + }
  915 + }
876 } 916 }
877 917
878 void CMultiSourceProcess::retrograde_trespass_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) { 918 void CMultiSourceProcess::retrograde_trespass_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) {
@@ -946,7 +986,6 @@ bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &amp;obj_key, const al @@ -946,7 +986,6 @@ bool CMultiSourceProcess::save_snapshot_process(const OBJ_KEY &amp;obj_key, const al
946 obj_save_info.json_str = json_str; 986 obj_save_info.json_str = json_str;
947 m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(obj_save_info); 987 m_save_snapshot_reprocessing->reprocessing_process_wo_locus_async(obj_save_info);
948 } 988 }
949 -  
950 989
951 return true; 990 return true;
952 } 991 }
953 \ No newline at end of file 992 \ No newline at end of file
src/ai_platform/MultiSourceProcess.h
@@ -49,9 +49,11 @@ public: @@ -49,9 +49,11 @@ public:
49 private: 49 private:
50 // 算法相关 50 // 算法相关
51 int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem); 51 int algorthim_vpt(vector<DeviceMemory*> vec_gpuMem);
52 - // 逆行&非法闯入算法模块  
53 - void algorthim_retrograde_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs,  
54 - vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID); 52 + // 逆行
  53 + void algorthim_retrograde(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs, vector<onelevel_det_result>& vptResult);
  54 + // 闯入
  55 + void algorthim_trespass(vector<string>& vpt_interest_task_id, vector<DeviceMemory*> vpt_interest_imgs,
  56 + vector<onelevel_det_result>& vptResult ,vector<vector<int>>& deleteObjectID);
55 57
56 private: 58 private:
57 // 工具处理函数 59 // 工具处理函数
@@ -63,12 +65,11 @@ private: @@ -63,12 +65,11 @@ private:
63 void vehicle_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID); 65 void vehicle_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID);
64 void vehicle_locus_finished(const OBJ_KEY obj_key); 66 void vehicle_locus_finished(const OBJ_KEY obj_key);
65 67
66 - int endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type);  
67 -  
68 bool save_snapshot_process(const OBJ_KEY &obj_key, const algorithm_type_t &algorithm_type, vpc_img_info img_info, vpc_img_info roi_img, 68 bool save_snapshot_process(const OBJ_KEY &obj_key, const algorithm_type_t &algorithm_type, vpc_img_info img_info, vpc_img_info roi_img,
69 const long long id,const std::string &json_str); 69 const long long id,const std::string &json_str);
70 70
71 - int endframe_retrograde_trespass(const OBJ_KEY &obj_key); 71 + void retrograde_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID);
  72 + void trespass_snapshot(vector<string>& vpt_interest_task_id, vector<vector<int>> deleteObjectID);
72 void retrograde_trespass_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) ; 73 void retrograde_trespass_alarm(const OBJ_KEY &obj_key, const algorithm_type_t &algor_type) ;
73 74
74 private: 75 private:
src/decoder/dvpp/DvppDec.cpp deleted
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 - m_cached_mem = nullptr;  
23 - }  
24 -  
25 - DvppDec::~DvppDec(){  
26 - releaseResource();  
27 - }  
28 -  
29 - bool DvppDec::init_vdpp(DvppDecConfig cfg){  
30 -  
31 - m_dec_name = cfg.dec_name;  
32 -  
33 - LOG_INFO("[{}]- Init device start...", m_dec_name);  
34 -  
35 - m_dvpp_deviceId = atoi(cfg.dev_id.c_str());  
36 -  
37 - if(cfg.codec_id == 0){  
38 - // 66:Baseline,77:Main,>=100:High  
39 - if(cfg.profile == 77){  
40 - enType = H264_MAIN_LEVEL;  
41 - }else if(cfg.profile < 77){  
42 - enType = H264_BASELINE_LEVEL;  
43 - }else{  
44 - enType = H264_HIGH_LEVEL;  
45 - }  
46 - }else if(cfg.codec_id == 1){  
47 - // h265只有main  
48 - enType = H265_MAIN_LEVEL;  
49 - }else {  
50 - LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);  
51 - return false;  
52 - }  
53 -  
54 - post_decoded_cbk = cfg.post_decoded_cbk;  
55 - m_pktQueueptr = cfg.pktQueueptr;  
56 -  
57 - // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize  
58 - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();  
59 - m_context = pSrcMgr->getContext(m_dvpp_deviceId);  
60 - m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);  
61 - if(m_dvpp_channel < 0){  
62 - LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);  
63 - return false;  
64 - }  
65 -  
66 - do  
67 - {  
68 - CHECK_AND_BREAK(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed !");  
69 -  
70 - int ret = 0;  
71 - // int ret = picConverter.init(m_context, m_dec_name);  
72 - // if(ret != ACL_ERROR_NONE){  
73 - // LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);  
74 - // break;  
75 - // }  
76 -  
77 - // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死  
78 - for (size_t i = 0; i < 20; i++){  
79 - void *vdecInputbuf = nullptr;  
80 - ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);  
81 - if(ret != ACL_ERROR_NONE){  
82 - LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);  
83 - // 析构函数中有对channel 的补救性释放,所以这里可以直接return  
84 - return false;;  
85 - }  
86 - m_vec_vdec.push_back(vdecInputbuf);  
87 - }  
88 -  
89 - if(!m_vdecQueue.init(m_vec_vdec)){  
90 - break;  
91 - }  
92 -  
93 - m_vdec_out_size = cfg.width * cfg.height * 3 / 2;  
94 -  
95 - LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);  
96 - return true;  
97 -  
98 - } while (0);  
99 -  
100 - LOG_INFO("[{}]- init vdpp failed!", m_dec_name);  
101 - // 初始化失败,释放channel  
102 - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);  
103 - return false;  
104 -}  
105 -  
106 -bool DvppDec::start(){  
107 - m_bRunning = true;  
108 -  
109 - pthread_create(&m_decode_thread,0,  
110 - [](void* arg)  
111 - {  
112 - DvppDec* a=(DvppDec*)arg;  
113 - a->decode_thread();  
114 - return (void*)0;  
115 - }  
116 - ,this);  
117 -  
118 - return true;  
119 -}  
120 -  
121 -static void *ReportThd(void *arg)  
122 -{  
123 - DvppDec *self = (DvppDec *)arg;  
124 - if(nullptr != self){  
125 - self->doProcessReport();  
126 - }  
127 - return (void *)0;  
128 -}  
129 -  
130 -void DvppDec::doProcessReport(){  
131 -  
132 - aclError ret = aclrtSetDevice(m_dvpp_deviceId);  
133 - if(ret != ACL_ERROR_NONE){  
134 - // cout << "aclrtSetDevice failed" << endl;  
135 - LOG_ERROR("aclrtSetDevice failed !");  
136 - return ;  
137 - }  
138 -  
139 - aclrtContext ctx;  
140 - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);  
141 - if (ret != ACL_ERROR_NONE) {  
142 - // cout << "aclrtCreateContext failed " << endl;  
143 - LOG_ERROR("aclrtCreateContext failed !");  
144 - return ;  
145 - }  
146 -  
147 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");  
148 - // 阻塞等待vdec线程开始  
149 -  
150 - while (!m_bExitReportThd) {  
151 - aclrtProcessReport(1000);  
152 - }  
153 -  
154 - ret = aclrtDestroyContext(ctx);  
155 - if(ret != ACL_ERROR_NONE){  
156 - LOG_ERROR("aclrtDestroyContext failed !");  
157 - }  
158 - LOG_INFO("doProcessReport exit.");  
159 -}  
160 -  
161 -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)  
162 -{  
163 - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;  
164 - if(nullptr != userData){  
165 - DvppDec* self = userData->self;  
166 - if(self != nullptr){  
167 -  
168 - self->doVdppVdecCallBack(input, output);  
169 - }  
170 - delete userData;  
171 - userData = nullptr;  
172 - }  
173 -}  
174 -  
175 -void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){  
176 -  
177 - // dvpp_crop(output);  
178 -  
179 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");  
180 -  
181 - void *inputDataDev = acldvppGetStreamDescData(input);  
182 - void *outputDataDev = acldvppGetPicDescData(output);  
183 - uint32_t outputSize = acldvppGetPicDescSize(output);  
184 - uint32_t width = acldvppGetPicDescWidth(output);  
185 - uint32_t width_stride = acldvppGetPicDescWidthStride(output);  
186 - uint32_t height = acldvppGetPicDescHeight(output);  
187 - uint32_t height_stride = acldvppGetPicDescHeightStride(output);  
188 -  
189 -  
190 - DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, (unsigned char *)outputDataDev);  
191 - post_decoded_cbk(m_postDecArg, mem);  
192 -  
193 - if(m_bSnapShoting){  
194 - // 缓存snapshot  
195 - std::unique_lock<std::mutex> locker(m_cached_mutex);  
196 -  
197 - m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false);  
198 - if(m_cached_mem != nullptr){  
199 - aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE);  
200 - }  
201 -  
202 - locker.unlock();  
203 - m_cached_cond.notify_one();  
204 - m_bSnapShoting = false;  
205 - }  
206 -  
207 -  
208 -  
209 -  
210 -// DvppDataMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);  
211 -// if(rgbMem != nullptr){  
212 -// #ifdef TEST_DECODER  
213 -// // D2H  
214 -// if(vdecHostAddr == nullptr){  
215 -// CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");  
216 -// }  
217 -// uint32_t data_size = rgbMem->getSize();  
218 -// CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");  
219 -  
220 -// // 保存vdec结果  
221 -// if(count_frame > 45 && count_frame < 50)  
222 -// {  
223 -// string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;  
224 -// FILE *outputFile = fopen(file_name.c_str(), "a");  
225 -// if(outputFile){  
226 -// fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);  
227 -// fclose(outputFile);  
228 -// }  
229 -// }  
230 -// else if(count_frame > 50 && vdecHostAddr != nullptr){  
231 -// CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");  
232 -// vdecHostAddr = nullptr;  
233 -// }  
234 -// count_frame++;  
235 -// #endif  
236 -// post_decoded_cbk(m_postDecArg, rgbMem);  
237 -// }else{  
238 -// LOG_ERROR("[{}]- convert2bgr failed !", m_dec_name);  
239 -// }  
240 -  
241 - // // 测试  
242 - // acldvppFree(outputDataDev);  
243 - // outputDataDev = nullptr;  
244 -  
245 - m_vdecQueue.addHead();  
246 -  
247 - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");  
248 - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");  
249 -}  
250 -  
251 -void DvppDec::close(){  
252 - m_bRunning=false;  
253 -  
254 - if(m_decode_thread != 0){  
255 - pthread_join(m_decode_thread,0);  
256 - }  
257 -}  
258 -  
259 -bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){  
260 - // create stream desc  
261 - acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();  
262 - if (streamInputDesc == nullptr) {  
263 - LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);  
264 - return false;  
265 - }  
266 - aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);  
267 - if (ret != ACL_SUCCESS) {  
268 - LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));  
269 - (void)acldvppDestroyStreamDesc(streamInputDesc);  
270 - return false;  
271 - }  
272 -  
273 - // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.  
274 - LOG_INFO("[{}]- send eos", m_dec_name);  
275 - ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);  
276 - (void)acldvppDestroyStreamDesc(streamInputDesc);  
277 - if (ret != ACL_SUCCESS) {  
278 - LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);  
279 - return false;  
280 - }  
281 -  
282 - return true;  
283 -}  
284 -  
285 -void DvppDec::releaseResource(){  
286 - for(int i = 0; i < m_vec_vdec.size(); i++){  
287 - if(m_vec_vdec[i] != nullptr){  
288 - acldvppFree(m_vec_vdec[i]);  
289 - m_vec_vdec[i] = nullptr;  
290 - }  
291 - }  
292 - m_vec_vdec.clear();  
293 -  
294 - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();  
295 - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);  
296 -}  
297 -  
298 -void DvppDec::decode_thread(){  
299 -  
300 - long startTime = UtilTools::get_cur_time_ms();  
301 -  
302 - int ret = -1;  
303 -  
304 - // // dvpp解码参数  
305 - // CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");  
306 -  
307 - m_bExitReportThd = false;  
308 - pthread_t report_thread;  
309 - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);  
310 - if(ret != 0){  
311 - LOG_ERROR("[{}]- pthread_create failed", m_dec_name);  
312 - return;  
313 - }  
314 -  
315 - aclrtSetDevice(m_dvpp_deviceId);  
316 - aclrtContext ctx;  
317 - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);  
318 - if (ret != ACL_ERROR_NONE) {  
319 - // cout << "aclrtCreateContext failed " << endl;  
320 - LOG_ERROR("aclrtCreateContext failed !");  
321 - return ;  
322 - }  
323 -  
324 - // 创建aclvdecChannelDesc类型的数据  
325 - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();  
326 - if (vdecChannelDesc == nullptr) {  
327 - LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);  
328 - return;  
329 - }  
330 - do{  
331 - // 创建 channel dec结构体  
332 - // 通道ID在dvpp层面为0~31  
333 - CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");  
334 - CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");  
335 - CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");  
336 - CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");  
337 - CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");  
338 - CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");  
339 -  
340 - uint64_t frame_count = 0;  
341 - bool bBreak = false;  
342 - while (m_bRunning)  
343 - {  
344 - if (m_bPause){  
345 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
346 - continue;  
347 - }  
348 - int ret = sentFrame(vdecChannelDesc, frame_count);  
349 - if(ret == 2){  
350 - break;  
351 - bBreak = true;  
352 - }else if(ret == 1){  
353 - continue;  
354 - }  
355 -  
356 - frame_count++;  
357 - }  
358 -  
359 - // 尽量保证数据全部解码完成  
360 - int sum = 0;  
361 - if(!bBreak){  
362 - aclrtSetDevice(m_dvpp_deviceId);  
363 - aclrtSetCurrentContext(ctx);  
364 - while(!m_pktQueueptr->isEmpty()){  
365 - int ret = sentFrame(vdecChannelDesc, frame_count);  
366 - if(ret == 2){  
367 - break;  
368 - }  
369 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
370 - sum++;  
371 - if(sum > 40){  
372 - // 避免卡死  
373 - break;  
374 - }  
375 - }  
376 - }  
377 -  
378 - sendVdecEos(vdecChannelDesc);  
379 -  
380 - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");  
381 - }while(0);  
382 -  
383 - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");  
384 -  
385 - // report_thread 需后于destroy退出  
386 - m_bRunning = false;  
387 - m_bExitReportThd = true;  
388 - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");  
389 -  
390 - releaseResource();  
391 - LOG_INFO("[{}]- decode thread exit.", m_dec_name);  
392 -}  
393 -  
394 -int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){  
395 -  
396 - AVPacket * pkt = m_pktQueueptr->getHead();  
397 - if(pkt == nullptr){  
398 - std::this_thread::sleep_for(std::chrono::milliseconds(10));  
399 - return 1;  
400 - }  
401 - // 解码  
402 - void *vdecInputbuf = m_vdecQueue.getTail();  
403 - if(vdecInputbuf == nullptr){  
404 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
405 - return 1;  
406 - }  
407 -  
408 - int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);  
409 - if(ACL_ERROR_NONE != ret){  
410 - LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);  
411 - return 2;  
412 - }  
413 -  
414 - void *vdecOutputBuf = nullptr;  
415 - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);  
416 - if(ret != ACL_ERROR_NONE){  
417 - LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);  
418 - return 2;  
419 - }  
420 -  
421 - acldvppStreamDesc *input_stream_desc = nullptr;  
422 - acldvppPicDesc *output_pic_desc = nullptr;  
423 - do{  
424 - input_stream_desc = acldvppCreateStreamDesc();  
425 - if (input_stream_desc == nullptr) {  
426 - LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);  
427 - break;  
428 - }  
429 - output_pic_desc = acldvppCreatePicDesc();  
430 - if (output_pic_desc == nullptr) {  
431 - LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);  
432 - break;  
433 - }  
434 - CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");  
435 - CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");  
436 - CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");  
437 - CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");  
438 -  
439 - Vdec_CallBack_UserData *user_data = NULL;  
440 - user_data = new Vdec_CallBack_UserData;  
441 - user_data->frameId = frame_count;  
442 - // user_data->startTime = startTime;  
443 - user_data->sendTime = UtilTools::get_cur_time_ms();  
444 - user_data->self = this;  
445 - ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));  
446 - av_packet_unref(pkt);  
447 - m_pktQueueptr->addHead();  
448 - if(ret != ACL_ERROR_NONE){  
449 - delete user_data;  
450 - user_data = nullptr;  
451 - LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);  
452 - break;  
453 - }  
454 -  
455 - m_vdecQueue.addTail();  
456 -  
457 - return 0;  
458 - }while (0);  
459 -  
460 - // 报错情形  
461 - if(input_stream_desc){  
462 - CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");  
463 - }  
464 - if(output_pic_desc){  
465 - CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");  
466 - }  
467 -  
468 - if (vdecOutputBuf){  
469 - acldvppFree(vdecOutputBuf);  
470 - vdecOutputBuf = nullptr;  
471 - }  
472 -  
473 - return 1;  
474 -}  
475 -  
476 -  
477 -void DvppDec::setPostDecArg(const void* postDecArg){  
478 - m_postDecArg = postDecArg;  
479 -}  
480 -  
481 -void DvppDec::pause(){  
482 - m_bPause = true;  
483 -}  
484 -  
485 -void DvppDec::resume(){  
486 - m_bPause = false;  
487 -}  
488 -  
489 -DeviceMemory* DvppDec::snapshot(){  
490 - // 开始抓拍  
491 - m_bSnapShoting = true;  
492 -  
493 - std::unique_lock<std::mutex> locker(m_cached_mutex);  
494 - while (m_cached_mem == nullptr)  
495 - m_cached_cond.wait(locker); // Unlock mutex and wait to be notified  
496 - locker.unlock();  
497 -  
498 - DeviceMemory* mem = m_cached_mem;  
499 - m_cached_mem = nullptr;  
500 -  
501 - return mem;  
502 -}  
503 \ No newline at end of file 0 \ No newline at end of file
src/decoder/dvpp/DvppDec.h deleted
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 -#include <mutex>  
13 -#include <condition_variable>  
14 -  
15 -using namespace std;  
16 -  
17 -// #define TEST_DECODER  
18 -  
19 -struct DvppDecConfig{  
20 - string dec_name;  
21 - POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口  
22 - string dev_id; // gpu id  
23 - bool force_tcp{true}; // 是否指定使用tcp连接  
24 - int skip_frame{1}; // 跳帧数  
25 - int codec_id; // 0 : h264 1:h265  
26 - int profile;  
27 - CircularQueue<AVPacket*> *pktQueueptr;  
28 -  
29 - int width;  
30 - int height;  
31 -};  
32 -  
33 -  
34 -class DvppDec {  
35 -public:  
36 - DvppDec();  
37 - ~DvppDec();  
38 - bool init_vdpp(DvppDecConfig cfg);  
39 - void setPostDecArg(const void* postDecArg);  
40 - bool start();  
41 - void close();  
42 - void pause();  
43 - void resume();  
44 - DeviceMemory* snapshot();  
45 -  
46 -public:  
47 - void doProcessReport();  
48 - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output);  
49 -  
50 -private:  
51 - void decode_thread();  
52 - void releaseResource();  
53 - bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);  
54 - int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count);  
55 -  
56 -private:  
57 -  
58 - bool m_bRunning{false};  
59 - bool m_bPause{false};  
60 - bool m_bExitReportThd{false};  
61 -  
62 - int m_dvpp_deviceId {-1};  
63 - int m_dvpp_channel {-1};  
64 - aclrtContext m_context;  
65 - acldvppStreamFormat enType;  
66 -  
67 - pthread_t m_decode_thread;  
68 -  
69 - DvppDecConfig m_cfg;  
70 - string m_dec_name;  
71 -  
72 - vector<void*> m_vec_vdec;  
73 - CircularQueue<void *> m_vdecQueue;  
74 - CircularQueue<AVPacket *> *m_pktQueueptr;  
75 -  
76 - const void * m_postDecArg;  
77 - POST_DECODE_CALLBACK post_decoded_cbk;  
78 -  
79 - VpcPicConverter picConverter;  
80 -  
81 - int m_vdec_out_size {-1};  
82 -  
83 - bool m_bSnapShoting{false};  
84 - DvppDataMemory* m_cached_mem;  
85 - mutex m_cached_mutex;  
86 - condition_variable m_cached_cond;  
87 -  
88 -#ifdef TEST_DECODER  
89 - void *vdecHostAddr = nullptr;  
90 - int count_frame = 0;  
91 -#endif  
92 -  
93 -};  
94 \ No newline at end of file 0 \ No newline at end of file
src/decoder/dvpp/DvppDecoder.cpp
1 #include "DvppDecoder.h" 1 #include "DvppDecoder.h"
  2 +#include "DvppSourceManager.h"
2 3
3 -void receiver_finish_cbk(const void* userPtr){  
4 - if(userPtr != nullptr){  
5 - DvppDecoder* self = (DvppDecoder*)userPtr;  
6 - self->taskFinishing(); 4 +
  5 +struct Vdec_CallBack_UserData {
  6 + uint64_t frameId;
  7 + long startTime;
  8 + long sendTime;
  9 + // void* vdecOutputBuf;
  10 + DvppDecoder* self;
  11 + Vdec_CallBack_UserData() {
  12 + frameId = 0;
7 } 13 }
8 -} 14 +};
9 15
10 DvppDecoder::DvppDecoder(){ 16 DvppDecoder::DvppDecoder(){
11 - m_pktQueueptr = new CircularQueue<AVPacket *>(); 17 + m_read_thread = 0;
  18 + m_decode_thread = 0;
  19 + m_cached_mem = nullptr;
  20 +
  21 + fmt_ctx = nullptr;
  22 + m_bRunning = false;
  23 +
  24 + stream = nullptr;
  25 + video_index = -1;
  26 + pix_fmt = AV_PIX_FMT_NONE;
  27 + m_dec_name = "";
  28 +
  29 + m_bPause = false;
  30 + m_bReal = true;
  31 +
  32 + m_bFinished = false;
  33 + m_dec_keyframe = false;
  34 + m_fps = 0.0;
  35 +
  36 + m_bSnapShoting = false;
12 } 37 }
13 38
14 DvppDecoder::~DvppDecoder(){ 39 DvppDecoder::~DvppDecoder(){
15 - delete m_pktQueueptr;  
16 - m_pktQueueptr = nullptr;  
17 } 40 }
18 41
19 bool DvppDecoder::init(FFDecConfig cfg){ 42 bool DvppDecoder::init(FFDecConfig cfg){
20 43
21 m_dec_name = cfg.dec_name; 44 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); 45 +
  46 + AVCodecContext* avctx = init_FFmpeg(cfg);
30 if(avctx == nullptr){ 47 if(avctx == nullptr){
31 return false; 48 return false;
32 } 49 }
33 - m_receiver.setFinishCbkArg(this);  
34 50
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); 51 + bool bRet = init_vdpp(cfg, avctx);
53 if(!bRet){ 52 if(!bRet){
54 return false; 53 return false;
55 } 54 }
@@ -63,22 +62,189 @@ bool DvppDecoder::init(FFDecConfig cfg){ @@ -63,22 +62,189 @@ bool DvppDecoder::init(FFDecConfig cfg){
63 return true; 62 return true;
64 } 63 }
65 64
  65 +AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){
  66 +
  67 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
  68 + av_register_all();
  69 +#endif
  70 +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
  71 + avcodec_register_all();
  72 +#endif
  73 +
  74 + avformat_network_init();
  75 +
  76 + const char* uri = config.uri.c_str();
  77 + fstream infile(uri);
  78 + if (infile.is_open()){
  79 + m_bReal = false;
  80 + infile.close();
  81 + } else {
  82 + m_bReal = true;
  83 + }
  84 +
  85 + // 打开输入视频文件
  86 + AVDictionary *options = nullptr;
  87 + av_dict_set( &options, "bufsize", "655360", 0 );
  88 + av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 );
  89 + av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
  90 +
  91 + const char* input_file = uri;
  92 +
  93 + do{
  94 + fmt_ctx = avformat_alloc_context();
  95 + if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
  96 + LOG_ERROR("[{}]- Cannot open input file: {}", m_dec_name, input_file);
  97 + break;
  98 + }
  99 + av_dump_format(fmt_ctx, 0, input_file, 0);
  100 +
  101 + // 查找流信息
  102 + if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
  103 + LOG_ERROR("[{}]- Cannot find input stream information!", m_dec_name);
  104 + break;
  105 + }
  106 +
  107 + // 查找视频流信息
  108 + AVCodec *decoder = nullptr;
  109 + video_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
  110 + if (video_index < 0) {
  111 + LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
  112 + break;
  113 + }
  114 + AVCodec *vcodec = avcodec_find_decoder(decoder->id);
  115 +
  116 + avctx = avcodec_alloc_context3(vcodec);
  117 + if(avctx == nullptr){
  118 + LOG_ERROR("[{}]- alloc AVCodecContext failed!", m_dec_name);
  119 + break;
  120 + }
  121 +
  122 + // 得到视频流对象
  123 + AVStream* stream = fmt_ctx->streams[video_index];
  124 + AVCodecParameters *codecpar = stream->codecpar;
  125 + if (avcodec_parameters_to_context(avctx, codecpar) < 0)
  126 + break;
  127 +
  128 + const AVBitStreamFilter * filter = nullptr;
  129 + if(codecpar->codec_id == AV_CODEC_ID_H264){
  130 + filter = av_bsf_get_by_name("h264_mp4toannexb");
  131 + }else if(codecpar->codec_id == AV_CODEC_ID_HEVC){
  132 + filter = av_bsf_get_by_name("hevc_mp4toannexb");
  133 + }else {
  134 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
  135 + break;
  136 + }
  137 +
  138 + int ret = av_bsf_alloc(filter, &h264bsfc);
  139 + if (ret < 0){
  140 + break;
  141 + }
  142 +
  143 + avcodec_parameters_copy(h264bsfc->par_in, codecpar);
  144 + av_bsf_init(h264bsfc);
  145 +
  146 + frame_width = codecpar->width;
  147 + frame_height = codecpar->height;
  148 + pix_fmt = (AVPixelFormat)codecpar->format;
  149 + m_fps = av_q2d(stream ->avg_frame_rate);
  150 +
  151 + LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps);
  152 +
  153 + return avctx;
  154 + }while(0);
  155 +
  156 + release_ffmpeg();
  157 +
  158 + LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name, input_file);
  159 +
  160 + return nullptr;
  161 +}
  162 +
  163 + bool DvppDecoder::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) {
  164 +
  165 + LOG_INFO("[{}]- Init device start...", m_dec_name);
  166 +
  167 + m_dvpp_deviceId = atoi(cfg.gpuid.c_str());
  168 +
  169 + if(avctx->codec_id == AV_CODEC_ID_H264){
  170 + // 66:Baseline,77:Main,>=100:High
  171 + if(avctx->profile == 77){
  172 + enType = H264_MAIN_LEVEL;
  173 + }else if(avctx->profile < 77){
  174 + enType = H264_BASELINE_LEVEL;
  175 + }else{
  176 + enType = H264_HIGH_LEVEL;
  177 + }
  178 + }else if(avctx->codec_id == AV_CODEC_ID_HEVC){
  179 + // h265只有main
  180 + enType = H265_MAIN_LEVEL;
  181 + }else {
  182 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
  183 + return false;
  184 + }
  185 +
  186 + post_decoded_cbk = cfg.post_decoded_cbk;
  187 +
  188 + do{
  189 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
  190 + if(ret != ACL_ERROR_NONE){
  191 + LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
  192 + return false;
  193 + }
  194 +
  195 + ret = aclrtCreateContext(&m_context, m_dvpp_deviceId);
  196 + if (ret != ACL_ERROR_NONE) {
  197 + LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
  198 + return false;
  199 + }
  200 +
  201 + // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
  202 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  203 + m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
  204 + if(m_dvpp_channel < 0){
  205 + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
  206 + return false;
  207 + }
  208 + m_vdec_out_size = avctx->width * avctx->height * 3 / 2;
  209 +
  210 + LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
  211 + return true;
  212 + }while(0);
  213 +
  214 + release_dvpp();
  215 +
  216 + return false;
  217 +}
  218 +
66 bool DvppDecoder::isSurport(FFDecConfig& cfg){ 219 bool DvppDecoder::isSurport(FFDecConfig& cfg){
67 return true; 220 return true;
68 } 221 }
69 222
70 bool DvppDecoder::start(){ 223 bool DvppDecoder::start(){
71 - m_receiver.start();  
72 - m_decoder.start();  
73 - return true; 224 + m_bRunning = true;
  225 +
  226 + pthread_create(&m_read_thread,0,
  227 + [](void* arg)
  228 + {
  229 + DvppDecoder* a=(DvppDecoder*)arg;
  230 + a->read_thread();
  231 + return (void*)0;
  232 + }
  233 + ,this);
  234 +
  235 + return true;
74 } 236 }
75 237
76 void DvppDecoder::close(){ 238 void DvppDecoder::close(){
77 - m_receiver.close(); 239 + m_bRunning=false;
  240 +
  241 + if(m_read_thread != 0){
  242 + pthread_join(m_read_thread,0);
  243 + }
78 } 244 }
79 245
80 void DvppDecoder::setPostDecArg(const void* postDecArg){ 246 void DvppDecoder::setPostDecArg(const void* postDecArg){
81 - m_decoder.setPostDecArg(postDecArg); 247 + m_postDecArg = postDecArg;
82 } 248 }
83 249
84 void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){ 250 void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
@@ -86,19 +252,19 @@ void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){ @@ -86,19 +252,19 @@ void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
86 } 252 }
87 253
88 void DvppDecoder::pause(){ 254 void DvppDecoder::pause(){
89 - m_receiver.pause(); 255 + m_bPause = true;
90 } 256 }
91 257
92 void DvppDecoder::resume(){ 258 void DvppDecoder::resume(){
93 - m_receiver.resume(); 259 + m_bPause = false;
94 } 260 }
95 261
96 void DvppDecoder::setDecKeyframe(bool bKeyframe){ 262 void DvppDecoder::setDecKeyframe(bool bKeyframe){
97 - m_receiver.setDecKeyframe(bKeyframe); 263 + m_dec_keyframe = bKeyframe;
98 } 264 }
99 265
100 bool DvppDecoder::isRunning(){ 266 bool DvppDecoder::isRunning(){
101 - return m_receiver.isRunning(); 267 + return m_bRunning;
102 } 268 }
103 269
104 bool DvppDecoder::isFinished(){ 270 bool DvppDecoder::isFinished(){
@@ -106,32 +272,597 @@ bool DvppDecoder::isFinished(){ @@ -106,32 +272,597 @@ bool DvppDecoder::isFinished(){
106 } 272 }
107 273
108 bool DvppDecoder::isPausing(){ 274 bool DvppDecoder::isPausing(){
109 - return m_receiver.isPausing(); 275 + return m_bPause;
110 } 276 }
111 277
112 bool DvppDecoder::getResolution(int &width, int &height){ 278 bool DvppDecoder::getResolution(int &width, int &height){
113 - return m_receiver.getResolution(width, height); 279 + width = frame_width;
  280 + height = frame_height;
  281 + return true;
114 } 282 }
115 283
116 float DvppDecoder::fps(){ 284 float DvppDecoder::fps(){
117 - return m_receiver.fps(); 285 + return m_fps;
118 } 286 }
119 287
120 DeviceMemory* DvppDecoder::snapshot(){ 288 DeviceMemory* DvppDecoder::snapshot(){
121 // 注意内部有锁 289 // 注意内部有锁
122 - return m_decoder.snapshot(); 290 + // 开始抓拍
  291 + m_bSnapShoting = true;
  292 +
  293 + std::unique_lock<std::mutex> locker(m_cached_mutex);
  294 + while (m_cached_mem == nullptr)
  295 + m_cached_cond.wait_for(locker, std::chrono::milliseconds(400)); // Unlock mutex and wait to be notified
  296 + locker.unlock();
  297 +
  298 + DeviceMemory* mem = m_cached_mem;
  299 + m_cached_mem = nullptr;
  300 +
  301 + return mem;
123 } 302 }
124 303
125 int DvppDecoder::getCachedQueueLength(){ 304 int DvppDecoder::getCachedQueueLength(){
126 return 0; 305 return 0;
127 } 306 }
128 307
129 -void DvppDecoder::taskFinishing(){  
130 - // receiver 中读取线程结束时执行  
131 - m_decoder.close(); 308 +void DvppDecoder::release_ffmpeg() {
  309 + m_dec_keyframe = false;
  310 + if(h264bsfc){
  311 + av_bsf_free(&h264bsfc);
  312 + h264bsfc = nullptr;
  313 + }
  314 + if (fmt_ctx){
  315 + avformat_close_input(&fmt_ctx);
  316 + fmt_ctx = nullptr;
  317 + }
  318 + if(avctx){
  319 + avcodec_free_context(&avctx);
  320 + avctx = nullptr;
  321 + }
  322 +}
  323 +
  324 +void DvppDecoder::read_thread() {
  325 +
  326 + int frame_count = 0;
  327 + int ret = -1;
  328 +
  329 + pthread_create(&m_decode_thread,0,
  330 + [](void* arg)
  331 + {
  332 + DvppDecoder* a=(DvppDecoder*)arg;
  333 + a->decode_thread();
  334 + return (void*)0;
  335 + }
  336 + ,this);
  337 +
  338 + AVPacket* pkt = nullptr;
  339 + while (m_bRunning){
  340 +
  341 + if (!m_bReal){
  342 + if (m_bPause){
  343 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  344 + continue;
  345 + }
  346 + }
  347 +
  348 + m_pktQueue_mutex.lock();
  349 + if(m_pktQueue.size() > 10){
  350 + m_pktQueue_mutex.unlock();
  351 + std::this_thread::sleep_for(std::chrono::milliseconds(5));
  352 + continue;
  353 + }
  354 + m_pktQueue_mutex.unlock();
  355 +
  356 + pkt = av_packet_alloc();
  357 + av_init_packet( pkt );
  358 +
  359 + int result = av_read_frame(fmt_ctx, pkt);
  360 + if (result == AVERROR_EOF || result < 0){
  361 + av_packet_free(&pkt);
  362 + pkt = nullptr;
  363 + LOG_ERROR("[{}]- Failed to read frame!", m_dec_name);
  364 + break;
  365 + }
  366 +
  367 + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
  368 + av_packet_free(&pkt);
  369 + pkt = nullptr;
  370 + continue;
  371 + }
  372 +
  373 + if (video_index == pkt->stream_index){
  374 +
  375 + ret = av_bsf_send_packet(h264bsfc, pkt);
  376 + if(ret < 0) {
  377 + LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
  378 + av_packet_free(&pkt);
  379 + pkt = nullptr;
  380 + continue;
  381 + }
  382 +
  383 + bool bPushed = false;
  384 + while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
  385 + if(pkt->size > g_pkt_size){
  386 + LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);
  387 + break;
  388 + }
  389 +
  390 + if(!m_bRunning){
  391 + break;
  392 + }
  393 +
  394 + m_pktQueue_mutex.lock();
  395 + m_pktQueue.push(pkt);
  396 + m_pktQueue_mutex.unlock();
  397 +
  398 + bPushed = true;
  399 + frame_count++;
  400 + }
  401 +
  402 + if(!bPushed){
  403 + av_packet_free(&pkt);
  404 + pkt = nullptr;
  405 + }
  406 + } else {
  407 + // 音频等其他分量的情形
  408 + av_packet_free(&pkt);
  409 + pkt = nullptr;
  410 + }
  411 + }
  412 +
  413 + m_bRunning=false;
  414 +
  415 + if(m_decode_thread != 0){
  416 + pthread_join(m_decode_thread,0);
  417 + }
  418 +
  419 + m_pktQueue_mutex.lock();
  420 + while(m_pktQueue.size() > 0){
  421 + pkt = m_pktQueue.front();
  422 + av_packet_free(&pkt);
  423 + pkt = nullptr;
  424 + m_pktQueue.pop();
  425 + }
  426 + m_pktQueue_mutex.unlock();
  427 +
132 decode_finished_cbk(m_finishedDecArg); 428 decode_finished_cbk(m_finishedDecArg);
133 429
134 - m_bFinished = true; 430 + LOG_INFO("[{}]- read thread exit.", m_dec_name);
  431 + m_bFinished = true;
  432 +}
  433 +
  434 +static void *ReportThd(void *arg)
  435 +{
  436 + DvppDecoder *self = (DvppDecoder *)arg;
  437 + if(nullptr != self){
  438 + self->doProcessReport();
  439 + }
  440 + return (void *)0;
  441 +}
  442 +
  443 +void DvppDecoder::doProcessReport(){
  444 +
  445 + aclError ret = aclrtSetDevice(m_dvpp_deviceId);
  446 + if(ret != ACL_ERROR_NONE){
  447 + // cout << "aclrtSetDevice failed" << endl;
  448 + LOG_ERROR("aclrtSetDevice failed !");
  449 + return ;
  450 + }
  451 +
  452 + aclrtContext ctx;
  453 + ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  454 + if (ret != ACL_ERROR_NONE) {
  455 + // cout << "aclrtCreateContext failed " << endl;
  456 + LOG_ERROR("aclrtCreateContext failed !");
  457 + return ;
  458 + }
  459 +
  460 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed");
  461 + // 阻塞等待vdec线程开始
  462 +
  463 + while (!m_bExitReportThd) {
  464 + aclrtProcessReport(1000);
  465 + }
  466 +
  467 + ret = aclrtDestroyContext(ctx);
  468 + if(ret != ACL_ERROR_NONE){
  469 + LOG_ERROR("aclrtDestroyContext failed !");
  470 + }
  471 + LOG_INFO("doProcessReport exit.");
  472 +}
  473 +
  474 +static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
  475 +{
  476 + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
  477 + if(nullptr != userData){
  478 + DvppDecoder* self = userData->self;
  479 + if(self != nullptr){
  480 +
  481 + self->doVdppVdecCallBack(input, output);
  482 + }
  483 + delete userData;
  484 + userData = nullptr;
  485 + }
  486 +}
  487 +
  488 +void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){
  489 +
  490 + m_vdecQueue_mutex.lock();
  491 + if(m_vdecQueue.size() > 0){
  492 + void* inputData = m_vdecQueue.front();
  493 + acldvppFree(inputData);
  494 + inputData = nullptr;
  495 + m_vdecQueue.pop();
  496 + }
  497 + m_vdecQueue_mutex.unlock();
  498 +
  499 +
  500 + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
  501 +
  502 + void *outputDataDev = acldvppGetPicDescData(output);
  503 + uint32_t outputSize = acldvppGetPicDescSize(output);
  504 + uint32_t width = acldvppGetPicDescWidth(output);
  505 + uint32_t width_stride = acldvppGetPicDescWidthStride(output);
  506 + uint32_t height = acldvppGetPicDescHeight(output);
  507 + uint32_t height_stride = acldvppGetPicDescHeightStride(output);
  508 +
  509 + do{
  510 + int ret = acldvppGetPicDescRetCode(output);
  511 + if(ret != ACL_ERROR_NONE){
  512 + LOG_ERROR("[{}]- decode result error, retCode:{} ", m_dec_name, ret);
  513 + acldvppFree(outputDataDev);
  514 + outputDataDev = nullptr;
  515 + break;
  516 + }
  517 +
  518 + if(width > 0 && height > 0 && outputSize > 0){
  519 + DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, (unsigned char *)outputDataDev);
  520 + if(mem){
  521 + post_decoded_cbk(m_postDecArg, mem);
  522 +
  523 + if(m_bSnapShoting){
  524 + // 缓存snapshot
  525 + std::unique_lock<std::mutex> locker(m_cached_mutex);
  526 +
  527 + m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false);
  528 + if(m_cached_mem != nullptr){
  529 + aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
  530 + }
  531 +
  532 + locker.unlock();
  533 + m_cached_cond.notify_one();
  534 + m_bSnapShoting = false;
  535 + }
  536 + } else {
  537 + LOG_ERROR("[{}]- DvppDataMemory 创建失败! ", m_dec_name, ret);
  538 + acldvppFree(outputDataDev);
  539 + outputDataDev = nullptr;
  540 + }
  541 +
  542 + } else {
  543 + LOG_WARN("[{}]- decode result error, width:{} width_stride:{} height:{} height_stride:{} size:{}", m_dec_name, width, width_stride, height, height_stride, outputSize);
  544 + acldvppFree(outputDataDev);
  545 + outputDataDev = nullptr;
  546 + }
  547 +
  548 + // DvppDataMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
  549 + // if(rgbMem != nullptr){
  550 + // #ifdef TEST_DECODER
  551 + // // D2H
  552 + // if(vdecHostAddr == nullptr){
  553 + // CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");
  554 + // }
  555 + // uint32_t data_size = rgbMem->getSize();
  556 + // CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
  557 +
  558 + // // 保存vdec结果
  559 + // if(count_frame > 45 && count_frame < 50)
  560 + // {
  561 + // string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;
  562 + // FILE *outputFile = fopen(file_name.c_str(), "a");
  563 + // if(outputFile){
  564 + // fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
  565 + // fclose(outputFile);
  566 + // }
  567 + // }
  568 + // else if(count_frame > 50 && vdecHostAddr != nullptr){
  569 + // CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
  570 + // vdecHostAddr = nullptr;
  571 + // }
  572 + // count_frame++;
  573 + // #endif
  574 + // post_decoded_cbk(m_postDecArg, rgbMem);
  575 + // }else{
  576 + // LOG_ERROR("[{}]- convert2bgr failed !", m_dec_name);
  577 + // }
  578 + }while(0);
  579 +
  580 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
  581 + CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
  582 +}
  583 +
  584 +void DvppDecoder::decode_thread(){
  585 +
  586 + long startTime = UtilTools::get_cur_time_ms();
  587 +
  588 + int ret = -1;
  589 +
  590 + m_bExitReportThd = false;
  591 + pthread_t report_thread;
  592 + ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
  593 + if(ret != 0){
  594 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
  595 + return;
  596 + }
  597 +
  598 + aclrtSetDevice(m_dvpp_deviceId);
  599 + aclrtContext ctx;
  600 + ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
  601 + if (ret != ACL_ERROR_NONE) {
  602 + // cout << "aclrtCreateContext failed " << endl;
  603 + LOG_ERROR("aclrtCreateContext failed !");
  604 + return ;
  605 + }
  606 +
  607 + // 创建aclvdecChannelDesc类型的数据
  608 + aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
  609 + if (vdecChannelDesc == nullptr) {
  610 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
  611 + return;
  612 + }
  613 + do{
  614 + // 创建 channel dec结构体
  615 + // 通道ID在dvpp层面为0~31
  616 + CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
  617 + CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
  618 + CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
  619 + CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");
  620 + CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
  621 + CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
  622 +
  623 + uint64_t frame_count = 0;
  624 + bool bBreak = false;
  625 + while (m_bRunning)
  626 + {
  627 + if (m_bPause){
  628 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  629 + continue;
  630 + }
  631 + int ret = sentFrame(vdecChannelDesc, frame_count);
  632 + if(ret == 2){
  633 + bBreak = true;
  634 + break;
  635 + }else if(ret == 1){
  636 + continue;
  637 + }
  638 +
  639 + frame_count++;
  640 + }
  641 +
  642 + // 尽量保证数据全部解码完成
  643 + int sum = 0;
  644 + if(!bBreak){
  645 + aclrtSetDevice(m_dvpp_deviceId);
  646 + aclrtSetCurrentContext(ctx);
  647 + while(m_pktQueue.size() > 0){
  648 + int ret = sentFrame(vdecChannelDesc, frame_count);
  649 + if(ret == 2){
  650 + break;
  651 + }
  652 + std::this_thread::sleep_for(std::chrono::milliseconds(3));
  653 + sum++;
  654 + if(sum > 40){
  655 + // 避免卡死
  656 + break;
  657 + }
  658 + }
  659 + }
  660 +
  661 + sendVdecEos(vdecChannelDesc);
  662 +
  663 + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
  664 + }while(0);
  665 +
  666 + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
  667 +
  668 + // report_thread 需后于destroy退出
  669 + m_bRunning = false;
  670 + m_bExitReportThd = true;
  671 + CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");
  672 +
  673 + // 最后清理一遍未解码的数据
  674 + m_vdecQueue_mutex.lock();
  675 + if(m_vdecQueue.size() > 0){
  676 + void* inputData = m_vdecQueue.front();
  677 + acldvppFree(inputData);
  678 + inputData = nullptr;
  679 + m_vdecQueue.pop();
  680 + }
  681 + m_vdecQueue_mutex.unlock();
  682 +
  683 + release_dvpp();
  684 +
  685 + ret = aclrtDestroyContext(ctx);
  686 + if(ret != ACL_ERROR_NONE){
  687 + LOG_ERROR("aclrtDestroyContext failed !");
  688 + }
  689 +
  690 + LOG_INFO("[{}]- decode thread exit.", m_dec_name);
  691 +}
  692 +
  693 +#include <fstream>
  694 +#include <iostream>
  695 +#include <cstring>
135 696
136 - LOG_INFO("[{}]- task finished.", m_dec_name); 697 +static int nRecoder = 0;
  698 +
  699 +
  700 +
  701 +int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
  702 +
  703 + // 此处需要判断 m_vdecQueue 队列长度,避免占用过多显存
  704 + m_vdecQueue_mutex.lock();
  705 + if(m_vdecQueue.size() > 20){
  706 + m_vdecQueue_mutex.unlock();
  707 + std::this_thread::sleep_for(std::chrono::milliseconds(2));
  708 + return 1;
  709 + }
  710 + m_vdecQueue_mutex.unlock();
  711 +
  712 + AVPacket * pkt = nullptr;
  713 + m_pktQueue_mutex.lock();
  714 + if(m_pktQueue.size() <= 0){
  715 + m_pktQueue_mutex.unlock();
  716 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  717 + return 1;
  718 + }
  719 + pkt = m_pktQueue.front();
  720 + m_pktQueue.pop();
  721 + m_pktQueue_mutex.unlock();
  722 +
  723 + // 解码
  724 + void *vdecInputbuf = nullptr;
  725 + int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  726 + if(ACL_ERROR_NONE != ret){
  727 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  728 + av_packet_free(&pkt);
  729 + pkt = nullptr;
  730 + return 2;
  731 + }
  732 +
  733 + // std::ofstream outfile;
  734 + // string file_name = "./pkt/pkt";
  735 + // file_name = file_name + to_string(nRecoder) + ".bin";
  736 + // outfile.open(file_name.c_str(), std::ios::binary | std::ios::app);
  737 + // if (!outfile) {
  738 + // std::cerr << "Failed to open file!" << std::endl;
  739 + // return 2;
  740 + // }
  741 +
  742 + // outfile.write((const char*)pkt->data, pkt->size);
  743 + // outfile.close();
  744 +
  745 + // nRecoder ++ ;
  746 + // if(nRecoder >= 1000){
  747 +
  748 + // return 2;
  749 + // }
  750 +
  751 +
  752 +
  753 + ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
  754 + if(ACL_ERROR_NONE != ret){
  755 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
  756 + av_packet_free(&pkt);
  757 + pkt = nullptr;
  758 + return 2;
  759 + }
  760 +
  761 + void *vdecOutputBuf = nullptr;
  762 + ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
  763 + if(ret != ACL_ERROR_NONE){
  764 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
  765 + av_packet_free(&pkt);
  766 + pkt = nullptr;
  767 + return 2;
  768 + }
  769 +
  770 + acldvppStreamDesc *input_stream_desc = nullptr;
  771 + acldvppPicDesc *output_pic_desc = nullptr;
  772 + do{
  773 + input_stream_desc = acldvppCreateStreamDesc();
  774 + if (input_stream_desc == nullptr) {
  775 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  776 + break;
  777 + }
  778 + output_pic_desc = acldvppCreatePicDesc();
  779 + if (output_pic_desc == nullptr) {
  780 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  781 + break;
  782 + }
  783 + CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
  784 + CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
  785 + CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
  786 + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
  787 +
  788 + Vdec_CallBack_UserData *user_data = NULL;
  789 + user_data = new Vdec_CallBack_UserData;
  790 + user_data->frameId = frame_count;
  791 + // user_data->startTime = startTime;
  792 + user_data->sendTime = UtilTools::get_cur_time_ms();
  793 + user_data->self = this;
  794 + ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  795 + av_packet_free(&pkt);
  796 + pkt = nullptr;
  797 + if(ret != ACL_ERROR_NONE){
  798 + delete user_data;
  799 + user_data = nullptr;
  800 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
  801 + break;
  802 + }
  803 +
  804 + m_vdecQueue_mutex.lock();
  805 + m_vdecQueue.push(vdecInputbuf);
  806 + m_vdecQueue_mutex.unlock();
  807 +
  808 + return 0;
  809 + }while (0);
  810 +
  811 + if(pkt != nullptr){
  812 + av_packet_free(&pkt);
  813 + pkt = nullptr;
  814 + }
  815 +
  816 + // 报错情形
  817 + if(input_stream_desc){
  818 + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
  819 + }
  820 + if(output_pic_desc){
  821 + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
  822 + }
  823 +
  824 + if (vdecOutputBuf){
  825 + acldvppFree(vdecOutputBuf);
  826 + vdecOutputBuf = nullptr;
  827 + }
  828 +
  829 + return 1;
  830 +}
  831 +
  832 +bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
  833 + // create stream desc
  834 + acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
  835 + if (streamInputDesc == nullptr) {
  836 + LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
  837 + return false;
  838 + }
  839 + aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
  840 + if (ret != ACL_SUCCESS) {
  841 + LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
  842 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  843 + return false;
  844 + }
  845 +
  846 + // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
  847 + LOG_INFO("[{}]- send eos", m_dec_name);
  848 + ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
  849 + (void)acldvppDestroyStreamDesc(streamInputDesc);
  850 + if (ret != ACL_SUCCESS) {
  851 + LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
  852 + return false;
  853 + }
  854 +
  855 + return true;
  856 +}
  857 +
  858 +void DvppDecoder::release_dvpp(){
  859 + if(m_context){
  860 + aclError ret = aclrtDestroyContext(m_context);
  861 + if(ret != ACL_ERROR_NONE){
  862 + LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
  863 + }
  864 + }
  865 +
  866 + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
  867 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
137 } 868 }
138 \ No newline at end of file 869 \ No newline at end of file
src/decoder/dvpp/DvppDecoder.h
1 #include<string> 1 #include<string>
2 2
3 #include "depend_headers.h" 3 #include "depend_headers.h"
4 -#include "CircularQueue.hpp"  
5 -#include "FFReceiver.h"  
6 -#include "DvppDec.h" 4 +#include "dvpp_headers.h"
  5 +#include "DvppDataMemory.hpp"
  6 +
  7 +#include <queue>
  8 +#include <mutex>
  9 +#include <condition_variable>
  10 +
7 11
8 using namespace std; 12 using namespace std;
9 13
  14 +typedef void(*RECEIVER_FINISHED_CALLBACK)(const void* userPtr);
  15 +
  16 +const int g_pkt_size = 1024 * 1024; // 单个AVPacket大小的最大值
  17 +
10 class DvppDecoder{ 18 class DvppDecoder{
11 public: 19 public:
12 DvppDecoder(); 20 DvppDecoder();
@@ -44,19 +52,72 @@ public: @@ -44,19 +52,72 @@ public:
44 int getCachedQueueLength(); 52 int getCachedQueueLength();
45 53
46 public: 54 public:
47 - void taskFinishing(); 55 + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output);
  56 + void doProcessReport();
  57 +
  58 +private:
  59 + AVCodecContext* init_FFmpeg(FFDecConfig config);
  60 + bool init_vdpp(FFDecConfig cfg, AVCodecContext* avctx);
  61 + void release_ffmpeg();
  62 + void read_thread();
  63 +
  64 + void decode_thread();
  65 + int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count);
  66 + bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc);
  67 + void release_dvpp();
48 68
49 private: 69 private:
50 FFDecConfig m_cfg; 70 FFDecConfig m_cfg;
51 string m_dec_name; 71 string m_dec_name;
52 72
53 - CircularQueue<AVPacket *> *m_pktQueueptr;  
54 - FFReceiver m_receiver;  
55 - DvppDec m_decoder;  
56 -  
57 const void * m_finishedDecArg; 73 const void * m_finishedDecArg;
58 DECODE_FINISHED_CALLBACK decode_finished_cbk; 74 DECODE_FINISHED_CALLBACK decode_finished_cbk;
59 75
60 bool m_bFinished{false}; 76 bool m_bFinished{false};
  77 + bool m_bRunning{false};
  78 + bool m_bPause{false};
  79 + bool m_bExitReportThd{false};
  80 +
  81 + // 读取数据
  82 + AVStream* stream{nullptr};
  83 + int video_index{-1};
  84 + AVFormatContext *fmt_ctx{nullptr};
  85 + AVPixelFormat pix_fmt;
  86 + AVCodecContext *avctx{nullptr};
  87 + AVBSFContext * h264bsfc{nullptr};
  88 +
  89 + int frame_width{0};
  90 + int frame_height{0};
  91 + bool m_bReal; // 是否实时流
  92 + float m_fps{0.0};
  93 +
  94 + RECEIVER_FINISHED_CALLBACK receiver_finished_cbk;
  95 +
  96 + pthread_t m_read_thread{0};
  97 +
  98 + bool m_dec_keyframe;
  99 +
  100 + mutex m_pktQueue_mutex;
  101 + queue<AVPacket*> m_pktQueue;
  102 +
  103 + // 解码
  104 + int m_dvpp_deviceId {-1};
  105 + int m_dvpp_channel {-1};
  106 + aclrtContext m_context{nullptr};
  107 + acldvppStreamFormat enType;
  108 +
  109 + pthread_t m_decode_thread{0};
  110 + mutex m_vdecQueue_mutex;
  111 + queue<void*> m_vdecQueue;
  112 +
  113 + const void * m_postDecArg;
  114 + POST_DECODE_CALLBACK post_decoded_cbk;
  115 +
  116 + int m_vdec_out_size {-1};
61 117
  118 + // 截图
  119 + bool m_bSnapShoting{false};
  120 + DvppDataMemory* m_cached_mem{nullptr};
  121 + mutex m_cached_mutex;
  122 + condition_variable m_cached_cond;
62 }; 123 };
63 \ No newline at end of file 124 \ No newline at end of file
src/decoder/dvpp/FFReceiver.cpp deleted
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 < 50; 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 -  
164 - AVPacket* pkt;  
165 -  
166 - while (m_bRunning){  
167 -  
168 - if (!m_bReal){  
169 - if (m_bPause){  
170 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
171 - continue;  
172 - }  
173 - }  
174 -  
175 - AVPacket* pkt = m_pktQueueptr->getTail();  
176 - if(pkt == nullptr){  
177 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
178 - continue;  
179 - }  
180 -  
181 - // AVPacket* pkt = av_packet_alloc();  
182 - // av_init_packet( pkt );  
183 -  
184 - int result = av_read_frame(fmt_ctx, pkt);  
185 - if (result == AVERROR_EOF || result < 0){  
186 - av_packet_unref(pkt);  
187 - LOG_ERROR("[{}]- Failed to read frame!", m_dec_name);  
188 - break;  
189 - }  
190 -  
191 - // m_pktQueueptr->addTail();  
192 -  
193 - // std::this_thread::sleep_for(std::chrono::milliseconds(1));  
194 - // pkt = m_pktQueueptr->getHead();  
195 - // av_packet_unref(pkt);  
196 - // m_pktQueueptr->addHead();  
197 -  
198 - // av_packet_free(&pkt);  
199 - // pkt = nullptr;  
200 - // continue;  
201 -  
202 - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {  
203 - av_packet_unref(pkt);  
204 - continue;  
205 - }  
206 -  
207 - if (stream_index == pkt->stream_index){  
208 -  
209 - ret = av_bsf_send_packet(h264bsfc, pkt);  
210 - if(ret < 0) {  
211 - LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);  
212 - }  
213 -  
214 - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {  
215 - if(pkt->size > g_pkt_size){  
216 - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name);  
217 - break;  
218 - }  
219 -  
220 - if(!m_bRunning){  
221 - break;  
222 - }  
223 -  
224 - m_pktQueueptr->addTail();  
225 -  
226 - frame_count++;  
227 - }  
228 - } else {  
229 - // 音频等其他分量的情形  
230 - av_packet_unref(pkt);  
231 - }  
232 - }  
233 -  
234 - LOG_INFO("[{}]- read thread exit.", m_dec_name);  
235 - m_bFinished = true;  
236 -  
237 - receiver_finished_cbk(m_finishedReceiveArg);  
238 -}  
239 -  
240 -bool FFReceiver::start(){  
241 - m_bRunning = true;  
242 -  
243 - pthread_create(&m_read_thread,0,  
244 - [](void* arg)  
245 - {  
246 - FFReceiver* a=(FFReceiver*)arg;  
247 - a->read_thread();  
248 - return (void*)0;  
249 - }  
250 - ,this);  
251 -  
252 - return true;  
253 -}  
254 -  
255 -void FFReceiver::close(){  
256 - m_bRunning=false;  
257 -  
258 - if(m_read_thread != 0){  
259 - pthread_join(m_read_thread,0);  
260 - }  
261 -}  
262 -  
263 -float FFReceiver::fps(){  
264 - return m_fps;  
265 -}  
266 -  
267 -bool FFReceiver::getResolution( int &width, int &height ){  
268 - width = frame_width;  
269 - height = frame_height;  
270 - return true;  
271 -}  
272 -  
273 -void FFReceiver::pause(){  
274 - m_bPause = true;  
275 -}  
276 -  
277 -void FFReceiver::resume(){  
278 - m_bPause = false;  
279 -}  
280 -  
281 -void FFReceiver::setDecKeyframe(bool bKeyframe)  
282 -{  
283 - m_dec_keyframe = bKeyframe;  
284 -}  
285 -  
286 -bool FFReceiver::isRunning(){  
287 - return m_bRunning;  
288 -}  
289 -  
290 -bool FFReceiver::isFinished(){  
291 - return m_bFinished;  
292 -}  
293 -  
294 -bool FFReceiver::isPausing(){  
295 - return m_bPause;  
296 -}  
297 -  
298 -void FFReceiver::setFinishCbkArg(const void* userPtr){  
299 - m_finishedReceiveArg = userPtr;  
300 -}  
301 \ No newline at end of file 0 \ No newline at end of file
src/decoder/dvpp/FFReceiver.h deleted
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  
82 \ No newline at end of file 0 \ No newline at end of file