好久没看HEVC了,今天回归,来学习一下解码端的decompressSlice
函数,有两个,一个是TDecGop
类的成员函数,另一个是TDecSlice
类的。
TDecGop::decompressSlice
该函数比较简单,是解码一帧图像的上层入口函数,在TDecGop::xDecodeSlice
中被调用。主要功能是完成熵解码器初始化和计时工作,并会调用TDecSlice::decompressSlice
解码一帧图像。
//解码slice
Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic* pcPic)
{
//当前slice
TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
// Table of extracted substreams.
// These must be deallocated AND their internal fifos, too.
TComInputBitstream **ppcSubstreams = NULL;
//-- For time output for each slice
//计时器,统计每一个slice解码时间
clock_t iBeforeTime = clock();
//熵解码器初始化
m_pcSbacDecoder->init( (TDecBinIf*)m_pcBinCABAC );
m_pcEntropyDecoder->setEntropyDecoder (m_pcSbacDecoder);
const UInt uiNumSubstreams = pcSlice->getNumberOfSubstreamSizes()+1;
// init each couple {EntropyDecoder, Substream}
ppcSubstreams = new TComInputBitstream*[uiNumSubstreams];
for ( UInt ui = 0 ; ui < uiNumSubstreams ; ui++ )
{
ppcSubstreams[ui] = pcBitstream->extractSubstream(ui+1 < uiNumSubstreams ? (pcSlice->getSubstreamSize(ui)<<3) : pcBitstream->getNumBitsLeft());
}
//调用TDecSlice::decompressSlice解码slice
m_pcSliceDecoder->decompressSlice( ppcSubstreams, pcPic, m_pcSbacDecoder);
// deallocate all created substreams, including internal buffers.
//清楚buffer
for (UInt ui = 0; ui < uiNumSubstreams; ui++)
{
delete ppcSubstreams[ui];
}
delete[] ppcSubstreams;
//解码时间
m_dDecTime += (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
}
TDecSlice::decompressSlice
该函数在TDecGop::decompressSlice
中被调用,用于完成一帧图像的解码。其中涉及了大量熵编码的内容,个人不是很熟悉,可能存在错误,请指正。
主要流程如下:
1.初始化:CTU、熵解码器等。
2.如果是dependent slice,利用之前的slice优化上下文模型。
3.遍历所有CTU进行解码:
3.1 初始化CTU。
3.2 设置熵解码器,加载上下文模型。
3.3 SAO。
3.4 调用decodeCtu
(详见HEVC