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,6 +38,9 @@ FFNvDecoder::FFNvDecoder() | ||
38 | 38 | ||
39 | m_bPause = false; | 39 | m_bPause = false; |
40 | m_bReal = true; | 40 | m_bReal = true; |
41 | + | ||
42 | + m_decode_thread = 0; | ||
43 | + m_post_decode_thread = 0; | ||
41 | } | 44 | } |
42 | 45 | ||
43 | FFNvDecoder::~FFNvDecoder() | 46 | FFNvDecoder::~FFNvDecoder() |
@@ -45,97 +48,7 @@ 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 | m_cfg = cfg; | 53 | m_cfg = cfg; |
141 | 54 | ||
@@ -147,20 +60,23 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | @@ -147,20 +60,23 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | ||
147 | m_bReal = true; | 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 | AVDictionary *options = nullptr; | 72 | AVDictionary *options = nullptr; |
154 | av_dict_set( &options, "bufsize", "655360", 0 ); | 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 | // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s | 75 | // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s |
157 | av_dict_set( &options, "stimeout", "3000000", 0 ); | 76 | av_dict_set( &options, "stimeout", "3000000", 0 ); |
158 | - | ||
159 | - av_register_all(); | ||
160 | - avformat_network_init(); | ||
161 | 77 | ||
162 | fmt_ctx = avformat_alloc_context(); | 78 | fmt_ctx = avformat_alloc_context(); |
163 | - const char* input_file = cfg.uri.c_str(); | 79 | + const char* input_file = uri; |
164 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { | 80 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { |
165 | cout << "Cannot open input file" << input_file; | 81 | cout << "Cannot open input file" << input_file; |
166 | return false; | 82 | return false; |
@@ -180,7 +96,6 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | @@ -180,7 +96,6 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | ||
180 | return false; | 96 | return false; |
181 | } | 97 | } |
182 | 98 | ||
183 | - | ||
184 | string cuvid_dec_name = string(decoder->name) + "_cuvid"; | 99 | string cuvid_dec_name = string(decoder->name) + "_cuvid"; |
185 | AVCodec *vcodec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str()); | 100 | AVCodec *vcodec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str()); |
186 | if (!(avctx = avcodec_alloc_context3(vcodec))) | 101 | if (!(avctx = avcodec_alloc_context3(vcodec))) |
@@ -199,7 +114,7 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | @@ -199,7 +114,7 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) | ||
199 | 114 | ||
200 | // 打开解码器流 | 115 | // 打开解码器流 |
201 | AVDictionary *op = nullptr; | 116 | AVDictionary *op = nullptr; |
202 | - av_dict_set( &op, "gpu", cfg.gpuid.c_str(), 0 ); | 117 | + av_dict_set( &op, "gpu", gpuid, 0 ); |
203 | if (avcodec_open2(avctx, vcodec, &op) < 0) { | 118 | if (avcodec_open2(avctx, vcodec, &op) < 0) { |
204 | cout << "Failed to open codec for stream" << stream_index; | 119 | cout << "Failed to open codec for stream" << stream_index; |
205 | return false; | 120 | return false; |
@@ -324,8 +239,13 @@ void FFNvDecoder::post_decode_thread() | @@ -324,8 +239,13 @@ void FFNvDecoder::post_decode_thread() | ||
324 | void FFNvDecoder::close() | 239 | void FFNvDecoder::close() |
325 | { | 240 | { |
326 | m_bRunning=false; | 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 | if (avctx) | 250 | if (avctx) |
331 | { | 251 | { |
src/FFNvDecoder.h
@@ -41,8 +41,7 @@ class FFNvDecoder{ | @@ -41,8 +41,7 @@ class FFNvDecoder{ | ||
41 | public: | 41 | public: |
42 | FFNvDecoder(); | 42 | FFNvDecoder(); |
43 | ~FFNvDecoder(); | 43 | ~FFNvDecoder(); |
44 | - bool init(const string& path); | ||
45 | - bool init2(FFDecConfig& cfg); | 44 | + bool init(FFDecConfig& cfg); |
46 | void close(); | 45 | void close(); |
47 | void start(); | 46 | void start(); |
48 | void pause(); | 47 | void pause(); |
@@ -60,6 +59,7 @@ public: | @@ -60,6 +59,7 @@ public: | ||
60 | private: | 59 | private: |
61 | void decode_thread(); | 60 | void decode_thread(); |
62 | void post_decode_thread(); | 61 | void post_decode_thread(); |
62 | + bool init(const char* uri, const char* gpuid, bool force_tcp); | ||
63 | 63 | ||
64 | public: | 64 | public: |
65 | POST_DECODE_CALLBACK post_decoded_cbk; | 65 | POST_DECODE_CALLBACK post_decoded_cbk; |
src/FFNvDecoderManager.cpp
@@ -17,7 +17,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ | @@ -17,7 +17,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ | ||
17 | return nullptr; | 17 | return nullptr; |
18 | } | 18 | } |
19 | 19 | ||
20 | - bool bRet= dec->init2(config.cfg); | 20 | + bool bRet= dec->init(config.cfg); |
21 | if (bRet) | 21 | if (bRet) |
22 | { | 22 | { |
23 | dec->setName(config.name) ; | 23 | dec->setName(config.name) ; |
@@ -172,10 +172,27 @@ bool FFNvDecoderManager::resumeDecoder(string name) | @@ -172,10 +172,27 @@ bool FFNvDecoderManager::resumeDecoder(string name) | ||
172 | return false; | 172 | return false; |
173 | } | 173 | } |
174 | 174 | ||
175 | -bool FFNvDecoderManager::isSurport(const char* uri) | 175 | +bool FFNvDecoderManager::isSurport(FFDecConfig& cfg) |
176 | { | 176 | { |
177 | FFNvDecoder dec; | 177 | FFNvDecoder dec; |
178 | - bool bRet = dec.init(uri); | 178 | + bool bRet = dec.init(cfg); |
179 | dec.close(); | 179 | dec.close(); |
180 | return bRet; | 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 | \ No newline at end of file | 199 | \ No newline at end of file |
src/FFNvDecoderManager.h
@@ -41,7 +41,9 @@ public: | @@ -41,7 +41,9 @@ public: | ||
41 | bool pauseDecoder(string name); | 41 | bool pauseDecoder(string name); |
42 | bool resumeDecoder(string name); | 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 | int count(); | 48 | int count(); |
47 | 49 |