Commit e96e6489e333fe15d6737d3350b12c194d044345

Authored by Hu Chunming
1 parent 0b43216c

优化代码;添加isRunning函数

src/FFNvDecoder.cpp
... ... @@ -38,6 +38,9 @@ FFNvDecoder::FFNvDecoder()
38 38  
39 39 m_bPause = false;
40 40 m_bReal = true;
  41 +
  42 + m_decode_thread = 0;
  43 + m_post_decode_thread = 0;
41 44 }
42 45  
43 46 FFNvDecoder::~FFNvDecoder()
... ... @@ -45,97 +48,7 @@ FFNvDecoder::~FFNvDecoder()
45 48  
46 49 }
47 50  
48   -bool FFNvDecoder::init(const string& path)
49   -{
50   - fstream infile(path);
51   - if (infile.is_open()){
52   - m_bReal = false;
53   - infile.close();
54   - }else {
55   - m_bReal = true;
56   - }
57   -
58   - // 查找对应的硬件解码设备
59   - const char* device_name = "cuda";
60   - AVHWDeviceType hw_device_type = av_hwdevice_find_type_by_name(device_name);
61   - if (hw_device_type == AV_HWDEVICE_TYPE_NONE) {
62   - while ((hw_device_type = av_hwdevice_iterate_types(hw_device_type)) != AV_HWDEVICE_TYPE_NONE)
63   - cout << av_hwdevice_get_type_name(hw_device_type);
64   - return false;
65   - }
66   -
67   - // 打开输入视频文件
68   - AVDictionary *options = nullptr;
69   - av_dict_set( &options, "bufsize", "1024000", 0 );
70   - av_dict_set( &options, "rtsp_transport", "tcp", 0 );
71   - av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s
72   - fmt_ctx = avformat_alloc_context();
73   - const char* input_file = path.c_str();
74   - if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
75   - cout << "Cannot open input file" << input_file;
76   - return false;
77   - }
78   -
79   - // 查找流信息
80   - if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {
81   - cout << "Cannot find input stream information";
82   - return false;
83   - }
84   -
85   - // 查找视频流信息
86   - AVCodec *decoder = nullptr;
87   - stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
88   - if (stream_index < 0) {
89   - cout << "Cannot find a video stream in the input file";
90   - return false;
91   - }
92   -
93   - // 判断硬件解码设备是否兼容视频解码器
94   - for (int i = 0;; i++) {
95   - const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
96   - if (!config) {
97   - cout << "Decoder does not support device hw_device_type"
98   - << decoder->name << av_hwdevice_get_type_name(hw_device_type);
99   - return false;
100   - }
101   - // 得到硬件解码像素格式
102   - if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
103   - config->device_type == hw_device_type) {
104   - hw_pix_fmt = config->pix_fmt;
105   - break;
106   - }
107   - }
108   -
109   - // 得到解码器管理器
110   - if (!(avctx = avcodec_alloc_context3(decoder)))
111   - return (bool)AVERROR(ENOMEM);
112   -
113   - // 得到视频流对象
114   - stream = fmt_ctx->streams[stream_index];
115   - if (avcodec_parameters_to_context(avctx, stream->codecpar) < 0)
116   - return false;
117   -
118   - avctx->opaque = this;
119   - // 设置解码器管理器的像素格式回调函数
120   - avctx->get_format = get_hw_format;
121   -
122   - // 初始化硬件解码器
123   - AVBufferRef *hw_device_ctx = nullptr;
124   - if (av_hwdevice_ctx_create(&hw_device_ctx, hw_device_type, nullptr, nullptr, 0) < 0) {
125   - cout << "Failed to create specified HW device.";
126   - return false;
127   - }
128   -
129   - // 打开解码器流
130   - if (avcodec_open2(avctx, decoder, nullptr) < 0) {
131   - cout << "Failed to open codec for stream" << stream_index;
132   - return false;
133   - }
134   -
135   - return true;
136   -}
137   -
138   -bool FFNvDecoder::init2(FFDecConfig& cfg)
  51 +bool FFNvDecoder::init(FFDecConfig& cfg)
139 52 {
140 53 m_cfg = cfg;
141 54  
... ... @@ -147,20 +60,23 @@ bool FFNvDecoder::init2(FFDecConfig&amp; cfg)
147 60 m_bReal = true;
148 61 }
149 62  
150   -
  63 + return init(cfg.uri.c_str(), cfg.gpuid.c_str(),cfg.force_tcp);
  64 +}
  65 +
  66 +bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp)
  67 +{
  68 + av_register_all();
  69 + avformat_network_init();
151 70  
152 71 // 打开输入视频文件
153 72 AVDictionary *options = nullptr;
154 73 av_dict_set( &options, "bufsize", "655360", 0 );
155   - av_dict_set( &options, "rtsp_transport", cfg.force_tcp ? "tcp" : "udp", 0 );
  74 + av_dict_set( &options, "rtsp_transport", force_tcp ? "tcp" : "udp", 0 );
156 75 // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s
157 76 av_dict_set( &options, "stimeout", "3000000", 0 );
158   -
159   - av_register_all();
160   - avformat_network_init();
161 77  
162 78 fmt_ctx = avformat_alloc_context();
163   - const char* input_file = cfg.uri.c_str();
  79 + const char* input_file = uri;
164 80 if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) {
165 81 cout << "Cannot open input file" << input_file;
166 82 return false;
... ... @@ -180,7 +96,6 @@ bool FFNvDecoder::init2(FFDecConfig&amp; cfg)
180 96 return false;
181 97 }
182 98  
183   -
184 99 string cuvid_dec_name = string(decoder->name) + "_cuvid";
185 100 AVCodec *vcodec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str());
186 101 if (!(avctx = avcodec_alloc_context3(vcodec)))
... ... @@ -199,7 +114,7 @@ bool FFNvDecoder::init2(FFDecConfig&amp; cfg)
199 114  
200 115 // 打开解码器流
201 116 AVDictionary *op = nullptr;
202   - av_dict_set( &op, "gpu", cfg.gpuid.c_str(), 0 );
  117 + av_dict_set( &op, "gpu", gpuid, 0 );
203 118 if (avcodec_open2(avctx, vcodec, &op) < 0) {
204 119 cout << "Failed to open codec for stream" << stream_index;
205 120 return false;
... ... @@ -324,8 +239,13 @@ void FFNvDecoder::post_decode_thread()
324 239 void FFNvDecoder::close()
325 240 {
326 241 m_bRunning=false;
327   - pthread_join(m_decode_thread,0);
328   - pthread_join(m_post_decode_thread,0);
  242 + if(m_decode_thread != 0){
  243 + pthread_join(m_decode_thread,0);
  244 + }
  245 + if (m_post_decode_thread != 0)
  246 + {
  247 + pthread_join(m_post_decode_thread,0);
  248 + }
329 249  
330 250 if (avctx)
331 251 {
... ...
src/FFNvDecoder.h
... ... @@ -41,8 +41,7 @@ class FFNvDecoder{
41 41 public:
42 42 FFNvDecoder();
43 43 ~FFNvDecoder();
44   - bool init(const string& path);
45   - bool init2(FFDecConfig& cfg);
  44 + bool init(FFDecConfig& cfg);
46 45 void close();
47 46 void start();
48 47 void pause();
... ... @@ -60,6 +59,7 @@ public:
60 59 private:
61 60 void decode_thread();
62 61 void post_decode_thread();
  62 + bool init(const char* uri, const char* gpuid, bool force_tcp);
63 63  
64 64 public:
65 65 POST_DECODE_CALLBACK post_decoded_cbk;
... ...
src/FFNvDecoderManager.cpp
... ... @@ -17,7 +17,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig&amp; config){
17 17 return nullptr;
18 18 }
19 19  
20   - bool bRet= dec->init2(config.cfg);
  20 + bool bRet= dec->init(config.cfg);
21 21 if (bRet)
22 22 {
23 23 dec->setName(config.name) ;
... ... @@ -172,10 +172,27 @@ bool FFNvDecoderManager::resumeDecoder(string name)
172 172 return false;
173 173 }
174 174  
175   -bool FFNvDecoderManager::isSurport(const char* uri)
  175 +bool FFNvDecoderManager::isSurport(FFDecConfig& cfg)
176 176 {
177 177 FFNvDecoder dec;
178   - bool bRet = dec.init(uri);
  178 + bool bRet = dec.init(cfg);
179 179 dec.close();
180 180 return bRet;
  181 +}
  182 +
  183 +bool FFNvDecoderManager::isRunning(string name){
  184 + if (name.empty())
  185 + {
  186 + cout << "name 为空!"<< endl;
  187 + return false;
  188 + }
  189 +
  190 + auto dec = decoderMap.find(name);
  191 + if (dec != decoderMap.end())
  192 + {
  193 + return dec->second->isRunning();
  194 + }
  195 +
  196 + cout << "没有找到name为" << name << "的解码器!" << endl;
  197 + return false;
181 198 }
182 199 \ No newline at end of file
... ...
src/FFNvDecoderManager.h
... ... @@ -41,7 +41,9 @@ public:
41 41 bool pauseDecoder(string name);
42 42 bool resumeDecoder(string name);
43 43  
44   - bool isSurport(const char* uri);
  44 + bool isSurport(FFDecConfig& cfg);
  45 +
  46 + bool isRunning(string name);
45 47  
46 48 int count();
47 49  
... ...