HEVC compressGOP 接口
HEVC编码调用compressGOP()来实现一个GOPSize 图像序列的编码。在reference code里,真正做compressGOP编码之前,需要存GOPSize帧YUV在m_cListPic中。
if (pPicYuvOrg)
{
// get original YUV
TComPic* pcPicCurr = NULL;
m_cTEncTop.xGetNewPicBuffer( pcPicCurr );
pPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
// compute image characteristics
if ( m_cTEncTop.getUseAdaptiveQP() )
{
m_cTEncTop.m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
}
}
这种调用方式会造成delay, 不适合在实时环境中应用。故需要调整compressGOP函数,实现一帧入一帧出。修改起来也比较简单,如下:
Void TEncGOP::compressGOP( Int nGOPId, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
{
TComPic* pcPic;
TComPicYuv* pcPicYuvRecOut;
TComSlice* pcSlice;
TComOutputBitstream *pcBitstreamRedirect;
pcBitstreamRedirect = new TComOutputBitstream;
AccessUnit::iterator itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
UInt uiOneBitstreamPerSliceLength = 0;
TEncSbac* pcSbacCoders = NULL;
TComOutputBitstream* pcSubstreamsOut = NULL;
if(nGOPId == 0)----->每个GOP的第一帧做xInitGOP 即可
xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut );
m_iNumPicCoded = 0;
SEIPictureTiming pictureTimingSEI;
#if L0044_DU_DPB_OUTPUT_DELAY_HRD
Int picSptDpbOutputDuDelay = 0;
#endif
UInt *accumBitsDU = NULL;
UInt *accumNalsDU = NULL;
SEIDecodingUnitInfo decodingUnitInfoSEI;
//for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
for ( Int iGOPid= nGOPId ; iGOPid <= nGOPId; iGOPid++ ) -----每次encode一帧YUV
。。。。
}
nGOPId 是指示一个GOP的第几帧, iNumPicRcvd 表示 当前GOP已接收到几帧数据。在Void TAppEncTop::encode()调用如下:
m_cTEncTop.m_cGOPEncoder.compressGOP(nGOPid, m_cTEncTop.m_iPOCLast, nGOPid+1,
m_cTEncTop.m_cListPic, m_cListPicYuvRec, outputAccessUnits);