H.264 入门篇 - 10 (帧间预测 - 参考帧列表修改/重排)

2023-11-11

目录

0、写在前面

1、参考帧列表修改/重排 

1.1、短期参考帧的修改

1.1.1、计算 picNumLXPred

1.1.2、计算 picNumLXNoWrap

1.1.3、计算 picNumLX

1.1.4、修改参考帧列表

1.2、长期参考帧的修改


0、写在前面

有的文章写的是 “参考帧列表修改”,有的文章写的是“参考帧列表重排”,其实是同一个意思,在 H.264 的 slice_header 结构语法中,定义了 ”参考帧列表修改/重排“:

  • 低版本的 H.264 定义了这个过程为重排:slice_header->ref_pic_list_reordering() 过程
  • 高版本的 H.264 定义了这个过程为修改:slice_header->ref_pic_list_modification() 过程

通过比较高低版本的 SPEC,slice_header->ref_pic_list_reordering() 过程和 slice_header->ref_pic_list_modification() 过程高度相似,几乎没有区别;

这里我们以新版本的 slice_header->ref_pic_list_modification() 过程为例:

1、参考帧列表修改/重排 

参考图象重排序的大致过程为:对参考图像列表中的参考图像进行遍历,每遍历到一个参考图像,读入句法元素 modification_of_pic_nums_idc,更新其参考图像序号并调整列表。

ref_pic_list_modification_flag_l0 = 1 时,对参考帧列表 RefPicList0 进行修改;

ref_pic_list_modification_flag_l1 = 1 时,对参考帧列表 RefPicList1 进行修改;

本节中以P帧解码时修改参考帧列表 RefPicList0 为例讨论其执行过程。

  • 首先设定一个值 refIdxL0 表示参考帧列表中参考帧的索引值,并初始化为 0;
  • 读取码流中的 modification_of_pic_nums_idc 值,并根据其取值进行计算:
    • 若 modification_of_pic_nums_idc 为 0 或 1,执行短期参考帧的修改过程;
  • 若 modification_of_pic_nums_idc 为 2,执行长期参考帧的修改过程;
  • 若 modification_of_pic_nums_idc 为 3,参考帧列表的修改过程完成;
  • ref_pic_list_modification_flag_lx = 1,则一直读取 modification_of_pic_nums_idc 的值做循环,直到读到3时,退出循环;可能有多个长期多个短期

参考帧列表修改过程以 refIdxL0 作为输入参数,执行完成后的结果也返回给 refIdxL0;

1.1、短期参考帧的修改

修改短期参考帧主要步骤如下:可参考JM代码中reorder_short_term

1.1.1、计算 picNumLXPred

  • picNumLXPred 可以认为是下一步骤中要计算的变量 picNumLXNoWrap 的预测值;
  • 当 slice_header 中出现第一个 modification_of_pic_nums_idc 值时,picNumLXPred 设置为CurrPicNum,即当前帧的 frame_num;
  • 随后,每当计算得到一个 picNumLXNoWrap 后,这一个 picNumLXNoWrap 值都会赋值给picNumLXPred。

1.1.2、计算 picNumLXNoWrap

  • 计算picNumLXNoWrap的方法根据modification_of_pic_nums_idc的取值不同而不同;
  • 当modification_of_pic_nums_idc取值为0时,其含义为码流中读出的abs_diff_pic_num_minus1为picNumLXNoWrap为相对于picNumLXPred的负增量,即需要从picNumLXPred中减去该值。计算方法如下:(标准协议8.2.4.3.1)
if( picNumLXPred − ( abs_diff_pic_num_minus1 + 1 ) < 0 )
    picNumLXNoWrap = picNumLXPred − ( abs_diff_pic_num_minus1 + 1 ) + MaxPicNum
else
    picNumLXNoWrap = picNumLXPred − ( abs_diff_pic_num_minus1 + 1 )

当modification_of_pic_nums_idc取值为1时,其含义为码流中读出的abs_diff_pic_num_minus1为picNumLXNoWrap为相对于picNumLXPred的正增量,即需要从picNumLXPred中加上该值。计算方法如下:

if( picNumLXPred + ( abs_diff_pic_num_minus1 + 1 ) >= MaxPicNum )
    picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1 + 1 ) − MaxPicNum
else
    picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1 + 1 )

1.1.3、计算 picNumLX

picNumLX的值通过picNumLXNoWrap与当前frame_num的值比较后计算得到,具体计算方式如下:

if( picNumLXNoWrap > CurrPicNum )
    picNumLX = picNumLXNoWrap − MaxPicNum
else
    picNumLX = picNumLXNoWrap

该步骤中得到的picNumLX应等于参考帧列表中的某一个短期参考帧的PicNum值。

1.1.4、修改参考帧列表

在计算得到picNumLX后,配合传入的的索引值refIdxLX,接着进行参考帧列表的修改。其方法为将picNumLX对应的短期参考帧置于refIdxLX位置,并且清除掉列表中PicNum等于picNumLX的参考帧。具体计算方法如下:

for( cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > refIdxLX; cIdx− − )
    RefPicListX[ cIdx ] = RefPicListX[ cIdx − 1]
RefPicListX[ refIdxLX++ ] = short-term reference picture with PicNum equal to picNumLX
nIdx = refIdxLX
for( cIdx = refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++ )
    if( PicNumF( RefPicListX[ cIdx ] ) != picNumLX )
        RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ]

1.2、长期参考帧的修改

修改长期参考帧的方法相对简单。在ref_pic_list_modification结构中的long_term_pic_num即表示待操作的长期参考帧索引。修改的方式类似短期参考帧的修改。具体计算方法如下:

for( cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > refIdxLX; cIdx− − )
    RefPicListX[ cIdx ] = RefPicListX[ cIdx − 1]
RefPicListX[ refIdxLX++ ] = long-term reference picture with LongTermPicNum equal to long_term_pic_num
nIdx = refIdxLX
for( cIdx = refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1; cIdx++ )
    if( LongTermPicNumF( RefPicListX[ cIdx ] ) != long_term_pic_num )
        RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

H.264 入门篇 - 10 (帧间预测 - 参考帧列表修改/重排) 的相关文章

随机推荐

  • bash循环得到日期目录

    1 bin bash 2 today date Y m d 3 echo today is today 4 single input raw data 5 6 7 startday date Y m d d 90 days ago 8 en
  • 计算机毕业设计之基于tensorflow-lstm的股票爬虫+预测及可视化

    1 简介 博主介绍 全网粉丝30W csdn特邀作者 博客专家 CSDN新星计划导师 编程领域优质创作者 博客之星 各平台优质作者 专注于Java python等技术领域和毕业项目实战 文末获取源码联系 计算机毕业设计之基于tensorfl
  • 最短路径A*算法原理及java代码实现(看不懂是我的失败)

    算法只要懂原理了 代码都是小问题 先看下面理论 尤其是红色标注的 要源码请留下邮箱 有测试用例 直接运行即可 A 算法 百度上的解释 A 1 A Star 算法是一种静态路网中求解最短路最有效的直接搜索方法 公式表示为 f n g n h
  • 图像边缘检测

    文章目录 前言 一 图像边缘检测 二 边缘检测算子 1 Roberts算子 2 Prewitt算子 3 Sobel算子 三 代码实现 总结 前言 有了图像放大缩小 图像灰度化处理等相关基础知识过后 就可以进行图像边缘检测了 边缘检测最后也会
  • 全屋智能家居搭建初级指南(装修用户)

    环境 小M等智能设备 新装修用户 稳定网络环境 规划好电路布局 问题描述 全屋智能家居如何搭建 初级指南 装修用户 下面部分内容摘自小M智能家居 解决方案 一 装修中需要注意什么 句话概括 需在水电进场前考虑智能家居设计 主要准备两件事 铺
  • jdbc,jpa,springjdbc,springdatajpa,mybatis之间的区别

    jdbc jdbc是Java提供的原生态接口 操作数据库的唯一技术 缺点 重复写代码 代码写死 耦合性高 开发效率低换数据库比较苦难 优点 运行速度最快 所有操作数据库的技术底层都是jdbc写的 jpa java persistence a
  • 汉诺塔(Hanoi)理解(递归函数)

    1 编程求解汉诺塔问题 汉诺塔 Hanoi 是必须用递归方法才能解决的经典问题 它来自于印度神话 上帝创造世界时作了三根金刚石柱子 在第一根柱子上从下往上按大小顺序摞着64片黄金圆盘 如图7 3所示 上帝命令婆罗门把圆盘从下面开始按大小顺序
  • Postman使用Get请求和Post请求

    今天写了很多新活动接口文档 然后使用了Postman 主要总结一下postman的用法 1 Get请求 对应你方法中的getmapping 这种方法只要把参数拼上去就可以了 拼参数有两种格式 A在 中放入的参数 PathVariable 直
  • 业务架构·应用架构·数据架构实战~TOGAF理论全景解读

    1 解读TOGAF 9 2的BA DA AA TA内容模型 企业架构 Enterprise Architecture 包含如下四种架构 BA Business Architecture 业务架构 DA Data Architecture 数
  • 使用Linux脚本更新Weblogic部署的应用程序

    在利用Jenkins实现Weblogic应用自动部署的功能时 如何通过Shell 脚本自动更新Weblogic部署的应用程序呢 可以使用weblogic jar包中的weblogic Deployer这个class 命令如下 java we
  • 移动电源/充电管理设计

    移动电源 充电管理设计 简述 伴随着智能手机的兴起 智能手机的续航成了较大的问题 因此移动电源 充电宝 成为不时之需 而近来的各类无线耳机的兴起 无线耳机的续航又成为新的问题 为此针对无线耳机充电的各大厂商又一次成为热门 而这些都需要类似于
  • Windows11如何使用安卓子系统的Amazon Appstore

    这个月更新了Windows11以后 已经可以在微软应用商店下载安卓子系统并且安装安卓应用了 但是安卓子系统默认使用的是亚马逊的Amazon Appstore 目前这个商店只限制在美国使用 如果直接打开的话会提示Amazon AppStore
  • python学习日记【13 - 面向对象三】

    面向对象三 继承简介 方法重写 super 多重继承 多态 属性和方法 继承简介 继承是面向对象三大特性之一 通过继承我们可以使一个类获取到其他类中的属性和方法 在定义类时 可以在类名后面的括号中指定当前类的父类 超类 基类 继承提高了类的
  • 拥抱你的zsh,Linux下速通zsh&oh-my-zsh配置(附常用插件&主题)

    zsh oh my zsh配置 为什么要使用zsh 功能强大插件 丰富酷炫的主题 对bash完全兼容 这意味着与bash语法一致 功能更 健全 的Tab补全 代码高亮 相信你在阅读完本文以及用上zsh一段时间过后之后 可能并不需要很久 能对
  • 移动端适配方案之postcss-px-to-viewport

    之前做移动端适配时 基本上是采用rem方案 现在发现了一个新的方案 就是用viewport单位 现在viewport单位越来越受到众多浏览器的支持 postcss px to viewport 将px单位自动转换成viewport单位 用起
  • linux 消息队列状态:struct msqid_ds

    Linux的消息队列 queue 实质上是一个链表 它有消息队列标识符 queue ID msgget创建一个新队列或打开一个存在的队列 msgsnd向队列末端添加一条新消息 msgrcv从队列中取消息 取消息是不一定遵循先进先出的 也可以
  • 斐波那契数列应用——有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    以下一道常见的关于斐波那契数列的算法题 发现python的解法比较少 特此分享一下 首先从题目分析 得出以下结论 1 最初一对兔子是一公和一母 2 兔子三个月就能生育 3 后续生下来的兔子很标准的一夫一妻制 但是有近亲繁殖的问题 细思极恐
  • 最好用的五个黑科技搜索引擎推荐

    一 数据搜 http data chongbuluo com 数据搜 这个网站就是搜索一些热词和数据指数的 包括百度指数 阿里指数 微博指数 微信指数 搜狗指数等等 当然 还有一些汽车数据 腾讯大数据 票房数据相关数据查询网站 估计很多人经
  • 多输入多输出

    多输入多输出 MATLAB实现CNN LSTM卷积长短期记忆神经网络多输入多输出 目录 多输入多输出 MATLAB实现CNN LSTM卷积长短期记忆神经网络多输入多输出 预测效果 基本介绍 程序设计 往期精彩 参考资料 预测效果 基本介绍
  • H.264 入门篇 - 10 (帧间预测 - 参考帧列表修改/重排)

    目录 0 写在前面 1 参考帧列表修改 重排 1 1 短期参考帧的修改 1 1 1 计算 picNumLXPred 1 1 2 计算 picNumLXNoWrap 1 1 3 计算 picNumLX 1 1 4 修改参考帧列表 1 2 长期