libaom 源码分析:帧间 Skip 模式分析

发布于:2024-12-18 ⋅ 阅读:(65) ⋅ 点赞:(0)

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将继续在视频编码领域发挥重要作用。

AV1 帧间Skip模式

  • AV1 的帧间Skip 模式是一种压缩工具,用于提高编码效率。通过跳过某些特定块的编码过程,Skip 模式可以显著减少比特率需求,同时保持较高的视频质量。这种方法尤其适合于低运动场景或重复帧。
  • Skip 模式是 AV1 编码器中不可或缺的优化工具,通过智能跳过不必要的计算和编码步骤,不仅显著提升了编码效率,还能在低比特率场景中保持良好的视觉质量。它与其他压缩技术(如 Zeromv、残差剪枝)协同工作,共同实现 AV1 在现代视频编码中的性能优势。
  • Skip 模式的定义:Skip 模式的核心思想是,如果某个块的内容可以通过参考帧完全预测出来,就无需显式存储该块的数据。此时编码器可以跳过:
    • 变换系数的编码。
    • 残差的计算和编码。
    • 运动矢量的编码(在特定情况下)。
    • 当使用 Skip 模式时,解码器会直接从参考帧重建该块的内容。
  • Skip 模式的优点
    • 显著节省比特率:减少了不必要的信息存储,降低了编码复杂度。
    • 提高编码效率:跳过某些复杂计算,如变换和残差编码,编码速度加快。
    • 适用性广:在静态场景、重复帧或低运动内容中效果显著。
  • Skip 模式的局限性
    • 不适用于高运动块:高运动内容通常需要显式存储残差和运动矢量,Skip 模式难以触发。
    • 依赖参考帧质量:如果参考帧质量较低,Skip 模式可能会导致解码器重建的块质量下降。
    • 需结合其他模式优化:Skip 模式通常与 Zeromv 或 Nearestmv 模式结合使用,需要编码器智能选择。
  • 帧间 Skip 模式的触发条件:在帧间预测中,Skip 模式的使用条件主要包括以下几方面:
    • 残差为零:预测值和块内容完全匹配,没有残差需要编码。例如:静态背景、重复内容块。
    • 无显著变换系数:预测块的变换系数接近零,可以省略变换编码。
    • 运动矢量和预测运动矢量一致:如果块的运动矢量等于预测运动矢量,可以跳过运动矢量的显式编码。
    • 块划分模式一致:当前块划分方式与参考帧的划分方式一致。

libaom 帧间Skip模式分析

  1. 流程框图:
    在这里插入图片描述
  2. av1_rd_pick_inter_mode_sb_seg_skip 函数源码分析
//开启SEG_LVL_SKIP时,帧间 skip 模式计算
void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
                                        TileDataEnc *tile_data, MACROBLOCK *x,
                                        int mi_row, int mi_col,
                                        RD_STATS *rd_cost, BLOCK_SIZE bsize,
                                        PICK_MODE_CONTEXT *ctx,
                                        int64_t best_rd_so_far) {
   
  const AV1_COMMON *const cm = &cpi->common;
  const FeatureFlags *const features = &cm->features;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = xd->mi[0];
  unsigned char segment_id = mbmi->segment_id;
  const int comp_pred = 0;
  int i;
  unsigned int ref_costs_single[REF_FRAMES];
  unsigned int ref_costs_comp[REF_FRAMES][REF_FRAMES];
  const ModeCosts *mode_costs = &x->mode_costs;
  const int *comp_inter_cost =
      mode_costs->comp_inter_cost[av1_get_reference_mode_context(xd)];
  InterpFilter best_filter = SWITCHABLE;
  int64_t this_rd = INT64_MAX;
  int rate2 = 0;
  const int64_t distortion2 = 0;
  (void)mi_row;
  (void)mi_col;
  (void)tile_data;

  av1_collect_neighbors_ref_counts(xd);//分析当前块的邻居块,统计它们的参考帧使用情况

  //根据当前块上下文,估算编码参考帧所需要的比特数
  estimate_ref_frame_costs(cm, xd, mode_costs, segment_id, ref_costs_single,
                           ref_costs_comp);

  for (i = 0; i < REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX;
  for (i = LAST_FRAME; i < REF_FRAMES; ++i) x->pred_mv_sad[i] = INT_MAX;

  rd_cost->rate = INT_MAX;

  assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));//检查是否启用了 SEG_LVL_SKIP 特性

 //调色板模式与滤波模式初始化
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0; //禁用调色板,因为 SEG_LVL_SKIp 特性下通常不使用调色板
  mbmi->filter_intra_mode_info.use_filter_intra = 0; //不使用滤波器内插
  //模式和运动设置
  mbmi->mode = GLOBALMV; //全局运动
  mbmi->motion_mode = SIMPLE_TRANSLATION; //简单平移运动,不考虑亚像素精度和其他运动模式
  mbmi->uv_mode = UV_DC_PRED;//色度使用 DC 模式

  //参考帧选择
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME))
    mbmi->ref_frame[0] = get_segdata(&cm->seg, segment_id, SEG_LVL_

网站公告

今日签到

点亮在社区的每一天
去签到