视频编码SVC --- JSVM代码阅读笔记(二)

    技术2022-05-20  27

    H264AVCEncoder::process( ExtBinDataAccessorList&  rcExtBinDataAccessorList,

                             PicBuffer*           apcOriginalPicBuffer    [MAX_LAYERS],   //每层的原始帧

                             PicBuffer*           apcReconstructPicBuffer [MAX_LAYERS],   //每层的重建帧

                             PicBufferList*        apcPicBufferOutputList,        //输出图像List

                             PicBufferList*        apcPicBufferUnusedList )       //未使用图像List

    这个H264AVCEncoderH264AVCEncoderTestCreaterH264AVCEncoderSVC编码器H264AVCEncoder

    //每一层的原始帧apcOriginalPicBufferèH264AVCEncoder::PicBufferList  m_acOrgPicBufferList[MAX_LAYERS]

    //每一层的重建帧apcReconstructPicBuffer èH264AVCEncoder::PicBufferList  m_acRecPicBufferList[MAX_LAYERS]

    关联OrgRec图像List!!!!!!!!!!!!!!!!!!!!!!

     

    //当读到了一个GOP数量的帧时,进行编码------------------并不是读完所有帧才编码

    xProcessGOP( apcPicBufferOutputList, apcPicBufferUnusedList )

    //对每一层                这里都是每一层!!!!!!!!!!!!!!!!!!!!!!!!!!!

      //设置D_idQ_id

     

      //m_cAccessUnitDataList弄出一个AU,读取对应层的原始帧

      m_apcLayerEncoder[uiLayer]->initGOP( m_cAccessUnitDataList.getAccessUnitData( MSYS_UINT_MAX ),

     m_acOrgPicBufferList[uiLayer] )   注意 这是LayerEncoder

         LayerEncoder的成员

      Frame*      m_apcFrameTemp[NUM_TMP_FRAMES];       // auxiliary frame memories

      Frame**     m_papcFrame;                          //读取每层的原始帧   编码后的重建帧

      Frame**     m_papcELFrame;                        // GOP最高EL层的参考帧

      Frame*      m_pcResidualLF;                       // frame stores for residual data

      Frame*      m_pcResidualILPred;                   // 层间预测的值(像素域)

      Frame*      m_pcSubband;                          //去块滤波之前的重建帧

      Frame*      m_apcBaseFrame[2];                    // RefBasePicGOP第一和最后一帧

     

      Frame*      m_pcAnchorFrameOriginal;              // GOP最后一针的原始数据

      Frame*      m_pcAnchorFrameReconstructed;         // GOP最后一帧的重建数据

      Frame*      m_pcBaseLayerFrame;                  // BLm_pcSubband

      Frame*      m_pcBaseLayerResidual;                // BL m_pcResidualILPred

     

    xInitGOP ( rcPicBufferInputList )  ---------------------------initGOP----------START-------------------

    //如果第一个GOP已经编码

    LayerEncoder成员Frame**  m_papcFrame的第一帧拷贝LayerEncoder成员

    Frame*  m_pcAnchorFrameOriginal的内容和参数

    m_papcELFrame只设置参数,没读取内容

     

    //GOP中每一帧

    m_papcFrame读取帧,设置POC

    m_papcFrame [ uiFrame ]->setPicParameters ( *m_pcResizeParameters )  //设置ReSize  帧和场的信息

    setPicParameters( cPP, ePicType )

    xUpdatePicParameters()

    m_papcELFrame不读取帧,但设置POCPicParameters

     

    //拷贝GOP最后一帧作为Anchor   (第一个I帧不算GOP的)

    m_pcAnchorFrameOriginal ->copyAll ( m_papcFrame[ m_uiGOPSize ] )

    m_pcAnchorFrameOriginal ->copyPicParameters (*m_papcFrame[ m_uiGOPSize ] );  //拷贝Resize信息

    m_pcAnchorFrameReconstructed ->copyPicParameters (*m_papcFrame[ m_uiGOPSize ] )

     

    //LayerEncoder的成员ControlData*  m_pacControlData用来控制GOP每一帧,其成员MbDataCtrl*   //getMbDataCtrl 用来控制所有Mb----------作为数组存在,关联MbDataMvDMotionTCoeff

    为每一帧初始化m_pacControlDatapcMbDataCtrl

     

    //设置SliceHeader和参考队列(marking   reordering  MMCO)

    xInitSliceHeadersAndRefLists()

      清空按帧播放顺序的参考队列m_acRefPicListFrameId_L0 m_acRefPicListFrameId_L1

      初始化播放顺序、编码顺序、时间分层顺序数组

     

      xInitRefFrameLists( uiFrameIdInGOP, uiTemporalId )  //设置前后向队列

      修正参考队列,并计算队列长度

     

      //GOP每一帧

    xInitSliceHeader( uiFrameIdInGOP, FRAME )

        //SH存在m_pacControlData[ uiFrameIdInGOP ]

        xSetSliceHeaderBase         ( *pcSliceHeader, uiFrameIdInGOP, ePicType )  //设置SH基本参数

    xSetSliceTypeAndRefLists    ( *pcSliceHeader, uiFrameIdInGOP, ePicType )

    m_acRefPicListFrameId_LX将播放顺序转成FrameNum顺序

    设置SliceTyperef_idx等等

    xSetReorderingCommandsST()    //参考队列重排序

    xSetMMCOAndUpdateParameters ( *pcSliceHeader, uiFrameIdInGOP, ePicType )   //进行MMCO

     

    //如果有去块滤波,初始化滤波参数

    pcSliceHeader->getDeblockingFilterParameter().setDisableDeblockingFilterIdc ( uiFilterIdc);

        pcSliceHeader->getDeblockingFilterParameter().setSliceAlphaC0Offset ( 2 * m_iAlphaOffset );

        pcSliceHeader->getDeblockingFilterParameter().setSliceBetaOffset    ( 2 * m_iBetaOffset );

     

        //计算并在SH里写POC

        m_pcPocCalculator->setPoc( *pcSliceHeader, m_papcFrame[uiFrameIdInGOP]->getPoc() + i2ndFieldOffset ) );

        rcSliceHeader.setBotFieldPoc( );

             rcSliceHeader.setDeltaPicOrderCntBottom ()

        rcSliceHeader.setPicOrderCntLsb ( iCurrPoc & ~( -1 << m_iBitsLsb ) );

        m_papcFrame[uiFrameIdInGOP]->setPoc( *pcSliceHeader )

     

        //初始化SH里的ESS参数

     

        //初始化SliceGroup

    pcSliceHeader->setSliceGroupChangeCycle(1);

        pcSliceHeader->FMOInit();

     

         xSetScalingFactors    ()

           //对每个时间层

           xSetScalingFactors( uiLevel )      //设定每帧的ScalingFactor

      

         xClearELPics  ()       //让所有EL的参考层不可用

           m_papcELFrame[uiIndex]->setUnvalid()

     

        //如果已经编码了GOP,则从前面的GOP中拷贝出重建的最后一帧

         xEncodePicture( bPicCoded, 0, 0, rcAccessUnitData, rcPicBufferInputList )

            m_pcAnchorFrameReconstructed à m_papcFrame[ uiFrameIdInGOP ]

    m_apcBaseFrame[1]à m_apcBaseFrame[0]

     

      ---------------------------initGOP----------END-----------------------------

     

    //一个GOP中最多允许的65AU,对每一个AU

      //对每一层

        m_apcLayerEncoder[uiLayer]->process( uiAUIndex,

                    m_cAccessUnitDataList.getAccessUnitData( uiAUIndex ),          //没找到对应号就新建

                    m_acOrgPicBufferList  [uiLayer], m_acRecPicBufferList  [uiLayer],

                    apcPicBufferUnusedList[uiLayer], m_pcParameterSetMng ) );     后面分析  GOP中一个AU的一层   

        //如果是第一个GOP,还要设置ProfileLevelIdcConstraintXFlag

     

    //对每一层

        把重建队列m_acRecPicBufferList[ uiLayer ]里的帧给输出队列apcPicBufferOutputList[ uiLayer ] (go())

    m_acOrgPicBufferList[ uiLayer ]m_acRecPicBufferList[ uiLayer ]都给apcPicBufferUnusedList[ uiLayer ] (go())

    清空原始和重建队列

     

    //把编码得到的NalUnit写到传入参数rcExtBinDataAccessorList

    m_cAccessUnitDataList.emptyNALULists( rcExtBinDataAccessorList );


    最新回复(0)