4061a3c3
Hu Chunming
更换decoder
|
1
|
#include "DvppSnapshot.h"
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
2
3
|
#include "DvppSourceManager.h"
|
4061a3c3
Hu Chunming
更换decoder
|
4
5
|
#include "VpcUtils.h"
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
6
|
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
7
8
9
10
11
12
13
14
|
#define CHECK_NOT_RETURN(ret, message) \
if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);}
#define CHECK_AND_RETURN_NOVALUE(ret, message) \
if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;}
#define CHECK_AND_BREAK(ret, message) \
if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;}
|
4061a3c3
Hu Chunming
更换decoder
|
15
16
17
|
constexpr int MAX_QUEUE_LENGTH = 3;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
18
19
20
21
22
|
struct Vdec_CallBack_UserData {
uint64_t frameId;
uint64_t frame_nb;
long startTime;
long sendTime;
|
4061a3c3
Hu Chunming
更换decoder
|
23
|
DvppSnapshot* self;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
24
25
26
27
28
29
30
|
Vdec_CallBack_UserData() {
frameId = 0;
frame_nb = 0;
}
};
|
4061a3c3
Hu Chunming
更换decoder
|
31
32
33
34
35
36
37
|
static long get_cur_time_ms() {
chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
= chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
return tpMicro.time_since_epoch().count();
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
38
39
|
static void *ReportThd(void *arg)
{
|
4061a3c3
Hu Chunming
更换decoder
|
40
|
DvppSnapshot *self = (DvppSnapshot *)arg;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
41
42
43
44
45
46
47
48
49
50
|
if(nullptr != self){
self->doProcessReport();
}
return (void *)0;
}
static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData)
{
Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
if(nullptr != userData){
|
4061a3c3
Hu Chunming
更换decoder
|
51
|
DvppSnapshot* self = userData->self;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
52
53
54
55
56
57
58
59
|
if(self != nullptr){
self->doVdppVdecCallBack(input, output, userData);
}
delete userData;
userData = nullptr;
}
}
|
4061a3c3
Hu Chunming
更换decoder
|
60
|
DvppSnapshot::DvppSnapshot(){
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
61
|
|
4061a3c3
Hu Chunming
更换decoder
|
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
fmt_ctx = nullptr;
m_bRunning = false;
video_index = -1;
pix_fmt = AV_PIX_FMT_NONE;
m_dec_name = "";
m_bReal = true;
m_bFinished = false;
m_fps = 0.0;
std::queue<DvppDataMemory*>().swap(m_decoded_data_queue);
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
76
|
|
4061a3c3
Hu Chunming
更换decoder
|
77
78
|
DvppSnapshot::~DvppSnapshot(){
LOG_DEBUG("[{}]- ~DvppSnapshot() in_count:{} out_count:{}", m_dec_name, m_in_count, m_out_count);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
79
80
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
81
|
bool DvppSnapshot::init(FFDecConfig cfg){
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
82
83
84
|
m_dec_name = cfg.dec_name;
|
4061a3c3
Hu Chunming
更换decoder
|
85
86
87
88
89
90
91
92
93
94
95
96
97
|
m_cfg = cfg;
AVCodecContext* avctx = init_FFmpeg(cfg);
if(avctx == nullptr){
return false;
}
do
{
bool bRet = init_vdpp(cfg, avctx);
if(!bRet){
break;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
98
|
|
4061a3c3
Hu Chunming
更换decoder
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
m_bFinished = false;
return true;
} while (0);
release_ffmpeg();
return false;
}
AVCodecContext* DvppSnapshot::init_FFmpeg(FFDecConfig config){
const char* input_file = config.uri.c_str();
// 打开输入视频文件
AVDictionary *options = nullptr;
av_dict_set( &options, "bufsize", "655360", 0 );
av_dict_set( &options, "rtsp_transport", "tcp", 0 );
av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
118
119
|
do{
|
4061a3c3
Hu Chunming
更换decoder
|
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
fmt_ctx = avformat_alloc_context();
if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
LOG_ERROR("[{}]- Cannot open input file: {}", m_dec_name, input_file);
break;
}
av_dump_format(fmt_ctx, 0, input_file, 0);
FILE* infile = fopen(input_file, "r");
if(nullptr != infile) {
// 可以作为本地文件打开,那必然是文件
m_bReal = false;
fclose(infile);
infile = nullptr;
} else {
// http://xxxx/xxx.mp4 也与文件同
if (fmt_ctx->iformat && fmt_ctx->iformat->extensions) {
m_bReal = false;
} else {
m_bReal = true;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
140
141
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
142
143
144
145
|
// 查找流信息
if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
LOG_ERROR("[{}]- Cannot find input stream information!", m_dec_name);
break;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
146
147
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
148
149
150
151
152
153
154
|
// 查找视频流信息
AVCodec *decoder = nullptr;
video_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (video_index < 0) {
LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name);
break;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
155
|
|
4061a3c3
Hu Chunming
更换decoder
|
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
avctx = avcodec_alloc_context3(decoder);
if(avctx == nullptr){
LOG_ERROR("[{}]- alloc AVCodecContext failed!", m_dec_name);
break;
}
// 得到视频流对象
AVStream* stream = fmt_ctx->streams[video_index];
AVCodecParameters *codecpar = stream->codecpar;
if (avcodec_parameters_to_context(avctx, codecpar) < 0)
break;
const AVBitStreamFilter * filter = nullptr;
if(codecpar->codec_id == AV_CODEC_ID_H264){
filter = av_bsf_get_by_name("h264_mp4toannexb");
}else if(codecpar->codec_id == AV_CODEC_ID_HEVC){
filter = av_bsf_get_by_name("hevc_mp4toannexb");
}else {
LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name);
break;
}
int enType = getVdecType(codecpar->codec_id, codecpar->profile);
if(-1 == enType) {
break;
}
m_enType = static_cast<acldvppStreamFormat>(enType);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
183
|
|
4061a3c3
Hu Chunming
更换decoder
|
184
185
186
187
188
189
190
|
int ret = av_bsf_alloc(filter, &h264bsfc);
if (ret < 0){
break;
}
avcodec_parameters_copy(h264bsfc->par_in, codecpar);
av_bsf_init(h264bsfc);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
191
|
|
4061a3c3
Hu Chunming
更换decoder
|
192
193
194
|
frame_width = codecpar->width;
frame_height = codecpar->height;
pix_fmt = (AVPixelFormat)codecpar->format;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
195
|
|
4061a3c3
Hu Chunming
更换decoder
|
196
197
|
m_bResize = config.resize;
calcOutResolution(frame_width, frame_height);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
198
|
|
4061a3c3
Hu Chunming
更换decoder
|
199
200
201
202
203
|
if (stream->avg_frame_rate.den) {
m_fps = av_q2d(stream ->avg_frame_rate);
} else {
m_fps = 0.0;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
204
|
|
4061a3c3
Hu Chunming
更换decoder
|
205
|
LOG_INFO("[{}]- init ffmpeg success! input:{} src:({}, {}) out:({}, {}) fps:{} ", m_dec_name, input_file, frame_width, frame_height, out_frame_width, out_frame_height, m_fps);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
206
|
|
4061a3c3
Hu Chunming
更换decoder
|
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
return avctx;
}while(0);
release_ffmpeg();
LOG_ERROR("[{}]- init ffmpeg failed ! input:{} ", m_dec_name, input_file);
return nullptr;
}
void DvppSnapshot::calcOutResolution(int width, int height) {
if(m_bResize) {
float srcRatio = width / (float)height;
float stdRatio = 1920.0 / 1080.0f ;
int outWidth = 1920;
int outHeight = 1080;
if (srcRatio > stdRatio) {
outHeight = static_cast<int>(outWidth * (float)height / width) ;
if (outHeight % 2 == 1) {
outHeight += 1;
}
} else if (srcRatio < stdRatio) {
outWidth = static_cast<int>(outHeight * (float)width / height) ;
if (outWidth % 2 == 1) {
outWidth += 1;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
233
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
234
235
236
237
238
239
|
out_frame_width = outWidth;
out_frame_height = outHeight;
} else {
out_frame_width = width;
out_frame_height = height;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
240
241
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
242
243
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
244
|
int DvppSnapshot::getVdecType(int videoType, int profile)
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
245
246
247
248
|
{
int streamFormat = H264_MAIN_LEVEL;
// VDEC only support H265 main level,264 baseline level,main level,high level
|
4061a3c3
Hu Chunming
更换decoder
|
249
|
if (videoType == AV_CODEC_ID_HEVC) {
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
250
|
streamFormat = H265_MAIN_LEVEL;
|
4061a3c3
Hu Chunming
更换decoder
|
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
} else if (videoType == AV_CODEC_ID_H264) {
switch (profile) {
case FF_PROFILE_H264_BASELINE:
streamFormat = H264_BASELINE_LEVEL;
break;
case FF_PROFILE_H264_MAIN:
streamFormat = H264_MAIN_LEVEL;
break;
case FF_PROFILE_H264_HIGH:
case FF_PROFILE_H264_HIGH_10:
case FF_PROFILE_H264_HIGH_10_INTRA:
case FF_PROFILE_H264_MULTIVIEW_HIGH:
case FF_PROFILE_H264_HIGH_422:
case FF_PROFILE_H264_HIGH_422_INTRA:
case FF_PROFILE_H264_STEREO_HIGH:
case FF_PROFILE_H264_HIGH_444:
case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
case FF_PROFILE_H264_HIGH_444_INTRA:
streamFormat = H264_HIGH_LEVEL;
break;
default:
LOG_INFO("Not support h264 profile {}, use as mp", profile);
streamFormat = H264_MAIN_LEVEL;
break;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
276
277
|
} else {
streamFormat = -1;
|
4061a3c3
Hu Chunming
更换decoder
|
278
|
LOG_ERROR("Not support stream, type {}, profile {}", videoType, profile);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
279
280
281
282
283
|
}
return streamFormat;
}
|
4061a3c3
Hu Chunming
更换decoder
|
284
|
bool DvppSnapshot::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) {
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
285
|
|
4061a3c3
Hu Chunming
更换decoder
|
286
|
LOG_INFO("[{}]- Init device start...", m_dec_name);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
287
|
|
4061a3c3
Hu Chunming
更换decoder
|
288
|
m_dvpp_deviceId = atoi(cfg.gpuid.c_str());
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
289
|
|
4061a3c3
Hu Chunming
更换decoder
|
290
|
VpcUtils::getInstance(m_dvpp_deviceId); // 初始化工具类
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
291
|
|
4061a3c3
Hu Chunming
更换decoder
|
292
293
294
295
296
297
|
do{
aclError ret = aclrtSetDevice(m_dvpp_deviceId);
if(ret != ACL_ERROR_NONE){
LOG_ERROR("[{}]-aclrtSetDevice failed !", m_dec_name);
break;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
298
|
|
4061a3c3
Hu Chunming
更换decoder
|
299
300
301
302
303
|
ret = aclrtCreateContext(&m_context, m_dvpp_deviceId);
if (ret != ACL_ERROR_NONE) {
LOG_ERROR("[{}]-aclrtCreateContext failed !", m_dec_name);
break;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
304
|
|
4061a3c3
Hu Chunming
更换decoder
|
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
// DvppSourceManager 创建时包含 aclInit,析构时包含 aclFinalize
DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
m_dvpp_channel = pSrcMgr->getChannel(m_dvpp_deviceId);
if(m_dvpp_channel < 0){
LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name);
break;
}
m_vdec_out_size = frame_width * frame_height * 3;
LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel);
return true;
}while(0);
release_dvpp();
return false;
}
void DvppSnapshot::release_ffmpeg() {
if(h264bsfc){
av_bsf_free(&h264bsfc);
h264bsfc = nullptr;
}
if(avctx){
avcodec_free_context(&avctx);
avctx = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
333
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
334
335
336
337
|
if (fmt_ctx){
avformat_close_input(&fmt_ctx);
fmt_ctx = nullptr;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
338
|
|
4061a3c3
Hu Chunming
更换decoder
|
339
340
|
LOG_DEBUG("[{}]- release_ffmpeg", m_dec_name);
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
341
|
|
4061a3c3
Hu Chunming
更换decoder
|
342
|
DvppDataMemory* DvppSnapshot::snapshot() {
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
343
|
|
4061a3c3
Hu Chunming
更换decoder
|
344
|
int ret = -1;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
345
|
|
4061a3c3
Hu Chunming
更换decoder
|
346
347
348
349
350
351
352
|
m_bExitReportThd = false;
pthread_t report_thread;
ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this);
if(ret != 0){
LOG_ERROR("[{}]- pthread_create failed", m_dec_name);
return nullptr;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
353
|
|
4061a3c3
Hu Chunming
更换decoder
|
354
355
356
|
aclrtContext ctx = nullptr;
aclrtStream stream = nullptr;
aclvdecChannelDesc *vdecChannelDesc = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
357
|
|
4061a3c3
Hu Chunming
更换decoder
|
358
359
360
361
362
363
364
365
366
367
|
m_bRunning = true;
do {
CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed");
CHECK_AND_BREAK(aclrtCreateContext(&ctx, m_dvpp_deviceId), "aclrtCreateContext failed");
CHECK_AND_BREAK(aclrtCreateStream(&stream), "aclrtCreateStream failed");
vdecChannelDesc = aclvdecCreateChannelDesc();
if (vdecChannelDesc == nullptr) {
LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
368
369
370
|
break;
}
|
4061a3c3
Hu Chunming
更换decoder
|
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
// 创建 channel dec结构体
// 通道ID在dvpp层面为0~31
CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed");
CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed");
CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed");
CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, m_enType), "aclvdecSetChannelDescEnType failed");
// CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed");
CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_BGR_888), "aclvdecSetChannelDescOutPicFormat failed");
CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed");
AVPacket* pkt = av_packet_alloc();
av_init_packet( pkt );
unsigned long long frame_nb = 0;
while (m_bRunning){
m_decoded_data_queue_mtx.lock();
if(m_decoded_data_queue.size() > 1){
m_decoded_data_queue_mtx.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(5));
break;
}
m_decoded_data_queue_mtx.unlock();
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
393
|
|
4061a3c3
Hu Chunming
更换decoder
|
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
|
int result = av_read_frame(fmt_ctx, pkt);
if (result == AVERROR_EOF || result < 0){
av_packet_unref(pkt);
LOG_WARN("[{}]- Failed to read frame!", m_dec_name);
break;
}
if (m_bReal && m_DvppCacheCounter.load() > 20){
// 解码器解码不过来。实时流在此处的处理会导致花屏,这是由于解码器性能问题导致,无法避免
// 实时流在这里处理是为了避免长时间不读取数据导致数据中断
std::this_thread::sleep_for(std::chrono::milliseconds(10));
continue;
}
if (video_index == pkt->stream_index){
ret = av_bsf_send_packet(h264bsfc, pkt);
if(ret < 0) {
LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name);
av_packet_unref(pkt);
continue;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
415
416
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
417
418
419
420
421
422
423
424
425
426
|
int nSended = -1;
while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) {
if(!m_bRunning){
break;
}
nSended = sendPkt(vdecChannelDesc, pkt, frame_nb);
frame_nb++;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
427
|
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
428
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
429
430
431
432
433
434
435
|
if(nSended < 0) {
// 执行出错,强行结束整个任务
m_bRunning=false;
break;
}
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
436
|
|
4061a3c3
Hu Chunming
更换decoder
|
437
438
439
|
// 音频等其他分量的情形
av_packet_unref(pkt);
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
440
|
|
4061a3c3
Hu Chunming
更换decoder
|
441
442
443
444
445
|
av_packet_free(&pkt);
pkt = nullptr;
if (vdecChannelDesc) {
sendVdecEos(vdecChannelDesc);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
446
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
447
|
|
4061a3c3
Hu Chunming
更换decoder
|
448
449
450
|
} while (0);
DvppDataMemory* snapshot_mem = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
451
|
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
452
|
if (m_decoded_data_queue.size() > 0) {
|
4061a3c3
Hu Chunming
更换decoder
|
453
454
|
auto mem = m_decoded_data_queue.front();
snapshot_mem = new DvppDataMemory(mem);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
455
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
456
|
|
4061a3c3
Hu Chunming
更换decoder
|
457
458
459
460
461
|
if (vdecChannelDesc) {
CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed");
CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed");
vdecChannelDesc = nullptr;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
462
|
|
4061a3c3
Hu Chunming
更换decoder
|
463
464
465
466
467
468
469
470
471
472
473
|
m_bRunning=false;
m_bExitReportThd = true;
CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed");
m_decoded_data_queue_mtx.lock();
while (!m_decoded_data_queue.empty()) {
DvppDataMemory* memPtr = m_decoded_data_queue.front();
m_decoded_data_queue.pop();
delete memPtr;
memPtr = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
474
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
475
476
477
478
|
m_decoded_data_queue_mtx.unlock();
if(stream){
CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed");
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
479
480
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
481
482
|
if (ctx){
CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed");
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
483
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
484
485
486
|
release_ffmpeg();
release_dvpp();
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
487
|
|
4061a3c3
Hu Chunming
更换decoder
|
488
489
490
491
492
|
m_bFinished = true;
LOG_INFO("[{}]- snapshot finished.", m_dec_name);
return snapshot_mem;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
493
494
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
495
|
int DvppSnapshot::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb){
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
|
void *vdecInputbuf = nullptr;
void *vdecOutputBuf = nullptr;
acldvppStreamDesc *input_stream_desc = nullptr;
acldvppPicDesc *output_pic_desc = nullptr;
do{
int ret = acldvppMalloc((void **)&vdecInputbuf, pkt->size);
if(ACL_ERROR_NONE != ret){
LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret);
break;
}
ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE);
if(ACL_ERROR_NONE != ret){
LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name);
break;
}
|
4061a3c3
Hu Chunming
更换decoder
|
514
|
ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
|
if(ret != ACL_ERROR_NONE){
LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name);
break;
}
input_stream_desc = acldvppCreateStreamDesc();
if (input_stream_desc == nullptr) {
LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name);
break;
}
output_pic_desc = acldvppCreatePicDesc();
if (output_pic_desc == nullptr) {
LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name);
break;
}
CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed");
CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed");
CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed");
|
4061a3c3
Hu Chunming
更换decoder
|
533
|
CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed");
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
|
Vdec_CallBack_UserData *user_data = NULL;
user_data = new Vdec_CallBack_UserData;
user_data->frameId = frame_nb;
user_data->frame_nb = frame_nb;
// user_data->startTime = startTime;
user_data->sendTime = UtilTools::get_cur_time_ms();
user_data->self = this;
m_in_count++;
// 内部缓存计数加1
m_DvppCacheCounter++;
ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data));
if(ret != ACL_ERROR_NONE){
LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name);
delete user_data;
user_data = nullptr;
return -2;
}
return 0;
}while (0);
if (vdecInputbuf){
acldvppFree(vdecInputbuf);
vdecInputbuf = nullptr;
}
// 报错情形
if(input_stream_desc){
CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed");
}
if (vdecOutputBuf){
acldvppFree(vdecOutputBuf);
vdecOutputBuf = nullptr;
}
if(output_pic_desc){
CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed");
}
return -1;
}
|
4061a3c3
Hu Chunming
更换decoder
|
580
|
void DvppSnapshot::doProcessReport(){
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
581
|
|
4061a3c3
Hu Chunming
更换decoder
|
582
|
aclError ret = aclrtSetDevice(m_dvpp_deviceId);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
583
|
if(ret != ACL_ERROR_NONE){
|
4061a3c3
Hu Chunming
更换decoder
|
584
585
586
|
// cout << "aclrtSetDevice failed" << endl;
LOG_ERROR("aclrtSetDevice failed !");
return ;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
587
588
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
589
590
591
592
593
594
|
aclrtContext ctx;
ret = aclrtCreateContext(&ctx, m_dvpp_deviceId);
if (ret != ACL_ERROR_NONE) {
// cout << "aclrtCreateContext failed " << endl;
LOG_ERROR("aclrtCreateContext failed !");
return ;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
595
596
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
597
598
|
while (!m_bExitReportThd) {
aclrtProcessReport(1000);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
599
600
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
601
602
603
604
605
|
ret = aclrtDestroyContext(ctx);
if(ret != ACL_ERROR_NONE){
LOG_ERROR("aclrtDestroyContext failed !");
}
LOG_INFO("doProcessReport exit.");
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
606
607
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
608
609
610
611
|
void DvppSnapshot::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData){
// 内部缓存计数减1
m_DvppCacheCounter--;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
612
|
|
4061a3c3
Hu Chunming
更换decoder
|
613
614
|
if(nullptr == pUserData){
return;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
615
616
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
617
618
|
Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData;
uint64_t frame_nb = userData->frame_nb;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
619
|
|
4061a3c3
Hu Chunming
更换decoder
|
620
|
m_out_count++;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
621
|
|
4061a3c3
Hu Chunming
更换decoder
|
622
|
CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed");
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
623
|
|
4061a3c3
Hu Chunming
更换decoder
|
624
625
626
|
void *inputDataDev = acldvppGetStreamDescData(input);
acldvppFree(inputDataDev);
inputDataDev = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
627
|
|
4061a3c3
Hu Chunming
更换decoder
|
628
629
630
631
632
633
|
void *outputDataDev = acldvppGetPicDescData(output);
uint32_t outputSize = acldvppGetPicDescSize(output);
uint32_t width = acldvppGetPicDescWidth(output);
uint32_t width_stride = acldvppGetPicDescWidthStride(output);
uint32_t height = acldvppGetPicDescHeight(output);
uint32_t height_stride = acldvppGetPicDescHeightStride(output);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
634
|
|
4061a3c3
Hu Chunming
更换decoder
|
635
636
637
638
639
640
641
642
|
bool bCached = false;
do{
int ret = acldvppGetPicDescRetCode(output);
if(ret != ACL_ERROR_NONE){
LOG_ERROR("[{}]- decode result error, frame_nb:{}, retCode:{} ", m_dec_name, frame_nb, ret);
acldvppFree(outputDataDev);
outputDataDev = nullptr;
break;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
643
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
644
|
|
4061a3c3
Hu Chunming
更换decoder
|
645
|
if(width > 0 && height > 0 && outputSize > 0){
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
646
|
|
4061a3c3
Hu Chunming
更换decoder
|
647
648
649
650
651
|
// 限制队列的最大长度为20
m_decoded_data_queue_mtx.lock();
if(m_decoded_data_queue.size() >= 20){
m_decoded_data_queue_mtx.unlock();
break;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
652
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
653
|
m_decoded_data_queue_mtx.unlock();
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
654
|
|
4061a3c3
Hu Chunming
更换decoder
|
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
|
// 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏
DvppDataMemory* mem = nullptr;
if (m_bResize && (width > 1920 || height > 1080)) {
float srcRatio = width / (float)height;
float stdRatio = 1920.0 / 1080.0f ;
int outWidth = 1920;
int outHeight = 1080;
if (srcRatio > stdRatio) {
outHeight = static_cast<int>(outWidth * (float)height / width) ;
if (outHeight % 2 == 1)
{
outHeight += 1;
}
} else if (srcRatio < stdRatio) {
outWidth = static_cast<int>(outHeight * (float)width / height) ;
if (outWidth % 2 == 1)
{
outWidth += 1;
}
}
VpcUtils* pUtils = VpcUtils::getInstance(m_dvpp_deviceId);
mem = pUtils->resize(output, outWidth, outHeight);
if (mem) {
acldvppFree(outputDataDev);
outputDataDev = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
681
|
|
4061a3c3
Hu Chunming
更换decoder
|
682
683
684
685
686
|
mem->setDeviceId(to_string(m_dvpp_deviceId));
mem->setId(m_dec_name);
mem->setFrameNb(frame_nb);
}
} else {
|
881ac79d
Hu Chunming
代码调通,结果正常输出
|
687
|
mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, frame_nb, (unsigned char *)outputDataDev);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
688
689
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
690
691
692
693
694
|
if(mem != nullptr){
m_decoded_data_queue.push(mem);
bCached = true;
} else {
LOG_WARN("[{}]- decode result warning, width:{} width_stride:{} height:{} height_stride:{} size:{}", m_dec_name, width, width_stride, height, height_stride, outputSize);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
695
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
696
697
698
|
}
}while(0);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
699
|
|
4061a3c3
Hu Chunming
更换decoder
|
700
701
702
703
|
if(!bCached) {
acldvppFree(outputDataDev);
outputDataDev = nullptr;
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
704
|
|
4061a3c3
Hu Chunming
更换decoder
|
705
706
707
|
CHECK_AND_RETURN_NOVALUE(acldvppDestroyStreamDesc(input), "acldvppDestroyStreamDesc failed");
CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed");
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
708
|
|
4061a3c3
Hu Chunming
更换decoder
|
709
710
711
712
713
714
|
bool DvppSnapshot::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) {
// create stream desc
acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc();
if (streamInputDesc == nullptr) {
LOG_ERROR("[{}]- fail to create input stream desc", m_dec_name);
return false;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
715
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
716
717
718
719
720
|
aclError ret = acldvppSetStreamDescEos(streamInputDesc, 1);
if (ret != ACL_SUCCESS) {
LOG_ERROR("[{}]- fail to set eos for stream desc, errorCode = {}", m_dec_name, static_cast<int32_t>(ret));
(void)acldvppDestroyStreamDesc(streamInputDesc);
return false;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
721
722
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
723
724
725
726
727
728
729
|
// send vdec eos frame. when all vdec callback are completed, aclvdecSendFrame can be returned.
LOG_INFO("[{}]- send eos", m_dec_name);
ret = aclvdecSendFrame(vdecChannelDesc, streamInputDesc, nullptr, nullptr, nullptr);
(void)acldvppDestroyStreamDesc(streamInputDesc);
if (ret != ACL_SUCCESS) {
LOG_ERROR("[{}]- fail to send eos frame, ret={}", m_dec_name, ret);
return false;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
730
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
731
|
|
4061a3c3
Hu Chunming
更换decoder
|
732
|
return true;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
733
734
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
735
736
737
|
void DvppSnapshot::release_dvpp(){
if(m_context){
aclError ret = aclrtDestroyContext(m_context);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
738
|
if(ret != ACL_ERROR_NONE){
|
4061a3c3
Hu Chunming
更换decoder
|
739
|
LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
740
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
741
|
m_context = nullptr;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
742
|
}
|
4061a3c3
Hu Chunming
更换decoder
|
743
744
745
746
|
if(m_dvpp_channel >= 0){
DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance();
pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
747
|
|
4061a3c3
Hu Chunming
更换decoder
|
748
|
LOG_INFO("[{}]- release channel:{}.", m_dec_name, m_dvpp_channel);
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
749
|
|
4061a3c3
Hu Chunming
更换decoder
|
750
|
m_dvpp_channel = -1;
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
751
|
}
|
6fdcb6a5
Hu Chunming
初次提交,代码大体完成编写,完善中
|
752
|
}
|