zoukankan      html  css  js  c++  java
  • 设置I帧的QP,提高I帧的质量

    作者

    Hank FU hankf@xilinx.com 2021-09-30

    介绍

    在有些应用中,发现I帧不够大。MPSoC VCU CtrlSW可以设置每一帧的QP大小。因此,可以通过设置I帧的QP,提高I帧的大小,从而提高I帧的质量。

    代码

    下面是设置I帧的QP的示例代码。

    GOP长度变量

    在struct EncoderSink : IFrameSink的定义里添加GOP的成员变量,记录GOP长度。

    #if USER_I_FRAME_QP
                   // USER_I_FRAME_QP changes START 
                   float uFrameRate = 0.0f;
                   int uGopLength = 0; 
                   // USER_I_FRAME_QP changes END 
    			   
    #endif  // USER_I_FRAME_QP
    

    记录GOP长度

    在EncoderSink 的EncoderSink函数设置GOP的变量的值。

                struct EncoderSink : IFrameSink
    {
      EncoderSink(ConfigFile const& cfg, AL_IEncScheduler* pScheduler, AL_TAllocator* pAllocator
                  ) :
        CmdFile(cfg.sCmdFileName, false),
        EncCmd(CmdFile.fp, cfg.RunInfo.iScnChgLookAhead, cfg.Settings.tChParam[0].tGopParam.uFreqLT),
        twoPassMngr(cfg.sTwoPassFileName, cfg.Settings.TwoPass, cfg.Settings.bEnableFirstPassSceneChangeDetection, cfg.Settings.tChParam[0].tGopParam.uGopLength,
                    cfg.Settings.tChParam[0].tRCParam.uCPBSize / 90, cfg.Settings.tChParam[0].tRCParam.uInitialRemDelay / 90, cfg.MainInput.FileInfo.FrameRate),
        qpBuffers{cfg.Settings, cfg.RunInfo.eGenerateQpMode},
        pAllocator{pAllocator},
        pSettings{&cfg.Settings}
      {
     
    #if USER_I_FRAME_QP
                     // USER_I_FRAME_QP changes STARTED ----------------------------------
                     uFrameRate = cfg.Settings.tChParam.tRCParam.uFrameRate;
                     uGopLength = cfg.Settings.tChParam.tGopParam.uGopLength;
                     // USER_I_FRAME_QP changes END --------------------------------------
    #endif  // USER_I_FRAME_QP
     
        } 
    

    设置QP

    在EncoderSink 的ProcessFrame函数里,根据GOP长度,确定每个GOP开始的I帧。然后再设置QP的值。可以试试20-35之间的QP值。QP值是20时,能带来很好的图像质量。

    void ProcessFrame(AL_TBuffer* Src) override
      {
        if(m_picCount == 0)
          m_StartTime = GetPerfTime();
     
        if(!Src)
        {
          LogVerbose("Flushing...
    
    ");
     
          if(!AL_Encoder_Process(hEnc, nullptr, nullptr))
            throw std::runtime_error("Failed");
          return;
        }
     
        DisplayFrameStatus(m_picCount);
     
        if(twoPassMngr.iPass)
        {
          auto pPictureMetaTP = AL_TwoPassMngr_CreateAndAttachTwoPassMetaData(Src);
     
          if(twoPassMngr.iPass == 2)
            twoPassMngr.GetFrame(pPictureMetaTP);
        }
     
        AL_TBuffer* QpBuf = qpBuffers.getBuffer(m_picCount);
     
        std::shared_ptr<AL_TBuffer> QpBufShared(QpBuf, [&](AL_TBuffer* pBuf) { qpBuffers.releaseBuffer(pBuf); });
     
        if(pSettings->hRcPluginDmaContext != NULL)
          RCPlugin_SetNextFrameQP(pSettings, pAllocator);
     
    #if   USER_I_FRAME_QP
        if( 0 == (m_picCount%uGopLength) )
        {
     
            AL_Encoder_SetQP(hEnc, 20 );
        }
    #endif  // USER_I_FRAME_QP
     
        
        if(!AL_Encoder_Process(hEnc, Src, QpBuf))
          throw std::runtime_error("Failed");
     
        m_picCount++;
        m_picGopCount++;
      }
    
  • 相关阅读:
    理解和驾驭软件开发的那些事儿
    Dubbo 泛化调用的参数解析问题及一个强大的参数解析工具 PojoUtils
    HBase指定大量列集合的场景下并发拉取数据时卡住的问题排查
    阅读的收获
    碎碎念集萃二十
    《深度工作》学习笔记
    系统思考学习笔记
    思考力笔记
    碎碎念集萃十九
    设计方案考量的准则与细则
  • 原文地址:https://www.cnblogs.com/hankfu/p/15357536.html
Copyright © 2011-2022 走看看