Commit 3c7e3e11e19bf471a835a17f40ae895783bbf6ab
1 parent
0a826b3d
1.修改日志
2.添加DECODE_FINISHED_CALLBACK 3.添加isPausing接口 4.添加getCachedQueueLength接口 5.添加snapshot和releaseFFImgInfo接口 6.测试代码添加log回调的自定义设置
Showing
5 changed files
with
410 additions
and
60 deletions
src/FFNvDecoder.cpp
1 | #include "FFNvDecoder.h" | 1 | #include "FFNvDecoder.h" |
2 | -#include<iostream> | ||
3 | 2 | ||
4 | #include <chrono> | 3 | #include <chrono> |
5 | #include <thread> | 4 | #include <thread> |
@@ -24,7 +23,7 @@ static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *p | @@ -24,7 +23,7 @@ static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *p | ||
24 | return *p; | 23 | return *p; |
25 | } | 24 | } |
26 | 25 | ||
27 | - //cout << "Failed to get HW surface format"; | 26 | + av_log(NULL, AV_LOG_ERROR, "Failed to get HW surface format. \n"); |
28 | return AV_PIX_FMT_NONE; | 27 | return AV_PIX_FMT_NONE; |
29 | } | 28 | } |
30 | 29 | ||
@@ -86,13 +85,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | @@ -86,13 +85,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | ||
86 | fmt_ctx = avformat_alloc_context(); | 85 | fmt_ctx = avformat_alloc_context(); |
87 | const char* input_file = uri; | 86 | const char* input_file = uri; |
88 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { | 87 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { |
89 | - cout << "Cannot open input file: " << input_file; | 88 | + av_log(NULL, AV_LOG_ERROR, "Cannot open input file: %s \n", input_file); |
90 | return false; | 89 | return false; |
91 | } | 90 | } |
92 | 91 | ||
93 | // 查找流信息 | 92 | // 查找流信息 |
94 | if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) { | 93 | if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) { |
95 | - cout << "Cannot find input stream information"; | 94 | + av_log(NULL, AV_LOG_ERROR, "Cannot find input stream information ! \n"); |
96 | return false; | 95 | return false; |
97 | } | 96 | } |
98 | 97 | ||
@@ -100,7 +99,7 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | @@ -100,7 +99,7 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | ||
100 | AVCodec *decoder = nullptr; | 99 | AVCodec *decoder = nullptr; |
101 | stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); | 100 | stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); |
102 | if (stream_index < 0) { | 101 | if (stream_index < 0) { |
103 | - cout << "Cannot find a video stream in the input file"; | 102 | + av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n"); |
104 | return false; | 103 | return false; |
105 | } | 104 | } |
106 | 105 | ||
@@ -130,9 +129,9 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | @@ -130,9 +129,9 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) | ||
130 | // 打开解码器流 | 129 | // 打开解码器流 |
131 | AVDictionary *op = nullptr; | 130 | AVDictionary *op = nullptr; |
132 | av_dict_set( &op, "gpu", gpuid, 0 ); | 131 | av_dict_set( &op, "gpu", gpuid, 0 ); |
133 | - // av_dict_set( &op, "surfaces", "3", 0 ); | 132 | + av_dict_set( &op, "surfaces", "10", 0 ); |
134 | if (avcodec_open2(avctx, vcodec, &op) < 0) { | 133 | if (avcodec_open2(avctx, vcodec, &op) < 0) { |
135 | - cout << "Failed to open codec for stream" << stream_index; | 134 | + av_log(NULL, AV_LOG_ERROR, "Failed to open codec for stream ! \n"); |
136 | return false; | 135 | return false; |
137 | } | 136 | } |
138 | 137 | ||
@@ -208,14 +207,9 @@ void FFNvDecoder::decode_thread() | @@ -208,14 +207,9 @@ void FFNvDecoder::decode_thread() | ||
208 | } | 207 | } |
209 | 208 | ||
210 | int result = av_read_frame(fmt_ctx, pkt); | 209 | int result = av_read_frame(fmt_ctx, pkt); |
211 | - if (result == AVERROR_EOF) | 210 | + if (result == AVERROR_EOF || result < 0) |
212 | { | 211 | { |
213 | - cout << "Failed to read frame!" << endl; | ||
214 | - break; | ||
215 | - } | ||
216 | - if (result < 0) | ||
217 | - { | ||
218 | - cout << "Failed to read frame!" << endl; | 212 | + av_log(NULL, AV_LOG_ERROR, "Failed to read frame! \n"); |
219 | break; | 213 | break; |
220 | } | 214 | } |
221 | 215 | ||
@@ -234,19 +228,16 @@ void FFNvDecoder::decode_thread() | @@ -234,19 +228,16 @@ void FFNvDecoder::decode_thread() | ||
234 | } | 228 | } |
235 | } | 229 | } |
236 | 230 | ||
237 | - if (stream_index == pkt->stream_index) | ||
238 | - { | 231 | + if (stream_index == pkt->stream_index){ |
239 | result = avcodec_send_packet(avctx, pkt); | 232 | result = avcodec_send_packet(avctx, pkt); |
240 | - if (result < 0) | ||
241 | - { | ||
242 | - cout << "Failed to send pkt:" << result << endl; | 233 | + if (result < 0){ |
234 | + av_log(NULL, AV_LOG_ERROR, "Failed to send pkt: %d \n",result); | ||
243 | continue; | 235 | continue; |
244 | } | 236 | } |
245 | 237 | ||
246 | result = avcodec_receive_frame(avctx, gpuFrame); | 238 | result = avcodec_receive_frame(avctx, gpuFrame); |
247 | - if (result == AVERROR(EAGAIN) || result == AVERROR_EOF || result < 0) | ||
248 | - { | ||
249 | - cout << "Failed to receive frame"<< endl; | 239 | + if ((result == AVERROR(EAGAIN) || result == AVERROR_EOF) || result < 0){ |
240 | + av_log(NULL, AV_LOG_ERROR, "Failed to receive frame: %d \n",result); | ||
250 | continue; | 241 | continue; |
251 | } | 242 | } |
252 | 243 | ||
@@ -255,6 +246,14 @@ void FFNvDecoder::decode_thread() | @@ -255,6 +246,14 @@ void FFNvDecoder::decode_thread() | ||
255 | av_packet_unref(pkt); | 246 | av_packet_unref(pkt); |
256 | } | 247 | } |
257 | 248 | ||
249 | + // 队列中没有数据了再结束 | ||
250 | + while (mFrameQueue.length() > 0){ | ||
251 | + if(!m_bRunning){ | ||
252 | + break; | ||
253 | + } | ||
254 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
255 | + } | ||
256 | + | ||
258 | m_bRunning = false; | 257 | m_bRunning = false; |
259 | 258 | ||
260 | // long end_time = get_cur_time(); | 259 | // long end_time = get_cur_time(); |
@@ -266,9 +265,11 @@ void FFNvDecoder::decode_thread() | @@ -266,9 +265,11 @@ void FFNvDecoder::decode_thread() | ||
266 | pthread_join(m_post_decode_thread,0); | 265 | pthread_join(m_post_decode_thread,0); |
267 | } | 266 | } |
268 | 267 | ||
268 | + decode_finished_cbk(m_userPtr); | ||
269 | + | ||
269 | decode_finished(); | 270 | decode_finished(); |
270 | 271 | ||
271 | - cout << "decode thread exited." << endl; | 272 | + av_log(NULL, AV_LOG_INFO, "decode thread exited. \n"); |
272 | } | 273 | } |
273 | 274 | ||
274 | void FFNvDecoder::decode_finished() | 275 | void FFNvDecoder::decode_finished() |
@@ -289,7 +290,7 @@ void FFNvDecoder::decode_finished() | @@ -289,7 +290,7 @@ void FFNvDecoder::decode_finished() | ||
289 | 290 | ||
290 | void FFNvDecoder::post_decode_thread() | 291 | void FFNvDecoder::post_decode_thread() |
291 | { | 292 | { |
292 | - while (m_bRunning) | 293 | + while (m_bRunning || mFrameQueue.length() > 0) |
293 | { | 294 | { |
294 | AVFrame * gpuFrame = mFrameQueue.getHead(); | 295 | AVFrame * gpuFrame = mFrameQueue.getHead(); |
295 | if (gpuFrame == nullptr) | 296 | if (gpuFrame == nullptr) |
@@ -302,8 +303,8 @@ void FFNvDecoder::post_decode_thread() | @@ -302,8 +303,8 @@ void FFNvDecoder::post_decode_thread() | ||
302 | 303 | ||
303 | mFrameQueue.addHead(); | 304 | mFrameQueue.addHead(); |
304 | } | 305 | } |
305 | - | ||
306 | - cout << "post decode thread exited." << endl; | 306 | + |
307 | + av_log(NULL, AV_LOG_INFO, "post decode thread exited. \n"); | ||
307 | } | 308 | } |
308 | 309 | ||
309 | void FFNvDecoder::close() | 310 | void FFNvDecoder::close() |
@@ -338,6 +339,10 @@ bool FFNvDecoder::isFinished() | @@ -338,6 +339,10 @@ bool FFNvDecoder::isFinished() | ||
338 | return m_bFinished; | 339 | return m_bFinished; |
339 | } | 340 | } |
340 | 341 | ||
342 | +bool FFNvDecoder::isPausing(){ | ||
343 | + return m_bPause; | ||
344 | +} | ||
345 | + | ||
341 | bool FFNvDecoder::getResolution( int &width, int &height ) | 346 | bool FFNvDecoder::getResolution( int &width, int &height ) |
342 | { | 347 | { |
343 | if (avctx != nullptr) | 348 | if (avctx != nullptr) |
@@ -363,4 +368,135 @@ void FFNvDecoder::resume() | @@ -363,4 +368,135 @@ void FFNvDecoder::resume() | ||
363 | void FFNvDecoder::setDecKeyframe(bool bKeyframe) | 368 | void FFNvDecoder::setDecKeyframe(bool bKeyframe) |
364 | { | 369 | { |
365 | m_dec_keyframe = bKeyframe; | 370 | m_dec_keyframe = bKeyframe; |
371 | +} | ||
372 | + | ||
373 | +int FFNvDecoder::getCachedQueueLength(){ | ||
374 | + return mFrameQueue.length(); | ||
375 | +} | ||
376 | + | ||
377 | +FFImgInfo* FFNvDecoder::snapshot(const string& uri){ | ||
378 | + | ||
379 | + AVFormatContext* ifmt_ctx = NULL; | ||
380 | + AVCodecContext* codec_ctx = nullptr; | ||
381 | + AVCodec* codec = nullptr; | ||
382 | + AVPacket* pkt = nullptr; | ||
383 | + AVFrame *frame = nullptr; | ||
384 | + AVFrame *pFrameRGB = nullptr; | ||
385 | + int video_index = -1; | ||
386 | + AVStream* st = nullptr; | ||
387 | + SwsContext *img_convert_ctx = nullptr; | ||
388 | + uint8_t *buffer = NULL; | ||
389 | + int numBytes = 0; | ||
390 | + | ||
391 | + FFImgInfo* imgInfo = nullptr; | ||
392 | + | ||
393 | + //av_register_all(); | ||
394 | + avformat_network_init(); | ||
395 | + | ||
396 | + ///打开输入的流 | ||
397 | + int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), NULL, NULL); | ||
398 | + if (ret != 0){ | ||
399 | + av_log(NULL, AV_LOG_ERROR, "Couldn't open input stream ! \n"); | ||
400 | + goto end_flag ; | ||
401 | + } | ||
402 | + | ||
403 | + //查找流信息 | ||
404 | + if (avformat_find_stream_info(ifmt_ctx, NULL) < 0){ | ||
405 | + av_log(NULL, AV_LOG_ERROR, "Couldn't find stream information ! \n"); | ||
406 | + goto end_flag ; | ||
407 | + } | ||
408 | + | ||
409 | + //找到视频流索引 | ||
410 | + video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); | ||
411 | + | ||
412 | + st = ifmt_ctx->streams[video_index]; | ||
413 | + | ||
414 | + //找到解码器 | ||
415 | + codec = avcodec_find_decoder(st->codecpar->codec_id); | ||
416 | + if (!codec){ | ||
417 | + av_log(NULL, AV_LOG_ERROR, "Codec not found ! \n"); | ||
418 | + goto end_flag ; | ||
419 | + } | ||
420 | + | ||
421 | + //申请AVCodecContext | ||
422 | + codec_ctx = avcodec_alloc_context3(codec); | ||
423 | + if (!codec_ctx){ | ||
424 | + goto end_flag ; | ||
425 | + } | ||
426 | + | ||
427 | + avcodec_parameters_to_context(codec_ctx, ifmt_ctx->streams[video_index]->codecpar); | ||
428 | + | ||
429 | + //打开解码器 | ||
430 | + if ((ret = avcodec_open2(codec_ctx, codec, NULL) < 0)){ | ||
431 | + goto end_flag ; | ||
432 | + } | ||
433 | + | ||
434 | + // 计算解码后原始数据所需缓冲区大小,并分配内存空间 Determine required buffer size and allocate buffer | ||
435 | + numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1); | ||
436 | + buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t)); | ||
437 | + | ||
438 | + pFrameRGB = av_frame_alloc(); | ||
439 | + av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_BGR24, codec_ctx->width, codec_ctx->height, 1); | ||
440 | + | ||
441 | + img_convert_ctx = sws_getContext(codec_ctx->width, codec_ctx->height,codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_BGR24, | ||
442 | + SWS_BICUBIC, NULL, NULL, NULL); | ||
443 | + | ||
444 | + pkt = av_packet_alloc(); | ||
445 | + frame = av_frame_alloc(); | ||
446 | + while (av_read_frame(ifmt_ctx, pkt) >= 0){ | ||
447 | + if (pkt->stream_index == video_index){ | ||
448 | + int ret = avcodec_send_packet(codec_ctx, pkt); | ||
449 | + if (ret >= 0){ | ||
450 | + ret = avcodec_receive_frame(codec_ctx, frame); | ||
451 | + if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ | ||
452 | + av_log(NULL, AV_LOG_ERROR, "Failed to receive frame: %d \n", ret); | ||
453 | + continue; | ||
454 | + } | ||
455 | + | ||
456 | + sws_scale(img_convert_ctx, (const unsigned char* const*)frame->data, frame->linesize, 0, codec_ctx->height, pFrameRGB->data, pFrameRGB->linesize); | ||
457 | + | ||
458 | + imgInfo = new FFImgInfo(); | ||
459 | + imgInfo->pData = buffer; | ||
460 | + imgInfo->height = codec_ctx->height; | ||
461 | + imgInfo->width = codec_ctx->width; | ||
462 | + | ||
463 | + break; | ||
464 | + } | ||
465 | + } | ||
466 | + } | ||
467 | + | ||
468 | +end_flag: | ||
469 | + if (codec_ctx != nullptr){ | ||
470 | + avcodec_close(codec_ctx); | ||
471 | + avcodec_free_context(&codec_ctx); | ||
472 | + } | ||
473 | + | ||
474 | + if (ifmt_ctx != nullptr){ | ||
475 | + avformat_close_input(&ifmt_ctx); | ||
476 | + } | ||
477 | + | ||
478 | + if (frame != nullptr){ | ||
479 | + av_frame_free(&frame); | ||
480 | + } | ||
481 | + | ||
482 | + if (pFrameRGB != nullptr){ | ||
483 | + av_frame_free(&pFrameRGB); | ||
484 | + } | ||
485 | + | ||
486 | + if (pkt != nullptr){ | ||
487 | + av_packet_free(&pkt); | ||
488 | + } | ||
489 | + | ||
490 | + return imgInfo; | ||
491 | +} | ||
492 | + | ||
493 | +void FFNvDecoder::releaseFFImgInfo(FFImgInfo* info){ | ||
494 | + if(nullptr != info){ | ||
495 | + if(info->pData != nullptr){ | ||
496 | + av_free(info->pData); | ||
497 | + info->pData = nullptr; | ||
498 | + } | ||
499 | + delete info; | ||
500 | + info = nullptr; | ||
501 | + } | ||
366 | } | 502 | } |
367 | \ No newline at end of file | 503 | \ No newline at end of file |
src/FFNvDecoder.h
@@ -12,6 +12,7 @@ extern "C" | @@ -12,6 +12,7 @@ extern "C" | ||
12 | #include <libavutil/avutil.h> | 12 | #include <libavutil/avutil.h> |
13 | #include <libavutil/pixdesc.h> | 13 | #include <libavutil/pixdesc.h> |
14 | #include <libswscale/swscale.h> | 14 | #include <libswscale/swscale.h> |
15 | + #include <libavutil/imgutils.h> | ||
15 | } | 16 | } |
16 | 17 | ||
17 | using namespace std; | 18 | using namespace std; |
@@ -29,14 +30,22 @@ using namespace std; | @@ -29,14 +30,22 @@ using namespace std; | ||
29 | **************************************************/ | 30 | **************************************************/ |
30 | typedef void(*POST_DECODE_CALLBACK)(const void * userPtr, AVFrame * gpuFrame); | 31 | typedef void(*POST_DECODE_CALLBACK)(const void * userPtr, AVFrame * gpuFrame); |
31 | 32 | ||
32 | -struct FFDecConfig | ||
33 | -{ | 33 | +typedef void(*DECODE_FINISHED_CALLBACK)(const void* userPtr); |
34 | + | ||
35 | +struct FFDecConfig{ | ||
34 | string uri; // 视频地址 | 36 | string uri; // 视频地址 |
35 | POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 | 37 | POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 |
38 | + DECODE_FINISHED_CALLBACK decode_finished_cbk; // 解码线程结束后的回调接口 | ||
36 | string gpuid; // gpu id | 39 | string gpuid; // gpu id |
37 | bool force_tcp{true}; // 是否指定使用tcp连接 | 40 | bool force_tcp{true}; // 是否指定使用tcp连接 |
38 | }; | 41 | }; |
39 | 42 | ||
43 | +struct FFImgInfo{ | ||
44 | + int width; | ||
45 | + int height; | ||
46 | + unsigned char * pData; | ||
47 | +}; | ||
48 | + | ||
40 | class FFNvDecoder{ | 49 | class FFNvDecoder{ |
41 | public: | 50 | public: |
42 | FFNvDecoder(); | 51 | FFNvDecoder(); |
@@ -51,6 +60,7 @@ public: | @@ -51,6 +60,7 @@ public: | ||
51 | 60 | ||
52 | bool isRunning(); | 61 | bool isRunning(); |
53 | bool isFinished(); | 62 | bool isFinished(); |
63 | + bool isPausing(); | ||
54 | bool getResolution( int &width, int &height ); | 64 | bool getResolution( int &width, int &height ); |
55 | 65 | ||
56 | void setName(string nm); | 66 | void setName(string nm); |
@@ -58,6 +68,12 @@ public: | @@ -58,6 +68,12 @@ public: | ||
58 | 68 | ||
59 | bool isSurport(FFDecConfig& cfg); | 69 | bool isSurport(FFDecConfig& cfg); |
60 | 70 | ||
71 | + int getCachedQueueLength(); | ||
72 | + | ||
73 | + static FFImgInfo* snapshot(const string& uri); | ||
74 | + | ||
75 | + static void releaseFFImgInfo(FFImgInfo*); | ||
76 | + | ||
61 | public: | 77 | public: |
62 | AVPixelFormat getHwPixFmt(); | 78 | AVPixelFormat getHwPixFmt(); |
63 | 79 | ||
@@ -69,6 +85,7 @@ private: | @@ -69,6 +85,7 @@ private: | ||
69 | 85 | ||
70 | public: | 86 | public: |
71 | POST_DECODE_CALLBACK post_decoded_cbk; | 87 | POST_DECODE_CALLBACK post_decoded_cbk; |
88 | + DECODE_FINISHED_CALLBACK decode_finished_cbk; | ||
72 | const void * m_userPtr; | 89 | const void * m_userPtr; |
73 | FFDecConfig m_cfg; | 90 | FFDecConfig m_cfg; |
74 | 91 |
src/FFNvDecoderManager.cpp
1 | #include "FFNvDecoderManager.h" | 1 | #include "FFNvDecoderManager.h" |
2 | -#include<iostream> | ||
3 | 2 | ||
4 | using namespace std; | 3 | using namespace std; |
5 | 4 | ||
6 | 5 | ||
7 | -FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ | 6 | +FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){ |
8 | 7 | ||
9 | closeAllFinishedDecoder(); | 8 | closeAllFinishedDecoder(); |
10 | 9 | ||
11 | - int num = decoderMap.count(config.name); | ||
12 | - if (num > 0) | ||
13 | - { | ||
14 | - cout << "已存在name所标记的解码器" << endl; | 10 | + std::lock_guard<std::mutex> l(m_mutex); |
11 | + | ||
12 | + auto it = decoderMap.find(config.name); | ||
13 | + if (it != decoderMap.end()){ | ||
14 | + av_log(NULL, AV_LOG_ERROR, "已存在name所标记的解码器 \n"); | ||
15 | return nullptr; | 15 | return nullptr; |
16 | } | 16 | } |
17 | 17 | ||
@@ -26,6 +26,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ | @@ -26,6 +26,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ | ||
26 | { | 26 | { |
27 | dec->setName(config.name) ; | 27 | dec->setName(config.name) ; |
28 | dec->post_decoded_cbk = config.cfg.post_decoded_cbk; | 28 | dec->post_decoded_cbk = config.cfg.post_decoded_cbk; |
29 | + dec->decode_finished_cbk = config.cfg.decode_finished_cbk; | ||
29 | decoderMap[config.name] = dec; | 30 | decoderMap[config.name] = dec; |
30 | return dec; | 31 | return dec; |
31 | } | 32 | } |
@@ -41,10 +42,12 @@ bool FFNvDecoderManager::setUserPtr(const string name, const void * userPtr) | @@ -41,10 +42,12 @@ bool FFNvDecoderManager::setUserPtr(const string name, const void * userPtr) | ||
41 | { | 42 | { |
42 | if (name.empty()) | 43 | if (name.empty()) |
43 | { | 44 | { |
44 | - cout << "name 为空!"<< endl; | 45 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
45 | return false; | 46 | return false; |
46 | } | 47 | } |
47 | 48 | ||
49 | + std::lock_guard<std::mutex> l(m_mutex); | ||
50 | + | ||
48 | auto dec = decoderMap.find(name); | 51 | auto dec = decoderMap.find(name); |
49 | if (dec != decoderMap.end()) | 52 | if (dec != decoderMap.end()) |
50 | { | 53 | { |
@@ -52,7 +55,7 @@ bool FFNvDecoderManager::setUserPtr(const string name, const void * userPtr) | @@ -52,7 +55,7 @@ bool FFNvDecoderManager::setUserPtr(const string name, const void * userPtr) | ||
52 | return true; | 55 | return true; |
53 | } | 56 | } |
54 | 57 | ||
55 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 58 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
56 | return false; | 59 | return false; |
57 | } | 60 | } |
58 | 61 | ||
@@ -60,17 +63,19 @@ FFNvDecoder* FFNvDecoderManager::getDecoderByName(const string name) | @@ -60,17 +63,19 @@ FFNvDecoder* FFNvDecoderManager::getDecoderByName(const string name) | ||
60 | { | 63 | { |
61 | if (name.empty()) | 64 | if (name.empty()) |
62 | { | 65 | { |
63 | - cout << "name 为空!"<< endl; | 66 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
64 | return nullptr; | 67 | return nullptr; |
65 | } | 68 | } |
66 | 69 | ||
70 | + std::lock_guard<std::mutex> l(m_mutex); | ||
71 | + | ||
67 | auto dec = decoderMap.find(name); | 72 | auto dec = decoderMap.find(name); |
68 | if (dec != decoderMap.end()) | 73 | if (dec != decoderMap.end()) |
69 | { | 74 | { |
70 | return dec->second; | 75 | return dec->second; |
71 | } | 76 | } |
72 | 77 | ||
73 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 78 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
74 | return nullptr; | 79 | return nullptr; |
75 | } | 80 | } |
76 | 81 | ||
@@ -84,10 +89,12 @@ void FFNvDecoderManager::startDecode(FFNvDecoder* dec){ | @@ -84,10 +89,12 @@ void FFNvDecoderManager::startDecode(FFNvDecoder* dec){ | ||
84 | bool FFNvDecoderManager::startDecodeByName(const string name){ | 89 | bool FFNvDecoderManager::startDecodeByName(const string name){ |
85 | if (name.empty()) | 90 | if (name.empty()) |
86 | { | 91 | { |
87 | - cout << "name 为空!"<< endl; | 92 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
88 | return false; | 93 | return false; |
89 | } | 94 | } |
90 | 95 | ||
96 | + std::lock_guard<std::mutex> l(m_mutex); | ||
97 | + | ||
91 | auto dec = decoderMap.find(name); | 98 | auto dec = decoderMap.find(name); |
92 | if (dec != decoderMap.end()) | 99 | if (dec != decoderMap.end()) |
93 | { | 100 | { |
@@ -95,11 +102,14 @@ bool FFNvDecoderManager::startDecodeByName(const string name){ | @@ -95,11 +102,14 @@ bool FFNvDecoderManager::startDecodeByName(const string name){ | ||
95 | return true; | 102 | return true; |
96 | } | 103 | } |
97 | 104 | ||
98 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 105 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
99 | return false; | 106 | return false; |
100 | } | 107 | } |
101 | 108 | ||
102 | void FFNvDecoderManager::startAllDecode(){ | 109 | void FFNvDecoderManager::startAllDecode(){ |
110 | + | ||
111 | + std::lock_guard<std::mutex> l(m_mutex); | ||
112 | + | ||
103 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ | 113 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ |
104 | if (!iter->second->isRunning()) | 114 | if (!iter->second->isRunning()) |
105 | { | 115 | { |
@@ -111,11 +121,12 @@ void FFNvDecoderManager::startAllDecode(){ | @@ -111,11 +121,12 @@ void FFNvDecoderManager::startAllDecode(){ | ||
111 | bool FFNvDecoderManager::closeDecoderByName(const string name){ | 121 | bool FFNvDecoderManager::closeDecoderByName(const string name){ |
112 | if (name.empty()) | 122 | if (name.empty()) |
113 | { | 123 | { |
114 | - cout << "name 为空!"<< endl; | 124 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
115 | return false; | 125 | return false; |
116 | } | 126 | } |
117 | 127 | ||
118 | - m_mutex_erase.lock(); | 128 | + std::lock_guard<std::mutex> l(m_mutex); |
129 | + | ||
119 | auto dec = decoderMap.find(name); | 130 | auto dec = decoderMap.find(name); |
120 | if (dec != decoderMap.end()) | 131 | if (dec != decoderMap.end()) |
121 | { | 132 | { |
@@ -124,30 +135,29 @@ bool FFNvDecoderManager::closeDecoderByName(const string name){ | @@ -124,30 +135,29 @@ bool FFNvDecoderManager::closeDecoderByName(const string name){ | ||
124 | dec->second = nullptr; | 135 | dec->second = nullptr; |
125 | decoderMap.erase(dec); | 136 | decoderMap.erase(dec); |
126 | 137 | ||
127 | - m_mutex_erase.unlock(); | ||
128 | return true; | 138 | return true; |
129 | } | 139 | } |
130 | 140 | ||
131 | - m_mutex_erase.unlock(); | ||
132 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 141 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
133 | return false; | 142 | return false; |
134 | } | 143 | } |
135 | 144 | ||
136 | void FFNvDecoderManager::closeAllDecoder() | 145 | void FFNvDecoderManager::closeAllDecoder() |
137 | { | 146 | { |
138 | - m_mutex_erase.lock(); | 147 | + std::lock_guard<std::mutex> l(m_mutex); |
148 | + | ||
139 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ | 149 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ |
140 | iter->second->close(); | 150 | iter->second->close(); |
141 | delete iter->second; | 151 | delete iter->second; |
142 | iter->second = nullptr; | 152 | iter->second = nullptr; |
143 | } | 153 | } |
144 | decoderMap.clear(); | 154 | decoderMap.clear(); |
145 | - m_mutex_erase.unlock(); | ||
146 | } | 155 | } |
147 | 156 | ||
148 | void FFNvDecoderManager::closeAllFinishedDecoder() | 157 | void FFNvDecoderManager::closeAllFinishedDecoder() |
149 | { | 158 | { |
150 | - m_mutex_erase.lock(); | 159 | + std::lock_guard<std::mutex> l(m_mutex); |
160 | + | ||
151 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); ){ | 161 | for(auto iter = decoderMap.begin(); iter != decoderMap.end(); ){ |
152 | if (iter->second->isFinished()) | 162 | if (iter->second->isFinished()) |
153 | { | 163 | { |
@@ -160,13 +170,13 @@ void FFNvDecoderManager::closeAllFinishedDecoder() | @@ -160,13 +170,13 @@ void FFNvDecoderManager::closeAllFinishedDecoder() | ||
160 | iter++ ; | 170 | iter++ ; |
161 | } | 171 | } |
162 | } | 172 | } |
163 | - m_mutex_erase.unlock(); | ||
164 | } | 173 | } |
165 | 174 | ||
166 | int FFNvDecoderManager::count() | 175 | int FFNvDecoderManager::count() |
167 | { | 176 | { |
168 | closeAllFinishedDecoder(); | 177 | closeAllFinishedDecoder(); |
169 | 178 | ||
179 | + std::lock_guard<std::mutex> l(m_mutex); | ||
170 | return decoderMap.size(); | 180 | return decoderMap.size(); |
171 | } | 181 | } |
172 | 182 | ||
@@ -174,10 +184,12 @@ bool FFNvDecoderManager::pauseDecoder(const string name) | @@ -174,10 +184,12 @@ bool FFNvDecoderManager::pauseDecoder(const string name) | ||
174 | { | 184 | { |
175 | if (name.empty()) | 185 | if (name.empty()) |
176 | { | 186 | { |
177 | - cout << "name 为空!"<< endl; | 187 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
178 | return false; | 188 | return false; |
179 | } | 189 | } |
180 | 190 | ||
191 | + std::lock_guard<std::mutex> l(m_mutex); | ||
192 | + | ||
181 | auto dec = decoderMap.find(name); | 193 | auto dec = decoderMap.find(name); |
182 | if (dec != decoderMap.end()) | 194 | if (dec != decoderMap.end()) |
183 | { | 195 | { |
@@ -185,7 +197,7 @@ bool FFNvDecoderManager::pauseDecoder(const string name) | @@ -185,7 +197,7 @@ bool FFNvDecoderManager::pauseDecoder(const string name) | ||
185 | return true; | 197 | return true; |
186 | } | 198 | } |
187 | 199 | ||
188 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 200 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
189 | return false; | 201 | return false; |
190 | } | 202 | } |
191 | 203 | ||
@@ -193,10 +205,12 @@ bool FFNvDecoderManager::resumeDecoder(const string name) | @@ -193,10 +205,12 @@ bool FFNvDecoderManager::resumeDecoder(const string name) | ||
193 | { | 205 | { |
194 | if (name.empty()) | 206 | if (name.empty()) |
195 | { | 207 | { |
196 | - cout << "name 为空!"<< endl; | 208 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
197 | return false; | 209 | return false; |
198 | } | 210 | } |
199 | 211 | ||
212 | + std::lock_guard<std::mutex> l(m_mutex); | ||
213 | + | ||
200 | auto dec = decoderMap.find(name); | 214 | auto dec = decoderMap.find(name); |
201 | if (dec != decoderMap.end()) | 215 | if (dec != decoderMap.end()) |
202 | { | 216 | { |
@@ -204,7 +218,7 @@ bool FFNvDecoderManager::resumeDecoder(const string name) | @@ -204,7 +218,7 @@ bool FFNvDecoderManager::resumeDecoder(const string name) | ||
204 | return true; | 218 | return true; |
205 | } | 219 | } |
206 | 220 | ||
207 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 221 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
208 | return false; | 222 | return false; |
209 | } | 223 | } |
210 | 224 | ||
@@ -217,17 +231,57 @@ bool FFNvDecoderManager::isSurport(FFDecConfig& cfg) | @@ -217,17 +231,57 @@ bool FFNvDecoderManager::isSurport(FFDecConfig& cfg) | ||
217 | bool FFNvDecoderManager::isRunning(const string name){ | 231 | bool FFNvDecoderManager::isRunning(const string name){ |
218 | if (name.empty()) | 232 | if (name.empty()) |
219 | { | 233 | { |
220 | - cout << "name 为空!"<< endl; | 234 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
221 | return false; | 235 | return false; |
222 | } | 236 | } |
223 | 237 | ||
238 | + std::lock_guard<std::mutex> l(m_mutex); | ||
239 | + | ||
224 | auto dec = decoderMap.find(name); | 240 | auto dec = decoderMap.find(name); |
225 | if (dec != decoderMap.end()) | 241 | if (dec != decoderMap.end()) |
226 | { | 242 | { |
227 | return dec->second->isRunning(); | 243 | return dec->second->isRunning(); |
228 | } | 244 | } |
229 | 245 | ||
230 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 246 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
247 | + return false; | ||
248 | +} | ||
249 | + | ||
250 | +bool FFNvDecoderManager::isFinished(const string name){ | ||
251 | + if (name.empty()) | ||
252 | + { | ||
253 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); | ||
254 | + return false; | ||
255 | + } | ||
256 | + | ||
257 | + std::lock_guard<std::mutex> l(m_mutex); | ||
258 | + | ||
259 | + auto dec = decoderMap.find(name); | ||
260 | + if (dec != decoderMap.end()) | ||
261 | + { | ||
262 | + return dec->second->isFinished(); | ||
263 | + } | ||
264 | + | ||
265 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); | ||
266 | + return false; | ||
267 | +} | ||
268 | + | ||
269 | +bool FFNvDecoderManager::isPausing(const string name){ | ||
270 | + if (name.empty()) | ||
271 | + { | ||
272 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); | ||
273 | + return false; | ||
274 | + } | ||
275 | + | ||
276 | + std::lock_guard<std::mutex> l(m_mutex); | ||
277 | + | ||
278 | + auto dec = decoderMap.find(name); | ||
279 | + if (dec != decoderMap.end()) | ||
280 | + { | ||
281 | + return dec->second->isPausing(); | ||
282 | + } | ||
283 | + | ||
284 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); | ||
231 | return false; | 285 | return false; |
232 | } | 286 | } |
233 | 287 | ||
@@ -235,10 +289,12 @@ bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) | @@ -235,10 +289,12 @@ bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) | ||
235 | { | 289 | { |
236 | if (name.empty()) | 290 | if (name.empty()) |
237 | { | 291 | { |
238 | - cout << "name 为空!"<< endl; | 292 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); |
239 | return false; | 293 | return false; |
240 | } | 294 | } |
241 | 295 | ||
296 | + std::lock_guard<std::mutex> l(m_mutex); | ||
297 | + | ||
242 | auto dec = decoderMap.find(name); | 298 | auto dec = decoderMap.find(name); |
243 | if (dec != decoderMap.end()) | 299 | if (dec != decoderMap.end()) |
244 | { | 300 | { |
@@ -246,6 +302,65 @@ bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) | @@ -246,6 +302,65 @@ bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) | ||
246 | return true; | 302 | return true; |
247 | } | 303 | } |
248 | 304 | ||
249 | - cout << "没有找到name为" << name << "的解码器!" << endl; | 305 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); |
306 | + return false; | ||
307 | +} | ||
308 | + | ||
309 | +bool FFNvDecoderManager::getResolution(const string name, int &width, int &height) | ||
310 | +{ | ||
311 | + if (name.empty()) | ||
312 | + { | ||
313 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); | ||
314 | + return false; | ||
315 | + } | ||
316 | + | ||
317 | + std::lock_guard<std::mutex> l(m_mutex); | ||
318 | + | ||
319 | + auto dec = decoderMap.find(name); | ||
320 | + if (dec != decoderMap.end()) | ||
321 | + { | ||
322 | + dec->second->getResolution(width, height); | ||
323 | + return true; | ||
324 | + } | ||
325 | + | ||
326 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); | ||
250 | return false; | 327 | return false; |
328 | +} | ||
329 | + | ||
330 | +vector<string> FFNvDecoderManager::getAllDecodeName(){ | ||
331 | + | ||
332 | + closeAllFinishedDecoder(); | ||
333 | + | ||
334 | + std::lock_guard<std::mutex> l(m_mutex); | ||
335 | + | ||
336 | + vector<string> decode_names; | ||
337 | + for(auto it = decoderMap.begin(); it != decoderMap.end(); ++it){ | ||
338 | + decode_names.push_back(it->first); | ||
339 | + } | ||
340 | + return decode_names; | ||
341 | +} | ||
342 | + | ||
343 | +int FFNvDecoderManager::getCachedQueueLength(const string name){ | ||
344 | + if (name.empty()){ | ||
345 | + av_log(NULL, AV_LOG_ERROR, "name 为空! \n"); | ||
346 | + return -1; | ||
347 | + } | ||
348 | + | ||
349 | + std::lock_guard<std::mutex> l(m_mutex); | ||
350 | + | ||
351 | + auto dec = decoderMap.find(name); | ||
352 | + if (dec != decoderMap.end()){ | ||
353 | + return dec->second->getCachedQueueLength(); | ||
354 | + } | ||
355 | + | ||
356 | + av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str()); | ||
357 | + return -1; | ||
358 | +} | ||
359 | + | ||
360 | +FFImgInfo* FFNvDecoderManager::snapshot(const string& uri){ | ||
361 | + return FFNvDecoder::snapshot(uri); | ||
362 | +} | ||
363 | + | ||
364 | +void FFNvDecoderManager::releaseFFImgInfo(FFImgInfo* info){ | ||
365 | + FFNvDecoder::releaseFFImgInfo(info); | ||
251 | } | 366 | } |
252 | \ No newline at end of file | 367 | \ No newline at end of file |
src/FFNvDecoderManager.h
@@ -45,7 +45,7 @@ public: | @@ -45,7 +45,7 @@ public: | ||
45 | * 返回:成功返回解码器, 失败返回 nullptr | 45 | * 返回:成功返回解码器, 失败返回 nullptr |
46 | * 备注: | 46 | * 备注: |
47 | **************************************************/ | 47 | **************************************************/ |
48 | - FFNvDecoder* createDecoder(MgrDecConfig& config); | 48 | + FFNvDecoder* createDecoder(MgrDecConfig config); |
49 | 49 | ||
50 | /************************************************** | 50 | /************************************************** |
51 | * 接口:setUserPtr | 51 | * 接口:setUserPtr |
@@ -111,6 +111,15 @@ public: | @@ -111,6 +111,15 @@ public: | ||
111 | **************************************************/ | 111 | **************************************************/ |
112 | void closeAllDecoder(); | 112 | void closeAllDecoder(); |
113 | 113 | ||
114 | + /************************************************** | ||
115 | + * 接口:closeAllDecoderByGpuid | ||
116 | + * 功能:关闭某张显卡撒花姑娘的全部解码器 | ||
117 | + * 参数:const string gpuid gpu的id | ||
118 | + * 返回:void | ||
119 | + * 备注: | ||
120 | + **************************************************/ | ||
121 | + void closeAllDecoderByGpuid(const string gpuid); | ||
122 | + | ||
114 | /************************************************** | 123 | /************************************************** |
115 | * 接口:pauseDecoder | 124 | * 接口:pauseDecoder |
116 | * 功能:暂停指定名称的解码器 | 125 | * 功能:暂停指定名称的解码器 |
@@ -147,6 +156,24 @@ public: | @@ -147,6 +156,24 @@ public: | ||
147 | **************************************************/ | 156 | **************************************************/ |
148 | bool isRunning(const string name); | 157 | bool isRunning(const string name); |
149 | 158 | ||
159 | + /************************************************** | ||
160 | + * 接口:isFinished | ||
161 | + * 功能:根据解码器名称判断解码器是否已经结束 | ||
162 | + * 参数:const string name 解码器名称 | ||
163 | + * 返回:正在运行返回true,否则返回false | ||
164 | + * 备注: | ||
165 | + **************************************************/ | ||
166 | + bool isFinished(const string name); | ||
167 | + | ||
168 | + /************************************************** | ||
169 | + * 接口:isPausing | ||
170 | + * 功能:根据解码器名称判断解码器是否暂停 | ||
171 | + * 参数:const string name 解码器名称 | ||
172 | + * 返回:正在运行返回true,否则返回false | ||
173 | + * 备注: | ||
174 | + **************************************************/ | ||
175 | + bool isPausing(const string name); | ||
176 | + | ||
150 | /************************************************** | 177 | /************************************************** |
151 | * 接口:count | 178 | * 接口:count |
152 | * 功能:获取正在运行的解码器数量 | 179 | * 功能:获取正在运行的解码器数量 |
@@ -161,11 +188,58 @@ public: | @@ -161,11 +188,58 @@ public: | ||
161 | * 功能:设置是否只解码关键帧。默认全解 | 188 | * 功能:设置是否只解码关键帧。默认全解 |
162 | * 参数:const string name 解码器名称 | 189 | * 参数:const string name 解码器名称 |
163 | * bool bKeyframe 是否只解码关键帧。true,只解码关键帧;false,普通的全解码 | 190 | * bool bKeyframe 是否只解码关键帧。true,只解码关键帧;false,普通的全解码 |
164 | - * 返回:void | 191 | + * 返回:bool 成功返回true,失败返回false |
165 | * 备注: | 192 | * 备注: |
166 | **************************************************/ | 193 | **************************************************/ |
167 | bool setDecKeyframe(const string name, bool bKeyframe); | 194 | bool setDecKeyframe(const string name, bool bKeyframe); |
168 | 195 | ||
196 | + /************************************************** | ||
197 | + * 接口:getResolution | ||
198 | + * 功能:获取视频分辨率 | ||
199 | + * 参数:const string name 解码器名称 | ||
200 | + * int &width 从 width 返回视频宽度 | ||
201 | + * int &height 从 height 返回视频高度 | ||
202 | + * 返回:bool 成功获取返回true,失败返回false | ||
203 | + * 备注: | ||
204 | + **************************************************/ | ||
205 | + bool getResolution(const string name, int &width, int &height); | ||
206 | + | ||
207 | + /************************************************** | ||
208 | + * 接口:getAllDecodeName | ||
209 | + * 功能:获取全部解码器名称 | ||
210 | + * 参数:void | ||
211 | + * 返回:vector<string> 返回全部解码器名称 | ||
212 | + * 备注: | ||
213 | + **************************************************/ | ||
214 | + vector<string> getAllDecodeName(); | ||
215 | + | ||
216 | + /************************************************** | ||
217 | + * 接口:getCachedQueueLength | ||
218 | + * 功能:获取解码缓冲队列当前长度 | ||
219 | + * 参数:const string name 解码器名称 | ||
220 | + * 返回:int 解码缓冲队列当前长度 | ||
221 | + * 备注: | ||
222 | + **************************************************/ | ||
223 | + int getCachedQueueLength(const string name); | ||
224 | + | ||
225 | + /************************************************** | ||
226 | + * 接口:snapshot | ||
227 | + * 功能:获取视频快照 | ||
228 | + * 参数:const string& uri 视频地址 | ||
229 | + * 返回:FFImgInfo* 快照信息 | ||
230 | + * 备注: | ||
231 | + **************************************************/ | ||
232 | + FFImgInfo* snapshot(const string& uri); | ||
233 | + | ||
234 | + /************************************************** | ||
235 | + * 接口:releaseFFImgInfo | ||
236 | + * 功能:释放视频快照信息 | ||
237 | + * 参数:FFImgInfo* info 视频快照信息 | ||
238 | + * 返回:void | ||
239 | + * 备注: | ||
240 | + **************************************************/ | ||
241 | + void releaseFFImgInfo(FFImgInfo* info); | ||
242 | + | ||
169 | private: | 243 | private: |
170 | FFNvDecoderManager(){} | 244 | FFNvDecoderManager(){} |
171 | 245 | ||
@@ -174,5 +248,5 @@ private: | @@ -174,5 +248,5 @@ private: | ||
174 | private: | 248 | private: |
175 | map<string, FFNvDecoder*> decoderMap; | 249 | map<string, FFNvDecoder*> decoderMap; |
176 | 250 | ||
177 | - mutex m_mutex_erase; | 251 | + mutex m_mutex; |
178 | }; | 252 | }; |
179 | \ No newline at end of file | 253 | \ No newline at end of file |
src/main.cpp
@@ -225,8 +225,16 @@ int CheckCUDAProperty( int devId ) | @@ -225,8 +225,16 @@ int CheckCUDAProperty( int devId ) | ||
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | 227 | ||
228 | +void logFF(void *, int level, const char *fmt, va_list ap) | ||
229 | +{ | ||
230 | + vfprintf(stdout, fmt, ap); | ||
231 | +} | ||
232 | + | ||
233 | + | ||
228 | int main(){ | 234 | int main(){ |
229 | 235 | ||
236 | + // av_log_set_callback(&logFF); | ||
237 | + | ||
230 | CheckCUDAProperty(0); | 238 | CheckCUDAProperty(0); |
231 | 239 | ||
232 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); | 240 | FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); |