diff --git a/build/arm-msvs/obj_int_extract.bat b/build/arm-msvs/obj_int_extract.bat
new file mode 100644
index 0000000000000000000000000000000000000000..147342d3d1a7d5ae8fa3a80d90c8f2eff3f4a9aa
--- /dev/null
+++ b/build/arm-msvs/obj_int_extract.bat
@@ -0,0 +1,25 @@
+REM   Copyright (c) 2013 The WebM project authors. All Rights Reserved.
+REM
+REM   Use of this source code is governed by a BSD-style license
+REM   that can be found in the LICENSE file in the root of the source
+REM   tree. An additional intellectual property rights grant can be found
+REM   in the file PATENTS.  All contributing project authors may
+REM   be found in the AUTHORS file in the root of the source tree.
+echo on
+
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/common/vp9_asm_com_offsets.c"
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/decoder/vp9_asm_dec_offsets.c"
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp9/encoder/vp9_asm_enc_offsets.c"
+obj_int_extract.exe rvds "vp9_asm_com_offsets.obj" > "vp9_asm_com_offsets.asm"
+obj_int_extract.exe rvds "vp9_asm_dec_offsets.obj" > "vp9_asm_dec_offsets.asm"
+obj_int_extract.exe rvds "vp9_asm_enc_offsets.obj" > "vp9_asm_enc_offsets.asm"
+
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/common/vp8_asm_com_offsets.c"
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/decoder/vp8_asm_dec_offsets.c"
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/encoder/vp8_asm_enc_offsets.c"
+obj_int_extract.exe rvds "vp8_asm_com_offsets.obj" > "vp8_asm_com_offsets.asm"
+obj_int_extract.exe rvds "vp8_asm_dec_offsets.obj" > "vp8_asm_dec_offsets.asm"
+obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm"
+
+cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vpx_scale/vpx_scale_asm_offsets.c"
+obj_int_extract.exe rvds "vpx_scale_asm_offsets.obj" > "vpx_scale_asm_offsets.asm"
diff --git a/build/make/Makefile b/build/make/Makefile
index de71c613317944036db0ec41e935b82ce15631bf..7a2523960d3f653a0727aad5f4d5841758104b69 100644
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -388,11 +388,14 @@ ifneq ($(call enabled,DIST-SRCS),)
     DIST-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_sln.sh
     DIST-SRCS-$(CONFIG_MSVS)  += build/x86-msvs/yasm.rules
     DIST-SRCS-$(CONFIG_MSVS)  += build/x86-msvs/obj_int_extract.bat
+    DIST-SRCS-$(CONFIG_MSVS)  += build/arm-msvs/obj_int_extract.bat
     DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh
     # Include obj_int_extract if we use offsets from *_asm_*_offsets
     DIST-SRCS-$(ARCH_ARM)$(ARCH_X86)$(ARCH_X86_64)    += build/make/obj_int_extract.c
     DIST-SRCS-$(ARCH_ARM)    += build/make/ads2gas.pl
     DIST-SRCS-$(ARCH_ARM)    += build/make/ads2gas_apple.pl
+    DIST-SRCS-$(ARCH_ARM)    += build/make/ads2armasm_ms.pl
+    DIST-SRCS-$(ARCH_ARM)    += build/make/thumb.pm
     DIST-SRCS-yes            += $(target:-$(TOOLCHAIN)=).mk
 endif
 INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS)
diff --git a/build/make/ads2armasm_ms.pl b/build/make/ads2armasm_ms.pl
new file mode 100755
index 0000000000000000000000000000000000000000..1def53901d42fb0e214c571b692af2d37f4a40c1
--- /dev/null
+++ b/build/make/ads2armasm_ms.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+##
+##  Copyright (c) 2013 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.
+##
+
+use FindBin;
+use lib $FindBin::Bin;
+use thumb;
+
+print "; This file was created from a .asm file\n";
+print ";  using the ads2armasm_ms.pl script.\n";
+
+while (<STDIN>)
+{
+    undef $comment;
+    undef $line;
+
+    s/REQUIRE8//;
+    s/PRESERVE8//;
+    s/^\s*ARM\s*$//;
+    s/AREA\s+\|\|(.*)\|\|/AREA |$1|/;
+    s/qsubaddx/qsax/i;
+    s/qaddsubx/qasx/i;
+
+    thumb::FixThumbInstructions($_, 1);
+
+    s/ldrneb/ldrbne/i;
+    s/ldrneh/ldrhne/i;
+
+    print;
+}
+
diff --git a/build/make/ads2gas.pl b/build/make/ads2gas.pl
index 95be467ab1ea62395cfbaa123db9d1f6db94b518..9c41901295f51ee70febb0b6556d912c2d1fd72f 100755
--- a/build/make/ads2gas.pl
+++ b/build/make/ads2gas.pl
@@ -17,9 +17,24 @@
 #
 # Usage: cat inputfile | perl ads2gas.pl > outputfile
 #
+
+use FindBin;
+use lib $FindBin::Bin;
+use thumb;
+
+my $thumb = 0;
+
+foreach my $arg (@ARGV) {
+    $thumb = 1 if ($arg eq "-thumb");
+}
+
 print "@ This file was created from a .asm file\n";
 print "@  using the ads2gas.pl script.\n";
 print "\t.equ DO1STROUNDING, 0\n";
+if ($thumb) {
+    print "\t.syntax unified\n";
+    print "\t.thumb\n";
+}
 
 # Stack of procedure names.
 @proc_stack = ();
@@ -151,8 +166,13 @@ while (<STDIN>)
     # ALIGN directive
     s/\bALIGN\b/.balign/g;
 
-    # ARM code
-    s/\sARM/.arm/g;
+    if ($thumb) {
+        # ARM code - we force everything to thumb with the declaration in the header
+        s/\sARM//g;
+    } else {
+        # ARM code
+        s/\sARM/.arm/g;
+    }
 
     # push/pop
     s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g;
@@ -162,6 +182,10 @@ while (<STDIN>)
     s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g;
     s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g;
 
+    if ($thumb) {
+        thumb::FixThumbInstructions($_, 0);
+    }
+
     # eabi_attributes numerical equivalents can be found in the
     # "ARM IHI 0045C" document.
 
diff --git a/build/make/configure.sh b/build/make/configure.sh
index c50ef58ad923f9251331e7bea396eeafd1287fee..ee4493d2b5f3b870ba0c7ee66c6fce350a95de38 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -88,6 +88,7 @@ Build options:
   ${toggle_debug}             enable/disable debug mode
   ${toggle_gprof}             enable/disable gprof profiling instrumentation
   ${toggle_gcov}              enable/disable gcov coverage instrumentation
+  ${toggle_thumb}             enable/disable building arm assembly in thumb mode
 
 Install options:
   ${toggle_install_docs}      control whether docs are installed
@@ -416,6 +417,8 @@ SRC_PATH_BARE=$source_path
 BUILD_PFX=${BUILD_PFX}
 TOOLCHAIN=${toolchain}
 ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl}
+GEN_VCPROJ=${gen_vcproj_cmd}
+MSVS_ARCH_DIR=${msvs_arch_dir}
 
 CC=${CC}
 CXX=${CXX}
@@ -433,6 +436,7 @@ ASFLAGS = ${ASFLAGS}
 extralibs = ${extralibs}
 AS_SFX    = ${AS_SFX:-.asm}
 EXE_SFX   = ${EXE_SFX}
+VCPROJ_SFX = ${VCPROJ_SFX}
 RTCD_OPTIONS = ${RTCD_OPTIONS}
 EOF
 
@@ -794,7 +798,13 @@ process_common_toolchain() {
             check_add_asflags --defsym ARCHITECTURE=${arch_int}
             tune_cflags="-mtune="
             if [ ${tgt_isa} == "armv7" ]; then
-                [ -z "${float_abi}" ] && float_abi=softfp
+                if [ -z "${float_abi}" ]; then
+                    check_cpp <<EOF && float_abi=hard || float_abi=softfp
+#ifndef __ARM_PCS_VFP
+#error "not hardfp"
+#endif
+EOF
+                fi
                 check_add_cflags  -march=armv7-a -mfloat-abi=${float_abi}
                 check_add_asflags -march=armv7-a -mfloat-abi=${float_abi}
 
@@ -814,6 +824,18 @@ process_common_toolchain() {
 
             enabled debug && add_asflags -g
             asm_conversion_cmd="${source_path}/build/make/ads2gas.pl"
+            if enabled thumb; then
+                asm_conversion_cmd="$asm_conversion_cmd -thumb"
+                check_add_cflags -mthumb
+                check_add_asflags -mthumb -mimplicit-it=always
+            fi
+            ;;
+        vs*)
+            asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
+            AS_SFX=.s
+            msvs_arch_dir=arm-msvs
+            disable multithread
+            disable unit_tests
             ;;
         rvct)
             CC=armcc
@@ -1057,6 +1079,7 @@ EOF
                 # invoked directly. Checking at configure time is unnecessary.
                 # Skip the check by setting AS arbitrarily
                 AS=msvs
+                msvs_arch_dir=x86-msvs
             ;;
         esac
 
@@ -1180,7 +1203,7 @@ EOF
     check_cc <<EOF && INLINE="inline"
     static inline function() {}
 EOF
-    check_cc <<EOF && INLINE="__attribute__((always_inline))"
+    check_cc <<EOF && INLINE="__inline__ __attribute__((always_inline))"
     static __attribute__((always_inline)) function() {}
 EOF
 
diff --git a/build/make/gen_msvs_sln.sh b/build/make/gen_msvs_sln.sh
index 240678b6455388dc09f4c9e92cf85c51b8fd1385..5a8c793682343e69ba1a56ded1479f4d5232600b 100755
--- a/build/make/gen_msvs_sln.sh
+++ b/build/make/gen_msvs_sln.sh
@@ -25,7 +25,7 @@ files.
 Options:
     --help                      Print this message
     --out=outfile               Redirect output to a file
-    --ver=version               Version (7,8,9) of visual studio to generate for
+    --ver=version               Version (7,8,9,10,11) of visual studio to generate for
     --target=isa-os-cc          Target specifier
 EOF
     exit 1
@@ -55,14 +55,19 @@ indent_pop() {
 
 parse_project() {
     local file=$1
-    local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
-    local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
+    if [ "$sfx" = "vcproj" ]; then
+        local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
+        local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
+    else
+        local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
+        local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
+    fi
 
     # save the project GUID to a varaible, normalizing to the basename of the
     # vcproj file without the extension
     local var
     var=${file##*/}
-    var=${var%%.vcproj}
+    var=${var%%.${sfx}}
     eval "${var}_file=\"$1\""
     eval "${var}_name=$name"
     eval "${var}_guid=$guid"
@@ -83,14 +88,14 @@ process_project() {
     # vcproj file without the extension
     local var
     var=${file##*/}
-    var=${var%%.vcproj}
+    var=${var%%.${sfx}}
     eval "${var}_guid=$guid"
 
     echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
     indent_push
 
     eval "local deps=\"\${${var}_deps}\""
-    if [ -n "$deps" ]; then
+    if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then
         echo "${indent}ProjectSection(ProjectDependencies) = postProject"
         indent_push
 
@@ -221,7 +226,7 @@ for opt in "$@"; do
     ;;
     --ver=*) vs_ver="$optval"
              case $optval in
-             [789])
+             [789]|10|11)
              ;;
              *) die Unrecognized Visual Studio Version in $opt
              ;;
@@ -257,6 +262,20 @@ case "${vs_ver:-8}" in
     9) sln_vers="10.00"
        sln_vers_str="Visual Studio 2008"
     ;;
+    10) sln_vers="11.00"
+       sln_vers_str="Visual Studio 2010"
+    ;;
+    11) sln_vers="12.00"
+       sln_vers_str="Visual Studio 2012"
+    ;;
+esac
+case "${vs_ver:-8}" in
+    [789])
+    sfx=vcproj
+    ;;
+    10|11)
+    sfx=vcxproj
+    ;;
 esac
 
 for f in "${file_list[@]}"; do
diff --git a/build/make/gen_msvs_vcxproj.sh b/build/make/gen_msvs_vcxproj.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4875915250cb3441efd324747c939ea9027f1fff
--- /dev/null
+++ b/build/make/gen_msvs_vcxproj.sh
@@ -0,0 +1,530 @@
+#!/bin/bash
+##
+##  Copyright (c) 2013 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.
+##
+
+
+self=$0
+self_basename=${self##*/}
+self_dirname=$(dirname "$0")
+EOL=$'\n'
+
+show_help() {
+    cat <<EOF
+Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
+
+This script generates a Visual Studio project file from a list of source
+code files.
+
+Options:
+    --help                      Print this message
+    --exe                       Generate a project for building an Application
+    --lib                       Generate a project for creating a static library
+    --dll                       Generate a project for creating a dll
+    --static-crt                Use the static C runtime (/MT)
+    --target=isa-os-cc          Target specifier (required)
+    --out=filename              Write output to a file [stdout]
+    --name=project_name         Name of the project (required)
+    --proj-guid=GUID            GUID to use for the project
+    --module-def=filename       File containing export definitions (for DLLs)
+    --ver=version               Version (10,11) of visual studio to generate for
+    --src-path-bare=dir         Path to root of source tree
+    -Ipath/to/include           Additional include directories
+    -DFLAG[=value]              Preprocessor macros to define
+    -Lpath/to/lib               Additional library search paths
+    -llibname                   Library to link against
+EOF
+    exit 1
+}
+
+die() {
+    echo "${self_basename}: $@" >&2
+    exit 1
+}
+
+die_unknown(){
+    echo "Unknown option \"$1\"." >&2
+    echo "See ${self_basename} --help for available options." >&2
+    exit 1
+}
+
+generate_uuid() {
+    local hex="0123456789ABCDEF"
+    local i
+    local uuid=""
+    local j
+    #93995380-89BD-4b04-88EB-625FBE52EBFB
+    for ((i=0; i<32; i++)); do
+        (( j = $RANDOM % 16 ))
+        uuid="${uuid}${hex:$j:1}"
+    done
+    echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}"
+}
+
+indent1="    "
+indent=""
+indent_push() {
+    indent="${indent}${indent1}"
+}
+indent_pop() {
+    indent="${indent%${indent1}}"
+}
+
+tag_attributes() {
+    for opt in "$@"; do
+        optval="${opt#*=}"
+        [ -n "${optval}" ] ||
+            die "Missing attribute value in '$opt' while generating $tag tag"
+        echo "${indent}${opt%%=*}=\"${optval}\""
+    done
+}
+
+open_tag() {
+    local tag=$1
+    shift
+    if [ $# -ne 0 ]; then
+        echo "${indent}<${tag}"
+        indent_push
+        tag_attributes "$@"
+        echo "${indent}>"
+    else
+        echo "${indent}<${tag}>"
+        indent_push
+    fi
+}
+
+close_tag() {
+    local tag=$1
+    indent_pop
+    echo "${indent}</${tag}>"
+}
+
+tag() {
+    local tag=$1
+    shift
+    if [ $# -ne 0 ]; then
+        echo "${indent}<${tag}"
+        indent_push
+        tag_attributes "$@"
+        indent_pop
+        echo "${indent}/>"
+    else
+        echo "${indent}<${tag}/>"
+    fi
+}
+
+tag_content() {
+    local tag=$1
+    local content=$2
+    shift
+    shift
+    if [ $# -ne 0 ]; then
+        echo "${indent}<${tag}"
+        indent_push
+        tag_attributes "$@"
+        echo "${indent}>${content}</${tag}>"
+        indent_pop
+    else
+        echo "${indent}<${tag}>${content}</${tag}>"
+    fi
+}
+
+generate_filter() {
+    local name=$1
+    local pats=$2
+    local file_list_sz
+    local i
+    local f
+    local saveIFS="$IFS"
+    local pack
+    echo "generating filter '$name' from ${#file_list[@]} files" >&2
+    IFS=*
+
+    file_list_sz=${#file_list[@]}
+    for i in ${!file_list[@]}; do
+        f=${file_list[i]}
+        for pat in ${pats//;/$IFS}; do
+            if [ "${f##*.}" == "$pat" ]; then
+                unset file_list[i]
+
+                objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g')
+
+                if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then
+                    open_tag CustomBuild \
+                        Include=".\\$f"
+                    for plat in "${platforms[@]}"; do
+                        for cfg in Debug Release; do
+                            tag_content Message "Assembling %(Filename)%(Extension)" \
+                                Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+                            tag_content Command "$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \
+                                Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+                            tag_content Outputs "\$(IntDir)$objf" \
+                                Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'"
+                        done
+                    done
+                    close_tag CustomBuild
+                elif [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then
+                    open_tag ClCompile \
+                        Include=".\\$f"
+                    # Separate file names with Condition?
+                    tag_content ObjectFileName "\$(IntDir)$objf"
+                    close_tag ClCompile
+                elif [ "$pat" == "h" ] ; then
+                    tag ClInclude \
+                        Include=".\\$f"
+                elif [ "$pat" == "vcxproj" ] ; then
+                    open_tag ProjectReference \
+                        Include="$f"
+                    depguid=`grep ProjectGuid "$f" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
+                    tag_content Project "$depguid"
+                    tag_content ReferenceOutputAssembly false
+                    close_tag ProjectReference
+                else
+                    tag None \
+                        Include=".\\$f"
+                fi
+
+                break
+            fi
+        done
+    done
+
+    IFS="$saveIFS"
+}
+
+# Process command line
+unset target
+for opt in "$@"; do
+    optval="${opt#*=}"
+    case "$opt" in
+        --help|-h) show_help
+        ;;
+        --target=*) target="${optval}"
+        ;;
+        --out=*) outfile="$optval"
+        ;;
+        --name=*) name="${optval}"
+        ;;
+        --proj-guid=*) guid="${optval}"
+        ;;
+        --module-def=*) module_def="${optval}"
+        ;;
+        --exe) proj_kind="exe"
+        ;;
+        --dll) proj_kind="dll"
+        ;;
+        --lib) proj_kind="lib"
+        ;;
+        --src-path-bare=*) src_path_bare="$optval"
+        ;;
+        --static-crt) use_static_runtime=true
+        ;;
+        --ver=*)
+            vs_ver="$optval"
+            case "$optval" in
+                10|11)
+                ;;
+                *) die Unrecognized Visual Studio Version in $opt
+                ;;
+            esac
+        ;;
+        -I*)
+            opt="${opt%/}"
+            incs="${incs}${incs:+;}${opt##-I}"
+            yasmincs="${yasmincs} ${opt}"
+        ;;
+        -D*) defines="${defines}${defines:+;}${opt##-D}"
+        ;;
+        -L*) # fudge . to $(OutDir)
+            if [ "${opt##-L}" == "." ]; then
+                libdirs="${libdirs}${libdirs:+;}\$(OutDir)"
+            else
+                 # Also try directories for this platform/configuration
+                 libdirs="${libdirs}${libdirs:+;}${opt##-L}"
+                 libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)/\$(Configuration)"
+                 libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)"
+            fi
+        ;;
+        -l*) libs="${libs}${libs:+ }${opt##-l}.lib"
+        ;;
+        -*) die_unknown $opt
+        ;;
+        *)
+            file_list[${#file_list[@]}]="$opt"
+            case "$opt" in
+                 *.asm|*.s) uses_asm=true
+                 ;;
+            esac
+        ;;
+    esac
+done
+outfile=${outfile:-/dev/stdout}
+guid=${guid:-`generate_uuid`}
+asm_use_custom_step=false
+uses_asm=${uses_asm:-false}
+case "${vs_ver:-11}" in
+    10|11)
+       asm_use_custom_step=$uses_asm
+    ;;
+esac
+
+[ -n "$name" ] || die "Project name (--name) must be specified!"
+[ -n "$target" ] || die "Target (--target) must be specified!"
+
+if ${use_static_runtime:-false}; then
+    release_runtime=MultiThreaded
+    debug_runtime=MultiThreadedDebug
+    lib_sfx=mt
+else
+    release_runtime=MultiThreadedDLL
+    debug_runtime=MultiThreadedDebugDLL
+    lib_sfx=md
+fi
+
+# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
+# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
+# debug exe, so this may need to be refactored later.
+for lib in ${libs}; do
+    if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
+        lib=${lib%.lib}d.lib
+    fi
+    debug_libs="${debug_libs}${debug_libs:+ }${lib}"
+done
+debug_libs=${debug_libs// /;}
+libs=${libs// /;}
+
+
+# List of all platforms supported for this target
+case "$target" in
+    x86_64*)
+        platforms[0]="x64"
+        asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} &quot;%(FullPath)&quot;"
+        asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} &quot;%(FullPath)&quot;"
+    ;;
+    x86*)
+        platforms[0]="Win32"
+        asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} &quot;%(FullPath)&quot;"
+        asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} &quot;%(FullPath)&quot;"
+    ;;
+    arm*)
+        asm_Debug_cmdline="armasm -nologo &quot;%(FullPath)&quot;"
+        asm_Release_cmdline="armasm -nologo &quot;%(FullPath)&quot;"
+        if [ "$name" = "obj_int_extract" ]; then
+            # We don't want to build this tool for the target architecture,
+            # but for an architecture we can run locally during the build.
+            platforms[0]="Win32"
+        else
+            platforms[0]="ARM"
+        fi
+    ;;
+    *) die "Unsupported target $target!"
+    ;;
+esac
+
+generate_vcxproj() {
+    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+    open_tag Project \
+        DefaultTargets="Build" \
+        ToolsVersion="4.0" \
+        xmlns="http://schemas.microsoft.com/developer/msbuild/2003" \
+
+    open_tag ItemGroup \
+        Label="ProjectConfigurations"
+    for plat in "${platforms[@]}"; do
+        for config in Debug Release; do
+            open_tag ProjectConfiguration \
+                Include="$config|$plat"
+            tag_content Configuration $config
+            tag_content Platform $plat
+            close_tag ProjectConfiguration
+        done
+    done
+    close_tag ItemGroup
+
+    open_tag PropertyGroup \
+        Label="Globals"
+        tag_content ProjectGuid "{${guid}}"
+        tag_content RootNamespace ${name}
+        tag_content Keyword ManagedCProj
+    close_tag PropertyGroup
+
+    tag Import \
+        Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props"
+
+    for plat in "${platforms[@]}"; do
+        for config in Release Debug; do
+            open_tag PropertyGroup \
+                Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" \
+                Label="Configuration"
+            if [ "$proj_kind" = "exe" ]; then
+                tag_content ConfigurationType Application
+            elif [ "$proj_kind" = "dll" ]; then
+                tag_content ConfigurationType DynamicLibrary
+            else
+                tag_content ConfigurationType StaticLibrary
+            fi
+            if [ "$vs_ver" = "11" ]; then
+                if [ "$plat" = "ARM" ]; then
+                    # Setting the wp80 toolchain automatically sets the
+                    # WINAPI_FAMILY define, which is required for building
+                    # code for arm with the windows headers. Alternatively,
+                    # one could add AppContainerApplication=true in the Globals
+                    # section and add PrecompiledHeader=NotUsing and
+                    # CompileAsWinRT=false in ClCompile and SubSystem=Console
+                    # in Link.
+                    tag_content PlatformToolset v110_wp80
+                else
+                    tag_content PlatformToolset v110
+                fi
+            fi
+            tag_content CharacterSet Unicode
+            if [ "$config" = "Release" ]; then
+                tag_content WholeProgramOptimization true
+            fi
+            close_tag PropertyGroup
+        done
+    done
+
+    tag Import \
+        Project="\$(VCTargetsPath)\\Microsoft.Cpp.props"
+
+    open_tag ImportGroup \
+        Label="PropertySheets"
+        tag Import \
+            Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" \
+            Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" \
+            Label="LocalAppDataPlatform"
+    close_tag ImportGroup
+
+    tag PropertyGroup \
+        Label="UserMacros"
+
+    for plat in "${platforms[@]}"; do
+        plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
+        for config in Debug Release; do
+            open_tag PropertyGroup \
+                Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'"
+            tag_content OutDir "\$(SolutionDir)$plat_no_ws\\\$(Configuration)\\"
+            tag_content IntDir "$plat_no_ws\\\$(Configuration)\\${name}\\"
+            close_tag PropertyGroup
+        done
+    done
+
+    for plat in "${platforms[@]}"; do
+        for config in Debug Release; do
+            open_tag ItemDefinitionGroup \
+                Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'"
+            if [ "$name" = "vpx" ]; then
+                open_tag PreBuildEvent
+                tag_content Command "call obj_int_extract.bat $src_path_bare"
+                close_tag PreBuildEvent
+            fi
+            open_tag ClCompile
+            if [ "$config" = "Debug" ]; then
+                opt=Disabled
+                runtime=$debug_runtime
+                curlibs=$debug_libs
+                confsuffix=d
+                case "$name" in
+                obj_int_extract)
+                    debug=DEBUG
+                    ;;
+                *)
+                    debug=_DEBUG
+                    ;;
+                esac
+            else
+                opt=MaxSpeed
+                runtime=$release_runtime
+                curlibs=$libs
+                confsuffix=""
+                tag_content FavorSizeOrSpeed Speed
+                debug=NDEBUG
+            fi
+            case "$name" in
+            obj_int_extract)
+                extradefines=";_CONSOLE"
+                ;;
+            *)
+                extradefines=";$defines"
+                ;;
+            esac
+            tag_content Optimization $opt
+            tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)"
+            tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)"
+            tag_content RuntimeLibrary $runtime
+            tag_content WarningLevel Level3
+            # DebugInformationFormat
+            close_tag ClCompile
+            case "$proj_kind" in
+            exe)
+                open_tag Link
+                if [ "$name" = "obj_int_extract" ]; then
+                    tag_content OutputFile "${name}.exe"
+                else
+                    tag_content AdditionalDependencies "$curlibs"
+                    tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)"
+                fi
+                tag_content GenerateDebugInformation true
+                close_tag Link
+                ;;
+            dll)
+                open_tag Link
+                tag_content GenerateDebugInformation true
+                tag_content ModuleDefinitionFile $module_def
+                close_tag Link
+                ;;
+            lib)
+                open_tag Lib
+                tag_content OutputFile "\$(OutDir)${name}${lib_sfx}${confsuffix}.lib"
+                close_tag Lib
+                ;;
+            esac
+            close_tag ItemDefinitionGroup
+        done
+
+    done
+
+    open_tag ItemGroup
+    generate_filter "Source Files"   "c;cc;def;odl;idl;hpj;bat;asm;asmx;s"
+    close_tag ItemGroup
+    open_tag ItemGroup
+    generate_filter "Header Files"   "h;hm;inl;inc;xsd"
+    close_tag ItemGroup
+    open_tag ItemGroup
+    generate_filter "Build Files"    "mk"
+    close_tag ItemGroup
+    open_tag ItemGroup
+    generate_filter "References"     "vcxproj"
+    close_tag ItemGroup
+
+    tag Import \
+        Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets"
+
+    open_tag ImportGroup \
+        Label="ExtensionTargets"
+    close_tag ImportGroup
+
+    close_tag Project
+
+    # This must be done from within the {} subshell
+    echo "Ignored files list (${#file_list[@]} items) is:" >&2
+    for f in "${file_list[@]}"; do
+        echo "    $f" >&2
+    done
+}
+
+# This regexp doesn't catch most of the strings in the vcxproj format,
+# since they're like <tag>path</tag> instead of <tag attr="path" />
+# as previously. It still seems to work ok despite this.
+generate_vcxproj |
+    sed  -e '/"/s;\([^ "]\)/;\1\\;g' |
+    sed  -e '/xmlns/s;\\;/;g' > ${outfile}
+
+exit
diff --git a/build/make/thumb.pm b/build/make/thumb.pm
new file mode 100644
index 0000000000000000000000000000000000000000..f34728743c6f0ae6276e31e03873ca8b94df780e
--- /dev/null
+++ b/build/make/thumb.pm
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+##
+##  Copyright (c) 2013 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.
+##
+
+package thumb;
+
+sub FixThumbInstructions($$)
+{
+    my $short_branches = $_[1];
+    my $branch_shift_offset = $short_branches ? 1 : 0;
+
+    # Write additions with shifts, such as "add r10, r11, lsl #8",
+    # in three operand form, "add r10, r10, r11, lsl #8".
+    s/(add\s+)(r\d+),\s*(r\d+),\s*(lsl #\d+)/$1$2, $2, $3, $4/g;
+
+    # Convert additions with a non-constant shift into a sequence
+    # with left shift, addition and a right shift (to restore the
+    # register to the original value). Currently the right shift
+    # isn't necessary in the code base since the values in these
+    # registers aren't used, but doing the shift for consitency.
+    # This converts instructions such as "add r12, r12, r5, lsl r4"
+    # into the sequence "lsl r5, r4", "add r12, r12, r5", "lsr r5, r4".
+    s/^(\s*)(add)(\s+)(r\d+),\s*(r\d+),\s*(r\d+),\s*lsl (r\d+)/$1lsl$3$6, $7\n$1$2$3$4, $5, $6\n$1lsr$3$6, $7/g;
+
+    # Convert loads with right shifts in the indexing into a
+    # sequence of an add, load and sub. This converts
+    # "ldrb r4, [r9, lr, asr #1]" into "add r9, r9, lr, asr #1",
+    # "ldrb r9, [r9]", "sub r9, r9, lr, asr #1".
+    s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+),\s*(asr #\d+)\]/$1add $3$5, $5, $6, $7\n$1$2$3$4, [$5]\n$1sub $3$5, $5, $6, $7/g;
+
+    # Convert register indexing with writeback into a separate add
+    # instruction. This converts "ldrb r12, [r1, r2]!" into
+    # "ldrb r12, [r1, r2]", "add r1, r1, r2".
+    s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+)\]!/$1$2$3$4, [$5, $6]\n$1add $3$5, $6/g;
+
+    # Convert negative register indexing into separate sub/add instructions.
+    # This converts "ldrne r4, [src, -pstep, lsl #1]" into
+    # "subne src, src, pstep, lsl #1", "ldrne r4, [src]",
+    # "addne src, src, pstep, lsl #1". In a couple of cases where
+    # this is used, it's used for two subsequent load instructions,
+    # where a hand-written version of it could merge two subsequent
+    # add and sub instructions.
+    s/^(\s*)((ldr|str)(ne)?)(\s+)(r\d+),\s*\[(\w+), -([^\]]+)\]/$1sub$4$5$7, $7, $8\n$1$2$5$6, [$7]\n$1add$4$5$7, $7, $8/g;
+
+    # Convert register post indexing to a separate add instruction.
+    # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]",
+    # "add r0, r2".
+    s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g;
+
+    # Convert a conditional addition to the pc register into a series of
+    # instructions. This converts "addlt pc, pc, r3, lsl #2" into
+    # "itttt lt", "movlt.n r12, pc", "addlt.w r12, #12",
+    # "addlt.w r12, r12, r3, lsl #2", "movlt.n pc, r12".
+    # This assumes that r12 is free at this point.
+    s/^(\s*)addlt(\s+)pc,\s*pc,\s*(\w+),\s*lsl\s*#(\d+)/$1itttt$2lt\n$1movlt.n$2r12, pc\n$1addlt.w$2r12, #12\n$1addlt.w$2r12, r12, $3, lsl #($4-$branch_shift_offset)\n$1movlt.n$2pc, r12/g;
+
+    # Convert "mov pc, lr" into "bx lr", since the former only works
+    # for switching from arm to thumb (and only in armv7), but not
+    # from thumb to arm.
+    s/mov(\s*)pc\s*,\s*lr/bx$1lr/g;
+}
+
+1;
diff --git a/configure b/configure
index 05e5384b51fdbd39046e9d9175032f2b6712c78c..28676fbc6c3a6e99134969b7ddd6e2052a6f08e5 100755
--- a/configure
+++ b/configure
@@ -98,6 +98,7 @@ all_platforms="${all_platforms} armv7-darwin-gcc"    #neon Cortex-A8
 all_platforms="${all_platforms} armv7-linux-rvct"    #neon Cortex-A8
 all_platforms="${all_platforms} armv7-linux-gcc"     #neon Cortex-A8
 all_platforms="${all_platforms} armv7-none-rvct"     #neon Cortex-A8
+all_platforms="${all_platforms} armv7-win32-vs11"
 all_platforms="${all_platforms} mips32-linux-gcc"
 all_platforms="${all_platforms} ppc32-darwin8-gcc"
 all_platforms="${all_platforms} ppc32-darwin9-gcc"
@@ -122,6 +123,8 @@ all_platforms="${all_platforms} x86-win32-gcc"
 all_platforms="${all_platforms} x86-win32-vs7"
 all_platforms="${all_platforms} x86-win32-vs8"
 all_platforms="${all_platforms} x86-win32-vs9"
+all_platforms="${all_platforms} x86-win32-vs10"
+all_platforms="${all_platforms} x86-win32-vs11"
 all_platforms="${all_platforms} x86_64-darwin9-gcc"
 all_platforms="${all_platforms} x86_64-darwin10-gcc"
 all_platforms="${all_platforms} x86_64-darwin11-gcc"
@@ -132,6 +135,8 @@ all_platforms="${all_platforms} x86_64-solaris-gcc"
 all_platforms="${all_platforms} x86_64-win64-gcc"
 all_platforms="${all_platforms} x86_64-win64-vs8"
 all_platforms="${all_platforms} x86_64-win64-vs9"
+all_platforms="${all_platforms} x86_64-win64-vs10"
+all_platforms="${all_platforms} x86_64-win64-vs11"
 all_platforms="${all_platforms} universal-darwin8-gcc"
 all_platforms="${all_platforms} universal-darwin9-gcc"
 all_platforms="${all_platforms} universal-darwin10-gcc"
@@ -309,6 +314,7 @@ CMDLINE_SELECT="
     optimizations
     ccache
     runtime_cpu_detect
+    thumb
 
     libs
     examples
@@ -642,6 +648,16 @@ process_toolchain() {
         vs*) enable msvs
              enable solution
              vs_version=${tgt_cc##vs}
+             case $vs_version in
+             [789])
+                 VCPROJ_SFX=vcproj
+                 gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh
+                 ;;
+             10|11)
+                 VCPROJ_SFX=vcxproj
+                 gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
+                 ;;
+             esac
              all_targets="${all_targets} solution"
              INLINE="__forceinline"
         ;;
diff --git a/examples.mk b/examples.mk
index 8426ee7690bc92bebb70296c7dc51df1e100222e..5b5ca237931cd68bdadabede9e1bbde0b3aace8c 100644
--- a/examples.mk
+++ b/examples.mk
@@ -231,19 +231,19 @@ endif
 # even though there is no real dependency there (the dependency is on
 # the makefiles). We may want to revisit this.
 define vcproj_template
-$(1): $($(1:.vcproj=).SRCS)
+$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX)
 	@echo "    [vcproj] $$@"
-	$$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh\
+	$$(GEN_VCPROJ)\
             --exe\
             --target=$$(TOOLCHAIN)\
-            --name=$$(@:.vcproj=)\
+            --name=$$(@:.$(VCPROJ_SFX)=)\
             --ver=$$(CONFIG_VS_VERSION)\
-            --proj-guid=$$($$(@:.vcproj=).GUID)\
+            --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\
             $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \
             --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \
-            $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) -lwinmm $$^
+            $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) $$^
 endef
-PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES:.c=.vcproj)
+PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES:.c=.$(VCPROJ_SFX))
 INSTALL-BINS-$(CONFIG_MSVS) += $(foreach p,$(VS_PLATFORMS),\
                                $(addprefix bin/$(p)/,$(ALL_EXAMPLES:.c=.exe)))
 $(foreach proj,$(call enabled,PROJECTS),\
diff --git a/libs.mk b/libs.mk
index adcde33f75d1bdaf1613a03b9ab57ae8bf218a31..8428f899d2d17fee2165d75cb2f4548f0a82728e 100644
--- a/libs.mk
+++ b/libs.mk
@@ -12,7 +12,7 @@
 # ARM assembly files are written in RVCT-style. We use some make magic to
 # filter those files to allow GCC compilation
 ifeq ($(ARCH_ARM),yes)
-  ASM:=$(if $(filter yes,$(CONFIG_GCC)),.asm.s,.asm)
+  ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.s,.asm)
 else
   ASM:=.asm
 endif
@@ -207,10 +207,10 @@ libvpx_srcs.txt:
 ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
 ifeq ($(CONFIG_MSVS),yes)
 
-obj_int_extract.vcproj: $(SRC_PATH_BARE)/build/make/obj_int_extract.c
-	@cp $(SRC_PATH_BARE)/build/x86-msvs/obj_int_extract.bat .
+obj_int_extract.$(VCPROJ_SFX): $(SRC_PATH_BARE)/build/make/obj_int_extract.c
+	@cp $(SRC_PATH_BARE)/build/$(MSVS_ARCH_DIR)/obj_int_extract.bat .
 	@echo "    [CREATE] $@"
-	$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
+	$(qexec)$(GEN_VCPROJ) \
     --exe \
     --target=$(TOOLCHAIN) \
     --name=obj_int_extract \
@@ -221,7 +221,7 @@ obj_int_extract.vcproj: $(SRC_PATH_BARE)/build/make/obj_int_extract.c
     -I. \
     -I"$(SRC_PATH_BARE)" \
 
-PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.vcproj
+PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.$(VCPROJ_SFX)
 
 vpx.def: $(call enabled,CODEC_EXPORTS)
 	@echo "    [CREATE] $@"
@@ -230,9 +230,9 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
             --out=$@ $^
 CLEAN-OBJS += vpx.def
 
-vpx.vcproj: $(CODEC_SRCS) vpx.def
+vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def obj_int_extract.$(VCPROJ_SFX)
 	@echo "    [CREATE] $@"
-	$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
+	$(qexec)$(GEN_VCPROJ) \
             $(if $(CONFIG_SHARED),--dll,--lib) \
             --target=$(TOOLCHAIN) \
             $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
@@ -243,10 +243,10 @@ vpx.vcproj: $(CODEC_SRCS) vpx.def
             --out=$@ $(CFLAGS) $^ \
             --src-path-bare="$(SRC_PATH_BARE)" \
 
-PROJECTS-$(BUILD_LIBVPX) += vpx.vcproj
+PROJECTS-$(BUILD_LIBVPX) += vpx.$(VCPROJ_SFX)
 
-vpx.vcproj: vpx_config.asm
-vpx.vcproj: $(RTCD)
+vpx.$(VCPROJ_SFX): vpx_config.asm
+vpx.$(VCPROJ_SFX): $(RTCD)
 
 endif
 else
@@ -403,9 +403,9 @@ testdata:: $(LIBVPX_TEST_DATA)
 ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
 ifeq ($(CONFIG_MSVS),yes)
 
-gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc
+gtest.$(VCPROJ_SFX): $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc
 	@echo "    [CREATE] $@"
-	$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
+	$(qexec)$(GEN_VCPROJ) \
             --lib \
             --target=$(TOOLCHAIN) \
             $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
@@ -414,14 +414,14 @@ gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc
             --ver=$(CONFIG_VS_VERSION) \
             --src-path-bare="$(SRC_PATH_BARE)" \
             -D_VARIADIC_MAX=10 \
-            --out=gtest.vcproj $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \
+            --out=gtest.$(VCPROJ_SFX) $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \
             -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" -I"$(SRC_PATH_BARE)/third_party/googletest/src"
 
-PROJECTS-$(CONFIG_MSVS) += gtest.vcproj
+PROJECTS-$(CONFIG_MSVS) += gtest.$(VCPROJ_SFX)
 
-test_libvpx.vcproj: $(LIBVPX_TEST_SRCS)
+test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX)
 	@echo "    [CREATE] $@"
-	$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \
+	$(qexec)$(GEN_VCPROJ) \
             --exe \
             --target=$(TOOLCHAIN) \
             --name=test_libvpx \
@@ -431,9 +431,9 @@ test_libvpx.vcproj: $(LIBVPX_TEST_SRCS)
             $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
             --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
             -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
-            -L. -l$(CODEC_LIB) -lwinmm -l$(GTEST_LIB) $^
+            -L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
 
-PROJECTS-$(CONFIG_MSVS) += test_libvpx.vcproj
+PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)
 
 test:: testdata
 	@set -e; for t in $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BINS:.cc=.exe))); do $$t; done
diff --git a/nestegg/halloc/src/macros.h b/nestegg/halloc/src/macros.h
index c36b516eed38c5728761b6c82d2829bcccc3324f..1f84bc2779363aacb31c010c4ea10f82f3060f2a 100644
--- a/nestegg/halloc/src/macros.h
+++ b/nestegg/halloc/src/macros.h
@@ -20,7 +20,7 @@
 /*
  	restore pointer to the structure by a pointer to its field
  */
-#define structof(p,t,f) ((t*)(- offsetof(t,f) + (char*)(p)))
+#define structof(p,t,f) ((t*)(- (ptrdiff_t) offsetof(t,f) + (char*)(p)))
 
 /*
  *	redefine for the target compiler
diff --git a/solution.mk b/solution.mk
index 948305f0594384f0202e40e7c977799c58d0a6a1..2c8d29a2a1e87ecfad0229f254af42d2e502c5e7 100644
--- a/solution.mk
+++ b/solution.mk
@@ -9,14 +9,14 @@
 ##
 
 # libvpx reverse dependencies (targets that depend on libvpx)
-VPX_NONDEPS=$(addsuffix .vcproj,vpx gtest obj_int_extract)
+VPX_NONDEPS=$(addsuffix .$(VCPROJ_SFX),vpx gtest obj_int_extract)
 VPX_RDEPS=$(foreach vcp,\
-              $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.vcproj=):vpx)
+              $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.$(VCPROJ_SFX)=):vpx)
 
-vpx.sln: $(wildcard *.vcproj)
+vpx.sln: $(wildcard *.$(VCPROJ_SFX))
 	@echo "    [CREATE] $@"
 	$(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \
-            $(if $(filter vpx.vcproj,$^),$(VPX_RDEPS)) \
+            $(if $(filter vpx.$(VCPROJ_SFX),$^),$(VPX_RDEPS)) \
             --dep=vpx:obj_int_extract \
             --dep=test_libvpx:gtest \
             --ver=$(CONFIG_VS_VERSION)\
diff --git a/vp8/common/arm/armv6/filter_v6.asm b/vp8/common/arm/armv6/filter_v6.asm
index 1ba91ddd657a1da84f84426f82b3d9a37fcfb7cb..eb4b75bd8025d7391535bdd7997cd4ec28558296 100644
--- a/vp8/common/arm/armv6/filter_v6.asm
+++ b/vp8/common/arm/armv6/filter_v6.asm
@@ -394,7 +394,7 @@
     mov     r4, #0x40                       ; rounding factor (for smlad{x})
 
 |height_loop_2nd_4|
-    ldrd    r8, [r0, #-4]                   ; load the data
+    ldrd    r8, r9, [r0, #-4]               ; load the data
     orr     r7, r7, r3, lsr #1              ; loop counter
 
 |width_loop_2nd_4|
diff --git a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
index e7a3ed173f3d158b6eefe75c0c5f281675ca4ef6..9d22c52521c747ab7ab9fb7a8abfda4854998bce 100644
--- a/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
+++ b/vp8/common/arm/neon/vp8_subpixelvariance16x16_neon.asm
@@ -9,9 +9,6 @@
 ;
 
 
-bilinear_taps_coeff
-    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
-
 ;-----------------
 
     EXPORT  |vp8_sub_pixel_variance16x16_neon_func|
@@ -29,6 +26,9 @@ bilinear_taps_coeff
 ; stack(r6) unsigned int *sse
 ;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon.
 
+bilinear_taps_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
 |vp8_sub_pixel_variance16x16_neon_func| PROC
     push            {r4-r6, lr}
 
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 5baeb3c5ba2a1443ac0740d464a749926d04c02c..b550f6be1cfd5a143958a46fb3e129ead227518c 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1299,8 +1299,9 @@ int vp8cx_encode_inter_macroblock
     }
 
     {
-        /* Experimental code. Special case for gf and arf zeromv modes.
-         * Increase zbin size to supress noise
+        /* Experimental code.
+         * Special case for gf and arf zeromv modes, for 1 temporal layer.
+         * Increase zbin size to supress noise.
          */
         x->zbin_mode_boost = 0;
         if (x->zbin_mode_boost_enabled)
@@ -1309,7 +1310,8 @@ int vp8cx_encode_inter_macroblock
             {
                 if (xd->mode_info_context->mbmi.mode == ZEROMV)
                 {
-                    if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
+                    if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME &&
+                        cpi->oxcf.number_of_layers == 1)
                         x->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
                     else
                         x->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index aec7bffa4a9124394d1173b3911eddc3a16b8641..51b154f45c15417aeca535d501feaff0b23a9c94 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -289,6 +289,125 @@ static void restore_layer_context(VP8_COMP *cpi, const int layer)
             sizeof(cpi->mb.count_mb_ref_frame_usage));
 }
 
+static int rescale(int val, int num, int denom)
+{
+    int64_t llnum = num;
+    int64_t llden = denom;
+    int64_t llval = val;
+
+    return (int)(llval * llnum / llden);
+}
+
+static void init_temporal_layer_context(VP8_COMP *cpi,
+                                        VP8_CONFIG *oxcf,
+                                        const int layer,
+                                        double prev_layer_frame_rate)
+{
+    LAYER_CONTEXT *lc = &cpi->layer_context[layer];
+
+    lc->frame_rate = cpi->output_frame_rate / cpi->oxcf.rate_decimator[layer];
+    lc->target_bandwidth = cpi->oxcf.target_bitrate[layer] * 1000;
+
+    lc->starting_buffer_level_in_ms = oxcf->starting_buffer_level;
+    lc->optimal_buffer_level_in_ms  = oxcf->optimal_buffer_level;
+    lc->maximum_buffer_size_in_ms   = oxcf->maximum_buffer_size;
+
+    lc->starting_buffer_level =
+        rescale((int)(oxcf->starting_buffer_level),
+                lc->target_bandwidth, 1000);
+
+    if (oxcf->optimal_buffer_level == 0)
+      lc->optimal_buffer_level = lc->target_bandwidth / 8;
+    else
+      lc->optimal_buffer_level =
+          rescale((int)(oxcf->optimal_buffer_level),
+                  lc->target_bandwidth, 1000);
+
+    if (oxcf->maximum_buffer_size == 0)
+      lc->maximum_buffer_size = lc->target_bandwidth / 8;
+    else
+      lc->maximum_buffer_size =
+          rescale((int)(oxcf->maximum_buffer_size),
+                  lc->target_bandwidth, 1000);
+
+    /* Work out the average size of a frame within this layer */
+    if (layer > 0)
+      lc->avg_frame_size_for_layer =
+          (int)((cpi->oxcf.target_bitrate[layer] -
+                cpi->oxcf.target_bitrate[layer-1]) * 1000 /
+                (lc->frame_rate - prev_layer_frame_rate));
+
+     lc->active_worst_quality         = cpi->oxcf.worst_allowed_q;
+     lc->active_best_quality          = cpi->oxcf.best_allowed_q;
+     lc->avg_frame_qindex             = cpi->oxcf.worst_allowed_q;
+
+     lc->buffer_level                 = lc->starting_buffer_level;
+     lc->bits_off_target              = lc->starting_buffer_level;
+
+     lc->total_actual_bits                 = 0;
+     lc->ni_av_qi                          = 0;
+     lc->ni_tot_qi                         = 0;
+     lc->ni_frames                         = 0;
+     lc->rate_correction_factor            = 1.0;
+     lc->key_frame_rate_correction_factor  = 1.0;
+     lc->gf_rate_correction_factor         = 1.0;
+     lc->inter_frame_target                = 0;
+}
+
+// Upon a run-time change in temporal layers, reset the layer context parameters
+// for any "new" layers. For "existing" layers, let them inherit the parameters
+// from the previous layer state (at the same layer #). In future we may want
+// to better map the previous layer state(s) to the "new" ones.
+static void reset_temporal_layer_change(VP8_COMP *cpi,
+                                        VP8_CONFIG *oxcf,
+                                        const int prev_num_layers)
+{
+    unsigned int i;
+    double prev_layer_frame_rate = 0;
+    const int curr_num_layers = cpi->oxcf.number_of_layers;
+    // If the previous state was 1 layer, get current layer context from cpi.
+    // We need this to set the layer context for the new layers below.
+    if (prev_num_layers == 1)
+    {
+        cpi->current_layer = 0;
+        save_layer_context(cpi);
+    }
+    for (i = 0; i < curr_num_layers; i++)
+    {
+        LAYER_CONTEXT *lc = &cpi->layer_context[i];
+        if (i >= prev_num_layers)
+        {
+           init_temporal_layer_context(cpi, oxcf, i, prev_layer_frame_rate);
+        }
+        // The initial buffer levels are set based on their starting levels.
+        // We could set the buffer levels based on the previous state (normalized
+        // properly by the layer bandwidths) but we would need to keep track of
+        // the previous set of layer bandwidths (i.e., target_bitrate[i])
+        // before the layer change. For now, reset to the starting levels.
+        lc->buffer_level = cpi->oxcf.starting_buffer_level_in_ms *
+                           cpi->oxcf.target_bitrate[i];
+        lc->bits_off_target = lc->buffer_level;
+        // TDOD(marpan): Should we set the rate_correction_factor and
+        // active_worst/best_quality to values derived from the previous layer
+        // state (to smooth-out quality dips/rate fluctuation at transition)?
+
+        // We need to treat the 1 layer case separately: oxcf.target_bitrate[i]
+        // is not set for 1 layer, and the restore_layer_context/save_context()
+        // are not called in the encoding loop, so we need to call it here to
+        // pass the layer context state to |cpi|.
+        if (curr_num_layers == 1)
+        {
+            lc->target_bandwidth = cpi->oxcf.target_bandwidth;
+            lc->buffer_level = cpi->oxcf.starting_buffer_level_in_ms *
+                               lc->target_bandwidth  / 1000;
+            lc->bits_off_target = lc->buffer_level;
+            restore_layer_context(cpi, 0);
+        }
+        prev_layer_frame_rate =  cpi->output_frame_rate /
+                                 cpi->oxcf.rate_decimator[i];
+    }
+}
+
 static void setup_features(VP8_COMP *cpi)
 {
     // If segmentation enabled set the update flags
@@ -1200,17 +1319,6 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate)
 }
 
 
-static int
-rescale(int val, int num, int denom)
-{
-    int64_t llnum = num;
-    int64_t llden = denom;
-    int64_t llval = val;
-
-    return (int)(llval * llnum / llden);
-}
-
-
 static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
 {
     VP8_COMMON *cm = &cpi->common;
@@ -1265,59 +1373,9 @@ static void init_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
 
         for (i=0; i<cpi->oxcf.number_of_layers; i++)
         {
-            LAYER_CONTEXT *lc = &cpi->layer_context[i];
-
-            /* Layer configuration */
-            lc->frame_rate =
-                        cpi->output_frame_rate / cpi->oxcf.rate_decimator[i];
-            lc->target_bandwidth = cpi->oxcf.target_bitrate[i] * 1000;
-
-            lc->starting_buffer_level_in_ms = oxcf->starting_buffer_level;
-            lc->optimal_buffer_level_in_ms  = oxcf->optimal_buffer_level;
-            lc->maximum_buffer_size_in_ms   = oxcf->maximum_buffer_size;
-
-            lc->starting_buffer_level =
-              rescale((int)(oxcf->starting_buffer_level),
-                          lc->target_bandwidth, 1000);
-
-            if (oxcf->optimal_buffer_level == 0)
-                lc->optimal_buffer_level = lc->target_bandwidth / 8;
-            else
-                lc->optimal_buffer_level =
-                  rescale((int)(oxcf->optimal_buffer_level),
-                          lc->target_bandwidth, 1000);
-
-            if (oxcf->maximum_buffer_size == 0)
-                lc->maximum_buffer_size = lc->target_bandwidth / 8;
-            else
-                lc->maximum_buffer_size =
-                  rescale((int)oxcf->maximum_buffer_size,
-                          lc->target_bandwidth, 1000);
-
-            /* Work out the average size of a frame within this layer */
-            if (i > 0)
-                lc->avg_frame_size_for_layer =
-                  (int)((cpi->oxcf.target_bitrate[i] -
-                         cpi->oxcf.target_bitrate[i-1]) * 1000 /
-                        (lc->frame_rate - prev_layer_frame_rate));
-
-            lc->active_worst_quality         = cpi->oxcf.worst_allowed_q;
-            lc->active_best_quality          = cpi->oxcf.best_allowed_q;
-            lc->avg_frame_qindex             = cpi->oxcf.worst_allowed_q;
-
-            lc->buffer_level                 = lc->starting_buffer_level;
-            lc->bits_off_target              = lc->starting_buffer_level;
-
-            lc->total_actual_bits                 = 0;
-            lc->ni_av_qi                          = 0;
-            lc->ni_tot_qi                         = 0;
-            lc->ni_frames                         = 0;
-            lc->rate_correction_factor            = 1.0;
-            lc->key_frame_rate_correction_factor  = 1.0;
-            lc->gf_rate_correction_factor         = 1.0;
-            lc->inter_frame_target                = 0;
-
-            prev_layer_frame_rate = lc->frame_rate;
+            init_temporal_layer_context(cpi, oxcf, i, prev_layer_frame_rate);
+            prev_layer_frame_rate = cpi->output_frame_rate /
+                                    cpi->oxcf.rate_decimator[i];
         }
     }
 
@@ -1384,7 +1442,7 @@ static void update_layer_contexts (VP8_COMP *cpi)
 void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
 {
     VP8_COMMON *cm = &cpi->common;
-    int last_w, last_h;
+    int last_w, last_h, prev_number_of_layers;
 
     if (!cpi)
         return;
@@ -1409,6 +1467,7 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
 
     last_w = cpi->oxcf.Width;
     last_h = cpi->oxcf.Height;
+    prev_number_of_layers = cpi->oxcf.number_of_layers;
 
     cpi->oxcf = *oxcf;
 
@@ -1601,6 +1660,16 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
 
     cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
 
+    // Check if the number of temporal layers has changed, and if so reset the
+    // pattern counter and set/initialize the temporal layer context for the
+    // new layer configuration.
+    if (cpi->oxcf.number_of_layers != prev_number_of_layers)
+    {
+        // If the number of temporal layers are changed we must start at the
+        // base of the pattern cycle, so reset temporal_pattern_counter.
+        cpi->temporal_pattern_counter = 0;
+        reset_temporal_layer_change(cpi, oxcf, prev_number_of_layers);
+    }
 
     cm->Width       = cpi->oxcf.Width;
     cm->Height      = cpi->oxcf.Height;
@@ -1738,6 +1807,7 @@ struct VP8_COMP* vp8_create_compressor(VP8_CONFIG *oxcf)
 
     memcpy(cpi->base_skip_false_prob, vp8cx_base_skip_false_prob, sizeof(vp8cx_base_skip_false_prob));
     cpi->common.current_video_frame   = 0;
+    cpi->temporal_pattern_counter     = 0;
     cpi->kf_overspend_bits            = 0;
     cpi->kf_bitrate_adjustment        = 0;
     cpi->frames_till_gf_update_due      = 0;
@@ -3485,6 +3555,8 @@ static void encode_frame_to_data_rate
 
             cm->current_video_frame++;
             cpi->frames_since_key++;
+            // We advance the temporal pattern for dropped frames.
+            cpi->temporal_pattern_counter++;
 
 #if CONFIG_INTERNAL_STATS
             cpi->count ++;
@@ -3526,6 +3598,8 @@ static void encode_frame_to_data_rate
 #endif
         cm->current_video_frame++;
         cpi->frames_since_key++;
+        // We advance the temporal pattern for dropped frames.
+        cpi->temporal_pattern_counter++;
         return;
     }
 
@@ -4693,6 +4767,7 @@ static void encode_frame_to_data_rate
     {
         cm->current_video_frame++;
         cpi->frames_since_key++;
+        cpi->temporal_pattern_counter++;
     }
 
     /* reset to normal state now that we are done. */
@@ -5012,7 +5087,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l
 
         /* Restore layer specific context & set frame rate */
         layer = cpi->oxcf.layer_id[
-                            cm->current_video_frame % cpi->oxcf.periodicity];
+                cpi->temporal_pattern_counter % cpi->oxcf.periodicity];
         restore_layer_context (cpi, layer);
         vp8_new_frame_rate (cpi, cpi->layer_context[layer].frame_rate);
     }
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index c79531c5dbeb622c1eb8f1f67327c3db0c6f55ae..5120fcce9924c258310a4c885c6d6bde76659a04 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -509,6 +509,10 @@ typedef struct VP8_COMP
     int cyclic_refresh_q;
     signed char *cyclic_refresh_map;
 
+    // Frame counter for the temporal pattern. Counter is rest when the temporal
+    // layers are changed dynamically (run-time change).
+    unsigned int temporal_pattern_counter;
+
 #if CONFIG_MULTITHREAD
     /* multithread data */
     int * mt_current_mb_col;
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 90a175436dbf517a36d42243de85303deb02f54b..45cf3859e30c04239f9b0c4c1b3574360b7b1890 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -659,7 +659,7 @@ static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t  *ctx,
     /* iter acts as a flip flop, so an image is only returned on the first
      * call to get_frame.
      */
-    if (!(*iter))
+    if (!(*iter) && ctx->yv12_frame_buffers.pbi[0])
     {
         YV12_BUFFER_CONFIG sd;
         int64_t time_stamp = 0, time_end_stamp = 0;
@@ -943,10 +943,10 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
 {
 
     int *corrupted = va_arg(args, int *);
+    VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0];
 
-    if (corrupted)
+    if (corrupted && pbi)
     {
-        VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0];
         *corrupted = pbi->common.frame_to_show->corrupted;
 
         return VPX_CODEC_OK;
diff --git a/vp9/encoder/x86/vp9_dct_sse2.c b/vp9/encoder/x86/vp9_dct_sse2.c
index 49cb837e01c5ed79d95b7c39362afb1c360b0c23..aaacebee2cff64c1c0995d6f4e56b818daca136c 100644
--- a/vp9/encoder/x86/vp9_dct_sse2.c
+++ b/vp9/encoder/x86/vp9_dct_sse2.c
@@ -362,14 +362,14 @@ void vp9_short_fdct8x8_sse2(int16_t *input, int16_t *output, int pitch) {
     in6 = _mm_srai_epi16(in6, 1);
     in7 = _mm_srai_epi16(in7, 1);
     // store results
-    _mm_storeu_si128 ((__m128i *)(output + 0 * 8), in0);
-    _mm_storeu_si128 ((__m128i *)(output + 1 * 8), in1);
-    _mm_storeu_si128 ((__m128i *)(output + 2 * 8), in2);
-    _mm_storeu_si128 ((__m128i *)(output + 3 * 8), in3);
-    _mm_storeu_si128 ((__m128i *)(output + 4 * 8), in4);
-    _mm_storeu_si128 ((__m128i *)(output + 5 * 8), in5);
-    _mm_storeu_si128 ((__m128i *)(output + 6 * 8), in6);
-    _mm_storeu_si128 ((__m128i *)(output + 7 * 8), in7);
+    _mm_storeu_si128((__m128i *)(output + 0 * 8), in0);
+    _mm_storeu_si128((__m128i *)(output + 1 * 8), in1);
+    _mm_storeu_si128((__m128i *)(output + 2 * 8), in2);
+    _mm_storeu_si128((__m128i *)(output + 3 * 8), in3);
+    _mm_storeu_si128((__m128i *)(output + 4 * 8), in4);
+    _mm_storeu_si128((__m128i *)(output + 5 * 8), in5);
+    _mm_storeu_si128((__m128i *)(output + 6 * 8), in6);
+    _mm_storeu_si128((__m128i *)(output + 7 * 8), in7);
   }
 }
 
@@ -915,14 +915,14 @@ void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int pitch) {
         // 05 15 25 35 45 55 65 75
         // 06 16 26 36 46 56 66 76
         // 07 17 27 37 47 57 67 77
-        _mm_storeu_si128 ((__m128i *)(out + 0 * 16), tr2_0);
-        _mm_storeu_si128 ((__m128i *)(out + 1 * 16), tr2_1);
-        _mm_storeu_si128 ((__m128i *)(out + 2 * 16), tr2_2);
-        _mm_storeu_si128 ((__m128i *)(out + 3 * 16), tr2_3);
-        _mm_storeu_si128 ((__m128i *)(out + 4 * 16), tr2_4);
-        _mm_storeu_si128 ((__m128i *)(out + 5 * 16), tr2_5);
-        _mm_storeu_si128 ((__m128i *)(out + 6 * 16), tr2_6);
-        _mm_storeu_si128 ((__m128i *)(out + 7 * 16), tr2_7);
+        _mm_storeu_si128((__m128i *)(out + 0 * 16), tr2_0);
+        _mm_storeu_si128((__m128i *)(out + 1 * 16), tr2_1);
+        _mm_storeu_si128((__m128i *)(out + 2 * 16), tr2_2);
+        _mm_storeu_si128((__m128i *)(out + 3 * 16), tr2_3);
+        _mm_storeu_si128((__m128i *)(out + 4 * 16), tr2_4);
+        _mm_storeu_si128((__m128i *)(out + 5 * 16), tr2_5);
+        _mm_storeu_si128((__m128i *)(out + 6 * 16), tr2_6);
+        _mm_storeu_si128((__m128i *)(out + 7 * 16), tr2_7);
       }
       {
         // 00 01 02 03 04 05 06 07
@@ -982,14 +982,14 @@ void vp9_short_fdct16x16_sse2(int16_t *input, int16_t *output, int pitch) {
         // 06 16 26 36 46 56 66 76
         // 07 17 27 37 47 57 67 77
         // Store results
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 0 * 16), tr2_0);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 1 * 16), tr2_1);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 2 * 16), tr2_2);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 3 * 16), tr2_3);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 4 * 16), tr2_4);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 5 * 16), tr2_5);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 6 * 16), tr2_6);
-        _mm_storeu_si128 ((__m128i *)(out + 8 + 7 * 16), tr2_7);
+        _mm_storeu_si128((__m128i *)(out + 8 + 0 * 16), tr2_0);
+        _mm_storeu_si128((__m128i *)(out + 8 + 1 * 16), tr2_1);
+        _mm_storeu_si128((__m128i *)(out + 8 + 2 * 16), tr2_2);
+        _mm_storeu_si128((__m128i *)(out + 8 + 3 * 16), tr2_3);
+        _mm_storeu_si128((__m128i *)(out + 8 + 4 * 16), tr2_4);
+        _mm_storeu_si128((__m128i *)(out + 8 + 5 * 16), tr2_5);
+        _mm_storeu_si128((__m128i *)(out + 8 + 6 * 16), tr2_6);
+        _mm_storeu_si128((__m128i *)(out + 8 + 7 * 16), tr2_7);
       }
       out += 8*16;
     }
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 32cd62037f811bcfb2c535b13d63c4a31ffaf3e2..c240a9e614400e6999b1a4b6daf5c90abb2fa5c8 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -406,7 +406,7 @@ static void parse_superframe_index(const uint8_t *data,
 
     if (data_sz >= index_sz && data[data_sz - index_sz] == marker) {
       // found a valid superframe index
-      int i, j;
+      uint32_t i, j;
       const uint8_t *x = data + data_sz - index_sz + 1;
 
       for (i = 0; i < frames; i++) {
diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h
index f1cf6265e766a05fb3a094dd84d81a799df9e650..a51cd2e01bb3f14dfc968ad9898a27b9d408dc78 100644
--- a/vpx_ports/x86.h
+++ b/vpx_ports/x86.h
@@ -33,7 +33,7 @@ typedef enum {
   VPX_CPU_LAST
 }  vpx_cpu_t;
 
-#if defined(__GNUC__) && __GNUC__
+#if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__)
 #if ARCH_X86_64
 #define cpuid(func,ax,bx,cx,dx)\
   __asm__ __volatile__ (\
@@ -49,7 +49,7 @@ typedef enum {
                         : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
                         : "a" (func));
 #endif
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/
 #if ARCH_X86_64
 #define cpuid(func,ax,bx,cx,dx)\
   asm volatile (\
@@ -69,7 +69,7 @@ typedef enum {
                 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
                 : "a" (func));
 #endif
-#else
+#else /* end __SUNPRO__ */
 #if ARCH_X86_64
 void __cpuid(int CPUInfo[4], int info_type);
 #pragma intrinsic(__cpuid)
@@ -86,7 +86,7 @@ void __cpuid(int CPUInfo[4], int info_type);
   __asm mov c, ecx\
   __asm mov d, edx
 #endif
-#endif
+#endif /* end others */
 
 #define HAS_MMX   0x01
 #define HAS_SSE   0x02
diff --git a/vpxdec.c b/vpxdec.c
index 9ae868f294b0c53f5ae068314c1aca038886f79b..deb45d35949e26287679dab87bed021505cd6c2d 100644
--- a/vpxdec.c
+++ b/vpxdec.c
@@ -715,6 +715,7 @@ int main(int argc, const char **argv_) {
   int                     do_scale = 0;
   int                     stream_w = 0, stream_h = 0;
   vpx_image_t             *scaled_img = NULL;
+  int                     frame_avail, got_data;
 
   /* Parse command line */
   exec_name = argv_[0];
@@ -982,30 +983,50 @@ int main(int argc, const char **argv_) {
     arg_skip--;
   }
 
+  frame_avail = 1;
+  got_data = 0;
+
   /* Decode file */
-  while (!read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) {
+  while (frame_avail || got_data) {
     vpx_codec_iter_t  iter = NULL;
     vpx_image_t    *img;
     struct vpx_usec_timer timer;
     int                   corrupted;
 
-    vpx_usec_timer_start(&timer);
+    frame_avail = 0;
+    if (!stop_after || frame_in < stop_after) {
+      if(!read_frame(&input, &buf, &buf_sz, &buf_alloc_sz)) {
+        frame_avail = 1;
+        frame_in++;
 
-    if (vpx_codec_decode(&decoder, buf, (unsigned int)buf_sz, NULL, 0)) {
-      const char *detail = vpx_codec_error_detail(&decoder);
-      fprintf(stderr, "Failed to decode frame: %s\n", vpx_codec_error(&decoder));
+        vpx_usec_timer_start(&timer);
 
-      if (detail)
-        fprintf(stderr, "  Additional information: %s\n", detail);
+        if (vpx_codec_decode(&decoder, buf, (unsigned int)buf_sz, NULL, 0)) {
+          const char *detail = vpx_codec_error_detail(&decoder);
+          fprintf(stderr, "Failed to decode frame: %s\n",
+                  vpx_codec_error(&decoder));
 
-      goto fail;
+          if (detail)
+            fprintf(stderr, "  Additional information: %s\n", detail);
+          goto fail;
+        }
+
+        vpx_usec_timer_mark(&timer);
+        dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
+      }
+    }
+
+    vpx_usec_timer_start(&timer);
+
+    got_data = 0;
+    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
+      ++frame_out;
+      got_data = 1;
     }
 
     vpx_usec_timer_mark(&timer);
     dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
 
-    ++frame_in;
-
     if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
       fprintf(stderr, "Failed VP8_GET_FRAME_CORRUPTED: %s\n",
               vpx_codec_error(&decoder));
@@ -1013,14 +1034,6 @@ int main(int argc, const char **argv_) {
     }
     frames_corrupted += corrupted;
 
-    vpx_usec_timer_start(&timer);
-
-    if ((img = vpx_codec_get_frame(&decoder, &iter)))
-      ++frame_out;
-
-    vpx_usec_timer_mark(&timer);
-    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);
-
     if (progress)
       show_progress(frame_in, frame_out, dx_time);