Commit d248da62fff59e75b5da6d00f1cb2c727fc737ff

Authored by Hu Chunming
1 parent 207d694c

优化代码,修正dvpp的一些bug

src/demo/main_dvpp.cpp
@@ -91,23 +91,11 @@ void postDecoded(const void * userPtr, DeviceRgbMemory* devFrame){ @@ -91,23 +91,11 @@ void postDecoded(const void * userPtr, DeviceRgbMemory* devFrame){
91 AbstractDecoder* decoder = (AbstractDecoder*)userPtr; 91 AbstractDecoder* decoder = (AbstractDecoder*)userPtr;
92 if (decoder!= nullptr) 92 if (decoder!= nullptr)
93 { 93 {
94 - // cout << "decode name: " << decoder->getName() << endl;  
95 -  
96 - // const char* gpu_pixfmt = av_get_pix_fmt_name((AVPixelFormat)gpuFrame->format);  
97 - // cout << "pixfmt: " << gpu_pixfmt << endl;  
98 - // cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl;  
99 - // cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl; 94 + }
100 95
101 - int sum = sum1;  
102 - if (decoder->getName() == "dec0")  
103 - {  
104 - sum1 ++ ;  
105 - sum = sum1;  
106 - } else if (decoder->getName() == "dec2")  
107 - {  
108 - sum2 ++ ;  
109 - sum = sum2;  
110 - } 96 + if(devFrame){
  97 + delete devFrame;
  98 + devFrame = nullptr;
111 } 99 }
112 } 100 }
113 101
@@ -169,7 +157,8 @@ bool decode_request_stream_cbk(const char* deviceId){ @@ -169,7 +157,8 @@ bool decode_request_stream_cbk(const char* deviceId){
169 // string test_uri = "rtsp://176.10.0.2:8554/stream"; 157 // string test_uri = "rtsp://176.10.0.2:8554/stream";
170 // string test_uri = "/mnt/f/fiss/test_data/h265.mp4"; 158 // string test_uri = "/mnt/f/fiss/test_data/h265.mp4";
171 // string test_uri = "rtsp://176.10.0.4:8554/stream"; 159 // string test_uri = "rtsp://176.10.0.4:8554/stream";
172 -string test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0"; 160 +// string test_uri = "rtsp://admin:admin@123456@192.168.60.176:554/cam/realmonitor?channel=1&subtype=0";
  161 +string test_uri = "/home/huchunming/data/woyikewangh265.mp4";
173 162
174 void createDecode(int index, const char* gpu_id){ 163 void createDecode(int index, const char* gpu_id){
175 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); 164 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
@@ -241,6 +230,7 @@ void createDvppDecoder(int index, char* devId, int channelId){ @@ -241,6 +230,7 @@ void createDvppDecoder(int index, char* devId, int channelId){
241 AbstractDecoder* decoder = pDecManager->createDecoder(config); 230 AbstractDecoder* decoder = pDecManager->createDecoder(config);
242 if (!decoder) 231 if (!decoder)
243 { 232 {
  233 + cout << "创建解码器失败" << endl;
244 return ; 234 return ;
245 } 235 }
246 pDecManager->setPostDecArg(config.name, decoder); 236 pDecManager->setPostDecArg(config.name, decoder);
@@ -256,7 +246,7 @@ void logFF(void *, int level, const char *fmt, va_list ap) @@ -256,7 +246,7 @@ void logFF(void *, int level, const char *fmt, va_list ap)
256 246
257 int main(int argc, char* argv[]){ 247 int main(int argc, char* argv[]){
258 248
259 - test_uri = argv[1]; 249 + // test_uri = argv[1];
260 char* gpuid = argv[2]; 250 char* gpuid = argv[2];
261 int port = atoi(argv[3]); 251 int port = atoi(argv[3]);
262 cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl; 252 cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl;
@@ -272,7 +262,7 @@ int main(int argc, char* argv[]){ @@ -272,7 +262,7 @@ int main(int argc, char* argv[]){
272 // cudaSetDevice(atoi(gpuid)); 262 // cudaSetDevice(atoi(gpuid));
273 while (true) 263 while (true)
274 { 264 {
275 - std::this_thread::sleep_for(std::chrono::minutes(1)); 265 + std::this_thread::sleep_for(std::chrono::seconds(10));
276 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); 266 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
277 int count = pDecManager->count(); 267 int count = pDecManager->count();
278 cout << "当前时间:" << UtilTools::get_cur_time_ms() << " 当前运行路数: " << pDecManager->count() << endl; 268 cout << "当前时间:" << UtilTools::get_cur_time_ms() << " 当前运行路数: " << pDecManager->count() << endl;
@@ -288,6 +278,14 @@ int main(int argc, char* argv[]){ @@ -288,6 +278,14 @@ int main(int argc, char* argv[]){
288 278
289 createDvppDecoder(i, gpuid, 0); 279 createDvppDecoder(i, gpuid, 0);
290 i++; 280 i++;
  281 + createDvppDecoder(i, gpuid, 0);
  282 + i++;
  283 + createDvppDecoder(i, gpuid, 0);
  284 + i++;
  285 +
  286 + for(;i<30;i++){
  287 + createDvppDecoder(i, gpuid, 0);
  288 + }
291 289
292 while (true) 290 while (true)
293 { 291 {
src/dvpp/DvppDec.cpp
1 #include "DvppDec.h" 1 #include "DvppDec.h"
2 #include "DvppSourceManager.h" 2 #include "DvppSourceManager.h"
3 3
4 -#define CHECK_AND_RETURN(ret, message) \  
5 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}  
6 -#define CHECK_NOT_RETURN(ret, message) \  
7 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}  
8 -#define CHECK_AND_RETURN_NOVALUE(ret, message) \  
9 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}  
10 -#define CHECK_AND_BREAK(ret, message) \  
11 - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}  
12 -  
13 struct Vdec_CallBack_UserData { 4 struct Vdec_CallBack_UserData {
14 uint64_t frameId; 5 uint64_t frameId;
15 long startTime; 6 long startTime;
@@ -22,10 +13,6 @@ struct Vdec_CallBack_UserData { @@ -22,10 +13,6 @@ struct Vdec_CallBack_UserData {
22 } 13 }
23 }; 14 };
24 15
25 -#ifdef TEST_DECODER  
26 -static void *vdecHostAddr = nullptr;  
27 -#endif  
28 -  
29 static const int g_pkt_size = 1024 * 1024; 16 static const int g_pkt_size = 1024 * 1024;
30 17
31 DvppDec::DvppDec(){ 18 DvppDec::DvppDec(){
@@ -33,11 +20,14 @@ static const int g_pkt_size = 1024 * 1024; @@ -33,11 +20,14 @@ static const int g_pkt_size = 1024 * 1024;
33 } 20 }
34 21
35 DvppDec::~DvppDec(){ 22 DvppDec::~DvppDec(){
36 - 23 + releaseResource();
37 } 24 }
38 25
39 bool DvppDec::init_vdpp(DvppDecConfig cfg){ 26 bool DvppDec::init_vdpp(DvppDecConfig cfg){
40 - cout << "Init device....\n"; 27 +
  28 + m_dec_name = cfg.dec_name;
  29 +
  30 + LOG_INFO("[{}]- Init device start...", m_dec_name);
41 31
42 m_dvpp_deviceId = atoi(cfg.dev_id.c_str()); 32 m_dvpp_deviceId = atoi(cfg.dev_id.c_str());
43 33
@@ -54,7 +44,7 @@ static const int g_pkt_size = 1024 * 1024; @@ -54,7 +44,7 @@ static const int g_pkt_size = 1024 * 1024;
54 // h265只有main 44 // h265只有main
55 enType = H265_MAIN_LEVEL; 45 enType = H265_MAIN_LEVEL;
56 }else { 46 }else {
57 - cout << "codec_id is not supported!" << endl; 47 + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
58 return false; 48 return false;
59 } 49 }
60 50
@@ -66,42 +56,47 @@ static const int g_pkt_size = 1024 * 1024; @@ -66,42 +56,47 @@ static const int g_pkt_size = 1024 * 1024;
66 m_context = pSrcMgr->getContext(m_dvpp_deviceId); 56 m_context = pSrcMgr->getContext(m_dvpp_deviceId);
67 m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId); 57 m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
68 if(m_dvpp_channel < 0){ 58 if(m_dvpp_channel < 0){
69 - cout << "该设备channel已经用完了" << endl; 59 + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
70 return false; 60 return false;
71 } 61 }
72 62
73 - cout << "devProgram start, device: " << m_dvpp_deviceId << endl;  
74 - int ret = aclrtSetCurrentContext(m_context);  
75 - if (ret != ACL_ERROR_NONE) {  
76 - cout << "aclrtSetCurrentContext failed" << endl;  
77 - return false;  
78 - }  
79 -  
80 - // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死  
81 - for (size_t i = 0; i < 20; i++){  
82 - void *vdecInputbuf = nullptr;  
83 - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);  
84 - if(ret != ACL_ERROR_NONE){  
85 - cout << "acldvppMalloc failed" << endl;  
86 - return false;;  
87 - }  
88 - m_vec_vdec.push_back(vdecInputbuf);  
89 - } 63 + do
  64 + {
  65 + CHECK_AND_BREAK(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed !");
90 66
91 - if(!m_vdecQueue.init(m_vec_vdec)){  
92 - return false;  
93 - } 67 + int ret = picConverter.init(m_context, m_dec_name);
  68 + if(ret != ACL_ERROR_NONE){
  69 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  70 + break;
  71 + }
94 72
95 - ret = picConverter.init(m_context);  
96 - if(!ret){  
97 - picConverter.release();  
98 - } 73 + // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死
  74 + for (size_t i = 0; i < 20; i++){
  75 + void *vdecInputbuf = nullptr;
  76 + ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);
  77 + if(ret != ACL_ERROR_NONE){
  78 + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
  79 + // 析构函数中有对channel 的补救性释放,所以这里可以直接return
  80 + return false;;
  81 + }
  82 + m_vec_vdec.push_back(vdecInputbuf);
  83 + }
99 84
100 - m_vdec_out_size = cfg.width * cfg.height * 3 / 2;  
101 - m_dec_name = cfg.dec_name; 85 + if(!m_vdecQueue.init(m_vec_vdec)){
  86 + break;
  87 + }
102 88
103 - cout << "init vdpp success!" << endl;  
104 - return true; 89 + m_vdec_out_size = cfg.width * cfg.height * 3 / 2;
  90 +
  91 + LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
  92 + return true;
  93 +
  94 + } while (0);
  95 +
  96 + LOG_INFO("[{}]- init vdpp failed!", m_dec_name);
  97 + // 初始化失败,释放channel
  98 + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
  99 + return false;
105 } 100 }
106 101
107 bool DvppDec::start(){ 102 bool DvppDec::start(){
@@ -139,22 +134,18 @@ void DvppDec::doProcessReport(){ @@ -139,22 +134,18 @@ void DvppDec::doProcessReport(){
139 } 134 }
140 } 135 }
141 136
142 -static int count_frame = 0;  
143 -static long lastts = 0;  
144 static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData) 137 static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
145 { 138 {
146 - cout << "VdecCallback: " << UtilTools::get_cur_time_ms() - lastts << endl;  
147 - lastts = UtilTools::get_cur_time_ms();  
148 -  
149 Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData; 139 Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
150 - DvppDec* self = userData->self;  
151 - if(self != nullptr){ 140 + if(nullptr != userData){
  141 + DvppDec* self = userData->self;
  142 + if(self != nullptr){
152 143
153 - self->doVdppVdecCallBack(input, output);  
154 - }  
155 -  
156 - delete userData;  
157 - userData = nullptr; 144 + self->doVdppVdecCallBack(input, output);
  145 + }
  146 + delete userData;
  147 + userData = nullptr;
  148 + }
158 } 149 }
159 150
160 void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){ 151 void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){
@@ -166,43 +157,38 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu @@ -166,43 +157,38 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu
166 uint32_t outputSize = acldvppGetPicDescSize(output); 157 uint32_t outputSize = acldvppGetPicDescSize(output);
167 uint32_t width = acldvppGetPicDescWidth(output); 158 uint32_t width = acldvppGetPicDescWidth(output);
168 uint32_t height = acldvppGetPicDescHeight(output); 159 uint32_t height = acldvppGetPicDescHeight(output);
169 -  
170 - cout << "width = " << width << " height = " << height << " data_size:" << outputSize << endl;  
171 160
172 - if (!m_bPause)  
173 - {  
174 - DvppRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);  
175 - post_decoded_cbk(m_postDecArg, rgbMem); 161 +
  162 + DvppRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);
  163 + if(rgbMem != nullptr){
176 #ifdef TEST_DECODER 164 #ifdef TEST_DECODER
177 - if(rgbMem != nullptr){  
178 - // D2H  
179 - if(vdecHostAddr == nullptr){  
180 - CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");  
181 - }  
182 - uint32_t data_size = rgbMem->getSize();  
183 - CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");  
184 -  
185 - // 保存vdec结果  
186 - if(count_frame > 45 && count_frame < 50)  
187 - {  
188 - string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;  
189 - FILE *outputFile = fopen(file_name.c_str(), "a");  
190 - if(outputFile){  
191 - fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);  
192 - fclose(outputFile);  
193 - }  
194 - }  
195 - else if(count_frame > 50 && vdecHostAddr != nullptr){  
196 - CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");  
197 - vdecHostAddr = nullptr; 165 + // D2H
  166 + if(vdecHostAddr == nullptr){
  167 + CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, width * height * 3), "aclrtMallocHost failed");
  168 + }
  169 + uint32_t data_size = rgbMem->getSize();
  170 + CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");
  171 +
  172 + // 保存vdec结果
  173 + if(count_frame > 45 && count_frame < 50)
  174 + {
  175 + string file_name = "./yuv_pic/vdec_out_"+ m_dec_name +".rgb" ;
  176 + FILE *outputFile = fopen(file_name.c_str(), "a");
  177 + if(outputFile){
  178 + fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);
  179 + fclose(outputFile);
198 } 180 }
199 - count_frame++;  
200 - } 181 + }
  182 + else if(count_frame > 50 && vdecHostAddr != nullptr){
  183 + CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");
  184 + vdecHostAddr = nullptr;
  185 + }
  186 + count_frame++;
201 #endif 187 #endif
202 -  
203 - }else{  
204 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
205 - } 188 + post_decoded_cbk(m_postDecArg, rgbMem);
  189 + }else{
  190 + LOG_ERROR("[{}]- convert2bgr failed !", m_dec_name);
  191 + }
206 192
207 acldvppFree((uint8_t*)outputDataDev); 193 acldvppFree((uint8_t*)outputDataDev);
208 outputDataDev = nullptr; 194 outputDataDev = nullptr;
@@ -211,8 +197,6 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu @@ -211,8 +197,6 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu
211 197
212 CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed"); 198 CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
213 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed"); 199 CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
214 -  
215 - cout << "callback exit." << endl;  
216 } 200 }
217 201
218 void DvppDec::close(){ 202 void DvppDec::close(){
@@ -227,21 +211,21 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){ @@ -227,21 +211,21 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
227 // create stream desc 211 // create stream desc
228 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc(); 212 acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
229 if (streamInputDesc == nullptr) { 213 if (streamInputDesc == nullptr) {
230 - cout << "fail to create input stream desc" << endl; 214 + LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
231 return false; 215 return false;
232 } 216 }
233 aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1); 217 aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
234 if (ret != ACL_SUCCESS) { 218 if (ret != ACL_SUCCESS) {
235 - cout << "fail to set eos for stream desc, errorCode = " << static_cast<int32_t>(ret) << endl; 219 + LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
236 (void)acldvppDestroyStreamDesc(streamInputDesc); 220 (void)acldvppDestroyStreamDesc(streamInputDesc);
237 return false; 221 return false;
238 } 222 }
239 223
240 // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned. 224 // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
241 - cout << "send eos" << endl; 225 + LOG_INFO("[{}]- send eos", m_dec_name);
242 ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr); 226 ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
243 if (ret != ACL_SUCCESS) { 227 if (ret != ACL_SUCCESS) {
244 - cout << "fail to send eos frame, ret=" << ret << endl; 228 + LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
245 (void)acldvppDestroyStreamDesc(streamInputDesc); 229 (void)acldvppDestroyStreamDesc(streamInputDesc);
246 return false; 230 return false;
247 } 231 }
@@ -251,7 +235,6 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){ @@ -251,7 +235,6 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){
251 } 235 }
252 236
253 void DvppDec::releaseResource(){ 237 void DvppDec::releaseResource(){
254 -  
255 for(int i = 0; i < m_vec_vdec.size(); i++){ 238 for(int i = 0; i < m_vec_vdec.size(); i++){
256 if(m_vec_vdec[i] != nullptr){ 239 if(m_vec_vdec[i] != nullptr){
257 acldvppFree(m_vec_vdec[i]); 240 acldvppFree(m_vec_vdec[i]);
@@ -277,14 +260,14 @@ void DvppDec::decode_thread(){ @@ -277,14 +260,14 @@ void DvppDec::decode_thread(){
277 pthread_t report_thread; 260 pthread_t report_thread;
278 ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this); 261 ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
279 if(ret != 0){ 262 if(ret != 0){
280 - cout << "pthread_create failed" << endl; 263 + LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
281 return; 264 return;
282 } 265 }
283 266
284 // 创建aclvdecChannelDesc类型的数据 267 // 创建aclvdecChannelDesc类型的数据
285 aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc(); 268 aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();
286 if (vdecChannelDesc == nullptr) { 269 if (vdecChannelDesc == nullptr) {
287 - cout << "aclvdecCreateChannelDesc failed"; 270 + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
288 return; 271 return;
289 } 272 }
290 do{ 273 do{
@@ -301,6 +284,10 @@ void DvppDec::decode_thread(){ @@ -301,6 +284,10 @@ void DvppDec::decode_thread(){
301 bool bBreak = false; 284 bool bBreak = false;
302 while (m_bRunning) 285 while (m_bRunning)
303 { 286 {
  287 + if (m_bPause){
  288 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  289 + continue;
  290 + }
304 int ret = sentFrame(vdecChannelDesc, frame_count); 291 int ret = sentFrame(vdecChannelDesc, frame_count);
305 if(ret == 2){ 292 if(ret == 2){
306 break; 293 break;
@@ -341,7 +328,8 @@ void DvppDec::decode_thread(){ @@ -341,7 +328,8 @@ void DvppDec::decode_thread(){
341 m_bExitReportThd = true; 328 m_bExitReportThd = true;
342 CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed"); 329 CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");
343 330
344 - cout << "decode thread exit." << endl; 331 + releaseResource();
  332 + LOG_INFO("[{}]- decode thread exit.", m_dec_name);
345 } 333 }
346 334
347 int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){ 335 int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){
@@ -349,41 +337,41 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count @@ -349,41 +337,41 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
349 AVPacket * pkt = m_pktQueueptr->getHead(); 337 AVPacket * pkt = m_pktQueueptr->getHead();
350 if(pkt == nullptr){ 338 if(pkt == nullptr){
351 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 339 std::this_thread::sleep_for(std::chrono::milliseconds(10));
352 - // cout << "getTail failed" << endl;  
353 - // continue;  
354 return 1; 340 return 1;
355 } 341 }
356 // 解码 342 // 解码
357 void *vdecInputbuf = m_vdecQueue.getTail(); 343 void *vdecInputbuf = m_vdecQueue.getTail();
358 if(vdecInputbuf == nullptr){ 344 if(vdecInputbuf == nullptr){
359 std::this_thread::sleep_for(std::chrono::milliseconds(3)); 345 std::this_thread::sleep_for(std::chrono::milliseconds(3));
360 - // cout << "getTail failed" << endl;  
361 - // continue;  
362 return 1; 346 return 1;
363 } 347 }
364 348
365 int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); 349 int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
366 if(ACL_ERROR_NONE != ret){ 350 if(ACL_ERROR_NONE != ret){
367 - cout << "aclrtMemcpy failed" << endl;  
368 - // break; 351 + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
369 return 2; 352 return 2;
370 } 353 }
371 354
372 void *vdecOutputBuf = nullptr; 355 void *vdecOutputBuf = nullptr;
373 ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); 356 ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
374 if(ret != ACL_ERROR_NONE){ 357 if(ret != ACL_ERROR_NONE){
375 - cout << "acldvppMalloc failed" << endl;  
376 - // break; 358 + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
377 return 2; 359 return 2;
378 } 360 }
379 361
380 acldvppStreamDesc *input_stream_desc = nullptr; 362 acldvppStreamDesc *input_stream_desc = nullptr;
381 acldvppPicDesc *output_pic_desc = nullptr; 363 acldvppPicDesc *output_pic_desc = nullptr;
382 do{ 364 do{
383 - input_stream_desc = acldvppCreateStreamDesc();  
384 - if (input_stream_desc == nullptr) { cout << "acldvppCreateStreamDesc error" << endl; } 365 + input_stream_desc = acldvppCreateStreamDesc();
  366 + if (input_stream_desc == nullptr) {
  367 + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
  368 + break;
  369 + }
385 output_pic_desc = acldvppCreatePicDesc(); 370 output_pic_desc = acldvppCreatePicDesc();
386 - if (output_pic_desc == nullptr) { cout<< "acldvppCreatePicDesc error" << endl; } 371 + if (output_pic_desc == nullptr) {
  372 + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
  373 + break;
  374 + }
387 CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed"); 375 CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
388 CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed"); 376 CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
389 CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed"); 377 CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
@@ -395,12 +383,13 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count @@ -395,12 +383,13 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
395 // user_data->startTime = startTime; 383 // user_data->startTime = startTime;
396 user_data->sendTime = UtilTools::get_cur_time_ms(); 384 user_data->sendTime = UtilTools::get_cur_time_ms();
397 user_data->self = this; 385 user_data->self = this;
398 -  
399 ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data)); 386 ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
  387 + av_packet_unref(pkt);
  388 + m_pktQueueptr->addHead();
400 if(ret != ACL_ERROR_NONE){ 389 if(ret != ACL_ERROR_NONE){
401 - cout << "aclvdecSendFrame failed" << endl;  
402 - m_pktQueueptr->addHead();  
403 - av_packet_unref(pkt); 390 + delete user_data;
  391 + user_data = nullptr;
  392 + LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
404 break; 393 break;
405 } 394 }
406 395
@@ -409,6 +398,7 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count @@ -409,6 +398,7 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count
409 return 0; 398 return 0;
410 }while (0); 399 }while (0);
411 400
  401 + // 报错情形
412 if(input_stream_desc){ 402 if(input_stream_desc){
413 CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed"); 403 CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
414 } 404 }
src/dvpp/DvppDec.h
@@ -14,7 +14,6 @@ using namespace std; @@ -14,7 +14,6 @@ using namespace std;
14 14
15 #define TEST_DECODER 15 #define TEST_DECODER
16 16
17 -  
18 struct DvppDecConfig{ 17 struct DvppDecConfig{
19 string dec_name; 18 string dec_name;
20 POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 19 POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
@@ -77,4 +76,10 @@ private: @@ -77,4 +76,10 @@ private:
77 VpcPicConverter picConverter; 76 VpcPicConverter picConverter;
78 77
79 int m_vdec_out_size {-1}; 78 int m_vdec_out_size {-1};
  79 +
  80 +#ifdef TEST_DECODER
  81 + void *vdecHostAddr = nullptr;
  82 + int count_frame = 0;
  83 +#endif
  84 +
80 }; 85 };
81 \ No newline at end of file 86 \ No newline at end of file
src/dvpp/DvppDecoder.cpp
1 #include "DvppDecoder.h" 1 #include "DvppDecoder.h"
2 -#include "DvppSourceManager.h"  
3 2
4 -#define CHECK_AND_RETURN(ret, message) \  
5 - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message; return ret;}  
6 -#define CHECK_NOT_RETURN(ret, message) \  
7 - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message;}  
8 -#define CHECK_AND_RETURN_NOVALUE(ret, message) \  
9 - if(ret != 0) {cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", ret: " << ret << ", [ERROR] " << message; return;}  
10 -  
11 -  
12 -  
13 -struct Vdec_CallBack_UserData {  
14 - uint64_t frameId;  
15 - long startTime;  
16 - long sendTime;  
17 - // void* vdecOutputBuf;  
18 - DvppDecoder* self;  
19 - shared_ptr<MemNode> inBufNode;  
20 - Vdec_CallBack_UserData() {  
21 - frameId = 0; 3 +void receiver_finish_cbk(const void* userPtr){
  4 + if(userPtr != nullptr){
  5 + DvppDecoder* self = (DvppDecoder*)userPtr;
  6 + self->taskFinishing();
22 } 7 }
23 -};  
24 -  
25 -  
26 -const int g_pkt_que_size = 10;  
27 -const int g_pkt_size = 1024 * 1024;  
28 -  
29 -#ifdef TEST_DECODER  
30 -void *vdecHostAddr;  
31 -#endif  
32 -  
33 -static long GetCurTimeUs(){  
34 - chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro  
35 - = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());  
36 -  
37 - return tpMicro.time_since_epoch().count();  
38 } 8 }
39 9
40 -DvppDecoder::DvppDecoder()  
41 -{  
42 - // 初始化解码对象  
43 - fmt_ctx = nullptr;  
44 - m_bRunning = false;  
45 -  
46 - stream = nullptr;  
47 - stream_index = -1;  
48 - pix_fmt = AV_PIX_FMT_NONE;  
49 - m_dec_name = "";  
50 -  
51 - m_bPause = false;  
52 - m_bReal = true;  
53 -  
54 - m_decode_thread = 0;  
55 - m_post_decode_thread = 0;  
56 -  
57 - m_bFinished = false;  
58 - m_dec_keyframe = false;  
59 - m_fps = 0.0; 10 +DvppDecoder::DvppDecoder(){
  11 + m_pktQueueptr = new CircularQueue<AVPacket *>();
60 } 12 }
61 13
62 -DvppDecoder::~DvppDecoder()  
63 -{  
64 - m_dec_keyframe = false;  
65 - releaseResource(); 14 +DvppDecoder::~DvppDecoder(){
  15 + delete m_pktQueueptr;
  16 + m_pktQueueptr = nullptr;
66 } 17 }
67 18
68 -bool DvppDecoder::init_FFmpeg(const char* uri, bool force_tcp){  
69 -  
70 -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)  
71 - av_register_all();  
72 -#endif  
73 -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)  
74 - avcodec_register_all();  
75 -#endif  
76 -  
77 - avformat_network_init();  
78 -  
79 - // 打开输入视频文件  
80 - AVDictionary *options = nullptr;  
81 - av_dict_set( &options, "bufsize", "655360", 0 );  
82 - av_dict_set( &options, "rtsp_transport", force_tcp ? "tcp" : "udp", 0 );  
83 - // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s  
84 - av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒  
85 -  
86 - fmt_ctx = avformat_alloc_context();  
87 - const char* input_file = uri;  
88 - if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {  
89 - cout << "Cannot open input file:" << input_file << endl;  
90 - return false;  
91 - }  
92 - av_dump_format(fmt_ctx, 0, input_file, 0);  
93 -  
94 - // 查找流信息  
95 - if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {  
96 - cout << "Cannot find input stream information" << endl;  
97 - return false;  
98 - }  
99 -  
100 - // 查找视频流信息  
101 - AVCodec *decoder = nullptr;  
102 - stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);  
103 - if (stream_index < 0) {  
104 - cout << "Cannot find a video stream in the input file" << endl;  
105 - return false;  
106 - }  
107 - AVCodec *vcodec = avcodec_find_decoder(decoder->id);  
108 -  
109 - AVCodecContext *avctx = avcodec_alloc_context3(vcodec);  
110 - if(avctx == nullptr){  
111 - cout << "alloc AVCodecContext failed." << endl;  
112 - return false;  
113 - }  
114 -  
115 - do{  
116 - // 得到视频流对象  
117 - AVStream* stream = fmt_ctx->streams[stream_index];  
118 - AVCodecParameters *codecpar = stream->codecpar;  
119 - if (avcodec_parameters_to_context(avctx, codecpar) < 0)  
120 - break;  
121 -  
122 - const AVBitStreamFilter * filter = nullptr;  
123 - if(codecpar->codec_id == AV_CODEC_ID_H264){  
124 - // 66:Baseline,77:Main,>=100:High  
125 - if(codecpar->profile == 77){  
126 - enType = H264_MAIN_LEVEL;  
127 - }else if(codecpar->profile < 77){  
128 - enType = H264_BASELINE_LEVEL;  
129 - }else{  
130 - enType = H264_HIGH_LEVEL;  
131 - }  
132 - filter = av_bsf_get_by_name("h264_mp4toannexb");  
133 - }else if(codecpar->codec_id == AV_CODEC_ID_HEVC){  
134 - // h265只有main  
135 - enType = H265_MAIN_LEVEL;  
136 - filter = av_bsf_get_by_name("hevc_mp4toannexb");  
137 - }else {  
138 - cout << "codec_id is not supported!" << endl;  
139 - break;  
140 - }  
141 -  
142 - int ret = av_bsf_alloc(filter, &h264bsfc);  
143 - if (ret < 0){  
144 - break;  
145 - }  
146 -  
147 - avcodec_parameters_copy(h264bsfc->par_in, codecpar);  
148 - av_bsf_init(h264bsfc);  
149 -  
150 - frame_width = codecpar->width;  
151 - frame_height = codecpar->height;  
152 - pix_fmt = (AVPixelFormat)codecpar->format;  
153 - m_fps = av_q2d(stream ->avg_frame_rate);  
154 -  
155 - m_vdec_out_size = frame_width * frame_height * 3 /2;  
156 -  
157 - cout << "frame_width = " << frame_width << " frame_height = " << frame_height << " fps = " << m_fps << " m_vdec_out_size:" << m_vdec_out_size << endl;  
158 -  
159 - cout << "init ffmpeg success!" << endl;  
160 -  
161 - return true;  
162 - }while(0);  
163 -  
164 - avcodec_free_context(&avctx);  
165 -  
166 - return false;  
167 -}  
168 -  
169 -static void *ReportThd(void *arg)  
170 -{  
171 - DvppDecoder *self = (DvppDecoder *)arg;  
172 - if(nullptr != self){  
173 - self->doProcessReport();  
174 - }  
175 - return (void *)0;  
176 -}  
177 -  
178 -void DvppDecoder::doProcessReport(){  
179 - // aclrtContext thdContext = nullptr;  
180 - // CHECK_AND_RETURN_NOVALUE(aclrtCreateContext(&thdContext, m_dvpp_deviceId), "aclrtCreateContext failed");  
181 -  
182 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");  
183 - // 阻塞等待vdec线程开始  
184 -  
185 - int ret;  
186 - while (m_bRunning) {  
187 - ret = aclrtProcessReport(1000);  
188 - if (ret != ACL_ERROR_NONE) {  
189 - cout << "device: " << m_dvpp_deviceId << ", chn: " << m_dvpp_channel << ", aclrtProcessReport failed, ret: " << ret << endl;  
190 - }  
191 - }  
192 -  
193 - // CHECK_AND_RETURN_NOVALUE(aclrtDestroyContext(thdContext), "aclrtDestroyContext failed");  
194 -}  
195 -  
196 -int count_frame = 0;  
197 -long lastts = 0;  
198 -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)  
199 -{  
200 - cout << "VdecCallback: " << GetCurTimeUs() - lastts << endl;  
201 - lastts = GetCurTimeUs();  
202 -  
203 - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;  
204 - DvppDecoder* self = userData->self;  
205 - if(self != nullptr){  
206 -  
207 - self->doVdppVdecCallBack(input, output, self);  
208 - }  
209 -  
210 - delete userData;  
211 - userData = nullptr;  
212 -}  
213 -  
214 -void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, DvppDecoder *self){  
215 -  
216 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");  
217 -  
218 - void *inputDataDev = acldvppGetStreamDescData(input);  
219 - void *outputDataDev = acldvppGetPicDescData(output);  
220 - uint32_t outputSize = acldvppGetPicDescSize(output);  
221 - uint32_t width = acldvppGetPicDescWidth(output);  
222 - uint32_t height = acldvppGetPicDescHeight(output);  
223 -  
224 - cout << "width = " << width << " height = " << height << " data_size:" << outputSize << endl;  
225 -  
226 - if (!m_bPause)  
227 - {  
228 - DeviceRgbMemory* rgbMem = picConverter.convert2bgr(output, width, height, false);  
229 -#ifdef TEST_DECODER  
230 - if(rgbMem != nullptr){  
231 - // D2H  
232 - uint32_t data_size = rgbMem->getSize();  
233 - CHECK_AND_RETURN_NOVALUE(aclrtMemcpy(vdecHostAddr, data_size, rgbMem->getMem(), data_size, ACL_MEMCPY_DEVICE_TO_HOST), "D2H aclrtMemcpy failed");  
234 -  
235 - // 保存vdec结果  
236 - if(count_frame > 45 && count_frame < 50)  
237 - {  
238 - string file_name = "./yuv_pic/vdec_out"+ getName() +".rgb" ;  
239 - FILE *outputFile = fopen(file_name.c_str(), "a");  
240 - if(outputFile){  
241 - fwrite(vdecHostAddr, data_size, sizeof(char), outputFile);  
242 - fclose(outputFile);  
243 - }  
244 - }  
245 - count_frame++;  
246 - }  
247 -#endif  
248 -  
249 - }else{  
250 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
251 - }  
252 -  
253 - cout << "callback acldvppFree." << endl;  
254 -  
255 - acldvppFree((uint8_t*)outputDataDev);  
256 - outputDataDev = nullptr;  
257 -  
258 - m_vdecQueue.addHead();  
259 -  
260 - CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");  
261 - CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");  
262 -  
263 - cout << "callback exit." << endl;  
264 -}  
265 -  
266 -bool DvppDecoder::init_vdpp(int devId){  
267 - cout << "Init device....\n";  
268 - // DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize  
269 - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();  
270 - m_context = pSrcMgr->getContext(m_dvpp_deviceId);  
271 - m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);  
272 - if(m_dvpp_channel < 0){  
273 - cout << "该设备channel已经用完了" << endl;  
274 - return false;  
275 - }  
276 -  
277 - cout << "devProgram start, device: " << m_dvpp_deviceId << endl;  
278 - int ret = aclrtSetCurrentContext(m_context);  
279 - if (ret != ACL_ERROR_NONE) {  
280 - cout << "aclrtSetCurrentContext failed" << endl;  
281 - return false;  
282 - }  
283 -  
284 - // queue_size 最小应大于16,否则关键帧之间距离太远的时候会导致回调函数与循环队列卡死  
285 - for (size_t i = 0; i < 20; i++){  
286 - void *vdecInputbuf = nullptr;  
287 - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size);  
288 - if(ret != ACL_ERROR_NONE){  
289 - cout << "acldvppMalloc failed" << endl;  
290 - return false;;  
291 - }  
292 - m_vec_vdec.push_back(vdecInputbuf);  
293 - }  
294 -  
295 - if(!m_vdecQueue.init(m_vec_vdec)){  
296 - return false;  
297 - }  
298 -  
299 -#ifdef TEST_DECODER  
300 - CHECK_NOT_RETURN(aclrtMallocHost(&vdecHostAddr, frame_width * frame_height * 3), "aclrtMallocHost failed");  
301 -#endif  
302 -  
303 - cout << "init vdpp success!" << endl;  
304 - return true;  
305 -}  
306 -  
307 -bool DvppDecoder::init(FFDecConfig& cfg){  
308 - m_cfg = cfg;  
309 -  
310 - fstream infile(cfg.uri);  
311 - if (infile.is_open()){  
312 - m_bReal = false;  
313 - infile.close();  
314 - }else {  
315 - m_bReal = true;  
316 - }  
317 -  
318 - post_decoded_cbk = cfg.post_decoded_cbk;  
319 - decode_finished_cbk = cfg.decode_finished_cbk;  
320 -  
321 - bool ret = init_FFmpeg(cfg.uri.c_str(), cfg.force_tcp);  
322 - if(!ret){  
323 - return false;  
324 - }  
325 -  
326 - m_dvpp_deviceId = atoi(cfg.gpuid.c_str());  
327 - ret = init_vdpp(m_dvpp_deviceId);  
328 - if (!ret)  
329 - {  
330 - releaseFFmpeg();  
331 - } 19 +bool DvppDecoder::init(FFDecConfig cfg){
332 20
333 - ret = picConverter.init(m_context);  
334 - if(!ret){  
335 - picConverter.release();  
336 - }  
337 -  
338 - return ret;  
339 -}  
340 -  
341 -bool DvppDecoder::start(){  
342 - m_bRunning = true;  
343 -  
344 - pthread_create(&m_decode_thread,0,  
345 - [](void* arg)  
346 - {  
347 - DvppDecoder* a=(DvppDecoder*)arg;  
348 - a->decode_thread();  
349 - return (void*)0;  
350 - }  
351 - ,this);  
352 -  
353 - return true;  
354 -}  
355 -  
356 -void DvppDecoder::close(){  
357 - m_bRunning=false;  
358 -  
359 - if(m_decode_thread != 0){  
360 - pthread_join(m_decode_thread,0);  
361 - }  
362 -  
363 -#ifdef TEST_DECODER  
364 - if(vdecHostAddr != nullptr){  
365 - CHECK_NOT_RETURN(aclrtFreeHost(vdecHostAddr), "aclrtFreeHost failed");  
366 - }  
367 -#endif  
368 -}  
369 -  
370 -bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){  
371 - // create stream desc  
372 - acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();  
373 - if (streamInputDesc == nullptr) {  
374 - cout << "fail to create input stream desc" << endl; 21 + 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);
  30 + if(avctx == nullptr){
375 return false; 31 return false;
376 } 32 }
377 - aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);  
378 - if (ret != ACL_SUCCESS) {  
379 - cout << "fail to set eos for stream desc, errorCode = " << static_cast<int32_t>(ret) << endl;  
380 - (void)acldvppDestroyStreamDesc(streamInputDesc); 33 + m_receiver.setFinishCbkArg(this);
  34 +
  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 {
381 return false; 41 return false;
382 } 42 }
383 -  
384 - // send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.  
385 - ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);  
386 - if (ret != ACL_SUCCESS) {  
387 - cout << "fail to send eos frame, ret=" << ret << endl;  
388 - (void)acldvppDestroyStreamDesc(streamInputDesc); 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);
  53 + if(!bRet){
389 return false; 54 return false;
390 } 55 }
391 - (void)acldvppDestroyStreamDesc(streamInputDesc);  
392 -  
393 - return true;  
394 -}  
395 56
396 -void DvppDecoder::releaseFFmpeg(){  
397 - m_dec_keyframe = false;  
398 - if(h264bsfc){  
399 - av_bsf_free(&h264bsfc);  
400 - h264bsfc = nullptr;  
401 - }  
402 - if (fmt_ctx)  
403 - {  
404 - avformat_close_input(&fmt_ctx);  
405 - fmt_ctx = nullptr;  
406 - }  
407 -} 57 + m_cfg = cfg;
408 58
409 -void DvppDecoder::releaseResource(){  
410 - releaseFFmpeg(); 59 + decode_finished_cbk = cfg.decode_finished_cbk;
411 60
412 - for(int i = 0; i < m_vec_vdec.size(); i++){  
413 - if(m_vec_vdec[i] != nullptr){  
414 - acldvppFree((uint8_t*)m_vec_vdec[i]);  
415 - m_vec_vdec[i] = nullptr;  
416 - }  
417 - }  
418 - m_vec_vdec.clear(); 61 + m_bFinished = false;
419 62
420 - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();  
421 - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel); 63 + return true;
422 } 64 }
423 65
424 -void DvppDecoder::decode_thread(){  
425 -  
426 - int frame_count = 0;  
427 - long startTime = GetCurTimeUs();  
428 -  
429 - int ret = -1;  
430 -  
431 - // dvpp解码参数  
432 - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");  
433 -  
434 - pthread_t report_thread;  
435 - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);  
436 - if(ret != 0){  
437 - cout << "pthread_create failed" << endl;  
438 - return;  
439 - }  
440 -  
441 - // 创建aclvdecChannelDesc类型的数据  
442 - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc();  
443 - if (vdecChannelDesc == nullptr) {  
444 - cout << "aclvdecCreateChannelDesc failed";  
445 - return;  
446 - }  
447 - // 创建 channel dec结构体  
448 - // 通道ID在dvpp层面为0~31  
449 - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");  
450 - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");  
451 - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");  
452 - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed");  
453 - CHECK_AND_RETURN_NOVALUE(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");  
454 - CHECK_AND_RETURN_NOVALUE(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");  
455 -  
456 - AVPacket* pkt ;  
457 - pkt = av_packet_alloc();  
458 - av_init_packet( pkt );  
459 -  
460 - acldvppStreamDesc *input_stream_desc = nullptr;  
461 - acldvppPicDesc *output_pic_desc = nullptr;  
462 -  
463 - void *vdecInputbuf = nullptr;  
464 - void *vdecOutputBuf = nullptr;  
465 - while (m_bRunning)  
466 - {  
467 - if (!m_bReal)  
468 - {  
469 - if (m_bPause)  
470 - {  
471 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
472 - continue;  
473 - }  
474 - }  
475 -  
476 - int result = av_read_frame(fmt_ctx, pkt);  
477 - if (result == AVERROR_EOF || result < 0)  
478 - {  
479 - cout << "Failed to read frame!" << endl;  
480 - break;  
481 - }  
482 -  
483 - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {  
484 - av_packet_unref(pkt);  
485 - continue;  
486 - }  
487 -  
488 - if (stream_index == pkt->stream_index){  
489 -  
490 - ret = av_bsf_send_packet(h264bsfc, pkt);  
491 - if(ret < 0) {  
492 - cout << "av_bsf_send_packet error" << endl;  
493 - }  
494 -  
495 - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {  
496 - // 解码  
497 -  
498 - if(pkt->size > g_pkt_size){  
499 - cout << "pkt size 大于 预设" << endl;  
500 - break;  
501 - }  
502 -  
503 - if(!m_bRunning){  
504 - break;  
505 - }  
506 -  
507 - vdecInputbuf = m_vdecQueue.getTail();  
508 - if(vdecInputbuf == nullptr){  
509 - std::this_thread::sleep_for(std::chrono::milliseconds(3));  
510 - // cout << "getTail failed" << endl;  
511 - continue;  
512 - }  
513 -  
514 - ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);  
515 - if(ACL_ERROR_NONE != ret){  
516 - cout << "aclrtMemcpy failed" << endl;  
517 - goto end_flag;  
518 - }  
519 -  
520 - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);  
521 - if(ret != ACL_ERROR_NONE){  
522 - cout << "acldvppMalloc failed" << endl;  
523 - goto end_flag;  
524 - }  
525 -  
526 - /************ 解码*************/  
527 - input_stream_desc = acldvppCreateStreamDesc();  
528 - if (input_stream_desc == nullptr) { cout << "acldvppCreateStreamDesc error" << endl; }  
529 - output_pic_desc = acldvppCreatePicDesc();  
530 - if (output_pic_desc == nullptr) { cout<< "acldvppCreatePicDesc error" << endl; }  
531 - CHECK_NOT_RETURN(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");  
532 - CHECK_NOT_RETURN(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");  
533 - CHECK_NOT_RETURN(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");  
534 - CHECK_NOT_RETURN(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");  
535 -  
536 - Vdec_CallBack_UserData *user_data = NULL;  
537 - user_data = new Vdec_CallBack_UserData;  
538 - user_data->frameId = frame_count;  
539 - user_data->startTime = startTime;  
540 - user_data->sendTime = GetCurTimeUs();  
541 - user_data->self = this;  
542 - // user_data->inBufNode = bufNode;  
543 - cout << "send frame" << endl;  
544 - CHECK_NOT_RETURN(aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data)),  
545 - "aclvdecSendFrame failed");  
546 -  
547 - frame_count++;  
548 -  
549 - m_vdecQueue.addTail();  
550 -  
551 - vdecInputbuf = nullptr;  
552 - vdecOutputBuf = nullptr;  
553 - }  
554 - /****************************/  
555 - }  
556 - av_packet_unref(pkt);  
557 - }  
558 -  
559 -end_flag:  
560 -  
561 - av_packet_free(&pkt);  
562 -  
563 - sendVdecEos(vdecChannelDesc);  
564 -  
565 - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");  
566 - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");  
567 -  
568 - // report_thread 需后于destroy退出  
569 - m_bRunning = false;  
570 - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed");  
571 -  
572 - if(m_vdecQueue.length() > 0){  
573 - cout << m_vdecQueue.length() << endl;  
574 - }  
575 -  
576 - if(vdecOutputBuf != nullptr){  
577 - acldvppFree((uint8_t*)vdecOutputBuf);  
578 - vdecOutputBuf = nullptr;  
579 - } 66 +bool DvppDecoder::isSurport(FFDecConfig& cfg){
  67 + return true;
  68 +}
580 69
581 - cout << "read thread exit." << endl; 70 +bool DvppDecoder::start(){
  71 + m_receiver.start();
  72 + m_decoder.start();
  73 + return true;
582 } 74 }
583 75
584 -float DvppDecoder::fps(){  
585 - return m_fps; 76 +void DvppDecoder::close(){
  77 + m_receiver.close();
586 } 78 }
587 79
588 -bool DvppDecoder::isSurport(FFDecConfig& cfg){  
589 - bool bRet = init(cfg);  
590 - return bRet; 80 +void DvppDecoder::setPostDecArg(const void* postDecArg){
  81 + m_decoder.setPostDecArg(postDecArg);
591 } 82 }
592 83
593 -bool DvppDecoder::getResolution( int &width, int &height ){  
594 - width = frame_width;  
595 - height = frame_height;  
596 - return true; 84 +void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){
  85 + m_finishedDecArg = finishedDecArg;
597 } 86 }
598 87
599 void DvppDecoder::pause(){ 88 void DvppDecoder::pause(){
600 - m_bPause = true; 89 + m_receiver.pause();
601 } 90 }
602 91
603 void DvppDecoder::resume(){ 92 void DvppDecoder::resume(){
604 - m_bPause = false; 93 + m_receiver.resume();
605 } 94 }
606 95
607 -void DvppDecoder::setDecKeyframe(bool bKeyframe)  
608 -{  
609 - m_dec_keyframe = bKeyframe; 96 +void DvppDecoder::setDecKeyframe(bool bKeyframe){
  97 + m_receiver.setDecKeyframe(bKeyframe);
610 } 98 }
611 99
612 bool DvppDecoder::isRunning(){ 100 bool DvppDecoder::isRunning(){
613 - return m_bRunning; 101 + return m_receiver.isRunning();
614 } 102 }
615 103
616 bool DvppDecoder::isFinished(){ 104 bool DvppDecoder::isFinished(){
617 - return m_bFinished; 105 + return m_bFinished;
618 } 106 }
619 107
620 bool DvppDecoder::isPausing(){ 108 bool DvppDecoder::isPausing(){
621 - return m_bPause; 109 + return m_receiver.isPausing();
622 } 110 }
623 111
624 -int DvppDecoder::getCachedQueueLength(){  
625 - // TODO  
626 - return 0; 112 +bool DvppDecoder::getResolution(int &width, int &height){
  113 + return m_receiver.getResolution(width, height);
  114 +}
  115 +
  116 +float DvppDecoder::fps(){
  117 + return m_receiver.fps();
627 } 118 }
628 119
629 FFImgInfo* DvppDecoder::snapshot(){ 120 FFImgInfo* DvppDecoder::snapshot(){
@@ -631,10 +122,16 @@ FFImgInfo* DvppDecoder::snapshot(){ @@ -631,10 +122,16 @@ FFImgInfo* DvppDecoder::snapshot(){
631 return nullptr; 122 return nullptr;
632 } 123 }
633 124
634 -void DvppDecoder::setPostDecArg(const void* postDecArg){  
635 - m_postDecArg = postDecArg; 125 +int DvppDecoder::getCachedQueueLength(){
  126 + return 0;
636 } 127 }
637 128
638 -void DvppDecoder::setFinishedDecArg(const void* finishedDecArg){  
639 - m_finishedDecArg = finishedDecArg; 129 +void DvppDecoder::taskFinishing(){
  130 + // receiver 中读取线程结束时执行
  131 + m_decoder.close();
  132 + decode_finished_cbk(m_finishedDecArg);
  133 +
  134 + m_bFinished = true;
  135 +
  136 + LOG_INFO("[{}]- task finished.", m_dec_name);
640 } 137 }
641 \ No newline at end of file 138 \ No newline at end of file
src/dvpp/DvppDecoder.h
1 #include<string> 1 #include<string>
2 -#include <pthread.h>  
3 2
4 -#include "dvpp_headers.h"  
5 #include "depend_headers.h" 3 #include "depend_headers.h"
6 -#include "user_mem.h"  
7 #include "CircularQueue.hpp" 4 #include "CircularQueue.hpp"
8 -#include "VpcPicConverter.h"  
9 -  
10 -#include <queue> 5 +#include "FFReceiver.h"
  6 +#include "DvppDec.h"
11 7
12 using namespace std; 8 using namespace std;
13 9
14 -#define TEST_DECODER  
15 -  
16 -  
17 class DvppDecoder{ 10 class DvppDecoder{
18 public: 11 public:
19 DvppDecoder(); 12 DvppDecoder();
20 ~DvppDecoder(); 13 ~DvppDecoder();
21 - bool init(FFDecConfig& cfg); 14 + bool init(FFDecConfig cfg);
22 void close(); 15 void close();
23 bool start(); 16 bool start();
24 void pause(); 17 void pause();
@@ -33,12 +26,8 @@ public: @@ -33,12 +26,8 @@ public:
33 26
34 bool isSurport(FFDecConfig& cfg); 27 bool isSurport(FFDecConfig& cfg);
35 28
36 - int getCachedQueueLength();  
37 -  
38 float fps(); 29 float fps();
39 30
40 - DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP; }  
41 -  
42 void setName(string nm){ 31 void setName(string nm){
43 m_dec_name = nm; 32 m_dec_name = nm;
44 } 33 }
@@ -52,60 +41,22 @@ public: @@ -52,60 +41,22 @@ public:
52 void setPostDecArg(const void* postDecArg); 41 void setPostDecArg(const void* postDecArg);
53 void setFinishedDecArg(const void* finishedDecArg); 42 void setFinishedDecArg(const void* finishedDecArg);
54 43
55 -public:  
56 - void doProcessReport();  
57 - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, DvppDecoder *self);  
58 -  
59 -private:  
60 - void decode_thread();  
61 - void post_decode_thread();  
62 - void releaseFFmpeg();  
63 - void releaseResource();  
64 - bool init_FFmpeg(const char* uri, bool force_tcp);  
65 - bool init_vdpp(int _deviceId); 44 + int getCachedQueueLength();
66 45
67 - bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc); 46 +public:
  47 + void taskFinishing();
68 48
69 private: 49 private:
70 - AVStream* stream;  
71 - int stream_index;  
72 - AVFormatContext *fmt_ctx;  
73 - AVPixelFormat pix_fmt;  
74 - uint32_t m_vdec_out_size{0};  
75 - int frame_width{0};  
76 - int frame_height{0};  
77 -  
78 - int m_dvpp_deviceId {-1};  
79 - int m_dvpp_channel {-1};  
80 -  
81 - pthread_t m_decode_thread;  
82 - pthread_t m_post_decode_thread;  
83 -  
84 - bool m_bRunning;  
85 - bool m_bFinished;  
86 -  
87 - bool m_bPause;  
88 -  
89 - bool m_bReal; // 是否实时流  
90 -  
91 - float m_fps;  
92 -  
93 FFDecConfig m_cfg; 50 FFDecConfig m_cfg;
94 string m_dec_name; 51 string m_dec_name;
95 - bool m_dec_keyframe;  
96 -  
97 - AVBSFContext * h264bsfc{nullptr};  
98 52
99 - aclrtContext m_context;  
100 - acldvppStreamFormat enType; 53 + CircularQueue<AVPacket *> *m_pktQueueptr;
  54 + FFReceiver m_receiver;
  55 + DvppDec m_decoder;
101 56
102 - vector<void*> m_vec_vdec;  
103 - CircularQueue<void *> m_vdecQueue;  
104 -  
105 - const void * m_postDecArg;  
106 - POST_DECODE_CALLBACK post_decoded_cbk;  
107 const void * m_finishedDecArg; 57 const void * m_finishedDecArg;
108 DECODE_FINISHED_CALLBACK decode_finished_cbk; 58 DECODE_FINISHED_CALLBACK decode_finished_cbk;
109 59
110 - VpcPicConverter picConverter; 60 + bool m_bFinished{false};
  61 +
111 }; 62 };
112 \ No newline at end of file 63 \ No newline at end of file
src/dvpp/DvppDecoder2.h deleted
1 -#include<string>  
2 -  
3 -#include "depend_headers.h"  
4 -#include "CircularQueue.hpp"  
5 -#include "FFReceiver.h"  
6 -#include "DvppDec.h"  
7 -  
8 -using namespace std;  
9 -  
10 -class DvppDecoder2{  
11 -public:  
12 - DvppDecoder2();  
13 - ~DvppDecoder2();  
14 - bool init(FFDecConfig cfg);  
15 - void close();  
16 - bool start();  
17 - void pause();  
18 - void resume();  
19 -  
20 - void setDecKeyframe(bool bKeyframe);  
21 -  
22 - bool isRunning();  
23 - bool isFinished();  
24 - bool isPausing();  
25 - bool getResolution( int &width, int &height );  
26 -  
27 - bool isSurport(FFDecConfig& cfg);  
28 -  
29 - float fps();  
30 -  
31 - void setName(string nm){  
32 - m_dec_name = nm;  
33 - }  
34 -  
35 - string getName(){  
36 - return m_dec_name;  
37 - }  
38 -  
39 - FFImgInfo* snapshot();  
40 -  
41 - void setPostDecArg(const void* postDecArg);  
42 - void setFinishedDecArg(const void* finishedDecArg);  
43 -  
44 - int getCachedQueueLength();  
45 -  
46 -public:  
47 - void taskFinishing();  
48 -  
49 -private:  
50 -  
51 - FFDecConfig m_cfg;  
52 - string m_dec_name;  
53 -  
54 - CircularQueue<AVPacket *> *m_pktQueueptr;  
55 - FFReceiver m_receiver;  
56 - DvppDec m_decoder;  
57 -  
58 - const void * m_finishedDecArg;  
59 - DECODE_FINISHED_CALLBACK decode_finished_cbk;  
60 -  
61 -};  
62 -  
63 -void receiver_finish_cbk(const void* userPtr){  
64 - if(userPtr != nullptr){  
65 - DvppDecoder2* self = (DvppDecoder2*)userPtr;  
66 - self->taskFinishing();  
67 - }  
68 -}  
69 -  
70 -DvppDecoder2::DvppDecoder2(){  
71 - m_pktQueueptr = new CircularQueue<AVPacket *>();  
72 -}  
73 -  
74 -DvppDecoder2::~DvppDecoder2(){  
75 - delete m_pktQueueptr;  
76 - m_pktQueueptr = nullptr;  
77 -}  
78 -  
79 -bool DvppDecoder2::init(FFDecConfig cfg){  
80 -  
81 - ReceiverConfig receiver_config;  
82 - receiver_config.uri = cfg.uri.c_str();  
83 - receiver_config.dec_name = cfg.dec_name;  
84 - receiver_config.force_tcp = cfg.force_tcp;  
85 - receiver_config.pktQueueptr = m_pktQueueptr;  
86 - receiver_config.receiver_finished_cbk = receiver_finish_cbk;  
87 - AVCodecContext* avctx = m_receiver.init_FFmpeg(receiver_config);  
88 - if(avctx == nullptr){  
89 - return false;  
90 - }  
91 - m_receiver.setFinishCbkArg(this);  
92 -  
93 - DvppDecConfig dec_cfg;  
94 - if(avctx->codec_id == AV_CODEC_ID_H264){  
95 - dec_cfg.codec_id = 0;  
96 - }else if(avctx->codec_id == AV_CODEC_ID_HEVC){  
97 - dec_cfg.codec_id = 1;  
98 - }else {  
99 - return false;  
100 - }  
101 - dec_cfg.dec_name = cfg.dec_name;  
102 - dec_cfg.post_decoded_cbk = cfg.post_decoded_cbk;  
103 - dec_cfg.dev_id = cfg.gpuid;  
104 - dec_cfg.force_tcp = cfg.force_tcp;  
105 - dec_cfg.skip_frame = cfg.skip_frame;  
106 - dec_cfg.profile = avctx->profile;  
107 - dec_cfg.pktQueueptr = m_pktQueueptr;  
108 - dec_cfg.width = avctx->width;  
109 - dec_cfg.height = avctx->height;  
110 - bool bRet = m_decoder.init_vdpp(dec_cfg);  
111 - if(!bRet){  
112 - return false;  
113 - }  
114 -  
115 - m_cfg = cfg;  
116 -  
117 - decode_finished_cbk = cfg.decode_finished_cbk;  
118 -  
119 - return true;  
120 -}  
121 -  
122 -bool DvppDecoder2::isSurport(FFDecConfig& cfg){  
123 - return true;  
124 -}  
125 -  
126 -bool DvppDecoder2::start(){  
127 - m_receiver.start();  
128 - m_decoder.start();  
129 - return true;  
130 -}  
131 -  
132 -void DvppDecoder2::close(){  
133 - m_receiver.close();  
134 -}  
135 -  
136 -void DvppDecoder2::setPostDecArg(const void* postDecArg){  
137 - m_decoder.setPostDecArg(postDecArg);  
138 -}  
139 -  
140 -void DvppDecoder2::setFinishedDecArg(const void* finishedDecArg){  
141 - m_finishedDecArg = finishedDecArg;  
142 -}  
143 -  
144 -void DvppDecoder2::pause(){  
145 - m_receiver.pause();  
146 -}  
147 -  
148 -void DvppDecoder2::resume(){  
149 - m_receiver.resume();  
150 -}  
151 -  
152 -void DvppDecoder2::setDecKeyframe(bool bKeyframe){  
153 - m_receiver.setDecKeyframe(bKeyframe);  
154 -}  
155 -  
156 -bool DvppDecoder2::isRunning(){  
157 - return m_receiver.isRunning();  
158 -}  
159 -  
160 -bool DvppDecoder2::isFinished(){  
161 - return m_receiver.isFinished();  
162 -}  
163 -  
164 -bool DvppDecoder2::isPausing(){  
165 - return m_receiver.isPausing();  
166 -}  
167 -  
168 -bool DvppDecoder2::getResolution(int &width, int &height){  
169 - return m_receiver.getResolution(width, height);  
170 -}  
171 -  
172 -float DvppDecoder2::fps(){  
173 - return m_receiver.fps();  
174 -}  
175 -  
176 -FFImgInfo* DvppDecoder2::snapshot(){  
177 - // TODO  
178 - return nullptr;  
179 -}  
180 -  
181 -int DvppDecoder2::getCachedQueueLength(){  
182 - return 0;  
183 -}  
184 -  
185 -void DvppDecoder2::taskFinishing(){  
186 - // receiver 中读取线程结束时执行  
187 - m_decoder.close();  
188 - decode_finished_cbk(m_finishedDecArg);  
189 -  
190 - LOG_INFO("[{}]- task finished.", m_dec_name);  
191 -  
192 -}  
193 \ No newline at end of file 0 \ No newline at end of file
src/dvpp/DvppDecoderApi.cpp
1 #include "DvppDecoderApi.h" 1 #include "DvppDecoderApi.h"
2 -#include "DvppDecoder2.h" 2 +#include "DvppDecoder.h"
3 3
4 DvppDecoderApi::DvppDecoderApi(){ 4 DvppDecoderApi::DvppDecoderApi(){
5 m_pDecoder = nullptr; 5 m_pDecoder = nullptr;
@@ -13,7 +13,7 @@ DvppDecoderApi::~DvppDecoderApi(){ @@ -13,7 +13,7 @@ DvppDecoderApi::~DvppDecoderApi(){
13 } 13 }
14 14
15 bool DvppDecoderApi::init(FFDecConfig& cfg){ 15 bool DvppDecoderApi::init(FFDecConfig& cfg){
16 - m_pDecoder = new DvppDecoder2(); 16 + m_pDecoder = new DvppDecoder();
17 if(m_pDecoder != nullptr){ 17 if(m_pDecoder != nullptr){
18 return m_pDecoder->init(cfg); 18 return m_pDecoder->init(cfg);
19 } 19 }
src/dvpp/DvppDecoderApi.h
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 6
7 using namespace std; 7 using namespace std;
8 8
9 -class DvppDecoder2; 9 +class DvppDecoder;
10 10
11 class DvppDecoderApi : public AbstractDecoder{ 11 class DvppDecoderApi : public AbstractDecoder{
12 public: 12 public:
@@ -40,5 +40,5 @@ public: @@ -40,5 +40,5 @@ public:
40 void setPostDecArg(const void* postDecArg); 40 void setPostDecArg(const void* postDecArg);
41 void setFinishedDecArg(const void* finishedDecArg); 41 void setFinishedDecArg(const void* finishedDecArg);
42 private: 42 private:
43 - DvppDecoder2* m_pDecoder; 43 + DvppDecoder* m_pDecoder;
44 }; 44 };
45 \ No newline at end of file 45 \ No newline at end of file
src/dvpp/DvppSourceManager.cpp
@@ -59,5 +59,8 @@ int DvppSourceManager::getChannel(int devId){ @@ -59,5 +59,8 @@ int DvppSourceManager::getChannel(int devId){
59 59
60 void DvppSourceManager::releaseChannel(int devId, int iChannel){ 60 void DvppSourceManager::releaseChannel(int devId, int iChannel){
61 string channelKey = "channel_" + to_string(devId) + "_" + to_string(iChannel) ; 61 string channelKey = "channel_" + to_string(devId) + "_" + to_string(iChannel) ;
62 - channelMap.erase(channelKey); 62 + auto it = channelMap.find(channelKey);
  63 + if(it != channelMap.end()){
  64 + channelMap.erase(channelKey);
  65 + }
63 } 66 }
64 \ No newline at end of file 67 \ No newline at end of file
src/dvpp/FFReceiver.cpp
@@ -26,6 +26,12 @@ FFReceiver::FFReceiver(/* args */) @@ -26,6 +26,12 @@ FFReceiver::FFReceiver(/* args */)
26 FFReceiver::~FFReceiver() 26 FFReceiver::~FFReceiver()
27 { 27 {
28 releaseFFmpeg(); 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 + }
29 } 35 }
30 36
31 AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){ 37 AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){
@@ -131,8 +137,6 @@ AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){ @@ -131,8 +137,6 @@ AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){
131 137
132 LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name); 138 LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name);
133 139
134 - releaseFFmpeg();  
135 -  
136 return nullptr; 140 return nullptr;
137 } 141 }
138 142
@@ -150,10 +154,6 @@ void FFReceiver::releaseFFmpeg(){ @@ -150,10 +154,6 @@ void FFReceiver::releaseFFmpeg(){
150 avcodec_free_context(&avctx); 154 avcodec_free_context(&avctx);
151 avctx = nullptr; 155 avctx = nullptr;
152 } 156 }
153 -  
154 - for(int i = 0; i < m_vec_pkt.size(); i++){  
155 - av_packet_free(&m_vec_pkt[i]);  
156 - }  
157 } 157 }
158 158
159 void FFReceiver::read_thread(){ 159 void FFReceiver::read_thread(){
@@ -214,6 +214,7 @@ void FFReceiver::read_thread(){ @@ -214,6 +214,7 @@ void FFReceiver::read_thread(){
214 } 214 }
215 215
216 LOG_INFO("[{}]- read thread exit.", m_dec_name); 216 LOG_INFO("[{}]- read thread exit.", m_dec_name);
  217 + m_bFinished = true;
217 218
218 receiver_finished_cbk(m_finishedReceiveArg); 219 receiver_finished_cbk(m_finishedReceiveArg);
219 } 220 }
src/dvpp/VpcPicConverter.cpp
@@ -3,35 +3,40 @@ @@ -3,35 +3,40 @@
3 3
4 #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align))) 4 #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align)))
5 5
6 -bool VpcPicConverter::init(aclrtContext context){ 6 +VpcPicConverter::VpcPicConverter(){
7 7
8 - aclrtSetCurrentContext(context);  
9 - aclrtCreateStream(&stream_);  
10 -  
11 - // 3. 创建图片数据处理通道时的通道描述信息,dvppChannelDesc_是acldvppChannelDesc类型  
12 - dvppChannelDesc_ = acldvppCreateChannelDesc(); 8 +}
13 9
14 - // 4. 创建图片数据处理的通道。  
15 - int ret = acldvppCreateChannel(dvppChannelDesc_);  
16 - if(ret != ACL_ERROR_NONE){  
17 - LOG_ERROR("acldvppCreateChannel failed !");  
18 - return false; 10 +VpcPicConverter::~VpcPicConverter(){
  11 + if(nullptr == stream_){
  12 + aclrtDestroyStream(stream_);
19 } 13 }
  14 +}
20 15
21 - ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);  
22 - if(ret != ACL_ERROR_NONE){  
23 - LOG_ERROR("acldvppSetChannelDescMode failed !");  
24 - return false;  
25 - } 16 +int VpcPicConverter::init(aclrtContext context, string dec_name){
  17 +
  18 + m_dec_name = dec_name;
  19 +
  20 + CHECK_AND_RETURN(aclrtSetCurrentContext(context), "aclrtSetCurrentContext failed");
  21 + CHECK_AND_RETURN(aclrtCreateStream(&stream_), "aclrtCreateStream failed! ");
26 22
27 - return true; 23 + dvppChannelDesc_ = acldvppCreateChannelDesc();
  24 +
  25 + int ret = ACL_ERROR_NONE;
  26 + do
  27 + {
  28 + ret = acldvppCreateChannel(dvppChannelDesc_);
  29 + CHECK_AND_BREAK(ret, "acldvppCreateChannel failed !");
  30 +
  31 + ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC);
  32 + CHECK_AND_BREAK(ret, "acldvppSetChannelDescMode failed !");
  33 + } while (0);
  34 +
  35 + return ret;
28 } 36 }
29 37
30 DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){ 38 DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){
31 39
32 - // 8. 创建色域转换的输出图片的描述信息,并设置各属性值, 输出的宽和高要求和输入一致  
33 - // 如果色域转换的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致  
34 - // outputDesc_是acldvppPicDesc类型  
35 int out_buf_width = ALIGN_UP(out_width, 16) * 3; 40 int out_buf_width = ALIGN_UP(out_width, 16) * 3;
36 int out_buf_height = ALIGN_UP(out_height, 2); 41 int out_buf_height = ALIGN_UP(out_height, 2);
37 int out_buf_size = out_buf_width * out_buf_height; 42 int out_buf_size = out_buf_width * out_buf_height;
@@ -48,8 +53,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ @@ -48,8 +53,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
48 acldvppSetPicDescHeightStride(outputDesc_, out_buf_height); 53 acldvppSetPicDescHeightStride(outputDesc_, out_buf_height);
49 acldvppSetPicDescSize(outputDesc_, out_buf_size); 54 acldvppSetPicDescSize(outputDesc_, out_buf_size);
50 55
51 -  
52 -  
53 aclError ret = ACL_ERROR_NONE; 56 aclError ret = ACL_ERROR_NONE;
54 do{ 57 do{
55 // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 58 // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成
@@ -65,8 +68,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ @@ -65,8 +68,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
65 } 68 }
66 }while(0); 69 }while(0);
67 70
68 - // 10. 色域转换结束后,释放资源,包括输入/输出图片的描述信息、输入/输出内存  
69 - // acldvppDestroyPicDesc(inputDesc_);  
70 acldvppDestroyPicDesc(outputDesc_); 71 acldvppDestroyPicDesc(outputDesc_);
71 72
72 if(ret != ACL_ERROR_NONE){ 73 if(ret != ACL_ERROR_NONE){
@@ -75,9 +76,4 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ @@ -75,9 +76,4 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_
75 } 76 }
76 77
77 return rgbMem; 78 return rgbMem;
78 -}  
79 -  
80 -void VpcPicConverter::release(){  
81 - aclrtDestroyStream(stream_);  
82 - // aclrtDestroyContext(context_);  
83 } 79 }
84 \ No newline at end of file 80 \ No newline at end of file
src/dvpp/VpcPicConverter.h
@@ -5,15 +5,16 @@ @@ -5,15 +5,16 @@
5 5
6 class VpcPicConverter{ 6 class VpcPicConverter{
7 public: 7 public:
8 - bool init(aclrtContext context); 8 + VpcPicConverter();
  9 + ~VpcPicConverter();
  10 + int init(aclrtContext context, string dec_name);
9 11
10 DvppRgbMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame); 12 DvppRgbMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame);
11 13
12 - void release();  
13 -  
14 private: 14 private:
15 aclrtContext context_; 15 aclrtContext context_;
16 aclrtStream stream_; 16 aclrtStream stream_;
17 int m_devId; 17 int m_devId;
18 acldvppChannelDesc *dvppChannelDesc_ ; 18 acldvppChannelDesc *dvppChannelDesc_ ;
  19 + string m_dec_name;
19 }; 20 };
20 \ No newline at end of file 21 \ No newline at end of file
src/dvpp/dvpp_headers.h
@@ -27,5 +27,14 @@ @@ -27,5 +27,14 @@
27 #include "acl/ops/acl_dvpp.h" 27 #include "acl/ops/acl_dvpp.h"
28 28
29 29
  30 +#define CHECK_AND_RETURN(ret, message) \
  31 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;}
  32 +#define CHECK_NOT_RETURN(ret, message) \
  33 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
  34 +#define CHECK_AND_RETURN_NOVALUE(ret, message) \
  35 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
  36 +#define CHECK_AND_BREAK(ret, message) \
  37 + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
  38 +
30 #endif 39 #endif
31 40
src/interface/FFNvDecoderManager.cpp
@@ -52,10 +52,10 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){ @@ -52,10 +52,10 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){
52 return nullptr; 52 return nullptr;
53 } 53 }
54 54
  55 + config.cfg.dec_name = config.name;
55 bool bRet= dec->init(config.cfg); 56 bool bRet= dec->init(config.cfg);
56 if (bRet) 57 if (bRet)
57 { 58 {
58 - dec->setName(config.name) ;  
59 decoderMap[config.name] = dec; 59 decoderMap[config.name] = dec;
60 60
61 LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri); 61 LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri);