有人知道aom编码器内部在--tune=ssim的情况下是如何进行调整拉个朗日乘子的吗?
源代码内会调用 av1_set_mb_ssim_rdmult_scaling函数设置对rdmult的缩放因子,但是为什么这样设置有人知道吗,它的rdo模型是怎么样的?特别是里面那个指数函数拟合代表什么意思?
void av1_set_mb_ssim_rdmult_scaling(AV1_COMP *cpi) {
const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
const MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
uint8_t *y_buffer = cpi->source->y_buffer;
const int y_stride = cpi->source->y_stride;
const int block_size = BLOCK_16X16;
const int num_mi_w = mi_size_wide[block_size];
const int num_mi_h = mi_size_high[block_size];
const int num_cols = (mi_params->mi_cols + num_mi_w - 1) / num_mi_w;
const int num_rows = (mi_params->mi_rows + num_mi_h - 1) / num_mi_h;
double log_sum = 0.0;
// Loop through each 16x16 block.
for (int row = 0; row < num_rows; ++row) {
for (int col = 0; col < num_cols; ++col) {
double var = 0.0, num_of_var = 0.0;
const int index = row * num_cols + col;
// Loop through each 8x8 block.
for (int mi_row = row * num_mi_h;
mi_row < mi_params->mi_rows && mi_row < (row + 1) * num_mi_h;
mi_row += 2) {
for (int mi_col = col * num_mi_w;
mi_col < mi_params->mi_cols && mi_col < (col + 1) * num_mi_w;
mi_col += 2) {
struct buf_2d buf;
const int row_offset_y = mi_row << 2;
const int col_offset_y = mi_col << 2;
buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y;
buf.stride = y_stride;
var += av1_get_perpixel_variance_facade(cpi, xd, &buf, BLOCK_8X8,
AOM_PLANE_Y);
num_of_var += 1.0;
}
}
var = var / num_of_var;
// Curve fitting with an exponential model on all 16x16 blocks from the
// midres dataset.
var = 67.035434 * (1 - exp(-0.0021489 * var)) + 17.492222;
// As per the above computation, var will be in the range of
// [17.492222, 84.527656], assuming the data type is of infinite
// precision. The following assert conservatively checks if var is in the
// range of [17.0, 85.0] to avoid any issues due to the precision of the
// relevant data type.
assert(var > 17.0 && var < 85.0);
cpi->ssim_rdmult_scaling_factors[index] = var;
log_sum += log(var);
}
}
// As log_sum holds the geometric mean, it will be in the range
// [17.492222, 84.527656]. Hence, in the below loop, the value of
// cpi->ssim_rdmult_scaling_factors[index] would be in the range
// [0.2069, 4.8323].
log_sum = exp(log_sum / (double)(num_rows * num_cols));
for (int row = 0; row < num_rows; ++row) {
for (int col = 0; col < num_cols; ++col) {
const int index = row * num_cols + col;
cpi->ssim_rdmult_scaling_factors[index] /= log_sum;
}
}
}