HM中字典编码分析

时间:2022-02-02 00:28:20

LZ77算法基本过程 http://jpkc.zust.edu.cn/2007/dmt/course/MMT03_05_2.htm

LZ77压缩算法详解 http://wenku.baidu.com/view/c4ee642bcfc789eb172dc8f5.html

输入待字典编码的CU,

CopyCuFromPicYuv444(pcPic,m_pCuBuf, cuIdx,bEncOrg);

待编码的输入64*64,重排序后的YUV (*(m_matchFinderBase.stream)).data

void CDictEncoder::WriteStrMapResult(int len, int pos,const UChar * pCurBuf)

//写入编码的结果,32位数的iDst编码结果push_banck到m_pStrMapBufList,m_uCurrPackSize为list大小。

{

if (len == 1 && pos == (UInt)-1)//没有匹配的

{

if (numCoded>=3)

{

litFlag = (pCurBuf[0]-pCurBuf[-3])<0;

c = (UInt)ABS_DIFF(pCurBuf[0],pCurBuf[-3]);

}

else

c = (UInt)pCurBuf[0];

WriteBits(iDst,0,1,1);

WriteBits(iDst,litFlag,1,2);//因为排列顺序是YUVYUV,所以编的是与pCurBuf[-3]的差值,litFlag表示差值的正负

WriteBits(iDst,c,8,3);

}

else

{

WriteBits(iDst,1,1,1); //第1个bit占一位,指示有匹配,第2bit开始的9位表示匹配长度len,第11bit开始的22位表示偏移pos

WriteBits(iDst,len,9,2);

WriteBits(iDst,pos,22,11);

}

}

void CDictEncoder::DictCodeOneBlock()

{

for (;;)

{

len = GetOptimumFast(&pos);//返回最佳的匹配,len长度,pos偏移

pCurBuf = MatchFinder_GetPointerToCurrentPos(&m_matchFinderBase) - m_uAdditionalOffset;

//(m_matchFinderBase).buffer匹配的结束位置,即m_uAdditionalOffset=len,向前len为匹配的开始位置pCurBuf,len>8 时匹配串在pCurBuf-(pos-8)-1, pos<8时,在pCurBuf- m_uReps[pos]-1

WriteStrMapResult(len,pos,pCurBuf);

m_uAdditionalOffset -= len;

nowPos32 += len;

if ((m_uAdditionalOffset == 0) && (MatchFinder_GetNumAvailableBytes(&m_matchFinderBase) == 0))// AvailableBytes还待编的字符数,编完了则跳出

{

break;

}

}//for

}

字典的输入是pixels data in previously constructed CUs 和current LCU data

如果previously constructed CUs 是dictionary编码的,无需rollback

如果是HM编码的,则previous CUs需 rollback.

rollback的原因:用HM的constructed CU要作为下一个CU的字典输入,还需调用DictCompressCu(uiCUAddr,cuCnt-1,false,pcSlice); 再字典编码一次,不过与真正的字典编码不同,只执行编码的过程(哈希和匹配),而不写入结果。这样constructed CU 就生成了哈希表,可以作为了下一个CU的字典,方便查找。

if(dCostHM / dCostDictCoder > 1.0)

{

int i;

m_pTComDictEncoder->WriteCu2RecYuv444(pcCU,uiCUAddr);//选择字典编码,内部其实是把原CU写入到重构pic,因为重构和原CU一样

bLastCuRollBack = false;

pcCU->m_bCUCodedByDictCoderFlag = true;

for (i=0;i<pcCU->getTotalNumPart();i++)

{

pcCU->setPredictionMode(i,MODE_INTRA);

}

}

else

{

m_pTComDictEncoder->SetNeedRollBackVar(true);

bLastCuRollBack = true;

m_pTComDictEncoder->DictCompressCu(uiCUAddr,cuCnt-1,false,pcSlice);

m_pTComDictEncoder->SetNeedRollBackVar(false);

}

void TComDictEnc::DictCompressCu(UInt cuIdx, UInt cuEndIdx, bool bEncOrg, TComSlice* pcSlice)

{

if (m_bNeedRollBack)

{

for(i = 0 ;i < m_pDictEncoder->m_uCurrPackSize;i++)//选择的是HM编码,所以把第一次CU原图字典编码写入的结果都弹出

{

m_pDictEncoder->m_pStrMapBufList.pop_back();

}

m_pDictEncoder->m_uCurrPackSize = 0;

}

...

CopyCuFromPicYuv444(pcPic,m_pCuBuf, cuIdx,bEncOrg);// 原CU编码时,复制的是原CU到m_pCuBuf,rollback时复制的是重构CU到m_pCuBuf

m_pDictEncoder->DictCodeOneBlock();

}

void CDictEncoder::DictCodeOneBlock()

{

len = GetOptimumFast(&pos);

if (!m_matchFinderBase.m_bEncOrg)//重构CU,rollback,只执行了编码过程,不写入结果

{

m_uAdditionalOffset -= len;

if ((m_uAdditionalOffset == 0) && (MatchFinder_GetNumAvailableBytes(&m_matchFinderBase) == 0))

{

m_bIsLastCuRollBack = 1;

break;

}

continue;

}

if (m_matchFinderBase.m_bEncOrg)//原CU,要写入结果

{

WriteStrMapResult(len,pos,pCurBuf);

}

}

void CDictEncoder::DictCodeOneBlock()

{

for (;;)

{

len = GetOptimumFast(&pos);//返回最佳的匹配,len长度,pos偏移

if (!m_matchFinderBase.m_bEncOrg)//重构CU,rollback,只执行了编码过程,不写入结果

{

m_uAdditionalOffset -= len;

if ((m_uAdditionalOffset == 0) && (MatchFinder_GetNumAvailableBytes(&m_matchFinderBase) == 0))

{

m_bIsLastCuRollBack = 1;

break;

}

continue;

}//if

if (m_matchFinderBase.m_bEncOrg)//原CU,要写入结果

{

pCurBuf = MatchFinder_GetPointerToCurrentPos(&m_matchFinderBase) - m_uAdditionalOffset;

//(m_matchFinderBase).buffer匹配的结束位置,即m_uAdditionalOffset=len,向前len为匹配的开始位置pCurBuf,len>8 时匹配串在pCurBuf-(pos-8)-1, pos<8时,在pCurBuf- m_uReps[pos]-1

WriteStrMapResult(len,pos,pCurBuf);

m_uAdditionalOffset -= len;

nowPos32 += len;

if ((m_uAdditionalOffset == 0) && (MatchFinder_GetNumAvailableBytes(&m_matchFinderBase) == 0))// AvailableBytes还待编的字符数,编完了则跳出

{

break;

}

}//if

}//for

}

参考:

JCTVC-K0133

JCTVC-I0272-r2444 Screen Content Coding using Dual-coder Mixed Chroma-sampling-rate (DMC) Techniques

HM80ECF444DualCoderSourceCode.zip