#include "DecoderManager.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; DecoderManager::~DecoderManager(){ closeAllDecoder(); avformat_network_deinit(); } void DecoderManager::init() { #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); #endif #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100) avcodec_register_all(); #endif avformat_network_init(); } AbstractDecoder* DecoderManager::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 DecoderManager::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 DecoderManager::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* DecoderManager::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 DecoderManager::startDecode(AbstractDecoder* dec){ if (dec != nullptr && !dec->isRunning()) { return dec->start(); } return false; } bool DecoderManager::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 DecoderManager::startAllDecode(){ std::lock_guard l(m_mutex); for(auto iter = decoderMap.begin(); iter != decoderMap.end(); iter++){ if (!iter->second->isRunning()) { iter->second->start(); } } } bool DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::count() { closeAllFinishedDecoder(); std::lock_guard l(m_mutex); return decoderMap.size(); } bool DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::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 DecoderManager::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; } bool DecoderManager::getOutResolution(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->getOutResolution(width, height); return true; } LOG_ERROR("没有找到name为{}的解码器",name); return false; } vector DecoderManager::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 DecoderManager::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 DecoderManager::releaseDeviceMemory(DeviceMemory* info){ if(nullptr != info){ delete info; info = nullptr; } } DeviceMemory* DecoderManager::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 DecoderManager::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()){ DeviceMemory* imginfo = it->second->snapshot(); if(imginfo != nullptr){ vec.push_back(imginfo); } it->second->updateLastSnapTime(); } } return vec; } DeviceMemory* DecoderManager::snapshot_out_task(string& uri, int devId) { FFDecConfig cfg; cfg.uri = uri; cfg.post_decoded_cbk = nullptr; cfg.decode_finished_cbk = nullptr; cfg.force_tcp = true; // rtsp用tcp cfg.gpuid = to_string(devId); cfg.skip_frame = 0; AbstractDecoder* dec = new DvppDecoderApi(); if (dec == nullptr){ LOG_ERROR("解码器创建失败"); return nullptr; } DeviceMemory* devMem = nullptr; bool bRet= dec->init(cfg); if (bRet){ LOG_INFO("snapshot 解码器初始化成功"); dec->start(); devMem = dec->snapshot(); } // 创建失败,关闭解码器 dec->close(); delete dec; return devMem; } void DecoderManager::doRecode(RecoderInfo& recoderInfo) { string name = recoderInfo.task_id; if (name.empty()){ LOG_ERROR("name 为空!"); return; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()){ dec->second->doRecode(recoderInfo); return; } LOG_ERROR("没有找到name为{}的解码器",name); return; } void DecoderManager::set_mq_callback(const string name, std::function mq_publish) { if (name.empty()){ LOG_ERROR("name 为空!"); return; } std::lock_guard l(m_mutex); auto dec = decoderMap.find(name); if (dec != decoderMap.end()){ dec->second->set_mq_callback(mq_publish); return; } LOG_ERROR("没有找到name为{}的解码器",name); return; }