当前位置: 首页 > news >正文

H.266/VVC SCC技术学习:块差分脉冲编码调整(block differential pulse coded modulation, BDPCM)

近年来,屏幕内容视频广泛用于多媒体应用,例如远程桌面,屏幕共享等。由于屏幕内容视频的特性与自然视频有较大区别,VVC中使用了帧内块复制(intra block copy, 即IBC), 调色板(Palette), 变换跳过(transform skip, 即TS), 块差分脉冲编码调制(block differential pulse coded modulation ,即BDPCM)等技术来提高其编码效率。本文将阐述BDPCM技术的实现原理。

一、BDPCM技术简介

在VVC中,BDPCM在提案 JVET-M0057 中被提出。

在SPS层需要传输 BDPCM 启用标志,仅当SPS层传输了 Transform Skip 标志才会传输该标志。

在 CU 层,如果 CU 允许使用 Transform Skip 技术时(像素数 <= MaxTsSize×MaxTsSize)才允许使用 BDPCM 技术。如果 CU 使用帧内编码时,需要进一步传输 CU 级标志表明当前 CU 采用帧内编码还是 BDPCM 编码,如果采用 BDPCM 编码,则进一步需要传输一个 BDPCM 预测方向标志位标识当前 CU 采用水平预测方向还是垂直预测方向。

void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
{
  if( !cu.cs->sps->BDPCM) return;
  if( !CU::bdpcmAllowed( cu, compID ) ) return;

  int bdpcmMode = cu.bdpcmM[toChannelType(compID)];

  unsigned ctxId = isLuma(compID) ? 0 : 2; 
  // BDPCM 启用标志位
  m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId));
  if (bdpcmMode)
  {
    // BDPCM 预测方向标志位
    m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1));
  }
}

对于 BDPCM 编码的 CU,通过以下四步进行预测过程:

1)编码器使用未滤波的参考像素,通过BDPCM所选择的预测方向对编码单元做普通的帧内预测(水平或者垂直);

void IntraPrediction::xPredIntraBDPCM(PelBuf& pDst, const CPelBuf& pSrc, const uint32_t dirMode, const ClpRng& clpRng)
{
  const int wdt = pDst.width;
  const int hgt = pDst.height;

  const int strideP = pDst.stride;
  const int strideS = pSrc.stride;

  CHECK(!(dirMode == 1 || dirMode == 2), "Incorrect BDPCM mode parameter.");

  Pel* pred = &pDst.buf[0];
  if (dirMode == 1)
  {
    Pel  val;
    for (int y = 0; y < hgt; y++)
    {
      val = pSrc.buf[(y + 1) + strideS];
      for (int x = 0; x < wdt; x++)
      {
        pred[x] = val;
      }
      pred += strideP;
    }
  }
  else
  {
    for (int y = 0; y < hgt; y++)
    {
      for (int x = 0; x < wdt; x++)
      {
        pred[x] = pSrc.buf[x + 1];
      }
      pred += strideP;
    }
  }
}

2)普通帧内预测得到的残差被直接量化;

3)编码器沿着BDPCM所选择的方向对量化后的残差做进一步预测。BDPCM将每个位置的量化残差与该方向的上一个相邻量化残差计算得到差值。最后,编码器将这些差值编码并且传输到解码端。计算差值的具体过程如下所示:

对于一个大小为 M× N的块,设r_{(i,j)}(其中 0\leq i\leq M - 10\leq j\leq N - 1)为预测残差。设Q(r_{(i,j)}) 表示残差 r_{(i,j)}的量化后的结果。BDPCM 应用于量化后的残差值,得到一个修改后的 M\times N数组\tilde{R},其元素为\tilde{r}_{(i,j)},这里 \tilde{r}_{(i,j)}是从其相邻的量化残差值预测得到的。

对于垂直BDPCM技术,\tilde{r}_{(i,j)}通常通过以下计算得到

对于水平BDPCM技术,\tilde{r}_{(i,j)}通常通过以下计算得到

 

void fwdResDPCM( TransformUnit& tu, const ComponentID compID )
{
  const CompArea& rect   = tu.blocks[compID];
  const int       wdt    = rect.width;
  const int       hgt    = rect.height;
  CoeffSigBuf     coeffs = tu.getCoeffs(compID);

  TCoeffSig* coef = &coeffs.buf[0];
  if (tu.cu->bdpcmM[toChannelType(compID)] == 1)
  {
    for( int y = 0; y < hgt; y++ )
    {
      for( int x = wdt - 1; x > 0; x-- )
      {
        coef[x] -= coef[x - 1];
      }
      coef += coeffs.stride;
    }
  }
  else
  {
    coef += coeffs.stride * (hgt - 1);
    for( int y = 0; y < hgt - 1; y++ )
    {
      for ( int x = 0; x < wdt; x++ )
      {
        coef[x] -= coef[x - coeffs.stride];
      }
      coef -= coeffs.stride;
    }
  }
}

对于解码端,量化后的残差Q(r_{(i,j)}) 可以通过此预测过程的逆过程得到

将反量化后的残差Q^{-1}(Q(r_{i,j}))与帧内块预测值相加,得到重建像素。

Deblock过程中,如果块边界两侧的两个块都使用 BDPCM 进行编码,那么该特定的块边界将不进行滤波处理。

二、编码增益

在VVC参考软件VTM-10.0中,关闭BDPCM对ClassF和ClassTGM的标准测试序列有如下影响:

Acronym

BDR-Y

BDR-U

BDR-V

Tester EncTime

Tester DecTime

XChecker EncTime

XChecker DecTime

AI

BDPCM ClassF

0.93%

0.92%

0.97%

98%

105%

101%

105%

BDPCM ClassTGM

1.45%

1.58%

1.58%

101%

103%

92%

94%

RA

BDPCM ClassF

0.70%

0.68%

0.93%

99%

100%

100%

103%

BDPCM ClassTGM

0.79%

1.03%

0.98%

100%

101%

92%

84%

LD

BDPCM ClassF

0.35%

-0.37%

0.35%

100%

103%

96%

98%

BDPCM ClassTGM

0.29%

0.42%

0.37%

99%

99%

95%

83%

http://www.dtcms.com/a/111224.html

相关文章:

  • 生信入门:专栏概要与内容目录
  • AI算法大全初见面
  • Redisson使用详解
  • 《Maven高级应用:继承聚合设计与私服Nexus实战指南》
  • 嵌入式学习笔记——SPI协议
  • “一路有你”公益行携手《东方星动》走进湖南岳阳岑川镇中心小学
  • AI Agent设计模式二:Parallelization
  • 【新能源汽车整车动力学模型深度解析:面向MATLAB/Simulink仿真测试工程师的硬核指南】
  • PyTorch:解锁AI新时代的钥匙
  • Python基于时间序列分析的降雨量预测系统的设计与实现【附源码、文档说明】
  • 一周学会Pandas2 Python数据处理与分析-Jupyter Notebook安装
  • C++类的特殊成员函数:构造、拷贝构造与析构函数详解
  • F#语言的折线图
  • Prolog语言的强化学习
  • MySQL 知识点详解(索引、存储引擎、事务、锁机制、优化)
  • 当机器学习遇见购物车分析:FP-Growth算法全解析
  • 对模板方法模式的理解
  • WPF设计学习记录滴滴滴6
  • 池化技术的深度解析与实践指南【大模型总结】
  • 【51单片机】2-6【I/O口】电动车简易防盗报警器实现
  • Python循环控制语句
  • 幻觉抵抗优化大模型:teapotllm
  • Linux 线程1-线程的概念、线程与进程区别、线程的创建、线程的调度机制、线程函数传参
  • SpringBoot+Spring+MyBatis相关知识点
  • MQL5教程 05 指标开发实战:双色线、双线变色MACD、跨时间周期均线
  • TSMaster在新能源汽车研发测试中的硬核应用指南
  • 【rockchip】使用RKMPP+RGA解码H264并转换数据格式输出
  • 一文理解什么是中值模糊
  • C++多线程函数介绍
  • 【Kafka基础】ZooKeeper在Kafka中的核心作用:分布式系统中枢神经系统