H.266/VVC SCC技术学习:帧内块拷贝(Intra block copy, IBC)

这篇具有很好参考价值的文章主要介绍了H.266/VVC SCC技术学习:帧内块拷贝(Intra block copy, IBC)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

帧内块拷贝 (Intra block copy, IBC) 是 HEVC 针对屏幕内容编码(Screen content coding)序列的扩展工具,它显着提高了屏幕内容序列的编码效率。

IBC 是一种块级编码模式, IBC 编码的 CU 被视为除帧内或帧间预测模式之外的第三预测模式。和帧间技术类似,编码端执行运动搜索(块匹配,Block Maching, BM )为每个 CU 找到其最佳的块向量(Block Vector,也可以称为运动向量 Motion Vector),块向量用于指示从当前块到参考块的位移。和帧间技术不同的地方在于,IBC 的最佳块向量是在当前 CU所处帧重建区域搜索得到的,而帧间的运动向量是通过相邻参考帧内搜索得到的。

IBC 编码的 CU 的亮度块向量是整数精度。 色度块向量也四舍五入到整数精度。 当 IBC 与 AMVR 结合使用时,IBC 模式可以在 1 像素和 4 像素块向量精度之间切换。

IBC应用条件:IBC 模式适用于宽度和高度均小于或等于 64 的 CU。当 CU 为DUAL_TREE partition时,禁止色度块应用IBC。

和帧间技术类似,IBC也包括 IBC Merge模式和 IBC AMVP模式,编码端通过一个flag来标识 IBC AMVP 模式或 IBC Skip/Merge模式,如下所示:

  • IBC Skip/Merge 模式:Merge 候选索引用于指示来自 IBC 编码块的相邻候选列表中的哪些块向量用于预测当前块。 Merge列表由空间、HMVP 和成对候选者组成。
  • IBC AMVP 模式:块向量差以与运动向量差相同的方式编码。 块向量预测方法使用两个候选作为预测变量,一个来自左邻居,一个来自上邻居(如果 IBC 编码)。 当任一邻居不可用时,将使用默认块向量作为预测向量。 需要发送信号以指示块预测矢量的索引。

对于IBC AMVP模式,需要通过运动估计来搜索最佳块运动向量。IBC的运动估计方法包括基于哈希的运动估计(hash-based search)和基于块匹配的运动搜索(block matching based local search)。对于AMVP模式,首先使用基于哈希的搜索来执行块向量搜索。 如果哈希搜索没有返回有效的候选者,则执行基于块匹配的本地搜索。

在基于哈希(hash-based)的搜索中,当前块和参考块之间的散列键匹配(32 位 CRC)被扩展到所有允许的块大小。 当前图片中每个位置的哈希键计算基于 4x4 子块。 对于更大尺寸的当前块,当所有4×4子块的哈希键与对应参考位置的哈希键匹配时,确定哈希键与参考块的哈希键匹配。 如果发现多个参考块的哈希键与当前块的哈希键匹配,则计算每个匹配参考的块向量成本,并选择成本最小的一个。

一、IBC 参考区域

为了减少内存消耗和解码器复杂度,VVC 中的 IBC 只允许预定义区域(同一CTU Line)的重建部分,包括当前 CTU 的区域和左侧 CTU 的某些区域。 下图说明了 IBC 模式的参考区域,其中每个块代表 64x64 亮度样本。粗实线代表一个CTU,一个CTU包括 4 个64x64的亮度块。

H.266/VVC SCC技术学习:帧内块拷贝(Intra block copy, IBC)

根据当前CU在CTU中的位置可分为下面4种情况:

  • 如果当前块落入当前CTU左上角的64x64块中,如左上图,那么除了当前CTU中已重建的样本外,还可以参考CPR模式下左侧CTU的右下角64x64的块、左下角64x64的块、右上角64x64的块。
  • 如果当前CU是CTU右上角的64x64的块,如右上图,除了当前CTU已重建的样本,如果相对于当前CTU的(0,64)位置还未重建,当前块也能参考CPR模式下左侧CTU的右下角64x64的块、左下角64x64的块;否则当前块能参考左侧CTU的右下角64x64的块
  • 如果当前CU是CTU左下角的64x64的块,如左下图,除了当前CTU已重建部分,如果相对于当前CTU的(64, 0) 位置还未重建,当前块也能参考CPR模式下当前CTU的右上角64x64的块、左侧CTU的右下角64x64的块;否则当前块能参考CPR模式下左侧CTU的右下角64x64的块。
  • 如果当前CU是CTU右下角的64x64的块,它只能参考CPR模式下当前CTU已重建部分。

判断其在参考块是否有效:searchBv 函数

bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize)
{
  const int ctuSizeLog2 = floorLog2(ctuSize);

  int refRightX = xPos + xBv + width - 1; // 参考块的右上角的坐标
  int refBottomY = yPos + yBv + height - 1; // 参考块的左下角的坐标

  // 参考块左上角的坐标 (x, y)
  int refLeftX = xPos + xBv;
  int refTopY = yPos + yBv;

  if ((xPos + xBv) < 0)
  {
    return false;
  }
  if (refRightX >= picWidth) // 判断右侧是否超出图像边界
  {
    return false;
  }

  if ((yPos + yBv) < 0)
  {
    return false;
  }
  if (refBottomY >= picHeight) // 判断下侧是否超出图像边界
  {
    return false;
  }

  if ((xBv + width) > 0 && (yBv + height) > 0)
  {
    return false;
  }

  // Don't search the above CTU row 不要搜索上面的 CTU 行
  if (refTopY >> ctuSizeLog2 < yPos >> ctuSizeLog2)
    return false;

  // Don't search the below CTU row 不要搜索下面的 CTU 行
  if (refBottomY >> ctuSizeLog2 > yPos >> ctuSizeLog2)
  {
    return false;
  }
  // 判断参考块和当前块是否在同一个Tile中
  unsigned curTileIdx = pu.cs->pps->getTileIdx(pu.lumaPos());
  unsigned refTileIdx = pu.cs->pps->getTileIdx(Position(refLeftX, refTopY));
  if (curTileIdx != refTileIdx)
  {
    return false;
  }
  refTileIdx = pu.cs->pps->getTileIdx(Position(refLeftX, refBottomY));
  if (curTileIdx != refTileIdx)
  {
    return false;
  }
  refTileIdx = pu.cs->pps->getTileIdx(Position(refRightX, refTopY));
  if (curTileIdx != refTileIdx)
  {
    return false;
  }
  refTileIdx = pu.cs->pps->getTileIdx(Position(refRightX, refBottomY));
  if (curTileIdx != refTileIdx)
  {
    return false;
  }

  // in the same CTU line 同一CTU行
  int numLeftCTUs = (1 << ((7 - ctuSizeLog2) << 1)) - ((ctuSizeLog2 < 7) ? 1 : 0);
  // refRightX >> ctuSizeLog2 <= xPos >> ctuSizeLog2 应该是判断参考区域所在CTU在当前CTU或者左侧相邻CTU
  // (refLeftX >> ctuSizeLog2 >= (xPos >> ctuSizeLog2) - numLeftCTUs)) 应该是判断参考区域所在CTU不能超出左侧相邻CTU
  if ((refRightX >> ctuSizeLog2 <= xPos >> ctuSizeLog2) && (refLeftX >> ctuSizeLog2 >= (xPos >> ctuSizeLog2) - numLeftCTUs))
  {
    // in the same CTU, or left CTU 参考块在同一个CTU或者左侧相邻CTU
    // if part of ref block is in the left CTU, some area can be referred from the not-yet updated local CTU buffer
     // 如果参考块的一部分在左侧 CTU 中,则可以从尚未更新的本地 CTU 缓冲区中引用某些区域
    if (((refLeftX >> ctuSizeLog2) == ((xPos >> ctuSizeLog2) - 1)) && (ctuSizeLog2 == 7))
    {
      // ref block's collocated block in current CTU 当前 CTU 中参考块的并置块
      const Position refPosCol = pu.Y().topLeft().offset(xBv + ctuSize, yBv);
      int offset64x = (refPosCol.x >> (ctuSizeLog2 - 1)) << (ctuSizeLog2 - 1);
      int offset64y = (refPosCol.y >> (ctuSizeLog2 - 1)) << (ctuSizeLog2 - 1);
      const Position refPosCol64x64 = {offset64x, offset64y};
      if (pu.cs->isDecomp(refPosCol64x64, toChannelType(COMPONENT_Y)))
        return false;
      if (refPosCol64x64 == pu.Y().topLeft())
        return false;
    }
  }
  else
    return false;

  // in the same CTU, or valid area from left CTU. Check if the reference block is already coded
  // 在同一个 CTU 或左侧 CTU 的有效区域中。 检查参考块是否已经重建
  const Position refPosLT = pu.Y().topLeft().offset(xBv, yBv); // 参考区域的左上角
  const Position refPosBR = pu.Y().bottomRight().offset(xBv, yBv); // 参考区域的右上角
  const ChannelType      chType = toChannelType(COMPONENT_Y);
  if (!pu.cs->isDecomp(refPosBR, chType))
    return false;
  if (!pu.cs->isDecomp(refPosLT, chType))
    return false;
  return true;
}

二、IBC 与其他编码工具的交互

IBC 模式与 VVC 中其他帧间编码工具之间的交互,例如成对 Merge 候选、基于历史的运动矢量预测 (HMVP)、帧内/帧间联合预测 (CIIP)、具有运动矢量差的 Merge 模式 (MMVD) 和几何划分模式(GPM)如下:

  • IBC 可以与成对 Merge 候选以及 HMVP 一起使用。 可以通过平均两个 IBC Merge候选来生成新的成对 IBC 合并候选。 对于 HMVP,IBC 运动信息被插入历史缓冲区以供将来参考。
  • IBC 不能与以下工具结合使用:Affine、CIIP、MMVD 和 GPM。

与HEVC屏幕内容编码扩展不同,当前图片不再作为参考图片之一包含在IBC预测的参考图片列表0中。

与 HEVC 屏幕内容编码扩展不同,当前图片不再作为参考图片之一包含在用于 IBC 预测的参考图片列表 0 中。 IBC 模式的运动矢量推导过程排除了帧间模式中的所有相邻块,反之亦然。VVC的IBC包括了以下改进:文章来源地址https://www.toymoban.com/news/detail-421773.html

  • IBC 与常规 MV Merge 共享相同的过程,包括成对 Merge 候选和基于历史的运动预测,但不允许 TMVP 和零向量,因为它们对 IBC 模式无效。
  • 单独的 HMVP 缓冲区(每个 5 个候选)分别用于传统的 MV 和 IBC。
  • 块向量约束以比特流一致性约束的形式实现,编码器需要确保比特流中不存在无效向量,如果Merge 候选无效(超出范围或为0),则不应使用 Merge 。这种比特流一致性约束用虚拟缓冲器来表达。
  • 对于Deblock,IBC 作为帧间模式处理。
  • 如果当前块使用IBC预测模式编码,AMVR不使用四分之一像素;相反,AMVR 仅指示 MV 是整数像素还是 4 整数像素。
  • IBC Merge 候选者的数量可以在 Slice header 中与常规、子块和几何 Merge 候选者的数量分开表示。

到了这里,关于H.266/VVC SCC技术学习:帧内块拷贝(Intra block copy, IBC)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Kafka的零拷贝技术Zero-Copy

    流程步骤: (1)操作系统将数据从磁盘文件中读取到内核空间的页面缓存; (2)应用程序将数据从内核空间读入用户空间缓冲区; (3)应用程序将读到数据写回内核空间并放入socket缓冲区; (4)操作系统将数据从socket缓冲区复制到网卡接口,此时数据才能通过网络发送

    2024年02月08日
    浏览(31)
  • U4_1:图论之DFS/BFS/TS/Scc

    由点(vertices)和边(edges)组成 G = ( V , E ) G=(V,E) G = ( V , E ) , ∣ V ∣ = n |V|=n ∣ V ∣ = n , ∣ E ∣ = m |E|=m ∣ E ∣ = m (这里默认有向图,无向图用 G G G = = = { V V V , E E E }表示 顶点的度是关联在其上的边的数量。满足 ∑ d e g r e e ( v ) = 2 ∣ E ∣ sum degree(v)=2|E| ∑ d e g ree ( v ) = 2∣

    2024年02月05日
    浏览(25)
  • 零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(上)

    当涉及到网络传输中的零拷贝技术时,它在提高性能和效率方面扮演着重要的角色。在之前我们已经讨论了磁盘设备管理中的零拷贝技术,其中涉及到了DMA技术。现在,让我们来深入探讨一下网络传输中零拷贝技术的实现方式以及它的重要性。 在没有DMA(直接内存访问)技术

    2024年02月08日
    浏览(33)
  • 零拷贝技术:减少数据复制和上下文切换,提高网络传输效率(下)

    在前一章节中,我们了解了DMA技术在文件传输中的重要性,并简要介绍了零拷贝技术。为了提高文件传输的性能,我们需要减少用户态与内核态之间的上下文切换次数以及内存拷贝次数。本章将深入探讨零拷贝技术的优化方法,让我们一起走进零拷贝的优化之路! 当我们意识

    2024年02月08日
    浏览(43)
  • JVET-AC0315:用于色度帧内预测的跨分量Merge模式

    ECM采用了许多跨分量的预测(Cross-componentprediction,CCP)模式,包括跨分量包括跨分量线性模型(CCLM)、卷积跨分量模型(CCCM)和梯度线性模型(GLM),以利用分量间的相关性。该提案提出了一种跨分量的Merge模式(cross-componentmerge,CCMerge)作为一种新的CCP模式。CCMerge编码的

    2023年04月27日
    浏览(17)
  • 关于Open Shift(OKD) 中 用户认证、权限管理、SCC 管理的一些笔记

    因为参加考试,会陆续分享一些 OpenShift 的笔记 博文内容为 openshift 用户认证和权限管理以及 scc 管理相关笔记 学习环境为 openshift v3 的版本,有些旧 这里如果专门学习 openshift ,建议学习 v4 版本 理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后

    2023年04月25日
    浏览(29)
  • Objective-C学习笔记(block,协议)4.10

    1.block :是一个数据类型,存储一段代码,代码可以有参数有返回值。 2.声明block : 返回值类型 (^block变量名称)(参数列表);                         int (^myblock) (int num1,int num2);                         代码段格式:^返回值类型(参数列表){                            

    2024年04月17日
    浏览(34)
  • ctfshow web入门 反序列化 前篇 254-266

    这里266后面主要是框架,以后在讲 反序列化入门可以参考我写的另一篇很详细的哦~php 反序列化总结 这里分析一下,我们通过get可以传参两个值,这里他会自动new一个类,我们传的参就会被送入login中做强比较,只要我们传入的值等于$username和$password的值,我们就可以获得

    2024年02月01日
    浏览(30)
  • 【C++学习】类和对象 | 拷贝构造 | 探索拷贝构造函数为什么需要引用传参 | 深拷贝 | 初识运算符重载

    上一篇文章我们开始学习类内的默认成员函数, 这里是传送门,有兴趣可以去看看:http://t.csdn.cn/iXdpH 这篇文章我们继续来学习类和对象的知识。 目录 写在前面: 1. 拷贝构造 2. 拷贝构造函数为什么需要引用传参? 3. 深拷贝 4. 初识运算符重载 写在最后: 我们在创建一个对

    2024年02月11日
    浏览(40)
  • 多传感器分布式融合算法——加权最小二乘WLS融合/简单凸组合SCC融合

    原创不易,路过的各位大佬请点个赞 主要讲解算法:          加权最小二乘融合WLS          简单凸组合融合SCC 应用于: 多传感器网络协同目标跟踪/定位/导航 联系WX: ZB823618313          根据系统需求(成本、安全性、可维护性等)以及外界环境(自然环境、人为对抗环境),信

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包