Commit d248da62fff59e75b5da6d00f1cb2c727fc737ff
1 parent
207d694c
优化代码,修正dvpp的一些bug
Showing
14 changed files
with
272 additions
and
1013 deletions
src/demo/main_dvpp.cpp
... | ... | @@ -91,23 +91,11 @@ void postDecoded(const void * userPtr, DeviceRgbMemory* devFrame){ |
91 | 91 | AbstractDecoder* decoder = (AbstractDecoder*)userPtr; |
92 | 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 | 157 | // string test_uri = "rtsp://176.10.0.2:8554/stream"; |
170 | 158 | // string test_uri = "/mnt/f/fiss/test_data/h265.mp4"; |
171 | 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 | 163 | void createDecode(int index, const char* gpu_id){ |
175 | 164 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
... | ... | @@ -241,6 +230,7 @@ void createDvppDecoder(int index, char* devId, int channelId){ |
241 | 230 | AbstractDecoder* decoder = pDecManager->createDecoder(config); |
242 | 231 | if (!decoder) |
243 | 232 | { |
233 | + cout << "创建解码器失败" << endl; | |
244 | 234 | return ; |
245 | 235 | } |
246 | 236 | pDecManager->setPostDecArg(config.name, decoder); |
... | ... | @@ -256,7 +246,7 @@ void logFF(void *, int level, const char *fmt, va_list ap) |
256 | 246 | |
257 | 247 | int main(int argc, char* argv[]){ |
258 | 248 | |
259 | - test_uri = argv[1]; | |
249 | + // test_uri = argv[1]; | |
260 | 250 | char* gpuid = argv[2]; |
261 | 251 | int port = atoi(argv[3]); |
262 | 252 | cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl; |
... | ... | @@ -272,7 +262,7 @@ int main(int argc, char* argv[]){ |
272 | 262 | // cudaSetDevice(atoi(gpuid)); |
273 | 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 | 266 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |
277 | 267 | int count = pDecManager->count(); |
278 | 268 | cout << "当前时间:" << UtilTools::get_cur_time_ms() << " 当前运行路数: " << pDecManager->count() << endl; |
... | ... | @@ -288,6 +278,14 @@ int main(int argc, char* argv[]){ |
288 | 278 | |
289 | 279 | createDvppDecoder(i, gpuid, 0); |
290 | 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 | 290 | while (true) |
293 | 291 | { | ... | ... |
src/dvpp/DvppDec.cpp
1 | 1 | #include "DvppDec.h" |
2 | 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 | 4 | struct Vdec_CallBack_UserData { |
14 | 5 | uint64_t frameId; |
15 | 6 | long startTime; |
... | ... | @@ -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 | 16 | static const int g_pkt_size = 1024 * 1024; |
30 | 17 | |
31 | 18 | DvppDec::DvppDec(){ |
... | ... | @@ -33,11 +20,14 @@ static const int g_pkt_size = 1024 * 1024; |
33 | 20 | } |
34 | 21 | |
35 | 22 | DvppDec::~DvppDec(){ |
36 | - | |
23 | + releaseResource(); | |
37 | 24 | } |
38 | 25 | |
39 | 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 | 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 | 44 | // h265只有main |
55 | 45 | enType = H265_MAIN_LEVEL; |
56 | 46 | }else { |
57 | - cout << "codec_id is not supported!" << endl; | |
47 | + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name); | |
58 | 48 | return false; |
59 | 49 | } |
60 | 50 | |
... | ... | @@ -66,42 +56,47 @@ static const int g_pkt_size = 1024 * 1024; |
66 | 56 | m_context = pSrcMgr->getContext(m_dvpp_deviceId); |
67 | 57 | m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId); |
68 | 58 | if(m_dvpp_channel < 0){ |
69 | - cout << "该设备channel已经用完了" << endl; | |
59 | + LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name); | |
70 | 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 | 102 | bool DvppDec::start(){ |
... | ... | @@ -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 | 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 | 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 | 151 | void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){ |
... | ... | @@ -166,43 +157,38 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu |
166 | 157 | uint32_t outputSize = acldvppGetPicDescSize(output); |
167 | 158 | uint32_t width = acldvppGetPicDescWidth(output); |
168 | 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 | 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 | 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 | 193 | acldvppFree((uint8_t*)outputDataDev); |
208 | 194 | outputDataDev = nullptr; |
... | ... | @@ -211,8 +197,6 @@ void DvppDec::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *outpu |
211 | 197 | |
212 | 198 | CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed"); |
213 | 199 | CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed"); |
214 | - | |
215 | - cout << "callback exit." << endl; | |
216 | 200 | } |
217 | 201 | |
218 | 202 | void DvppDec::close(){ |
... | ... | @@ -227,21 +211,21 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){ |
227 | 211 | // create stream desc |
228 | 212 | acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc(); |
229 | 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 | 215 | return false; |
232 | 216 | } |
233 | 217 | aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1); |
234 | 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 | 220 | (void)acldvppDestroyStreamDesc(streamInputDesc); |
237 | 221 | return false; |
238 | 222 | } |
239 | 223 | |
240 | 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 | 226 | ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr); |
243 | 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 | 229 | (void)acldvppDestroyStreamDesc(streamInputDesc); |
246 | 230 | return false; |
247 | 231 | } |
... | ... | @@ -251,7 +235,6 @@ bool DvppDec::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc){ |
251 | 235 | } |
252 | 236 | |
253 | 237 | void DvppDec::releaseResource(){ |
254 | - | |
255 | 238 | for(int i = 0; i < m_vec_vdec.size(); i++){ |
256 | 239 | if(m_vec_vdec[i] != nullptr){ |
257 | 240 | acldvppFree(m_vec_vdec[i]); |
... | ... | @@ -277,14 +260,14 @@ void DvppDec::decode_thread(){ |
277 | 260 | pthread_t report_thread; |
278 | 261 | ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this); |
279 | 262 | if(ret != 0){ |
280 | - cout << "pthread_create failed" << endl; | |
263 | + LOG_ERROR("[{}]- pthread_create failed", m_dec_name); | |
281 | 264 | return; |
282 | 265 | } |
283 | 266 | |
284 | 267 | // 创建aclvdecChannelDesc类型的数据 |
285 | 268 | aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc(); |
286 | 269 | if (vdecChannelDesc == nullptr) { |
287 | - cout << "aclvdecCreateChannelDesc failed"; | |
270 | + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name); | |
288 | 271 | return; |
289 | 272 | } |
290 | 273 | do{ |
... | ... | @@ -301,6 +284,10 @@ void DvppDec::decode_thread(){ |
301 | 284 | bool bBreak = false; |
302 | 285 | while (m_bRunning) |
303 | 286 | { |
287 | + if (m_bPause){ | |
288 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); | |
289 | + continue; | |
290 | + } | |
304 | 291 | int ret = sentFrame(vdecChannelDesc, frame_count); |
305 | 292 | if(ret == 2){ |
306 | 293 | break; |
... | ... | @@ -341,7 +328,8 @@ void DvppDec::decode_thread(){ |
341 | 328 | m_bExitReportThd = true; |
342 | 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 | 335 | int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){ |
... | ... | @@ -349,41 +337,41 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count |
349 | 337 | AVPacket * pkt = m_pktQueueptr->getHead(); |
350 | 338 | if(pkt == nullptr){ |
351 | 339 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
352 | - // cout << "getTail failed" << endl; | |
353 | - // continue; | |
354 | 340 | return 1; |
355 | 341 | } |
356 | 342 | // 解码 |
357 | 343 | void *vdecInputbuf = m_vdecQueue.getTail(); |
358 | 344 | if(vdecInputbuf == nullptr){ |
359 | 345 | std::this_thread::sleep_for(std::chrono::milliseconds(3)); |
360 | - // cout << "getTail failed" << endl; | |
361 | - // continue; | |
362 | 346 | return 1; |
363 | 347 | } |
364 | 348 | |
365 | 349 | int ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); |
366 | 350 | if(ACL_ERROR_NONE != ret){ |
367 | - cout << "aclrtMemcpy failed" << endl; | |
368 | - // break; | |
351 | + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name); | |
369 | 352 | return 2; |
370 | 353 | } |
371 | 354 | |
372 | 355 | void *vdecOutputBuf = nullptr; |
373 | 356 | ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); |
374 | 357 | if(ret != ACL_ERROR_NONE){ |
375 | - cout << "acldvppMalloc failed" << endl; | |
376 | - // break; | |
358 | + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); | |
377 | 359 | return 2; |
378 | 360 | } |
379 | 361 | |
380 | 362 | acldvppStreamDesc *input_stream_desc = nullptr; |
381 | 363 | acldvppPicDesc *output_pic_desc = nullptr; |
382 | 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 | 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 | 375 | CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed"); |
388 | 376 | CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed"); |
389 | 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 | 383 | // user_data->startTime = startTime; |
396 | 384 | user_data->sendTime = UtilTools::get_cur_time_ms(); |
397 | 385 | user_data->self = this; |
398 | - | |
399 | 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 | 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 | 393 | break; |
405 | 394 | } |
406 | 395 | |
... | ... | @@ -409,6 +398,7 @@ int DvppDec::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count |
409 | 398 | return 0; |
410 | 399 | }while (0); |
411 | 400 | |
401 | + // 报错情形 | |
412 | 402 | if(input_stream_desc){ |
413 | 403 | CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed"); |
414 | 404 | } | ... | ... |
src/dvpp/DvppDec.h
... | ... | @@ -14,7 +14,6 @@ using namespace std; |
14 | 14 | |
15 | 15 | #define TEST_DECODER |
16 | 16 | |
17 | - | |
18 | 17 | struct DvppDecConfig{ |
19 | 18 | string dec_name; |
20 | 19 | POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 |
... | ... | @@ -77,4 +76,10 @@ private: |
77 | 76 | VpcPicConverter picConverter; |
78 | 77 | |
79 | 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 | 86 | \ No newline at end of file | ... | ... |
src/dvpp/DvppDecoder.cpp
1 | 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 | 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 | 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 | 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 | 88 | void DvppDecoder::pause(){ |
600 | - m_bPause = true; | |
89 | + m_receiver.pause(); | |
601 | 90 | } |
602 | 91 | |
603 | 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 | 100 | bool DvppDecoder::isRunning(){ |
613 | - return m_bRunning; | |
101 | + return m_receiver.isRunning(); | |
614 | 102 | } |
615 | 103 | |
616 | 104 | bool DvppDecoder::isFinished(){ |
617 | - return m_bFinished; | |
105 | + return m_bFinished; | |
618 | 106 | } |
619 | 107 | |
620 | 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 | 120 | FFImgInfo* DvppDecoder::snapshot(){ |
... | ... | @@ -631,10 +122,16 @@ FFImgInfo* DvppDecoder::snapshot(){ |
631 | 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 | 138 | \ No newline at end of file | ... | ... |
src/dvpp/DvppDecoder.h
1 | 1 | #include<string> |
2 | -#include <pthread.h> | |
3 | 2 | |
4 | -#include "dvpp_headers.h" | |
5 | 3 | #include "depend_headers.h" |
6 | -#include "user_mem.h" | |
7 | 4 | #include "CircularQueue.hpp" |
8 | -#include "VpcPicConverter.h" | |
9 | - | |
10 | -#include <queue> | |
5 | +#include "FFReceiver.h" | |
6 | +#include "DvppDec.h" | |
11 | 7 | |
12 | 8 | using namespace std; |
13 | 9 | |
14 | -#define TEST_DECODER | |
15 | - | |
16 | - | |
17 | 10 | class DvppDecoder{ |
18 | 11 | public: |
19 | 12 | DvppDecoder(); |
20 | 13 | ~DvppDecoder(); |
21 | - bool init(FFDecConfig& cfg); | |
14 | + bool init(FFDecConfig cfg); | |
22 | 15 | void close(); |
23 | 16 | bool start(); |
24 | 17 | void pause(); |
... | ... | @@ -33,12 +26,8 @@ public: |
33 | 26 | |
34 | 27 | bool isSurport(FFDecConfig& cfg); |
35 | 28 | |
36 | - int getCachedQueueLength(); | |
37 | - | |
38 | 29 | float fps(); |
39 | 30 | |
40 | - DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP; } | |
41 | - | |
42 | 31 | void setName(string nm){ |
43 | 32 | m_dec_name = nm; |
44 | 33 | } |
... | ... | @@ -52,60 +41,22 @@ public: |
52 | 41 | void setPostDecArg(const void* postDecArg); |
53 | 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 | 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 | 50 | FFDecConfig m_cfg; |
94 | 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 | 57 | const void * m_finishedDecArg; |
108 | 58 | DECODE_FINISHED_CALLBACK decode_finished_cbk; |
109 | 59 | |
110 | - VpcPicConverter picConverter; | |
60 | + bool m_bFinished{false}; | |
61 | + | |
111 | 62 | }; |
112 | 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 | 0 | \ No newline at end of file |
src/dvpp/DvppDecoderApi.cpp
1 | 1 | #include "DvppDecoderApi.h" |
2 | -#include "DvppDecoder2.h" | |
2 | +#include "DvppDecoder.h" | |
3 | 3 | |
4 | 4 | DvppDecoderApi::DvppDecoderApi(){ |
5 | 5 | m_pDecoder = nullptr; |
... | ... | @@ -13,7 +13,7 @@ DvppDecoderApi::~DvppDecoderApi(){ |
13 | 13 | } |
14 | 14 | |
15 | 15 | bool DvppDecoderApi::init(FFDecConfig& cfg){ |
16 | - m_pDecoder = new DvppDecoder2(); | |
16 | + m_pDecoder = new DvppDecoder(); | |
17 | 17 | if(m_pDecoder != nullptr){ |
18 | 18 | return m_pDecoder->init(cfg); |
19 | 19 | } | ... | ... |
src/dvpp/DvppDecoderApi.h
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | |
7 | 7 | using namespace std; |
8 | 8 | |
9 | -class DvppDecoder2; | |
9 | +class DvppDecoder; | |
10 | 10 | |
11 | 11 | class DvppDecoderApi : public AbstractDecoder{ |
12 | 12 | public: |
... | ... | @@ -40,5 +40,5 @@ public: |
40 | 40 | void setPostDecArg(const void* postDecArg); |
41 | 41 | void setFinishedDecArg(const void* finishedDecArg); |
42 | 42 | private: |
43 | - DvppDecoder2* m_pDecoder; | |
43 | + DvppDecoder* m_pDecoder; | |
44 | 44 | }; |
45 | 45 | \ No newline at end of file | ... | ... |
src/dvpp/DvppSourceManager.cpp
... | ... | @@ -59,5 +59,8 @@ int DvppSourceManager::getChannel(int devId){ |
59 | 59 | |
60 | 60 | void DvppSourceManager::releaseChannel(int devId, int iChannel){ |
61 | 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 | 67 | \ No newline at end of file | ... | ... |
src/dvpp/FFReceiver.cpp
... | ... | @@ -26,6 +26,12 @@ FFReceiver::FFReceiver(/* args */) |
26 | 26 | FFReceiver::~FFReceiver() |
27 | 27 | { |
28 | 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 | 37 | AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){ |
... | ... | @@ -131,8 +137,6 @@ AVCodecContext* FFReceiver::init_FFmpeg(ReceiverConfig config){ |
131 | 137 | |
132 | 138 | LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name); |
133 | 139 | |
134 | - releaseFFmpeg(); | |
135 | - | |
136 | 140 | return nullptr; |
137 | 141 | } |
138 | 142 | |
... | ... | @@ -150,10 +154,6 @@ void FFReceiver::releaseFFmpeg(){ |
150 | 154 | avcodec_free_context(&avctx); |
151 | 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 | 159 | void FFReceiver::read_thread(){ |
... | ... | @@ -214,6 +214,7 @@ void FFReceiver::read_thread(){ |
214 | 214 | } |
215 | 215 | |
216 | 216 | LOG_INFO("[{}]- read thread exit.", m_dec_name); |
217 | + m_bFinished = true; | |
217 | 218 | |
218 | 219 | receiver_finished_cbk(m_finishedReceiveArg); |
219 | 220 | } | ... | ... |
src/dvpp/VpcPicConverter.cpp
... | ... | @@ -3,35 +3,40 @@ |
3 | 3 | |
4 | 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 | 38 | DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){ |
31 | 39 | |
32 | - // 8. 创建色域转换的输出图片的描述信息,并设置各属性值, 输出的宽和高要求和输入一致 | |
33 | - // 如果色域转换的输出图片作为模型推理的输入,则输出图片的宽高要与模型要求的宽高保持一致 | |
34 | - // outputDesc_是acldvppPicDesc类型 | |
35 | 40 | int out_buf_width = ALIGN_UP(out_width, 16) * 3; |
36 | 41 | int out_buf_height = ALIGN_UP(out_height, 2); |
37 | 42 | int out_buf_size = out_buf_width * out_buf_height; |
... | ... | @@ -48,8 +53,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ |
48 | 53 | acldvppSetPicDescHeightStride(outputDesc_, out_buf_height); |
49 | 54 | acldvppSetPicDescSize(outputDesc_, out_buf_size); |
50 | 55 | |
51 | - | |
52 | - | |
53 | 56 | aclError ret = ACL_ERROR_NONE; |
54 | 57 | do{ |
55 | 58 | // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 |
... | ... | @@ -65,8 +68,6 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ |
65 | 68 | } |
66 | 69 | }while(0); |
67 | 70 | |
68 | - // 10. 色域转换结束后,释放资源,包括输入/输出图片的描述信息、输入/输出内存 | |
69 | - // acldvppDestroyPicDesc(inputDesc_); | |
70 | 71 | acldvppDestroyPicDesc(outputDesc_); |
71 | 72 | |
72 | 73 | if(ret != ACL_ERROR_NONE){ |
... | ... | @@ -75,9 +76,4 @@ DvppRgbMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out_ |
75 | 76 | } |
76 | 77 | |
77 | 78 | return rgbMem; |
78 | -} | |
79 | - | |
80 | -void VpcPicConverter::release(){ | |
81 | - aclrtDestroyStream(stream_); | |
82 | - // aclrtDestroyContext(context_); | |
83 | 79 | } |
84 | 80 | \ No newline at end of file | ... | ... |
src/dvpp/VpcPicConverter.h
... | ... | @@ -5,15 +5,16 @@ |
5 | 5 | |
6 | 6 | class VpcPicConverter{ |
7 | 7 | public: |
8 | - bool init(aclrtContext context); | |
8 | + VpcPicConverter(); | |
9 | + ~VpcPicConverter(); | |
10 | + int init(aclrtContext context, string dec_name); | |
9 | 11 | |
10 | 12 | DvppRgbMemory* convert2bgr(acldvppPicDesc *input, int out_width, int out_height, bool key_frame); |
11 | 13 | |
12 | - void release(); | |
13 | - | |
14 | 14 | private: |
15 | 15 | aclrtContext context_; |
16 | 16 | aclrtStream stream_; |
17 | 17 | int m_devId; |
18 | 18 | acldvppChannelDesc *dvppChannelDesc_ ; |
19 | + string m_dec_name; | |
19 | 20 | }; |
20 | 21 | \ No newline at end of file | ... | ... |
src/dvpp/dvpp_headers.h
... | ... | @@ -27,5 +27,14 @@ |
27 | 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 | 39 | #endif |
31 | 40 | ... | ... |
src/interface/FFNvDecoderManager.cpp
... | ... | @@ -52,10 +52,10 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){ |
52 | 52 | return nullptr; |
53 | 53 | } |
54 | 54 | |
55 | + config.cfg.dec_name = config.name; | |
55 | 56 | bool bRet= dec->init(config.cfg); |
56 | 57 | if (bRet) |
57 | 58 | { |
58 | - dec->setName(config.name) ; | |
59 | 59 | decoderMap[config.name] = dec; |
60 | 60 | |
61 | 61 | LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri); | ... | ... |