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;