libaom 源码分析:av1_rd_use_partition 函数

libaom

  • libaom 是 AOMedia Video 1 (AV1) 视频编码格式的参考实现库,由 Alliance for Open Media (AOMedia) 开发和维护。AV1 是一个高效、开放、免专利授权的下一代视频编解码标准,设计目标是提供较高的视频压缩效率,同时适配各种分辨率、码率和平台。
  • 下载:git clone https://aomedia.googlesource.com/aom
  • 以下是libaom的一些关键特点:
  1. 开放和免版税:libaom提供了一个开放源代码的编码器,任何个人和组织都可以免费使用,无需支付版税。

  2. 高效的编码:libaom旨在提供高效的视频压缩,以适应不同的网络条件和设备性能。

  3. 跨平台:libaom支持多种操作系统和平台,包括Windows、Linux和macOS。

  4. AV1编解码器:libaom实现了AV1编解码器,这是一种基于块的视频编码格式,它使用了一系列先进的压缩技术,如CDEF(Constrained Directional Enhancement Filtering)、CIC(Compound Internal Coding)、和PAET(Probabilistic Angular Early Termination)等。

  5. 可配置性:libaom提供了多种配置选项,允许开发者根据应用需求调整编码参数。

  6. 实时编码:libaom支持实时编码,适用于直播和实时通信应用。

  7. 兼容性:libaom编码的视频可以在支持AV1解码的任何播放器或设备上播放。

  8. 社区支持:作为一个开源项目,libaom得到了活跃的社区支持,不断有新功能和改进被加入。

libaom是实现AV1视频编码标准的关键部分,它被许多视频播放器、浏览器和视频服务提供商所采用。随着AV1编解码器的成熟和普及,libaom将继续在视频编码领域发挥重要作用。

libaom 分区搜索类型

  • 在 libaom 中会根据不同的分区搜索类型进行不同的分区操作,具体的分区搜索类型种类在 speed_features.h 头文件中共用体 PARTITION_SEARCH_TYPE 说明;类型主要有基于 RD 准则搜索分区、固定尺寸分区、基于方差分区、基于机器学习分区。
    在这里插入图片描述

AV1分区编码

AV1 分区编码(Partition Coding)是 AV1 编码器中用于将图像分割成不同大小的块,并针对每个块选择最优分区模式的一种技术。通过选择不同的分区模式,AV1 编码器能够平衡压缩效率(码率)与图像质量(失真),从而获得更高的压缩性能。

AV1 分区模式

AV1 中定义了多种分区模式,编码器根据当前块的特性(如内容复杂度、大小等)选择最合适的分区模式。常见的分区模式包括:

  • PARTITION_NONE:
    该模式表示不对当前块进行分区,整个块作为一个单元进行编码。
    适用于纹理较简单或者小块的场景。
  • PARTITION_SPLIT:
    将当前块分成四个相同大小的子块(通常是 2x2 或 4x4 分割),分别进行编码。
    适用于较复杂或不规则的图像区域。
  • PARTITION_HORZ:
    将当前块沿水平方向进行分区,分成上下两部分,分别进行编码。
    适用于横向纹理或大致水平方向的图像区域。
  • PARTITION_VERT:
    将当前块沿垂直方向进行分区,分成左右两部分,分别进行编码。
    适用于纵向纹理或大致垂直方向的图像区域。

av1_rd_use_partition 函数

  1. 函数功能:av1_rd_use_partition 是 AV1 编码器中用于递归分区搜索的重要函数。其作用是根据当前块的大小和内容特性,在各种分区模式中选择最优的分区模式(如 PARTITION_NONE、PARTITION_SPLIT、PARTITION_HORZ、PARTITION_VERT 等),以最小化码率失真代价(Rate-Distortion Cost, RD Cost)。

  2. 源码内部原理流程图:
    在这里插入图片描述

  3. 源码详细注释分析:

/*!\brief AV1 block partition search (partition estimation and partial search).
*
* \ingroup partition_search
* Encode the block by applying pre-calculated partition patterns that are
* represented by coding block sizes stored in the mbmi array. Minor partition
* adjustments are tested and applied if they lead to lower rd costs. The
* partition types are limited to a basic set: none, horz, vert, and split.
* 通过应用预先计算的分区模式来编码,这些模式由存储在 mbmi 数组中的编码块大小表示,
* 如果进行小的分区调整可以降低率失真 RD 成本,则会进行调整,分区类型被限制在基本集中:
* 不分、水平、垂直、分裂
* \param[in]    cpi       Top-level encoder structure
* \param[in]    td        Pointer to thread data
* \param[in]    tile_data Pointer to struct holding adaptive
data/contexts/models for the tile during encoding
* \param[in]    mib       Array representing MB_MODE_INFO pointers for mi
blocks starting from the first pixel of the current
block
* \param[in]    tp        Pointer to the starting token
* \param[in]    mi_row    Row coordinate of the block in a step size of MI_SIZE
* \param[in]    mi_col    Column coordinate of the block in a step size of
MI_SIZE
* \param[in]    bsize     Current block size 当前块大小
* \param[in]    rate      Pointer to the final rate for encoding the current
block
* \param[in]    dist      Pointer to the final distortion of the current block
* \param[in]    do_recon  Whether the reconstruction function needs to be run,
either for finalizing a superblock or providing 是否需要运行重建函数,用于完成超块或未来的子块分区提供参考
reference for future sub-partitions
* \param[in]    pc_tree   Pointer to the PC_TREE node holding the picked
partitions and mode info for the current block
*
* \remark Nothing is returned. The pc_tree struct is modified to store the
* picked partition and modes. The rate and dist are also updated with those
* corresponding to the best partition found.
*/
void av1_rd_use_partition(AV1_COMP *cpi, ThreadData *td, TileDataEnc *tile_data,
                          MB_MODE_INFO **mib, TokenExtra **tp, int mi_row,
                          int mi_col, BLOCK_SIZE bsize, int *rate,
                          int64_t *dist, int do_recon, PC_TREE *pc_tree) {
   
  AV1_COMMON *const cm = &cpi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int num_planes = av1_num_planes(cm);
  TileInfo *const tile_info = &tile_data->tile_info;
  MACROBLOCK *const x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
  const ModeCosts *mode_costs = &x->mode_costs;
  const int bs = mi_size_wide[bsize];
  const int hbs = bs / 2;
  //获取分区平面上下文索引
  const int pl = (bsize >= BLOCK_8X8)
                     ? partition_plane_context(xd, mi_row, mi_col, bsize)
                     : 0;
  //获取块的分区类型
  const PARTITION_TYPE partition =
      (bsize >= BLOCK_8X8) ? get_partition(cm, mi_row, mi_col, bsize)
                           : PARTITION_NONE;
  
  //根据分区类型获取子块大小
  const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
  RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
  RD_STATS last_part_rdc, none_rdc, chosen_rdc, invalid_rdc;
  BLOCK_SIZE bs_type = mib[0]->bsize;
  int use_partition_none = 0;
  x->try_merge_partition = 0;

  //分配内存,确保分区模式上下文存在
  if (pc_tree->none == NULL) {
   
    pc_tree->none = av1_alloc_pmc(cpi, bsize, &td->shared_coeff_buf);
    if (!pc_tree->none)
      aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
                         "Failed to allocate PICK_MODE_CONTEXT");
  }
  PICK_MODE_CONTEXT *ctx_none = pc_tree->none;

  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;//边界检查,如果块超过当前帧范围,直接退出

  assert(mi_size_wide[bsize] == mi_size_high[bsize]);
  // In rt mode, currently the min partition size is BLOCK_8X8.
  assert(bsize >= cpi->sf.part_sf.default_min_partition_size);

  av1_invalid_rd_stats(&last_part_rdc);
  av1_invalid_rd_stats(&none_rdc);
  av1_invalid_rd_stats(&chosen_rdc

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何恢复使用 Cursor 免费试用

当用户尝试创建过多免费试用账户时,会收到提示:“Too many free trial accounts used on this machine. Please upgrade to pro.” 这限制了用户的试用次数。AI大眼萌帮助大家绕过 Cursor 的设备指纹验证,以继续享受免费试用。 🚨…

【Excel学习记录】01-认识Excel

1.之前的优秀软件Lotus-1-2-3 默认公式以等号开头 兼容Lotus-1-2-3的公式写法,不用写等号 : 文件→选项→高级→勾选:“转换Lotus-1-2-3公式(U)” 备注:对于大范围手动输入公式可以使用该选项,否则请不要勾选&#x…

网络安全——防火墙

基本概念 防火墙是一个系统,通过过滤传输数据达到防止未经授权的网络传输侵入私有网络,阻止不必要流量的同时允许必要流量进入。防火墙旨在私有和共有网络间建立一道安全屏障,因为网上总有黑客和恶意攻击入侵私有网络来破坏,防火…

kafka进阶_4.kafka扩展

文章目录 一、Controller选举二、Kafka集成2.1、大数据应用场景2.1.1、Flume集成2.1.2、Spark集成2.1.3、Flink集成 2.2、Java应用场景(SpringBoot集成) 三、Kafka常见问题3.1、Kafka都有哪些组件?3.2、分区副本AR, ISR, OSR的含义?3.3、Producer 消息重…

OpenAI 12Days 第二天 强化微调(RFT):推动语言模型在科学研究中的应用

OpenAI 12Days 第二天 强化微调(RFT):推动语言模型在科学研究中的应用 文章目录 OpenAI 12Days 第二天 强化微调(RFT):推动语言模型在科学研究中的应用RFT的工作原理与应用领域案例研究:基因突变…

Go mysql驱动源码分析

文章目录 前言注册驱动连接器创建连接交互协议读写数据读数据写数据 mysqlConncontext超时控制 查询发送查询请求读取查询响应 Exec发送exec请求读取响应 预编译客户端预编译服务端预编译生成prepareStmt执行查询操作执行Exec操作 事务读取响应query响应exec响应 总结 前言 go…

MeshCNN复现

开源代码:GitHub - ranahanocka/MeshCNN: Convolutional Neural Network for 3D meshes in PyTorchConvolutional Neural Network for 3D meshes in PyTorch - ranahanocka/MeshCNNhttps://github.com/ranahanocka/MeshCNN/?tabreadme-ov-file 运行方式&#xff1…

ubuntu中使用ffmpeg库进行api调用开发

一般情况下,熟悉了ffmpeg的命令行操作,把他当成一个工具来进行编解码啥的问题不大,不过如果要把功能集成进自己的软件中,还是要调用ffmpeg的api才行。 ffmpeg的源码和外带的模块有点太多了,直接用官网别人编译好的库就…

【Ubuntu】URDC(Ubuntu远程桌面助手)安装、用法,及莫名其妙进入全黑模式的处理

1、简述 URDC是Ubuntu远程桌面助手的简称。 它可以: 实时显示桌面:URDC支持通过Windows连接至Ubuntu设备(包括x86和ARM架构,例如Jetson系列、树莓派等)的桌面及光标。远程操控双向同步剪切板多客户端连接:同一Ubuntu设备最多可同时被三台Windows客户端连接和操控,适用于…

备忘录模式的理解和实践

引言 在软件开发中,我们经常会遇到需要保存对象状态并在某个时间点恢复到该状态的需求。这种需求类似于我们平时说的“后悔药”,即允许用户撤销之前的操作,恢复到某个之前的状态。备忘录模式(Memento Pattern)正是为了…

云端微光,AI启航:低代码开发的智造未来

文章目录 前言一、引言:技术浪潮中的个人视角初次体验腾讯云开发 Copilot1.1 低代码的时代机遇1.1.1 为什么低代码如此重要? 1.2 AI 的引入:革新的力量1.1.2 Copilot 的亮点 1.3 初学者的视角1.3.1 Copilot 带来的改变 二、体验记录&#xff…

(css)element中el-select下拉框整体样式修改

(css)element中el-select下拉框整体样式修改 重点代码(颜色可行修改) // 修改input默认值颜色 兼容其它主流浏览器 /deep/ input::-webkit-input-placeholder {color: rgba(255, 255, 255, 0.50); } /deep/ input::-moz-input-placeholder {color: rgba…

Ungoogled Chromium127编译指南 Windows篇 - 获取源码(七)

1. 引言 在完成所有必要工具的安装和配置后,我们进入了Ungoogled Chromium编译过程的第一个关键阶段:获取源代码。本文将详细介绍如何正确获取和准备Ungoogled Chromium的源代码,为后续的编译工作打下基础。 2. 准备工作 2.1 环境检查 在…

802数据结构:2022年真题选择题

目录 前言 一、 选择题(本大题共 15小题,每小题 2分,共 30分) 1、当输入非法错误时一个“好”的算法会进行适当处理而不会产生难以理解的输出结果。这称为算法的()。A可读性    B.健壮性    C.正确性…

汽车零部件设计之——发动机曲轴预应力模态分析仿真APP

汽车零部件是汽车工业的基石,是构成车辆的基础元素。一辆汽车通常由上万件零部件组成,包括发动机系统、传动系统、制动系统、电子控制系统等,它们共同确保了汽车的安全、可靠性及高效运行。在汽车产业快速发展的今天,汽车零部件需…

QT实战--带行号的支持高亮的编辑器实现(2)

本文主要介绍了第二种实现带行号的支持高亮的编辑器的方式,基于QTextEdit实现的,支持自定义边框,背景,颜色,以及滚动条样式,支持输入变色,复制文本到里面变色,支持替换,是一个纯专业项目使用的编辑器 先上效果图: 1.头文件ContentTextEdit.h #ifndef CONTENT_TEXT_…

【JAVA】旅游行业中大数据的使用

一、应用场景 数据采集与整合:全面收集旅游数据,如客流量、游客满意度等,整合形成统一数据集,为后续分析提供便利。 舆情监测与分析:实时监测旅游目的地的舆情信息,运用NLP算法进行智能处理,及…

vxe-grid使用问题

目录 1.slot中使用模板字符串 2.合并表头 坑1:合并表头后一窜一窜的位置 坑2:合并表头后页面位置不够大,表头合并的位置就又窜了 3.footer-method部分行高 4.整列居左的前提下设置前几行居中 坑1:样式加不上去 坑2&#x…

Unity3D下采集camera场景并推送RTMP服务实现毫秒级延迟直播

技术背景 好多开发者,希望我们能够分享下如何实现Unity下的camera场景采集并推送rtmp服务,然后低延迟播放出来。简单来说,在Unity 中实现采集 Camera 场景并推送RTMP的话,先是获取 Camera 场景数据,通过创建 RenderTex…

分布式 Raft算法 总结

前言 相关系列 《分布式 & 目录》《分布式 & Raft算法 & 总结》《分布式 & Raft算法 & 问题》 参考文献 《Raft一致性算法论文译文》《深入剖析共识性算法 Raft》 简介 Raft 木筏是一种基于日志复制实现的分布式容错&一致性算法。在Raft算法…