Commit 34cc7f89b1d64f58347defb7fe99928917a8a2f5

Authored by Hu Chunming
2 parents bc52e542 6fc86385

Merge branch 'dev-wsl' into 'dev-cmhu'

Dev wsl

See merge request !3
.vscode/launch.json
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 "type": "cppdbg", 6 "type": "cppdbg",
7 "request": "launch", 7 "request": "launch",
8 "program": "${workspaceFolder}/bin/lib/test", 8 "program": "${workspaceFolder}/bin/lib/test",
9 - "args": [], 9 + "args": ["rtsp://176.10.0.4:8554/stream","0"],
10 "stopAtEntry": false, 10 "stopAtEntry": false,
11 "cwd": "${workspaceFolder}/bin/lib", 11 "cwd": "${workspaceFolder}/bin/lib",
12 "environment": [], 12 "environment": [],
.vscode/settings.json
@@ -10,6 +10,57 @@ @@ -10,6 +10,57 @@
10 "iostream": "cpp", 10 "iostream": "cpp",
11 "thread": "cpp", 11 "thread": "cpp",
12 "nvdec.h": "c", 12 "nvdec.h": "c",
13 - "chrono": "cpp" 13 + "chrono": "cpp",
  14 + "atomic": "cpp",
  15 + "bit": "cpp",
  16 + "*.tcc": "cpp",
  17 + "bitset": "cpp",
  18 + "cctype": "cpp",
  19 + "clocale": "cpp",
  20 + "cmath": "cpp",
  21 + "codecvt": "cpp",
  22 + "condition_variable": "cpp",
  23 + "cstdarg": "cpp",
  24 + "cstddef": "cpp",
  25 + "cstdint": "cpp",
  26 + "cstdio": "cpp",
  27 + "cstdlib": "cpp",
  28 + "cstring": "cpp",
  29 + "ctime": "cpp",
  30 + "cwchar": "cpp",
  31 + "cwctype": "cpp",
  32 + "deque": "cpp",
  33 + "map": "cpp",
  34 + "set": "cpp",
  35 + "unordered_map": "cpp",
  36 + "vector": "cpp",
  37 + "exception": "cpp",
  38 + "algorithm": "cpp",
  39 + "functional": "cpp",
  40 + "iterator": "cpp",
  41 + "memory": "cpp",
  42 + "memory_resource": "cpp",
  43 + "numeric": "cpp",
  44 + "optional": "cpp",
  45 + "random": "cpp",
  46 + "ratio": "cpp",
  47 + "system_error": "cpp",
  48 + "tuple": "cpp",
  49 + "type_traits": "cpp",
  50 + "utility": "cpp",
  51 + "fstream": "cpp",
  52 + "initializer_list": "cpp",
  53 + "iomanip": "cpp",
  54 + "istream": "cpp",
  55 + "limits": "cpp",
  56 + "mutex": "cpp",
  57 + "new": "cpp",
  58 + "ostream": "cpp",
  59 + "sstream": "cpp",
  60 + "stdexcept": "cpp",
  61 + "streambuf": "cpp",
  62 + "cfenv": "cpp",
  63 + "cinttypes": "cpp",
  64 + "__nullptr": "cpp"
14 } 65 }
15 } 66 }
16 \ No newline at end of file 67 \ No newline at end of file
check_tool/FFCuContextManager.cpp 0 โ†’ 100644
  1 +#include "FFCuContextManager.h"
  2 +#include <iostream>
  3 +
  4 +using namespace std;
  5 +
  6 +FFCuContextManager::~FFCuContextManager()
  7 +{
  8 + for(auto iter = ctxMap.begin(); iter != ctxMap.end(); iter++){
  9 + av_buffer_unref(&iter->second);
  10 + }
  11 + ctxMap.clear();
  12 +}
  13 +
  14 +AVBufferRef *FFCuContextManager::getCuCtx(string gpuid)
  15 +{
  16 + AVBufferRef *hw_device_ctx = ctxMap[gpuid];
  17 + if (nullptr == hw_device_ctx)
  18 + {
  19 + // ๅˆๅง‹ๅŒ–็กฌไปถ่งฃ็ ๅ™จ
  20 + if (av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, gpuid.c_str(), nullptr, 0) < 0)
  21 + {
  22 + av_log(nullptr, AV_LOG_ERROR, "Failed to create specified HW device ! \n");
  23 + return nullptr;
  24 + }
  25 + ctxMap[gpuid] = hw_device_ctx;
  26 + }
  27 + return hw_device_ctx;
  28 +}
0 \ No newline at end of file 29 \ No newline at end of file
check_tool/FFCuContextManager.h 0 โ†’ 100644
  1 +
  2 +#include<map>
  3 +#include<string>
  4 +
  5 +extern "C"
  6 +{
  7 + #include <libavcodec/avcodec.h>
  8 + #include <libavdevice/avdevice.h>
  9 + #include <libavformat/avformat.h>
  10 + #include <libavfilter/avfilter.h>
  11 + #include <libavutil/avutil.h>
  12 + #include <libavutil/pixdesc.h>
  13 + #include <libswscale/swscale.h>
  14 +}
  15 +
  16 +using namespace std;
  17 +
  18 +class FFCuContextManager{
  19 +public:
  20 + static FFCuContextManager* getInstance(){
  21 + static FFCuContextManager* singleton = nullptr;
  22 + if (singleton == nullptr){
  23 + singleton = new FFCuContextManager();
  24 + }
  25 + return singleton;
  26 + }
  27 +
  28 + AVBufferRef *getCuCtx(string gpuid);
  29 +
  30 +private:
  31 + FFCuContextManager(){}
  32 + ~FFCuContextManager();
  33 +
  34 +private:
  35 + map<string,AVBufferRef *> ctxMap;
  36 +
  37 +};
0 \ No newline at end of file 38 \ No newline at end of file
check_tool/Makefile 0 โ†’ 100644
  1 +
  2 +XX = g++
  3 +NVCC = nvcc
  4 +
  5 +PROJECT_ROOT= /mnt/e/fiss/FFNvDecoder
  6 +
  7 +DEPEND_DIR = $(PROJECT_ROOT)/bin
  8 +SRC_ROOT = $(PROJECT_ROOT)/check_tool
  9 +CUDA_ROOT = /usr/local/cuda
  10 +
  11 +TARGET= $(DEPEND_DIR)/lib/check_tool
  12 +
  13 +
  14 +INCLUDE= -I $(DEPEND_DIR)/include \
  15 + -I $(CUDA_ROOT)/include \
  16 + -I $(SRC_ROOT)\
  17 +
  18 +LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
  19 + -L $(CUDA_ROOT)/lib64 -lcudart -lcurand -lcublas -lnvjpeg \
  20 + -L /usr/lib/wsl/lib -lcuda -lnvcuvid\
  21 +
  22 +CFLAGS= -g -fPIC -O0 $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
  23 + # -DUNICODE -D_UNICODE
  24 +
  25 +NFLAGS_LIB=-g -c -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden
  26 +NFLAGS = $(NFLAGS_LIB) $(INCLUDE) -std=c++11
  27 +
  28 +SRCS:=$(wildcard $(SRC_ROOT)/*.cpp)
  29 +OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
  30 +
  31 +CU_SOURCES = $(wildcard ${SRC_ROOT}/*.cu)
  32 +CU_OBJS = $(patsubst %.cu, %.o, $(notdir $(CU_SOURCES)))
  33 +
  34 +
  35 +$(TARGET):$(OBJS) $(CU_OBJS)
  36 + rm -f $(TARGET)
  37 + $(XX) -o $@ $^ $(CFLAGS) $(LIBSPATH) $(LIBS) -Wwrite-strings
  38 + rm -f *.o
  39 +
  40 +%.o:$(SRC_ROOT)/%.cpp
  41 + $(XX) $(CFLAGS) -c $<
  42 +
  43 +%.o:$(SRC_ROOT)/%.cu
  44 + @echo "#######################CU_OBJS:$@###############"
  45 + $(NVCC) $(NFLAGS) -o $@ $<
  46 +
  47 +clean:
  48 + rm -f *.o $(TARGET)
  49 +
  50 +
check_tool/check_tool.cpp 0 โ†’ 100644
  1 +#include"check_tool.h"
  2 +
  3 +#include "FFCuContextManager.h"
  4 +
  5 +extern "C"
  6 +{
  7 + #include <libavcodec/avcodec.h>
  8 + #include <libavdevice/avdevice.h>
  9 + #include <libavformat/avformat.h>
  10 + #include <libavfilter/avfilter.h>
  11 + #include <libavutil/avutil.h>
  12 + #include <libavutil/pixdesc.h>
  13 + #include <libswscale/swscale.h>
  14 + #include <libavutil/imgutils.h>
  15 +}
  16 +
  17 +#include <chrono>
  18 +
  19 +static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *pix_fmts){
  20 +
  21 + const AVPixelFormat *p;
  22 +
  23 + for (p = pix_fmts; *p != -1; p++) {
  24 + if (*p == AV_PIX_FMT_CUDA)
  25 + return *p;
  26 + }
  27 +
  28 + av_log(nullptr, AV_LOG_ERROR, "Failed to get HW surface format. \n");
  29 + return AV_PIX_FMT_NONE;
  30 +}
  31 +
  32 +static long long get_cur_time(){
  33 + // ่Žทๅ–ๆ“ไฝœ็ณป็ปŸๅฝ“ๅ‰ๆ—ถ้—ด็‚น๏ผˆ็ฒพ็กฎๅˆฐๅพฎ็ง’๏ผ‰
  34 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  35 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  36 + // (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ด็‚น => (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ดๆˆณ
  37 + time_t currentTime = tpMicro.time_since_epoch().count();
  38 +
  39 + return (long long )currentTime;
  40 +}
  41 +
  42 +void evalQuality(const string& uri, const char* gpuid){
  43 + AVFormatContext* ifmt_ctx = nullptr;
  44 + AVCodecContext* codec_ctx = nullptr;
  45 + AVCodec *decoder = nullptr;
  46 + AVCodec* codec = nullptr;
  47 + AVPacket* pkt = nullptr;
  48 + int video_index = -1;
  49 + AVStream* st = nullptr;
  50 + SwsContext *img_convert_ctx = nullptr;
  51 + uint8_t *buffer = nullptr;
  52 + int numBytes = 0;
  53 +
  54 + long start_time = 0;
  55 + long end_time = 0;
  56 + long s_time = 0;
  57 + long e_time = 0;
  58 + long long sum = 0;
  59 + double avg_time = 0.0;
  60 +
  61 + int sep = 0;
  62 +
  63 + string cuvid_dec_name = "" ;
  64 + FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance();
  65 + AVDictionary *op = nullptr;
  66 + AVBufferRef *hw_device_ctx = nullptr;
  67 +
  68 +
  69 + avformat_network_init();
  70 +
  71 + // ๆ‰“ๅผ€่พ“ๅ…ฅ่ง†้ข‘ๆ–‡ไปถ
  72 + AVDictionary *options = nullptr;
  73 + av_dict_set( &options, "bufsize", "655360", 0 );
  74 + av_dict_set( &options, "rtsp_transport", "tcp", 0 );
  75 + // av_dict_set( &options, "listen_timeout", "30", 0 ); // ๅ•ไฝไธบs
  76 + av_dict_set( &options, "stimeout", "30000000", 0 ); // ๅ•ไฝไธบ ็™พไธ‡ๅˆ†ไน‹ไธ€็ง’
  77 +
  78 + ///ๆ‰“ๅผ€่พ“ๅ…ฅ็š„ๆต
  79 + ifmt_ctx = avformat_alloc_context();
  80 + int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options);
  81 + if (ret != 0){
  82 + av_log(nullptr, AV_LOG_ERROR, "Couldn't open input stream ! \n");
  83 + goto end_flag ;
  84 + }
  85 +
  86 + //ๆŸฅๆ‰พๆตไฟกๆฏ
  87 + if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){
  88 + av_log(nullptr, AV_LOG_ERROR, "Couldn't find stream information ! \n");
  89 + goto end_flag ;
  90 + }
  91 +
  92 + // ๆŸฅๆ‰พ่ง†้ข‘ๆตไฟกๆฏ
  93 + video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
  94 + if (video_index < 0) {
  95 + av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n");
  96 + goto end_flag ;
  97 + }
  98 +
  99 + cuvid_dec_name = string(decoder->name) + "_cuvid";
  100 + codec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str());
  101 + if (!codec){
  102 + av_log(nullptr, AV_LOG_ERROR, "Codec not found ! \n");
  103 + goto end_flag ;
  104 + }
  105 +
  106 + //็”ณ่ฏทAVCodecContext
  107 + codec_ctx = avcodec_alloc_context3(codec);
  108 + if (!codec_ctx){
  109 + goto end_flag ;
  110 + }
  111 +
  112 + st = ifmt_ctx->streams[video_index];
  113 + if(avcodec_parameters_to_context(codec_ctx, st->codecpar) < 0){
  114 + goto end_flag ;
  115 + }
  116 +
  117 + {
  118 + av_log(nullptr, AV_LOG_INFO, "path: %s \n", ifmt_ctx->url);
  119 + av_log(nullptr, AV_LOG_INFO, "format: %s \n", ifmt_ctx->iformat->name);
  120 + const char* profile = avcodec_profile_name(codec_ctx->codec_id, codec_ctx->profile);
  121 + av_log(nullptr, AV_LOG_INFO, "codec: %s(%s) \n", decoder->name, profile);
  122 + const char* pix_fmt_name = av_get_pix_fmt_name(codec_ctx->pix_fmt);
  123 + av_log(nullptr, AV_LOG_INFO, "pix_fmt_name: %s \n", pix_fmt_name);
  124 + av_log(nullptr, AV_LOG_INFO, "width x height: %dX%d \n", st->codecpar->width, st->codecpar->height);
  125 +
  126 + av_log(NULL, AV_LOG_INFO, "frame_rate: %1.0f ", av_q2d(st->r_frame_rate));
  127 + av_log(NULL, AV_LOG_INFO, " --> reference PPS: %f ms\n", 1/av_q2d(st->r_frame_rate) * 1000);
  128 +
  129 + }
  130 +
  131 + // ่ฎพ็ฝฎ่งฃ็ ๅ™จ็ฎก็†ๅ™จ็š„ๅƒ็ด ๆ ผๅผๅ›ž่ฐƒๅ‡ฝๆ•ฐ
  132 + codec_ctx->get_format = get_hw_format;
  133 +
  134 + hw_device_ctx = pCtxMgr->getCuCtx(gpuid);
  135 + if(nullptr == hw_device_ctx){
  136 + av_log(nullptr, AV_LOG_ERROR, "create CUDA context failed ! \n");
  137 + goto end_flag ;
  138 + }
  139 + codec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
  140 + if (nullptr == codec_ctx->hw_device_ctx){
  141 + goto end_flag ;
  142 + }
  143 +
  144 + // ๆ‰“ๅผ€่งฃ็ ๅ™จๆต
  145 + av_dict_set( &op, "gpu", gpuid, 0 );
  146 + if (avcodec_open2(codec_ctx, codec, &op) < 0) {
  147 + av_log(nullptr, AV_LOG_ERROR, "Failed to open codec for stream ! \n");
  148 + goto end_flag ;
  149 + }
  150 +
  151 + s_time = get_cur_time();
  152 + start_time = get_cur_time();
  153 + pkt = av_packet_alloc();
  154 + while (av_read_frame(ifmt_ctx, pkt) >= 0){
  155 + end_time = get_cur_time();
  156 + sum ++ ;
  157 + sep ++ ;
  158 + if(end_time - start_time > 1000){
  159 + avg_time = double(end_time - start_time) / sep;
  160 + start_time = get_cur_time();
  161 + sep = 0;
  162 + av_log(nullptr, AV_LOG_INFO, "PPS: %f ms\n", avg_time);
  163 + }
  164 + av_packet_unref(pkt);
  165 + }
  166 +
  167 + e_time = get_cur_time();
  168 + avg_time = double(e_time - s_time) / sum;
  169 + av_log(nullptr, AV_LOG_INFO, "TOOTAL PPS: %f ms\n", avg_time);
  170 +
  171 +end_flag:
  172 + if (codec_ctx != nullptr){
  173 + avcodec_close(codec_ctx);
  174 + avcodec_free_context(&codec_ctx);
  175 + }
  176 +
  177 + if (ifmt_ctx != nullptr){
  178 + avformat_close_input(&ifmt_ctx);
  179 + }
  180 +
  181 + if (pkt != nullptr){
  182 + av_packet_free(&pkt);
  183 + }
  184 +}
0 \ No newline at end of file 185 \ No newline at end of file
check_tool/check_tool.h 0 โ†’ 100644
  1 +#include<string>
  2 +
  3 +using namespace std;
  4 +
  5 +void evalQuality(const string& uri, const char* gpuid);
0 \ No newline at end of file 6 \ No newline at end of file
check_tool/main.cpp 0 โ†’ 100644
  1 +#include"check_tool.h"
  2 +
  3 +#include <cuda.h>
  4 +
  5 +#include<iostream>
  6 +
  7 +using namespace std;
  8 +
  9 +
  10 +#define checkCudaErrors(S) do {CUresult status; \
  11 + status = S; \
  12 + if (status != CUDA_SUCCESS ) {std::cout << __LINE__ <<" checkCudaErrors - status = " << status << std::endl; \
  13 + exit(EXIT_FAILURE);}\
  14 + } while (false)
  15 +
  16 +
  17 +
  18 +int CheckCUDAProperty( int devId )
  19 +{
  20 + cuInit(0);
  21 +
  22 + CUdevice dev = devId;
  23 + size_t memSize = 0;
  24 + char devName[256] = {0};
  25 + int major = 0, minor = 0;
  26 + CUresult rlt = CUDA_SUCCESS;
  27 +
  28 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, dev));
  29 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, dev));
  30 +
  31 + checkCudaErrors( cuDeviceGetName(devName, sizeof( devName ), dev) );
  32 +
  33 + printf( "Using GPU Device %d: %s has SM %d.%d compute capability\n",
  34 + dev, devName, major, minor );
  35 +
  36 + rlt = cuDeviceTotalMem( &memSize, dev );
  37 + checkCudaErrors( rlt );
  38 +
  39 + printf( "Total amount of global memory: %4.4f MB\n",
  40 + (float)memSize / ( 1024 * 1024 ) );
  41 +
  42 + return 0;
  43 +}
  44 +
  45 +
  46 +int main(int argc, char *argv[]) {
  47 + printf("start \n");
  48 + if (argc != 3) {
  49 + fprintf(stderr, "./xxx uri gpu_id\n");
  50 + return -1;
  51 + }
  52 +
  53 + char* uri = argv[1];
  54 + char* gpuid = argv[2];
  55 +
  56 + CheckCUDAProperty(atoi(gpuid));
  57 +
  58 + evalQuality(uri,gpuid);
  59 +
  60 + return 0;
  61 +}
0 \ No newline at end of file 62 \ No newline at end of file
src/FFCuContextManager.cpp
@@ -19,7 +19,7 @@ AVBufferRef *FFCuContextManager::getCuCtx(string gpuid) @@ -19,7 +19,7 @@ AVBufferRef *FFCuContextManager::getCuCtx(string gpuid)
19 // ๅˆๅง‹ๅŒ–็กฌไปถ่งฃ็ ๅ™จ 19 // ๅˆๅง‹ๅŒ–็กฌไปถ่งฃ็ ๅ™จ
20 if (av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, gpuid.c_str(), nullptr, 0) < 0) 20 if (av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, gpuid.c_str(), nullptr, 0) < 0)
21 { 21 {
22 - cout << "Failed to create specified HW device."; 22 + av_log(nullptr, AV_LOG_ERROR, "Failed to create specified HW device ! \n");
23 return nullptr; 23 return nullptr;
24 } 24 }
25 ctxMap[gpuid] = hw_device_ctx; 25 ctxMap[gpuid] = hw_device_ctx;
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>
6 #include <fstream> 5 #include <fstream>
7 6
8 -#include <chrono>  
9 -  
10 #include "FFCuContextManager.h" 7 #include "FFCuContextManager.h"
11 8
12 using namespace std; 9 using namespace std;
@@ -24,7 +21,7 @@ static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *p @@ -24,7 +21,7 @@ static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *p
24 return *p; 21 return *p;
25 } 22 }
26 23
27 - //cout << "Failed to get HW surface format"; 24 + av_log(nullptr, AV_LOG_ERROR, "Failed to get HW surface format. \n");
28 return AV_PIX_FMT_NONE; 25 return AV_PIX_FMT_NONE;
29 } 26 }
30 27
@@ -86,13 +83,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) @@ -86,13 +83,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
86 fmt_ctx = avformat_alloc_context(); 83 fmt_ctx = avformat_alloc_context();
87 const char* input_file = uri; 84 const char* input_file = uri;
88 if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { 85 if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
89 - cout << "Cannot open input file: " << input_file; 86 + av_log(nullptr, AV_LOG_ERROR, "Cannot open input file: %s \n", input_file);
90 return false; 87 return false;
91 } 88 }
92 89
93 // ๆŸฅๆ‰พๆตไฟกๆฏ 90 // ๆŸฅๆ‰พๆตไฟกๆฏ
94 if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) { 91 if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
95 - cout << "Cannot find input stream information"; 92 + av_log(nullptr, AV_LOG_ERROR, "Cannot find input stream information ! \n");
96 return false; 93 return false;
97 } 94 }
98 95
@@ -100,7 +97,7 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) @@ -100,7 +97,7 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
100 AVCodec *decoder = nullptr; 97 AVCodec *decoder = nullptr;
101 stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); 98 stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
102 if (stream_index < 0) { 99 if (stream_index < 0) {
103 - cout << "Cannot find a video stream in the input file"; 100 + av_log(nullptr, AV_LOG_ERROR, "Cannot find a video stream in the input file ! \n");
104 return false; 101 return false;
105 } 102 }
106 103
@@ -121,7 +118,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) @@ -121,7 +118,13 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
121 hw_pix_fmt = AV_PIX_FMT_CUDA; 118 hw_pix_fmt = AV_PIX_FMT_CUDA;
122 119
123 FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance(); 120 FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance();
124 - avctx->hw_device_ctx = av_buffer_ref(pCtxMgr->getCuCtx(gpuid)); 121 +
  122 + AVBufferRef *hw_device_ctx = pCtxMgr->getCuCtx(gpuid);
  123 + if(nullptr == hw_device_ctx){
  124 + av_log(nullptr, AV_LOG_ERROR, "create CUDA context failed ! \n");
  125 + return false;
  126 + }
  127 + avctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
125 if (nullptr == avctx->hw_device_ctx) 128 if (nullptr == avctx->hw_device_ctx)
126 { 129 {
127 return false; 130 return false;
@@ -130,9 +133,9 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) @@ -130,9 +133,9 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
130 // ๆ‰“ๅผ€่งฃ็ ๅ™จๆต 133 // ๆ‰“ๅผ€่งฃ็ ๅ™จๆต
131 AVDictionary *op = nullptr; 134 AVDictionary *op = nullptr;
132 av_dict_set( &op, "gpu", gpuid, 0 ); 135 av_dict_set( &op, "gpu", gpuid, 0 );
133 - av_dict_set( &op, "surfaces", "3", 0 ); 136 + // av_dict_set( &op, "surfaces", "10", 0 );
134 if (avcodec_open2(avctx, vcodec, &op) < 0) { 137 if (avcodec_open2(avctx, vcodec, &op) < 0) {
135 - cout << "Failed to open codec for stream" << stream_index; 138 + av_log(nullptr, AV_LOG_ERROR, "Failed to open codec for stream ! \n");
136 return false; 139 return false;
137 } 140 }
138 141
@@ -162,14 +165,12 @@ void FFNvDecoder::start(){ @@ -162,14 +165,12 @@ void FFNvDecoder::start(){
162 165
163 static long long get_cur_time(){ 166 static long long get_cur_time(){
164 // ่Žทๅ–ๆ“ไฝœ็ณป็ปŸๅฝ“ๅ‰ๆ—ถ้—ด็‚น๏ผˆ็ฒพ็กฎๅˆฐๅพฎ็ง’๏ผ‰ 167 // ่Žทๅ–ๆ“ไฝœ็ณป็ปŸๅฝ“ๅ‰ๆ—ถ้—ด็‚น๏ผˆ็ฒพ็กฎๅˆฐๅพฎ็ง’๏ผ‰
165 - chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro  
166 - = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()); 168 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  169 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
167 // (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ด็‚น => (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ดๆˆณ 170 // (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ด็‚น => (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ดๆˆณ
168 - time_t totalMicroSeconds = tpMicro.time_since_epoch().count();  
169 -  
170 - long long currentTime = ((long long)totalMicroSeconds)/1000; 171 + time_t currentTime = tpMicro.time_since_epoch().count();
171 172
172 - return currentTime; 173 + return (long long )currentTime;
173 } 174 }
174 175
175 void FFNvDecoder::decode_thread() 176 void FFNvDecoder::decode_thread()
@@ -208,14 +209,9 @@ void FFNvDecoder::decode_thread() @@ -208,14 +209,9 @@ void FFNvDecoder::decode_thread()
208 } 209 }
209 210
210 int result = av_read_frame(fmt_ctx, pkt); 211 int result = av_read_frame(fmt_ctx, pkt);
211 - if (result == AVERROR_EOF) 212 + if (result == AVERROR_EOF || result < 0)
212 { 213 {
213 - cout << "Failed to read frame!" << endl;  
214 - break;  
215 - }  
216 - if (result < 0)  
217 - {  
218 - cout << "Failed to read frame!" << endl; 214 + av_log(nullptr, AV_LOG_ERROR, "Failed to read frame! \n");
219 break; 215 break;
220 } 216 }
221 217
@@ -234,19 +230,16 @@ void FFNvDecoder::decode_thread() @@ -234,19 +230,16 @@ void FFNvDecoder::decode_thread()
234 } 230 }
235 } 231 }
236 232
237 - if (stream_index == pkt->stream_index)  
238 - { 233 + if (stream_index == pkt->stream_index){
239 result = avcodec_send_packet(avctx, pkt); 234 result = avcodec_send_packet(avctx, pkt);
240 - if (result < 0)  
241 - {  
242 - cout << "Failed to send pkt:" << result << endl; 235 + if (result < 0){
  236 + av_log(nullptr, AV_LOG_ERROR, "%s - Failed to send pkt: %d \n",name,result);
243 continue; 237 continue;
244 } 238 }
245 239
246 result = avcodec_receive_frame(avctx, gpuFrame); 240 result = avcodec_receive_frame(avctx, gpuFrame);
247 - if (result == AVERROR(EAGAIN) || result == AVERROR_EOF || result < 0)  
248 - {  
249 - cout << "Failed to receive frame"<< endl; 241 + if ((result == AVERROR(EAGAIN) || result == AVERROR_EOF) || result < 0){
  242 + av_log(nullptr, AV_LOG_ERROR, "%s - Failed to receive frame: %d \n",name,result);
250 continue; 243 continue;
251 } 244 }
252 245
@@ -255,6 +248,14 @@ void FFNvDecoder::decode_thread() @@ -255,6 +248,14 @@ void FFNvDecoder::decode_thread()
255 av_packet_unref(pkt); 248 av_packet_unref(pkt);
256 } 249 }
257 250
  251 + // ้˜Ÿๅˆ—ไธญๆฒกๆœ‰ๆ•ฐๆฎไบ†ๅ†็ป“ๆŸ
  252 + while (mFrameQueue.length() > 0){
  253 + if(!m_bRunning){
  254 + break;
  255 + }
  256 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  257 + }
  258 +
258 m_bRunning = false; 259 m_bRunning = false;
259 260
260 // long end_time = get_cur_time(); 261 // long end_time = get_cur_time();
@@ -266,9 +267,11 @@ void FFNvDecoder::decode_thread() @@ -266,9 +267,11 @@ void FFNvDecoder::decode_thread()
266 pthread_join(m_post_decode_thread,0); 267 pthread_join(m_post_decode_thread,0);
267 } 268 }
268 269
  270 + decode_finished_cbk(m_userPtr);
  271 +
269 decode_finished(); 272 decode_finished();
270 273
271 - cout << "decode thread exited." << endl; 274 + av_log(nullptr, AV_LOG_INFO, "%s - decode thread exited. \n",name);
272 } 275 }
273 276
274 void FFNvDecoder::decode_finished() 277 void FFNvDecoder::decode_finished()
@@ -289,7 +292,7 @@ void FFNvDecoder::decode_finished() @@ -289,7 +292,7 @@ void FFNvDecoder::decode_finished()
289 292
290 void FFNvDecoder::post_decode_thread() 293 void FFNvDecoder::post_decode_thread()
291 { 294 {
292 - while (m_bRunning) 295 + while (m_bRunning || mFrameQueue.length() > 0)
293 { 296 {
294 AVFrame * gpuFrame = mFrameQueue.getHead(); 297 AVFrame * gpuFrame = mFrameQueue.getHead();
295 if (gpuFrame == nullptr) 298 if (gpuFrame == nullptr)
@@ -302,8 +305,8 @@ void FFNvDecoder::post_decode_thread() @@ -302,8 +305,8 @@ void FFNvDecoder::post_decode_thread()
302 305
303 mFrameQueue.addHead(); 306 mFrameQueue.addHead();
304 } 307 }
305 -  
306 - cout << "post decode thread exited." << endl; 308 +
  309 + av_log(nullptr, AV_LOG_INFO, "post decode thread exited. \n");
307 } 310 }
308 311
309 void FFNvDecoder::close() 312 void FFNvDecoder::close()
@@ -338,12 +341,16 @@ bool FFNvDecoder::isFinished() @@ -338,12 +341,16 @@ bool FFNvDecoder::isFinished()
338 return m_bFinished; 341 return m_bFinished;
339 } 342 }
340 343
  344 +bool FFNvDecoder::isPausing(){
  345 + return m_bPause;
  346 +}
  347 +
341 bool FFNvDecoder::getResolution( int &width, int &height ) 348 bool FFNvDecoder::getResolution( int &width, int &height )
342 { 349 {
343 - if (avctx != nullptr) 350 + if (stream != nullptr && stream->codecpar != nullptr)
344 { 351 {
345 - width = avctx->width;  
346 - height = avctx->height; 352 + width = stream->codecpar->width;
  353 + height = stream->codecpar->height;
347 return true; 354 return true;
348 } 355 }
349 356
@@ -363,4 +370,145 @@ void FFNvDecoder::resume() @@ -363,4 +370,145 @@ void FFNvDecoder::resume()
363 void FFNvDecoder::setDecKeyframe(bool bKeyframe) 370 void FFNvDecoder::setDecKeyframe(bool bKeyframe)
364 { 371 {
365 m_dec_keyframe = bKeyframe; 372 m_dec_keyframe = bKeyframe;
366 -}  
367 \ No newline at end of file 373 \ No newline at end of file
  374 +}
  375 +
  376 +int FFNvDecoder::getCachedQueueLength(){
  377 + return mFrameQueue.length();
  378 +}
  379 +
  380 +FFImgInfo* FFNvDecoder::snapshot(const string& uri){
  381 +
  382 + AVFormatContext* ifmt_ctx = nullptr;
  383 + AVCodecContext* codec_ctx = nullptr;
  384 + AVCodec* codec = nullptr;
  385 + AVPacket* pkt = nullptr;
  386 + AVFrame *frame = nullptr;
  387 + AVFrame *pFrameRGB = nullptr;
  388 + int video_index = -1;
  389 + AVStream* st = nullptr;
  390 + SwsContext *img_convert_ctx = nullptr;
  391 + uint8_t *buffer = nullptr;
  392 + int numBytes = 0;
  393 +
  394 + FFImgInfo* imgInfo = nullptr;
  395 +
  396 +
  397 + avformat_network_init();
  398 +
  399 + // ๆ‰“ๅผ€่พ“ๅ…ฅ่ง†้ข‘ๆ–‡ไปถ
  400 + AVDictionary *options = nullptr;
  401 + av_dict_set( &options, "bufsize", "655360", 0 );
  402 + av_dict_set( &options, "rtsp_transport", "tcp", 0 );
  403 + // av_dict_set( &options, "listen_timeout", "30", 0 ); // ๅ•ไฝไธบs
  404 + av_dict_set( &options, "stimeout", "30000000", 0 ); // ๅ•ไฝไธบ ็™พไธ‡ๅˆ†ไน‹ไธ€็ง’
  405 +
  406 + ///ๆ‰“ๅผ€่พ“ๅ…ฅ็š„ๆต
  407 + ifmt_ctx = avformat_alloc_context();
  408 + int ret = avformat_open_input(&ifmt_ctx, uri.c_str(), nullptr, &options);
  409 + if (ret != 0){
  410 + av_log(nullptr, AV_LOG_ERROR, "Couldn't open input stream ! \n");
  411 + goto end_flag ;
  412 + }
  413 +
  414 + //ๆŸฅๆ‰พๆตไฟกๆฏ
  415 + if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0){
  416 + av_log(nullptr, AV_LOG_ERROR, "Couldn't find stream information ! \n");
  417 + goto end_flag ;
  418 + }
  419 +
  420 + //ๆ‰พๅˆฐ่ง†้ข‘ๆต็ดขๅผ•
  421 + video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
  422 +
  423 + st = ifmt_ctx->streams[video_index];
  424 +
  425 + //ๆ‰พๅˆฐ่งฃ็ ๅ™จ
  426 + codec = avcodec_find_decoder(st->codecpar->codec_id);
  427 + if (!codec){
  428 + av_log(nullptr, AV_LOG_ERROR, "Codec not found ! \n");
  429 + goto end_flag ;
  430 + }
  431 +
  432 + //็”ณ่ฏทAVCodecContext
  433 + codec_ctx = avcodec_alloc_context3(codec);
  434 + if (!codec_ctx){
  435 + goto end_flag ;
  436 + }
  437 +
  438 + avcodec_parameters_to_context(codec_ctx, ifmt_ctx->streams[video_index]->codecpar);
  439 +
  440 + //ๆ‰“ๅผ€่งฃ็ ๅ™จ
  441 + if ((ret = avcodec_open2(codec_ctx, codec, nullptr) < 0)){
  442 + goto end_flag ;
  443 + }
  444 +
  445 + // ่ฎก็ฎ—่งฃ็ ๅŽๅŽŸๅง‹ๆ•ฐๆฎๆ‰€้œ€็ผ“ๅ†ฒๅŒบๅคงๅฐ๏ผŒๅนถๅˆ†้…ๅ†…ๅญ˜็ฉบ้—ด Determine required buffer size and allocate buffer
  446 + numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);
  447 + buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
  448 +
  449 + pFrameRGB = av_frame_alloc();
  450 + av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AV_PIX_FMT_BGR24, codec_ctx->width, codec_ctx->height, 1);
  451 +
  452 + 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,
  453 + SWS_BICUBIC, nullptr, nullptr, nullptr);
  454 +
  455 + pkt = av_packet_alloc();
  456 + frame = av_frame_alloc();
  457 + while (av_read_frame(ifmt_ctx, pkt) >= 0){
  458 + if (pkt->stream_index == video_index){
  459 + int ret = avcodec_send_packet(codec_ctx, pkt);
  460 + if (ret >= 0){
  461 + ret = avcodec_receive_frame(codec_ctx, frame);
  462 + if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){
  463 + av_log(nullptr, AV_LOG_ERROR, "Failed to receive frame: %d \n", ret);
  464 + av_packet_unref(pkt);
  465 + continue;
  466 + }
  467 +
  468 + sws_scale(img_convert_ctx, (const unsigned char* const*)frame->data, frame->linesize, 0, codec_ctx->height, pFrameRGB->data, pFrameRGB->linesize);
  469 +
  470 + imgInfo = new FFImgInfo();
  471 + imgInfo->pData = buffer;
  472 + imgInfo->height = codec_ctx->height;
  473 + imgInfo->width = codec_ctx->width;
  474 + break;
  475 + }
  476 + }
  477 +
  478 + av_packet_unref(pkt);
  479 + }
  480 +
  481 +end_flag:
  482 + if (codec_ctx != nullptr){
  483 + avcodec_close(codec_ctx);
  484 + avcodec_free_context(&codec_ctx);
  485 + }
  486 +
  487 + if (ifmt_ctx != nullptr){
  488 + avformat_close_input(&ifmt_ctx);
  489 + }
  490 +
  491 + if (frame != nullptr){
  492 + av_frame_free(&frame);
  493 + }
  494 +
  495 + if (pFrameRGB != nullptr){
  496 + av_frame_free(&pFrameRGB);
  497 + }
  498 +
  499 + if (pkt != nullptr){
  500 + av_packet_free(&pkt);
  501 + }
  502 +
  503 + return imgInfo;
  504 +}
  505 +
  506 +void FFNvDecoder::releaseFFImgInfo(FFImgInfo* info){
  507 + if(nullptr != info){
  508 + if(info->pData != nullptr){
  509 + av_free(info->pData);
  510 + info->pData = nullptr;
  511 + }
  512 + delete info;
  513 + info = nullptr;
  514 + }
  515 +}
src/FFNvDecoder.h
@@ -12,6 +12,7 @@ extern &quot;C&quot; @@ -12,6 +12,7 @@ extern &quot;C&quot;
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&amp; config){ @@ -26,6 +26,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig&amp; 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&amp; cfg) @@ -217,17 +231,57 @@ bool FFNvDecoderManager::isSurport(FFDecConfig&amp; 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/Makefile
@@ -2,14 +2,11 @@ @@ -2,14 +2,11 @@
2 XX = g++ 2 XX = g++
3 NVCC = nvcc 3 NVCC = nvcc
4 4
5 -  
6 -DEFS= -DPOST_USE_RABBITMQ  
7 -  
8 -PROJECT_ROOT= /home/cmhu/FFNvDecoder 5 +PROJECT_ROOT= /mnt/e/fiss/FFNvDecoder
9 6
10 DEPEND_DIR = $(PROJECT_ROOT)/bin 7 DEPEND_DIR = $(PROJECT_ROOT)/bin
11 SRC_ROOT = $(PROJECT_ROOT)/src 8 SRC_ROOT = $(PROJECT_ROOT)/src
12 -CUDA_ROOT = /usr/local/cuda-11.7 9 +CUDA_ROOT = /usr/local/cuda
13 10
14 TARGET= $(DEPEND_DIR)/lib/test 11 TARGET= $(DEPEND_DIR)/lib/test
15 12
@@ -21,12 +18,13 @@ INCLUDE= -I $(DEPEND_DIR)/include \ @@ -21,12 +18,13 @@ INCLUDE= -I $(DEPEND_DIR)/include \
21 -I $(SRC_ROOT)\ 18 -I $(SRC_ROOT)\
22 19
23 LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ 20 LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
24 - -L $(CUDA_ROOT)/lib64 -lcuda -lcudart -lnvcuvid -lcurand -lcublas -lnvjpeg \ 21 + -L $(CUDA_ROOT)/lib64 -lcudart -lcurand -lcublas -lnvjpeg \
  22 + -L /usr/lib/wsl/lib -lcuda -lnvcuvid\
25 23
26 -CFLAGS= -g -fPIC -O0 $(DEFS) $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl 24 +CFLAGS= -g -fPIC -O0 $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
27 # -DUNICODE -D_UNICODE 25 # -DUNICODE -D_UNICODE
28 26
29 -NFLAGS_LIB=-g -c $(DEFS) -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden 27 +NFLAGS_LIB=-g -c -shared -Xcompiler -fPIC -Xcompiler -fvisibility=hidden
30 NFLAGS = $(NFLAGS_LIB) $(INCLUDE) -std=c++11 28 NFLAGS = $(NFLAGS_LIB) $(INCLUDE) -std=c++11
31 29
32 SRCS:=$(wildcard $(SRC_ROOT)/*.cpp) 30 SRCS:=$(wildcard $(SRC_ROOT)/*.cpp)
src/common/inc/helper_cuda_drvapi.h
@@ -218,7 +218,8 @@ inline int gpuGetMaxGflopsDeviceIdDRV() @@ -218,7 +218,8 @@ inline int gpuGetMaxGflopsDeviceIdDRV()
218 // Find the best major SM Architecture GPU device 218 // Find the best major SM Architecture GPU device
219 while (current_device < device_count) 219 while (current_device < device_count)
220 { 220 {
221 - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); 221 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device));
  222 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device));
222 223
223 if (major > 0 && major < 9999) 224 if (major > 0 && major < 9999)
224 { 225 {
@@ -239,7 +240,9 @@ inline int gpuGetMaxGflopsDeviceIdDRV() @@ -239,7 +240,9 @@ inline int gpuGetMaxGflopsDeviceIdDRV()
239 checkCudaErrors(cuDeviceGetAttribute(&clockRate, 240 checkCudaErrors(cuDeviceGetAttribute(&clockRate,
240 CU_DEVICE_ATTRIBUTE_CLOCK_RATE, 241 CU_DEVICE_ATTRIBUTE_CLOCK_RATE,
241 current_device)); 242 current_device));
242 - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); 243 +
  244 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device));
  245 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device));
243 246
244 int computeMode; 247 int computeMode;
245 getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device); 248 getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device);
@@ -317,7 +320,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV() @@ -317,7 +320,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV()
317 while (current_device < device_count) 320 while (current_device < device_count)
318 { 321 {
319 checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device)); 322 checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device));
320 - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); 323 +
  324 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device));
  325 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device));
321 326
322 #if CUDA_VERSION >= 3020 327 #if CUDA_VERSION >= 3020
323 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); 328 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device));
@@ -369,7 +374,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV() @@ -369,7 +374,9 @@ inline int gpuGetMaxGflopsGLDeviceIdDRV()
369 checkCudaErrors(cuDeviceGetAttribute(&clockRate, 374 checkCudaErrors(cuDeviceGetAttribute(&clockRate,
370 CU_DEVICE_ATTRIBUTE_CLOCK_RATE, 375 CU_DEVICE_ATTRIBUTE_CLOCK_RATE,
371 current_device)); 376 current_device));
372 - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device)); 377 +
  378 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, current_device));
  379 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, current_device));
373 380
374 #if CUDA_VERSION >= 3020 381 #if CUDA_VERSION >= 3020
375 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device)); 382 checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device));
@@ -500,7 +507,9 @@ inline bool checkCudaCapabilitiesDRV(int major_version, int minor_version, int d @@ -500,7 +507,9 @@ inline bool checkCudaCapabilitiesDRV(int major_version, int minor_version, int d
500 507
501 checkCudaErrors(cuDeviceGet(&cuDevice, devID)); 508 checkCudaErrors(cuDeviceGet(&cuDevice, devID));
502 checkCudaErrors(cuDeviceGetName(name, 100, cuDevice)); 509 checkCudaErrors(cuDeviceGetName(name, 100, cuDevice));
503 - checkCudaErrors(cuDeviceComputeCapability(&major, &minor, devID)); 510 +
  511 + checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, devID));
  512 + checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, devID));
504 513
505 if ((major > major_version) || 514 if ((major > major_version) ||
506 (major == major_version && minor >= minor_version)) 515 (major == major_version && minor >= minor_version))
src/main.cpp
@@ -54,7 +54,7 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){ @@ -54,7 +54,7 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){
54 return; 54 return;
55 } 55 }
56 56
57 - string path = "/home/cmhu/data/" + decoder->getName() + "/" + to_string(sum) + ".jpg"; 57 + string path = "/mnt/f/fiss/data/" + decoder->getName() + "/" + to_string(sum) + ".jpg";
58 saveJpeg(path.c_str(), pHwRgb[0], gpuFrame->width, gpuFrame->height, stream[0]); // ้ชŒ่ฏ CUDAToRGB 58 saveJpeg(path.c_str(), pHwRgb[0], gpuFrame->width, gpuFrame->height, stream[0]); // ้ชŒ่ฏ CUDAToRGB
59 } 59 }
60 } else if (decoder->getName() == "dec2") 60 } else if (decoder->getName() == "dec2")
@@ -79,7 +79,7 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){ @@ -79,7 +79,7 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){
79 return; 79 return;
80 } 80 }
81 81
82 - string path = "/home/cmhu/data/" + decoder->getName() + "/" + to_string(sum) + ".jpg"; 82 + string path = "/mnt/f/fiss/data/" + decoder->getName() + "/" + to_string(sum) + ".jpg";
83 saveJpeg(path.c_str(), pHwRgb[1], gpuFrame->width, gpuFrame->height, stream[1]); // ้ชŒ่ฏ CUDAToRGB 83 saveJpeg(path.c_str(), pHwRgb[1], gpuFrame->width, gpuFrame->height, stream[1]); // ้ชŒ่ฏ CUDAToRGB
84 } 84 }
85 } 85 }
@@ -94,14 +94,10 @@ int count_std = 100; @@ -94,14 +94,10 @@ int count_std = 100;
94 94
95 static long long get_cur_time(){ 95 static long long get_cur_time(){
96 // ่Žทๅ–ๆ“ไฝœ็ณป็ปŸๅฝ“ๅ‰ๆ—ถ้—ด็‚น๏ผˆ็ฒพ็กฎๅˆฐๅพฎ็ง’๏ผ‰ 96 // ่Žทๅ–ๆ“ไฝœ็ณป็ปŸๅฝ“ๅ‰ๆ—ถ้—ด็‚น๏ผˆ็ฒพ็กฎๅˆฐๅพฎ็ง’๏ผ‰
97 - chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro  
98 - = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()); 97 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  98 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
99 // (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ด็‚น => (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ดๆˆณ 99 // (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ด็‚น => (ๅพฎ็ง’็ฒพๅบฆ็š„)ๆ—ถ้—ดๆˆณ
100 - time_t totalMicroSeconds = tpMicro.time_since_epoch().count();  
101 -  
102 - long long currentTime = ((long long)totalMicroSeconds)/1000;  
103 -  
104 - return currentTime; 100 + return tpMicro.time_since_epoch().count();
105 } 101 }
106 102
107 static int sum = 0; 103 static int sum = 0;
@@ -124,47 +120,52 @@ void postDecoded0(const void * userPtr, AVFrame * gpuFrame){ @@ -124,47 +120,52 @@ void postDecoded0(const void * userPtr, AVFrame * gpuFrame){
124 } 120 }
125 count++; 121 count++;
126 sum ++ ; 122 sum ++ ;
127 - // if (count >= count_std)  
128 - // {  
129 - // // end_time = get_cur_time();  
130 - // // long time_using = end_time - start_time;  
131 - // // double time_per_frame = double(time_using)/count_std ;  
132 - // // cout << count_std << "ๅธง็”จๆ—ถ:" << time_using << "ms ๆฏๅธง็”จๆ—ถ๏ผš" << time_per_frame << "ms" << endl;  
133 - // cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl;  
134 - // cout << gpuFrame->pts << endl;  
135 -  
136 - // count_flag = false;  
137 - // }  
138 - // cout << "ๅธงๆ•ฐ๏ผš" << sum << endl;  
139 -  
140 - // if (gpuFrame->format == AV_PIX_FMT_CUDA)  
141 - // {  
142 - // cudaSetDevice(atoi(decoder->m_cfg.gpuid.c_str()));  
143 - // // cout << "gpu id : " << decoder->m_cfg.gpuid.c_str() << endl;  
144 - // cudaError_t cudaStatus;  
145 - // if(pHwData == nullptr){  
146 - // cuda_common::setColorSpace2( ITU709, 0 );  
147 - // cudaStatus = cudaMalloc((void **)&pHwData, 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char));  
148 - // }  
149 - // cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], pHwData, gpuFrame->width, gpuFrame->height);  
150 - // cudaDeviceSynchronize();  
151 - // if (cudaStatus != cudaSuccess) {  
152 - // cout << "CUDAToBGR failed !!!" << endl;  
153 - // return;  
154 - // }  
155 -  
156 - // string path = "/home/cmhu/data/test/" + to_string(sum) + ".jpg";  
157 - // saveJpeg(path.c_str(), pHwData, gpuFrame->width, gpuFrame->height, nullptr); // ้ชŒ่ฏ CUDAToRGB  
158 - // } 123 + if (count >= count_std)
  124 + {
  125 + // end_time = get_cur_time();
  126 + // long time_using = end_time - start_time;
  127 + // double time_per_frame = double(time_using)/count_std ;
  128 + // cout << count_std << "ๅธง็”จๆ—ถ:" << time_using << "ms ๆฏๅธง็”จๆ—ถ๏ผš" << time_per_frame << "ms" << endl;
  129 + cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl;
  130 + cout << gpuFrame->pts << endl;
  131 +
  132 + count_flag = false;
  133 + }
  134 + cout << "ๅธงๆ•ฐ๏ผš" << sum << endl;
  135 +
  136 + if (gpuFrame->format == AV_PIX_FMT_CUDA)
  137 + {
  138 + cudaSetDevice(atoi(decoder->m_cfg.gpuid.c_str()));
  139 + // cout << "gpu id : " << decoder->m_cfg.gpuid.c_str() << endl;
  140 + cudaError_t cudaStatus;
  141 + if(pHwData == nullptr){
  142 + cuda_common::setColorSpace2( ITU709, 0 );
  143 + cudaStatus = cudaMalloc((void **)&pHwData, 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char));
  144 + }
  145 + cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], pHwData, gpuFrame->width, gpuFrame->height);
  146 + cudaDeviceSynchronize();
  147 + if (cudaStatus != cudaSuccess) {
  148 + cout << "CUDAToBGR failed !!!" << endl;
  149 + return;
  150 + }
  151 +
  152 + string path = "/mnt/f/fiss/data/" + to_string(sum) + ".jpg";
  153 + saveJpeg(path.c_str(), pHwData, gpuFrame->width, gpuFrame->height, nullptr); // ้ชŒ่ฏ CUDAToRGB
  154 + }
159 } 155 }
160 } 156 }
161 } 157 }
162 158
  159 +void decode_finished_cbk(const void* userPtr){
  160 + cout << "decode_finish timestamp: " << get_cur_time() << endl;
  161 +}
  162 +
163 // string test_uri = "rtmp://192.168.10.56:1935/objecteye/1"; 163 // string test_uri = "rtmp://192.168.10.56:1935/objecteye/1";
164 // string test_uri = "/home/cmhu/data/output_800x480.mp4"; 164 // string test_uri = "/home/cmhu/data/output_800x480.mp4";
165 // string test_uri = "/home/cmhu/data/output_1920x1080.mp4"; 165 // string test_uri = "/home/cmhu/data/output_1920x1080.mp4";
166 // string test_uri = "rtsp://176.10.0.2:8554/stream"; 166 // string test_uri = "rtsp://176.10.0.2:8554/stream";
167 -string test_uri = "/home/cmhu/data2/Street.uvf"; 167 +// string test_uri = "/mnt/f/fiss/test_data/h265.mp4";
  168 +string test_uri = "rtsp://176.10.0.4:8554/stream";
168 169
169 void createDecode(int index){ 170 void createDecode(int index){
170 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); 171 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
@@ -172,15 +173,16 @@ void createDecode(int index){ @@ -172,15 +173,16 @@ void createDecode(int index){
172 config.name = "dec" + to_string(index); 173 config.name = "dec" + to_string(index);
173 config.cfg.uri = test_uri; 174 config.cfg.uri = test_uri;
174 config.cfg.post_decoded_cbk = postDecoded; 175 config.cfg.post_decoded_cbk = postDecoded;
  176 + config.cfg.decode_finished_cbk = decode_finished_cbk;
175 config.cfg.force_tcp = true; 177 config.cfg.force_tcp = true;
176 178
177 if (index % 2 == 0) 179 if (index % 2 == 0)
178 { 180 {
179 - config.cfg.gpuid = "2"; 181 + config.cfg.gpuid = "0";
180 } 182 }
181 else 183 else
182 { 184 {
183 - config.cfg.gpuid = "1"; 185 + config.cfg.gpuid = "0";
184 } 186 }
185 187
186 FFNvDecoder* decoder = pDecManager->createDecoder(config); 188 FFNvDecoder* decoder = pDecManager->createDecoder(config);
@@ -207,7 +209,10 @@ int CheckCUDAProperty( int devId ) @@ -207,7 +209,10 @@ int CheckCUDAProperty( int devId )
207 int major = 0, minor = 0; 209 int major = 0, minor = 0;
208 CUresult rlt = CUDA_SUCCESS; 210 CUresult rlt = CUDA_SUCCESS;
209 211
210 - rlt = cuDeviceComputeCapability( &major, &minor, dev ); 212 + rlt = cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, dev);
  213 + checkCudaErrors( rlt );
  214 +
  215 + rlt = cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, dev);
211 checkCudaErrors( rlt ); 216 checkCudaErrors( rlt );
212 217
213 rlt = cuDeviceGetName( devName, sizeof( devName ), dev ); 218 rlt = cuDeviceGetName( devName, sizeof( devName ), dev );
@@ -225,9 +230,17 @@ int CheckCUDAProperty( int devId ) @@ -225,9 +230,17 @@ int CheckCUDAProperty( int devId )
225 return 0; 230 return 0;
226 } 231 }
227 232
  233 +void logFF(void *, int level, const char *fmt, va_list ap)
  234 +{
  235 + vfprintf(stdout, fmt, ap);
  236 +}
  237 +
  238 +
228 int main(){ 239 int main(){
229 240
230 - CheckCUDAProperty(1); 241 + // av_log_set_callback(&logFF);
  242 +
  243 + CheckCUDAProperty(0);
231 244
232 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); 245 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
233 246
@@ -241,17 +254,22 @@ int main(){ @@ -241,17 +254,22 @@ int main(){
241 config.name = "dec"; 254 config.name = "dec";
242 config.cfg.uri = test_uri; 255 config.cfg.uri = test_uri;
243 config.cfg.post_decoded_cbk = postDecoded0; 256 config.cfg.post_decoded_cbk = postDecoded0;
  257 + config.cfg.decode_finished_cbk = decode_finished_cbk;
244 config.cfg.force_tcp = true; 258 config.cfg.force_tcp = true;
245 - config.cfg.gpuid = "2"; 259 + config.cfg.gpuid = "0";
246 FFNvDecoder* dec2 = pDecManager->createDecoder(config); 260 FFNvDecoder* dec2 = pDecManager->createDecoder(config);
247 if (!dec2) 261 if (!dec2)
248 { 262 {
249 return 1; 263 return 1;
250 } 264 }
251 pDecManager->setUserPtr(config.name, dec2); 265 pDecManager->setUserPtr(config.name, dec2);
252 - pDecManager->setDecKeyframe(config.name, true); 266 + // pDecManager->setDecKeyframe(config.name, true);
253 pDecManager->startDecodeByName(config.name); 267 pDecManager->startDecodeByName(config.name);
254 268
  269 + int w,h;
  270 + pDecManager->getResolution(config.name, w,h);
  271 + printf( "%s : %dx%d\n", config.name.c_str() , w,h );
  272 +
255 pthread_t m_decode_thread; 273 pthread_t m_decode_thread;
256 pthread_create(&m_decode_thread,0, 274 pthread_create(&m_decode_thread,0,
257 [](void* arg) 275 [](void* arg)