diff --git a/src/FFNvDecoder.cpp b/src/FFNvDecoder.cpp index f2ef798..6ba885f 100644 --- a/src/FFNvDecoder.cpp +++ b/src/FFNvDecoder.cpp @@ -41,6 +41,8 @@ FFNvDecoder::FFNvDecoder() m_decode_thread = 0; m_post_decode_thread = 0; + + m_bFinished = false; } FFNvDecoder::~FFNvDecoder() @@ -73,12 +75,12 @@ bool FFNvDecoder::init(const char* uri, const char* gpuid, bool force_tcp) av_dict_set( &options, "bufsize", "655360", 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_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 fmt_ctx = avformat_alloc_context(); const char* input_file = uri; if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { - cout << "Cannot open input file" << input_file; + cout << "Cannot open input file: " << input_file; return false; } @@ -135,6 +137,13 @@ void FFNvDecoder::start(){ return (void*)0; } ,this); +} + +void FFNvDecoder::decode_thread() +{ + AVPacket* pkt ; + pkt = av_packet_alloc(); + av_init_packet( pkt ); pthread_create(&m_post_decode_thread,0, [](void* arg) @@ -144,13 +153,6 @@ void FFNvDecoder::start(){ return (void*)0; } ,this); -} - -void FFNvDecoder::decode_thread() -{ - AVPacket* pkt ; - pkt = av_packet_alloc(); - av_init_packet( pkt ); while (m_bRunning) { @@ -214,9 +216,36 @@ void FFNvDecoder::decode_thread() } m_bRunning = false; + + if (m_post_decode_thread != 0) + { + pthread_join(m_post_decode_thread,0); + } + + decode_finished(); + cout << "decode thread exited." << endl; } +void FFNvDecoder::decode_finished() +{ + if (avctx) + { + if (avctx->hw_device_ctx) + { + av_buffer_unref(&avctx->hw_device_ctx); + } + avcodec_free_context(&avctx); + } + + if (fmt_ctx) + { + avformat_close_input(&fmt_ctx); + } + + m_bFinished = true; +} + void FFNvDecoder::post_decode_thread() { while (m_bRunning) @@ -242,24 +271,6 @@ void FFNvDecoder::close() 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) - { - if (avctx->hw_device_ctx) - { - av_buffer_unref(&avctx->hw_device_ctx); - } - avcodec_free_context(&avctx); - } - - if (fmt_ctx) - { - avformat_close_input(&fmt_ctx); - } } void FFNvDecoder::setName(string nm){ @@ -280,6 +291,11 @@ bool FFNvDecoder::isRunning() return m_bRunning; } +bool FFNvDecoder::isFinished() +{ + return m_bFinished; +} + bool FFNvDecoder::getResolution( int &width, int &height ) { if (avctx != nullptr) diff --git a/src/FFNvDecoder.h b/src/FFNvDecoder.h index 8bad29c..6e39b93 100644 --- a/src/FFNvDecoder.h +++ b/src/FFNvDecoder.h @@ -48,6 +48,7 @@ public: void resume(); bool isRunning(); + bool isFinished(); bool getResolution( int &width, int &height ); void setName(string nm); @@ -60,6 +61,7 @@ private: void decode_thread(); void post_decode_thread(); bool init(const char* uri, const char* gpuid, bool force_tcp); + void decode_finished(); public: POST_DECODE_CALLBACK post_decoded_cbk; @@ -77,6 +79,7 @@ private: pthread_t m_post_decode_thread; bool m_bRunning; + bool m_bFinished; string name; bool m_bPause; diff --git a/src/FFNvDecoderManager.cpp b/src/FFNvDecoderManager.cpp index bb6dc54..c7c2057 100644 --- a/src/FFNvDecoderManager.cpp +++ b/src/FFNvDecoderManager.cpp @@ -3,7 +3,11 @@ using namespace std; + FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig& config){ + + closeAllFinishedDecoder(); + int num = decoderMap.count(config.name); if (num > 0) { @@ -126,11 +130,26 @@ void FFNvDecoderManager::closeAllDecoder() { for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ iter->second->close(); + delete iter->second; + } + decoderMap.clear(); +} + +void FFNvDecoderManager::closeAllFinishedDecoder() +{ + for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ + if (iter->second->isFinished()) + { + delete iter->second; + decoderMap.erase(iter); + } } } int FFNvDecoderManager::count() { + closeAllFinishedDecoder(); + return decoderMap.size(); } diff --git a/src/FFNvDecoderManager.h b/src/FFNvDecoderManager.h index 16243e3..b609339 100644 --- a/src/FFNvDecoderManager.h +++ b/src/FFNvDecoderManager.h @@ -37,6 +37,9 @@ public: bool closeDecoderByName(string name); void closeAllDecoder(); + void closeAllFinishedDecoder(); + + bool removeDecoderByName(string name); bool pauseDecoder(string name); bool resumeDecoder(string name); diff --git a/src/main.cpp b/src/main.cpp index 66ebcf9..a36d59a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,11 +14,11 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){ FFNvDecoder* decoder = (FFNvDecoder*)userPtr; if (decoder!= nullptr) { - cout << decoder->getName() << endl; - const char* gpu_pixfmt = av_get_pix_fmt_name((AVPixelFormat)gpuFrame->format); - cout << "pixfmt: " << gpu_pixfmt << endl; + cout << "decode name: " << decoder->getName() << endl; + // const char* gpu_pixfmt = av_get_pix_fmt_name((AVPixelFormat)gpuFrame->format); + // cout << "pixfmt: " << gpu_pixfmt << endl; cout << "keyframe: " << gpuFrame->key_frame << " width: " << gpuFrame->width << " height: "<< gpuFrame->height << endl; - cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl; + // cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl; if (gpuFrame->format == AV_PIX_FMT_CUDA) { @@ -42,25 +42,37 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){ } } -int main(){ - +void createDecode(int index){ FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); MgrDecConfig config; - config.name = "dec1"; - config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; + config.name = "dec" + to_string(index); + config.cfg.uri = "rtsp://176.10.0.4:8554/stream"; config.cfg.post_decoded_cbk = postDecoded; config.cfg.force_tcp = true; config.cfg.gpuid = "1"; FFNvDecoder* decoder = pDecManager->createDecoder(config); if (!decoder) { - return 1; + return ; } pDecManager->setUserPtr(config.name, decoder); pDecManager->startDecodeByName(config.name); +} + +int main(){ + + FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); + // for (size_t i = 0; i < 20; i++) + // { + // createDecode(i); + // } + + MgrDecConfig config; config.name = "dec2"; - config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; + config.cfg.uri = "/home/cmhu/data/test.mp4"; + config.cfg.post_decoded_cbk = postDecoded; + config.cfg.force_tcp = true; config.cfg.gpuid = "2"; FFNvDecoder* dec2 = pDecManager->createDecoder(config); if (!dec2) @@ -71,27 +83,27 @@ int main(){ pDecManager->startDecodeByName(config.name); - config.name = "dec0"; - config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; - config.cfg.gpuid = "0"; - FFNvDecoder* dec0 = pDecManager->createDecoder(config); - if (!dec0) - { - return 1; - } - pDecManager->setUserPtr(config.name, dec0); - pDecManager->startDecodeByName(config.name); - - config.name = "dec01"; - config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; - config.cfg.gpuid = "0"; - FFNvDecoder* dec01 = pDecManager->createDecoder(config); - if (!dec01) - { - return 1; - } - pDecManager->setUserPtr(config.name, dec01); - pDecManager->startDecodeByName(config.name); + // config.name = "dec0"; + // config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; + // config.cfg.gpuid = "0"; + // FFNvDecoder* dec0 = pDecManager->createDecoder(config); + // if (!dec0) + // { + // return 1; + // } + // pDecManager->setUserPtr(config.name, dec0); + // pDecManager->startDecodeByName(config.name); + + // config.name = "dec01"; + // config.cfg.uri = "rtmp://192.168.10.56:1935/objecteye/1"; + // config.cfg.gpuid = "0"; + // FFNvDecoder* dec01 = pDecManager->createDecoder(config); + // if (!dec01) + // { + // return 1; + // } + // pDecManager->setUserPtr(config.name, dec01); + // pDecManager->startDecodeByName(config.name); // while (getchar() != 'q');