对qscale的理解
qscale和qp的关系
QP转qscale: qscale = 0.85f * powf(2.0f, (qp - 12.0f - QP_BD_OFFSET) / 6.0f)
qscale转QP: qp = 12.0f + QP_BD_OFFSET + 6.0f * log2f(qscale/0.85f)
QP (Quantization Parameter): 这是一个整数,范围通常是 0-51。它是 H.264/AVC 标准中定义的参数,直接控制量化器的“粗糙”程度。QP 是最终执行量化步骤时所使用的值。
qscale (Quantization Scale): 这是一个浮点数,可以理解为量化步长(Quantizer Step Size)的内部表示。它与 QP 呈指数关系。
qscale 和 QP 是同一物理意义的两种不同数学表示。QP 是离散的、非线性的整数标度,而 qscale 是连续的、线性的浮点标度。x264 内部进行数学计算和决策时使用 qscale 更方便、更精确,但在最终应用到量化器时,必须转换为标准规定的整数 QP。
qscale 直接决定了 RDO 决策中的一个关键因子——拉格朗日乘数 λ (Lambda)。λ 用于平衡“失真”(Distortion)和“码率”(Rate),qscale 越高,λ 就越大,RDO 就会越倾向于节省码率(容忍更高失真)
为什么要通过qscale计算QP
在数学上,使用线性的qscale进行计算和预测,比使用对数的 QP 更简单、更准确。
x264 的码率控制是一个复杂的系统,它需要根据过去的编码结果(实际产生的比特数、复杂度等)来预测未来编码一个画面或一个宏块(Macroblock)所需要的量化强度,以达到目标码率或目标品质。
预测模型: 码率控制模型通常假设码率与 qscale 成反比,即 Rate∝1/qscale。这是一个相对简单和稳定的线性关系,便于建立数学模型进行预测。 如果直接使用 QP,关系会变成 Rate∝1/(2 QP/6 ),这是一个复杂的指数关系,不便于计算和调整。
平滑调整: 码率控制器在运行中会不断微调量化强度。使用浮点数的 qscale 可以进行非常平滑和精细的调整。例如,控制器计算出下一个理想的 qscale 可能是 24.5。
最终转换: 但是,H.264 标准的量化器只接受整数 QP 作为输入。因此,当 x264 的码率控制算法确定了最优的 qscale 值(例如 24.5)后,它会执行最后一步:将这个 qscale 值反向计算,转换成与之最接近的整数 QP 值,然后才送给量化器。
qscale和RDO的关系
Lambda表:x264预计算了lambda表,其中lambda的计算公式为pow(2, qp/6-2)
拉格朗日乘数:qscale本质上就是拉格朗日乘数,用于在RDO中平衡率(Rate)和失真(Distortion)
优化计算:在RDO过程中,lambda值用于计算率失真代价函数:Cost = Distortion + λ × Rate
多种lambda表:x264提供了不同用途的lambda表,包括常规lambda表和lambda2表,以及用于trellis量化的lambda表 lambda表计算:lambda = pow(2,qp/6-2) lambda2表计算:lambda2 = pow(lambda,2) * .9 * 256 trellis_lambda2
- inter_lambda = .85 * .85 * 2**(qp/3. + 10 - LAMBDA_BITS)
- intra_lambda = .65 * .65 * 2**(qp/3. + 10 - LAMBDA_BITS)
由此可见,lambda的计算公式正式qp转qscale的公式类似,lambda2和trellis_lambda也都是根据labmda表转换过来的, 所以qscale其实就是RDO中lambda。