Merge "Remove the vp8_vpxyv12_copy_y_neon."
diff --git a/build/make/thumb.pm b/build/make/thumb.pm
index 9604c8e..483c253 100644
--- a/build/make/thumb.pm
+++ b/build/make/thumb.pm
@@ -51,7 +51,7 @@
 
     # Convert register post indexing to a separate add instruction.
     # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]",
-    # "add r0, r2".
+    # "addne r0, r0, r2".
     s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g;
 
     # Convert a conditional addition to the pc register into a series of
diff --git a/configure b/configure
index 170bd8d..fea9129 100755
--- a/configure
+++ b/configure
@@ -51,6 +51,7 @@
   ${toggle_postproc_visualizer}   macro block / block level visualizers
   ${toggle_multi_res_encoding}    enable multiple-resolution encoding
   ${toggle_temporal_denoising}    enable temporal denoising and disable the spatial denoiser
+  ${toggle_webm_io}               enable input from and output to WebM container
 
 Codecs:
   Codecs can be selectively enabled or disabled individually, or by family:
@@ -314,6 +315,7 @@
     postproc_visualizer
     os_support
     unit_tests
+    webm_io
     decode_perf_tests
     multi_res_encoding
     temporal_denoising
@@ -367,6 +369,7 @@
     small
     postproc_visualizer
     unit_tests
+    webm_io
     decode_perf_tests
     multi_res_encoding
     temporal_denoising
@@ -704,6 +707,9 @@
         enabled postproc || die "postproc_visualizer requires postproc to be enabled"
     fi
 
+    # Enable WebM IO by default.
+    soft_enable webm_io
+
     # Enable unit tests by default if we have a working C++ compiler.
     case "$toolchain" in
         *-vs*)
diff --git a/examples.mk b/examples.mk
index 7ec1a8e..87be5a8 100644
--- a/examples.mk
+++ b/examples.mk
@@ -26,16 +26,18 @@
 vpxdec.SRCS                 += args.c args.h
 vpxdec.SRCS                 += ivfdec.c ivfdec.h
 vpxdec.SRCS                 += tools_common.c tools_common.h
-vpxdec.SRCS                 += webmdec.c webmdec.h
 vpxdec.SRCS                 += y4menc.c y4menc.h
-vpxdec.SRCS                 += third_party/nestegg/halloc/halloc.h
-vpxdec.SRCS                 += third_party/nestegg/halloc/src/align.h
-vpxdec.SRCS                 += third_party/nestegg/halloc/src/halloc.c
-vpxdec.SRCS                 += third_party/nestegg/halloc/src/hlist.h
-vpxdec.SRCS                 += third_party/nestegg/halloc/src/macros.h
-vpxdec.SRCS                 += third_party/nestegg/include/nestegg/nestegg.h
-vpxdec.SRCS                 += third_party/nestegg/src/nestegg.c
 vpxdec.SRCS                 += $(LIBYUV_SRCS)
+ifeq ($(CONFIG_WEBM_IO),yes)
+  vpxdec.SRCS                 += third_party/nestegg/halloc/halloc.h
+  vpxdec.SRCS                 += third_party/nestegg/halloc/src/align.h
+  vpxdec.SRCS                 += third_party/nestegg/halloc/src/halloc.c
+  vpxdec.SRCS                 += third_party/nestegg/halloc/src/hlist.h
+  vpxdec.SRCS                 += third_party/nestegg/halloc/src/macros.h
+  vpxdec.SRCS                 += third_party/nestegg/include/nestegg/nestegg.h
+  vpxdec.SRCS                 += third_party/nestegg/src/nestegg.c
+  vpxdec.SRCS                 += webmdec.c webmdec.h
+endif
 vpxdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
 vpxdec.DESCRIPTION           = Full featured decoder
 UTILS-$(CONFIG_ENCODERS)    += vpxenc.c
@@ -45,15 +47,17 @@
 vpxenc.SRCS                 += rate_hist.c rate_hist.h
 vpxenc.SRCS                 += tools_common.c tools_common.h
 vpxenc.SRCS                 += warnings.c warnings.h
-vpxenc.SRCS                 += webmenc.c webmenc.h
 vpxenc.SRCS                 += vpx_ports/mem_ops.h
 vpxenc.SRCS                 += vpx_ports/mem_ops_aligned.h
 vpxenc.SRCS                 += vpx_ports/vpx_timer.h
 vpxenc.SRCS                 += vpxstats.c vpxstats.h
-vpxenc.SRCS                 += third_party/libmkv/EbmlIDs.h
-vpxenc.SRCS                 += third_party/libmkv/EbmlWriter.c
-vpxenc.SRCS                 += third_party/libmkv/EbmlWriter.h
 vpxenc.SRCS                 += $(LIBYUV_SRCS)
+ifeq ($(CONFIG_WEBM_IO),yes)
+  vpxenc.SRCS                 += third_party/libmkv/EbmlIDs.h
+  vpxenc.SRCS                 += third_party/libmkv/EbmlWriter.c
+  vpxenc.SRCS                 += third_party/libmkv/EbmlWriter.h
+  vpxenc.SRCS                 += webmenc.c webmenc.h
+endif
 vpxenc.GUID                  = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
 vpxenc.DESCRIPTION           = Full featured encoder
 EXAMPLES-$(CONFIG_VP9_ENCODER)    += vp9_spatial_scalable_encoder.c
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 1609d58..ebb9d22 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -2660,14 +2660,6 @@
   mbmi->segment_id = 0;
 }
 
-static INLINE int get_block_row(int b32i, int b16i, int b8i) {
-  return ((b32i >> 1) << 2) + ((b16i >> 1) << 1) + (b8i >> 1);
-}
-
-static INLINE int get_block_col(int b32i, int b16i, int b8i) {
-  return ((b32i & 1) << 2) + ((b16i & 1) << 1) + (b8i & 1);
-}
-
 static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
                                 int mi_row, int mi_col,
                                 int *rate, int64_t *dist,
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index 1b28dee..2ae8a2a 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1014,14 +1014,11 @@
   const int in_what_stride = xd->plane[0].pre[0].stride;
   const uint8_t *best_address;
 
-  MV this_mv;
-
   int bestsad = INT_MAX;
   int best_site = 0;
   int last_site = 0;
 
   int ref_row, ref_col;
-  int this_row_offset, this_col_offset;
 
   // search_param determines the length of the initial step and hence the number
   // of iterations
@@ -1030,7 +1027,6 @@
   const search_site *const ss = &x->ss[search_param * x->searches_per_step];
   const int tot_steps = (x->ss_count / x->searches_per_step) - search_param;
 
-  int thissad;
   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
 
   const int *mvjsadcost = x->nmvjointsadcost;
@@ -1056,21 +1052,14 @@
 
   for (step = 0; step < tot_steps; step++) {
     for (j = 0; j < x->searches_per_step; j++) {
-      // Trap illegal vectors
-      this_row_offset = best_mv->row + ss[i].mv.row;
-      this_col_offset = best_mv->col + ss[i].mv.col;
-
-      if ((this_col_offset > x->mv_col_min) &&
-          (this_col_offset < x->mv_col_max) &&
-          (this_row_offset > x->mv_row_min) &&
-          (this_row_offset < x->mv_row_max)) {
+      const MV this_mv = {best_mv->row + ss[i].mv.row,
+                          best_mv->col + ss[i].mv.col};
+      if (is_mv_in(x, &this_mv)) {
         const uint8_t *const check_here = ss[i].offset + best_address;
-        thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
+        int thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
                               bestsad);
 
         if (thissad < bestsad) {
-          this_mv.row = this_row_offset;
-          this_mv.col = this_col_offset;
           thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
                                     mvjsadcost, mvsadcost, sad_per_bit);
 
@@ -1091,18 +1080,13 @@
       last_site = best_site;
 #if defined(NEW_DIAMOND_SEARCH)
       while (1) {
-        this_row_offset = best_mv->row + ss[best_site].mv.row;
-        this_col_offset = best_mv->col + ss[best_site].mv.col;
-        if ((this_col_offset > x->mv_col_min) &&
-            (this_col_offset < x->mv_col_max) &&
-            (this_row_offset > x->mv_row_min) &&
-            (this_row_offset < x->mv_row_max)) {
-          check_here = ss[best_site].offset + best_address;
-          thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
-                                bestsad);
+        const MV this_mv = {best_mv->row + ss[best_site].mv.row,
+                            best_mv->col + ss[best_site].mv.col};
+        if (is_mv_in(x, &this_mv)) {
+          const uint8_t *const check_here = ss[best_site].offset + best_address;
+          int thissad = fn_ptr->sdf(what, what_stride, check_here,
+                                    in_what_stride, bestsad);
           if (thissad < bestsad) {
-            this_mv.row = this_row_offset;
-            this_mv.col = this_col_offset;
             thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
                                       mvjsadcost, mvsadcost, sad_per_bit);
             if (thissad < bestsad) {
@@ -1139,16 +1123,12 @@
   const int in_what_stride = xd->plane[0].pre[0].stride;
   const uint8_t *best_address;
 
-  MV this_mv;
-
   unsigned int bestsad = INT_MAX;
   int best_site = 0;
   int last_site = 0;
 
   int ref_row;
   int ref_col;
-  int this_row_offset;
-  int this_col_offset;
 
   // search_param determines the length of the initial step and hence the number
   // of iterations.
@@ -1158,7 +1138,6 @@
   const search_site *ss = &x->ss[search_param * x->searches_per_step];
   const int tot_steps = (x->ss_count / x->searches_per_step) - search_param;
 
-  unsigned int thissad;
   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
 
   const int *mvjsadcost = x->nmvjointsadcost;
@@ -1209,8 +1188,8 @@
 
         for (t = 0; t < 4; t++, i++) {
           if (sad_array[t] < bestsad) {
-            this_mv.row = best_mv->row + ss[i].mv.row;
-            this_mv.col = best_mv->col + ss[i].mv.col;
+            const MV this_mv = {best_mv->row + ss[i].mv.row,
+                                best_mv->col + ss[i].mv.col};
             sad_array[t] += mvsad_err_cost(&this_mv, &fcenter_mv,
                                            mvjsadcost, mvsadcost, sad_per_bit);
 
@@ -1224,20 +1203,15 @@
     } else {
       for (j = 0; j < x->searches_per_step; j++) {
         // Trap illegal vectors
-        this_row_offset = best_mv->row + ss[i].mv.row;
-        this_col_offset = best_mv->col + ss[i].mv.col;
+        const MV this_mv = {best_mv->row + ss[i].mv.row,
+                            best_mv->col + ss[i].mv.col};
 
-        if ((this_col_offset > x->mv_col_min) &&
-            (this_col_offset < x->mv_col_max) &&
-            (this_row_offset > x->mv_row_min) &&
-            (this_row_offset < x->mv_row_max)) {
+        if (is_mv_in(x, &this_mv)) {
           const uint8_t *const check_here = ss[i].offset + best_address;
-          thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
-                                bestsad);
+          unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here,
+                                             in_what_stride, bestsad);
 
           if (thissad < bestsad) {
-            this_mv.row = this_row_offset;
-            this_mv.col = this_col_offset;
             thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
                                       mvjsadcost, mvsadcost, sad_per_bit);
 
@@ -1257,18 +1231,13 @@
       last_site = best_site;
 #if defined(NEW_DIAMOND_SEARCH)
       while (1) {
-        this_row_offset = best_mv->row + ss[best_site].mv.row;
-        this_col_offset = best_mv->col + ss[best_site].mv.col;
-        if ((this_col_offset > x->mv_col_min) &&
-            (this_col_offset < x->mv_col_max) &&
-            (this_row_offset > x->mv_row_min) &&
-            (this_row_offset < x->mv_row_max)) {
-          check_here = ss[best_site].offset + best_address;
-          thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride,
-                                bestsad);
+        const MV this_mv = {best_mv->row + ss[best_site].mv.row,
+                            best_mv->col + ss[best_site].mv.col};
+        if (is_mv_in(x, &this_mv)) {
+          const uint8_t *const check_here = ss[best_site].offset + best_address;
+          unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here,
+                                             in_what_stride, bestsad);
           if (thissad < bestsad) {
-            this_mv.row = this_row_offset;
-            this_mv.col = this_col_offset;
             thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
                                       mvjsadcost, mvsadcost, sad_per_bit);
             if (thissad < bestsad) {
diff --git a/vpxdec.c b/vpxdec.c
index b69e55e..4c37234 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -218,9 +218,11 @@
 static int read_frame(struct VpxDecInputContext *input, uint8_t **buf,
                       size_t *bytes_in_buffer, size_t *buffer_size) {
   switch (input->vpx_input_ctx->file_type) {
+#if CONFIG_WEBM_IO
     case FILE_TYPE_WEBM:
       return webm_read_frame(input->webm_ctx,
                              buf, bytes_in_buffer, buffer_size);
+#endif
     case FILE_TYPE_RAW:
       return raw_read_frame(input->vpx_input_ctx->file,
                             buf, bytes_in_buffer, buffer_size);
@@ -663,12 +665,17 @@
   input.vpx_input_ctx->file = infile;
   if (file_is_ivf(input.vpx_input_ctx))
     input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
+#if CONFIG_WEBM_IO
   else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
     input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
+#endif
   else if (file_is_raw(input.vpx_input_ctx))
     input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
   else {
     fprintf(stderr, "Unrecognized input file type.\n");
+#if !CONFIG_WEBM_IO
+    fprintf(stderr, "vpxdec was built without WebM container support.\n");
+#endif
     return EXIT_FAILURE;
   }
 
@@ -691,6 +698,7 @@
       return EXIT_FAILURE;
     }
 
+#if CONFIG_WEBM_IO
     if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
       if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
         fprintf(stderr, "Failed to guess framerate -- error parsing "
@@ -698,6 +706,7 @@
         return EXIT_FAILURE;
       }
     }
+#endif
   }
 
   fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
@@ -941,9 +950,12 @@
     }
   }
 
+#if CONFIG_WEBM_IO
   if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
     webm_free(input.webm_ctx);
-  else
+#endif
+
+  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM)
     free(buf);
 
   if (scaled_img) vpx_img_free(scaled_img);
diff --git a/vpxenc.c b/vpxenc.c
index c61d83e..1cd5e92 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -123,6 +123,7 @@
   return 0;
 }
 
+#if CONFIG_WEBM_IO
 /* Murmur hash derived from public domain reference implementation at
  *   http:// sites.google.com/site/murmurhash/
  */
@@ -169,7 +170,7 @@
 
   return h;
 }
-
+#endif  // CONFIG_WEBM_IO
 
 static const arg_def_t debugmode = ARG_DEF("D", "debug", 0,
                                            "Debug mode (makes output deterministic)");
@@ -218,7 +219,7 @@
 static const arg_def_t framerate        = ARG_DEF(NULL, "fps", 1,
                                                   "Stream frame rate (rate/scale)");
 static const arg_def_t use_ivf          = ARG_DEF(NULL, "ivf", 0,
-                                                  "Output IVF (default is WebM)");
+                                                  "Output IVF (default is WebM if WebM IO is enabled)");
 static const arg_def_t out_part = ARG_DEF("P", "output-partitions", 0,
                                           "Makes encoder output partitions. Requires IVF output!");
 static const arg_def_t q_hist_n         = ARG_DEF(NULL, "q-hist", 1,
@@ -834,7 +835,9 @@
     /* Initialize remaining stream parameters */
     stream->config.stereo_fmt = STEREO_FORMAT_MONO;
     stream->config.write_webm = 1;
+#if CONFIG_WEBM_IO
     stream->ebml.last_pts_ms = -1;
+#endif
 
     /* Allows removal of the application version from the EBML tags */
     stream->ebml.debug = global->debug;
@@ -1143,13 +1146,17 @@
   if (stream->config.write_webm && fseek(stream->file, 0, SEEK_CUR))
     fatal("WebM output to pipes not supported.");
 
+#if CONFIG_WEBM_IO
   if (stream->config.write_webm) {
     stream->ebml.stream = stream->file;
     write_webm_file_header(&stream->ebml, cfg,
                            &global->framerate,
                            stream->config.stereo_fmt,
                            global->codec->fourcc);
-  } else {
+  }
+#endif
+
+  if (!stream->config.write_webm) {
     ivf_write_file_header(stream->file, cfg, global->codec->fourcc, 0);
   }
 }
@@ -1162,11 +1169,15 @@
   if (cfg->g_pass == VPX_RC_FIRST_PASS)
     return;
 
+#if CONFIG_WEBM_IO
   if (stream->config.write_webm) {
     write_webm_file_footer(&stream->ebml, stream->hash);
     free(stream->ebml.cue_list);
     stream->ebml.cue_list = NULL;
-  } else {
+  }
+#endif
+
+  if (!stream->config.write_webm) {
     if (!fseek(stream->file, 0, SEEK_SET))
       ivf_write_file_header(stream->file, &stream->config.cfg,
                             fourcc,
@@ -1316,6 +1327,7 @@
           fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz);
 
         update_rate_histogram(stream->rate_hist, cfg, pkt);
+#if CONFIG_WEBM_IO
         if (stream->config.write_webm) {
           /* Update the hash */
           if (!stream->ebml.debug)
@@ -1324,7 +1336,9 @@
                                   stream->hash);
 
           write_webm_block(&stream->ebml, cfg, pkt);
-        } else {
+        }
+#endif
+        if (!stream->config.write_webm) {
           if (pkt->data.frame.partition_id <= 0) {
             ivf_header_pos = ftello(stream->file);
             fsize = pkt->data.frame.sz;
@@ -1594,6 +1608,14 @@
         " and --passes=2\n", stream->index, global.pass);
     });
 
+#if !CONFIG_WEBM_IO
+    FOREACH_STREAM({
+      stream->config.write_webm = 0;
+      warn("vpxenc was compiled without WebM container support."
+           "Producing IVF output");
+    });
+#endif
+
     /* Use the frame rate from the file only if none was specified
      * on the command-line.
      */