H264/AVC-帧内预测

2023-11-16

I宏块使用帧内预测编码压缩数据,根据相邻宏块数据恢复当前宏块信息。值得注意的一点是,帧内预测所参考的相邻宏块数据是deblocking之前的像素值,因为上一宏块的deblocking依赖当前宏块像素值,但当前宏块数据还未重建。
在这里插入图片描述

1.帧内预测类型

帧内预测包含4种类型:

  • 亮度4x4块Intra_4x4预测方式
  • 亮度8x8块Intra_8x8预测方式
  • 亮度16x16宏块Intra_16x16预测方式
  • 色度8x8块预测方式。

帧内预测的输入为预测模式和相邻块像素值,输出为当前块的预测值。

2. 亮度Intra_4x4预测

该模式下,16x16宏块中的亮度块,可分为16个4x4块,每个4x4块都使用Intra_4x4预测方式。其中16个4x4块的扫描顺序如下图:
在这里插入图片描述
对于索引号luma4x4BlkIdx为0-15的4x4块,预测过程如下:
1) 根据相邻块Intra4x4PredMode推导当前块Intra4x4PredMode;
2) 根据Intra4x4PredMode和相邻块像素值,得到当前块预测像素值。

2.1 当前块Intra4x4PredMode的推导过程

本过程的输入是 4x4 亮度块的索引 luma4x4BlkIdx 和先前(按照解码顺序)已经得到的相邻宏块的预测方式 Intra4x4PredMode (如果可用) 和 Intra8x8PredMode(如果可用)。 本过程的输出是变量 每个4x4块的Intra4x4PredMode[ luma4x4BlkIdx ]。
下表定义了 Intra4x4PredMode[ luma4x4BlkIdx ]的值和相应的名称。
在这里插入图片描述
Intra4x4PredMode[ luma4x4BlkIdx ]的值为 0、1、2、3、4、5、6、7 和 8,这些值分别代表不同预测方向,如下图:
在这里插入图片描述
Intra4x4PredMode[ luma4x4BlkIdx ] 由以下方式得到:
1) 以下任一条件满足则使用DC预测(Intra_4x4_DC):

  • 宏块mbAddrA(当前宏块左相邻宏块)不可用;
  • 宏块mbAddrB(当前宏块上相邻宏块)不可用;
  • 宏块mbAddrA可用,并且以帧间预测方式进行编码、constrained_intra_ pred_flag为1;
  • 宏块mbAddrB可用,并且以帧间预测方式进行编码、constrained_intra_ pred_flag为1;

举个例子,I slice的第一个宏块必定使用DC预测,因为它的相邻块mbAddrA、mbAddrB都不可用。

2) 不满足上述条件,则通过相邻块预测模式预测当前块Intra4x4PredMode。
已知以下信息:mbAddrA的预测模式、mbAddrB的预测模式、码流中读取的语法元素prev_intra4x4_pred_mode_flag。

  • 从mbAddrA和mbAddrB的预测模式中选取较小的一个作为预先定义模式。
  • 判断码流中读取的标志位prev_intra4x4_pred_mode_flag,如果该标志位为1,则预先定义模式就是当前块的预测模式;
  • 如果标志位prev_intra4x4_pred_mode_flag为0,则根据码流中解析出的语法元素 rem_intra4x4_pred_mode判断。如果rem_intra4x4_pred_mode的值小于预定义模式的值则选用rem_intra4x4_pred_mode;如果大于等于预定义模式,则当前块的预测模式设为rem_intra4x4_pred_mode + 1。

伪代码如下:

predIntra4x4PredMode = Min( intraMxMPredModeA, intraMxMPredModeB )
if( prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ] )
    Intra4x4PredMode[ luma4x4BlkIdx ] = predIntra4x4PredMode
else
    if( rem_intra4x4_pred_mode[ luma4x4BlkIdx ] < predIntra4x4PredMode )
        Intra4x4PredMode[ luma4x4BlkIdx ] = rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
else
    Intra4x4PredMode[ luma4x4BlkIdx ] = rem_intra4x4_pred_mode[ luma4x4BlkIdx ] + 1

标准文档中这部分内容比较繁杂,其实可以总结为:

  • 如果不能获取相邻宏块的预测方式,则当前块的预测模式为DC预测;
  • 否则选择相邻块预测方式较小的一个作为当前的模式预测值;
  • 码流中指定了要不要使用这个预测值。如果用,那么这个预测值就是当前块的帧内预测模式;否则就从后续读取的预测模式中计算。

2.2 获取预测数据

Intra_4x4预测需要用到的13个相邻像素值如下图所示:
在这里插入图片描述
相邻像素如何获取可参考帧内预测相邻像素推导过程.
首先需要判断这13个像素值是否有效。当下列4个条件满足任意一个,那么该像素便被判定为无效,不能用于预测:

  • 宏块mbAddrN不可获得;
  • 宏块mbAddrN为帧间预测模式,且标识位constrained_intra_pred_flag为1;
  • 宏块mbAddrN为SI类型,,且标识位constrained_intra_pred_flag为1,且当前宏块不是SI类型;
  • 块索引luma4x4BlkIdx为3或11时,EFGH4个像素值不可用;(如下图所示,当解码到第3个块时,4还未解码,所以块4中的预测像素值不能使用,也就是EFGH这4个像素值)。
    在这里插入图片描述

2.3 Intra4x4预测

Intra4x4预测根据相邻的13个像素值得到当前4x4块预测像素值。预测方式共有9种;

2.3.1 Intra4x4_Vertical预测模式

在这里插入图片描述

2.3.2 Intra4x4_Horizontal预测模式

在这里插入图片描述

2.3.3 Intra4x4_DC预测模式

在这里插入图片描述
Dc数值为相邻像素值的均值:
1)A、B、C、D、I、J、K、L都存在时,dc为这8个像素值的均值;
2)A、B、C、D不可用时,dc为I、J、K、L这4个像素的均值;
3)I、J、K、L不可用时,dc为A、B、C、D这4个像素的均值;
4)当这8个像素都不可用时,dc为(1<<(bit_depth-1))。

2.3.4 Intra4x4_Diagonal_Down_left预测模式

当A、B、C、D、E、F、G、H 8个像素存在时才能使用这种预测模式;

  • 当(x,y)=(3,3),即计算一个4×4像素块最右下方的像素p时:
    pred4x4L[ x, y ] = ( p[ 6, −1 ] + 3 * p[ 7, −1 ] + 2 ) >> 2
  • 其他情况计算方式如下:
    pred4x4L[ x, y ] = ( p[ x + y, −1 ] + 2 * p[ x + y + 1, −1 ] + p[ x + y + 2, −1 ] + 2 ) >> 2;

以像素点a为例,做一条左下方向成45°直线,会穿过预测像素点B,预测计算过程依赖A、B、C三个像素值,pred_a = (A+2B+C+2)/4

在这里插入图片描述

2.3.5 Intra4x4_Diagonal_Down_right预测模式

在这里插入图片描述

2.3.6 Intra_4x4_Vertical_Right预测模式

后面的几种预测方向不是45°整数倍,要分成两种情况分别计算。
以Intra_4x4_Vertical_Right为例,像素a、j的预测值为(A+Q+1)/2;
像素f、o的预测值为(Q+2A+B+2)/4

在这里插入图片描述

2.3.7 Intra_4x4_Horizontal_Down预测模式

在这里插入图片描述

2.3.8 Intra_4x4_Vertical_Left预测模式

在这里插入图片描述

2.3.9 Intra_4x4_Horizontal_Up预测模式

在这里插入图片描述

2.亮度Intra_8x8预测

一个宏块种的16x16亮度分量可分为4个8x8亮度块,每个8x8块都是用Intra_8x8预测方式。其中4个8x8块的扫描顺序如下:
在这里插入图片描述
对于索引号luma8x8BlkIdx为0-3的8x8块,预测方式推导过程、预测像素计算过程与Intra4x4类似,在此不再赘述。获取8x8块预测像素值流程如下:
1) 根据相邻块Intra8x8PredMode推导当前块Intra8x8PredMode;
2) 确定预测过程使用的相邻块预测像素是否可用
3)根据Intra8x8PredMode和相邻块预测像素值,得到当前块预测像素值。

3.亮度Intra_16x16预测

相比于Intra_4x4和Intra_8x8,Intra_16x16的区别主要有以下几点:

  • 预测模式可以直接从mb_type得到,不需要通过相邻块预测;
  • 预测模式只有4种

Intra_16x16需要33个参考像素点,分别为当前宏块左侧16个像素点,上方16个像素点以及左上方一个像素点。这些参考像素点是否可用的判断方式于Intra_4x4类似。
4种预测模式如下:
在这里插入图片描述

3.1 Intra_16x16_Vertical预测模式

只有上方16个参考像素有效时才可以使用,计算方法为
predL[ x, y ] = p[ x, −1 ], x, y = 0…15

3.2 Intra_16x16_Horizontal预测模式

只有左侧16个参考像素有效时才可以使用,计算方法为
predL[ x, y ] = p[ −1, y ], x, y = 0…15

3.3 Intra_16x16_DC预测模式

16×16模式的DC预测模式同4×4模式的DC预测方法类似,判断左侧16个像素和上方16个像素的有效性,将其中有效部分的均值作为整个预测块的像素值。如果32个像素都无效,则预测块像素值为( 1 << ( bit_depth − 1 ) )。
一般码流中第一个I slice的第一个宏块会使用Intra_16x16_DC预测模式,对于8bit像素,其宏块预测值为128.

3.4 Intra_16x16_Plane预测模式

Intra_16x16_Plane模式要求33个像素值都存在时才能使用。计算方式如下:
predL[ x, y ] = Clip1Y( ( a + b * ( x − 7 ) + c * ( y − 7 ) + 16 ) >> 5 ),x,y = 0…15
其中,
a = 16 * ( p[−1, 15 ] + p[ 15, −1 ] )
b = ( 5 * H + 32 ) >> 6
c = ( 5 * V + 32 ) >> 6

4.色度8x8块预测

一个宏块包含两个8x8色度块,分别为cb分量和cr分量。这两个分量使用相同的预测方式,由mb header中的语法元素intra_chroma_pred_mode决定。
在这里插入图片描述
这4种预测模式与Intra_16x16类似,不再赘述。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H264/AVC-帧内预测 的相关文章

  • janus以及coturncentos8的配置_排错填坑完结篇

    前言 查阅了不少资料 网上对janus以及coturn的配置比比皆是 不过 我发现了一个问题 那就是 janus要直接对接coturn作为turn服务器吗 为什么 janus的demo例子 譬如 video room 能不能在手机4g网络上
  • netty文件上传断点续传的演示

    Netty文件上传断点续传的演示 一 理论和协议规范和工具类等 1 实现原理 netty文件上传采用自定义的协议方式实现 断点续传主要是依据RandomAccessFile类的随机读写能力 主要流程是客户端发起请求 将需要上传文件名称 路径
  • Leetcode[数组] 分发饼干 -- 贪心算法

    0 题目描述 leetcode原题链接 分发饼干 1 预排序 双指针 利用贪心算法的思想 每次都先满足胃口最小的孩子 直到有效饼干分完 或者小胃口孩子都被满足则停止分发 class Solution def findContentChild
  • 区块链浏览器搭建

    嗨喽 大家好 不知道大家是否遇见过类似的问题 自己使用以太坊源代码搭建了一个开发网私链时 缺少了主网或者测试网的区块链浏览器这种区块链数据直观展示的工具 那么今天就带大家一起搭建一个适合自己的区块链浏览器使用 文章目录 一 环境准备 1 1
  • 利用BFD协议提高SD-WAN网络的故障收敛时间

    BFD简介 为了减小设备故障对业务的影响 提高网络的可用性 设备需要能够尽快检测到与相邻设备间的通信故障 以便能够及时采取措施 从而保证业务继续进行 现有的故障检测方法主要包括以下几种 1 硬件检测 例如通过SDH Synchronous
  • 第三章 C++之面向对象

    C 基础进阶系列文章 目录 第一章 C 之函数 第二章 C 之引用实现游戏对话框显示 第三章 C 之面向对象 第二章 C 之面向对象 C 基础进阶系列文章 前言 一 什么是面向对象 二 抽象与类 1 C 中的类 2 类的声明 3 创建第一个
  • Java基础知识总结(史上最全)

    Java基础知识总结 写代码 1 明确需求 我要做什么 2 分析思路 我要怎么做 1 2 3 3 确定步骤 每一个思路部分用到哪些语句 方法 和对象 4 代码实现 用具体的java语言代码把思路体现出来 学习新技术的四点 1 该技术是什么
  • openssl编程指南

    openssl编程指南 对于openssl应用编程这方面的详细文档很少 我是通过认真分析openssl源码包中的示例代码来学习并结合man文档来理解它的基本结构的 SSL通讯模型为标准的C S结构 除了在TCP层之上进行传输之外 与一般的通
  • ubuntu18.04使用jlnk下载程序

    ubuntu使用JLink下载程序 JLink安装 JLink官网下载最新的JLink驱动程序 ubuntu使用的是deb包 下载时选J Link Software and Documentation Pack下面的链接 使用sudo dp
  • 基于梯度下降的线性回归(Gradient Descent For Linear Regression)

    概述 梯度下降是很常用的算法 它不仅被用在线性回归上和线性回归模型 平方误差代价函数 在本次 我们要将梯度下降和代价函数结合 我们将用到此算法 并将其应用于具体的拟合直线的线性回归算法里 梯度下降算法和线性回归算法比较如图 左边梯度下降 右

随机推荐

  • Python 队列(Queue)用法

    一 队列 Queue Python的Queue模块中提供了同步的 线程安全的队列类 包括FIFO 先入先出 队列Queue LIFO 后入先出 队列LifoQueue 和优先级队列PriorityQueue 这些队列都实现了锁原语 能够在多
  • Win32程序之进程的原理

  • 面试题更新之-使用 base64 编码的优缺点

    文章目录 base64 编码是什么 使用 base64 编码的优缺点 base64 编码是什么 Base64编码是一种将二进制数据转换为ASCII字符的编码方式 它将三个字节的二进制数据分割成四组 每组6个比特 然后将这些6个比特转换为可打
  • IP有效性检查(C language)

    STATUS ip valid check const char v p Str int i int tmp char p NULL if strlen v p Str gt 15 return ERROR p char v p Str t
  • 基于Logistic回归和Sigmoid函数的分类【机器学习】

    一 认识Logistic回归 LR 分类器 首先 Logistic回归虽然名字里带 回归 但是它实际上是一种分类方法 主要用于两分类问题 利用Logistic函数 或称为Sigmoid函数 自变量取值范围为 INF INF 自变量的取值范围
  • poll方法01

    p select poll 功能 创建poll对象 返回值 poll对象 p register fd event 功能 注册关注的io事件 参数 fd 要关注的IO event 要关注的io事件类型 通用类型 POLLIN 读io事件 po
  • iphone邮箱看不到已发送_不看不知道 教你如何设置iPhone邮箱

    电子邮件是我们日常生活中必不可少的实用工具 尤其是在商务发面发挥着重要的作用 所以 这次我要教大家怎样设置与使用iPhone的电子邮箱功能 电子邮件是我们日常生活中必不可少的实用工具 尤其是在商务发面发挥着重要的作用 所以 这次我要教大家怎
  • Linux Cobbler自动部署装机

    Cobbler自动部署装机 一 实验准备 二 Cobbler自动装机服务搭建步骤 1 导入epel源 2 安装Cobbler以及其相关服务软件包 3 修改cobbler主配置文件 4 使用cobbler check 命令对Cobbler做检
  • ztree实现异步加载(点击节点,请求后台数据,添加数据到对应节点)真正实现了异步树加载数据

    ztree实现异步加载 首先说一下这篇文章和我写的上一篇异步树的区别 上一篇的我实现的是其实是个伪异步加载 因为我实际是把异步的操作写在了节点上面 点击节点时 获取当前节点的ID 取回子节点的数据 然后手动拼接到当前节点下面 真正的异步其实
  • Linux中挖矿病毒清理通用思路

    目录 前言 清理流程 检查修复DNS 停止计划任务 取消tmp目录的可执行权限 服务排查 进程排查 高CPU占用进程查杀 计划任务清理 预加载劫持清理 系统命令变动排查 中毒前后可执行文件排查 系统配置文件排查 小结 前言 在被植入挖矿病毒
  • 制作USB多系统启动盘

    制作USB多系统启动盘 背景 现在的操作系统更新越来越频繁了 如果用刻录光盘来安装系统的话 会导致大量的浪费 而且光盘寿命太短 一旦划伤 基本上就用不了了 所以想办法使用USB来做为启动盘 利用ISO直接安装系统 这样方便 而且更为灵活 想
  • MySQL--彻底删除数据, 修改/设置密码

    目录 MySQL彻底卸载的方法 修改 设置密码 1 使用 SET PASSWORD 命令 2 使用mysqladmin修改密码 3 UPDATE直接编辑user表 4 忘记密码 此文的背景是 昨天反复安装了几次 刚开始一直无法正常启动使用
  • 语义分割python教学_语义分割:基于openCV和深度学习(二)

    语义分割 基于openCV和深度学习 二 Semantic segmentation in images with OpenCV 开始吧 打开segment py归档并插入以下代码 Semantic segmentation with Op
  • VMware虚拟机禁止防火墙启动

    每次打开虚拟机时候 都会启动防火墙 使用起来很不方便 可以做到永久关闭防火墙 查看firewall状态 systemctl status firewalld service 停止firewall systemctl stop firewal
  • 线段树(单点修改+区间查询)(区间修改+区间查询)

    什么是线段树 线段树 是一种二叉搜索树 它将一段区间划分为若干单位区间 每一个节点都储存着一个区间 它功能强大 支持区间求和 区间最大值 区间修改 单点修改等操作 线段树的思想和分治思想很相像 线段树的每一个节点都储存着一段区间 L R 的
  • (三)Fabric2.0启动网络脚本配置剖析

    总目录 0 如何利用区块链保护知识产权 一 HyperLedger Fabric 2 0 release测试网络部署 二 Fabric2 0 first network 生成配置说明 三 Fabric2 0启动网络脚本配置剖析 四 Fabr
  • 初识MySQL(一)

    目录 一 初识MySQL数据库 Database 1 1 为什么要有数据库 1 2 关于数据库的大体分类 二 数据库的操作 2 1 如何创建一个库 2 1 1 SQL方式 2 1 2 图形化界面方式 My SQL Workbench 2 2
  • python socket基于TCP/IP协议实现多人聊天室

    文章目录 前言 一 实现原理 二 queue队列 三 代码实现 四 需要注意的地方 五 总结 前言 所谓套接字 Socket 就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象 一个套接字就是网络上进程通信的一端 提供了应用层进程
  • Vue简单示例——weex跨平台解决方案

    简单介绍 Weex的出现主要解决了Web开发的应用频繁发布版本和多端研发两个问题 同时解决了前端语言性能差异和显示效果受限的问题 什么是weex Weex是使用流行的Web开发体验来开发高性能原生应用框架 使开发者可以用JS语言和前端开发经
  • H264/AVC-帧内预测

    I宏块使用帧内预测编码压缩数据 根据相邻宏块数据恢复当前宏块信息 值得注意的一点是 帧内预测所参考的相邻宏块数据是deblocking之前的像素值 因为上一宏块的deblocking依赖当前宏块像素值 但当前宏块数据还未重建 1 帧内预测类