Merge "Refactor rd_pick_intra_angle_" into nextgenv2
diff --git a/configure b/configure
index c93c22c..9769880 100755
--- a/configure
+++ b/configure
@@ -282,6 +282,7 @@
     ans
     loop_restoration
     ext_partition
+    obmc
 "
 CONFIG_LIST="
     dependency_tracking
diff --git a/test/hbd_metrics_test.cc b/test/hbd_metrics_test.cc
new file mode 100644
index 0000000..75b7c9b
--- /dev/null
+++ b/test/hbd_metrics_test.cc
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (c) 2016 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <new>
+
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "test/acm_random.h"
+#include "test/util.h"
+#include "./vpx_config.h"
+#include "vpx_dsp/ssim.h"
+#include "vpx_ports/mem.h"
+#include "vpx_ports/msvc.h"
+#include "vpx_scale/yv12config.h"
+
+
+using libvpx_test::ACMRandom;
+
+namespace {
+
+typedef double (*LBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
+                                const YV12_BUFFER_CONFIG *dest,
+                                double *weight);
+typedef double (*HBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
+                                const YV12_BUFFER_CONFIG *dest,
+                                double *weight, unsigned int bd);
+
+class HBDMetricsTestBase {
+ public:
+  virtual ~HBDMetricsTestBase() {}
+
+ protected:
+  void RunAccuracyCheck() {
+    const int width = 1920;
+    const int height = 1080;
+    int i = 0;
+    const uint8_t kPixFiller = 128;
+    YV12_BUFFER_CONFIG lbd_src, lbd_dst;
+    YV12_BUFFER_CONFIG hbd_src, hbd_dst;
+    ACMRandom rnd(ACMRandom::DeterministicSeed());
+    double lbd_score, hbd_score, lbd_db, hbd_db, lbd_w, hbd_w;
+
+    memset(&lbd_src, 0, sizeof(lbd_src));
+    memset(&lbd_dst, 0, sizeof(lbd_dst));
+    memset(&hbd_src, 0, sizeof(hbd_src));
+    memset(&hbd_dst, 0, sizeof(hbd_dst));
+
+    vpx_alloc_frame_buffer(&lbd_src, width, height, 1, 1, 0, 32, 16);
+    vpx_alloc_frame_buffer(&lbd_dst, width, height, 1, 1, 0, 32, 16);
+    vpx_alloc_frame_buffer(&hbd_src, width, height, 1, 1, 1, 32, 16);
+    vpx_alloc_frame_buffer(&hbd_dst, width, height, 1, 1, 1, 32, 16);
+
+    memset(lbd_src.buffer_alloc, kPixFiller, lbd_src.buffer_alloc_sz);
+    while (i < lbd_src.buffer_alloc_sz) {
+      uint16_t spel, dpel;
+      spel = lbd_src.buffer_alloc[i];
+      // Create some distortion for dst buffer.
+      lbd_dst.buffer_alloc[i] = rnd.Rand8();
+      dpel = lbd_dst.buffer_alloc[i];
+      ((uint16_t*)(hbd_src.buffer_alloc))[i] = spel << (bit_depth_ - 8);
+      ((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
+      i++;
+    }
+
+    lbd_score = lbd_metric_(&lbd_src, &lbd_dst, &lbd_w);
+    hbd_score = hbd_metric_(&hbd_src, &hbd_dst, &hbd_w, bit_depth_);
+
+    lbd_db = 100 * pow(lbd_score / lbd_w, 8.0);
+    hbd_db = 100 * pow(hbd_score / hbd_w, 8.0);
+
+    vpx_free_frame_buffer(&lbd_src);
+    vpx_free_frame_buffer(&lbd_dst);
+    vpx_free_frame_buffer(&hbd_src);
+    vpx_free_frame_buffer(&hbd_dst);
+
+    EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
+  }
+
+  int bit_depth_;
+  double threshold_;
+  LBDMetricFunc lbd_metric_;
+  HBDMetricFunc hbd_metric_;
+};
+
+typedef std::tr1::tuple<LBDMetricFunc,
+                        HBDMetricFunc, int, double> MetricTestTParam;
+class HBDMetricsTest
+    : public HBDMetricsTestBase,
+      public ::testing::TestWithParam<MetricTestTParam> {
+ public:
+  virtual void SetUp() {
+    lbd_metric_ = GET_PARAM(0);
+    hbd_metric_ = GET_PARAM(1);
+    bit_depth_ = GET_PARAM(2);
+    threshold_ = GET_PARAM(3);
+  }
+  virtual void TearDown() {}
+};
+
+TEST_P(HBDMetricsTest, RunAccuracyCheck) {
+  RunAccuracyCheck();
+}
+
+// Allow small variation due to floating point operations.
+static const double kSsim_thresh = 0.001;
+
+INSTANTIATE_TEST_CASE_P(
+    C, HBDMetricsTest,
+    ::testing::Values(
+        MetricTestTParam(&vpx_calc_ssim, &vpx_highbd_calc_ssim, 10,
+                         kSsim_thresh),
+        MetricTestTParam(&vpx_calc_ssim, &vpx_highbd_calc_ssim, 12,
+                         kSsim_thresh)));
+}  // namespace
+
diff --git a/test/test.mk b/test/test.mk
index d6d08ff..7926cae 100644
--- a/test/test.mk
+++ b/test/test.mk
@@ -171,11 +171,12 @@
 endif # VP10
 
 ## Multi-codec / unconditional whitebox tests.
-
 ifeq ($(findstring yes,$(CONFIG_VP9_ENCODER)$(CONFIG_VP10_ENCODER)),yes)
 LIBVPX_TEST_SRCS-yes += avg_test.cc
 endif
-
+ifeq ($(CONFIG_INTERNAL_STATS),yes)
+LIBVPX_TEST_SRCS-$(CONFIG_VP9_HIGHBITDEPTH) += hbd_metrics_test.cc
+endif
 LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc
 LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_txfm_test.h
 LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_fwd_txfm1d_test.cc
diff --git a/vp10/common/vp10_fwd_txfm1d.c b/vp10/common/vp10_fwd_txfm1d.c
index 6e19e27..f3da5c9 100644
--- a/vp10/common/vp10_fwd_txfm1d.c
+++ b/vp10/common/vp10_fwd_txfm1d.c
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <stdlib.h>
 #include "vp10/common/vp10_fwd_txfm1d.h"
 #if CONFIG_COEFFICIENT_RANGE_CHECKING
 #define range_check(stage, input, buf, size, bit)                         \
@@ -24,7 +25,7 @@
           printf("%d,", input[j]);                                        \
         }                                                                 \
         printf("\n");                                                     \
-        assert(0, "vp10_fwd_txfm1d.c: range_check overflow");             \
+        assert(0);                                                        \
       }                                                                   \
     }                                                                     \
   }
diff --git a/vp10/common/vp10_inv_txfm1d.c b/vp10/common/vp10_inv_txfm1d.c
index b64b601..606ca55 100644
--- a/vp10/common/vp10_inv_txfm1d.c
+++ b/vp10/common/vp10_inv_txfm1d.c
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <stdlib.h>
 #include "vp10/common/vp10_inv_txfm1d.h"
 #if CONFIG_COEFFICIENT_RANGE_CHECKING
 #define range_check(stage, input, buf, size, bit)                         \
@@ -24,7 +25,7 @@
           printf("%d,", input[j]);                                        \
         }                                                                 \
         printf("\n");                                                     \
-        assert(0, "vp10_inv_txfm1d.c: range_check overflow");             \
+        assert(0);                                                        \
       }                                                                   \
     }                                                                     \
   }
diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c
index c99442b..ed56006 100644
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -3186,7 +3186,7 @@
 #if CONFIG_VAR_TX
           xd->above_txfm_context = cm->above_txfm_context + mi_col;
           xd->left_txfm_context =
-              xd->left_txfm_context_buffer + (mi_row & 0x07);
+              xd->left_txfm_context_buffer + (mi_row & MI_MASK);
           restore_context(x, mi_row, mi_col, a, l, sa, sl, ta, tl, bsize);
 #else
           restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -5210,6 +5210,11 @@
   ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
 #endif  // CONFIG_EXT_TX
   for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
+#if CONFIG_VAR_TX
+    ENTROPY_CONTEXT ctxa[16], ctxl[16];
+    const struct macroblockd_plane *const pd = &xd->plane[0];
+    int coeff_ctx = 1;
+#endif  // CONFIG_VAR_TX
 #if CONFIG_EXT_TX
     if (!ext_tx_used_inter[ext_tx_set][tx_type])
       continue;
@@ -5223,12 +5228,23 @@
       continue;
 #endif  // CONFIG_EXT_TX
     mbmi->tx_type = tx_type;
-    vp10_txfm_rd_in_plane_supertx(x,
+
 #if CONFIG_VAR_TX
-                                  cpi,
-#endif
-                                  &this_rate, &this_dist, &pnskip,
+    this_rate = 0;
+    this_dist = 0;
+    pnsse = 0;
+    pnskip = 1;
+
+    vp10_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
+    coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
+    vp10_tx_block_rd_b(cpi, x, tx_size,
+                       0, 0, 0, 0,
+                       bsize, coeff_ctx,
+                       &this_rate, &this_dist, &pnsse, &pnskip);
+#else
+    vp10_txfm_rd_in_plane_supertx(x, &this_rate, &this_dist, &pnskip,
                                   &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
+#endif  // CONFIG_VAR_TX
 
 #if CONFIG_EXT_TX
     if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index f92b964..9e29ce6 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -2314,10 +2314,10 @@
 }
 
 #if CONFIG_VAR_TX
-static void tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
-                          int blk_row, int blk_col, int plane, int block,
-                          int plane_bsize, int coeff_ctx,
-                          int *rate, int64_t *dist, int64_t *bsse, int *skip) {
+void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
+                        int blk_row, int blk_col, int plane, int block,
+                        int plane_bsize, int coeff_ctx,
+                        int *rate, int64_t *dist, int64_t *bsse, int *skip) {
   MACROBLOCKD *xd = &x->e_mbd;
   const struct macroblock_plane *const p = &x->plane[plane];
   struct macroblockd_plane *const pd = &xd->plane[plane];
@@ -2528,8 +2528,8 @@
 
   if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
     mbmi->inter_tx_size[tx_idx] = tx_size;
-    tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
-                  plane_bsize, coeff_ctx, rate, dist, bsse, skip);
+    vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
+                       plane_bsize, coeff_ctx, rate, dist, bsse, skip);
 
     if ((RDCOST(x->rdmult, x->rddiv, *rate, *dist) >=
          RDCOST(x->rdmult, x->rddiv, zero_blk_rate, *bsse) || *skip == 1) &&
@@ -2860,8 +2860,8 @@
         break;
     }
     coeff_ctx = combine_entropy_contexts(ta[0], tl[0]);
-    tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
-                  plane_bsize, coeff_ctx, rate, dist, bsse, skip);
+    vp10_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
+                       plane_bsize, coeff_ctx, rate, dist, bsse, skip);
     for (i = 0; i < (1 << tx_size); ++i) {
       ta[i] = !(p->eobs[block] == 0);
       tl[i] = !(p->eobs[block] == 0);
diff --git a/vp10/encoder/rdopt.h b/vp10/encoder/rdopt.h
index 62b0aea..a6394fa 100644
--- a/vp10/encoder/rdopt.h
+++ b/vp10/encoder/rdopt.h
@@ -74,6 +74,13 @@
                                     int64_t best_rd_so_far);
 
 #if CONFIG_SUPERTX
+#if CONFIG_VAR_TX
+void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
+                        int blk_row, int blk_col, int plane, int block,
+                        int plane_bsize, int coeff_ctx,
+                        int *rate, int64_t *dist, int64_t *bsse, int *skip);
+#endif
+
 void vp10_txfm_rd_in_plane_supertx(MACROBLOCK *x,
 #if CONFIG_VAR_TX
                                    const VP10_COMP *cpi,