Compute energy distribution among hor freqs A 16x4 H-DCT is used in units of 16x4 blocks in a frame to compute the total energy in the various higher frequencies. Change-Id: I64e05e897b5bd4fae4efa87869c97004ae576678
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 4a1827d..432ae5c 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -265,6 +265,54 @@ } } +// Compute the horizontal frequency component energy in a frame +// by calucluating the 16x4 Horizontal DCT. This will be subsequently +// used to decide the superresolution factors. +void analyze_hor_freq(const AV1_COMP *cpi, double *energy) { + uint64_t freq_energy[16] = { 0 }; + const YV12_BUFFER_CONFIG *buf = cpi->source; + const int bd = cpi->td.mb.e_mbd.bd; + const int width = buf->y_crop_width; + const int height = buf->y_crop_height; + int32_t coeff[16 * 4]; + int n = 0; + if (buf->flags & YV12_FLAG_HIGHBITDEPTH) { + const int16_t *src16 = (const int16_t *)CONVERT_TO_SHORTPTR(buf->y_buffer); + for (int i = 0; i < height - 4; i += 4) { + for (int j = 0; j < width - 16; j += 16) { + av1_fwd_txfm2d_16x4(src16 + i * buf->y_stride + j, coeff, buf->y_stride, + H_DCT, bd); + for (int k = 4; k < 16; ++k) { + const int64_t en = + coeff[k] * coeff[k] + coeff[k + 16] * coeff[k + 16] + + coeff[k + 32] * coeff[k + 32] + coeff[k + 48] * coeff[k + 48]; + freq_energy[k] += ROUND_POWER_OF_TWO(en, 2 * (bd - 8)); + } + n++; + } + } + } else { + int16_t src16[16 * 4]; + for (int i = 0; i < height - 4; i += 4) { + for (int j = 0; j < width - 16; j += 16) { + for (int ii = 0; ii < 4; ++ii) + for (int jj = 0; jj < 16; ++jj) + src16[ii * 16 + jj] = + buf->y_buffer[(i + ii) * buf->y_stride + (j + jj)]; + av1_fwd_txfm2d_16x4(src16, coeff, buf->y_stride, H_DCT, bd); + for (int k = 4; k < 16; ++k) { + const int64_t en = + coeff[k] * coeff[k] + coeff[k + 16] * coeff[k + 16] + + coeff[k + 32] * coeff[k + 32] + coeff[k + 48] * coeff[k + 48]; + freq_energy[k] += ROUND_POWER_OF_TWO(en, 2 * (bd - 8)); + } + n++; + } + } + } + for (int k = 4; k < 16; ++k) energy[k] = (double)freq_energy[k] / n; +} + static void set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv, int cur_frame_force_integer_mv) { MACROBLOCK *const mb = &cpi->td.mb;