/* * Copyright (c) 2016, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
for (i = 0; i < MAX_SEGMENTS; ++i) { // Set up avg segment id to be 1.0 and adjust the other segments around // it. int qindex_delta =
av1_compute_qdelta_by_rate(cpi, cm->current_frame.frame_type,
base_qindex, rate_ratio[i] / avg_ratio);
// We don't allow qindex 0 in a segment if the base value is not 0. // Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment // Q delta is sometimes applied without going back around the rd loop. // This could lead to an illegal combination of partition size and q. if ((base_qindex != 0) && ((base_qindex + qindex_delta) == 0)) {
qindex_delta = -base_qindex + 1;
}
av1_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta);
av1_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
}
}
}
int av1_log_block_avg(const AV1_COMP *cpi, const MACROBLOCK *x, BLOCK_SIZE bs, int mi_row, int mi_col) { // This functions returns the block average of luma block unsignedint sum, avg, num_pix; int r, c; constint pic_w = cpi->common.width; constint pic_h = cpi->common.height; constint bw = MI_SIZE * mi_size_wide[bs]; constint bh = MI_SIZE * mi_size_high[bs]; const uint16_t *x16 = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
sum = 0;
num_pix = 0;
avg = 0; int row = mi_row << MI_SIZE_LOG2; int col = mi_col << MI_SIZE_LOG2; for (r = row; (r < (row + bh)) && (r < pic_h); r++) { for (c = col; (c < (col + bw)) && (c < pic_w); c++) {
sum += *(x16 + r * x->plane[0].src.stride + c);
num_pix++;
}
} if (num_pix != 0) {
avg = sum / num_pix;
} return avg;
}
int av1_compute_q_from_energy_level_deltaq_mode(const AV1_COMP *const cpi, int block_var_level) { int rate_level; const AV1_COMMON *const cm = &cpi->common;
// Comparer used by qsort() to order an array of unsigned int from smallest to // largest. staticint comp_unsigned_int(constvoid *a, constvoid *b) { unsignedint arg1 = *(constunsignedint *)a; unsignedint arg2 = *(constunsignedint *)b;
const MACROBLOCKD *xd = &x->e_mbd; unsignedint sse; // Octile is currently hard-coded and optimized for still pictures. In the // future, we might want to expose this as a parameter that can be fine-tuned // by the caller. // An octile of 5 was chosen because it was found to strike the best balance // between quality and consistency. Lower octiles tend to score lower in // SSIMU2, while higher octiles tend to harm subjective quality consistency, // especially in <1 MP images. constint octile = 5; const uint8_t *all_zeros = is_cur_buf_hbd(xd)
? CONVERT_TO_BYTEPTR(av1_highbd_all_zeros)
: av1_all_zeros; unsignedint variances[SUBBLOCKS_IN_SB];
// Calculate subblock variances.
aom_variance_fn_t vf = cpi->ppi->fn_ptr[BLOCK_8X8].vf; for (int subb_i = 0; subb_i < SUBBLOCKS_IN_SB_DIM; subb_i++) { int i = subb_i * SUBBLOCK_SIZE; for (int subb_j = 0; subb_j < SUBBLOCKS_IN_SB_DIM; subb_j++) { int j = subb_j * SUBBLOCK_SIZE; // Truncating values to integers (i.e. the 64 term) was found to perform // better than rounding, or returning them as doubles.
variances[subb_i * SUBBLOCKS_IN_SB_DIM + subb_j] =
vf(x->plane[0].src.buf + i * x->plane[0].src.stride + j,
x->plane[0].src.stride, all_zeros, 0, &sse) /
64;
}
}
// Order the 8x8 SB values from smallest to largest variance.
qsort(variances, SUBBLOCKS_IN_SB, sizeof(unsignedint), comp_unsigned_int);
// Sample three 8x8 variance values: at the specified octile, previous octile, // and next octile. Make sure we use the last subblock in each octile as the // representative of the octile.
assert(octile >= 1 && octile <= 8); constint middle_index = octile * SUBBLOCKS_IN_OCTILE - 1; constint lower_index =
AOMMAX(SUBBLOCKS_IN_OCTILE - 1, middle_index - SUBBLOCKS_IN_OCTILE); constint upper_index =
AOMMIN(SUBBLOCKS_IN_SB - 1, middle_index + SUBBLOCKS_IN_OCTILE);
// Weigh the three variances in a 1:2:1 ratio, with rounding (the +2 term). // This allows for smoother delta-q transitions among superblocks with // mixed-variance features. constunsignedint variance =
(variances[lower_index] + (variances[middle_index] * 2) +
variances[upper_index] + 2) /
4;
// This function returns a score for the blocks local variance as calculated // by: sum of the log of the (4x4 variances) of each subblock to the current // block (x,bs) // * 32 / number of pixels in the block_size. // This is used for segmentation because to avoid situations in which a large // block with a gentle gradient gets marked high variance even though each // subblock has a low variance. This allows us to assign the same segment // number for the same sorts of area regardless of how the partitioning goes.
const MACROBLOCKD *xd = &x->e_mbd; double var = 0; unsignedint sse; int i, j;
aom_variance_fn_t vf = cpi->ppi->fn_ptr[BLOCK_4X4].vf; for (i = 0; i < bh; i += 4) { for (j = 0; j < bw; j += 4) { if (is_cur_buf_hbd(xd)) {
var += log1p(vf(x->plane[0].src.buf + i * x->plane[0].src.stride + j,
x->plane[0].src.stride,
CONVERT_TO_BYTEPTR(av1_highbd_all_zeros), 0, &sse) /
16.0);
} else {
var += log1p(vf(x->plane[0].src.buf + i * x->plane[0].src.stride + j,
x->plane[0].src.stride, av1_all_zeros, 0, &sse) /
16.0);
}
}
} // Use average of 4x4 log variance. The range for 8 bit 0 - 9.704121561.
var /= (bw / 4 * bh / 4); if (var > 7) var = 7;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.