#include "FFNvDecoderManager.h" #ifdef USE_NVDEC #include "../nvdec/FFNvDecoder.h" #include "../gb28181/FFGB28181Decoder.h" #endif #ifdef USE_DVPP #include "./dvpp/DvppDecoderApi.h" #endif #include "logger.hpp" using namespace std; AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){ closeAllFinishedDecoder(); if (config.cfg.post_decoded_cbk == nullptr || config.cfg.decode_finished_cbk== nullptr){ return nullptr; } std::lock_guard l(m_mutex); auto it = decoderMap.find(config.name); if (it != decoderMap.end()){ LOG_ERROR("已存在name为{}的解码器", config.name); return nullptr; } AbstractDecoder* dec = nullptr; #ifdef USE_NVDEC if(DECODER_TYPE_FFMPEG == config.dec_type){ dec = new FFNvDecoder(); } if(DECODER_TYPE_GB28181 == config.dec_type){ dec = new FFGB28181Decoder(); } #endif #ifdef USE_DVPP if(DECODER_TYPE_DVPP == config.dec_type){ dec = new DvppDecoderApi(); } #endif if (dec == nullptr){ LOG_ERROR("没有指定解码器类型"); return nullptr; } config.cfg.dec_name = config.name; bool bRet= dec->init(config.cfg); if (bRet) { decoderMap[config.name] = dec; LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri); return dec; } // 创建失败,关闭解码器 dec->close(); delete dec; LOG_ERROR("[{}][{}]- 解码器初始化失败!",config.name, config.cfg.uri); return nullptr; } bool FFNvDecoderManager::setPostDecArg(const string name, const void * userPtr) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->setPostDecArg(userPtr); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::setFinishedDecArg(const string name, const void * userPtr) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->setFinishedDecArg(userPtr); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } AbstractDecoder* FFNvDecoderManager::getDecoderByName(const string name) { if (name.empty()) { LOG_ERROR("name 为空!"); return nullptr; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { return dec->second; } LOG_ERROR("没有找到name为{}的解码器",name); return nullptr; } bool FFNvDecoderManager::startDecode(AbstractDecoder* dec){ if (dec != nullptr && !dec->isRunning()) { return dec->start(); } return false; } bool FFNvDecoderManager::startDecodeByName(const string name){ if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { return dec->second->start(); } LOG_ERROR("没有找到name为{}的解码器",name); return false; } void FFNvDecoderManager::startAllDecode(){ std::lock_guard l(m_mutex); for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ if (!iter->second->isRunning()) { iter->second->start(); } } } bool FFNvDecoderManager::closeDecoderByName(const string name){ if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->close(); delete dec->second; dec->second = nullptr; decoderMap.erase(dec); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } void FFNvDecoderManager::closeAllDecoder() { std::lock_guard l(m_mutex); for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ iter->second->close(); delete iter->second; iter->second = nullptr; } decoderMap.clear(); } void FFNvDecoderManager::closeAllFinishedDecoder() { std::lock_guard l(m_mutex); for(auto iter = decoderMap.begin(); iter != decoderMap.end(); ){ if (iter->second->isFinished()) { delete iter->second; iter->second = nullptr; iter = decoderMap.erase(iter); } else { iter++ ; } } } int FFNvDecoderManager::count() { closeAllFinishedDecoder(); std::lock_guard l(m_mutex); return decoderMap.size(); } bool FFNvDecoderManager::pauseDecoder(const string name) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->pause(); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::resumeDecoder(const string name) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->resume(); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::isSurport(MgrDecConfig& config) { { std::lock_guard l(m_mutex); auto it = decoderMap.find(config.name); if (it != decoderMap.end()){ LOG_ERROR("已存在name所标记的解码器"); return false; } } AbstractDecoder* dec = nullptr; #ifdef USE_NVDEC if(DECODER_TYPE_FFMPEG == config.dec_type){ dec = new FFNvDecoder(); } if(DECODER_TYPE_GB28181 == config.dec_type){ dec = new FFGB28181Decoder(); } #endif #ifdef USE_DVPP if(DECODER_TYPE_DVPP == config.dec_type){ dec = new DvppDecoderApi(); } #endif if (dec == nullptr){ LOG_ERROR("没有指定解码器类型"); return false; } bool bRet = dec->isSurport(config.cfg); delete dec; dec = nullptr; return bRet; } bool FFNvDecoderManager::isRunning(const string name){ if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { return dec->second->isRunning(); } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::isFinished(const string name){ if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { return dec->second->isFinished(); } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::isPausing(const string name){ if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { return dec->second->isPausing(); } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->setDecKeyframe(bKeyframe); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } bool FFNvDecoderManager::getResolution(const string name, int &width, int &height) { if (name.empty()) { LOG_ERROR("name 为空!"); return false; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()) { dec->second->getResolution(width, height); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } vector FFNvDecoderManager::getAllDecodeName(){ closeAllFinishedDecoder(); std::lock_guard l(m_mutex); vector decode_names; for(auto it = decoderMap.begin(); it != decoderMap.end(); ++it){ decode_names.push_back(it->first); } return decode_names; } int FFNvDecoderManager::getCachedQueueLength(const string name){ if (name.empty()){ LOG_ERROR("name 为空!"); return -1; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()){ return dec->second->getCachedQueueLength(); } LOG_ERROR("没有找到name为{}的解码器",name); return -1; } void FFNvDecoderManager::releaseFFImgInfo(FFImgInfo* info){ if(nullptr != info){ if(info->pData != nullptr){ free(info->pData); info->pData = nullptr; } delete info; info = nullptr; } } FFImgInfo* FFNvDecoderManager::snapshot_in_task(const string name){ if (name.empty()){ LOG_ERROR("name 为空!"); return nullptr; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()){ return dec->second->snapshot(); } LOG_ERROR("没有找到name为{}的解码器",name); return nullptr; } vector FFNvDecoderManager::timing_snapshot_all(){ closeAllFinishedDecoder(); std::lock_guard l(m_mutex); vector vec; for(auto it = decoderMap.begin(); it != decoderMap.end(); ++it){ if(it->second->isSnapTime()){ FFImgInfo* imginfo = it->second->snapshot(); if(imginfo != nullptr){ vec.push_back(imginfo); } it->second->updateLastSnapTime(); } } return vec; }