Commit e96e6489e333fe15d6737d3350b12c194d044345
1 parent
0b43216c
优化代码;添加isRunning函数
Showing
4 changed files
with
46 additions
and
107 deletions
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& 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& 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& 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& 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