其实按道理来讲,h265/HEVC和JVET的区别并不大,具体框架都差不多,所以还是以h.265讲解为主啦;
根据我自己的理解,大家有什么问题可以留言一起 讨论JVET的问题;
TAppEncTop::encode函数中,通过调用了TEncTop::encode对视频帧进行编码,下面将对TEncTop::encode进行学习。
按照HM-16.6-JEM-4.0代码理解来看,TEncTop::encode主要作用是为GOP压缩之前做一些准备工作,包括创建当前图像缓冲区、设定QP是否自适应、根据码率控制模式来确定是否需要先初始化GOP,然后调用TEncGop::compressGOP来压缩GOP。
主要过程如下:
其中调用了重要函数TEncGop::compressGOP,用来进行GOP的压缩,这是进入深层编码的入口函数,将是接下来要学习的函数。
具体的函数代码详解如下
Void TEncTop::encode( Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded
#if VCEG_AZ07_BAC_ADAPT_WDOW || VCEG_AZ07_INIT_PREVFRAME
,TComStats* m_apcStats
#endif
)
{
if (pcPicYuvOrg != NULL)
{
// get original YUV
TComPic* pcPicCurr = NULL; // get original YUV 获取原始YUV
xGetNewPicBuffer( pcPicCurr ); //给当前图像分配新的缓冲区
pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() ); //将pcPicYuvOrg的信息赋给当前图像
pcPicYuvTrueOrg->copyToPic( pcPicCurr->getPicYuvTrueOrg() ); //将pcPicYuvTrueOrg的信息赋给当前图像
// compute image characteristics 计算图像的特征
if ( getUseAdaptiveQP() ) //如果使用自适应QP,则调用TEncPreanalyzer::xPreanalyze来分析图像并计算用于QP自适应的局部图像特征
{
m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
}
}
if ((m_iNumPicRcvd == 0) || (!flush && (m_iPOCLast != 0) && (m_iNumPicRcvd != m_iGOPSize) && (m_iGOPSize != 0)))
{
iNumEncoded = 0;
return;
}
if ( m_RCEnableRateControl ) //若使用m_RCEnableRateControl,则对GOP进行初始化
{
m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
}
// compress GOP 调用TEncGop::compressGOP压缩GOP
m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false, snrCSC, m_printFrameMSE
#if VCEG_AZ07_BAC_ADAPT_WDOW || VCEG_AZ07_INIT_PREVFRAME
, m_apcStats
#endif
);
if ( m_RCEnableRateControl ) //若使用了m_RCEnableRateControl,则需要消灭之前初始化的GOP
{
m_cRateCtrl.destroyRCGOP();
}
iNumEncoded = m_iNumPicRcvd;
m_iNumPicRcvd = 0;
m_uiNumAllPicCoded += iNumEncoded;
}