libaom 源码分析:帧间运动矢量预测

AV1 帧间运动矢量预测原理

  1. 运动矢量可以被相邻块预测,这些相邻块可以是空域相邻块,或位于参考帧中的时域相邻块;通过检查所有这些块,将确定一组运动矢量预测器,并用于编码运动矢量信息。

空域运动矢量预测

  1. 两组空域相邻块可以被利用寻找空域 MV 预测器,第一组包括当前块的直接上方和左侧的邻近空间邻居,第二组包括靠近但不是直接相邻于当前块的外部空间邻居。
  2. 对于每组空间邻近块,首先从左到右检查顶行,然后从上到下检查左列。对于相邻空间邻近块,在检查完左列邻近块之后,还会额外检查右上角的块。对于非相邻空间邻近块,首先检查位于(-1,-1)位置的左上角块,然后以与相邻邻近块相似的方式检查顶行和左列。首先检查相邻邻近块,其次检查下一子节将描述的时间运动矢量预测器,之后检查非相邻空间邻近块。
  3. 对于使用一对参考帧的复合预测,不使用非相邻空间邻近块来推导运动矢量预测器。
    在这里插入图片描述

时域运动矢量预测

  1. 除了空域相邻块,MV 预测器还可以使用参考图像的同位块来推导出运动矢量(MV)预测器,即所谓的时间MV预测器。

  2. 过程:

    • 存储参考帧的MV:首先,将参考帧的MV与各自的参考帧索引一起存储。

    • 为当前帧的每个8×8块生成时间MV预测器:对于当前帧的每个8×8块,识别并存储穿过该块的参考帧的MV,并与参考帧索引一起存放在时间MV缓冲区中。

    • 示例:如下图所示的例子中,参考帧1(R1;图右侧)的MV,即MVref,从R1指向R1的参考帧(图左侧)。在此过程中,它穿过了当前帧的8×8块。MVref被存储在与这个8×8块相关联的时间MV缓冲区中。
      在这里插入图片描述

    • 运动投影过程:在推导时间MV预测器的过程中,参考帧按预定义的顺序进行扫描:LAST_FRAME、BWDREF_FRAME、ALTREF2_FRAME、ALTREF_FRAME和LAST2_FRAME。按扫描顺序,较晚的参考帧的MV会替换之前识别的MV。

    • 最终时间MV预测器的确定:给定预定义的块坐标,识别并投影存储在时间MV缓冲区中的相关MV,以派生出指向当前块到其参考帧的时间MV预测器,例如上图中的MV0。

    • 时间MV预测器的预定义块位置:如下图所示,展示了派生16×16块时间MV预测器的预定义块位置。最多检查七个块以找到有效的时间MV预测器。在检查最近的空间MV预测器之后,但在检查非相邻空间MV预测器之前,会检查时间MV预测器。
      在这里插入图片描述

  3. MV预测器的派生:在派生MV预测器时,将所有空间和时间MV候选项汇集在一起,每个预测器被分配一个在扫描空间和时间邻近块期间确定的权重。基于相关权重,对候选项进行排序和排名,并识别出多达四个候选项,将它们添加到MV预测器列表中。这个MV预测器列表也被称为动态参考列表(DRL),如下一子节所述,它在动态MV预测模式中进一步使用。

动态运动矢量预测

  1. 运动向量(MVs)的预测可以通过以下方式完成:

    • 空间邻近块:在当前帧内,利用空间上邻近的编码块来预测MV。
    • 时间邻近块:在参考帧内,利用时间上邻近的块来预测MV。
    • MV预测器集合:通过检查所有这些块,最多可以确定四个MV预测器。
  2. 单参考帧间预测的MV预测模式:

    • NEARESTMV:始终使用MV预测器列表中索引为0的条目。它适用于那些运动变化不大的场景,选择最接近当前编码块的运动向量作为预测。
    • NEARMV:使用索引为1、2或3的条目之一,信号化一个三元DRL(直接参考列表)索引来指示使用哪个条目作为MV预测器。
    • NEWMV:使用索引为0、1或2的条目之一,信号化一个三元DRL索引来指示使用哪个条目作为MV预测器,并信号化相对于MV预测器的MV差分(MVD)。
    • GLOBALMV:使用基于帧级全局运动参数的MV作为MV预测器。它适用于全局运动补偿的场景,其中整个帧或大部分区域都遵循相同的运动。
      在这里插入图片描述
  3. 复合帧间预测的MV预测模式:

    • NEAREST_NEARESTMV:始终使用列表中索引为0的MV对。

    • NEAR_NEARMV:使用由三元DRL索引信号化的索引为1、2或3的MV对。

    • NEAREST_NEWMV:始终使用列表中索引为0的MV对作为MV预测器,并为第二个MV信号化一个MVD。

    • NEW_NEARESTMV:始终使用列表中索引为0的MV对作为MV预测器,并为第一个MV信号化一个MVD。

    • NEAR_NEWMV:使用由三元DRL索引信号化的索引为1、2或3的MV对作为MV预测器,并为第二个MV信号化一个MVD。

    • NEW_NEARMV:使用由三元DRL索引信号化的索引为1、2或3的MV对作为MV预测器,并为第一个MV信号化一个MVD。

    • NEW_NEWMV:使用由三元DRL索引信号化的索引为0、1或2的MV对作为MV预测器,并为两个MV都信号化MVD。

    • GLOBAL_GLOBALMV:基于每个参考帧的帧级全局运动参数使用MV。
      在这里插入图片描述

    • 除了NEARESTMV和NEAREST_NEARESTMV模式外,在所有情况下,都需要信号化DRL索引来指定用作MV预测器的确切MV或MV对。然而,DRL索引的范围在参考列表中可以根据MV预测模式是[0, 1, 2]或[1, 2, 3]。

libaom 相关源码分析

  1. 函数关系:
    在这里插入图片描述

  2. av1_find_mv_refs 函数:

  • 获取宏块位置:从 xd 结构中获取当前宏块的行(mi_row)和列(mi_col)。
  • 初始化全局运动矢量:gm_mv 数组用于存储全局运动矢量,它将被初始化为零。
  • 处理内部帧:如果参考帧是内部帧(INTRA_FRAME),则将全局运动矢量设置为零,并将 global_mvs 对应的元素标记为无效。
  • 计算全局运动矢量:如果参考帧不是内部帧,根据参考帧的类型(单参考帧或复合参考帧),计算全局运动矢量。这些矢量是通过 gm_get_motion_vector 函数计算的,该函数考虑了是否允许高精密运动矢量和是否强制整数运动矢量。
  • 设置参考运动矢量列表:调用 setup_ref_mv_list 函数,传入上述参数,以设置参考运动矢量列表。这个列表将用于后续的运动矢量预测和编码过程。
void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,MB_MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,uint8_t ref_mv_count[MODE_CTX_REF_FRAMES],CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE],uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE],int_mv mv_ref_list[][MAX_MV_REF_CANDIDATES],int_mv *global_mvs, int16_t *mode_context) {const int mi_row = xd->mi_row;const int mi_col = xd->mi_col;int_mv gm_mv[2];if (ref_frame == INTRA_FRAME) {gm_mv[0].as_int = gm_mv[1].as_int = 0;if (global_mvs != NULL) {global_mvs[ref_frame].as_int = INVALID_MV;}} else {const BLOCK_SIZE bsize = mi->bsize;const int allow_high_precision_mv = cm->features.allow_high_precision_mv;const int force_integer_mv = cm->features.cur_frame_force_integer_mv;if (ref_frame < REF_FRAMES) {gm_mv[0] = gm_get_motion_vector(&cm->global_motion[ref_frame],allow_high_precision_mv, bsize, mi_col,mi_row, force_integer_mv);gm_mv[1].as_int = 0;if (global_mvs != NULL) global_mvs[ref_frame] = gm_mv[0];} else {MV_REFERENCE_FRAME rf[2];av1_set_ref_frame(rf, ref_frame);gm_mv[0] = gm_get_motion_vector(&cm->global_motion[rf[0]],allow_high_precision_mv, bsize, mi_col,mi_row, force_integer_mv);gm_mv[1] = gm_get_motion_vector(&cm->global_motion[rf[1]],allow_high_precision_mv, bsize, mi_col,mi_row, force_integer_mv);}}setup_ref_mv_list(cm, xd, ref_frame, &ref_mv_count[ref_frame],ref_mv_stack[ref_frame], ref_mv_weight[ref_frame],mv_ref_list ? mv_ref_list[ref_frame] : NULL, gm_mv, mi_row,mi_col, mode_context);
}
  1. setup_ref_mv_list 函数
  • 扫描第一行上方模式信息:scan_row_mbmi 函数被调用来扫描当前宏块正上方的行(row_offset = -1)的模式信息;
  • 扫描第一列左边模式信息:scan_col_mbmi 函数被调用来扫描当前宏块左方的列(col_offset = -1)的模式信息;
  • 检查上右边界:如果宏块有右上角块(has_tr 为真),则调用 scan_blk_mbmi 函数来扫描右上角块的模式信息;
  • 获取时域参考 mv 信息:调用add_tpl_ref_mv函数获取时域参考 mv 信息;
  • 扫描第二外层区域,检查左上角块:scan_blk_mbmi 函数检查左上角块;
  • for 循环两次外层行列:分别调用scan_row_mbmi、scan_col_mbmi函数扫描外层的行、列信息;
  • 根据nearest_match 更新模式上下文mode_context,这个上下文信息将用于后续的编码决策,包括选择最佳的运动矢量预测模式。通过这种方式,编码器可以更智能地选择运动矢量,从而提高编码效率和视频质量;
  • 排序参考帧候选,分配最近 mv 和近 mv;
  • 处理复合参考帧:通过调用 process_compound_ref_mv_candidate 函数,处理行和列偏移量内的宏块,以收集复合参考 MV 候选。
  • 处理单参考帧:通过调用 process_single_ref_mv_candidate 函数,处理行和列偏移量内的宏块,以收集单一参考 MV 候选。
static AOM_INLINE void setup_ref_mv_list(const AV1_COMMON *cm, const MACROBLOCKD *xd, MV_REFERENCE_FRAME ref_frame,uint8_t *const refmv_count,CANDIDATE_MV ref_mv_stack[MAX_REF_MV_STACK_SIZE],uint16_t ref_mv_weight[MAX_REF_MV_STACK_SIZE],int_mv mv_ref_list[MAX_MV_REF_CANDIDATES], int_mv *gm_mv_candidates,int mi_row, int mi_col, int16_t *mode_context) {const int bs = AOMMAX(xd->width, xd->height);const int has_tr = has_top_right(cm, xd, mi_row, mi_col, bs);MV_REFERENCE_FRAME rf[2];const TileInfo *const tile = &xd->tile;int max_row_offset = 0, max_col_offset = 0;const int row_adj = (xd->height < mi_size_high[BLOCK_8X8]) && (mi_row & 0x01);const int col_adj = (xd->width < mi_size_wide[BLOCK_8X8]) && (mi_col & 0x01);int processed_rows = 0;int processed_cols = 0;av1_set_ref_frame(rf, ref_frame);mode_context[ref_frame] = 0;*refmv_count = 0;// Find valid maximum row/col offset.if (xd->up_available) {max_row_offset = -(MVREF_ROW_COLS << 1) + row_adj;if (xd->height < mi_size_high[BLOCK_8X8])max_row_offset = -(2 << 1) + row_adj;max_row_offset = find_valid_row_offset(tile, mi_row, max_row_offset);}if (xd->left_available) {max_col_offset = -(MVREF_ROW_COLS << 1) + col_adj;if (xd->width < mi_size_wide[BLOCK_8X8])max_col_offset = -(2 << 1) + col_adj;max_col_offset = find_valid_col_offset(tile, mi_col, max_col_offset);}uint8_t col_match_count = 0;uint8_t row_match_count = 0;uint8_t newmv_count = 0;// Scan the first above row mode info. row_offset = -1;if (abs(max_row_offset) >= 1)scan_row_mbmi(cm, xd, mi_col, rf, -1, ref_mv_stack, ref_mv_weight,refmv_count, &row_match_count, &newmv_count, gm_mv_candidates,max_row_offset, &processed_rows);// Scan the first left column mode info. col_offset = -1;if (abs(max_col_offset) >= 1)scan_col_mbmi(cm, xd, mi_row, rf, -1, ref_mv_stack, ref_mv_weight,refmv_count, &col_match_count, &newmv_count, gm_mv_candidates,max_col_offset, &processed_cols);// Check top-right boundaryif (has_tr)scan_blk_mbmi(cm, xd, mi_row, mi_col, rf, -1, xd->width, ref_mv_stack,ref_mv_weight, &row_match_count, &newmv_count,gm_mv_candidates, refmv_count);const uint8_t nearest_match = (row_match_count > 0) + (col_match_count > 0);const uint8_t nearest_refmv_count = *refmv_count;// TODO(yunqing): for comp_search, do it for all 3 cases.for (int idx = 0; idx < nearest_refmv_count; ++idx)ref_mv_weight[idx] += REF_CAT_LEVEL;if (cm->features.allow_ref_frame_mvs) {int is_available = 0;const int voffset =</

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/6761.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

轮播图【HTML+CSS+JavaScript】

给大家分享一个很好看的轮播图&#xff0c;这个也是之前看到别人写的效果感觉很好看&#xff0c;所以后面也自己实现了一下&#xff0c;在这里分享给大家&#xff0c;希望大家也可以有所收获 轮播图效果&#xff1a; 视频效果有点浑浊&#xff0c;大家凑合着看&#xff0c;大家…

OneRestore: A Universal Restoration Framework for Composite Degradation 论文阅读笔记

这是武汉大学一作单位的一篇发表在ECCV2024上的论文&#xff0c;文章代码开源&#xff0c;文章首页图如下所示&#xff0c;做混合图像干扰去除&#xff0c;还能分别去除&#xff0c;看起来很牛逼。文章是少见的做混合图像干扰去除的&#xff0c;不过可惜只包含了3种degradation…

基于Springboot的任务发布平台设计与实现(源码齐全+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

centos7 kafka高可用集群安装及测试

前言 用三台虚拟机centos7 搭建高可用集群&#xff0c;及测试方法 高可用搭建的方法&#xff0c;参考&#xff1a;https://blog.csdn.net/u011197085/article/details/134070318 高可用搭建 1、安装配置zookeeper集群 下载zookeeper 注&#xff1a;zookeeper链接如果失效&a…

30条勒索病毒处置原则

当前&#xff0c;勒索病毒在全球范围内肆虐&#xff0c;成为企业数据资产安全的头号威胁。这些狡猾的恶意软件&#xff0c;如同网络空间中的幽灵&#xff0c;不断寻找并利用系统的漏洞&#xff0c;通过加密数据或窃取敏感信息&#xff0c;向企业索取高额赎金。一旦感染&#xf…

推荐一款业内领先的建模工具:SAP PowerDesigner

SAP PowerDesigner是一款业内领先的建模工具&#xff0c;帮助您改进商务智能&#xff0c;打造更卓越的信息架构。通过该软件的元数据管理功能&#xff0c;可以构建关键信息资产的 360 度全方位视图&#xff0c;从而使数据管理、BI、数据集成和数据整合工作大获裨益。其分析功能…

6本SCI/SSCI被解除「On Hold」, 重新回归, 单位如何认定?还能投吗?

【SciencePub学术】截止至2024年10月&#xff0c;被WOS数据标记的on hold 期刊&#xff0c;共计25本&#xff0c;其中已有6本解除on hold, 重回SCI,SSCI。今天小编就带大家盘点这些“出狱”期刊情况&#xff0c;分析一下这些期刊是否还能投&#xff0c;值得投&#xff1f; 01In…

Linux下GCC编译器的安装

Linux下GCC编译器的安装 以下所有的版本都可以在https://gcc.gnu.org/pub/gcc/infrastructure/这里找最新的 通过apt-get方式下载的Qt5.9的gcc编译器版本只是4.8.3&#xff0c;无法打开一些Qt5的库头文件&#xff0c;所以准备在Llinux下再安装一个gcc5.3.0。 查看gcc版本 ubu…

【Linux】

软件包管理器 yum yum类似应用商店客户端&#xff0c;有人已经把软件写好放在服务器上了&#xff0c;通过yum找到服务器上的软件下载 软件操作 yum list 可以显示所有可下载软件&#xff0c;我们要找lrzsz软件 yum install 下载 yum remove 卸载 yum源 yum下载软件是通过…

【论文复现】基于图卷积网络的轻量化推荐模型

本文所涉及所有资源均在这里可获取。 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐、摄影的一位博主。 &#x1f4d7;本文收录于论文复现系列&#xff0c;大家有兴趣的可以看一看…

天命人开店日记之门店经营调研(下)

在调研前拟定了一些想要去了解的信息&#xff0c;包括&#xff1a;月销量、净利润、用户购买的主要担忧、与电商平台的竞争差异等关键内容&#xff0c;然而当自己去实地考察线下门店时&#xff0c;确发现实际情况与自己的预期相差非常大。大大出乎预料的包括三方面&#xff1a;…

桑基图在医学数据分析中的更复杂应用示例

桑基图&#xff08;Sankey Diagram&#xff09;能够有效地展示复杂的流动关系&#xff0c;特别适合用于医学数据分析中的多种转归和治疗路径的可视化。接下来&#xff0c;我们将构建一个稍微复杂的示例&#xff0c;展示不同疾病患者在治疗过程中的流动&#xff0c;以及他们的治…

【linux】再谈网络基础(一)

1. 再谈 "协议" 协议是一种 "约定"&#xff0c;在读写数据时, 都是按 "字符串" 的方式来发送接收的. 但是这里我们会遇到一些问题&#xff1a; 如何确保从网上读取的数据是否是完整的&#xff0c;区分缓冲区中的由不同客户端发来的数据 2. 网…

基于CNN-RNN的影像报告生成

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【PaddleNLP的FAQ问答机器人】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

【AI落地应用实战】构建基于知识图谱的知识问答系统

一、知识图谱概述 知识图谱&#xff08;Knowledge Graph&#xff09;是一种结构化的语义知识库&#xff0c;它以图形的方式组织和整合信息&#xff0c;使得数据之间的关系变得直观和易于理解。知识图谱的概念融合了计算机科学、数据科学、人工智能等多个领域的技术&#xff0c…

微积分复习笔记 Calculus Volume 1 - 4.8 L’Hôpital’s Rule

4.8 L’Hpital’s Rule - Calculus Volume 1 | OpenStax

AI辅助论文写作的利弊

人工智能的时代&#xff0c;AI从自动驾驶到智能家居&#xff0c;慢慢的都成为了我们生活中的一部分。可当AI被放到学术研究领域&#xff0c;特别是撰写论文这一问题上时&#xff0c;却出现了大量的争议&#xff0c;认为AI撰写论文会削弱该有的批判性思维能力。那不用AI撰写论文…

AOP详解

一.什么是 AOP&#xff1f; AOP 的目的是将横切关注点&#xff08;如日志记录、事务管理、权限控制、接口限流、接口幂等等&#xff09;从核心业务逻辑中分离出来&#xff0c;通过动态代理、字节码操作等技术&#xff0c;实现代码的复用和解耦&#xff0c;提高代码的可维护性和…

红队知识学习入门(4)Windows病毒编写

声明 学习视频来自B站UP主 泷羽sec,如涉及侵泷羽sec权马上删除文章笔记的只是方便各位师傅学习知识,以下网站涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 1、端口号及对应漏洞 ftp:21 tenlnet:23 web:80 80-89:可能是web 443&#xff1a;ssl心脏滴血…

知识竞赛答题系统,线上答题小程序链接怎么做?

随着智能手机的普及&#xff0c;越来越多的单位开始在线上开展知识竞赛。这种形式的知识竞赛不仅易于操作&#xff0c;而且参与度更高。那么线上知识竞赛答题系统怎么做呢&#xff1f;自己可以做吗&#xff1f;答案是可以的&#xff01;借助微信答题系统制作平台风传吧&#xf…