音视频笔记|运动估计 ME 源码简要分析(上)

Last updated on April 30, 2023 am

前言

运动估计在分别会在 lookahead 阶段和后续编码阶段被使用,但两者使用的方法并不相同。本文将介绍编码阶段的 ME 进行讨论,下文将对 lookahead 阶段的 ME 进行介绍。

运动估计是帧间预测阶段的核心部分,它通过比较当前帧与先前帧之间的相似性,来确定宏块(Macroblock)或子宏块(Sub-macroblock)之间的运动矢量。运动估计可以有效地消除时间冗余,从而降低编码后的比特率,提高编码效率。x264中的运动估计算法有很多种,包括钻石搜索(Diamond Search),六边形搜索(Hexagon Search)和不对称交叉多六边形搜索(Uneven Multi-Hexagon Search)等。

ME 相关知识

宏块的运动补偿

宏块(Macroblock)是帧中 16x16 大小的区域,它是包括 MPEG-1、MPEG-2、MPEG-4 Visual、H.261、H.262、H,264 在内的很多视频编码标准的运动补偿预测的基本单元。

在常见的 YUV 4:2:0 图像编码格式中,一个宏块由:

  1. 64 个红色色差采样构成,这些采样组成 1 个 8x8 的采样块;

  2. 64 个红色色差采样构成,这些采样组成 1 个 8x8 的采样块;

  3. 64 个蓝色色差采样构成,这些采样组成 1 个 8x8 的采样块;

即一共 6 个采样块,示意图如下:

宏块的运动估计,主要是寻找参考帧中和当前宏块匹配的 16x16 采样区域。参考帧是先前就编码好的一个帧,在时间维上,参考帧可以在过去或者未来。参考帧中以当前宏块为中心的区域被搜索,寻找最佳匹配。

最佳匹配的照度、色差采样,被从当前宏块中减去,这样就产生了一个残余宏块。残余宏块与标示了最佳匹配区域和当前宏块的相对位移的 移动向量 一起编码并传输。

在上述基本的运动估计、运动补偿的基础上,有很多变体的算法:

  1. 如果使用了未来的帧作为参考帧,则未来的帧必须在当前帧之前编码,也就是帧的编码必须是乱序的;
  2. 当参考帧和当前帧的差异非常大时,不使用运动补偿可能更加高效,编码器可能选择使用帧内预测;
  3. 视频中的移动物体很少能恰恰匹配16x16的边缘,因此使用可变大小的块往往更加高效;
  4. 物体移动的距离可能不是整像素,例如物体可能在水平方向移动3.83像素的距离。因此一个好的预测算法会在搜索最佳匹配之前在参考帧中,在次像素级别进行插值。

Preset 与 ME

笔者本以为在 ultrafast 等较快的 Preset 模式下 ME 是不会开启的,但后来翻看源码发现:在所有 Preset 模式下都会启用,同时会根据 Preset 档次来选择对应的 ME 算法(diamon,haxgon,umh 等)

AQ(Adopt Quatinazation, 自适应量化) 在除 ultrafast (禁用 AQ 降低复杂度) 以外的所有 Preset 下都会开启。

源码中调用位置

  • slices_write()

  • **slice_write()**(主要是slice,不是复数)

  • x264_macroblock_analyse() - 【slice_write() / analyse.c】

  • mb_analyse_inter_p16x16()【P 帧为例】

  • x264_me_search_ref【mb_analyse_inter_b16x16】

以上便是ME在源码中的函数调用位置。

由于笔者在此阶段也只是简略进行分析,如有疏漏请欢迎指正!


音视频笔记|运动估计 ME 源码简要分析(上)
https://erenship.com/posts/49d0.html
Author
Eren
Posted on
April 16, 2023
Licensed under