首页 > 编程语言 >libaom 源码分析:av1_rd_use_partition 函数

libaom 源码分析:av1_rd_use_partition 函数

时间:2024-12-09 16:59:09浏览次数:6  
标签:use libaom 分区 partition mi AV1 源码 const

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

标签:use,libaom,分区,partition,mi,AV1,源码,const
From: https://blog.csdn.net/yanceyxin/article/details/144352229

相关文章

  • 英飞达医学影像存档与通信系统WebUserLogin.asmx存在信息泄露
    免责声明:本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在使用本......
  • 基于springboot+vue实现的项目评审系统 (源码+L文+ppt)4-116
    摘 要相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低运营人员成本,实现了项目评审系统的标准化、制度化、程序化的管理,有效地防止了项目评审的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正项目信息、评审结果、项目申报等信息。课题主要采......
  • 基于springboot+vue实现的剧本杀管理系统(源码+L文+ppt)4-114
      摘 要剧本杀管理系统是一个综合性平台,为剧本杀游戏爱好者、创作者及商家提供多方位服务。系统具备用户账号管理、剧本分类、预约、评价和论坛交流等核心功能。通过这个平台,用户可以便捷地浏览各类剧本信息,根据兴趣和时间安排进行预约,同时在游戏结束后对体验进行反馈。......
  • 基于springboot+vue实现的项目评审系统 (源码+L文+ppt)4-116
      摘 要相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低运营人员成本,实现了项目评审系统的标准化、制度化、程序化的管理,有效地防止了项目评审的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正项目信息、评审结果、项目申报等信息。课题主......
  • 即时通讯在线客服系统源码-使用Golang Gin 和 Redis实现分布式webocket
    使用Go实现一个基于Gin框架和Redis的分布式WebSocket系统需要以下几个步骤:实现架构Gin处理HTTP/WebSocket请求Gin用于启动HTTP服务并处理WebSocket请求。RedisPub/SubRedis用于跨节点消息分发。WebSocket连接管理在服务内维护WebSocket连接池......
  • Flink Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be
     packagecom.example;importorg.apache.flink.api.common.typeinfo.TypeInformation;importorg.apache.flink.api.java.typeutils.RowTypeInfo;importorg.apache.flink.connector.jdbc.JdbcExecutionOptions;importorg.apache.flink.connector.jdbc.JdbcInputForm......
  • 【从0带做】基于协同过滤算法的springboot+vue的煤矿员工健康管理系统的设计与实现 【
    ✍✍计算机编程指导师⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java实战|SpringBoot/SSMPython实战项目|Django微信小程......
  • 基于java ssm篮球网上商城系统(源码+文档+运行视频+讲解视频)
     文章目录系列文章目录目的前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架SSM前端框架vueSSM框架详细介绍系统测试四、代码参考源码获取目的摘要: 本文论述基于JavaSSM框架构建的篮球网上商城系统。该系统在满足篮球爱好者购物需求和推动篮球运动发......
  • 基于java ssm家用电器上门回收系统回收分配订单(源码+文档+运行视频+讲解视频)
     文章目录系列文章目录目的前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架SSM前端框架vueSSM框架详细介绍系统测试四、代码参考源码获取目的摘要: 本文论述基于JavaSSM框架构建的家用电器上门回收系统。该系统在推动资源循环利用和环保事业中发挥着......
  • 基于java ssm教师教学数据统计分析系统论文课题科研成果工作量考核工作日志(源码+文档+
     文章目录系列文章目录目的前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架SSM前端框架vueSSM框架详细介绍系统测试四、代码参考源码获取目的摘要: 本文论述基于JavaSSM框架构建的教师教学数据统计分析系统。该系统对提升教学管理水平和教师教学质量......