FFNvDecoderManager.cpp 8.29 KB
#include "FFNvDecoderManager.h"

using namespace std;


FFNvDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){

    closeAllFinishedDecoder();

    std::lock_guard<std::mutex> l(m_mutex);

    auto it = decoderMap.find(config.name);
    if (it != decoderMap.end()){
        av_log(NULL, AV_LOG_ERROR, "已存在name所标记的解码器 \n");
        return nullptr;
    }
    
    FFNvDecoder* dec = new FFNvDecoder();
    if (dec == nullptr)
    {
        return nullptr;
    }
    
    bool bRet= dec->init(config.cfg);
    if (bRet)
    {
        dec->setName(config.name) ;
        dec->post_decoded_cbk = config.cfg.post_decoded_cbk;
        dec->decode_finished_cbk = config.cfg.decode_finished_cbk;
        decoderMap[config.name] = dec;
        return dec;
    }
    
    // 创建失败,关闭解码器
    dec->close();
    delete dec;

    return nullptr;
}

bool FFNvDecoderManager::setUserPtr(const string name, const void * userPtr)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->m_userPtr = userPtr;
        return true;
    }

    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

FFNvDecoder* FFNvDecoderManager::getDecoderByName(const string name)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return nullptr;
    }
    
    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        return dec->second;
    }

    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return nullptr;
}

void FFNvDecoderManager::startDecode(FFNvDecoder* dec){
    if (dec != nullptr && !dec->isRunning())
    {
        dec->start();
    }
}

bool FFNvDecoderManager::startDecodeByName(const string name){
     if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->start();
        return true;
    }

    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

void FFNvDecoderManager::startAllDecode(){

    std::lock_guard<std::mutex> 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())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> 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;
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

void FFNvDecoderManager::closeAllDecoder()
{
    std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> l(m_mutex);
    return decoderMap.size();
}

bool FFNvDecoderManager::pauseDecoder(const string name)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->pause();
        return true;
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::resumeDecoder(const string name)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->resume();
        return true;
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::isSurport(FFDecConfig& cfg)
{
    FFNvDecoder dec;
    return dec.isSurport(cfg);
}

bool FFNvDecoderManager::isRunning(const string name){
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        return dec->second->isRunning();
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::isFinished(const string name){
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        return dec->second->isFinished();
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::isPausing(const string name){
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        return dec->second->isPausing();
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::setDecKeyframe(const string name, bool bKeyframe)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->setDecKeyframe(bKeyframe);
        return true;
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

bool FFNvDecoderManager::getResolution(const string name, int &width, int &height)
{
    if (name.empty())
    {
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return false;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end())
    {
        dec->second->getResolution(width, height);
        return true;
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return false;
}

vector<string> FFNvDecoderManager::getAllDecodeName(){
    
    closeAllFinishedDecoder();

    std::lock_guard<std::mutex> l(m_mutex);

    vector<string> 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()){
        av_log(NULL, AV_LOG_ERROR, "name 为空! \n");
        return -1;
    }

    std::lock_guard<std::mutex> l(m_mutex);

    auto dec = decoderMap.find(name);
    if (dec != decoderMap.end()){
        return dec->second->getCachedQueueLength();
    }
    
    av_log(NULL, AV_LOG_ERROR, "没有找到name为 %s 的解码器! \n", name.c_str());
    return -1;
}

FFImgInfo* FFNvDecoderManager::snapshot(const string& uri){
    return FFNvDecoder::snapshot(uri);
}

void FFNvDecoderManager::releaseFFImgInfo(FFImgInfo* info){
    FFNvDecoder::releaseFFImgInfo(info);
}