Merge "Add protection for codec interface name change."
diff --git a/test/tools_common.sh b/test/tools_common.sh
index 27785c3..34c1516 100755
--- a/test/tools_common.sh
+++ b/test/tools_common.sh
@@ -401,6 +401,7 @@
 VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf"
 
 VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm"
+VP9_FPM_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-07-frame_parallel-1.webm"
 
 YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv"
 YUV_RAW_INPUT_WIDTH=352
diff --git a/test/vpxdec.sh b/test/vpxdec.sh
index f92acbd..d73a447 100755
--- a/test/vpxdec.sh
+++ b/test/vpxdec.sh
@@ -16,7 +16,8 @@
 
 # Environment check: Make sure input is available.
 vpxdec_verify_environment() {
-  if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_WEBM_FILE}" ]; then
+  if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_WEBM_FILE}" ] || \
+    [ ! -e "${VP9_FPM_WEBM_FILE}" ] ; then
     elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
     return 1
   fi
@@ -78,8 +79,20 @@
   fi
 }
 
+vpxdec_vp9_webm_frame_parallel() {
+  if [ "$(vpxdec_can_decode_vp9)" = "yes" ] && \
+     [ "$(webm_io_available)" = "yes" ]; then
+    for threads in 2 3 4 5 6 7 8; do
+      vpxdec "${VP9_FPM_WEBM_FILE}" --summary --noblit --threads=$threads \
+        --frame-parallel
+    done
+  fi
+
+}
+
 vpxdec_tests="vpxdec_vp8_ivf
               vpxdec_vp8_ivf_pipe_input
-              vpxdec_vp9_webm"
+              vpxdec_vp9_webm
+              vpxdec_vp9_webm_frame_parallel"
 
 run_tests vpxdec_verify_environment "${vpxdec_tests}"
diff --git a/usage.dox b/usage.dox
index 6bfca3b..8823520 100644
--- a/usage.dox
+++ b/usage.dox
@@ -12,13 +12,13 @@
     - \ref usage_init
     - \ref usage_errors
 
-    Fore more information on decoder and encoder specific usage, see the
+    For more information on decoder and encoder specific usage, see the
     following pages:
     \if decoder
-    - \subpage usage_decode
+    \li \subpage usage_decode
     \endif
-    \if decoder
-    - \subpage usage_encode
+    \if encoder
+    \li \subpage usage_encode
     \endif
 
     \section usage_types Important Data Types
@@ -81,12 +81,12 @@
 
     The available initialization methods are:
     \if encoder
-     - #vpx_codec_enc_init (calls vpx_codec_enc_init_ver())
-     - #vpx_codec_enc_init_multi (calls vpx_codec_enc_init_multi_ver())
-     .
+    \li #vpx_codec_enc_init (calls vpx_codec_enc_init_ver())
+    \li #vpx_codec_enc_init_multi (calls vpx_codec_enc_init_multi_ver())
     \endif
-    \if decoder - #vpx_codec_dec_init (calls vpx_codec_dec_init_ver()) \endif
-
+    \if decoder
+    \li #vpx_codec_dec_init (calls vpx_codec_dec_init_ver())
+    \endif
 
 
     \section usage_errors Error Handling
diff --git a/usage_cx.dox b/usage_cx.dox
index 62f3e45..92b0d34 100644
--- a/usage_cx.dox
+++ b/usage_cx.dox
@@ -1,4 +1,4 @@
-/*! \page usage_encode Encode
+/*! \page usage_encode Encoding
 
     The vpx_codec_encode() function is at the core of the encode loop. It
     processes raw images passed by the application, producing packets of
diff --git a/vp9/encoder/vp9_avg.c b/vp9/encoder/vp9_avg.c
index 90d113c..dc5cfe2 100644
--- a/vp9/encoder/vp9_avg.c
+++ b/vp9/encoder/vp9_avg.c
@@ -46,10 +46,9 @@
 int16_t vp9_int_pro_col_c(uint8_t const *ref, const int width) {
   int idx;
   int16_t sum = 0;
-  const int norm_factor = MAX(8, width >> 1);
   for (idx = 0; idx < width; ++idx)
     sum += ref[idx];
-  return sum / norm_factor;
+  return sum;
 }
 
 int vp9_vector_var_c(int16_t const *ref, int16_t const *src,
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 1344b5b..ac9de21 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -44,12 +44,6 @@
 #include "vp9/encoder/vp9_segmentation.h"
 #include "vp9/encoder/vp9_tokenize.h"
 
-#define GF_ZEROMV_ZBIN_BOOST 0
-#define LF_ZEROMV_ZBIN_BOOST 0
-#define MV_ZBIN_BOOST        0
-#define SPLIT_MV_ZBIN_BOOST  0
-#define INTRA_ZBIN_BOOST     0
-
 static void encode_superblock(VP9_COMP *cpi, ThreadData * td,
                               TOKENEXTRA **t, int output_enabled,
                               int mi_row, int mi_col, BLOCK_SIZE bsize,
@@ -406,7 +400,7 @@
                                int mi_col,
                                int64_t threshold,
                                BLOCK_SIZE bsize_min,
-                               int segment_id) {
+                               int force_split) {
   VP9_COMMON * const cm = &cpi->common;
   variance_node vt;
   const int block_width = num_8x8_blocks_wide_lookup[bsize];
@@ -415,8 +409,7 @@
   assert(block_height == block_width);
   tree_to_node(data, bsize, &vt);
 
-  // No 64x64 blocks on segments other than base (un-boosted) segment.
-  if (cyclic_refresh_segment_id_boosted(segment_id) && bsize == BLOCK_64X64)
+  if (force_split)
     return 0;
 
   // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
@@ -432,7 +425,9 @@
     }
     return 0;
   } else if (bsize > bsize_min) {
-    get_variance(&vt.part_variances->none);
+    // Variance is already computed for 32x32 blocks to set the force_split.
+    if (bsize != BLOCK_32X32)
+      get_variance(&vt.part_variances->none);
     // For key frame or low_res: for bsize above 32X32 or very high variance,
     // take split.
     if (cm->frame_type == KEY_FRAME &&
@@ -486,32 +481,34 @@
     return;
   } else {
     VP9_COMMON *const cm = &cpi->common;
-    const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     const int is_key_frame = (cm->frame_type == KEY_FRAME);
-    const int use_4x4_partition = is_key_frame;
-    const int low_res = (cm->width <= 352 && cm->height <= 288);
     const int threshold_multiplier = is_key_frame ? 80 : 4;
     const int64_t threshold_base = (int64_t)(threshold_multiplier *
         vp9_convert_qindex_to_q(q, cm->bit_depth));
-    cpi->vbp_threshold = threshold_base;
-    cpi->vbp_threshold_bsize_min = threshold_base << oxcf->speed;
-    cpi->vbp_threshold_bsize_max = threshold_base;
 
-    if (is_key_frame) {
-      cpi->vbp_threshold = threshold_base >> 2;
-      cpi->vbp_threshold_bsize_min = threshold_base << 2;
-    } else if (low_res) {
-      cpi->vbp_threshold_bsize_min = threshold_base << 3;
-      cpi->vbp_threshold_bsize_max = threshold_base >> 2;
-    }
     // TODO(marpan): Allow 4x4 partitions for inter-frames.
     // use_4x4_partition = (variance4x4downsample[i2 + j] == 1);
     // If 4x4 partition is not used, then 8x8 partition will be selected
     // if variance of 16x16 block is very high, so use larger threshold
     // for 16x16 (threshold_bsize_min) in that case.
-    cpi->vbp_threshold_16x16 = (use_4x4_partition) ?
-      cpi->vbp_threshold : cpi->vbp_threshold_bsize_min;
-    cpi->vbp_bsize_min = (use_4x4_partition) ? BLOCK_8X8 : BLOCK_16X16;
+    if (is_key_frame) {
+      cpi->vbp_threshold = threshold_base >> 2;
+      cpi->vbp_threshold_bsize_max = threshold_base;
+      cpi->vbp_threshold_bsize_min = threshold_base << 2;
+      cpi->vbp_threshold_16x16 = cpi->vbp_threshold;
+      cpi->vbp_bsize_min = BLOCK_8X8;
+    } else {
+      cpi->vbp_threshold = threshold_base;
+      if (cm->width <= 352 && cm->height <= 288) {
+        cpi->vbp_threshold_bsize_max = threshold_base >> 2;
+        cpi->vbp_threshold_bsize_min = threshold_base << 3;
+      } else {
+        cpi->vbp_threshold_bsize_max = threshold_base;
+        cpi->vbp_threshold_bsize_min = threshold_base << cpi->oxcf.speed;
+      }
+      cpi->vbp_threshold_16x16 = cpi->vbp_threshold_bsize_min;
+      cpi->vbp_bsize_min = BLOCK_16X16;
+    }
   }
 }
 
@@ -526,6 +523,7 @@
   int i, j, k, m;
   v64x64 vt;
   v16x16 vt2[16];
+  int force_split[5];
   uint8_t *s;
   const uint8_t *d;
   int sp;
@@ -643,12 +641,15 @@
 #endif  // CONFIG_VP9_HIGHBITDEPTH
   }
 
+  // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks,
+  force_split[0] = 0;
   // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances
   // for splits.
   for (i = 0; i < 4; i++) {
     const int x32_idx = ((i & 1) << 5);
     const int y32_idx = ((i >> 1) << 5);
     const int i2 = i << 2;
+    force_split[i + 1] = 0;
     for (j = 0; j < 4; j++) {
       const int x16_idx = x32_idx + ((j & 1) << 4);
       const int y16_idx = y32_idx + ((j >> 1) << 4);
@@ -735,6 +736,11 @@
     }
   }
 
+  // No 64x64 blocks on segments other than base (un-boosted) segment,
+  // so force split.
+  if (cyclic_refresh_segment_id_boosted(segment_id))
+    force_split[0] = 1;
+
   // Fill the rest of the variance tree by summing split partition values.
   for (i = 0; i < 4; i++) {
     const int i2 = i << 2;
@@ -742,22 +748,29 @@
       if (variance4x4downsample[i2 + j] == 1) {
         v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] :
             &vt.split[i].split[j];
-        for (m = 0; m < 4; m++) {
+        for (m = 0; m < 4; m++)
           fill_variance_tree(&vtemp->split[m], BLOCK_8X8);
-        }
         fill_variance_tree(vtemp, BLOCK_16X16);
       }
     }
     fill_variance_tree(&vt.split[i], BLOCK_32X32);
+    // If variance of this 32x32 block is above the threshold, force the block
+    // to split. This also forces a split on the upper (64x64) level.
+    get_variance(&vt.split[i].part_variances.none);
+    if (vt.split[i].part_variances.none.variance > cpi->vbp_threshold) {
+      force_split[i + 1] = 1;
+      force_split[0] = 1;
+    }
   }
-  fill_variance_tree(&vt, BLOCK_64X64);
+  if (!force_split[0])
+    fill_variance_tree(&vt, BLOCK_64X64);
 
   // Now go through the entire structure,  splitting every block size until
   // we get to one that's got a variance lower than our threshold.
   if ( mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows ||
       !set_vt_partitioning(cpi, xd, &vt, BLOCK_64X64, mi_row, mi_col,
                            cpi->vbp_threshold_bsize_max, BLOCK_16X16,
-                           segment_id)) {
+                           force_split[0])) {
     for (i = 0; i < 4; ++i) {
       const int x32_idx = ((i & 1) << 2);
       const int y32_idx = ((i >> 1) << 2);
@@ -765,7 +778,7 @@
       if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32,
                                (mi_row + y32_idx), (mi_col + x32_idx),
                                cpi->vbp_threshold,
-                               BLOCK_16X16, segment_id)) {
+                               BLOCK_16X16, force_split[i + 1])) {
         for (j = 0; j < 4; ++j) {
           const int x16_idx = ((j & 1) << 1);
           const int y16_idx = ((j >> 1) << 1);
@@ -779,7 +792,7 @@
                                    mi_row + y32_idx + y16_idx,
                                    mi_col + x32_idx + x16_idx,
                                    cpi->vbp_threshold_16x16,
-                                   cpi->vbp_bsize_min, segment_id)) {
+                                   cpi->vbp_bsize_min, 0)) {
             for (k = 0; k < 4; ++k) {
               const int x8_idx = (k & 1);
               const int y8_idx = (k >> 1);
@@ -789,7 +802,7 @@
                                          mi_row + y32_idx + y16_idx + y8_idx,
                                          mi_col + x32_idx + x16_idx + x8_idx,
                                          cpi->vbp_threshold_bsize_min,
-                                         BLOCK_8X8, segment_id)) {
+                                         BLOCK_8X8, 0)) {
                   set_block_size(cpi, xd,
                                  (mi_row + y32_idx + y16_idx + y8_idx),
                                  (mi_col + x32_idx + x16_idx + x8_idx),
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index 88c5ca0..9602eb5 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1805,6 +1805,7 @@
   MV *tmp_mv = &xd->mi[0].src_mi->mbmi.mv[0].as_mv;
   unsigned int best_sad, tmp_sad, this_sad[4];
   MV this_mv;
+  const int norm_factor = 3 + (bw >> 5);
 
 #if CONFIG_VP9_HIGHBITDEPTH
   tmp_mv->row = 0;
@@ -1822,7 +1823,7 @@
 
   ref_buf = xd->plane[0].pre[0].buf - (bh >> 1) * ref_stride;
   for (idx = 0; idx < search_height; ++idx) {
-    vbuf[idx] = vp9_int_pro_col(ref_buf, bw);
+    vbuf[idx] = vp9_int_pro_col(ref_buf, bw) >> norm_factor;
     ref_buf += ref_stride;
   }
 
@@ -1834,7 +1835,7 @@
 
   src_buf = x->plane[0].src.buf;
   for (idx = 0; idx < bh; ++idx) {
-    src_vbuf[idx] = vp9_int_pro_col(src_buf, bw);
+    src_vbuf[idx] = vp9_int_pro_col(src_buf, bw) >> norm_factor;
     src_buf += src_stride;
   }
 
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 5bc9fca..7c1a930 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -615,9 +615,9 @@
 static const REF_MODE ref_mode_set[RT_INTER_MODES] = {
     {LAST_FRAME, ZEROMV},
     {LAST_FRAME, NEARESTMV},
+    {GOLDEN_FRAME, ZEROMV},
     {LAST_FRAME, NEARMV},
     {LAST_FRAME, NEWMV},
-    {GOLDEN_FRAME, ZEROMV},
     {GOLDEN_FRAME, NEARESTMV},
     {GOLDEN_FRAME, NEARMV},
     {GOLDEN_FRAME, NEWMV}
@@ -755,8 +755,6 @@
       vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
                             &frame_mv[NEARESTMV][ref_frame],
                             &frame_mv[NEARMV][ref_frame]);
-      clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
-      clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);
 
       if (!vp9_is_scaled(sf) && bsize >= BLOCK_8X8)
         vp9_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
@@ -803,9 +801,6 @@
       continue;
 
     if (this_mode == NEWMV) {
-      if (cpi->sf.partition_search_type != VAR_BASED_PARTITION
-          && best_rdc.rdcost < (int64_t) (1 << num_pels_log2_lookup[bsize]))
-        continue;
       if (ref_frame > LAST_FRAME) {
         int tmp_sad;
         int dis, cost_list[5];
@@ -840,8 +835,9 @@
       }
     }
 
-    if (this_mode != NEARESTMV && frame_mv[this_mode][ref_frame].as_int ==
-        frame_mv[NEARESTMV][ref_frame].as_int)
+    if (this_mode != NEARESTMV &&
+        frame_mv[this_mode][ref_frame].as_int ==
+            frame_mv[NEARESTMV][ref_frame].as_int)
       continue;
 
     mbmi->mode = this_mode;
@@ -905,11 +901,11 @@
         free_pred_buffer(current_pred);
 
       mbmi->interp_filter = best_filter;
-      mbmi->tx_size = pf_tx_size[mbmi->interp_filter];
-      this_rdc.rate = pf_rate[mbmi->interp_filter];
-      this_rdc.dist = pf_dist[mbmi->interp_filter];
-      var_y = pf_var[mbmi->interp_filter];
-      sse_y = pf_sse[mbmi->interp_filter];
+      mbmi->tx_size = pf_tx_size[best_filter];
+      this_rdc.rate = pf_rate[best_filter];
+      this_rdc.dist = pf_dist[best_filter];
+      var_y = pf_var[best_filter];
+      sse_y = pf_sse[best_filter];
       x->skip_txfm[0] = skip_txfm;
     } else {
       mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP : filter_ref;
diff --git a/vp9/encoder/x86/vp9_avg_intrin_sse2.c b/vp9/encoder/x86/vp9_avg_intrin_sse2.c
index 618b5f7..4e80b255e 100644
--- a/vp9/encoder/x86/vp9_avg_intrin_sse2.c
+++ b/vp9/encoder/x86/vp9_avg_intrin_sse2.c
@@ -112,7 +112,6 @@
   __m128i s0 = _mm_sad_epu8(src_line, zero);
   __m128i s1;
   int i;
-  const int norm_factor = 3 + (width >> 5);
 
   for (i = 16; i < width; i += 16) {
     ref += 16;
@@ -124,7 +123,7 @@
   s1 = _mm_srli_si128(s0, 8);
   s0 = _mm_adds_epu16(s0, s1);
 
-  return _mm_extract_epi16(s0, 0) >> norm_factor;
+  return _mm_extract_epi16(s0, 0);
 }
 
 int vp9_vector_var_sse2(int16_t const *ref, int16_t const *src,
diff --git a/vpxdec.c b/vpxdec.c
index 59c982d..62a5e93 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -75,6 +75,8 @@
     "o", "output", 1, "Output file name pattern (see below)");
 static const arg_def_t threadsarg = ARG_DEF(
     "t", "threads", 1, "Max threads to use");
+static const arg_def_t frameparallelarg = ARG_DEF(
+    NULL, "frame-parallel", 0, "Frame parallel decode");
 static const arg_def_t verbosearg = ARG_DEF(
     "v", "verbose", 0, "Show version string");
 static const arg_def_t error_concealment = ARG_DEF(
@@ -95,7 +97,7 @@
 static const arg_def_t *all_args[] = {
   &codecarg, &use_yv12, &use_i420, &flipuvarg, &rawvideo, &noblitarg,
   &progressarg, &limitarg, &skiparg, &postprocarg, &summaryarg, &outputfile,
-  &threadsarg, &verbosearg, &scalearg, &fb_arg,
+  &threadsarg, &frameparallelarg, &verbosearg, &scalearg, &fb_arg,
   &md5arg, &error_concealment, &continuearg,
 #if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
   &outbitdeptharg,
@@ -542,7 +544,7 @@
   size_t                 bytes_in_buffer = 0, buffer_size = 0;
   FILE                  *infile;
   int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
-  int                    do_md5 = 0, progress = 0;
+  int                    do_md5 = 0, progress = 0, frame_parallel = 0;
   int                    stop_after = 0, postproc = 0, summary = 0, quiet = 1;
   int                    arg_skip = 0;
   int                    ec_enabled = 0;
@@ -575,7 +577,7 @@
 #if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
   vpx_image_t             *img_shifted = NULL;
 #endif
-  int                     frame_avail, got_data;
+  int                     frame_avail, got_data, flush_decoder = 0;
   int                     num_external_frame_buffers = 0;
   struct ExternalFrameBufferList ext_fb_list = {0, NULL};
 
@@ -642,6 +644,10 @@
       summary = 1;
     else if (arg_match(&arg, &threadsarg, argi))
       cfg.threads = arg_parse_uint(&arg);
+#if CONFIG_VP9_DECODER
+    else if (arg_match(&arg, &frameparallelarg, argi))
+      frame_parallel = 1;
+#endif
     else if (arg_match(&arg, &verbosearg, argi))
       quiet = 0;
     else if (arg_match(&arg, &scalearg, argi))
@@ -794,7 +800,8 @@
     interface = get_vpx_decoder_by_index(0);
 
   dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
-              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
+              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0) |
+              (frame_parallel ? VPX_CODEC_USE_FRAME_THREADING : 0);
   if (vpx_codec_dec_init(&decoder, interface->codec_interface(),
                          &cfg, dec_flags)) {
     fprintf(stderr, "Failed to initialize decoder: %s\n",
@@ -892,11 +899,22 @@
 
         vpx_usec_timer_mark(&timer);
         dx_time += vpx_usec_timer_elapsed(&timer);
+      } else {
+        flush_decoder = 1;
       }
+    } else {
+      flush_decoder = 1;
     }
 
     vpx_usec_timer_start(&timer);
 
+    if (flush_decoder) {
+      // Flush the decoder in frame parallel decode.
+      if (vpx_codec_decode(&decoder, NULL, 0, NULL, 0)) {
+        warn("Failed to flush decoder: %s", vpx_codec_error(&decoder));
+      }
+    }
+
     got_data = 0;
     if ((img = vpx_codec_get_frame(&decoder, &iter))) {
       ++frame_out;
@@ -906,7 +924,8 @@
     vpx_usec_timer_mark(&timer);
     dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
 
-    if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
+    if (!frame_parallel &&
+        vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
       warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
       if (!keep_going)
         goto fail;