aac5773f
hucm
功能基本完成,接口待打磨
|
1
|
#include "FFNvDecoder.h"
|
aac5773f
hucm
功能基本完成,接口待打磨
|
2
3
4
|
#include <chrono>
#include <thread>
|
8c180bab
hucm
添加是否实时流判断
|
5
|
#include <fstream>
|
aac5773f
hucm
功能基本完成,接口待打磨
|
6
|
|
3d2ab595
Hu Chunming
支持gb28181
|
7
8
|
#include <chrono>
|
f40cc409
Hu Chunming
优化显存占用。当前在3080显卡上...
|
9
10
|
#include "FFCuContextManager.h"
|
63e6f7bc
Hu Chunming
完成dvpp。但是nv和gb281...
|
11
|
#include "common_header.h"
|
3d2ab595
Hu Chunming
支持gb28181
|
12
|
|
63e6f7bc
Hu Chunming
完成dvpp。但是nv和gb281...
|
13
14
|
#include "GpuRgbMemory.hpp"
#include "cuda_kernels.h"
|
92989af0
ming
更新解码器
|
15
|
|
aac5773f
hucm
功能基本完成,接口待打磨
|
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
using namespace std;
// 参考博客: https://blog.csdn.net/qq_40116098/article/details/120704340
static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *pix_fmts)
{
FFNvDecoder* _this = (FFNvDecoder*)avctx->opaque;
const AVPixelFormat *p;
for (p = pix_fmts; *p != -1; p++) {
if (*p == _this->getHwPixFmt())
return *p;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
31
|
LOG_ERROR("Failed to get HW surface format");
|
aac5773f
hucm
功能基本完成,接口待打磨
|
32
33
34
35
36
37
38
39
40
41
42
43
44
|
return AV_PIX_FMT_NONE;
}
FFNvDecoder::FFNvDecoder()
{
// 初始化解码对象
fmt_ctx = nullptr;
avctx = nullptr;
m_bRunning = false;
stream = nullptr;
stream_index = -1;
hw_pix_fmt = AV_PIX_FMT_NONE;
|
3d2ab595
Hu Chunming
支持gb28181
|
45
|
m_dec_name = "";
|
aac5773f
hucm
功能基本完成,接口待打磨
|
46
47
|
m_bPause = false;
|
8c180bab
hucm
添加是否实时流判断
|
48
|
m_bReal = true;
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
49
50
51
|
m_decode_thread = 0;
m_post_decode_thread = 0;
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
52
53
|
m_bFinished = false;
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
54
|
m_dec_keyframe = false;
|
3d2ab595
Hu Chunming
支持gb28181
|
55
|
m_fps = 0.0;
|
aac5773f
hucm
功能基本完成,接口待打磨
|
56
57
58
59
|
}
FFNvDecoder::~FFNvDecoder()
{
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
60
|
m_dec_keyframe = false;
|
aac5773f
hucm
功能基本完成,接口待打磨
|
61
62
|
}
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
63
|
bool FFNvDecoder::init(FFDecConfig& cfg)
|
7319ea36
Hu Chunming
多显卡设置
|
64
65
66
67
68
69
70
71
72
73
74
|
{
m_cfg = cfg;
fstream infile(cfg.uri);
if (infile.is_open()){
m_bReal = false;
infile.close();
}else {
m_bReal = true;
}
|
372e629f
ming
gb28181支持TCP数据流
|
75
76
77
|
post_decoded_cbk = cfg.post_decoded_cbk;
decode_finished_cbk = cfg.decode_finished_cbk;
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
78
79
80
81
82
|
return init(cfg.uri.c_str(), cfg.gpuid.c_str(),cfg.force_tcp);
}
bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
{
|
f40cc409
Hu Chunming
优化显存占用。当前在3080显卡上...
|
83
84
|
// av_log_set_level(AV_LOG_DEBUG);
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
85
|
avformat_network_init();
|
7319ea36
Hu Chunming
多显卡设置
|
86
87
88
89
|
// 打开输入视频文件
AVDictionary *options = nullptr;
av_dict_set( &options, "bufsize", "655360", 0 );
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
90
|
av_dict_set( &options, "rtsp_transport", force_tcp ? "tcp" : "udp", 0 );
|
7319ea36
Hu Chunming
多显卡设置
|
91
|
// av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
92
|
av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒
|
7319ea36
Hu Chunming
多显卡设置
|
93
94
|
fmt_ctx = avformat_alloc_context();
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
95
|
const char* input_file = uri;
|
7319ea36
Hu Chunming
多显卡设置
|
96
|
if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
|
3d2ab595
Hu Chunming
支持gb28181
|
97
|
LOG_ERROR("Cannot open input file:{}",input_file);
|
7319ea36
Hu Chunming
多显卡设置
|
98
99
100
101
102
|
return false;
}
// 查找流信息
if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
|
3d2ab595
Hu Chunming
支持gb28181
|
103
|
LOG_ERROR("Cannot find input stream information");
|
7319ea36
Hu Chunming
多显卡设置
|
104
105
106
107
108
109
110
|
return false;
}
// 查找视频流信息
AVCodec *decoder = nullptr;
stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (stream_index < 0) {
|
3d2ab595
Hu Chunming
支持gb28181
|
111
|
LOG_ERROR("Cannot find a video stream in the input file");
|
7319ea36
Hu Chunming
多显卡设置
|
112
113
114
|
return false;
}
|
7319ea36
Hu Chunming
多显卡设置
|
115
116
117
118
119
120
121
122
123
124
|
string cuvid_dec_name = string(decoder->name) + "_cuvid";
AVCodec *vcodec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str());
if (!(avctx = avcodec_alloc_context3(vcodec)))
return (bool)AVERROR(ENOMEM);
// 得到视频流对象
stream = fmt_ctx->streams[stream_index];
if (avcodec_parameters_to_context(avctx, stream->codecpar) < 0)
return false;
|
3d2ab595
Hu Chunming
支持gb28181
|
125
126
|
m_fps = av_q2d(stream ->avg_frame_rate);
|
7319ea36
Hu Chunming
多显卡设置
|
127
128
129
130
131
132
|
avctx->opaque = this;
// 设置解码器管理器的像素格式回调函数
avctx->get_format = get_hw_format;
hw_pix_fmt = AV_PIX_FMT_CUDA;
|
f40cc409
Hu Chunming
优化显存占用。当前在3080显卡上...
|
133
|
FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance();
|
d384f0e9
Hu Chunming
代码优化
|
134
135
136
137
138
139
140
|
AVBufferRef *hw_device_ctx = pCtxMgr->getCuCtx(gpuid);
if(nullptr == hw_device_ctx){
av_log(nullptr, AV_LOG_ERROR, "create CUDA context failed ! \n");
return false;
}
avctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
f40cc409
Hu Chunming
优化显存占用。当前在3080显卡上...
|
141
142
143
144
145
|
if (nullptr == avctx->hw_device_ctx)
{
return false;
}
|
7319ea36
Hu Chunming
多显卡设置
|
146
147
|
// 打开解码器流
AVDictionary *op = nullptr;
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
148
|
av_dict_set( &op, "gpu", gpuid, 0 );
|
3d2ab595
Hu Chunming
支持gb28181
|
149
|
// av_dict_set( &op, "surfaces", "5", 0 );
|
7319ea36
Hu Chunming
多显卡设置
|
150
|
if (avcodec_open2(avctx, vcodec, &op) < 0) {
|
3d2ab595
Hu Chunming
支持gb28181
|
151
|
LOG_ERROR("Failed to open codec for stream");
|
7319ea36
Hu Chunming
多显卡设置
|
152
153
|
return false;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
154
|
|
7319ea36
Hu Chunming
多显卡设置
|
155
156
157
|
return true;
}
|
0573bd98
Hu Chunming
优化代码;添加注释
|
158
159
160
161
162
163
164
|
bool FFNvDecoder::isSurport(FFDecConfig& cfg)
{
bool bRet = init(cfg);
decode_finished();
return bRet;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
165
|
bool FFNvDecoder::start(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
166
167
168
169
170
171
172
173
174
175
176
|
m_bRunning = true;
pthread_create(&m_decode_thread,0,
[](void* arg)
{
FFNvDecoder* a=(FFNvDecoder*)arg;
a->decode_thread();
return (void*)0;
}
,this);
|
3d2ab595
Hu Chunming
支持gb28181
|
177
178
|
return true;
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
179
180
|
}
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
181
182
183
184
185
|
void FFNvDecoder::decode_thread()
{
AVPacket* pkt ;
pkt = av_packet_alloc();
av_init_packet( pkt );
|
aac5773f
hucm
功能基本完成,接口待打磨
|
186
187
188
189
190
191
192
193
194
|
pthread_create(&m_post_decode_thread,0,
[](void* arg)
{
FFNvDecoder* a=(FFNvDecoder*)arg;
a->post_decode_thread();
return (void*)0;
}
,this);
|
aac5773f
hucm
功能基本完成,接口待打磨
|
195
|
|
92989af0
ming
更新解码器
|
196
|
// long start_time = UtilTools::get_cur_time_ms();
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
197
|
|
aac5773f
hucm
功能基本完成,接口待打磨
|
198
199
|
while (m_bRunning)
{
|
8c180bab
hucm
添加是否实时流判断
|
200
|
if (!m_bReal)
|
aac5773f
hucm
功能基本完成,接口待打磨
|
201
|
{
|
8c180bab
hucm
添加是否实时流判断
|
202
203
204
205
206
|
if (m_bPause)
{
std::this_thread::sleep_for(std::chrono::milliseconds(3));
continue;
}
|
aac5773f
hucm
功能基本完成,接口待打磨
|
207
|
}
|
aac5773f
hucm
功能基本完成,接口待打磨
|
208
209
|
int result = av_read_frame(fmt_ctx, pkt);
|
3c7e3e11
Hu Chunming
1.修改日志
|
210
|
if (result == AVERROR_EOF || result < 0)
|
aac5773f
hucm
功能基本完成,接口待打磨
|
211
|
{
|
3d2ab595
Hu Chunming
支持gb28181
|
212
|
LOG_ERROR("Failed to read frame!");
|
aac5773f
hucm
功能基本完成,接口待打磨
|
213
214
215
|
break;
}
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
216
217
218
219
220
|
if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) {
av_packet_unref(pkt);
continue;
}
|
3c7e3e11
Hu Chunming
1.修改日志
|
221
|
if (stream_index == pkt->stream_index){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
222
|
result = avcodec_send_packet(avctx, pkt);
|
3c7e3e11
Hu Chunming
1.修改日志
|
223
|
if (result < 0){
|
92989af0
ming
更新解码器
|
224
|
av_packet_unref(pkt);
|
3d2ab595
Hu Chunming
支持gb28181
|
225
|
LOG_ERROR("{} - Failed to send pkt: {}", m_dec_name, result);
|
aac5773f
hucm
功能基本完成,接口待打磨
|
226
227
228
|
continue;
}
|
92989af0
ming
更新解码器
|
229
|
AVFrame* gpuFrame = av_frame_alloc();
|
aac5773f
hucm
功能基本完成,接口待打磨
|
230
|
result = avcodec_receive_frame(avctx, gpuFrame);
|
3c7e3e11
Hu Chunming
1.修改日志
|
231
|
if ((result == AVERROR(EAGAIN) || result == AVERROR_EOF) || result < 0){
|
3d2ab595
Hu Chunming
支持gb28181
|
232
|
LOG_ERROR("{} - Failed to receive frame: {}", m_dec_name, result);
|
92989af0
ming
更新解码器
|
233
234
|
av_frame_free(&gpuFrame);
av_packet_unref(pkt);
|
aac5773f
hucm
功能基本完成,接口待打磨
|
235
236
|
continue;
}
|
92989af0
ming
更新解码器
|
237
|
av_packet_unref(pkt);
|
aac5773f
hucm
功能基本完成,接口待打磨
|
238
|
|
63e6f7bc
Hu Chunming
完成dvpp。但是nv和gb281...
|
239
240
241
242
243
244
245
246
|
if (m_bReal){
if (m_bPause){
av_frame_free(&gpuFrame);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
continue;
}
}
|
92989af0
ming
更新解码器
|
247
248
249
250
251
252
253
254
255
|
if(gpuFrame != nullptr){
m_queue_mutex.lock();
if(mFrameQueue.size() <= 10){
mFrameQueue.push(gpuFrame);
}else{
av_frame_free(&gpuFrame);
}
m_queue_mutex.unlock();
}
|
aac5773f
hucm
功能基本完成,接口待打磨
|
256
257
258
259
|
}
av_packet_unref(pkt);
}
|
aac5773f
hucm
功能基本完成,接口待打磨
|
260
|
m_bRunning = false;
|
63e6f7bc
Hu Chunming
完成dvpp。但是nv和gb281...
|
261
|
av_packet_free(&pkt);
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
262
|
|
92989af0
ming
更新解码器
|
263
|
// long end_time = UtilTools::get_cur_time_ms();
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
264
265
|
// cout << "解码用时:" << end_time - start_time << endl;
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
266
267
268
269
270
|
if (m_post_decode_thread != 0)
{
pthread_join(m_post_decode_thread,0);
}
|
3d2ab595
Hu Chunming
支持gb28181
|
271
|
decode_finished_cbk(m_finishedDecArg);
|
3c7e3e11
Hu Chunming
1.修改日志
|
272
|
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
273
274
|
decode_finished();
|
92989af0
ming
更新解码器
|
275
276
277
278
279
280
281
|
// 清空队列
while(mFrameQueue.size() > 0){
AVFrame * gpuFrame = mFrameQueue.front();
av_frame_free(&gpuFrame);
mFrameQueue.pop();
}
|
3d2ab595
Hu Chunming
支持gb28181
|
282
|
LOG_INFO("{} - decode thread exited.", m_dec_name);
|
aac5773f
hucm
功能基本完成,接口待打磨
|
283
284
|
}
|
3d2ab595
Hu Chunming
支持gb28181
|
285
|
void FFNvDecoder::decode_finished(){
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
286
287
|
if (avctx)
{
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
288
289
290
291
292
293
294
295
296
|
avcodec_free_context(&avctx);
}
if (fmt_ctx)
{
avformat_close_input(&fmt_ctx);
}
m_bFinished = true;
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
297
|
m_dec_keyframe = false;
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
298
299
|
}
|
3d2ab595
Hu Chunming
支持gb28181
|
300
301
302
303
304
305
306
|
void FFNvDecoder::post_decode_thread(){
int skip_frame = m_cfg.skip_frame;
if (skip_frame <= 0){
skip_frame = 1;
}
int index = 0;
|
92989af0
ming
更新解码器
|
307
|
while (m_bRunning)
|
3d2ab595
Hu Chunming
支持gb28181
|
308
|
{
|
92989af0
ming
更新解码器
|
309
310
311
312
313
314
315
316
317
318
319
320
|
if(mFrameQueue.size() > 0){
std::lock_guard<std::mutex> l(m_snapshot_mutex);
// 取队头数据
m_queue_mutex.lock();
AVFrame * gpuFrame = mFrameQueue.front();
mFrameQueue.pop();
m_queue_mutex.unlock();
// 跳帧
if (skip_frame == 1 || index % skip_frame == 0){
post_decoded_cbk(m_postDecArg, gpuFrame);
index = 0;
}
|
aac5773f
hucm
功能基本完成,接口待打磨
|
321
|
|
92989af0
ming
更新解码器
|
322
|
av_frame_free(&gpuFrame);
|
3c7e3e11
Hu Chunming
1.修改日志
|
323
|
|
92989af0
ming
更新解码器
|
324
325
|
index++;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
326
327
328
|
}
LOG_INFO("post decode thread exited.");
|
aac5773f
hucm
功能基本完成,接口待打磨
|
329
330
|
}
|
3d2ab595
Hu Chunming
支持gb28181
|
331
|
void FFNvDecoder::close(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
332
|
m_bRunning=false;
|
e96e6489
Hu Chunming
优化代码;添加isRunning函数
|
333
334
335
|
if(m_decode_thread != 0){
pthread_join(m_decode_thread,0);
}
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
336
|
m_dec_keyframe = false;
|
aac5773f
hucm
功能基本完成,接口待打磨
|
337
338
|
}
|
3d2ab595
Hu Chunming
支持gb28181
|
339
|
AVPixelFormat FFNvDecoder::getHwPixFmt(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
340
341
342
|
return hw_pix_fmt;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
343
|
bool FFNvDecoder::isRunning(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
344
345
346
|
return m_bRunning;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
347
|
bool FFNvDecoder::isFinished(){
|
48330793
Hu Chunming
修正解码线程自然结束时解码器内存没...
|
348
349
350
|
return m_bFinished;
}
|
3c7e3e11
Hu Chunming
1.修改日志
|
351
352
353
354
|
bool FFNvDecoder::isPausing(){
return m_bPause;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
355
356
|
bool FFNvDecoder::getResolution( int &width, int &height ){
if (avctx != nullptr)
|
aac5773f
hucm
功能基本完成,接口待打磨
|
357
|
{
|
3d2ab595
Hu Chunming
支持gb28181
|
358
359
|
width = avctx->width;
height = avctx->height;
|
aac5773f
hucm
功能基本完成,接口待打磨
|
360
361
362
363
364
365
|
return true;
}
return false;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
366
|
void FFNvDecoder::pause(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
367
368
369
|
m_bPause = true;
}
|
3d2ab595
Hu Chunming
支持gb28181
|
370
|
void FFNvDecoder::resume(){
|
aac5773f
hucm
功能基本完成,接口待打磨
|
371
|
m_bPause = false;
|
bc52e542
Hu Chunming
添加关键帧解码功能
|
372
373
374
375
376
|
}
void FFNvDecoder::setDecKeyframe(bool bKeyframe)
{
m_dec_keyframe = bKeyframe;
|
3c7e3e11
Hu Chunming
1.修改日志
|
377
378
379
|
}
int FFNvDecoder::getCachedQueueLength(){
|
92989af0
ming
更新解码器
|
380
381
382
383
|
m_queue_mutex.lock();
int queue_size = mFrameQueue.size();
m_queue_mutex.lock();
return queue_size;
|
3c7e3e11
Hu Chunming
1.修改日志
|
384
385
|
}
|
3d2ab595
Hu Chunming
支持gb28181
|
386
387
|
float FFNvDecoder::fps(){
return m_fps;
|
d384f0e9
Hu Chunming
代码优化
|
388
|
}
|
63e6f7bc
Hu Chunming
完成dvpp。但是nv和gb281...
|
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
|
FFImgInfo* FFNvDecoder::snapshot(){
// 锁住停止队列消耗
std::lock_guard<std::mutex> l(m_snapshot_mutex);
AVFrame * gpuFrame = nullptr;
bool bFirst = true;
while(true){
m_queue_mutex.lock();
if(mFrameQueue.size() <= 0){
m_queue_mutex.unlock();
if(bFirst){
std::this_thread::sleep_for(std::chrono::milliseconds(100));
bFirst = false;
continue;
}else{
// 再进来说明前面已经等了 100 ms
// 100 ms都没有等到解码数据,则退出
return nullptr;
}
}
// 队列中数据大于1
gpuFrame = mFrameQueue.front();
m_queue_mutex.unlock();
break;
}
if (gpuFrame != nullptr && gpuFrame->format == AV_PIX_FMT_CUDA ){
LOG_DEBUG("decode task: gpuid: {} width: {} height: {}", m_cfg.gpuid, gpuFrame->width, gpuFrame->height);
GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, getName(), m_cfg.gpuid , true);
if (gpuMem->getMem() == nullptr){
LOG_ERROR("new GpuRgbMemory failed !!!");
return nullptr;
}
cudaSetDevice(atoi(m_cfg.gpuid.c_str()));
cuda_common::setColorSpace( ITU_709, 0 );
cudaError_t cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], gpuMem->getMem(), gpuFrame->width, gpuFrame->height);
cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
LOG_ERROR("CUDAToBGR failed failed !!!");
return nullptr;
}
unsigned char * pHwRgb = gpuMem->getMem();
int channel = gpuMem->getChannel();
int width = gpuMem->getWidth();
int height = gpuMem->getHeight();
if (pHwRgb != nullptr && channel > 0 && width > 0 && height > 0){
int nSize = channel * height * width;
LOG_INFO("channel:{} height:{} width:{}", channel, height, width);
// unsigned char* cpu_data = new unsigned char[nSize];
unsigned char* cpu_data = (unsigned char *)av_malloc(nSize * sizeof(unsigned char));
cudaMemcpy(cpu_data, pHwRgb, nSize * sizeof(unsigned char), cudaMemcpyDeviceToHost);
cudaDeviceSynchronize();
delete gpuMem;
gpuMem = nullptr;
FFImgInfo* imgInfo = new FFImgInfo();
imgInfo->dec_name = m_dec_name;
imgInfo->pData = cpu_data;
imgInfo->height = height;
imgInfo->width = width;
imgInfo->timestamp = UtilTools::get_cur_time_ms();
imgInfo->index = m_index;
m_index++;
return imgInfo;
}
delete gpuMem;
gpuMem = nullptr;
}
return nullptr;
}
|