Merge "Reset Q for key frame when spatial resizing occurs."
diff --git a/.gitignore b/.gitignore
index 110146d..355bd9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,6 @@
 /vpx_config.h
 /vpx_version.h
 TAGS
+.cproject
+.project
+.settings
diff --git a/build/make/Makefile b/build/make/Makefile
index b6cf320..26ca0be 100644
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -66,6 +66,7 @@
 BUILD_ROOT?=.
 VPATH=$(SRC_PATH_BARE)
 CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
+CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
 ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/ -I$(SRC_PATH)/
 DIST_DIR?=dist
 HOSTCC?=gcc
@@ -111,11 +112,11 @@
 $(BUILD_PFX)%.cc.d: %.cc
 	$(if $(quiet),@echo "    [DEP] $@")
 	$(qexec)mkdir -p $(dir $@)
-	$(qexec)g++ $(INTERNAL_CFLAGS) $(CFLAGS) -M $< | $(fmt_deps) > $@
+	$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@
 
 $(BUILD_PFX)%.cc.o: %.cc
 	$(if $(quiet),@echo "    [CXX] $@")
-	$(qexec)g++ $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $<
+	$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
 
 $(BUILD_PFX)%.asm.d: %.asm
 	$(if $(quiet),@echo "    [DEP] $@")
@@ -213,7 +214,7 @@
 $(1): $(filter-out -%,$(2))
 $(1):
 	$(if $(quiet),@echo    "    [LD] $$@")
-	$(qexec)g++ $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs))
+	$(qexec)$$(CXX) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs))
 endef
 # make-3.80 has a bug with expanding large input strings to the eval function,
 # which was triggered in some cases by the following component of
diff --git a/build/make/configure.sh b/build/make/configure.sh
index 332593a..575a394 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -166,6 +166,17 @@
 
 add_cflags() {
     CFLAGS="${CFLAGS} $@"
+    CXXFLAGS="${CXXFLAGS} $@"
+}
+
+
+add_cflags_only() {
+    CFLAGS="${CFLAGS} $@"
+}
+
+
+add_cxxflags_only() {
+    CXXFLAGS="${CXXFLAGS} $@"
 }
 
 
@@ -277,6 +288,13 @@
     check_cmd ${CC} ${CFLAGS} "$@" -c -o ${TMP_O} ${TMP_C}
 }
 
+check_cxx() {
+    log check_cxx "$@"
+    cat >${TMP_C}
+    log_file ${TMP_C}
+    check_cmd ${CXX} ${CXXFLAGS} "$@" -c -o ${TMP_O} ${TMP_C}
+}
+
 check_cpp() {
     log check_cpp "$@"
     cat > ${TMP_C}
@@ -310,8 +328,25 @@
 EOF
 }
 
+check_cxxflags() {
+    log check_cxxflags "$@"
+
+    # Catch CFLAGS that trigger CXX warnings
+    case "$CXX" in
+      *g++*) check_cxx -Werror "$@" <<EOF
+int x;
+EOF
+      ;;
+      *) check_cxx "$@" <<EOF
+int x;
+EOF
+      ;;
+    esac
+}
+
 check_add_cflags() {
-    check_cflags "$@" && add_cflags "$@"
+    check_cxxflags "$@" && add_cxxflags_only "$@"
+    check_cflags "$@" && add_cflags_only "$@"
 }
 
 check_add_asflags() {
@@ -367,7 +402,9 @@
 
 write_common_target_config_mk() {
     local CC=${CC}
+    local CXX=${CXX}
     enabled ccache && CC="ccache ${CC}"
+    enabled ccache && CXX="ccache ${CXX}"
     print_webm_license $1 "##" ""
 
     cat >> $1 << EOF
@@ -379,6 +416,7 @@
 ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl}
 
 CC=${CC}
+CXX=${CXX}
 AR=${AR}
 LD=${LD}
 AS=${AS}
@@ -386,6 +424,7 @@
 NM=${NM}
 
 CFLAGS  = ${CFLAGS}
+CXXFLAGS  = ${CXXFLAGS}
 ARFLAGS = -rus\$(if \$(quiet),c,v)
 LDFLAGS = ${LDFLAGS}
 ASFLAGS = ${ASFLAGS}
@@ -538,6 +577,7 @@
 
 setup_gnu_toolchain() {
         CC=${CC:-${CROSS}gcc}
+        CXX=${CXX:-${CROSS}g++}
         AR=${AR:-${CROSS}ar}
         LD=${LD:-${CROSS}${link_with_cc:-ld}}
         AS=${AS:-${CROSS}as}
@@ -549,7 +589,7 @@
 
 process_common_toolchain() {
     if [ -z "$toolchain" ]; then
-        gcctarget="$(gcc -dumpmachine 2> /dev/null)"
+        gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
 
         # detect tgt_isa
         case "$gcctarget" in
@@ -792,6 +832,7 @@
                                -name "arm-linux-androideabi-gcc*" -print -quit`
             TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi-
             CC=${TOOLCHAIN_PATH}gcc
+            CXX=${TOOLCHAIN_PATH}g++
             AR=${TOOLCHAIN_PATH}ar
             LD=${TOOLCHAIN_PATH}gcc
             AS=${TOOLCHAIN_PATH}as
@@ -827,6 +868,7 @@
                 SDK_PATH=${sdk_path}
             fi
             TOOLCHAIN_PATH=${SDK_PATH}/usr/bin
+            CXX=${TOOLCHAIN_PATH}/g++
             CC=${TOOLCHAIN_PATH}/gcc
             AR=${TOOLCHAIN_PATH}/ar
             LD=${TOOLCHAIN_PATH}/arm-apple-darwin10-llvm-gcc-4.2
@@ -938,6 +980,7 @@
                 ;;
             solaris*)
                 CC=${CC:-${CROSS}gcc}
+                CXX=${CXX:-${CROSS}g++}
                 LD=${LD:-${CROSS}gcc}
                 CROSS=${CROSS:-g}
                 ;;
@@ -965,7 +1008,7 @@
                         tune_cflags="-march="
                     ;;
                 esac
-                ;;
+            ;;
             gcc*)
                 add_cflags -m${bits}
                 add_ldflags -m${bits}
@@ -974,7 +1017,13 @@
             setup_gnu_toolchain
                 #for 32 bit x86 builds, -O3 did not turn on this flag
                 enabled optimizations && check_add_cflags -fomit-frame-pointer
-                ;;
+            ;;
+            vs*)
+                # When building with Microsoft Visual Studio the assembler is
+                # invoked directly. Checking at configure time is unnecessary.
+                # Skip the check by setting AS arbitrarily
+                AS=msvs
+            ;;
         esac
 
         case "${AS}" in
@@ -983,7 +1032,7 @@
                 which yasm >/dev/null 2>&1 && AS=yasm
                 [ "${AS}" = auto -o -z "${AS}" ] \
                     && die "Neither yasm nor nasm have been found"
-                ;;
+            ;;
         esac
         log_echo "  using $AS"
         [ "${AS##*/}" = nasm ] && add_asflags -Ox
diff --git a/build/make/obj_int_extract.c b/build/make/obj_int_extract.c
index 04e14a6..bf317bd 100644
--- a/build/make/obj_int_extract.c
+++ b/build/make/obj_int_extract.c
@@ -680,7 +680,7 @@
     uint32_t symoffset;
 
     char **sectionlist;  //this array holds all section names in their correct order.
-    //it is used to check if the symbol is in .bss or .data section.
+    //it is used to check if the symbol is in .bss or .rdata section.
 
     nsections = get_le16(buf + 2);
     symtab_ptr = get_le32(buf + 8);
@@ -725,15 +725,15 @@
         }
         strcpy(sectionlist[i], sectionname);
 
-        if (!strcmp(sectionname, ".data")) sectionrawdata_ptr = get_le32(ptr + 20);
+        if (!strcmp(sectionname, ".rdata")) sectionrawdata_ptr = get_le32(ptr + 20);
 
         ptr += 40;
     }
 
     //log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
-    //log_msg("COFF: raw data pointer ofset for section .data is %u\n", sectionrawdata_ptr);
+    //log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", sectionrawdata_ptr);
 
-    /*  The compiler puts the data with non-zero offset in .data section, but puts the data with
+    /*  The compiler puts the data with non-zero offset in .rdata section, but puts the data with
         zero offset in .bss section. So, if the data in in .bss section, set offset=0.
         Note from Wiki: In an object module compiled from C, the bss section contains
         the local variables (but not functions) that were declared with the static keyword,
diff --git a/configure b/configure
index 62e1ffb..eed6f97 100755
--- a/configure
+++ b/configure
@@ -531,7 +531,7 @@
         check_add_cflags -Wimplicit-function-declaration
         check_add_cflags -Wuninitialized
         check_add_cflags -Wunused-variable
-        check_add_cflags -Wunused-but-set-variable        
+        check_add_cflags -Wunused-but-set-variable
         enabled extra_warnings || check_add_cflags -Wno-unused-function
     fi
 
@@ -586,6 +586,16 @@
     if enabled postproc_visualizer; then
         enabled postproc || die "postproc_visualizer requires postproc to be enabled"
     fi
+
+    # Enable unit tests if we have a working C++ compiler
+    case "$tgt_cc" in
+        vs*)
+            soft_enable unit_tests;;
+        *)
+            check_cxx "$@" <<EOF && soft_enable unit_tests
+int z;
+EOF
+    esac
 }
 
 
diff --git a/examples.mk b/examples.mk
index b93a16b..90913e6 100644
--- a/examples.mk
+++ b/examples.mk
@@ -98,7 +98,7 @@
 vp8cx_set_ref.DESCRIPTION           = VP8 set encoder reference frame
 
 # C file is provided, not generated automatically.
-GEN_EXAMPLES-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c
+UTILS-$(CONFIG_MULTI_RES_ENCODING) += vp8_multi_resolution_encoder.c
 vp8_multi_resolution_encoder.SRCS  \
                          += third_party/libyuv/include/libyuv/basic_types.h  \
                             third_party/libyuv/include/libyuv/cpu_id.h  \
diff --git a/examples/decoder_tmpl.txt b/examples/decoder_tmpl.txt
index 92a2c30..e652a63 100644
--- a/examples/decoder_tmpl.txt
+++ b/examples/decoder_tmpl.txt
@@ -48,8 +48,8 @@
     unsigned char *buf =img->planes[plane];
 
     for(y=0; y < (plane ? (img->d_h + 1) >> 1 : img->d_h); y++) {
-        if(fwrite(buf, 1, (plane ? (img->d_w + 1) >> 1 : img->d_w),
-           outfile));
+        (void) fwrite(buf, 1, (plane ? (img->d_w + 1) >> 1 : img->d_w),
+                      outfile);
         buf += img->stride[plane];
     }
 }
diff --git a/examples/encoder_tmpl.c b/examples/encoder_tmpl.c
index cc70b00..e2b65ec 100644
--- a/examples/encoder_tmpl.c
+++ b/examples/encoder_tmpl.c
@@ -85,7 +85,7 @@
     mem_put_le32(header+24, frame_cnt);           /* length */
     mem_put_le32(header+28, 0);                   /* unused */
 
-    if(fwrite(header, 1, 32, outfile));
+    (void) fwrite(header, 1, 32, outfile);
 }
 
 
@@ -103,7 +103,7 @@
     mem_put_le32(header+4, pts&0xFFFFFFFF);
     mem_put_le32(header+8, pts >> 32);
 
-    if(fwrite(header, 1, 12, outfile));
+    (void) fwrite(header, 1, 12, outfile);
 }
 
 int main(int argc, char **argv) {
diff --git a/examples/encoder_tmpl.txt b/examples/encoder_tmpl.txt
index 0042071..39aa221 100644
--- a/examples/encoder_tmpl.txt
+++ b/examples/encoder_tmpl.txt
@@ -61,8 +61,8 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
 case VPX_CODEC_CX_FRAME_PKT:
     write_ivf_frame_header(outfile, pkt);
-    if(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
-              outfile));
+    (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
+                  outfile);
     break;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
 
diff --git a/libs.mk b/libs.mk
index e2ba737..5624bac 100644
--- a/libs.mk
+++ b/libs.mk
@@ -66,6 +66,7 @@
 
 ifeq ($(CONFIG_MSVS),yes)
 CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
+GTEST_LIB=$(if $(CONFIG_STATIC_MSVCRT),gtestmt,gtestmd)
 # This variable uses deferred expansion intentionally, since the results of
 # $(wildcard) may change during the course of the Make.
 VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d))))
@@ -284,38 +285,44 @@
 
 ifeq ($(filter icc gcc,$(TGT_CC)), $(TGT_CC))
     $(BUILD_PFX)asm_com_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S
-	LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
     $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S: $(VP8_PREFIX)common/asm_com_offsets.c
     CLEAN-OBJS += $(BUILD_PFX)asm_com_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S
 
     $(BUILD_PFX)asm_enc_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S
-	LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
     $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S: $(VP8_PREFIX)encoder/asm_enc_offsets.c
     CLEAN-OBJS += $(BUILD_PFX)asm_enc_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S
 
     $(BUILD_PFX)asm_dec_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S
-	LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@
     $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S: $(VP8_PREFIX)decoder/asm_dec_offsets.c
     CLEAN-OBJS += $(BUILD_PFX)asm_dec_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S
 else
   ifeq ($(filter rvct,$(TGT_CC)), $(TGT_CC))
     asm_com_offsets.asm: obj_int_extract
     asm_com_offsets.asm: $(VP8_PREFIX)common/asm_com_offsets.c.o
-	./obj_int_extract rvds $< $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@
     OBJS-yes += $(VP8_PREFIX)common/asm_com_offsets.c.o
     CLEAN-OBJS += asm_com_offsets.asm
     $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_com_offsets.asm
 
     asm_enc_offsets.asm: obj_int_extract
     asm_enc_offsets.asm: $(VP8_PREFIX)encoder/asm_enc_offsets.c.o
-	./obj_int_extract rvds $< $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@
     OBJS-yes += $(VP8_PREFIX)encoder/asm_enc_offsets.c.o
     CLEAN-OBJS += asm_enc_offsets.asm
     $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_enc_offsets.asm
 
     asm_dec_offsets.asm: obj_int_extract
     asm_dec_offsets.asm: $(VP8_PREFIX)decoder/asm_dec_offsets.c.o
-	./obj_int_extract rvds $< $(ADS2GAS) > $@
+	@echo "    [CREATE] $@"
+	$(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@
     OBJS-yes += $(VP8_PREFIX)decoder/asm_dec_offsets.c.o
     CLEAN-OBJS += asm_dec_offsets.asm
     $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_dec_offsets.asm
@@ -328,7 +335,6 @@
 #
 # Rule to generate runtime cpu detection files
 #
-$(OBJS-yes:.o=.d): $(BUILD_PFX)vpx_rtcd.h
 $(BUILD_PFX)vpx_rtcd.h: $(SRC_PATH_BARE)/$(sort $(filter %rtcd_defs.sh,$(CODEC_SRCS)))
 	@echo "    [CREATE] $@"
 	$(qexec)$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$(TGT_ISA) \
@@ -345,14 +351,15 @@
 ##
 ## libvpx test directives
 ##
-
 ifeq ($(CONFIG_UNIT_TESTS),yes)
+
+include $(SRC_PATH_BARE)/test/test.mk
+LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
+LIBVPX_TEST_BINS=./test_libvpx
+
 ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
 ifeq ($(CONFIG_MSVS),yes)
 
-LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS))
-LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_SRCS:.cc.o=))
-
 gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc
 	@echo "    [CREATE] $@"
 	$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
@@ -379,7 +386,7 @@
             $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \
             --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \
             -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
-            -L. -lvpxmt -lwinmm -lgtestmt $$^
+            -L. -l$(CODEC_LIB) -lwinmm -l$(GTEST_LIB) $$^
 endef
 
 $(foreach proj,$(LIBVPX_TEST_BINS),\
@@ -396,23 +403,26 @@
 include $(SRC_PATH_BARE)/third_party/googletest/gtest.mk
 GTEST_SRCS := $(addprefix third_party/googletest/src/,$(call enabled,GTEST_SRCS))
 GTEST_OBJS=$(call objs,$(GTEST_SRCS))
-$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
-$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
+$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
+$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
 OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS)
 LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
 $(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
 
-LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS))
-LIBVPX_TEST_OBJS=$(call objs,$(LIBVPX_TEST_SRCS))
-$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
-$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
-LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_OBJS:.cc.o=))
+LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
+$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
+$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
 OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS)
 
+# Install test sources only if codec source is included
+INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
+    $(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
+INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
+
 $(foreach bin,$(LIBVPX_TEST_BINS),\
     $(if $(BUILD_LIBVPX),$(eval $(bin): libvpx.a libgtest.a ))\
     $(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\
-        $(bin).cc.o \
+        $(LIBVPX_TEST_OBJS) \
         -L. -lvpx -lgtest -lpthread -lm)\
         )))\
     $(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
@@ -435,3 +445,6 @@
 	@echo "PREDEFINED = VPX_CODEC_DISABLE_COMPAT" >> $@
 	@echo "INCLUDE_PATH += ." >> $@;
 	@echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@
+
+## Generate vpx_rtcd.h for all objects
+$(OBJS-yes:.o=.d): $(BUILD_PFX)vpx_rtcd.h
diff --git a/test/boolcoder_test.cc b/test/boolcoder_test.cc
new file mode 100644
index 0000000..41c2f7b
--- /dev/null
+++ b/test/boolcoder_test.cc
@@ -0,0 +1,102 @@
+/*
+ *  Copyright (c) 2012 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.
+ */
+
+extern "C" {
+#include "vp8/encoder/boolhuff.h"
+#include "vp8/decoder/dboolhuff.h"
+}
+
+#include <math.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "vpx/vpx_integer.h"
+
+namespace {
+const int num_tests = 10;
+
+class ACMRandom {
+ public:
+  explicit ACMRandom(int seed) { Reset(seed); }
+
+  void Reset(int seed) { srand(seed); }
+
+  uint8_t Rand8(void) { return (rand() >> 8) & 0xff; }
+
+  int PseudoUniform(int range) { return (rand() >> 8) % range; }
+
+  int operator()(int n) { return PseudoUniform(n); }
+
+  static int DeterministicSeed(void) { return 0xbaba; }
+};
+}  // namespace
+
+TEST(VP8, TestBitIO) {
+  ACMRandom rnd(ACMRandom::DeterministicSeed());
+  for (int n = 0; n < num_tests; ++n) {
+    for (int method = 0; method <= 7; ++method) {   // we generate various proba
+      const int bits_to_test = 1000;
+      uint8_t probas[bits_to_test];
+
+      for (int i = 0; i < bits_to_test; ++i) {
+        const int parity = i & 1;
+        probas[i] =
+            (method == 0) ? 0 : (method == 1) ? 255 :
+            (method == 2) ? 128 :
+            (method == 3) ? rnd.Rand8() :
+            (method == 4) ? (parity ? 0 : 255) :
+            // alternate between low and high proba:
+            (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) :
+            (method == 6) ?
+                (parity ? rnd(64) : 255 - rnd(64)) :
+                (parity ? rnd(32) : 255 - rnd(32));
+      }
+      for (int bit_method = 0; bit_method <= 3; ++bit_method) {
+        const int random_seed = 6432;
+        const int buffer_size = 10000;
+        ACMRandom bit_rnd(random_seed);
+        BOOL_CODER bw;
+        uint8_t bw_buffer[buffer_size];
+        vp8_start_encode(&bw, bw_buffer, bw_buffer + buffer_size);
+
+        int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0;
+        for (int i = 0; i < bits_to_test; ++i) {
+          if (bit_method == 2) {
+            bit = (i & 1);
+          } else if (bit_method == 3) {
+            bit = bit_rnd(2);
+          }
+          vp8_encode_bool(&bw, bit, static_cast<int>(probas[i]));
+        }
+
+        vp8_stop_encode(&bw);
+
+        BOOL_DECODER br;
+        vp8dx_start_decode(&br, bw_buffer, buffer_size);
+        bit_rnd.Reset(random_seed);
+        for (int i = 0; i < bits_to_test; ++i) {
+          if (bit_method == 2) {
+            bit = (i & 1);
+          } else if (bit_method == 3) {
+            bit = bit_rnd(2);
+          }
+          GTEST_ASSERT_EQ(vp8dx_decode_bool(&br, probas[i]), bit)
+              << "pos: "<< i << " / " << bits_to_test
+              << " bit_method: " << bit_method
+              << " method: " << method;
+        }
+      }
+    }
+  }
+}
diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc
new file mode 100644
index 0000000..0a188fa
--- /dev/null
+++ b/test/encode_test_driver.cc
@@ -0,0 +1,137 @@
+/*
+ *  Copyright (c) 2012 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 "test/encode_test_driver.h"
+#include "test/video_source.h"
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+namespace libvpx_test {
+
+void Encoder::EncodeFrame(VideoSource *video, unsigned long flags) {
+  if (video->img())
+    EncodeFrameInternal(*video, flags);
+  else
+    Flush();
+
+  // Handle twopass stats
+  CxDataIterator iter = GetCxData();
+
+  while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
+    if (pkt->kind != VPX_CODEC_STATS_PKT)
+      continue;
+
+    stats_->Append(*pkt);
+  }
+}
+
+void Encoder::EncodeFrameInternal(const VideoSource &video,
+                                  unsigned long flags) {
+  vpx_codec_err_t res;
+  const vpx_image_t *img = video.img();
+
+  // Handle first frame initialization
+  if (!encoder_.priv) {
+    cfg_.g_w = img->d_w;
+    cfg_.g_h = img->d_h;
+    cfg_.g_timebase = video.timebase();
+    cfg_.rc_twopass_stats_in = stats_->buf();
+    res = vpx_codec_enc_init(&encoder_, &vpx_codec_vp8_cx_algo, &cfg_, 0);
+    ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
+  }
+
+  // Handle frame resizing
+  if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) {
+    cfg_.g_w = img->d_w;
+    cfg_.g_h = img->d_h;
+    res = vpx_codec_enc_config_set(&encoder_, &cfg_);
+    ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
+  }
+
+  // Encode the frame
+  res = vpx_codec_encode(&encoder_,
+                         video.img(), video.pts(), video.duration(),
+                         flags, deadline_);
+  ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
+}
+
+void Encoder::Flush() {
+  const vpx_codec_err_t res = vpx_codec_encode(&encoder_, NULL, 0, 0, 0,
+                                               deadline_);
+  ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
+}
+
+void EncoderTest::SetMode(TestMode mode) {
+  switch (mode) {
+    case kRealTime:
+      deadline_ = VPX_DL_REALTIME;
+      break;
+
+    case kOnePassGood:
+    case kTwoPassGood:
+      deadline_ = VPX_DL_GOOD_QUALITY;
+      break;
+
+    case kOnePassBest:
+    case kTwoPassBest:
+      deadline_ = VPX_DL_BEST_QUALITY;
+      break;
+
+    default:
+      ASSERT_TRUE(false) << "Unexpected mode " << mode;
+  }
+
+  if (mode == kTwoPassGood || mode == kTwoPassBest)
+    passes_ = 2;
+  else
+    passes_ = 1;
+}
+
+void EncoderTest::RunLoop(VideoSource *video) {
+  for (unsigned int pass = 0; pass < passes_; pass++) {
+    if (passes_ == 1)
+      cfg_.g_pass = VPX_RC_ONE_PASS;
+    else if (pass == 0)
+      cfg_.g_pass = VPX_RC_FIRST_PASS;
+    else
+      cfg_.g_pass = VPX_RC_LAST_PASS;
+
+    BeginPassHook(pass);
+    Encoder encoder(cfg_, deadline_, &stats_);
+
+    bool again;
+
+    for (video->Begin(), again = true; again; video->Next()) {
+      again = video->img() != NULL;
+
+      PreEncodeFrameHook(video);
+      encoder.EncodeFrame(video, flags_);
+
+      CxDataIterator iter = encoder.GetCxData();
+
+      while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
+        again = true;
+
+        if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
+          continue;
+
+        FramePktHook(pkt);
+      }
+
+      if (!Continue())
+        break;
+    }
+
+    EndPassHook();
+
+    if (!Continue())
+      break;
+  }
+}
+
+}  // namespace libvpx_test
diff --git a/test/encode_test_driver.h b/test/encode_test_driver.h
new file mode 100644
index 0000000..2fb627c
--- /dev/null
+++ b/test/encode_test_driver.h
@@ -0,0 +1,182 @@
+/*
+ *  Copyright (c) 2012 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.
+ */
+#ifndef TEST_ENCODE_TEST_DRIVER_H_
+#define TEST_ENCODE_TEST_DRIVER_H_
+#include <string>
+#include <vector>
+#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "vpx/vpx_encoder.h"
+#include "vpx/vp8cx.h"
+
+namespace libvpx_test {
+
+class VideoSource;
+
+enum TestMode {
+  kRealTime,
+  kOnePassGood,
+  kOnePassBest,
+  kTwoPassGood,
+  kTwoPassBest
+};
+#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
+                                         ::libvpx_test::kOnePassGood, \
+                                         ::libvpx_test::kOnePassBest, \
+                                         ::libvpx_test::kTwoPassGood, \
+                                         ::libvpx_test::kTwoPassBest)
+
+#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
+                                              ::libvpx_test::kOnePassGood, \
+                                              ::libvpx_test::kOnePassBest)
+
+
+// Provides an object to handle the libvpx get_cx_data() iteration pattern
+class CxDataIterator {
+ public:
+  explicit CxDataIterator(vpx_codec_ctx_t *encoder)
+    : encoder_(encoder), iter_(NULL) {}
+
+  const vpx_codec_cx_pkt_t *Next() {
+    return vpx_codec_get_cx_data(encoder_, &iter_);
+  }
+
+ private:
+  vpx_codec_ctx_t  *encoder_;
+  vpx_codec_iter_t  iter_;
+};
+
+
+// Implements an in-memory store for libvpx twopass statistics
+class TwopassStatsStore {
+ public:
+  void Append(const vpx_codec_cx_pkt_t &pkt) {
+    buffer_.append(reinterpret_cast<char *>(pkt.data.twopass_stats.buf),
+                   pkt.data.twopass_stats.sz);
+  }
+
+  vpx_fixed_buf_t buf() {
+    const vpx_fixed_buf_t buf = { &buffer_[0], buffer_.size() };
+    return buf;
+  }
+
+ protected:
+  std::string  buffer_;
+};
+
+
+// Provides a simplified interface to manage one video encoding pass, given
+// a configuration and video source.
+//
+// TODO(jkoleszar): The exact services it provides and the appropriate
+// level of abstraction will be fleshed out as more tests are written.
+class Encoder {
+ public:
+  Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
+          TwopassStatsStore *stats)
+    : cfg_(cfg), deadline_(deadline), stats_(stats) {
+    memset(&encoder_, 0, sizeof(encoder_));
+  }
+
+  ~Encoder() {
+    vpx_codec_destroy(&encoder_);
+  }
+
+  CxDataIterator GetCxData() {
+    return CxDataIterator(&encoder_);
+  }
+
+  // This is a thin wrapper around vpx_codec_encode(), so refer to
+  // vpx_encoder.h for its semantics.
+  void EncodeFrame(VideoSource *video, unsigned long flags);
+
+  // Convenience wrapper for EncodeFrame()
+  void EncodeFrame(VideoSource *video) {
+    EncodeFrame(video, 0);
+  }
+
+  void set_deadline(unsigned long deadline) {
+    deadline_ = deadline;
+  }
+
+ protected:
+  const char *EncoderError() {
+    const char *detail = vpx_codec_error_detail(&encoder_);
+    return detail ? detail : vpx_codec_error(&encoder_);
+  }
+
+  // Encode an image
+  void EncodeFrameInternal(const VideoSource &video, unsigned long flags);
+
+  // Flush the encoder on EOS
+  void Flush();
+
+  vpx_codec_ctx_t      encoder_;
+  vpx_codec_enc_cfg_t  cfg_;
+  unsigned long        deadline_;
+  TwopassStatsStore   *stats_;
+};
+
+
+// Common test functionality for all Encoder tests.
+//
+// This class is a mixin which provides the main loop common to all
+// encoder tests. It provides hooks which can be overridden by subclasses
+// to implement each test's specific behavior, while centralizing the bulk
+// of the boilerplate. Note that it doesn't inherit the gtest testing
+// classes directly, so that tests can be parameterized differently.
+class EncoderTest {
+ protected:
+  EncoderTest() : abort_(false), flags_(0) {}
+
+  virtual ~EncoderTest() {}
+
+  // Initialize the cfg_ member with the default configuration.
+  void InitializeConfig() {
+    const vpx_codec_err_t res = vpx_codec_enc_config_default(
+                                    &vpx_codec_vp8_cx_algo, &cfg_, 0);
+    ASSERT_EQ(VPX_CODEC_OK, res);
+  }
+
+  // Map the TestMode enum to the deadline_ and passes_ variables.
+  void SetMode(TestMode mode);
+
+  // Main loop.
+  virtual void RunLoop(VideoSource *video);
+
+  // Hook to be called at the beginning of a pass.
+  virtual void BeginPassHook(unsigned int pass) {}
+
+  // Hook to be called at the end of a pass.
+  virtual void EndPassHook() {}
+
+  // Hook to be called before encoding a frame.
+  virtual void PreEncodeFrameHook(VideoSource *video) {}
+
+  // Hook to be called on every compressed data packet.
+  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {}
+
+  // Hook to determine whether the encode loop should continue.
+  virtual bool Continue() const { return !abort_; }
+
+  bool                 abort_;
+  vpx_codec_enc_cfg_t  cfg_;
+  unsigned int         passes_;
+  unsigned long        deadline_;
+  TwopassStatsStore    stats_;
+  unsigned long        flags_;
+};
+
+}  // namespace libvpx_test
+
+// Macros to be used with ::testing::Combine
+#define PARAMS(...) ::testing::TestWithParam< std::tr1::tuple< __VA_ARGS__ > >
+#define GET_PARAM(k) std::tr1::get< k >(GetParam())
+
+#endif  // TEST_ENCODE_TEST_DRIVER_H_
diff --git a/vp8/common/idctllm_test.h b/test/idctllm_test.cc
similarity index 83%
rename from vp8/common/idctllm_test.h
rename to test/idctllm_test.cc
index a6a694b..dd42e22 100755
--- a/vp8/common/idctllm_test.h
+++ b/test/idctllm_test.cc
@@ -9,10 +9,15 @@
  */
 
 
- #include "third_party/googletest/src/include/gtest/gtest.h"
+extern "C" {
+#include "vpx_config.h"
+#include "vpx_rtcd.h"
+}
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
 typedef void (*idct_fn_t)(short *input, unsigned char *pred_ptr,
-                            int pred_stride, unsigned char *dst_ptr,
-                            int dst_stride);
+                          int pred_stride, unsigned char *dst_ptr,
+                          int dst_stride);
 namespace {
 class IDCTTest : public ::testing::TestWithParam<idct_fn_t>
 {
@@ -110,4 +115,11 @@
         else
             EXPECT_EQ(0, output[i]) << "i==" << i;
 }
+
+INSTANTIATE_TEST_CASE_P(C, IDCTTest,
+                        ::testing::Values(vp8_short_idct4x4llm_c));
+#if HAVE_MMX
+INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
+                        ::testing::Values(vp8_short_idct4x4llm_mmx));
+#endif
 }
diff --git a/test/keyframe_test.cc b/test/keyframe_test.cc
new file mode 100644
index 0000000..db18e5d
--- /dev/null
+++ b/test/keyframe_test.cc
@@ -0,0 +1,103 @@
+/*
+ *  Copyright (c) 2012 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 <climits>
+#include <vector>
+#include "test/encode_test_driver.h"
+#include "test/video_source.h"
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+namespace {
+
+class KeyframeTest : public ::libvpx_test::EncoderTest,
+  public ::testing::TestWithParam<enum libvpx_test::TestMode> {
+ protected:
+  virtual void SetUp() {
+    InitializeConfig();
+    SetMode(GetParam());
+    kf_count_ = 0;
+    kf_count_max_ = INT_MAX;
+    kf_do_force_kf_ = false;
+  }
+
+  virtual bool Continue() {
+    return !HasFatalFailure() && !abort_;
+  }
+
+  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video) {
+    if (kf_do_force_kf_)
+      flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
+  }
+
+  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
+    if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
+      kf_pts_list_.push_back(pkt->data.frame.pts);
+      kf_count_++;
+      abort_ |= kf_count_ > kf_count_max_;
+    }
+  }
+
+  bool kf_do_force_kf_;
+  int kf_count_;
+  int kf_count_max_;
+  std::vector< vpx_codec_pts_t > kf_pts_list_;
+};
+
+TEST_P(KeyframeTest, TestRandomVideoSource) {
+  // Validate that encoding the RandomVideoSource produces multiple keyframes.
+  // This validates the results of the TestDisableKeyframes test.
+  kf_count_max_ = 2;  // early exit successful tests.
+
+  ::libvpx_test::RandomVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  EXPECT_GT(kf_count_, 1);
+}
+
+TEST_P(KeyframeTest, TestDisableKeyframes) {
+  cfg_.kf_mode = VPX_KF_DISABLED;
+  kf_count_max_ = 1;  // early exit failed tests.
+
+  ::libvpx_test::RandomVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  EXPECT_EQ(1, kf_count_);
+}
+
+TEST_P(KeyframeTest, TestForceKeyframe) {
+  cfg_.kf_mode = VPX_KF_DISABLED;
+  kf_do_force_kf_ = true;
+
+  ::libvpx_test::DummyVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  // verify that every third frame is a keyframe.
+  for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
+       iter != kf_pts_list_.end();
+       ++iter) {
+    ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter;
+  }
+}
+
+TEST_P(KeyframeTest, TestKeyframeMaxDistance) {
+  cfg_.kf_max_dist = 25;
+
+  ::libvpx_test::DummyVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  // verify that keyframe interval matches kf_max_dist
+  for (std::vector<vpx_codec_pts_t>::iterator iter = kf_pts_list_.begin();
+       iter != kf_pts_list_.end();
+       iter++) {
+    ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter;
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(AllModes, KeyframeTest, ALL_TEST_MODES);
+}  // namespace
diff --git a/test/resize_test.cc b/test/resize_test.cc
new file mode 100644
index 0000000..c846157
--- /dev/null
+++ b/test/resize_test.cc
@@ -0,0 +1,104 @@
+/*
+ *  Copyright (c) 2012 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 <climits>
+#include <vector>
+#include "test/encode_test_driver.h"
+#include "test/video_source.h"
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+namespace {
+
+const unsigned int kInitialWidth = 320;
+const unsigned int kInitialHeight = 240;
+
+unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
+  if (frame < 10)
+    return val;
+  if (frame < 20)
+    return val / 2;
+  if (frame < 30)
+    return val * 2 / 3;
+  if (frame < 40)
+    return val / 4;
+  if (frame < 50)
+    return val * 7 / 8;
+  return val;
+}
+
+class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
+ public:
+  ResizingVideoSource() {
+    SetSize(kInitialWidth, kInitialHeight);
+    limit_ = 60;
+  }
+
+ protected:
+  virtual void Next() {
+    ++frame_;
+    SetSize(ScaleForFrameNumber(frame_, kInitialWidth),
+            ScaleForFrameNumber(frame_, kInitialHeight));
+    FillFrame();
+  }
+};
+
+class ResizeTest : public ::libvpx_test::EncoderTest,
+  public ::testing::TestWithParam<enum libvpx_test::TestMode> {
+ protected:
+  struct FrameInfo {
+    FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
+        : pts(_pts), w(_w), h(_h) {}
+
+    vpx_codec_pts_t pts;
+    unsigned int    w;
+    unsigned int    h;
+  };
+
+  virtual void SetUp() {
+    InitializeConfig();
+    SetMode(GetParam());
+  }
+
+  virtual bool Continue() const {
+    return !HasFatalFailure() && !abort_;
+  }
+
+  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
+    if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
+      const unsigned char *buf =
+          reinterpret_cast<const unsigned char *>(pkt->data.frame.buf);
+      const unsigned int w = (buf[6] | (buf[7] << 8)) & 0x3fff;
+      const unsigned int h = (buf[8] | (buf[9] << 8)) & 0x3fff;
+
+      frame_info_list_.push_back(FrameInfo(pkt->data.frame.pts, w, h));
+    }
+  }
+
+  std::vector< FrameInfo > frame_info_list_;
+};
+
+TEST_P(ResizeTest, TestExternalResizeWorks) {
+  ResizingVideoSource video;
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  for (std::vector<FrameInfo>::iterator info = frame_info_list_.begin();
+       info != frame_info_list_.end(); ++info) {
+    const vpx_codec_pts_t pts = info->pts;
+    const unsigned int expected_w = ScaleForFrameNumber(pts, kInitialWidth);
+    const unsigned int expected_h = ScaleForFrameNumber(pts, kInitialHeight);
+
+    EXPECT_EQ(expected_w, info->w)
+        << "Frame " << pts << "had unexpected width";
+    EXPECT_EQ(expected_h, info->h)
+        << "Frame " << pts << "had unexpected height";
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(OnePass, ResizeTest, ONE_PASS_TEST_MODES);
+}  // namespace
diff --git a/test/test.mk b/test/test.mk
new file mode 100644
index 0000000..ac500fe
--- /dev/null
+++ b/test/test.mk
@@ -0,0 +1,9 @@
+LIBVPX_TEST_SRCS-yes += test.mk
+LIBVPX_TEST_SRCS-yes += boolcoder_test.cc
+LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
+LIBVPX_TEST_SRCS-yes += encode_test_driver.h
+LIBVPX_TEST_SRCS-yes += idctllm_test.cc
+LIBVPX_TEST_SRCS-yes += keyframe_test.cc
+LIBVPX_TEST_SRCS-yes += resize_test.cc
+LIBVPX_TEST_SRCS-yes += test_libvpx.cc
+LIBVPX_TEST_SRCS-yes += video_source.h
diff --git a/test/test_libvpx.cc b/test/test_libvpx.cc
new file mode 100644
index 0000000..48bfc6c
--- /dev/null
+++ b/test/test_libvpx.cc
@@ -0,0 +1,14 @@
+/*
+ *  Copyright (c) 2012 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 "third_party/googletest/src/include/gtest/gtest.h"
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/video_source.h b/test/video_source.h
new file mode 100644
index 0000000..3507ef0
--- /dev/null
+++ b/test/video_source.h
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (c) 2012 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.
+ */
+#ifndef TEST_VIDEO_SOURCE_H_
+#define TEST_VIDEO_SOURCE_H_
+#include "vpx/vpx_encoder.h"
+
+namespace libvpx_test {
+
+// Abstract base class for test video sources, which provide a stream of
+// vpx_image_t images with associated timestamps and duration.
+class VideoSource {
+ public:
+  virtual ~VideoSource() {}
+
+  // Prepare the stream for reading, rewind/open as necessary.
+  virtual void Begin() = 0;
+
+  // Advance the cursor to the next frame
+  virtual void Next() = 0;
+
+  // Get the current video frame, or NULL on End-Of-Stream.
+  virtual vpx_image_t *img() const = 0;
+
+  // Get the presentation timestamp of the current frame.
+  virtual vpx_codec_pts_t pts() const = 0;
+
+  // Get the current frame's duration
+  virtual unsigned long duration() const = 0;
+
+  // Get the timebase for the stream
+  virtual vpx_rational_t timebase() const = 0;
+
+  // Get the current frame counter, starting at 0.
+  virtual unsigned int frame() const = 0;
+};
+
+
+class DummyVideoSource : public VideoSource {
+ public:
+  DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
+    SetSize(80, 64);
+  }
+
+  virtual ~DummyVideoSource() { vpx_img_free(img_); }
+
+  virtual void Begin() {
+    frame_ = 0;
+    FillFrame();
+  }
+
+  virtual void Next() {
+    ++frame_;
+    FillFrame();
+  }
+
+  virtual vpx_image_t *img() const {
+    return (frame_ < limit_) ? img_ : NULL;
+  }
+
+  // Models a stream where Timebase = 1/FPS, so pts == frame.
+  virtual vpx_codec_pts_t pts() const { return frame_; }
+
+  virtual unsigned long duration() const { return 1; }
+
+  virtual vpx_rational_t timebase() const {
+    const vpx_rational_t t = {1, 30};
+    return t;
+  }
+
+  virtual unsigned int frame() const { return frame_; }
+
+  void SetSize(unsigned int width, unsigned int height) {
+    if (width != width_ || height != height_) {
+      vpx_img_free(img_);
+      raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
+      img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_VPXI420, width, height, 32);
+      width_ = width;
+      height_ = height;
+    }
+  }
+
+ protected:
+  virtual void FillFrame() { memset(img_->img_data, 0, raw_sz_); }
+
+  vpx_image_t *img_;
+  size_t       raw_sz_;
+  unsigned int limit_;
+  unsigned int frame_;
+  unsigned int width_;
+  unsigned int height_;
+};
+
+
+class RandomVideoSource : public DummyVideoSource {
+ protected:
+  // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
+  // than holding previous frames to encourage keyframes to be thrown.
+  virtual void FillFrame() {
+    if (frame_ % 30 < 15)
+      for (size_t i = 0; i < raw_sz_; ++i)
+        img_->img_data[i] = rand();
+    else
+      memset(img_->img_data, 0, raw_sz_);
+  }
+};
+
+}  // namespace libvpx_test
+
+#endif  // TEST_VIDEO_SOURCE_H_
diff --git a/third_party/libyuv/source/scale.c b/third_party/libyuv/source/scale.c
index 930a7ae..c142a17 100644
--- a/third_party/libyuv/source/scale.c
+++ b/third_party/libyuv/source/scale.c
@@ -60,7 +60,7 @@
 
 #if defined(__ARM_NEON__) && !defined(YUV_DISABLE_ASM)
 #define HAS_SCALEROWDOWN2_NEON
-void ScaleRowDown2_NEON(const uint8* src_ptr, int /* src_stride */,
+void ScaleRowDown2_NEON(const uint8* src_ptr, int  src_stride,
                         uint8* dst, int dst_width) {
   asm volatile (
     "1:                                        \n"
@@ -102,7 +102,7 @@
 }
 
 #define HAS_SCALEROWDOWN4_NEON
-static void ScaleRowDown4_NEON(const uint8* src_ptr, int /* src_stride */,
+static void ScaleRowDown4_NEON(const uint8* src_ptr, int src_stride,
                                uint8* dst_ptr, int dst_width) {
   asm volatile (
     "1:                                        \n"
@@ -160,7 +160,7 @@
 // Down scale from 4 to 3 pixels.  Use the neon multilane read/write
 //  to load up the every 4th pixel into a 4 different registers.
 // Point samples 32 pixels to 24 pixels.
-static void ScaleRowDown34_NEON(const uint8* src_ptr, int /* src_stride */,
+static void ScaleRowDown34_NEON(const uint8* src_ptr, int src_stride,
                                 uint8* dst_ptr, int dst_width) {
   asm volatile (
     "1:                                        \n"
@@ -284,7 +284,7 @@
     65536 / 18, 65536 / 18, 65536 / 18, 65536 / 18 };
 
 // 32 -> 12
-static void ScaleRowDown38_NEON(const uint8* src_ptr, int,
+static void ScaleRowDown38_NEON(const uint8* src_ptr, int src_stride,
                                 uint8* dst_ptr, int dst_width) {
   asm volatile (
     "vld1.u8      {q3}, [%3]                   \n"
diff --git a/tools/ftfy.sh b/tools/ftfy.sh
index 95fd397..c5cfdea 100755
--- a/tools/ftfy.sh
+++ b/tools/ftfy.sh
@@ -34,7 +34,7 @@
          --align-pointer=name \
          --indent-preprocessor --convert-tabs --indent-labels \
          --suffix=none --quiet "$@"
-  sed -i 's/[[:space:]]\{1,\},/,/g' "$@"
+  sed -i "" 's/[[:space:]]\{1,\},/,/g' "$@"
 }
 
 
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
index d58e49c..86485ac 100644
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -17,23 +17,6 @@
 #include "entropymode.h"
 #include "systemdependent.h"
 
-
-extern  void vp8_init_scan_order_mask();
-
-static void update_mode_info_border(MODE_INFO *mi, int rows, int cols)
-{
-    int i;
-    vpx_memset(mi - cols - 2, 0, sizeof(MODE_INFO) * (cols + 1));
-
-    for (i = 0; i < rows; i++)
-    {
-        /* TODO(holmer): Bug? This updates the last element of each row
-         * rather than the border element!
-         */
-        vpx_memset(&mi[i*cols-1], 0, sizeof(MODE_INFO));
-    }
-}
-
 void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
 {
     int i;
@@ -49,12 +32,13 @@
 
     vpx_free(oci->above_context);
     vpx_free(oci->mip);
+#if CONFIG_ERROR_CONCEALMENT
     vpx_free(oci->prev_mip);
+    oci->prev_mip = NULL;
+#endif
 
-    oci->above_context = 0;
-    oci->mip = 0;
-    oci->prev_mip = 0;
-
+    oci->above_context = NULL;
+    oci->mip = NULL;
 }
 
 int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
@@ -124,21 +108,8 @@
 
     oci->mi = oci->mip + oci->mode_info_stride + 1;
 
-    /* allocate memory for last frame MODE_INFO array */
-#if CONFIG_ERROR_CONCEALMENT
-    oci->prev_mip = vpx_calloc((oci->mb_cols + 1) * (oci->mb_rows + 1), sizeof(MODE_INFO));
-
-    if (!oci->prev_mip)
-    {
-        vp8_de_alloc_frame_buffers(oci);
-        return 1;
-    }
-
-    oci->prev_mi = oci->prev_mip + oci->mode_info_stride + 1;
-#else
-    oci->prev_mip = NULL;
-    oci->prev_mi = NULL;
-#endif
+    /* Allocation of previous mode info will be done in vp8_decode_frame()
+     * as it is a decoder only data */
 
     oci->above_context = vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * oci->mb_cols, 1);
 
@@ -148,11 +119,6 @@
         return 1;
     }
 
-    update_mode_info_border(oci->mi, oci->mb_rows, oci->mb_cols);
-#if CONFIG_ERROR_CONCEALMENT
-    update_mode_info_border(oci->prev_mi, oci->mb_rows, oci->mb_cols);
-#endif
-
     return 0;
 }
 void vp8_setup_version(VP8_COMMON *cm)
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index 7c648da..c7206b2 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -168,7 +168,7 @@
 } MODE_INFO;
 
 #if CONFIG_MULTI_RES_ENCODING
-/* The information needed to be stored for higher-resolution encoder */
+/* The mb-level information needed to be stored for higher-resolution encoder */
 typedef struct
 {
     MB_PREDICTION_MODE mode;
@@ -176,7 +176,15 @@
     int_mv mv;
     //union b_mode_info bmi[16];
     int dissim;    // dissimilarity level of the macroblock
-} LOWER_RES_INFO;
+} LOWER_RES_MB_INFO;
+
+/* The frame-level information needed to be stored for higher-resolution
+ *  encoder */
+typedef struct
+{
+    FRAME_TYPE frame_type;
+    LOWER_RES_MB_INFO *mb_info;
+} LOWER_RES_FRAME_INFO;
 #endif
 
 typedef struct blockd
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index de7e828..091e4c7 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -160,9 +160,7 @@
 void vp8_init_mbmode_probs(VP8_COMMON *x)
 {
     vpx_memcpy(x->fc.ymode_prob, vp8_ymode_prob, sizeof(vp8_ymode_prob));
-    vpx_memcpy(x->kf_ymode_prob, vp8_kf_ymode_prob, sizeof(vp8_kf_ymode_prob));
     vpx_memcpy(x->fc.uv_mode_prob, vp8_uv_mode_prob, sizeof(vp8_uv_mode_prob));
-    vpx_memcpy(x->kf_uv_mode_prob, vp8_kf_uv_mode_prob, sizeof(vp8_kf_uv_mode_prob));
     vpx_memcpy(x->fc.sub_mv_ref_prob, sub_mv_ref_prob, sizeof(sub_mv_ref_prob));
 }
 
@@ -171,7 +169,3 @@
     vpx_memcpy(p, vp8_bmode_prob, sizeof(vp8_bmode_prob));
 }
 
-void vp8_kf_default_bmode_probs(vp8_prob p [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1])
-{
-    vpx_memcpy(p, vp8_kf_bmode_prob, sizeof(vp8_kf_bmode_prob));
-}
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
index 70200cb..3a2fa84 100644
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -67,9 +67,14 @@
 
 extern const struct vp8_token_struct vp8_small_mvencodings[8];
 
-void vp8_init_mbmode_probs(VP8_COMMON *x);
+/* Key frame default mode probs */
+extern const vp8_prob vp8_kf_bmode_prob[VP8_BINTRAMODES][VP8_BINTRAMODES]
+[VP8_BINTRAMODES-1];
+extern const vp8_prob vp8_kf_uv_mode_prob[VP8_UV_MODES-1];
+extern const vp8_prob vp8_kf_ymode_prob[VP8_YMODES-1];
 
-void   vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]);
+void vp8_init_mbmode_probs(VP8_COMMON *x);
+void vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]);
 void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]);
 
 #endif
diff --git a/vp8/common/idctllm_test.cc b/vp8/common/idctllm_test.cc
deleted file mode 100755
index 0f6ebe7..0000000
--- a/vp8/common/idctllm_test.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Copyright (c) 2010 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.
- */
-
-
- extern "C" {
-    void vp8_short_idct4x4llm_c(short *input, unsigned char *pred_ptr,
-                            int pred_stride, unsigned char *dst_ptr,
-                            int dst_stride);
-}
-
-#include "vpx_config.h"
-#include "idctllm_test.h"
-namespace
-{
-
-INSTANTIATE_TEST_CASE_P(C, IDCTTest,
-                        ::testing::Values(vp8_short_idct4x4llm_c));
-
-} // namespace
-
-int main(int argc, char **argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h
index 2e282f6..67cb77c 100644
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -39,14 +39,6 @@
 
     typedef enum
     {
-        VP8_LAST_FLAG = 1,
-        VP8_GOLD_FLAG = 2,
-        VP8_ALT_FLAG = 4
-    } VP8_REFFRAME;
-
-
-    typedef enum
-    {
         USAGE_STREAM_FROM_SERVER    = 0x0,
         USAGE_LOCAL_FILE_PLAYBACK   = 0x1,
         USAGE_CONSTRAINED_QUALITY   = 0x2
@@ -106,7 +98,7 @@
         int Width;              // width of data passed to the compressor
         int Height;             // height of data passed to the compressor
         struct vpx_rational  timebase;
-        int target_bandwidth;    // bandwidth to be used in kilobits per second
+        unsigned int target_bandwidth;    // bandwidth to be used in kilobits per second
 
         int noise_sensitivity;   // parameter used for applying pre processing blur: recommendation 0
         int Sharpness;          // parameter used for sharpening output: recommendation 0:
@@ -244,8 +236,8 @@
 
     int vp8_use_as_reference(struct VP8_COMP* comp, int ref_frame_flags);
     int vp8_update_reference(struct VP8_COMP* comp, int ref_frame_flags);
-    int vp8_get_reference(struct VP8_COMP* comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
-    int vp8_set_reference(struct VP8_COMP* comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    int vp8_get_reference(struct VP8_COMP* comp, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    int vp8_set_reference(struct VP8_COMP* comp, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd);
     int vp8_update_entropy(struct VP8_COMP* comp, int update);
     int vp8_set_roimap(struct VP8_COMP* comp, unsigned char *map, unsigned int rows, unsigned int cols, int delta_q[4], int delta_lf[4], unsigned int threshold[4]);
     int vp8_set_active_map(struct VP8_COMP* comp, unsigned char *map, unsigned int rows, unsigned int cols);
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index c3215c0..d7d02c2 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -59,12 +59,6 @@
     RECON_CLAMP_NOTREQUIRED     = 1
 } CLAMP_TYPE;
 
-typedef enum
-{
-    SIXTAP   = 0,
-    BILINEAR = 1
-} INTERPOLATIONFILTERTYPE;
-
 typedef struct VP8Common
 
 {
@@ -130,11 +124,11 @@
 
     MODE_INFO *mip; /* Base of allocated array */
     MODE_INFO *mi;  /* Corresponds to upper left visible macroblock */
+#if CONFIG_ERROR_CONCEALMENT
     MODE_INFO *prev_mip; /* MODE_INFO array 'mip' from last decoded frame */
     MODE_INFO *prev_mi;  /* 'mi' from last frame (points into prev_mip) */
+#endif
 
-
-    INTERPOLATIONFILTERTYPE mcomp_filter_type;
     LOOPFILTERTYPE filter_type;
 
     loop_filter_info_n lf_info;
@@ -158,14 +152,6 @@
     ENTROPY_CONTEXT_PLANES *above_context;   /* row of context for each plane */
     ENTROPY_CONTEXT_PLANES left_context;  /* (up to) 4 contexts "" */
 
-
-    /* keyframe block modes are predicted by their above, left neighbors */
-
-    vp8_prob kf_bmode_prob [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1];
-    vp8_prob kf_ymode_prob [VP8_YMODES-1];  /* keyframe "" */
-    vp8_prob kf_uv_mode_prob [VP8_UV_MODES-1];
-
-
     FRAME_CONTEXT lfc; /* last frame entropy */
     FRAME_CONTEXT fc;  /* this frame entropy */
 
diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h
index 35a8b6e..60af1cc 100644
--- a/vp8/common/onyxd.h
+++ b/vp8/common/onyxd.h
@@ -22,6 +22,7 @@
 #include "ppflags.h"
 #include "vpx_ports/mem.h"
 #include "vpx/vpx_codec.h"
+#include "vpx/vp8.h"
 
     struct VP8D_COMP;
 
@@ -35,12 +36,6 @@
         int     error_concealment;
         int     input_fragments;
     } VP8D_CONFIG;
-    typedef enum
-    {
-        VP8_LAST_FLAG = 1,
-        VP8_GOLD_FLAG = 2,
-        VP8_ALT_FLAG = 4
-    } VP8_REFFRAME;
 
     typedef enum
     {
@@ -56,8 +51,8 @@
     int vp8dx_receive_compressed_data(struct VP8D_COMP* comp, unsigned long size, const unsigned char *dest, int64_t time_stamp);
     int vp8dx_get_raw_frame(struct VP8D_COMP* comp, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags);
 
-    vpx_codec_err_t vp8dx_get_reference(struct VP8D_COMP* comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
-    vpx_codec_err_t vp8dx_set_reference(struct VP8D_COMP* comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    vpx_codec_err_t vp8dx_get_reference(struct VP8D_COMP* comp, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    vpx_codec_err_t vp8dx_set_reference(struct VP8D_COMP* comp, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd);
 
     struct VP8D_COMP* vp8dx_create_decompressor(VP8D_CONFIG *oxcf);
 
diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c
index ccf6ad7..a94ae00 100644
--- a/vp8/common/postproc.c
+++ b/vp8/common/postproc.c
@@ -441,7 +441,7 @@
 
         }
 
-        for (next = next; next < 256; next++)
+        for (; next < 256; next++)
             char_dist[next] = 0;
 
     }
diff --git a/vp8/common/x86/idctllm_mmx_test.cc b/vp8/common/x86/idctllm_mmx_test.cc
deleted file mode 100755
index 8c11533..0000000
--- a/vp8/common/x86/idctllm_mmx_test.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Copyright (c) 2010 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.
- */
-
-
- extern "C" {
-    void vp8_short_idct4x4llm_mmx(short *input, unsigned char *pred_ptr,
-                            int pred_stride, unsigned char *dst_ptr,
-                            int dst_stride);
-}
-
-#include "vp8/common/idctllm_test.h"
-
-namespace
-{
-
-INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
-                        ::testing::Values(vp8_short_idct4x4llm_mmx));
-
-} // namespace
-
-int main(int argc, char **argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 51e2420..74bec58 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -52,7 +52,7 @@
     const int mis = pbi->common.mode_info_stride;
 
     mi->mbmi.ref_frame = INTRA_FRAME;
-    mi->mbmi.mode = read_kf_ymode(bc, pbi->common.kf_ymode_prob);
+    mi->mbmi.mode = read_kf_ymode(bc, vp8_kf_ymode_prob);
 
     if (mi->mbmi.mode == B_PRED)
     {
@@ -65,12 +65,12 @@
             const B_PREDICTION_MODE L = left_block_mode(mi, i);
 
             mi->bmi[i].as_mode =
-                read_bmode(bc, pbi->common.kf_bmode_prob [A] [L]);
+                read_bmode(bc, vp8_kf_bmode_prob [A] [L]);
         }
         while (++i < 16);
     }
 
-    mi->mbmi.uv_mode = read_uv_mode(bc, pbi->common.kf_uv_mode_prob);
+    mi->mbmi.uv_mode = read_uv_mode(bc, vp8_kf_uv_mode_prob);
 }
 
 static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc)
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 62a068b..48824ce 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -549,8 +549,8 @@
 {
     vp8_reader *bool_decoder = &pbi->bc2;
     unsigned int partition_idx;
-    int fragment_idx;
-    int num_token_partitions;
+    unsigned int fragment_idx;
+    unsigned int num_token_partitions;
     const unsigned char *first_fragment_end = pbi->fragments[0] +
                                           pbi->fragment_sizes[0];
 
@@ -661,7 +661,6 @@
         vp8_init_mbmode_probs(pc);
 
         vp8_default_coef_probs(pc);
-        vp8_kf_default_bmode_probs(pc->kf_bmode_prob);
 
         /* reset the segment feature data to 0 with delta coding (Default state). */
         vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
@@ -685,13 +684,8 @@
     }
     else
     {
-        if (!pc->use_bilinear_mc_filter)
-            pc->mcomp_filter_type = SIXTAP;
-        else
-            pc->mcomp_filter_type = BILINEAR;
-
         /* To enable choice of different interploation filters */
-        if (pc->mcomp_filter_type == SIXTAP)
+        if (!pc->use_bilinear_mc_filter)
         {
             xd->subpixel_predict        = vp8_sixtap_predict4x4;
             xd->subpixel_predict8x4     = vp8_sixtap_predict8x4;
@@ -737,6 +731,8 @@
     int corrupt_tokens = 0;
     int prev_independent_partitions = pbi->independent_partitions;
 
+    int frame_size_change = 0;
+
     /* start with no corruption of current frame */
     xd->corrupted = 0;
     pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
@@ -825,21 +821,42 @@
                     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                        "Failed to allocate frame buffers");
 
+                /* allocate memory for last frame MODE_INFO array */
 #if CONFIG_ERROR_CONCEALMENT
-                pbi->overlaps = NULL;
+
                 if (pbi->ec_enabled)
                 {
+                    /* old prev_mip was released by vp8_de_alloc_frame_buffers()
+                     * called in vp8_alloc_frame_buffers() */
+                    pc->prev_mip = vpx_calloc(
+                                       (pc->mb_cols + 1) * (pc->mb_rows + 1),
+                                       sizeof(MODE_INFO));
+
+                    if (!pc->prev_mip)
+                    {
+                        vp8_de_alloc_frame_buffers(pc);
+                        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+                                           "Failed to allocate"
+                                           "last frame MODE_INFO array");
+                    }
+
+                    pc->prev_mi = pc->prev_mip + pc->mode_info_stride + 1;
+
                     if (vp8_alloc_overlap_lists(pbi))
                         vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                            "Failed to allocate overlap lists "
                                            "for error concealment");
                 }
+
 #endif
 
 #if CONFIG_MULTITHREAD
+
                 if (pbi->b_multithreaded_rd)
                     vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
+
 #endif
+                frame_size_change = 1;
             }
         }
     }
@@ -1103,9 +1120,17 @@
 #endif
         vp8_setup_intra_recon(&pc->yv12_fb[pc->new_fb_idx]);
 
-    vp8_setup_block_dptrs(xd);
-
-    vp8_build_block_doffsets(xd);
+    if(frame_size_change)
+    {
+#if CONFIG_MULTITHREAD
+        for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
+        {
+            pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx];
+            vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd);
+        }
+#endif
+        vp8_build_block_doffsets(&pbi->mb);
+    }
 
     /* clear out the coeff buffer */
     vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
@@ -1132,7 +1157,7 @@
 #if CONFIG_MULTITHREAD
     if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION)
     {
-        int i;
+        unsigned int i;
         vp8mt_decode_mb_rows(pbi, xd);
         vp8_yv12_extend_frame_borders(&pc->yv12_fb[pc->new_fb_idx]);    /*cm->frame_to_show);*/
         for (i = 0; i < pbi->decoding_thread_count; ++i)
diff --git a/vp8/decoder/error_concealment.c b/vp8/decoder/error_concealment.c
index 7750728..8b2e32b 100644
--- a/vp8/decoder/error_concealment.c
+++ b/vp8/decoder/error_concealment.c
@@ -51,12 +51,13 @@
         vpx_free(pbi->overlaps);
         pbi->overlaps = NULL;
     }
+
     pbi->overlaps = vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols,
                                sizeof(MB_OVERLAP));
+
     if (pbi->overlaps == NULL)
         return -1;
-    vpx_memset(pbi->overlaps, 0,
-               sizeof(MB_OVERLAP) * pbi->common.mb_rows * pbi->common.mb_cols);
+
     return 0;
 }
 
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 2a9a11b..1c67e71 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -80,6 +80,7 @@
 
 #if CONFIG_ERROR_CONCEALMENT
     pbi->ec_enabled = oxcf->error_concealment;
+    pbi->overlaps = NULL;
 #else
     pbi->ec_enabled = 0;
 #endif
@@ -99,6 +100,8 @@
      */
     pbi->independent_partitions = 0;
 
+    vp8_setup_block_dptrs(&pbi->mb);
+
     return pbi;
 }
 
@@ -122,16 +125,16 @@
 }
 
 
-vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8_COMMON *cm = &pbi->common;
     int ref_fb_idx;
 
-    if (ref_frame_flag == VP8_LAST_FLAG)
+    if (ref_frame_flag == VP8_LAST_FRAME)
         ref_fb_idx = cm->lst_fb_idx;
-    else if (ref_frame_flag == VP8_GOLD_FLAG)
+    else if (ref_frame_flag == VP8_GOLD_FRAME)
         ref_fb_idx = cm->gld_fb_idx;
-    else if (ref_frame_flag == VP8_ALT_FLAG)
+    else if (ref_frame_flag == VP8_ALTR_FRAME)
         ref_fb_idx = cm->alt_fb_idx;
     else{
         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
@@ -153,17 +156,17 @@
 }
 
 
-vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8_COMMON *cm = &pbi->common;
     int *ref_fb_ptr = NULL;
     int free_fb;
 
-    if (ref_frame_flag == VP8_LAST_FLAG)
+    if (ref_frame_flag == VP8_LAST_FRAME)
         ref_fb_ptr = &cm->lst_fb_idx;
-    else if (ref_frame_flag == VP8_GOLD_FLAG)
+    else if (ref_frame_flag == VP8_GOLD_FRAME)
         ref_fb_ptr = &cm->gld_fb_idx;
-    else if (ref_frame_flag == VP8_ALT_FLAG)
+    else if (ref_frame_flag == VP8_ALTR_FRAME)
         ref_fb_ptr = &cm->alt_fb_idx;
     else{
         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
@@ -300,7 +303,7 @@
     if (pbi->num_fragments == 0)
     {
         /* New frame, reset fragment pointers and sizes */
-        vpx_memset(pbi->fragments, 0, sizeof(pbi->fragments));
+        vpx_memset((void*)pbi->fragments, 0, sizeof(pbi->fragments));
         vpx_memset(pbi->fragment_sizes, 0, sizeof(pbi->fragment_sizes));
     }
     if (pbi->input_fragments && !(source == NULL && size == 0))
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
index 97cf0dc..8a5b8d5 100644
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -31,7 +31,6 @@
 typedef struct
 {
     MACROBLOCKD  mbd;
-    int mb_row;
 } MB_ROW_DEC;
 
 typedef struct
@@ -62,7 +61,7 @@
     volatile int b_multithreaded_rd;
     int max_threads;
     int current_mb_col_main;
-    int decoding_thread_count;
+    unsigned int decoding_thread_count;
     int allocated_decoding_thread_count;
 
     int mt_baseline_filter_level[MAX_MB_SEGMENTS];
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
index 47a0349..a51ca64 100644
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -50,8 +50,6 @@
         mbd->pre = pc->yv12_fb[pc->lst_fb_idx];
         mbd->dst = pc->yv12_fb[pc->new_fb_idx];
 
-        vp8_setup_block_dptrs(mbd);
-        vp8_build_block_doffsets(mbd);
         mbd->segmentation_enabled    = xd->segmentation_enabled;
         mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
         vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
@@ -73,16 +71,18 @@
         vpx_memcpy(mbd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));
 
         mbd->fullpixel_mask = 0xffffffff;
-        if(pc->full_pixel)
+
+        if (pc->full_pixel)
             mbd->fullpixel_mask = 0xfffffff8;
 
     }
 
-    for (i=0; i< pc->mb_rows; i++)
-        pbi->mt_current_mb_col[i]=-1;
+    for (i = 0; i < pc->mb_rows; i++)
+        pbi->mt_current_mb_col[i] = -1;
 }
 
-static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, unsigned int mb_idx)
+static void mt_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
+                                 unsigned int mb_idx)
 {
     MB_PREDICTION_MODE mode;
     int i;
@@ -297,34 +297,16 @@
     }
 }
 
-typedef void (*init_current_bc_fn_t)(VP8D_COMP *pbi, MACROBLOCKD *xd,
-    int start_mb_row, int mb_row, int num_part);
-
-static void init_current_bc(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row,
-                     int mb_row, int num_part)
+static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row)
 {
-    (void) start_mb_row;
-
-    xd->current_bc = &pbi->mbc[mb_row%num_part];
-}
-
-static void init_current_bc_threads(VP8D_COMP *pbi, MACROBLOCKD *xd,
-                     int start_mb_row, int mb_row, int num_part)
-{
-    (void) xd;
-    pbi->mb_row_di[start_mb_row - 1].mb_row = mb_row;
-    pbi->mb_row_di[start_mb_row - 1].mbd.current_bc =  &pbi->mbc[mb_row%num_part];
-}
-
-
-static void decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, int start_mb_row,
-                           init_current_bc_fn_t init_current_bc_fn)
-{
-    volatile int *last_row_current_mb_col = NULL;
+    volatile const int *last_row_current_mb_col;
+    volatile int *current_mb_col;
     int mb_row;
     VP8_COMMON *pc = &pbi->common;
-    int nsync = pbi->sync_range;
+    const int nsync = pbi->sync_range;
+    const int first_row_no_sync_above = pc->mb_cols + nsync;
     int num_part = 1 << pbi->common.multi_token_partition;
+    int last_mb_row = start_mb_row;
 
     int dst_fb_idx = pc->new_fb_idx;
     unsigned char *ref_buffer[MAX_REF_FRAMES][3];
@@ -367,10 +349,17 @@
        int filter_level;
        loop_filter_info_n *lfi_n = &pc->lf_info;
 
-       init_current_bc_fn(pbi, xd, start_mb_row, mb_row, num_part);
+       /* save last row processed by this thread */
+       last_mb_row = mb_row;
+       /* select bool coder for current partition */
+       xd->current_bc =  &pbi->mbc[mb_row%num_part];
 
        if (mb_row > 0)
            last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
+       else
+           last_row_current_mb_col = &first_row_no_sync_above;
+
+       current_mb_col = &pbi->mt_current_mb_col[mb_row];
 
        recon_yoffset = mb_row * recon_y_stride * 16;
        recon_uvoffset = mb_row * recon_uv_stride * 8;
@@ -419,9 +408,11 @@
 
        for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
        {
-           if ( mb_row > 0 && (mb_col & (nsync-1)) == 0)
+           *current_mb_col = mb_col - 1;
+
+           if ((mb_col & (nsync - 1)) == 0)
            {
-               while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
+               while (mb_col > (*last_row_current_mb_col - nsync))
                {
                    x86_pause_hint();
                    thread_sleep(0);
@@ -477,7 +468,7 @@
            /* propagate errors from reference frames */
            xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame];
 
-           decode_macroblock(pbi, xd, 0);
+           mt_decode_macroblock(pbi, xd, 0);
 
            xd->left_available = 1;
 
@@ -591,9 +582,6 @@
            ++xd->mode_info_context;  /* next mb */
 
            xd->above_context++;
-
-           /*pbi->mb_row_di[ithread].current_mb_col = mb_col;*/
-           pbi->mt_current_mb_col[mb_row] = mb_col;
        }
 
        /* adjust to the next row of mbs */
@@ -611,8 +599,13 @@
                    pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
                }
            }
-       } else
-           vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
+       }
+       else
+           vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16,
+                             xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
+
+       /* last MB of row is ready just after extension is done */
+       *current_mb_col = mb_col + nsync;
 
        ++xd->mode_info_context;      /* skip prediction column */
        xd->up_available = 1;
@@ -620,6 +613,11 @@
        /* since we have multithread */
        xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
     }
+
+    /* signal end of frame decoding if this thread processed the last mb_row */
+    if (last_mb_row == (pc->mb_rows - 1))
+        sem_post(&pbi->h_event_end_decoding);
+
 }
 
 
@@ -635,7 +633,6 @@
         if (pbi->b_multithreaded_rd == 0)
             break;
 
-        /*if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)*/
         if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
         {
             if (pbi->b_multithreaded_rd == 0)
@@ -643,21 +640,11 @@
             else
             {
                 MACROBLOCKD *xd = &mbrd->mbd;
-
                 xd->left_context = &mb_row_left_context;
 
-                decode_mb_rows(pbi, xd, ithread+1, init_current_bc_threads);
+                mt_decode_mb_rows(pbi, xd, ithread+1);
             }
         }
-
-        /*  add this to each frame */
-        if ((mbrd->mb_row == pbi->common.mb_rows-1) ||
-            ((mbrd->mb_row == pbi->common.mb_rows-2) &&
-                (pbi->common.mb_rows % (pbi->decoding_thread_count+1))==1))
-        {
-            /*SetEvent(pbi->h_event_end_decoding);*/
-            sem_post(&pbi->h_event_end_decoding);
-        }
     }
 
     return 0 ;
@@ -667,7 +654,7 @@
 void vp8_decoder_create_threads(VP8D_COMP *pbi)
 {
     int core_count = 0;
-    int ithread;
+    unsigned int ithread;
 
     pbi->b_multithreaded_rd = 0;
     pbi->allocated_decoding_thread_count = 0;
@@ -694,6 +681,8 @@
         {
             sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
 
+            vp8_setup_block_dptrs(&pbi->mb_row_di[ithread].mbd);
+
             pbi->de_thread_data[ithread].ithread  = ithread;
             pbi->de_thread_data[ithread].ptr1     = (void *)pbi;
             pbi->de_thread_data[ithread].ptr2     = (void *) &pbi->mb_row_di[ithread];
@@ -881,7 +870,8 @@
 void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
 {
     VP8_COMMON *pc = &pbi->common;
-    int i;
+    unsigned int i;
+    int j;
 
     int filter_level = pc->filter_level;
 
@@ -892,19 +882,19 @@
         vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
         vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
 
-        for (i=1; i<pc->mb_rows; i++)
+        for (j=1; j<pc->mb_rows; j++)
         {
-            vpx_memset(pbi->mt_yabove_row[i] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
-            vpx_memset(pbi->mt_uabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
-            vpx_memset(pbi->mt_vabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
+            vpx_memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
+            vpx_memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
+            vpx_memset(pbi->mt_vabove_row[j] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
         }
 
         /* Set left_col to 129 initially */
-        for (i=0; i<pc->mb_rows; i++)
+        for (j=0; j<pc->mb_rows; j++)
         {
-            vpx_memset(pbi->mt_yleft_col[i], (unsigned char)129, 16);
-            vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
-            vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
+            vpx_memset(pbi->mt_yleft_col[j], (unsigned char)129, 16);
+            vpx_memset(pbi->mt_uleft_col[j], (unsigned char)129, 8);
+            vpx_memset(pbi->mt_vleft_col[j], (unsigned char)129, 8);
         }
 
         /* Initialize the loop filter for this frame. */
@@ -916,7 +906,7 @@
     for (i = 0; i < pbi->decoding_thread_count; i++)
         sem_post(&pbi->h_event_start_decoding[i]);
 
-    decode_mb_rows(pbi, xd, 0, init_current_bc);
+    mt_decode_mb_rows(pbi, xd, 0);
 
     sem_wait(&pbi->h_event_end_decoding);   /* add back for each frame */
 }
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 3824294..d7cd5a9 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -754,7 +754,7 @@
             if (c->mb_no_coeff_skip)
                 vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
 
-            kfwrite_ymode(bc, ym, c->kf_ymode_prob);
+            kfwrite_ymode(bc, ym, vp8_kf_ymode_prob);
 
             if (ym == B_PRED)
             {
@@ -771,12 +771,12 @@
                     ++intra_mode_stats [A] [L] [bm];
 #endif
 
-                    write_bmode(bc, bm, c->kf_bmode_prob [A] [L]);
+                    write_bmode(bc, bm, vp8_kf_bmode_prob [A] [L]);
                 }
                 while (++i < 16);
             }
 
-            write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob);
+            write_uv_mode(bc, (m++)->mbmi.uv_mode, vp8_kf_uv_mode_prob);
         }
 
         m++;    // skip L prediction border
@@ -1295,11 +1295,6 @@
     Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
 #endif
 
-    //vp8_kf_default_bmode_probs() is called in vp8_setup_key_frame() once for each
-    //K frame before encode frame. pc->kf_bmode_prob doesn't get changed anywhere
-    //else. No need to call it again here. --yw
-    //vp8_kf_default_bmode_probs( pc->kf_bmode_prob);
-
     // every keyframe send startcode, width, height, scale factor, clamp and color type
     if (oh.type == KEY_FRAME)
     {
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index a98fd50..9756acc 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -90,16 +90,17 @@
     signed int act_zbin_adj;
     signed int last_act_zbin_adj;
 
-    int mvcosts[2][MVvals+1];
     int *mvcost[2];
-    int mvsadcosts[2][MVfpvals+1];
     int *mvsadcost[2];
-    int mbmode_cost[2][MB_MODE_COUNT];
-    int intra_uv_mode_cost[2][MB_MODE_COUNT];
-    unsigned int bmode_costs[10][10][10];
-    unsigned int inter_bmode_costs[B_MODE_COUNT];
+    int (*mbmode_cost)[MB_MODE_COUNT];
+    int (*intra_uv_mode_cost)[MB_MODE_COUNT];
+    int (*bmode_costs)[10][10];
+    int *inter_bmode_costs;
+    int (*token_costs)[COEF_BANDS][PREV_COEF_CONTEXTS]
+    [MAX_ENTROPY_TOKENS];
 
-    // These define limits to motion vector components to prevent them from extending outside the UMV borders
+    // These define limits to motion vector components to prevent
+    // them from extending outside the UMV borders
     int mv_col_min;
     int mv_col_max;
     int mv_row_min;
@@ -107,7 +108,7 @@
 
     int skip;
 
-    int encode_breakout;
+    unsigned int encode_breakout;
 
     //char * gf_active_ptr;
     signed char *gf_active_ptr;
@@ -115,7 +116,6 @@
     unsigned char *active_ptr;
     MV_CONTEXT *mvc;
 
-    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
     int optimize;
     int q_index;
 
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 4450ab2..dce37a7 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -644,15 +644,15 @@
                sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
 
     // Special case treatment when GF and ARF are not sensible options for reference
-    if (cpi->ref_frame_flags == VP8_LAST_FLAG)
+    if (cpi->ref_frame_flags == VP8_LAST_FRAME)
         vp8_calc_ref_frame_costs(x->ref_frame_cost,
                                  cpi->prob_intra_coded,255,128);
     else if ((cpi->oxcf.number_of_layers > 1) &&
-               (cpi->ref_frame_flags == VP8_GOLD_FLAG))
+               (cpi->ref_frame_flags == VP8_GOLD_FRAME))
         vp8_calc_ref_frame_costs(x->ref_frame_cost,
                                  cpi->prob_intra_coded,1,255);
     else if ((cpi->oxcf.number_of_layers > 1) &&
-                (cpi->ref_frame_flags == VP8_ALT_FLAG))
+                (cpi->ref_frame_flags == VP8_ALTR_FRAME))
         vp8_calc_ref_frame_costs(x->ref_frame_cost,
                                  cpi->prob_intra_coded,1,1);
     else
@@ -692,7 +692,7 @@
     }
 
     // Functions setup for all frame types so we can use MC in AltRef
-    if (cm->mcomp_filter_type == SIXTAP)
+    if(!cm->use_bilinear_mc_filter)
     {
         xd->subpixel_predict        = vp8_sixtap_predict4x4;
         xd->subpixel_predict8x4     = vp8_sixtap_predict8x4;
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
index 2a2cb2f..57d5783 100644
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -336,21 +336,16 @@
     z->src.v_buffer      = x->src.v_buffer;
     */
 
+    z->mvcost[0] =  x->mvcost[0];
+    z->mvcost[1] =  x->mvcost[1];
+    z->mvsadcost[0] =  x->mvsadcost[0];
+    z->mvsadcost[1] =  x->mvsadcost[1];
 
-    vpx_memcpy(z->mvcosts,          x->mvcosts,         sizeof(x->mvcosts));
-    z->mvcost[0] = &z->mvcosts[0][mv_max+1];
-    z->mvcost[1] = &z->mvcosts[1][mv_max+1];
-    z->mvsadcost[0] = &z->mvsadcosts[0][mvfp_max+1];
-    z->mvsadcost[1] = &z->mvsadcosts[1][mvfp_max+1];
-
-
-    vpx_memcpy(z->token_costs,       x->token_costs,      sizeof(x->token_costs));
-    vpx_memcpy(z->inter_bmode_costs,  x->inter_bmode_costs, sizeof(x->inter_bmode_costs));
-    //memcpy(z->mvcosts,            x->mvcosts,         sizeof(x->mvcosts));
-    //memcpy(z->mvcost,         x->mvcost,          sizeof(x->mvcost));
-    vpx_memcpy(z->mbmode_cost,       x->mbmode_cost,      sizeof(x->mbmode_cost));
-    vpx_memcpy(z->intra_uv_mode_cost,  x->intra_uv_mode_cost, sizeof(x->intra_uv_mode_cost));
-    vpx_memcpy(z->bmode_costs,       x->bmode_costs,      sizeof(x->bmode_costs));
+    z->token_costs = x->token_costs;
+    z->inter_bmode_costs = x->inter_bmode_costs;
+    z->mbmode_cost = x->mbmode_cost;
+    z->intra_uv_mode_cost = x->intra_uv_mode_cost;
+    z->bmode_costs = x->bmode_costs;
 
     for (i = 0; i < 25; i++)
     {
@@ -358,17 +353,15 @@
         z->block[i].quant_fast      = x->block[i].quant_fast;
         z->block[i].quant_shift     = x->block[i].quant_shift;
         z->block[i].zbin            = x->block[i].zbin;
-        z->block[i].zrun_zbin_boost   = x->block[i].zrun_zbin_boost;
+        z->block[i].zrun_zbin_boost = x->block[i].zrun_zbin_boost;
         z->block[i].round           = x->block[i].round;
-        z->q_index                  = x->q_index;
-        z->act_zbin_adj             = x->act_zbin_adj;
-        z->last_act_zbin_adj        = x->last_act_zbin_adj;
-        /*
-        z->block[i].src             = x->block[i].src;
-        */
-        z->block[i].src_stride       = x->block[i].src_stride;
+        z->block[i].src_stride      = x->block[i].src_stride;
     }
 
+    z->q_index           = x->q_index;
+    z->act_zbin_adj      = x->act_zbin_adj;
+    z->last_act_zbin_adj = x->last_act_zbin_adj;
+
     {
         MACROBLOCKD *xd = &x->e_mbd;
         MACROBLOCKD *zd = &z->e_mbd;
@@ -400,9 +393,11 @@
         zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
         zd->segmentation_enabled     = xd->segmentation_enabled;
         zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
-        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
+        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data,
+                   sizeof(xd->segment_feature_data));
 
-        vpx_memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
+        vpx_memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc,
+                   sizeof(xd->dequant_y1_dc));
         vpx_memcpy(zd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
         vpx_memcpy(zd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
         vpx_memcpy(zd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 8de1a6a..36483d6 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -853,7 +853,8 @@
         else
             recon_file = fopen(filename, "ab");
 
-        if(fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file));
+        (void) fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1,
+                      recon_file);
         fclose(recon_file);
     }
 
diff --git a/vp8/encoder/mcomp.c b/vp8/encoder/mcomp.c
index 67e4f7e..dc0edfbc 100644
--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -34,17 +34,23 @@
 
 static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit)
 {
-    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
-        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
-        * error_per_bit + 128) >> 8;
+    // Ignore mv costing if mvcost is NULL
+    if (mvcost)
+        return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
+                 mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
+                 * error_per_bit + 128) >> 8;
+    return 0;
 }
 
 static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
 {
-    /* Calculate sad error cost on full pixel basis. */
-    return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] +
-        mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)])
-        * error_per_bit + 128) >> 8;
+    // Calculate sad error cost on full pixel basis.
+    // Ignore mv costing if mvsadcost is NULL
+    if (mvsadcost)
+        return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] +
+                 mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)])
+                * error_per_bit + 128) >> 8;
+    return 0;
 }
 
 void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
@@ -176,7 +182,7 @@
  * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
  * could reduce the area.
  */
-#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define MVC(r,c) (mvcost ? ((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 : 0) // estimated cost of a motion vector (r,c)
 #define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
 #define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
 #define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c
index c636c48..c61563c 100644
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -18,6 +18,8 @@
 void vp8_init_mode_costs(VP8_COMP *c)
 {
     VP8_COMMON *x = &c->common;
+    struct rd_costs_struct *rd_costs = &c->rd_costs;
+
     {
         const vp8_tree_p T = vp8_bmode_tree;
 
@@ -29,19 +31,24 @@
 
             do
             {
-                vp8_cost_tokens((int *)c->mb.bmode_costs[i][j], x->kf_bmode_prob[i][j], T);
+                vp8_cost_tokens(rd_costs->bmode_costs[i][j],
+                                vp8_kf_bmode_prob[i][j], T);
             }
             while (++j < VP8_BINTRAMODES);
         }
         while (++i < VP8_BINTRAMODES);
 
-        vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T);
+        vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.bmode_prob, T);
     }
-    vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree);
+    vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.sub_mv_ref_prob,
+                    vp8_sub_mv_ref_tree);
 
-    vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
-    vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree);
+    vp8_cost_tokens(rd_costs->mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
+    vp8_cost_tokens(rd_costs->mbmode_cost[0], vp8_kf_ymode_prob,
+                    vp8_kf_ymode_tree);
 
-    vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], x->fc.uv_mode_prob, vp8_uv_mode_tree);
-    vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob, vp8_uv_mode_tree);
+    vp8_cost_tokens(rd_costs->intra_uv_mode_cost[1], x->fc.uv_mode_prob,
+                    vp8_uv_mode_tree);
+    vp8_cost_tokens(rd_costs->intra_uv_mode_cost[0], vp8_kf_uv_mode_prob,
+                    vp8_uv_mode_tree);
 }
diff --git a/vp8/encoder/mr_dissim.c b/vp8/encoder/mr_dissim.c
index 7a62a06..564f963 100644
--- a/vp8/encoder/mr_dissim.c
+++ b/vp8/encoder/mr_dissim.c
@@ -65,14 +65,18 @@
         /* Store info for show/no-show frames for supporting alt_ref.
          * If parent frame is alt_ref, child has one too.
          */
+        LOWER_RES_FRAME_INFO* store_info
+                      = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info;
+
+        store_info->frame_type = cm->frame_type;
+
         if(cm->frame_type != KEY_FRAME)
         {
             int mb_row;
             int mb_col;
             /* Point to beginning of allocated MODE_INFO arrays. */
             MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
-            LOWER_RES_INFO* store_mode_info
-                            = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
+            LOWER_RES_MB_INFO* store_mode_info = store_info->mb_info;
 
             for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
             {
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 5b4d08b..fa8fea0 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -703,11 +703,11 @@
 
     /* Count enabled references */
     ref_frames = 1;
-    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+    if (cpi->ref_frame_flags & VP8_LAST_FRAME)
         ref_frames++;
-    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+    if (cpi->ref_frame_flags & VP8_GOLD_FRAME)
         ref_frames++;
-    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+    if (cpi->ref_frame_flags & VP8_ALTR_FRAME)
         ref_frames++;
 
     /* Convert speed to continuous range, with clamping */
@@ -1514,7 +1514,7 @@
     cpi->baseline_gf_interval =
         cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
 
-    cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+    cpi->ref_frame_flags = VP8_ALTR_FRAME | VP8_GOLD_FRAME | VP8_LAST_FRAME;
 
     //cpi->use_golden_frame_only = 0;
     //cpi->use_last_frame_only = 0;
@@ -1610,11 +1610,6 @@
     // Only allow dropped frames in buffered mode
     cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode;
 
-    if (!cm->use_bilinear_mc_filter)
-        cm->mcomp_filter_type = SIXTAP;
-    else
-        cm->mcomp_filter_type = BILINEAR;
-
     cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
 
 
@@ -1895,22 +1890,12 @@
     cpi->total_byte_count             = 0;
 
     cpi->drop_frame                  = 0;
-    cpi->drop_count                  = 0;
-    cpi->max_drop_count               = 0;
-    cpi->max_consec_dropped_frames     = 4;
 
     cpi->rate_correction_factor         = 1.0;
     cpi->key_frame_rate_correction_factor = 1.0;
     cpi->gf_rate_correction_factor  = 1.0;
     cpi->twopass.est_max_qcorrection_factor  = 1.0;
 
-    cpi->mb.mvcost[0] = &cpi->mb.mvcosts[0][mv_max+1];
-    cpi->mb.mvcost[1] = &cpi->mb.mvcosts[1][mv_max+1];
-    cpi->mb.mvsadcost[0] = &cpi->mb.mvsadcosts[0][mvfp_max+1];
-    cpi->mb.mvsadcost[1] = &cpi->mb.mvsadcosts[1][mvfp_max+1];
-
-    cal_mvsadcosts(cpi->mb.mvsadcost);
-
     for (i = 0; i < KEY_FRAME_CONTEXT; i++)
     {
         cpi->prior_key_frame_distance[i] = (int)cpi->output_frame_rate;
@@ -2044,13 +2029,29 @@
     cpi->common.error.setjmp = 0;
 
 #if CONFIG_MULTI_RES_ENCODING
+
     /* Calculate # of MBs in a row in lower-resolution level image. */
     if (cpi->oxcf.mr_encoder_id > 0)
         vp8_cal_low_res_mb_cols(cpi);
+
 #endif
 
-    return  cpi;
+    /* setup RD costs to MACROBLOCK struct */
 
+    cpi->mb.mvcost[0] = &cpi->rd_costs.mvcosts[0][mv_max+1];
+    cpi->mb.mvcost[1] = &cpi->rd_costs.mvcosts[1][mv_max+1];
+    cpi->mb.mvsadcost[0] = &cpi->rd_costs.mvsadcosts[0][mvfp_max+1];
+    cpi->mb.mvsadcost[1] = &cpi->rd_costs.mvsadcosts[1][mvfp_max+1];
+
+    cal_mvsadcosts(cpi->mb.mvsadcost);
+
+    cpi->mb.mbmode_cost = cpi->rd_costs.mbmode_cost;
+    cpi->mb.intra_uv_mode_cost = cpi->rd_costs.intra_uv_mode_cost;
+    cpi->mb.bmode_costs = cpi->rd_costs.bmode_costs;
+    cpi->mb.inter_bmode_costs = cpi->rd_costs.inter_bmode_costs;
+    cpi->mb.token_costs = cpi->rd_costs.token_costs;
+
+    return  cpi;
 }
 
 
@@ -2483,28 +2484,28 @@
     cpi->common.refresh_alt_ref_frame = 0;
     cpi->common.refresh_last_frame   = 0;
 
-    if (ref_frame_flags & VP8_LAST_FLAG)
+    if (ref_frame_flags & VP8_LAST_FRAME)
         cpi->common.refresh_last_frame = 1;
 
-    if (ref_frame_flags & VP8_GOLD_FLAG)
+    if (ref_frame_flags & VP8_GOLD_FRAME)
         cpi->common.refresh_golden_frame = 1;
 
-    if (ref_frame_flags & VP8_ALT_FLAG)
+    if (ref_frame_flags & VP8_ALTR_FRAME)
         cpi->common.refresh_alt_ref_frame = 1;
 
     return 0;
 }
 
-int vp8_get_reference(VP8_COMP *cpi, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+int vp8_get_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8_COMMON *cm = &cpi->common;
     int ref_fb_idx;
 
-    if (ref_frame_flag == VP8_LAST_FLAG)
+    if (ref_frame_flag == VP8_LAST_FRAME)
         ref_fb_idx = cm->lst_fb_idx;
-    else if (ref_frame_flag == VP8_GOLD_FLAG)
+    else if (ref_frame_flag == VP8_GOLD_FRAME)
         ref_fb_idx = cm->gld_fb_idx;
-    else if (ref_frame_flag == VP8_ALT_FLAG)
+    else if (ref_frame_flag == VP8_ALTR_FRAME)
         ref_fb_idx = cm->alt_fb_idx;
     else
         return -1;
@@ -2513,17 +2514,17 @@
 
     return 0;
 }
-int vp8_set_reference(VP8_COMP *cpi, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+int vp8_set_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8_COMMON *cm = &cpi->common;
 
     int ref_fb_idx;
 
-    if (ref_frame_flag == VP8_LAST_FLAG)
+    if (ref_frame_flag == VP8_LAST_FRAME)
         ref_fb_idx = cm->lst_fb_idx;
-    else if (ref_frame_flag == VP8_GOLD_FLAG)
+    else if (ref_frame_flag == VP8_GOLD_FRAME)
         ref_fb_idx = cm->gld_fb_idx;
-    else if (ref_frame_flag == VP8_ALT_FLAG)
+    else if (ref_frame_flag == VP8_ALTR_FRAME)
         ref_fb_idx = cm->alt_fb_idx;
     else
         return -1;
@@ -3032,10 +3033,10 @@
 
     if (cm->frame_type == KEY_FRAME)
     {
-        yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG | VP8_ALT_FLAG ;
+        yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FRAME | VP8_ALTR_FRAME ;
 
-        yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
-        yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+        yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
+        yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
 
         cm->alt_fb_idx = cm->gld_fb_idx = cm->new_fb_idx;
     }
@@ -3045,8 +3046,8 @@
         {
             assert(!cm->copy_buffer_to_arf);
 
-            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALT_FLAG;
-            cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALTR_FRAME;
+            cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
             cm->alt_fb_idx = cm->new_fb_idx;
         }
         else if (cm->copy_buffer_to_arf)
@@ -3057,8 +3058,8 @@
             {
                 if(cm->alt_fb_idx != cm->lst_fb_idx)
                 {
-                    yv12_fb[cm->lst_fb_idx].flags |= VP8_ALT_FLAG;
-                    yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+                    yv12_fb[cm->lst_fb_idx].flags |= VP8_ALTR_FRAME;
+                    yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
                     cm->alt_fb_idx = cm->lst_fb_idx;
                 }
             }
@@ -3066,8 +3067,8 @@
             {
                 if(cm->alt_fb_idx != cm->gld_fb_idx)
                 {
-                    yv12_fb[cm->gld_fb_idx].flags |= VP8_ALT_FLAG;
-                    yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+                    yv12_fb[cm->gld_fb_idx].flags |= VP8_ALTR_FRAME;
+                    yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
                     cm->alt_fb_idx = cm->gld_fb_idx;
                 }
             }
@@ -3077,8 +3078,8 @@
         {
             assert(!cm->copy_buffer_to_gf);
 
-            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG;
-            cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FRAME;
+            cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
             cm->gld_fb_idx = cm->new_fb_idx;
         }
         else if (cm->copy_buffer_to_gf)
@@ -3089,8 +3090,8 @@
             {
                 if(cm->gld_fb_idx != cm->lst_fb_idx)
                 {
-                    yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FLAG;
-                    yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+                    yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FRAME;
+                    yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
                     cm->gld_fb_idx = cm->lst_fb_idx;
                 }
             }
@@ -3098,8 +3099,8 @@
             {
                 if(cm->alt_fb_idx != cm->gld_fb_idx)
                 {
-                    yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FLAG;
-                    yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+                    yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FRAME;
+                    yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
                     cm->gld_fb_idx = cm->alt_fb_idx;
                 }
             }
@@ -3108,8 +3109,8 @@
 
     if (cm->refresh_last_frame)
     {
-        cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FLAG;
-        cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FLAG;
+        cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FRAME;
+        cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FRAME;
         cm->lst_fb_idx = cm->new_fb_idx;
     }
 }
@@ -3311,6 +3312,17 @@
         cm->frame_type = KEY_FRAME;
     }
 
+#if CONFIG_MULTI_RES_ENCODING
+    /* In multi-resolution encoding, frame_type is decided by lowest-resolution
+     * encoder. Same frame_type is adopted while encoding at other resolution.
+     */
+    if (cpi->oxcf.mr_encoder_id)
+    {
+        cm->frame_type =
+            ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->frame_type;
+    }
+#endif
+
     // Set default state for segment and mode based loop filter update flags
     cpi->mb.e_mbd.update_mb_segmentation_map = 0;
     cpi->mb.e_mbd.update_mb_segmentation_data = 0;
@@ -4311,30 +4323,6 @@
         }
     }
 
-#if 0
-
-    // If the frame was massively oversize and we are below optimal buffer level drop next frame
-    if ((cpi->drop_frames_allowed) &&
-        (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
-        (cpi->buffer_level < cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100) &&
-        (cpi->projected_frame_size > (4 * cpi->this_frame_target)))
-    {
-        cpi->drop_frame = 1;
-    }
-
-#endif
-
-    // Set the count for maximum consecutive dropped frames based upon the ratio of
-    // this frame size to the target average per frame bandwidth.
-    // (cpi->av_per_frame_bandwidth > 0) is just a sanity check to prevent / 0.
-    if (cpi->drop_frames_allowed && (cpi->av_per_frame_bandwidth > 0))
-    {
-        cpi->max_drop_count = cpi->projected_frame_size / cpi->av_per_frame_bandwidth;
-
-        if (cpi->max_drop_count > cpi->max_consec_dropped_frames)
-            cpi->max_drop_count = cpi->max_consec_dropped_frames;
-    }
-
     // Update the buffer level variable.
     // Non-viewable frames are a special case and are treated as pure overhead.
     if ( !cm->show_frame )
@@ -4525,16 +4513,16 @@
     else if (cm->refresh_alt_ref_frame ^ cm->refresh_golden_frame) // 1 refreshed but not the other
         cpi->gold_is_alt = 0;
 
-    cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+    cpi->ref_frame_flags = VP8_ALTR_FRAME | VP8_GOLD_FRAME | VP8_LAST_FRAME;
 
     if (cpi->gold_is_last)
-        cpi->ref_frame_flags &= ~VP8_GOLD_FLAG;
+        cpi->ref_frame_flags &= ~VP8_GOLD_FRAME;
 
     if (cpi->alt_is_last)
-        cpi->ref_frame_flags &= ~VP8_ALT_FLAG;
+        cpi->ref_frame_flags &= ~VP8_ALTR_FRAME;
 
     if (cpi->gold_is_alt)
-        cpi->ref_frame_flags &= ~VP8_ALT_FLAG;
+        cpi->ref_frame_flags &= ~VP8_ALTR_FRAME;
 
 
     if (!cpi->oxcf.error_resilient_mode)
@@ -4921,7 +4909,7 @@
 
             if (cpi->oxcf.number_of_layers > 1)
             {
-                int i;
+                unsigned int i;
 
                 // Update frame rates for each layer
                 for (i=0; i<cpi->oxcf.number_of_layers; i++)
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 900141b..3b202c9 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -25,6 +25,7 @@
 #include "vp8/common/threading.h"
 #include "vpx_ports/mem.h"
 #include "vpx/internal/vpx_codec_internal.h"
+#include "vpx/vp8.h"
 #include "mcomp.h"
 #include "vp8/common/findnearmv.h"
 #include "lookahead.h"
@@ -435,10 +436,6 @@
 
     int drop_frames_allowed;          // Are we permitted to drop frames?
     int drop_frame;                  // Drop this frame?
-    int drop_count;                  // How many frames have we dropped?
-    int max_drop_count;               // How many frames should we drop?
-    int max_consec_dropped_frames;     // Limit number of consecutive frames that can be dropped.
-
 
     int ymode_count [VP8_YMODES];        /* intra MB type cts this frame */
     int uv_mode_count[VP8_UV_MODES];       /* intra MB type cts this frame */
@@ -689,6 +686,17 @@
     int    mr_low_res_mb_cols;
 #endif
 
+    struct rd_costs_struct
+    {
+        int mvcosts[2][MVvals+1];
+        int mvsadcosts[2][MVfpvals+1];
+        int mbmode_cost[2][MB_MODE_COUNT];
+        int intra_uv_mode_cost[2][MB_MODE_COUNT];
+        int bmode_costs[10][10][10];
+        int inter_bmode_costs[B_MODE_COUNT];
+        int token_costs[BLOCK_TYPES][COEF_BANDS]
+        [PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
+    } rd_costs;
 } VP8_COMP;
 
 void control_data_rate(VP8_COMP *cpi);
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index 7f81713..47d646f 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -132,7 +132,7 @@
     MACROBLOCK *x,
     int ib,
     B_PREDICTION_MODE *best_mode,
-    unsigned int *mode_costs,
+    const int *mode_costs,
 
     int *bestrate,
     int *bestdistortion)
@@ -185,7 +185,7 @@
     int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
     int error;
     int distortion = 0;
-    unsigned int *bmode_costs;
+    const int *bmode_costs;
 
     intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);
 
@@ -405,8 +405,8 @@
                                MB_PREDICTION_MODE *parent_mode,
                                int_mv *parent_ref_mv, int mb_row, int mb_col)
 {
-    LOWER_RES_INFO* store_mode_info
-                          = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
+    LOWER_RES_MB_INFO* store_mode_info
+                          = ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->mb_info;
     unsigned int parent_mb_index;
     //unsigned int parent_mb_index = map_640x480_to_320x240[mb_row][mb_col];
 
@@ -458,7 +458,7 @@
     if (sse < x->encode_breakout)
     {
         // Check u and v to make sure skip is ok
-        int sse2 = 0;
+        unsigned int sse2 = 0;
 
         sse2 = VP8_UVSSE(x);
 
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 472e85f..f6baf4c 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -235,11 +235,9 @@
     cc->frames_since_golden       = cpi->common.frames_since_golden;
 
     vp8_copy(cc->mvc,      cpi->common.fc.mvc);
-    vp8_copy(cc->mvcosts,  cpi->mb.mvcosts);
+    vp8_copy(cc->mvcosts,  cpi->rd_costs.mvcosts);
 
-    vp8_copy(cc->kf_ymode_prob,   cpi->common.kf_ymode_prob);
     vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
-    vp8_copy(cc->kf_uv_mode_prob,  cpi->common.kf_uv_mode_prob);
     vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
 
     vp8_copy(cc->ymode_count, cpi->ymode_count);
@@ -274,11 +272,9 @@
 
     vp8_copy(cpi->common.fc.mvc, cc->mvc);
 
-    vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
+    vp8_copy(cpi->rd_costs.mvcosts, cc->mvcosts);
 
-    vp8_copy(cpi->common.kf_ymode_prob,   cc->kf_ymode_prob);
     vp8_copy(cpi->common.fc.ymode_prob,   cc->ymode_prob);
-    vp8_copy(cpi->common.kf_uv_mode_prob,  cc->kf_uv_mode_prob);
     vp8_copy(cpi->common.fc.uv_mode_prob,  cc->uv_mode_prob);
 
     vp8_copy(cpi->ymode_count, cc->ymode_count);
@@ -305,9 +301,6 @@
 
     vp8_default_coef_probs(& cpi->common);
 
-
-    vp8_kf_default_bmode_probs(cpi->common.kf_bmode_prob);
-
     vpx_memcpy(cpi->common.fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
     {
         int flag[2] = {1, 1};
@@ -357,7 +350,7 @@
 {
     // boost defaults to half second
     int kf_boost;
-    int target;
+    unsigned int target;
 
     // Clear down mmx registers to allow floating point in what follows
     vp8_clear_system_state();  //__asm emms;
@@ -973,7 +966,7 @@
     // In unbufferd mode (eg vide conferencing) the descision to
     // code or drop a frame is made outside the codec in response to real
     // world comms or buffer considerations.
-    if (cpi->drop_frames_allowed && cpi->buffered_mode &&
+    if (cpi->drop_frames_allowed &&
         (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
         ((cpi->common.frame_type != KEY_FRAME))) //|| !cpi->oxcf.allow_spatial_resampling) )
     {
@@ -991,28 +984,13 @@
             //vpx_log("Decoder: Drop frame due to bandwidth: %d \n",cpi->buffer_level, cpi->av_per_frame_bandwidth);
 
             cpi->drop_frame = 1;
-        }
 
-#if 0
-        // Check for other drop frame crtieria (Note 2 pass cbr uses decimation on whole KF sections)
-        else if ((cpi->buffer_level < cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100) &&
-                 (cpi->drop_count < cpi->max_drop_count) && (cpi->pass == 0))
-        {
-            cpi->drop_frame = 1;
-        }
-
-#endif
-
-        if (cpi->drop_frame)
-        {
             // Update the buffer level variable.
             cpi->bits_off_target += cpi->av_per_frame_bandwidth;
             if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
               cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
             cpi->buffer_level = cpi->bits_off_target;
         }
-        else
-            cpi->drop_count = 0;
     }
 
     // Adjust target frame size for Golden Frames:
@@ -1561,7 +1539,6 @@
         if (cpi->drop_frame)
         {
             cpi->drop_frame = 0;
-            cpi->drop_count++;
             return 0;
         }
     }
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 27956b1..6a1c4b7 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -149,8 +149,8 @@
 };
 
 static void fill_token_costs(
-    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS],
-    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]
+    int c[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],
+    const vp8_prob p[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]
 )
 {
     int i, j, k;
@@ -159,21 +159,24 @@
     for (i = 0; i < BLOCK_TYPES; i++)
         for (j = 0; j < COEF_BANDS; j++)
             for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+
                 // check for pt=0 and band > 1 if block type 0 and 0 if blocktype 1
-                if(k==0 && j>(i==0) )
-                    vp8_cost_tokens2((int *)(c [i][j][k]), p [i][j][k], vp8_coef_tree,2);
+                if (k == 0 && j > (i == 0))
+                    vp8_cost_tokens2(c[i][j][k], p [i][j][k], vp8_coef_tree, 2);
                 else
-                    vp8_cost_tokens((int *)(c [i][j][k]), p [i][j][k], vp8_coef_tree);
+                    vp8_cost_tokens(c[i][j][k], p [i][j][k], vp8_coef_tree);
 }
 
-static int rd_iifactor [ 32 ] =  {    4,   4,   3,   2,   1,   0,   0,   0,
-                                      0,   0,   0,   0,   0,   0,   0,   0,
-                                      0,   0,   0,   0,   0,   0,   0,   0,
-                                      0,   0,   0,   0,   0,   0,   0,   0,
-                                 };
+static const int rd_iifactor[32] =
+{
+    4, 4, 3, 2, 1, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
+};
 
 /* values are now correlated to quantizer */
-static int sad_per_bit16lut[QINDEX_RANGE] =
+static const int sad_per_bit16lut[QINDEX_RANGE] =
 {
     2,  2,  2,  2,  2,  2,  2,  2,
     2,  2,  2,  2,  2,  2,  2,  2,
@@ -192,7 +195,7 @@
     11, 11, 11, 11, 12, 12, 12, 12,
     12, 12, 13, 13, 13, 13, 14, 14
 };
-static int sad_per_bit4lut[QINDEX_RANGE] =
+static const int sad_per_bit4lut[QINDEX_RANGE] =
 {
     2,  2,  2,  2,  2,  2,  3,  3,
     3,  3,  3,  3,  3,  3,  3,  3,
@@ -637,7 +640,7 @@
     BLOCK *be,
     BLOCKD *b,
     B_PREDICTION_MODE *best_mode,
-    unsigned int *bmode_costs,
+    const int *bmode_costs,
     ENTROPY_CONTEXT *a,
     ENTROPY_CONTEXT *l,
 
@@ -717,7 +720,7 @@
     ENTROPY_CONTEXT_PLANES t_above, t_left;
     ENTROPY_CONTEXT *ta;
     ENTROPY_CONTEXT *tl;
-    unsigned int *bmode_costs;
+    const int *bmode_costs;
 
     vpx_memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
     vpx_memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
@@ -1766,7 +1769,7 @@
     {
         unsigned int sse;
         unsigned int var;
-        int threshold = (xd->block[0].dequant[1]
+        unsigned int threshold = (xd->block[0].dequant[1]
                     * xd->block[0].dequant[1] >>4);
 
         if(threshold < x->encode_breakout)
@@ -1785,7 +1788,7 @@
                 (sse /2 > var && sse-var < 64))
             {
                 // Check u and v to make sure skip is ok
-                int sse2=  VP8_UVSSE(x);
+                unsigned int sse2 = VP8_UVSSE(x);
                 if (sse2 * 2 < threshold)
                 {
                     x->skip = 1;
@@ -1967,6 +1970,11 @@
             best_rd_sse = INT_MAX;
 #endif
 
+#if CONFIG_TEMPORAL_DENOISING
+    unsigned int zero_mv_sse = INT_MAX, best_sse = INT_MAX,
+            best_rd_sse = INT_MAX;
+#endif
+
     mode_mv = mode_mv_sb[sign_bias];
     best_ref_mv.as_int = 0;
     best_mode.rd = INT_MAX;
diff --git a/vp8/encoder/rdopt.h b/vp8/encoder/rdopt.h
index db939f9..bbcb59f 100644
--- a/vp8/encoder/rdopt.h
+++ b/vp8/encoder/rdopt.h
@@ -86,15 +86,15 @@
                                        unsigned int    recon_yoffset,
                                        unsigned int    recon_uvoffset)
 {
-    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+    if (cpi->ref_frame_flags & VP8_LAST_FRAME)
         get_plane_pointers(&cpi->common.yv12_fb[cpi->common.lst_fb_idx],
                            plane[LAST_FRAME], recon_yoffset, recon_uvoffset);
 
-    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+    if (cpi->ref_frame_flags & VP8_GOLD_FRAME)
         get_plane_pointers(&cpi->common.yv12_fb[cpi->common.gld_fb_idx],
                            plane[GOLDEN_FRAME], recon_yoffset, recon_uvoffset);
 
-    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+    if (cpi->ref_frame_flags & VP8_ALTR_FRAME)
         get_plane_pointers(&cpi->common.yv12_fb[cpi->common.alt_fb_idx],
                            plane[ALTREF_FRAME], recon_yoffset, recon_uvoffset);
 }
@@ -106,11 +106,11 @@
     int i=0;
 
     ref_frame_map[i++] = INTRA_FRAME;
-    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+    if (cpi->ref_frame_flags & VP8_LAST_FRAME)
         ref_frame_map[i++] = LAST_FRAME;
-    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+    if (cpi->ref_frame_flags & VP8_GOLD_FRAME)
         ref_frame_map[i++] = GOLDEN_FRAME;
-    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+    if (cpi->ref_frame_flags & VP8_ALTR_FRAME)
         ref_frame_map[i++] = ALTREF_FRAME;
     for(; i<4; i++)
         ref_frame_map[i] = -1;
diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c
index 6c61b36..b391d5a 100644
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -134,7 +134,6 @@
 }
 
 #if ALT_REF_MC_ENABLED
-static int dummy_cost[2*mv_max+1];
 
 static int vp8_temporal_filter_find_matching_mb_c
 (
@@ -155,9 +154,6 @@
     int_mv best_ref_mv1;
     int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
 
-    int *mvcost[2]    = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
-    int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
-
     // Save input state
     unsigned char **base_src = b->base_src;
     int src = b->src;
@@ -191,12 +187,11 @@
 
     /*cpi->sf.search_method == HEX*/
     // TODO Check that the 16x16 vf & sdf are selected here
-    bestsme = vp8_hex_search(x, b, d,
-        &best_ref_mv1_full, &d->bmi.mv,
-        step_param,
-        sadpb,
-        &cpi->fn_ptr[BLOCK_16X16],
-        mvsadcost, mvcost, &best_ref_mv1);
+    // Ignore mv costing by sending NULL cost arrays
+    bestsme = vp8_hex_search(x, b, d, &best_ref_mv1_full, &d->bmi.mv,
+                             step_param, sadpb,
+                             &cpi->fn_ptr[BLOCK_16X16],
+                             NULL, NULL, &best_ref_mv1);
 
 #if ALT_REF_SUBPEL_ENABLED
     // Try sub-pixel MC?
@@ -204,10 +199,13 @@
     {
         int distortion;
         unsigned int sse;
+        // Ignore mv costing by sending NULL cost array
         bestsme = cpi->find_fractional_mv_step(x, b, d,
-                    &d->bmi.mv, &best_ref_mv1,
-                    x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
-                    mvcost, &distortion, &sse);
+                                               &d->bmi.mv,
+                                               &best_ref_mv1,
+                                               x->errorperbit,
+                                               &cpi->fn_ptr[BLOCK_16X16],
+                                               NULL, &distortion, &sse);
     }
 #endif
 
@@ -285,32 +283,36 @@
 
             for (frame = 0; frame < frame_count; frame++)
             {
-                int err = 0;
-
                 if (cpi->frames[frame] == NULL)
                     continue;
 
                 mbd->block[0].bmi.mv.as_mv.row = 0;
                 mbd->block[0].bmi.mv.as_mv.col = 0;
 
+                if (frame == alt_ref_index)
+                {
+                    filter_weight = 2;
+                }
+                else
+                {
+                    int err = 0;
 #if ALT_REF_MC_ENABLED
 #define THRESH_LOW   10000
 #define THRESH_HIGH  20000
-
-                // Find best match in this frame by MC
-                err = vp8_temporal_filter_find_matching_mb_c
-                      (cpi,
-                       cpi->frames[alt_ref_index],
-                       cpi->frames[frame],
-                       mb_y_offset,
-                       THRESH_LOW);
-
+                    // Find best match in this frame by MC
+                    err = vp8_temporal_filter_find_matching_mb_c
+                              (cpi,
+                               cpi->frames[alt_ref_index],
+                               cpi->frames[frame],
+                               mb_y_offset,
+                               THRESH_LOW);
 #endif
-                // Assign higher weight to matching MB if it's error
-                // score is lower. If not applying MC default behavior
-                // is to weight all MBs equal.
-                filter_weight = err<THRESH_LOW
-                                  ? 2 : err<THRESH_HIGH ? 1 : 0;
+                    // Assign higher weight to matching MB if it's error
+                    // score is lower. If not applying MC default behavior
+                    // is to weight all MBs equal.
+                    filter_weight = err<THRESH_LOW
+                                       ? 2 : err<THRESH_HIGH ? 1 : 0;
+                }
 
                 if (filter_weight != 0)
                 {
diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk
index 3a7b146..1fbe5d4 100644
--- a/vp8/vp8_common.mk
+++ b/vp8/vp8_common.mk
@@ -30,7 +30,6 @@
 VP8_COMMON_SRCS-yes += common/generic/systemdependent.c
 VP8_COMMON_SRCS-yes += common/idct_blk.c
 VP8_COMMON_SRCS-yes += common/idctllm.c
-VP8_COMMON_SRCS-yes += common/idctllm_test.cc
 VP8_COMMON_SRCS-yes += common/alloccommon.h
 VP8_COMMON_SRCS-yes += common/blockd.h
 VP8_COMMON_SRCS-yes += common/common.h
@@ -85,7 +84,6 @@
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/dequantize_mmx.asm
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idct_blk_mmx.c
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx.asm
-VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx_test.cc
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/iwalsh_mmx.asm
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/loopfilter_mmx.asm
 VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/recon_mmx.asm
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 5fb74c4..472db6e 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -227,7 +227,7 @@
 
     if (cfg->ts_number_layers > 1)
     {
-        int i;
+        unsigned int i;
         RANGE_CHECK_HI(cfg, ts_periodicity, 16);
 
         for (i=1; i<cfg->ts_number_layers; i++)
@@ -447,7 +447,7 @@
     vpx_codec_err_t res;
 
     if (((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
-        && cfg->g_lag_in_frames > 1)
+        && (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS))
         ERROR("Cannot change width or height after initialization");
 
     /* Prevent increasing lag_in_frames. This check is stricter than it needs
@@ -542,19 +542,27 @@
     vpx_codec_err_t res = 0;
 
 #if CONFIG_MULTI_RES_ENCODING
+    LOWER_RES_FRAME_INFO *shared_mem_loc;
     int mb_rows = ((cfg->g_w + 15) >>4);
     int mb_cols = ((cfg->g_h + 15) >>4);
 
-    *mem_loc = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_INFO));
-    if(!(*mem_loc))
+    shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO));
+    if(!shared_mem_loc)
     {
-        free(*mem_loc);
+        res = VPX_CODEC_MEM_ERROR;
+    }
+
+    shared_mem_loc->mb_info = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_MB_INFO));
+    if(!(shared_mem_loc->mb_info))
+    {
         res = VPX_CODEC_MEM_ERROR;
     }
     else
+    {
+        *mem_loc = (void *)shared_mem_loc;
         res = VPX_CODEC_OK;
+    }
 #endif
-
     return res;
 }
 
@@ -647,7 +655,11 @@
 #if CONFIG_MULTI_RES_ENCODING
     /* Free multi-encoder shared memory */
     if (ctx->oxcf.mr_total_resolutions > 0 && (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions-1))
+    {
+        LOWER_RES_FRAME_INFO *shared_mem_loc = (LOWER_RES_FRAME_INFO *)ctx->oxcf.mr_low_res_mode_info;
+        free(shared_mem_loc->mb_info);
         free(ctx->oxcf.mr_low_res_mode_info);
+    }
 #endif
 
     free(ctx->cx_data);
@@ -733,6 +745,9 @@
     if (!ctx->cfg.rc_target_bitrate)
         return res;
 
+    if (!ctx->cfg.rc_target_bitrate)
+        return res;
+
     if (img)
         res = validate_img(ctx, img);
 
@@ -756,13 +771,13 @@
         int ref = 7;
 
         if (flags & VP8_EFLAG_NO_REF_LAST)
-            ref ^= VP8_LAST_FLAG;
+            ref ^= VP8_LAST_FRAME;
 
         if (flags & VP8_EFLAG_NO_REF_GF)
-            ref ^= VP8_GOLD_FLAG;
+            ref ^= VP8_GOLD_FRAME;
 
         if (flags & VP8_EFLAG_NO_REF_ARF)
-            ref ^= VP8_ALT_FLAG;
+            ref ^= VP8_ALTR_FRAME;
 
         vp8_use_as_reference(ctx->cpi, ref);
     }
@@ -774,13 +789,13 @@
         int upd = 7;
 
         if (flags & VP8_EFLAG_NO_UPD_LAST)
-            upd ^= VP8_LAST_FLAG;
+            upd ^= VP8_LAST_FRAME;
 
         if (flags & VP8_EFLAG_NO_UPD_GF)
-            upd ^= VP8_GOLD_FLAG;
+            upd ^= VP8_GOLD_FRAME;
 
         if (flags & VP8_EFLAG_NO_UPD_ARF)
-            upd ^= VP8_ALT_FLAG;
+            upd ^= VP8_ALTR_FRAME;
 
         vp8_update_reference(ctx->cpi, upd);
     }
diff --git a/vp8_multi_resolution_encoder.c b/vp8_multi_resolution_encoder.c
index 78f50c2..497d8f7 100644
--- a/vp8_multi_resolution_encoder.c
+++ b/vp8_multi_resolution_encoder.c
@@ -164,7 +164,7 @@
     mem_put_le32(header+24, frame_cnt);           /* length */
     mem_put_le32(header+28, 0);                   /* unused */
 
-    if(fwrite(header, 1, 32, outfile));
+    (void) fwrite(header, 1, 32, outfile);
 }
 
 static void write_ivf_frame_header(FILE *outfile,
@@ -181,7 +181,7 @@
     mem_put_le32(header+4, pts&0xFFFFFFFF);
     mem_put_le32(header+8, pts >> 32);
 
-    if(fwrite(header, 1, 12, outfile));
+    (void) fwrite(header, 1, 12, outfile);
 }
 
 int main(int argc, char **argv)
@@ -288,8 +288,13 @@
     cfg[0].g_lag_in_frames   = 0;
 
     /* Disable automatic keyframe placement */
+    /* Note: These 3 settings are copied to all levels. But, except the lowest
+     * resolution level, all other levels are set to VPX_KF_DISABLED internally.
+     */
     //cfg[0].kf_mode           = VPX_KF_DISABLED;
-    cfg[0].kf_min_dist = cfg[0].kf_max_dist = 1000;
+    cfg[0].kf_mode           = VPX_KF_AUTO;
+    cfg[0].kf_min_dist = 0;
+    cfg[0].kf_max_dist = 150;
 
     cfg[0].rc_target_bitrate = target_bitrate[0];       /* Set target bitrate */
     cfg[0].g_timebase.num = 1;                          /* Set fps */
@@ -405,8 +410,8 @@
                 switch(pkt[i]->kind) {
                     case VPX_CODEC_CX_FRAME_PKT:
                         write_ivf_frame_header(outfile[i], pkt[i]);
-                        if(fwrite(pkt[i]->data.frame.buf, 1, pkt[i]->data.frame.sz,
-                                  outfile[i]));
+                        (void) fwrite(pkt[i]->data.frame.buf, 1,
+                                      pkt[i]->data.frame.sz, outfile[i]);
                     break;
                     case VPX_CODEC_PSNR_PKT:
                         if (show_psnr)
diff --git a/vp8_scalable_patterns.c b/vp8_scalable_patterns.c
index 9351874..bd88414 100644
--- a/vp8_scalable_patterns.c
+++ b/vp8_scalable_patterns.c
@@ -93,7 +93,7 @@
     mem_put_le32(header+24, frame_cnt);           /* length */
     mem_put_le32(header+28, 0);                   /* unused */
 
-    if(fwrite(header, 1, 32, outfile));
+    (void) fwrite(header, 1, 32, outfile);
 }
 
 
@@ -111,7 +111,7 @@
     mem_put_le32(header+4, pts&0xFFFFFFFF);
     mem_put_le32(header+8, pts >> 32);
 
-    if(fwrite(header, 1, 12, outfile));
+    (void) fwrite(header, 1, 12, outfile);
 }
 
 static int mode_to_num_layers[9] = {2, 2, 3, 3, 3, 3, 5, 2, 3};
@@ -156,7 +156,7 @@
     if (argc != 8+mode_to_num_layers[layering_mode])
         die ("Invalid number of arguments");
 
-    if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 1))
+    if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 32))
         die ("Failed to allocate image", width, height);
 
     printf("Using %s\n",vpx_codec_iface_name(interface));
@@ -530,8 +530,8 @@
                                               i<cfg.ts_number_layers; i++)
                 {
                     write_ivf_frame_header(outfile[i], pkt);
-                    if (fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
-                              outfile[i]));
+                    (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
+                                  outfile[i]);
                     frames_in_layer[i]++;
                 }
                 break;
@@ -562,4 +562,3 @@
 
     return EXIT_SUCCESS;
 }
-
diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c
index 03ddc62..db0120c 100644
--- a/vpx/src/vpx_encoder.c
+++ b/vpx/src/vpx_encoder.c
@@ -117,6 +117,13 @@
                 mr_cfg.mr_down_sampling_factor.num = dsf->num;
                 mr_cfg.mr_down_sampling_factor.den = dsf->den;
 
+                /* Force Key-frame synchronization. Namely, encoder at higher
+                 * resolution always use the same frame_type chosen by the
+                 * lowest-resolution encoder.
+                 */
+                if(mr_cfg.mr_encoder_id)
+                    cfg->kf_mode = VPX_KF_DISABLED;
+
                 ctx->iface = iface;
                 ctx->name = iface->name;
                 ctx->priv = NULL;
diff --git a/vpx_ports/asm_offsets.h b/vpx_ports/asm_offsets.h
index d3b4fc7..fc1287e 100644
--- a/vpx_ports/asm_offsets.h
+++ b/vpx_ports/asm_offsets.h
@@ -23,7 +23,7 @@
 #define BEGIN int main(void) {
 #define END return 0; }
 #else
-#define DEFINE(sym, val) int sym = val;
+#define DEFINE(sym, val) const int sym = val;
 #define BEGIN
 #define END
 #endif
diff --git a/vpxdec.c b/vpxdec.c
index 4482f3d..67e99a8 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -356,7 +356,7 @@
     }
     else
     {
-        if(fwrite(buf, 1, len, out));
+        (void) fwrite(buf, 1, len, out);
     }
 }
 
diff --git a/vpxenc.c b/vpxenc.c
index d32b21b..a86e237 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -245,7 +245,7 @@
 {
     if (stats->file)
     {
-        if(fwrite(pkt, 1, len, stats->file));
+        (void) fwrite(pkt, 1, len, stats->file);
     }
     else
     {
@@ -338,7 +338,7 @@
              * write_ivf_frame_header() for documentation on the frame header
              * layout.
              */
-            if(fread(junk, 1, IVF_FRAME_HDR_SZ, f));
+            (void) fread(junk, 1, IVF_FRAME_HDR_SZ, f);
         }
 
         for (plane = 0; plane < 3; plane++)
@@ -468,7 +468,7 @@
     mem_put_le32(header + 24, frame_cnt);         /* length */
     mem_put_le32(header + 28, 0);                 /* unused */
 
-    if(fwrite(header, 1, 32, outfile));
+    (void) fwrite(header, 1, 32, outfile);
 }
 
 
@@ -486,14 +486,14 @@
     mem_put_le32(header + 4, pts & 0xFFFFFFFF);
     mem_put_le32(header + 8, pts >> 32);
 
-    if(fwrite(header, 1, 12, outfile));
+    (void) fwrite(header, 1, 12, outfile);
 }
 
 static void write_ivf_frame_size(FILE *outfile, size_t size)
 {
     char             header[4];
     mem_put_le32(header, size);
-    fwrite(header, 1, 4, outfile);
+    (void) fwrite(header, 1, 4, outfile);
 }
 
 
@@ -541,7 +541,7 @@
 
 void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len)
 {
-    if(fwrite(buffer_in, 1, len, glob->stream));
+    (void) fwrite(buffer_in, 1, len, glob->stream);
 }
 
 #define WRITE_BUFFER(s) \
@@ -2259,8 +2259,8 @@
                     }
                 }
 
-                fwrite(pkt->data.frame.buf, 1,
-                       pkt->data.frame.sz, stream->file);
+                (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
+                              stream->file);
             }
             stream->nbytes += pkt->data.raw.sz;
             break;
@@ -2437,7 +2437,7 @@
                 vpx_img_alloc(&raw,
                               input.use_i420 ? VPX_IMG_FMT_I420
                                              : VPX_IMG_FMT_YV12,
-                              input.w, input.h, 1);
+                              input.w, input.h, 32);
 
             FOREACH_STREAM(init_rate_histogram(&stream->rate_hist,
                                                &stream->config.cfg,