Merge changes I8e9692fc,Ifc06110c

* changes:
  vpx_fdctNxN_1_c: remove unnecessary store
  vpx_fdct32x32_1_c: fix accumulator overflow
diff --git a/vp10/encoder/resize.c b/vp10/encoder/resize.c
index e339fa3..353e513 100644
--- a/vp10/encoder/resize.c
+++ b/vp10/encoder/resize.c
@@ -445,7 +445,7 @@
                              int length,
                              uint8_t *output,
                              int olength,
-                             uint8_t *buf) {
+                             uint8_t *otmp) {
   int steps;
   if (length == olength) {
     memcpy(output, input, sizeof(output[0]) * length);
@@ -456,16 +456,10 @@
   if (steps > 0) {
     int s;
     uint8_t *out = NULL;
-    uint8_t *tmpbuf = NULL;
-    uint8_t *otmp, *otmp2;
+    uint8_t *otmp2;
     int filteredlength = length;
-    if (!tmpbuf) {
-      tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * length);
-      if (tmpbuf == NULL) return;
-      otmp = tmpbuf;
-    } else {
-      otmp = buf;
-    }
+
+    assert(otmp != NULL);
     otmp2 = otmp + get_down2_length(length, 1);
     for (s = 0; s < steps; ++s) {
       const int proj_filteredlength = get_down2_length(filteredlength, 1);
@@ -483,8 +477,6 @@
     if (filteredlength != olength) {
       interpolate(out, filteredlength, output, olength);
     }
-    if (tmpbuf)
-      free(tmpbuf);
   } else {
     interpolate(input, length, output, olength);
   }
@@ -520,8 +512,11 @@
   uint8_t *intbuf = (uint8_t *)malloc(sizeof(uint8_t) * width2 * height);
   uint8_t *tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) *
                                       (width < height ? height : width));
-  uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * (height + height2));
-  if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error;
+  uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * height);
+  uint8_t *arrbuf2 = (uint8_t *)malloc(sizeof(uint8_t) * height2);
+  if (intbuf == NULL || tmpbuf == NULL ||
+      arrbuf == NULL || arrbuf2 == NULL)
+    goto Error;
   assert(width > 0);
   assert(height > 0);
   assert(width2 > 0);
@@ -531,14 +526,15 @@
                         intbuf + width2 * i, width2, tmpbuf);
   for (i = 0; i < width2; ++i) {
     fill_col_to_arr(intbuf + i, width2, height, arrbuf);
-    resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf);
-    fill_arr_to_col(output + i, out_stride, height2, arrbuf + height);
+    resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf);
+    fill_arr_to_col(output + i, out_stride, height2, arrbuf2);
   }
 
  Error:
   free(intbuf);
   free(tmpbuf);
   free(arrbuf);
+  free(arrbuf2);
 }
 
 #if CONFIG_VP9_HIGHBITDEPTH
@@ -741,7 +737,7 @@
                                     int length,
                                     uint16_t *output,
                                     int olength,
-                                    uint16_t *buf,
+                                    uint16_t *otmp,
                                     int bd) {
   int steps;
   if (length == olength) {
@@ -753,16 +749,10 @@
   if (steps > 0) {
     int s;
     uint16_t *out = NULL;
-    uint16_t *tmpbuf = NULL;
-    uint16_t *otmp, *otmp2;
+    uint16_t *otmp2;
     int filteredlength = length;
-    if (!tmpbuf) {
-      tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * length);
-      if (tmpbuf == NULL) return;
-      otmp = tmpbuf;
-    } else {
-      otmp = buf;
-    }
+
+    assert(otmp != NULL);
     otmp2 = otmp + get_down2_length(length, 1);
     for (s = 0; s < steps; ++s) {
       const int proj_filteredlength = get_down2_length(filteredlength, 1);
@@ -780,8 +770,6 @@
     if (filteredlength != olength) {
       highbd_interpolate(out, filteredlength, output, olength, bd);
     }
-    if (tmpbuf)
-      free(tmpbuf);
   } else {
     highbd_interpolate(input, length, output, olength, bd);
   }
@@ -820,24 +808,27 @@
   uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height);
   uint16_t *tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) *
                                         (width < height ? height : width));
-  uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * (height + height2));
-  if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error;
+  uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * height);
+  uint16_t *arrbuf2 = (uint16_t *)malloc(sizeof(uint16_t) * height2);
+  if (intbuf == NULL || tmpbuf == NULL ||
+      arrbuf == NULL || arrbuf2 == NULL) goto Error;
   for (i = 0; i < height; ++i) {
     highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width,
                             intbuf + width2 * i, width2, tmpbuf, bd);
   }
   for (i = 0; i < width2; ++i) {
     highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf);
-    highbd_resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf,
+    highbd_resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf,
                             bd);
     highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2,
-                           arrbuf + height);
+                           arrbuf2);
   }
 
  Error:
   free(intbuf);
   free(tmpbuf);
   free(arrbuf);
+  free(arrbuf2);
 }
 #endif  // CONFIG_VP9_HIGHBITDEPTH
 
diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c
index 5ae44e8..c85251e 100644
--- a/vp8/encoder/denoising.c
+++ b/vp8/encoder/denoising.c
@@ -497,7 +497,8 @@
                              loop_filter_info_n *lfi_n,
                              int mb_row,
                              int mb_col,
-                             int block_index)
+                             int block_index,
+                             int consec_zero_last)
 
 {
     int mv_row;
@@ -608,11 +609,6 @@
     motion_threshold = denoiser->denoise_pars.scale_motion_thresh *
         NOISE_MOTION_THRESHOLD;
 
-    // If block is considered to be skin area, lower the motion threshold.
-    // In current version set threshold = 0, so only denoise zero mv on skin.
-    if (x->is_skin)
-        motion_threshold = 0;
-
     if (motion_magnitude2 <
         denoiser->denoise_pars.scale_increase_filter * NOISE_MOTION_THRESHOLD)
       x->increase_denoising = 1;
@@ -624,6 +620,15 @@
     if (best_sse > sse_thresh || motion_magnitude2 > motion_threshold)
       decision = COPY_BLOCK;
 
+    // If block is considered skin, don't denoise if the block
+    // (1) is selected as non-zero motion for current frame, or
+    // (2) has not been selected as ZERO_LAST mode at least x past frames
+    // in a row.
+    // TODO(marpan): Parameter "x" should be varied with framerate.
+    // In particualar, should be reduced for temporal layers (base layer/LAST).
+    if (x->is_skin && (consec_zero_last < 2 || motion_magnitude2 > 0))
+      decision = COPY_BLOCK;
+
     if (decision == FILTER_BLOCK)
     {
         unsigned char *mc_running_avg_y =
diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h
index 148ccda..34c561d 100644
--- a/vp8/encoder/denoising.h
+++ b/vp8/encoder/denoising.h
@@ -108,7 +108,8 @@
                              loop_filter_info_n *lfi_n,
                              int mb_row,
                              int mb_col,
-                             int block_index);
+                             int block_index,
+                             int consec_zero_last);
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index 51fbe54..0708d65 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -36,7 +36,7 @@
 extern unsigned int cnt_pm;
 #endif
 
-#define MODEL_MODE 0
+#define MODEL_MODE 1
 
 extern const int vp8_ref_frame_order[MAX_MODES];
 extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
@@ -1477,7 +1477,8 @@
         vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
                                 recon_yoffset, recon_uvoffset,
                                 &cpi->common.lf_info, mb_row, mb_col,
-                                block_index);
+                                block_index,
+                                cpi->consec_zero_last_mvbias[block_index]);
 
         // Reevaluate ZEROMV after denoising: for large noise content
         // (i.e., cpi->mse_source_denoised is above threshold), do this for all
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index ab0ad15..9063cea 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -2530,7 +2530,7 @@
         vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
                                 recon_yoffset, recon_uvoffset,
                                 &cpi->common.lf_info, mb_row, mb_col,
-                                block_index);
+                                block_index, 0);
 
         /* Reevaluate ZEROMV after denoising. */
         if (best_mode.mbmode.ref_frame == INTRA_FRAME &&
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 9b58f81..9c78de1 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -9,6 +9,7 @@
  */
 
 
+#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include "./vp8_rtcd.h"
@@ -154,6 +155,8 @@
 {
     vpx_codec_err_t res = VPX_CODEC_OK;
 
+    assert(data != NULL);
+
     if(data + data_sz <= data)
     {
         res = VPX_CODEC_INVALID_PARAM;
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index ae2f66a..3d26fb2 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -158,8 +158,8 @@
   MODE_INFO *left_mi;
   MODE_INFO *above_mi;
 
-  int up_available;
-  int left_available;
+  unsigned int max_blocks_wide;
+  unsigned int max_blocks_high;
 
   const vpx_prob (*partition_probs)[PARTITION_TYPES - 1];
 
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index fd674cb..3fd935e 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -404,20 +404,8 @@
   xd->mb_to_right_edge  = ((mi_cols - bw - mi_col) * MI_SIZE) * 8;
 
   // Are edges available for intra prediction?
-  xd->up_available    = (mi_row != 0);
-  xd->left_available  = (mi_col > tile->mi_col_start);
-  // TODO(slavarnway): eliminate up/left available ???
-  if (xd->up_available) {
-    xd->above_mi = xd->mi[-xd->mi_stride];
-  } else {
-    xd->above_mi = NULL;
-  }
-
-  if (xd->left_available) {
-    xd->left_mi = xd->mi[-1];
-  } else {
-    xd->left_mi = NULL;
-  }
+  xd->above_mi = (mi_row != 0) ? xd->mi[-xd->mi_stride] : NULL;
+  xd->left_mi  = (mi_col > tile->mi_col_start) ? xd->mi[-1] : NULL;
 }
 
 static INLINE void update_partition_context(MACROBLOCKD *xd,
diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c
index c201890..92dc85a 100644
--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -20,10 +20,10 @@
   // left of the entries corresponding to real macroblocks.
   // The prediction flags in these dummy entries are initialized to 0.
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int left_type = xd->left_available && is_inter_block(left_mi) ?
+  const int left_type = left_mi && is_inter_block(left_mi) ?
                             left_mi->interp_filter : SWITCHABLE_FILTERS;
   const MODE_INFO *const above_mi = xd->above_mi;
-  const int above_type = xd->up_available && is_inter_block(above_mi) ?
+  const int above_type = above_mi && is_inter_block(above_mi) ?
                              above_mi->interp_filter : SWITCHABLE_FILTERS;
 
   if (left_type == above_type)
@@ -46,8 +46,8 @@
 int vp9_get_intra_inter_context(const MACROBLOCKD *xd) {
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int has_above = xd->up_available;
-  const int has_left = xd->left_available;
+  const int has_above = !!above_mi;
+  const int has_left = !!left_mi;
 
   if (has_above && has_left) {  // both edges available
     const int above_intra = !is_inter_block(above_mi);
@@ -66,8 +66,8 @@
   int ctx;
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int has_above = xd->up_available;
-  const int has_left = xd->left_available;
+  const int has_above = !!above_mi;
+  const int has_left = !!left_mi;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries corresponding to real macroblocks.
@@ -109,8 +109,8 @@
   int pred_context;
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int above_in_image = xd->up_available;
-  const int left_in_image = xd->left_available;
+  const int above_in_image = !!above_mi;
+  const int left_in_image = !!left_mi;
 
   // Note:
   // The mode info data structure has a one element border above and to the
@@ -190,8 +190,8 @@
   int pred_context;
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int has_above = xd->up_available;
-  const int has_left = xd->left_available;
+  const int has_above = !!above_mi;
+  const int has_left = !!left_mi;
   // Note:
   // The mode info data structure has a one element border above and to the
   // left of the entries corresponding to real macroblocks.
@@ -256,8 +256,8 @@
   int pred_context;
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int has_above = xd->up_available;
-  const int has_left = xd->left_available;
+  const int has_above = !!above_mi;
+  const int has_left = !!left_mi;
 
   // Note:
   // The mode info data structure has a one element border above and to the
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h
index 254cb8b..4942862 100644
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -113,8 +113,8 @@
   const int max_tx_size = max_txsize_lookup[xd->mi[0]->sb_type];
   const MODE_INFO *const above_mi = xd->above_mi;
   const MODE_INFO *const left_mi = xd->left_mi;
-  const int has_above = xd->up_available;
-  const int has_left = xd->left_available;
+  const int has_above = !!above_mi;
+  const int has_left = !!left_mi;
   int above_ctx = (has_above && !above_mi->skip) ? (int)above_mi->tx_size
                                                  : max_tx_size;
   int left_ctx = (has_left && !left_mi->skip) ? (int)left_mi->tx_size
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c
index 13a95ae..c4d91c8 100644
--- a/vp9/common/vp9_reconintra.c
+++ b/vp9/common/vp9_reconintra.c
@@ -425,8 +425,8 @@
                              int aoff, int loff, int plane) {
   const int bw = (1 << bwl_in);
   const int txw = (1 << tx_size);
-  const int have_top = loff || xd->up_available;
-  const int have_left = aoff || xd->left_available;
+  const int have_top = loff || (xd->above_mi != NULL);
+  const int have_left = aoff || (xd->left_mi != NULL);
   const int have_right = (aoff + txw) < bw;
   const int x = aoff * 4;
   const int y = loff * 4;
diff --git a/vp9/common/vp9_rtcd_defs.pl b/vp9/common/vp9_rtcd_defs.pl
index d6a0ce9..1cf636c 100644
--- a/vp9/common/vp9_rtcd_defs.pl
+++ b/vp9/common/vp9_rtcd_defs.pl
@@ -276,7 +276,7 @@
 $vp9_full_search_sad_sse4_1=vp9_full_search_sadx8;
 
 add_proto qw/int vp9_diamond_search_sad/, "const struct macroblock *x, const struct search_site_config *cfg,  struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_variance_vtable *fn_ptr, const struct mv *center_mv";
-specialize qw/vp9_diamond_search_sad avx/;
+specialize qw/vp9_diamond_search_sad/;
 
 add_proto qw/void vp9_temporal_filter_apply/, "uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count";
 specialize qw/vp9_temporal_filter_apply sse2 msa/;
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 32c7219..02962c8 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -883,6 +883,9 @@
       const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ?
           0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
 
+      xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide;
+      xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high;
+
       for (row = 0; row < max_blocks_high; row += step)
         for (col = 0; col < max_blocks_wide; col += step)
           predict_and_reconstruct_intra_block(xd, r, mi, plane,
@@ -911,6 +914,9 @@
         const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ?
             0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
 
+        xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide;
+        xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high;
+
         for (row = 0; row < max_blocks_high; row += step)
           for (col = 0; col < max_blocks_wide; col += step)
             eobtotal += reconstruct_inter_block(xd, r, mi, plane, row, col,
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c
index dcc75b9..47dc107 100644
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -152,65 +152,73 @@
   return c;
 }
 
-// TODO(slavarnway): Decode version of vp9_set_context.  Modify vp9_set_context
-// after testing is complete, then delete this version.
-static
-void dec_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
-                      TX_SIZE tx_size, int has_eob,
-                      int aoff, int loff) {
-  ENTROPY_CONTEXT *const a = pd->above_context + aoff;
-  ENTROPY_CONTEXT *const l = pd->left_context + loff;
-  const int tx_size_in_blocks = 1 << tx_size;
-
-  // above
-  if (has_eob && xd->mb_to_right_edge < 0) {
-    int i;
-    const int blocks_wide = pd->n4_w +
-                            (xd->mb_to_right_edge >> (5 + pd->subsampling_x));
-    int above_contexts = tx_size_in_blocks;
-    if (above_contexts + aoff > blocks_wide)
-      above_contexts = blocks_wide - aoff;
-
-    for (i = 0; i < above_contexts; ++i)
-      a[i] = has_eob;
-    for (i = above_contexts; i < tx_size_in_blocks; ++i)
-      a[i] = 0;
-  } else {
-    memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
+static void get_ctx_shift(MACROBLOCKD *xd, int *ctx_shift_a, int *ctx_shift_l,
+                          int x, int y, unsigned int tx_size_in_blocks) {
+  if (xd->max_blocks_wide) {
+    if (tx_size_in_blocks + x > xd->max_blocks_wide)
+      *ctx_shift_a = (tx_size_in_blocks - (xd->max_blocks_wide - x)) * 8;
   }
-
-  // left
-  if (has_eob && xd->mb_to_bottom_edge < 0) {
-    int i;
-    const int blocks_high = pd->n4_h +
-                            (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
-    int left_contexts = tx_size_in_blocks;
-    if (left_contexts + loff > blocks_high)
-      left_contexts = blocks_high - loff;
-
-    for (i = 0; i < left_contexts; ++i)
-      l[i] = has_eob;
-    for (i = left_contexts; i < tx_size_in_blocks; ++i)
-      l[i] = 0;
-  } else {
-    memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
+  if (xd->max_blocks_high) {
+    if (tx_size_in_blocks + y > xd->max_blocks_high)
+      *ctx_shift_l = (tx_size_in_blocks - (xd->max_blocks_high - y)) * 8;
   }
 }
 
-int vp9_decode_block_tokens(MACROBLOCKD *xd,
-                            int plane, const scan_order *sc,
-                            int x, int y,
-                            TX_SIZE tx_size, vpx_reader *r,
+int vp9_decode_block_tokens(MACROBLOCKD *xd, int plane, const scan_order *sc,
+                            int x, int y, TX_SIZE tx_size, vpx_reader *r,
                             int seg_id) {
   struct macroblockd_plane *const pd = &xd->plane[plane];
   const int16_t *const dequant = pd->seg_dequant[seg_id];
-  const int ctx = get_entropy_context(tx_size, pd->above_context + x,
-                                               pd->left_context + y);
-  const int eob = decode_coefs(xd, get_plane_type(plane),
-                               pd->dqcoeff, tx_size,
-                               dequant, ctx, sc->scan, sc->neighbors, r);
-  dec_set_contexts(xd, pd, tx_size, eob > 0, x, y);
+  int eob;
+  ENTROPY_CONTEXT *a = pd->above_context + x;
+  ENTROPY_CONTEXT *l = pd->left_context + y;
+  int ctx;
+  int ctx_shift_a = 0;
+  int ctx_shift_l = 0;
+
+  switch (tx_size) {
+    case TX_4X4:
+      ctx  = a[0] != 0;
+      ctx += l[0] != 0;
+      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
+                         dequant, ctx, sc->scan, sc->neighbors, r);
+      a[0] = l[0] = (eob > 0);
+      break;
+    case TX_8X8:
+      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_8X8);
+      ctx  = !!*(const uint16_t *)a;
+      ctx += !!*(const uint16_t *)l;
+      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
+                         dequant, ctx, sc->scan, sc->neighbors, r);
+      *(uint16_t *)a = ((eob > 0) * 0x0101) >> ctx_shift_a;
+      *(uint16_t *)l = ((eob > 0) * 0x0101) >> ctx_shift_l;
+      break;
+    case TX_16X16:
+      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_16X16);
+      ctx  = !!*(const uint32_t *)a;
+      ctx += !!*(const uint32_t *)l;
+      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
+                         dequant, ctx, sc->scan, sc->neighbors, r);
+      *(uint32_t *)a = ((eob > 0) * 0x01010101) >> ctx_shift_a;
+      *(uint32_t *)l = ((eob > 0) * 0x01010101) >> ctx_shift_l;
+      break;
+    case TX_32X32:
+      get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_32X32);
+      // NOTE: casting to uint64_t here is safe because the default memory
+      // alignment is at least 8 bytes and the TX_32X32 is aligned on 8 byte
+      // boundaries.
+      ctx  = !!*(const uint64_t *)a;
+      ctx += !!*(const uint64_t *)l;
+      eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size,
+                         dequant, ctx, sc->scan, sc->neighbors, r);
+      *(uint64_t *)a = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a;
+      *(uint64_t *)l = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l;
+      break;
+    default:
+      assert(0 && "Invalid transform size.");
+      eob = 0;
+      break;
+  }
+
   return eob;
 }
-
-
diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c
index 9eca2a2..3de182f 100644
--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -195,7 +195,8 @@
                                                          PICK_MODE_CONTEXT *ctx,
                                                          int motion_magnitude,
                                                          int is_skin,
-                                                         int *zeromv_filter) {
+                                                         int *zeromv_filter,
+                                                         int consec_zeromv) {
   int mv_col, mv_row;
   int sse_diff = ctx->zeromv_sse - ctx->newmv_sse;
   MV_REFERENCE_FRAME frame;
@@ -212,7 +213,7 @@
 
   saved_mi = *mi;
 
-  if (is_skin && motion_magnitude > 0)
+  if (is_skin && (motion_magnitude > 0 || consec_zeromv < 4))
     return COPY_BLOCK;
 
   // If the best reference frame uses inter-prediction and there is enough of a
@@ -332,6 +333,7 @@
                                           mi_row, mi_col);
   struct buf_2d src = mb->plane[0].src;
   int is_skin = 0;
+  int consec_zeromv = 0;
   mv_col = ctx->best_sse_mv.as_mv.col;
   mv_row = ctx->best_sse_mv.as_mv.row;
   motion_magnitude = mv_row * mv_row + mv_col * mv_col;
@@ -343,7 +345,7 @@
     // If motion for current block is small/zero, compute consec_zeromv for
     // skin detection (early exit in skin detection is done for large
     // consec_zeromv when current block has small/zero motion).
-    int consec_zeromv = 0;
+    consec_zeromv = 0;
     if (motion_level == 0) {
       CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
       VP9_COMMON * const cm = &cpi->common;
@@ -361,8 +363,8 @@
           consec_zeromv = VPXMIN(cr->consec_zero_mv[bl_index], consec_zeromv);
           // No need to keep checking 8x8 blocks if any of the sub-blocks
           // has small consec_zeromv (since threshold for no_skin based on
-          // zero/small motion in skin detection is high, i.e, > 5).
-          if (consec_zeromv < 5) {
+          // zero/small motion in skin detection is high, i.e, > 4).
+          if (consec_zeromv < 4) {
             i = ymis;
             j = xmis;
           }
@@ -393,7 +395,8 @@
                                            mi_row, mi_col, ctx,
                                            motion_magnitude,
                                            is_skin,
-                                           &zeromv_filter);
+                                           &zeromv_filter,
+                                           consec_zeromv);
 
   if (decision == FILTER_BLOCK) {
     decision = vp9_denoiser_filter(src.buf, src.stride,
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 40b332a..41b94bf 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1228,10 +1228,10 @@
   MODE_INFO *const mi = xd->mi[0];
   INTERP_FILTER filter_ref;
 
-  if (xd->up_available)
-    filter_ref = xd->mi[-xd->mi_stride]->interp_filter;
-  else if (xd->left_available)
-    filter_ref = xd->mi[-1]->interp_filter;
+  if (xd->above_mi)
+    filter_ref = xd->above_mi->interp_filter;
+  else if (xd->left_mi)
+    filter_ref = xd->left_mi->interp_filter;
   else
     filter_ref = EIGHTTAP;
 
@@ -2266,8 +2266,8 @@
                                     BLOCK_SIZE *max_block_size) {
   VP9_COMMON *const cm = &cpi->common;
   MODE_INFO **mi = xd->mi;
-  const int left_in_image = xd->left_available && mi[-1];
-  const int above_in_image = xd->up_available && mi[-xd->mi_stride];
+  const int left_in_image = !!xd->left_mi;
+  const int above_in_image = !!xd->above_mi;
   const int row8x8_remaining = tile->mi_row_end - mi_row;
   const int col8x8_remaining = tile->mi_col_end - mi_col;
   int bh, bw;
@@ -2362,7 +2362,7 @@
     }
   }
 
-  if (xd->left_available) {
+  if (xd->left_mi) {
     for (idy = 0; idy < mi_height; ++idy) {
       mi = xd->mi[idy * cm->mi_stride - 1];
       bs = mi ? mi->sb_type : bsize;
@@ -2371,7 +2371,7 @@
     }
   }
 
-  if (xd->up_available) {
+  if (xd->above_mi) {
     for (idx = 0; idx < mi_width; ++idx) {
       mi = xd->mi[idx - cm->mi_stride];
       bs = mi ? mi->sb_type : bsize;
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 10fd6c0..3ad175e 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -563,6 +563,7 @@
   double intra_factor;
   double brightness_factor;
   BufferPool *const pool = cm->buffer_pool;
+  MODE_INFO mi_above, mi_left;
 
   // First pass code requires valid last and new frame buffers.
   assert(new_yv12 != NULL);
@@ -695,6 +696,12 @@
                      mb_row << 1, num_8x8_blocks_high_lookup[bsize],
                      mb_col << 1, num_8x8_blocks_wide_lookup[bsize],
                      cm->mi_rows, cm->mi_cols);
+      // Are edges available for intra prediction?
+      // Since the firstpass does not populate the mi_grid_visible,
+      // above_mi/left_mi must be overwritten with a nonzero value when edges
+      // are available.  Required by vp9_predict_intra_block().
+      xd->above_mi = (mb_row != 0) ? &mi_above : NULL;
+      xd->left_mi  = (mb_col > tile.mi_col_start) ? &mi_left : NULL;
 
       // Do intra 16x16 prediction.
       x->skip_encode = 0;
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c
index 7ce86b4..3ae5b21 100644
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -243,13 +243,16 @@
   int mb_y_offset = 0, arf_y_offset = 0, gld_y_offset = 0;
   MV gld_top_mv = {0, 0};
   MODE_INFO mi_local;
+  MODE_INFO mi_above, mi_left;
 
   vp9_zero(mi_local);
   // Set up limit values for motion vectors to prevent them extending outside
   // the UMV borders.
   x->mv_row_min     = -BORDER_MV_PIXELS_B16;
   x->mv_row_max     = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16;
-  xd->up_available  = 0;
+  // Signal to vp9_predict_intra_block() that above is not available
+  xd->above_mi = NULL;
+
   xd->plane[0].dst.stride  = buf->y_stride;
   xd->plane[0].pre[0].stride  = buf->y_stride;
   xd->plane[1].dst.stride = buf->uv_stride;
@@ -268,7 +271,8 @@
     // the UMV borders.
     x->mv_col_min      = -BORDER_MV_PIXELS_B16;
     x->mv_col_max      = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16;
-    xd->left_available = 0;
+    // Signal to vp9_predict_intra_block() that left is not available
+    xd->left_mi = NULL;
 
     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
       MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col];
@@ -280,14 +284,19 @@
       if (mb_col == 0) {
         gld_top_mv = gld_left_mv;
       }
-      xd->left_available = 1;
+      // Signal to vp9_predict_intra_block() that left is available
+      xd->left_mi = &mi_left;
+
       mb_y_in_offset    += 16;
       gld_y_in_offset   += 16;
       arf_y_in_offset   += 16;
       x->mv_col_min     -= 16;
       x->mv_col_max     -= 16;
     }
-    xd->up_available = 1;
+
+    // Signal to vp9_predict_intra_block() that above is available
+    xd->above_mi = &mi_above;
+
     mb_y_offset     += buf->y_stride * 16;
     gld_y_offset    += golden_ref->y_stride * 16;
     if (alt_ref)
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 8b2e985..2057dca 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1017,8 +1017,8 @@
              tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
   MODE_INFO *const mic = xd->mi[0];
   int *bmode_costs;
-  const MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
-  const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
+  const MODE_INFO *above_mi = xd->above_mi;
+  const MODE_INFO *left_mi = xd->left_mi;
   const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
   const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
   bmode_costs = cpi->y_mode_costs[A][L];
@@ -1242,10 +1242,10 @@
   x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
   x->skip = 0;
 
-  if (xd->up_available)
-    filter_ref = xd->mi[-xd->mi_stride]->interp_filter;
-  else if (xd->left_available)
-    filter_ref = xd->mi[-1]->interp_filter;
+  if (xd->above_mi)
+    filter_ref = xd->above_mi->interp_filter;
+  else if (xd->left_mi)
+    filter_ref = xd->left_mi->interp_filter;
   else
     filter_ref = cm->interp_filter;
 
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 508c596..a304182 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2460,10 +2460,10 @@
 
   if (pred_filter_search) {
     INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
-    if (xd->up_available)
-      af = xd->mi[-xd->mi_stride]->interp_filter;
-    if (xd->left_available)
-      lf = xd->mi[-1]->interp_filter;
+    if (xd->above_mi)
+      af = xd->above_mi->interp_filter;
+    if (xd->left_mi)
+      lf = xd->left_mi->interp_filter;
 
     if ((this_mode != NEWMV) || (af == lf))
       best_filter = af;
diff --git a/vp9/encoder/vp9_resize.c b/vp9/encoder/vp9_resize.c
index 63f0ce2..307a112 100644
--- a/vp9/encoder/vp9_resize.c
+++ b/vp9/encoder/vp9_resize.c
@@ -446,7 +446,7 @@
                              int length,
                              uint8_t *output,
                              int olength,
-                             uint8_t *buf) {
+                             uint8_t *otmp) {
   int steps;
   if (length == olength) {
     memcpy(output, input, sizeof(output[0]) * length);
@@ -457,16 +457,10 @@
   if (steps > 0) {
     int s;
     uint8_t *out = NULL;
-    uint8_t *tmpbuf = NULL;
-    uint8_t *otmp, *otmp2;
+    uint8_t *otmp2;
     int filteredlength = length;
-    if (!tmpbuf) {
-      tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * length);
-      if (tmpbuf == NULL) return;
-      otmp = tmpbuf;
-    } else {
-      otmp = buf;
-    }
+
+    assert(otmp != NULL);
     otmp2 = otmp + get_down2_length(length, 1);
     for (s = 0; s < steps; ++s) {
       const int proj_filteredlength = get_down2_length(filteredlength, 1);
@@ -484,8 +478,6 @@
     if (filteredlength != olength) {
       interpolate(out, filteredlength, output, olength);
     }
-    if (tmpbuf)
-      free(tmpbuf);
   } else {
     interpolate(input, length, output, olength);
   }
@@ -521,25 +513,29 @@
   uint8_t *intbuf = (uint8_t *)malloc(sizeof(uint8_t) * width2 * height);
   uint8_t *tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) *
                                       (width < height ? height : width));
-  uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * (height + height2));
-  if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error;
+  uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * height);
+  uint8_t *arrbuf2 = (uint8_t *)malloc(sizeof(uint8_t) * height2);
+  if (intbuf == NULL || tmpbuf == NULL ||
+      arrbuf == NULL || arrbuf2 == NULL)
+    goto Error;
   assert(width > 0);
   assert(height > 0);
   assert(width2 > 0);
   assert(height2 > 0);
   for (i = 0; i < height; ++i)
     resize_multistep(input + in_stride * i, width,
-                        intbuf + width2 * i, width2, tmpbuf);
+                     intbuf + width2 * i, width2, tmpbuf);
   for (i = 0; i < width2; ++i) {
     fill_col_to_arr(intbuf + i, width2, height, arrbuf);
-    resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf);
-    fill_arr_to_col(output + i, out_stride, height2, arrbuf + height);
+    resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf);
+    fill_arr_to_col(output + i, out_stride, height2, arrbuf2);
   }
 
  Error:
   free(intbuf);
   free(tmpbuf);
   free(arrbuf);
+  free(arrbuf2);
 }
 
 #if CONFIG_VP9_HIGHBITDEPTH
@@ -742,7 +738,7 @@
                                     int length,
                                     uint16_t *output,
                                     int olength,
-                                    uint16_t *buf,
+                                    uint16_t *otmp,
                                     int bd) {
   int steps;
   if (length == olength) {
@@ -754,16 +750,10 @@
   if (steps > 0) {
     int s;
     uint16_t *out = NULL;
-    uint16_t *tmpbuf = NULL;
-    uint16_t *otmp, *otmp2;
+    uint16_t *otmp2;
     int filteredlength = length;
-    if (!tmpbuf) {
-      tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * length);
-      if (tmpbuf == NULL) return;
-      otmp = tmpbuf;
-    } else {
-      otmp = buf;
-    }
+
+    assert(otmp != NULL);
     otmp2 = otmp + get_down2_length(length, 1);
     for (s = 0; s < steps; ++s) {
       const int proj_filteredlength = get_down2_length(filteredlength, 1);
@@ -781,8 +771,6 @@
     if (filteredlength != olength) {
       highbd_interpolate(out, filteredlength, output, olength, bd);
     }
-    if (tmpbuf)
-      free(tmpbuf);
   } else {
     highbd_interpolate(input, length, output, olength, bd);
   }
@@ -821,24 +809,28 @@
   uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height);
   uint16_t *tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) *
                                         (width < height ? height : width));
-  uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * (height + height2));
-  if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error;
+  uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * height);
+  uint16_t *arrbuf2 = (uint16_t *)malloc(sizeof(uint16_t) * height2);
+  if (intbuf == NULL || tmpbuf == NULL ||
+      arrbuf == NULL || arrbuf2 == NULL)
+    goto Error;
   for (i = 0; i < height; ++i) {
     highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width,
                             intbuf + width2 * i, width2, tmpbuf, bd);
   }
   for (i = 0; i < width2; ++i) {
     highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf);
-    highbd_resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf,
+    highbd_resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf,
                             bd);
     highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2,
-                           arrbuf + height);
+                           arrbuf2);
   }
 
  Error:
   free(intbuf);
   free(tmpbuf);
   free(arrbuf);
+  free(arrbuf2);
 }
 #endif  // CONFIG_VP9_HIGHBITDEPTH
 
diff --git a/vpx_ports/mem_ops.h b/vpx_ports/mem_ops.h
index d4a3d77..1f8f914 100644
--- a/vpx_ports/mem_ops.h
+++ b/vpx_ports/mem_ops.h
@@ -168,8 +168,8 @@
 static VPX_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >> 8) & 0xff;
-  mem[1] = (val >> 0) & 0xff;
+  mem[0] = (MAU_T)((val >> 8) & 0xff);
+  mem[1] = (MAU_T)((val >> 0) & 0xff);
 }
 
 #undef  mem_put_be24
@@ -177,9 +177,9 @@
 static VPX_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >> 16) & 0xff;
-  mem[1] = (val >>  8) & 0xff;
-  mem[2] = (val >>  0) & 0xff;
+  mem[0] = (MAU_T)((val >> 16) & 0xff);
+  mem[1] = (MAU_T)((val >>  8) & 0xff);
+  mem[2] = (MAU_T)((val >>  0) & 0xff);
 }
 
 #undef  mem_put_be32
@@ -187,10 +187,10 @@
 static VPX_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >> 24) & 0xff;
-  mem[1] = (val >> 16) & 0xff;
-  mem[2] = (val >>  8) & 0xff;
-  mem[3] = (val >>  0) & 0xff;
+  mem[0] = (MAU_T)((val >> 24) & 0xff);
+  mem[1] = (MAU_T)((val >> 16) & 0xff);
+  mem[2] = (MAU_T)((val >>  8) & 0xff);
+  mem[3] = (MAU_T)((val >>  0) & 0xff);
 }
 
 #undef  mem_put_le16
@@ -198,8 +198,8 @@
 static VPX_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >>  0) & 0xff;
-  mem[1] = (val >>  8) & 0xff;
+  mem[0] = (MAU_T)((val >> 0) & 0xff);
+  mem[1] = (MAU_T)((val >> 8) & 0xff);
 }
 
 #undef  mem_put_le24
@@ -207,9 +207,9 @@
 static VPX_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >>  0) & 0xff;
-  mem[1] = (val >>  8) & 0xff;
-  mem[2] = (val >> 16) & 0xff;
+  mem[0] = (MAU_T)((val >>  0) & 0xff);
+  mem[1] = (MAU_T)((val >>  8) & 0xff);
+  mem[2] = (MAU_T)((val >> 16) & 0xff);
 }
 
 #undef  mem_put_le32
@@ -217,10 +217,10 @@
 static VPX_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) {
   MAU_T *mem = (MAU_T *)vmem;
 
-  mem[0] = (val >>  0) & 0xff;
-  mem[1] = (val >>  8) & 0xff;
-  mem[2] = (val >> 16) & 0xff;
-  mem[3] = (val >> 24) & 0xff;
+  mem[0] = (MAU_T)((val >>  0) & 0xff);
+  mem[1] = (MAU_T)((val >>  8) & 0xff);
+  mem[2] = (MAU_T)((val >> 16) & 0xff);
+  mem[3] = (MAU_T)((val >> 24) & 0xff);
 }
 
 #endif  // VPX_PORTS_MEM_OPS_H_
diff --git a/vpx_ports/mem_ops_aligned.h b/vpx_ports/mem_ops_aligned.h
index c16111f..46f6173 100644
--- a/vpx_ports/mem_ops_aligned.h
+++ b/vpx_ports/mem_ops_aligned.h
@@ -28,8 +28,8 @@
  * could redefine these macros.
  */
 #define swap_endian_16(val,raw) do {\
-    val = ((raw>>8) & 0x00ff) \
-          | ((raw<<8) & 0xff00);\
+    val = (uint16_t)(((raw>>8) & 0x00ff) \
+          | ((raw<<8) & 0xff00));\
   } while(0)
 #define swap_endian_32(val,raw) do {\
     val = ((raw>>24) & 0x000000ff) \