zoukankan      html  css  js  c++  java
  • HM中字典编码分析

    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_pStrMapBufListm_uCurrPackSizelist大小。

    {

    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); //1bit占一位,指示有匹配,第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编码时,复制的是原CUm_pCuBuf,rollback时复制的是重构CUm_pCuBuf

    m_pDictEncoder->DictCodeOneBlock();

    }

    void CDictEncoder::DictCodeOneBlock()

    {

    len = GetOptimumFast(&pos);

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

    {

    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)//重构CUrollback,只执行了编码过程,不写入结果

    {

    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

  • 相关阅读:
    UVa -- 401 Palindromes
    ffplay播放PCM裸流
    VLC2.2.4命令参数
    kurento搭建以及运行kurento-hello-world
    webrtp官方demo运行
    webrtc相关概念
    linux下面用Mingw编译libx264
    learning webrtc 使用node.js
    ffmpeg转码指南
    rtmpdump禁用openssl
  • 原文地址:https://www.cnblogs.com/mlj318/p/3275200.html
Copyright © 2011-2022 走看看