diff --git a/src/FFNvDecoder.cpp b/src/FFNvDecoder.cpp index 6eb369f..f2ef798 100644 --- a/src/FFNvDecoder.cpp +++ b/src/FFNvDecoder.cpp @@ -38,6 +38,9 @@ FFNvDecoder::FFNvDecoder() m_bPause = false; m_bReal = true; + + m_decode_thread = 0; + m_post_decode_thread = 0; } FFNvDecoder::~FFNvDecoder() @@ -45,97 +48,7 @@ FFNvDecoder::~FFNvDecoder() } -bool FFNvDecoder::init(const string& path) -{ - fstream infile(path); - if (infile.is_open()){ - m_bReal = false; - infile.close(); - }else { - m_bReal = true; - } - - // 查找对应的硬件解码设备 - const char* device_name = "cuda"; - AVHWDeviceType hw_device_type = av_hwdevice_find_type_by_name(device_name); - if (hw_device_type == AV_HWDEVICE_TYPE_NONE) { - while ((hw_device_type = av_hwdevice_iterate_types(hw_device_type)) != AV_HWDEVICE_TYPE_NONE) - cout << av_hwdevice_get_type_name(hw_device_type); - return false; - } - - // 打开输入视频文件 - AVDictionary *options = nullptr; - av_dict_set( &options, "bufsize", "1024000", 0 ); - av_dict_set( &options, "rtsp_transport", "tcp", 0 ); - av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s - fmt_ctx = avformat_alloc_context(); - const char* input_file = path.c_str(); - if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { - cout << "Cannot open input file" << input_file; - return false; - } - - // 查找流信息 - if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) { - cout << "Cannot find input stream information"; - return false; - } - - // 查找视频流信息 - AVCodec *decoder = nullptr; - stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); - if (stream_index < 0) { - cout << "Cannot find a video stream in the input file"; - return false; - } - - // 判断硬件解码设备是否兼容视频解码器 - for (int i = 0;; i++) { - const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i); - if (!config) { - cout << "Decoder does not support device hw_device_type" - << decoder->name << av_hwdevice_get_type_name(hw_device_type); - return false; - } - // 得到硬件解码像素格式 - if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && - config->device_type == hw_device_type) { - hw_pix_fmt = config->pix_fmt; - break; - } - } - - // 得到解码器管理器 - if (!(avctx = avcodec_alloc_context3(decoder))) - return (bool)AVERROR(ENOMEM); - - // 得到视频流对象 - stream = fmt_ctx->streams[stream_index]; - if (avcodec_parameters_to_context(avctx, stream->codecpar) < 0) - return false; - - avctx->opaque = this; - // 设置解码器管理器的像素格式回调函数 - avctx->get_format = get_hw_format; - - // 初始化硬件解码器 - AVBufferRef *hw_device_ctx = nullptr; - if (av_hwdevice_ctx_create(&hw_device_ctx, hw_device_type, nullptr, nullptr, 0) < 0) { - cout << "Failed to create specified HW device."; - return false; - } - - // 打开解码器流 - if (avcodec_open2(avctx, decoder, nullptr) < 0) { - cout << "Failed to open codec for stream" << stream_index; - return false; - } - - return true; -} - -bool FFNvDecoder::init2(FFDecConfig& cfg) +bool FFNvDecoder::init(FFDecConfig& cfg) { m_cfg = cfg; @@ -147,20 +60,23 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) m_bReal = true; } - + return init(cfg.uri.c_str(), cfg.gpuid.c_str(),cfg.force_tcp); +} + +bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) +{ + av_register_all(); + avformat_network_init(); // 打开输入视频文件 AVDictionary *options = nullptr; av_dict_set( &options, "bufsize", "655360", 0 ); - av_dict_set( &options, "rtsp_transport", cfg.force_tcp ? "tcp" : "udp", 0 ); + av_dict_set( &options, "rtsp_transport", force_tcp ? "tcp" : "udp", 0 ); // av_dict_set( &options, "listen_timeout", "30", 0 ); // 单位为s av_dict_set( &options, "stimeout", "3000000", 0 ); - - av_register_all(); - avformat_network_init(); fmt_ctx = avformat_alloc_context(); - const char* input_file = cfg.uri.c_str(); + const char* input_file = uri; if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { cout << "Cannot open input file" << input_file; return false; @@ -180,7 +96,6 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) return false; } - string cuvid_dec_name = string(decoder->name) + "_cuvid"; AVCodec *vcodec = avcodec_find_decoder_by_name(cuvid_dec_name.c_str()); if (!(avctx = avcodec_alloc_context3(vcodec))) @@ -199,7 +114,7 @@ bool FFNvDecoder::init2(FFDecConfig& cfg) // 打开解码器流 AVDictionary *op = nullptr; - av_dict_set( &op, "gpu", cfg.gpuid.c_str(), 0 ); + av_dict_set( &op, "gpu", gpuid, 0 ); if (avcodec_open2(avctx, vcodec, &op) < 0) { cout << "Failed to open codec for stream" << stream_index; return false; @@ -324,8 +239,13 @@ void FFNvDecoder::post_decode_thread() void FFNvDecoder::close() { m_bRunning=false; - pthread_join(m_decode_thread,0); - pthread_join(m_post_decode_thread,0); + if(m_decode_thread != 0){ + pthread_join(m_decode_thread,0); + } + if (m_post_decode_thread != 0) + { + pthread_join(m_post_decode_thread,0); + } if (avctx) { diff --git a/src/FFNvDecoder.h b/src/FFNvDecoder.h index 17a96b1..8bad29c 100644 --- a/src/FFNvDecoder.h +++ b/src/FFNvDecoder.h @@ -41,8 +41,7 @@ class FFNvDecoder{ public: FFNvDecoder(); ~FFNvDecoder(); - bool init(const string& path); - bool init2(FFDecConfig& cfg); + bool init(FFDecConfig& cfg); void close(); void start(); void pause(); @@ -60,6 +59,7 @@ public: private: void decode_thread(); void post_decode_thread(); + bool init(const char* uri, const char* gpuid, bool force_tcp); public: POST_DECODE_CALLBACK post_decoded_cbk; diff --git a/src/FFNvDecoderManager.cpp b/src/FFNvDecoderManager.cpp index 0800a94..bb6dc54 100644 --- a/src/FFNvDecoderManager.cpp +++ b/src/FFNvDecoderManager.cpp @@ -17,7 +17,7 @@ FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ return nullptr; } - bool bRet= dec->init2(config.cfg); + bool bRet= dec->init(config.cfg); if (bRet) { dec->setName(config.name) ; @@ -172,10 +172,27 @@ bool FFNvDecoderManager::resumeDecoder(string name) return false; } -bool FFNvDecoderManager::isSurport(const char* uri) +bool FFNvDecoderManager::isSurport(FFDecConfig& cfg) { FFNvDecoder dec; - bool bRet = dec.init(uri); + bool bRet = dec.init(cfg); dec.close(); return bRet; +} + +bool FFNvDecoderManager::isRunning(string name){ + if (name.empty()) + { + cout << "name 为空!"<< endl; + return false; + } + + auto dec = decoderMap.find(name); + if (dec != decoderMap.end()) + { + return dec->second->isRunning(); + } + + cout << "没有找到name为" << name << "的解码器!" << endl; + return false; } \ No newline at end of file diff --git a/src/FFNvDecoderManager.h b/src/FFNvDecoderManager.h index 9cc9811..16243e3 100644 --- a/src/FFNvDecoderManager.h +++ b/src/FFNvDecoderManager.h @@ -41,7 +41,9 @@ public: bool pauseDecoder(string name); bool resumeDecoder(string name); - bool isSurport(const char* uri); + bool isSurport(FFDecConfig& cfg); + + bool isRunning(string name); int count();