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;