HEVC帧间预测实现(HM实现)

帧间预测简要流程

        Inter 进行解码的基本单位是pu, 读一个pu 相关的信息,然后解码相应的pu块。 pu块的信息包括mv的信息等,解码pu块就是利用mv 从相应的参考帧中去出参考的块,然后利用参考块插值或者不插值出预测块。

 1、参考帧数据的来源

        主要是m_apcRefPicList这个参考数据是怎么得来的,有调用getRefPic( RefPicListe, IntiRefIdx) 实际是返回的m_apcRefPicList。

  TComPic*                    getRefPic( RefPicListe, IntiRefIdx)                  {  return m_apcRefPicList[e][iRefIdx];                           }

可以看到  这个列表包含下面两个reference list, 对于P帧来说只用list 0, b帧两个都有可能用到。

  REF_PIC_LIST_0               = 0,   ///< reference list 0

  REF_PIC_LIST_1               = 1,   ///< reference list 1

 

        在TDecTop.cpp 中xDecodeSlice 中调用decodeSliceHeader 之后会将dpb 的buffer list 设置到 调用  pcSlice->setRefPicList( m_cListPic, true ) 设置到m_apcRefPicList 中。 decodeSliceHeader里面主要是解析rps相关的信息,rps 是存储在slice header 中。rps 的相关信息在附录中。

m_cListPic:dpb的buffer 列表 在 xDecodeSlice调用xActivateParameterSets,在xActivateParameterSets调用 xGetNewPicBuffer 去取一块buffer (实际是创建TComPic 相关的类),这个类中存储解码相关的数据,然后将申请到的TComPic 放到m_cListPic 的队列里面。

setRefPicList:取出rcListPic 经过一系列的转换 然后放到 m_apcRefPicList[REF_PIC_LIST_0],  m_apcRefPicList[REF_PIC_LIST_1] 中。

从上面可以看出,m_cListPic (dpb buffer) 到m_apcRefPicList(参考帧列表) buffer 的在dpb index 和在referce index 已经变化了,但是我们可以通过poc 来进行一样对应。

 

2、在预测中的使用

        现在理清楚了帧间那边参考数据的来源, 现在回过头来看一下inter 那边使用的数据。

首先是decodePUWise , 分析merge 的情况,如果解析到merge,那么会时间空间构造5个mv的候选类别。时间上面就是左,上,左右等几个方位,空间就是去colrefpic的mv,空间距离上面最多又4个候选的mv,时间上面最多有1个候选的mv, 在HM中的代码 为了B帧考虑, 因为B帧需要5个候选的mv 组合成10个一对mv来进行候选。所以候选mv存放的方式是下面这样,有b帧的时候奇数的位置有数据,没有b帧奇数位置没有数据。

 

3、MERGE模式

首先解析到Merge的index,然后解码端构造候选的mergelist。 构造pcMvFieldNeighbours的过程,cMvFieldNeighbours是一个10大小的数组,最大的候选mv list 是5,但是考虑的B帧由前向和后向的mv,所以设置成10。如果是P帧的情况,那么像下面,偶数位置的mv为0。

如果是B帧的情况, 奇数 偶数位置都有值。

首先根据下面图的方位5个候选块中4个候选块的运动信息,列表按照A1→B1→B0→A0→(B2)的顺序建立,其中B2为替补,即当A1, B1, B0,A0中有一个或多个不存在时,则需要使用B2的运动信息。

时域候选mv的构建 这里就是取的colrefpic的地方,取出colmv 然后放到候选列表里面。如果这个时候候选的还没有到达5,会取前面已经构建好重新构建几个mv。

b帧在前面每个候选项都构建后l0和l1的mv,在这边组合的时候是按照下面的顺序进行取的,比如combIdx 为0 的 是取候选列表里面第一个的L0 和第二个的L1,就是对应pcMvFieldNeighbours中的0 和 3 位置的数据。

 

 

 

在实际JM代码中

如果是pu的第一块,是没有传入uiMergeIndex,直接在decodePUWise 中进行取,

          pcSubCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,  uhInterDirNeighbours, numValidMergeCand, numSpatialMergeCandidates );

否则 会传入uiMergeIndex, 在getInterMergeCandidates 如果说很快就构建好需要的候选mv 会提前退出来。

        pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx,  cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand,  numSpatialMergeCandidates, uiMergeIndex );

 

Ps:

HEVC中每一个slice header都要包含当前帧的RPS数据(IDR条带除外,其RPS隐含为空);除此之外,即使是I帧的slice可能也包含RPS数据,因为按照解码顺序在它后面的帧可能会参考它之前的数据;RPS中图像的数量不能超过DPB的大小。

RPS使用POC标识参考帧,除了所在当前帧的POC之外,每一个slice header都直接包含(或者继承自SPS)RPS中每一帧图像的POC。

每个图像的RPS包含5个不同的参考图像表:

    RefPicSetStCurrBefore:解码和输出顺序均在当前帧之前的短线参考帧,可用于当前帧的帧间预测;

   RefPicSetStCurrAfter:解码顺序在当前帧之前,输出顺序在当前帧之后的短线参考帧,可用于当前帧的帧间预测;

   RefPicSetStFoll:按解码顺序在当前帧之后的图像可用的短线参考帧,不能用于当前帧的帧间预测;

   RefPicSetLtCurr:可用于当前帧的帧间预测的长线参考帧;

   RefPicSetLtFoll:按解码顺序在当前帧之后的图像可用的长线参考帧,不能用于当前帧的帧间预测;

RPS根据参考图像类型的不同,分别使用三个循环迭代来传递数据:POC比当前帧更低的短线参考帧、POC比当前帧更高的短线参考帧、长线参考帧;除此之外,还将为每一帧传递一个标识used−by−curr−pic−X−flag来说明是否用作了当前帧的参考帧;

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的MATLAB代码示例,用于实现HEVC预测: ```matlab function [predBlock] = intra_predict(image, blockSize, row, col, mode) % image: 输入图像 % blockSize: 块大小 % row, col: 当前块的起始行和列 % mode: 预测模式 % 获取参考像素 switch(mode) case 0 % 模式0:DC预测 refBlock = image(row:blockSize + row - 1, col:blockSize + col - 1); p = mean2(refBlock); predBlock = ones(blockSize, blockSize) * p; case 1 % 模式1:水平预测 refBlock = image(row:blockSize + row - 1, col - 1); predBlock = repmat(refBlock, [1, blockSize]); case 2 % 模式2:垂直预测 refBlock = image(row - 1, col:blockSize + col - 1); predBlock = repmat(refBlock, [blockSize, 1]); case 3 % 模式3:左上角预测 refBlock = image(row - 1, col - 1); predBlock = ones(blockSize, blockSize) * refBlock; case 4 % 模式4:右上角预测 refBlock = image(row - 1, col + blockSize); predBlock = ones(blockSize, blockSize) * refBlock; case 5 % 模式5:左下角预测 refBlock = image(row + blockSize, col - 1); predBlock = ones(blockSize, blockSize) * refBlock; case 6 % 模式6:垂直右下预测 refBlock1 = image(row - 1, col + blockSize); refBlock2 = image(row - 2, col + blockSize); refBlock3 = image(row - 3, col + blockSize); refBlock4 = image(row - 4, col + blockSize); refBlock5 = image(row - 5, col + blockSize); refBlock6 = image(row - 6, col + blockSize); refBlock7 = image(row - 7, col + blockSize); refBlock = (refBlock1 + 2 * refBlock2 + 3 * refBlock3 + 4 * refBlock4 + 5 * refBlock5 + 6 * refBlock6 + 7 * refBlock7 + 8) / 16; predBlock = ones(blockSize, blockSize) * refBlock; case 7 % 模式7:水平右下预测 refBlock1 = image(row + blockSize, col - 1); refBlock2 = image(row + blockSize, col - 2); refBlock3 = image(row + blockSize, col - 3); refBlock4 = image(row + blockSize, col - 4); refBlock5 = image(row + blockSize, col - 5); refBlock6 = image(row + blockSize, col - 6); refBlock7 = image(row + blockSize, col - 7); refBlock = (refBlock1 + 2 * refBlock2 + 3 * refBlock3 + 4 * refBlock4 + 5 * refBlock5 + 6 * refBlock6 + 7 * refBlock7 + 8) / 16; predBlock = ones(blockSize, blockSize) * refBlock; end end ``` 请注意,此代码仅实现HEVC预测的一些基本模式,可能需要根据您的特定需求进行更改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值