Merge "Removed space in ETA printout"
diff --git a/build/make/gen_msvs_proj.sh b/build/make/gen_msvs_proj.sh
index 5936370..df91435 100755
--- a/build/make/gen_msvs_proj.sh
+++ b/build/make/gen_msvs_proj.sh
@@ -162,7 +162,8 @@
                         done
                     done
                 fi
-                if [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then
+                if [ "$pat" == "c" ] || \
+                   [ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
                     for plat in "${platforms[@]}"; do
                         for cfg in Debug Release; do
                             open_tag FileConfiguration \
@@ -561,7 +562,7 @@
     close_tag Configurations
 
     open_tag Files
-    generate_filter srcs   "Source Files"   "c;cc;def;odl;idl;hpj;bat;asm;asmx"
+    generate_filter srcs   "Source Files"   "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
     generate_filter hdrs   "Header Files"   "h;hm;inl;inc;xsd"
     generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
     generate_filter resrcs "Build Files"    "mk"
diff --git a/build/make/gen_msvs_vcxproj.sh b/build/make/gen_msvs_vcxproj.sh
index 7c8871b..23990a4 100755
--- a/build/make/gen_msvs_vcxproj.sh
+++ b/build/make/gen_msvs_vcxproj.sh
@@ -174,7 +174,8 @@
                         done
                     done
                     close_tag CustomBuild
-                elif [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then
+                elif [ "$pat" == "c" ] || \
+                     [ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
                     open_tag ClCompile \
                         Include=".\\$f"
                     # Separate file names with Condition?
@@ -524,7 +525,7 @@
     done
 
     open_tag ItemGroup
-    generate_filter "Source Files"   "c;cc;def;odl;idl;hpj;bat;asm;asmx;s"
+    generate_filter "Source Files"   "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s"
     close_tag ItemGroup
     open_tag ItemGroup
     generate_filter "Header Files"   "h;hm;inl;inc;xsd"
diff --git a/examples.mk b/examples.mk
index 87be5a8..fa5d66c 100644
--- a/examples.mk
+++ b/examples.mk
@@ -70,7 +70,7 @@
 vp9_spatial_scalable_encoder.GUID   = 4A38598D-627D-4505-9C7B-D4020C84100D
 vp9_spatial_scalable_encoder.DESCRIPTION = Spatial Scalable Encoder
 
-ifeq ($(CONFIG_SHARED),no)
+ifneq ($(CONFIG_SHARED),yes)
 EXAMPLES-$(CONFIG_VP9_ENCODER)    += resize_util.c
 endif
 
diff --git a/examples/vpx_temporal_scalable_patterns.c b/examples/vpx_temporal_scalable_patterns.c
index 3a4f05b..5cb4ee9 100644
--- a/examples/vpx_temporal_scalable_patterns.c
+++ b/examples/vpx_temporal_scalable_patterns.c
@@ -575,6 +575,7 @@
   } else if (strncmp(encoder->name, "vp9", 3) == 0) {
       vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
       vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
+      vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
       vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 0);
       if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) {
         die_codec(&codec, "Failed to set SVC");
diff --git a/test/tools_common.sh b/test/tools_common.sh
new file mode 100755
index 0000000..cd79771
--- /dev/null
+++ b/test/tools_common.sh
@@ -0,0 +1,437 @@
+#!/bin/sh
+##
+##  Copyright (c) 2014 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.
+##
+##  This file contains shell code shared by test scripts for libvpx tools.
+set -e
+
+# Sets $VPX_TOOL_TEST to the name specified by positional parameter one.
+test_begin() {
+  VPX_TOOL_TEST="${1}"
+}
+
+# Clears the VPX_TOOL_TEST variable after confirming that $VPX_TOOL_TEST matches
+# positional parameter one.
+test_end() {
+  if [ "$1" != "${VPX_TOOL_TEST}" ]; then
+    echo "FAIL completed test mismatch!."
+    echo "  completed test: ${1}"
+    echo "  active test: ${VPX_TOOL_TEST}."
+    return 1
+  fi
+  VPX_TOOL_TEST='<unset>'
+}
+
+# Echoes the target configuration being tested.
+test_configuration_target() {
+  vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
+  # Find the TOOLCHAIN line, split it using ':=' as the field separator, and
+  # print the last field to get the value. Then pipe the value to tr to consume
+  # any leading/trailing spaces while allowing tr to echo the output to stdout.
+  awk -F ':=' '/TOOLCHAIN/ { print $NF }' "${vpx_config_mk}" | tr -d ' '
+}
+
+# Trap function used for failure reports and tool output directory removal.
+# When the contents of $VPX_TOOL_TEST do not match the string '<unset>', reports
+# failure of test stored in $VPX_TOOL_TEST.
+cleanup() {
+  if [ -n "${VPX_TOOL_TEST}" ] && [ "${VPX_TOOL_TEST}" != '<unset>' ]; then
+    echo "FAIL: $VPX_TOOL_TEST"
+  fi
+  if [ -n "${VPX_TEST_OUTPUT_DIR}" ] && [ -d "${VPX_TEST_OUTPUT_DIR}" ]; then
+    rm -rf "${VPX_TEST_OUTPUT_DIR}"
+  fi
+}
+
+# Echoes the git hash portion of the VERSION_STRING variable defined in
+# $LIBVPX_CONFIG_PATH/config.mk to stdout, or the version number string when
+# no git hash is contained in VERSION_STRING.
+config_hash() {
+  vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
+  # Find VERSION_STRING line, split it with "-g" and print the last field to
+  # output the git hash to stdout.
+  vpx_version=$(awk -F -g '/VERSION_STRING/ {print $NF}' "${vpx_config_mk}")
+  # Handle two situations here:
+  # 1. The default case: $vpx_version is a git hash, so echo it unchanged.
+  # 2. When being run a non-dev tree, the -g portion is not present in the
+  #    version string: It's only the version number.
+  #    In this case $vpx_version is something like 'VERSION_STRING=v1.3.0', so
+  #    we echo only what is after the '='.
+  echo "${vpx_version##*=}"
+}
+
+# Echoes the short form of the current git hash.
+current_hash() {
+  if git --version > /dev/null 2>&1; then
+    (cd "$(dirname "${0}")"
+    git rev-parse --short HEAD)
+  else
+    # Return the config hash if git is unavailable: Fail silently, git hashes
+    # are used only for warnings.
+    config_hash
+  fi
+}
+
+# Echoes warnings to stdout when git hash in vpx_config.h does not match the
+# current git hash.
+check_git_hashes() {
+  hash_at_configure_time=$(config_hash)
+  hash_now=$(current_hash)
+
+  if [ "${hash_at_configure_time}" != "${hash_now}" ]; then
+    echo "Warning: git hash has changed since last configure."
+  fi
+}
+
+# This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and
+# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that
+# the variables are set and that they all evaluate to directory paths.
+verify_vpx_test_environment() {
+  if [ ! -d "${LIBVPX_BIN_PATH}" ]; then
+    echo "The LIBVPX_BIN_PATH environment variable must be set."
+    return 1
+  fi
+  if [ ! -d "${LIBVPX_CONFIG_PATH}" ]; then
+    echo "The LIBVPX_CONFIG_PATH environment variable must be set."
+    return 1
+  fi
+  if [ ! -d "${LIBVPX_TEST_DATA_PATH}" ]; then
+    echo "The LIBVPX_TEST_DATA_PATH environment variable must be set."
+    return 1
+  fi
+}
+
+# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which
+# should be a LIBVPX preprocessor flag. Echoes yes to stdout when the feature
+# is available.
+vpx_config_option_enabled() {
+  vpx_config_option="${1}"
+  vpx_config_file="${LIBVPX_CONFIG_PATH}/vpx_config.h"
+  config_line=$(grep "${vpx_config_option}" "${vpx_config_file}")
+  if echo "${config_line}" | egrep -q '1$'; then
+    echo yes
+  fi
+}
+
+# Echoes yes when output of test_configuration_target() contains win32 or win64.
+is_windows_target() {
+  if test_configuration_target \
+     | grep -q -e win32 -e win64 > /dev/null 2>&1; then
+    echo yes
+  fi
+}
+
+# Echoes yes to stdout when the file named by positional parameter one exists
+# in LIBVPX_BIN_PATH, and is executable.
+vpx_tool_available() {
+  tool_name="${1}"
+  if [ "$(is_windows_target)" = "yes" ]; then
+    tool_name="${tool_name}.exe"
+  fi
+  [ -x "${LIBVPX_BIN_PATH}/${1}" ] && echo yes
+}
+
+# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
+# CONFIG_VP8_DECODER.
+vp8_decode_available() {
+  [ "$(vpx_config_option_enabled CONFIG_VP8_DECODER)" = "yes" ] && echo yes
+}
+
+# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
+# CONFIG_VP8_ENCODER.
+vp8_encode_available() {
+  [ "$(vpx_config_option_enabled CONFIG_VP8_ENCODER)" = "yes" ] && echo yes
+}
+
+# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
+# CONFIG_VP9_DECODER.
+vp9_decode_available() {
+  [ "$(vpx_config_option_enabled CONFIG_VP9_DECODER)" = "yes" ] && echo yes
+}
+
+# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
+# CONFIG_VP9_ENCODER.
+vp9_encode_available() {
+  [ "$(vpx_config_option_enabled CONFIG_VP9_ENCODER)" = "yes" ] && echo yes
+}
+
+# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
+# CONFIG_WEBM_IO.
+webm_io_available() {
+  [ "$(vpx_config_option_enabled CONFIG_WEBM_IO)" = "yes" ] && echo yes
+}
+
+# Echoes yes to stdout when vpxdec exists according to vpx_tool_available().
+vpxdec_available() {
+  [ -n $(vpx_tool_available vpxdec) ] && echo yes
+}
+
+# Wrapper function for running vpxdec in noblit mode. Requires that
+# LIBVPX_BIN_PATH points to the directory containing vpxdec. Positional
+# parameter one is used as the input file path. Positional parameter two, when
+# present, is interpreted as a boolean flag that means the input should be sent
+# to vpxdec via pipe from cat instead of directly.
+vpxdec() {
+  input="${1}"
+  pipe_input=${2}
+
+  if [ $# -gt 2 ]; then
+    # shift away $1 and $2 so the remaining arguments can be passed to vpxdec
+    # via $@.
+    shift 2
+  fi
+
+  decoder="${LIBVPX_BIN_PATH}/vpxdec"
+
+  if [ "$(is_windows_target)" = "yes" ]; then
+    decoder="${decoder}.exe"
+  fi
+
+  if [ -z "${pipe_input}" ]; then
+    "${decoder}" "$input" --summary --noblit "$@" > /dev/null 2>&1
+  else
+    cat "${input}" | "${decoder}" - --summary --noblit "$@" > /dev/null 2>&1
+  fi
+}
+
+# Echoes yes to stdout when vpxenc exists according to vpx_tool_available().
+vpxenc_available() {
+  [ -n $(vpx_tool_available vpxenc) ] && echo yes
+}
+
+# Wrapper function for running vpxenc. Positional parameters are interpreted as
+# follows:
+#   1 - codec name
+#   2 - input width
+#   3 - input height
+#   4 - number of frames to encode
+#   5 - path to input file
+#   6 - path to output file
+#       Note: The output file path must end in .ivf to output an IVF file.
+#   7 - extra flags
+#       Note: Extra flags currently supports a special case: when set to "-"
+#             input is piped to vpxenc via cat.
+vpxenc() {
+  encoder="${LIBVPX_BIN_PATH}/vpxenc"
+  codec="${1}"
+  width=${2}
+  height=${3}
+  frames=${4}
+  input=${5}
+  output="${VPX_TEST_OUTPUT_DIR}/${6}"
+  extra_flags=${7}
+
+  if [ "$(is_windows_target)" = "yes" ]; then
+    encoder="${encoder}.exe"
+  fi
+
+  # Because --ivf must be within the command line to get IVF from vpxenc.
+  if echo "${output}" | egrep -q 'ivf$'; then
+    use_ivf=--ivf
+  else
+    unset use_ivf
+  fi
+
+  if [ "${extra_flags}" = "-" ]; then
+    pipe_input=yes
+    extra_flags=${8}
+  else
+    unset pipe_input
+  fi
+
+  if [ -z "${pipe_input}" ]; then
+    "${encoder}" --codec=${codec} --width=${width} --height=${height} \
+        --limit=${frames} ${use_ivf} ${extra_flags} --output="${output}" \
+        "${input}" > /dev/null 2>&1
+  else
+    cat "${input}" \
+        | "${encoder}" --codec=${codec} --width=${width} --height=${height} \
+            --limit=${frames} ${use_ivf} ${extra_flags} --output="${output}" - \
+            > /dev/null 2>&1
+  fi
+
+  if [ ! -e "${output}" ]; then
+    # Return non-zero exit status: output file doesn't exist, so something
+    # definitely went wrong.
+    return 1
+  fi
+}
+
+# Filters strings from positional parameter one using the filter specified by
+# positional parameter two. Filter behavior depends on the presence of a third
+# positional parameter. When parameter three is present, strings that match the
+# filter are excluded. When omitted, strings matching the filter are included.
+# The filtered string is echoed to stdout.
+filter_strings() {
+  strings=${1}
+  filter=${2}
+  exclude=${3}
+
+  if [ -n "${exclude}" ]; then
+    # When positional parameter three exists the caller wants to remove strings.
+    # Tell grep to invert matches using the -v argument.
+    exclude='-v'
+  else
+    unset exclude
+  fi
+
+  if [ -n "${filter}" ]; then
+    for s in ${strings}; do
+      if echo "${s}" | egrep -q ${exclude} "${filter}" > /dev/null 2>&1; then
+        filtered_strings="${filtered_strings} ${s}"
+      fi
+    done
+  else
+    filtered_strings="${strings}"
+  fi
+  echo "${filtered_strings}"
+}
+
+# Runs user test functions passed via positional parameters one and two.
+# Functions in positional parameter one are treated as environment verification
+# functions and are run unconditionally. Functions in positional parameter two
+# are run according to the rules specified in vpx_test_usage().
+run_tests() {
+  env_tests="verify_vpx_test_environment ${1}"
+  tests_to_filter="${2}"
+
+  if [ "${VPX_TEST_RUN_DISABLED_TESTS}" != "yes" ]; then
+    # Filter out DISABLED tests.
+    tests_to_filter=$(filter_strings "${tests_to_filter}" ^DISABLED exclude)
+  fi
+
+  if [ -n "${VPX_TEST_FILTER}" ]; then
+    # Remove tests not matching the user's filter.
+    tests_to_filter=$(filter_strings "${tests_to_filter}" ${VPX_TEST_FILTER})
+  fi
+
+  tests_to_run="${env_tests} ${tests_to_filter}"
+
+  check_git_hashes
+
+  # Run tests.
+  for test in ${tests_to_run}; do
+    test_begin "${test}"
+    "${test}"
+    [ "${VPX_TEST_VERBOSE_OUTPUT}" = "yes" ] && echo "  PASS ${test}"
+    test_end "${test}"
+  done
+
+  tested_config="$(test_configuration_target) @ $(current_hash)"
+  echo $(basename "${0%.*}"): Done, all tests pass for ${tested_config}.
+}
+
+vpx_test_usage() {
+cat << EOF
+  Usage: ${0##*/} [arguments]
+    --bin-path <path to libvpx binaries directory>
+    --config-path <path to libvpx config directory>
+    --filter <filter>: User test filter. Only tests matching filter are run.
+    --run-disabled-tests: Run disabled tests.
+    --help: Display this message and exit.
+    --test-data-path <path to libvpx test data directory>
+    --verbose: Verbose output.
+
+    When the --bin-path option is not specified the script attempts to use
+    \$LIBVPX_BIN_PATH and then the current directory.
+
+    When the --config-path option is not specified the script attempts to use
+    \$LIBVPX_CONFIG_PATH and then the current directory.
+
+    When the -test-data-path option is not specified the script attempts to use
+    \$LIBVPX_TEST_DATA_PATH and then the current directory.
+EOF
+}
+
+# Returns non-zero (failure) when required environment variables are empty
+# strings.
+vpx_test_check_environment() {
+  if [ -z "${LIBVPX_BIN_PATH}" ] || \
+     [ -z "${LIBVPX_CONFIG_PATH}" ] || \
+     [ -z "${LIBVPX_TEST_DATA_PATH}" ]; then
+    return 1
+  fi
+}
+
+# Parse the command line.
+while [ -n "$1" ]; do
+  case "$1" in
+    --bin-path)
+      LIBVPX_BIN_PATH="$2"
+      shift
+      ;;
+    --config-path)
+      LIBVPX_CONFIG_PATH="$2"
+      shift
+      ;;
+    --filter)
+      VPX_TEST_FILTER="$2"
+      shift
+      ;;
+    --run-disabled-tests)
+      VPX_TEST_RUN_DISABLED_TESTS=yes
+      ;;
+    --help)
+      vpx_test_usage
+      exit
+      ;;
+    --test-data-path)
+      LIBVPX_TEST_DATA_PATH="$2"
+      shift
+      ;;
+    --verbose)
+      VPX_TEST_VERBOSE_OUTPUT=yes
+      ;;
+    *)
+      vpx_test_usage
+      exit 1
+      ;;
+  esac
+  shift
+done
+
+# Handle running the tests from a build directory without arguments when running
+# the tests on *nix/macosx.
+LIBVPX_BIN_PATH="${LIBVPX_BIN_PATH:-.}"
+LIBVPX_CONFIG_PATH="${LIBVPX_CONFIG_PATH:-.}"
+LIBVPX_TEST_DATA_PATH="${LIBVPX_TEST_DATA_PATH:-.}"
+
+# Create a temporary directory for output files, and a trap to clean it up.
+if [ -n "${TMPDIR}" ]; then
+  VPX_TEST_TEMP_ROOT="${TMPDIR}"
+elif [ -n "${TEMPDIR}" ]; then
+  VPX_TEST_TEMP_ROOT="${TEMPDIR}"
+else
+  VPX_TEST_TEMP_ROOT=/tmp
+fi
+
+VPX_TEST_RAND=$(awk 'BEGIN { srand(); printf "%d\n",(rand() * 32768)}')
+VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_${VPX_TEST_RAND}"
+
+if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \
+   [ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then
+  echo "${0##*/}: Cannot create output directory, giving up."
+  echo "${0##*/}:   VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}"
+  exit 1
+fi
+
+trap cleanup EXIT
+
+if [ "${VPX_TEST_VERBOSE_OUTPUT}" = "yes" ]; then
+cat << EOF
+$(basename "${0%.*}") test configuration:
+  LIBVPX_BIN_PATH=${LIBVPX_BIN_PATH}
+  LIBVPX_CONFIG_PATH=${LIBVPX_CONFIG_PATH}
+  LIBVPX_TEST_DATA_PATH=${LIBVPX_TEST_DATA_PATH}
+  VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
+  VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT}
+  VPX_TEST_FILTER=${VPX_TEST_FILTER}
+  VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
+EOF
+fi
diff --git a/test/vpxdec.sh b/test/vpxdec.sh
new file mode 100755
index 0000000..d236f97
--- /dev/null
+++ b/test/vpxdec.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+##
+##  Copyright (c) 2014 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.
+##
+##  This file tests vpxdec. To add new tests to this file, do the following:
+##    1. Write a shell function (this is your test).
+##    2. Add the function to vpxdec_tests (on a new line).
+##
+. $(dirname $0)/tools_common.sh
+
+VP8_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp80-00-comprehensive-001.ivf"
+VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm"
+
+# Environment check: Make sure input is available.
+vpxdec_verify_environment() {
+  if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_WEBM_FILE}" ]; then
+    echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
+    return 1
+  fi
+}
+
+vpxdec_can_decode_vp8() {
+  if [ "$(vpxdec_available)" = "yes" ] && \
+     [ "$(vp8_decode_available)" = "yes" ]; then
+    echo yes
+  fi
+}
+
+vpxdec_can_decode_vp9() {
+  if [ "$(vpxdec_available)" = "yes" ] && \
+     [ "$(vp9_decode_available)" = "yes" ]; then
+    echo yes
+  fi
+}
+
+vpxdec_vp8_ivf() {
+  if [ "$(vpxdec_can_decode_vp8)" = "yes" ]; then
+    vpxdec "${VP8_IVF_FILE}"
+  fi
+}
+
+vpxdec_vp8_ivf_pipe_input() {
+  if [ "$(vpxdec_can_decode_vp8)" = "yes" ]; then
+    vpxdec "${VP8_IVF_FILE}" -
+  fi
+}
+
+vpxdec_vp9_webm() {
+  if [ "$(vpxdec_can_decode_vp9)" = "yes" ] && \
+     [ "$(webm_io_available)" = "yes" ]; then
+    vpxdec "${VP9_WEBM_FILE}"
+  fi
+}
+
+vpxdec_tests="vpxdec_vp8_ivf
+              vpxdec_vp8_ivf_pipe_input
+              vpxdec_vp9_webm"
+
+run_tests vpxdec_verify_environment "${vpxdec_tests}"
diff --git a/test/vpxenc.sh b/test/vpxenc.sh
new file mode 100755
index 0000000..89e4eb3
--- /dev/null
+++ b/test/vpxenc.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+##
+##  Copyright (c) 2014 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.
+##
+##  This file tests vpxenc using hantro_collage_w352h288.yuv as input. To add
+##  new tests to this file, do the following:
+##    1. Write a shell function (this is your test).
+##    2. Add the function to vpxenc_tests (on a new line).
+##
+. $(dirname $0)/tools_common.sh
+
+YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv"
+YUV_RAW_INPUT_WIDTH=352
+YUV_RAW_INPUT_HEIGHT=288
+TEST_FRAMES=10
+
+# Environment check: Make sure input is available.
+vpxenc_verify_environment() {
+  if [ ! -e "${YUV_RAW_INPUT}" ]; then
+    echo "The file ${YUV_RAW_INPUT##*/} must exist in LIBVPX_TEST_DATA_PATH."
+    return 1
+  fi
+}
+
+vpxenc_can_encode_vp8() {
+  if [ "$(vpxenc_available)" = "yes" ] && \
+     [ "$(vp8_encode_available)" = "yes" ]; then
+    echo yes
+  fi
+}
+
+vpxenc_can_encode_vp9() {
+  if [ "$(vpxenc_available)" = "yes" ] && \
+     [ "$(vp9_encode_available)" = "yes" ]; then
+    echo yes
+  fi
+}
+
+vpxenc_vp8_ivf() {
+  if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then
+    vpxenc vp8 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp8.ivf
+  fi
+}
+
+vpxenc_vp8_ivf_pipe_input() {
+  if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then
+    vpxenc vp8 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp8.ivf -
+  fi
+}
+
+vpxenc_vp8_webm() {
+  if [ "$(vpxenc_can_encode_vp8)" = "yes" ] &&
+     [ "$(webm_io_available)" = "yes" ] ; then
+    vpxenc vp8 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp8.webm
+  fi
+}
+
+vpxenc_vp9_ivf() {
+  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
+    vpxenc vp9 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp9.ivf
+  fi
+}
+
+vpxenc_vp9_webm() {
+  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] &&
+     [ "$(webm_io_available)" = "yes" ] ; then
+    vpxenc vp9 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp9.webm
+  fi
+}
+
+DISABLED_vpxenc_vp9_ivf_lossless() {
+  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
+    vpxenc vp9 ${YUV_RAW_INPUT_WIDTH} ${YUV_RAW_INPUT_HEIGHT} ${TEST_FRAMES} \
+        "${YUV_RAW_INPUT}" vp9_lossless.ivf --lossless
+  fi
+}
+
+vpxenc_tests="vpxenc_vp8_ivf
+              vpxenc_vp8_webm
+              vpxenc_vp8_ivf_pipe_input
+              vpxenc_vp9_ivf
+              vpxenc_vp9_webm
+              DISABLED_vpxenc_vp9_ivf_lossless"
+
+run_tests vpxenc_verify_environment "${vpxenc_tests}"
diff --git a/tools_common.h b/tools_common.h
index 58894de..549e895 100644
--- a/tools_common.h
+++ b/tools_common.h
@@ -22,10 +22,12 @@
 #endif
 
 #if defined(_MSC_VER)
-/* MSVS doesn't define off_t, and uses _f{seek,tell}i64. */
-typedef __int64 off_t;
+/* MSVS uses _f{seek,tell}i64. */
 #define fseeko _fseeki64
 #define ftello _ftelli64
+typedef long _off_t;  // NOLINT - MSVS compatible type
+typedef __int64 off_t;  // fseeki64 compatible type
+#define _OFF_T_DEFINED
 #elif defined(_WIN32)
 /* MinGW defines off_t as long and uses f{seek,tell}o64/off64_t for large
  * files. */
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h
index 1f7e632..55320a6 100644
--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -231,8 +231,6 @@
   /* Inverse transform function pointers. */
   void (*itxm_add)(const int16_t *input, uint8_t *dest, int stride, int eob);
 
-  const InterpKernel *interp_kernel;
-
   int corrupted;
 
   DECLARE_ALIGNED(16, int16_t, dqcoeff[MAX_MB_PLANE][64 * 64]);
diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c
index 0ab50d4..e722d6a 100644
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -146,6 +146,7 @@
   struct macroblockd_plane *const pd = &xd->plane[plane];
   const MODE_INFO *mi = xd->mi[0];
   const int is_compound = has_second_ref(&mi->mbmi);
+  const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
   int ref;
 
   for (ref = 0; ref < 1 + is_compound; ++ref) {
@@ -193,8 +194,7 @@
            + (scaled_mv.col >> SUBPEL_BITS);
 
     inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
-                    subpel_x, subpel_y, sf, w, h, ref, xd->interp_kernel,
-                    xs, ys);
+                    subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
   }
 }
 
@@ -250,6 +250,7 @@
   struct macroblockd_plane *const pd = &xd->plane[plane];
   const MODE_INFO *mi = xd->mi[0];
   const int is_compound = has_second_ref(&mi->mbmi);
+  const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
   int ref;
 
   for (ref = 0; ref < 1 + is_compound; ++ref) {
@@ -377,7 +378,7 @@
     }
 
     inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
-                    subpel_y, sf, w, h, ref, xd->interp_kernel, xs, ys);
+                    subpel_y, sf, w, h, ref, kernel, xs, ys);
   }
 }
 
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 53f94f8..5a2e6f8 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -360,8 +360,6 @@
     if (has_second_ref(mbmi))
       set_ref(cm, xd, 1, mi_row, mi_col);
 
-    xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
-
     // Prediction
     vp9_dec_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
 
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 7c811e2..dbefe1e 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -484,12 +484,12 @@
   }
 }
 
-static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size) {
+static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size,
+                                    vp9_coeff_stats *coef_branch_ct) {
   vp9_coeff_probs_model *coef_probs = cpi->frame_coef_probs[tx_size];
   vp9_coeff_count *coef_counts = cpi->coef_counts[tx_size];
   unsigned int (*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] =
       cpi->common.counts.eob_branch[tx_size];
-  vp9_coeff_stats *coef_branch_ct = cpi->frame_branch_ct[tx_size];
   int i, j, k, l, m;
 
   for (i = 0; i < PLANE_TYPES; ++i) {
@@ -512,11 +512,11 @@
 }
 
 static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
-                                     TX_SIZE tx_size) {
+                                     TX_SIZE tx_size,
+                                     vp9_coeff_stats *frame_branch_ct) {
   vp9_coeff_probs_model *new_frame_coef_probs = cpi->frame_coef_probs[tx_size];
   vp9_coeff_probs_model *old_frame_coef_probs =
       cpi->common.fc.coef_probs[tx_size];
-  vp9_coeff_stats *frame_branch_ct = cpi->frame_branch_ct[tx_size];
   const vp9_prob upd = DIFF_UPDATE_PROB;
   const int entropy_nodes_update = UNCONSTRAINED_NODES;
   int i, j, k, l, t;
@@ -669,13 +669,15 @@
   const TX_MODE tx_mode = cpi->common.tx_mode;
   const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
   TX_SIZE tx_size;
+  vp9_coeff_stats frame_branch_ct[TX_SIZES][PLANE_TYPES];
+
   vp9_clear_system_state();
 
   for (tx_size = TX_4X4; tx_size <= TX_32X32; ++tx_size)
-    build_tree_distribution(cpi, tx_size);
+    build_tree_distribution(cpi, tx_size, frame_branch_ct[tx_size]);
 
   for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
-    update_coef_probs_common(w, cpi, tx_size);
+    update_coef_probs_common(w, cpi, tx_size, frame_branch_ct[tx_size]);
 }
 
 static void encode_loopfilter(struct loopfilter *lf,
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 42e1ac8..67b8b02 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -856,13 +856,22 @@
 
   *mi_addr = *mi;
 
-  // For in frame adaptive Q, check for reseting the segment_id and updating
-  // the cyclic refresh map.
-  if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled &&
-      output_enabled) {
-    vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
-                                      mi_row, mi_col, bsize, 1);
-    vp9_init_plane_quantizers(cpi, x);
+  // If segmentation in use
+  if (seg->enabled && output_enabled) {
+    // For in frame complexity AQ copy the segment id from the segment map.
+    if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
+      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
+                                                 : cm->last_frame_seg_map;
+      mi_addr->mbmi.segment_id =
+        vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
+    }
+    // Else for cyclic refresh mode update the segment map, set the segment id
+    // and then update the quantizer.
+    else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
+      vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
+                                        mi_row, mi_col, bsize, 1);
+      vp9_init_plane_quantizers(cpi, x);
+    }
   }
 
   max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
@@ -3430,7 +3439,6 @@
     }
   } else {
     set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
-    xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
 
     if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
       // Adjust the zbin based on this MB rate.
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 7ec5255..26fc280 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -61,6 +61,8 @@
 #define MIN_GF_INTERVAL             4
 #endif
 
+#define DISABLE_RC_LONG_TERM_MEM
+
 static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
   YV12_BUFFER_CONFIG temp = *a;
   *a = *b;
@@ -2330,7 +2332,11 @@
 }
 
 void vp9_twopass_postencode_update(VP9_COMP *cpi) {
+#ifdef DISABLE_RC_LONG_TERM_MEM
+  const uint64_t bits_used = cpi->rc.this_frame_target;
+#else
   const uint64_t bits_used = cpi->rc.projected_frame_size;
+#endif
   cpi->twopass.bits_left -= bits_used;
   cpi->twopass.bits_left = MAX(cpi->twopass.bits_left, 0);
   // Update bits left to the kf and gf groups to account for overshoot or
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index b42fd38..d407010 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -500,8 +500,7 @@
                               MV *ref_mv,
                               int search_param,
                               int sad_per_bit,
-                              int do_init_search,
-                              int do_refine,
+                              int do_init_search, int do_refine,
                               const vp9_variance_fn_ptr_t *vfp,
                               int use_mvcost,
                               const MV *center_mv, MV *best_mv,
@@ -513,20 +512,15 @@
     10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
   };
   int i, j, s, t;
-  const uint8_t *what = x->plane[0].src.buf;
-  const int what_stride = x->plane[0].src.stride;
-  const int in_what_stride = xd->plane[0].pre[0].stride;
+  const struct buf_2d *const what = &x->plane[0].src;
+  const struct buf_2d *const in_what = &xd->plane[0].pre[0];
   int br, bc;
-  MV this_mv;
   int bestsad = INT_MAX;
   int thissad;
-  const uint8_t *base_offset;
-  const uint8_t *this_offset;
   int k = -1;
-  int best_site = -1;
   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
   int best_init_s = search_param_to_steps[search_param];
-  const int *mvjsadcost = x->nmvjointsadcost;
+  const int *const mvjsadcost = x->nmvjointsadcost;
   int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]};
 
   // adjust ref_mv to make sure it is within MV range
@@ -535,13 +529,10 @@
   bc = ref_mv->col;
 
   // Work out the start point for the search
-  base_offset = xd->plane[0].pre[0].buf;
-  this_offset = base_offset + (br * in_what_stride) + bc;
-  this_mv.row = br;
-  this_mv.col = bc;
-  bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride, 0x7fffffff)
-                + mvsad_err_cost(&this_mv, &fcenter_mv,
-                                 mvjsadcost, mvsadcost, sad_per_bit);
+  bestsad = vfp->sdf(what->buf, what->stride,
+                     get_buf_from_mv(in_what, ref_mv), in_what->stride,
+                     0x7fffffff) + mvsad_err_cost(ref_mv, &fcenter_mv,
+                         mvjsadcost, mvsadcost, sad_per_bit);
 
   // Search all possible scales upto the search param around the center point
   // pick the scale of the point that is best as the starting scale of
@@ -550,27 +541,25 @@
     s = best_init_s;
     best_init_s = -1;
     for (t = 0; t <= s; ++t) {
-      best_site = -1;
+      int best_site = -1;
       if (check_bounds(x, br, bc, 1 << t)) {
         for (i = 0; i < num_candidates[t]; i++) {
-          this_mv.row = br + candidates[t][i].row;
-          this_mv.col = bc + candidates[t][i].col;
-          this_offset = base_offset + (this_mv.row * in_what_stride) +
-                                       this_mv.col;
-          thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                             bestsad);
+          const MV this_mv = {br + candidates[t][i].row,
+                              bc + candidates[t][i].col};
+          thissad = vfp->sdf(what->buf, what->stride,
+                             get_buf_from_mv(in_what, &this_mv),
+                             in_what->stride, bestsad);
           CHECK_BETTER
         }
       } else {
         for (i = 0; i < num_candidates[t]; i++) {
-          this_mv.row = br + candidates[t][i].row;
-          this_mv.col = bc + candidates[t][i].col;
+          const MV this_mv = {br + candidates[t][i].row,
+                              bc + candidates[t][i].col};
           if (!is_mv_in(x, &this_mv))
             continue;
-          this_offset = base_offset + (this_mv.row * in_what_stride) +
-                                       this_mv.col;
-          thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                             bestsad);
+          thissad = vfp->sdf(what->buf, what->stride,
+                             get_buf_from_mv(in_what, &this_mv),
+                             in_what->stride, bestsad);
           CHECK_BETTER
         }
       }
@@ -590,31 +579,30 @@
   // If the center point is still the best, just skip this and move to
   // the refinement step.
   if (best_init_s != -1) {
+    int best_site = -1;
     s = best_init_s;
-    best_site = -1;
+
     do {
       // No need to search all 6 points the 1st time if initial search was used
       if (!do_init_search || s != best_init_s) {
         if (check_bounds(x, br, bc, 1 << s)) {
           for (i = 0; i < num_candidates[s]; i++) {
-            this_mv.row = br + candidates[s][i].row;
-            this_mv.col = bc + candidates[s][i].col;
-            this_offset = base_offset + (this_mv.row * in_what_stride) +
-                                         this_mv.col;
-            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                               bestsad);
+            const MV this_mv = {br + candidates[s][i].row,
+                                bc + candidates[s][i].col};
+            thissad = vfp->sdf(what->buf, what->stride,
+                               get_buf_from_mv(in_what, &this_mv),
+                               in_what->stride, bestsad);
             CHECK_BETTER
           }
         } else {
           for (i = 0; i < num_candidates[s]; i++) {
-            this_mv.row = br + candidates[s][i].row;
-            this_mv.col = bc + candidates[s][i].col;
+            const MV this_mv = {br + candidates[s][i].row,
+                                bc + candidates[s][i].col};
             if (!is_mv_in(x, &this_mv))
               continue;
-            this_offset = base_offset + (this_mv.row * in_what_stride) +
-                                         this_mv.col;
-            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                               bestsad);
+            thissad = vfp->sdf(what->buf, what->stride,
+                               get_buf_from_mv(in_what, &this_mv),
+                               in_what->stride, bestsad);
             CHECK_BETTER
           }
         }
@@ -637,24 +625,22 @@
 
         if (check_bounds(x, br, bc, 1 << s)) {
           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
-            this_mv.row = br + candidates[s][next_chkpts_indices[i]].row;
-            this_mv.col = bc + candidates[s][next_chkpts_indices[i]].col;
-            this_offset = base_offset + (this_mv.row * (in_what_stride)) +
-                                         this_mv.col;
-            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                               bestsad);
+            const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
+                                bc + candidates[s][next_chkpts_indices[i]].col};
+            thissad = vfp->sdf(what->buf, what->stride,
+                               get_buf_from_mv(in_what, &this_mv),
+                               in_what->stride, bestsad);
             CHECK_BETTER
           }
         } else {
           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
-            this_mv.row = br + candidates[s][next_chkpts_indices[i]].row;
-            this_mv.col = bc + candidates[s][next_chkpts_indices[i]].col;
+            const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
+                                bc + candidates[s][next_chkpts_indices[i]].col};
             if (!is_mv_in(x, &this_mv))
               continue;
-            this_offset = base_offset + (this_mv.row * (in_what_stride)) +
-                                         this_mv.col;
-            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                               bestsad);
+            thissad = vfp->sdf(what->buf, what->stride,
+                               get_buf_from_mv(in_what, &this_mv),
+                               in_what->stride, bestsad);
             CHECK_BETTER
           }
         }
@@ -671,29 +657,28 @@
   // Check 4 1-away neighbors if do_refine is true.
   // For most well-designed schemes do_refine will not be necessary.
   if (do_refine) {
-    static const MV neighbors[4] = { {0, -1}, { -1, 0}, {1, 0}, {0, 1} };
+    static const MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}};
+
     for (j = 0; j < 16; j++) {
-      best_site = -1;
+      int best_site = -1;
       if (check_bounds(x, br, bc, 1)) {
         for (i = 0; i < 4; i++) {
-          this_mv.row = br + neighbors[i].row;
-          this_mv.col = bc + neighbors[i].col;
-          this_offset = base_offset + this_mv.row * in_what_stride +
-                            this_mv.col;
-          thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                             bestsad);
+          const MV this_mv = {br + neighbors[i].row,
+                              bc + neighbors[i].col};
+          thissad = vfp->sdf(what->buf, what->stride,
+                             get_buf_from_mv(in_what, &this_mv),
+                             in_what->stride, bestsad);
           CHECK_BETTER
         }
       } else {
         for (i = 0; i < 4; i++) {
-          this_mv.row = br + neighbors[i].row;
-          this_mv.col = bc + neighbors[i].col;
+          const MV this_mv = {br + neighbors[i].row,
+                              bc + neighbors[i].col};
           if (!is_mv_in(x, &this_mv))
             continue;
-          this_offset = base_offset + this_mv.row * in_what_stride +
-                            this_mv.col;
-          thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride,
-                             bestsad);
+          thissad = vfp->sdf(what->buf, what->stride,
+                             get_buf_from_mv(in_what, &this_mv),
+                             in_what->stride, bestsad);
           CHECK_BETTER
         }
       }
@@ -710,8 +695,6 @@
   best_mv->row = br;
   best_mv->col = bc;
 
-  this_mv.row = best_mv->row * 8;
-  this_mv.col = best_mv->col * 8;
   return bestsad;
 }
 
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index f8427cf..9ecab57 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1002,7 +1002,7 @@
   mvjointsadcost[0] = 600;
   mvjointsadcost[1] = 300;
   mvjointsadcost[2] = 300;
-  mvjointsadcost[0] = 300;
+  mvjointsadcost[3] = 300;
 }
 
 static void cal_nmvsadcosts(int *mvsadcost[2]) {
@@ -3198,8 +3198,6 @@
   }
 
   set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
-  xd->interp_kernel = vp9_get_interp_kernel(
-      DEFAULT_INTERP_FILTER == SWITCHABLE ? EIGHTTAP : DEFAULT_INTERP_FILTER);
 
   if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
     vp9_vaq_init();
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index ab26125..d9dbd53 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -232,6 +232,9 @@
   int lossless;
   AQ_MODE aq_mode;  // Adaptive Quantization mode
 
+  // Enable feature to reduce the frame quantization every x frames.
+  int frame_periodic_boost;
+
   // two pass datarate control
   int two_pass_vbrbias;        // two pass datarate control tweaks
   int two_pass_vbrmin_section;
@@ -385,7 +388,6 @@
 
   vp9_coeff_count coef_counts[TX_SIZES][PLANE_TYPES];
   vp9_coeff_probs_model frame_coef_probs[TX_SIZES][PLANE_TYPES];
-  vp9_coeff_stats frame_branch_ct[TX_SIZES][PLANE_TYPES];
 
   struct vpx_codec_pkt_list  *output_pkt_list;
 
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 099add7..f987de5 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -188,12 +188,11 @@
 
   struct macroblock_plane *const p = &x->plane[0];
   struct macroblockd_plane *const pd = &xd->plane[0];
-  const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
 
-  int var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
-                               pd->dst.buf, pd->dst.stride, &sse);
+  int var = cpi->fn_ptr[bsize].vf(p->src.buf, p->src.stride,
+                                  pd->dst.buf, pd->dst.stride, &sse);
 
-  vp9_model_rd_from_var_lapndz(sse + var, 1 << num_pels_log2_lookup[bs],
+  vp9_model_rd_from_var_lapndz(sse + var, 1 << num_pels_log2_lookup[bsize],
                                pd->dequant[1] >> 3, &rate, &dist);
   *out_rate_sum = rate;
   *out_dist_sum = dist << 3;
@@ -211,7 +210,6 @@
   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
   struct macroblock_plane *const p = &x->plane[0];
   struct macroblockd_plane *const pd = &xd->plane[0];
-  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
   MB_PREDICTION_MODE this_mode, best_mode = ZEROMV;
   MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
   int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
@@ -255,13 +253,12 @@
                         EIGHTTAP : cpi->common.interp_filter;
   mbmi->skip = 0;
   mbmi->segment_id = segment_id;
-  xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
 
   for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
     x->pred_mv_sad[ref_frame] = INT_MAX;
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       vp9_setup_buffer_inter(cpi, x, tile,
-                             ref_frame, block_size, mi_row, mi_col,
+                             ref_frame, bsize, mi_row, mi_col,
                              frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
     }
     frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 21f4230..eb4db1a 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -982,7 +982,7 @@
   if (cpi->sf.use_nonrd_pick_mode) {
     if (q == 0)
       q++;
-    if (cpi->sf.force_ref_frame == 1)
+    if (cpi->sf.force_frame_boost == 1)
       q -= cpi->sf.max_delta_qindex;
 
     if (q < *bottom_index)
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index d758d3b..a3e5132 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1559,6 +1559,8 @@
   int thisrate = 0, ref;
   const scan_order *so = &vp9_default_scan_orders[TX_4X4];
   const int is_compound = has_second_ref(&mi->mbmi);
+  const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
+
   for (ref = 0; ref < 1 + is_compound; ++ref) {
     const uint8_t *pre = &pd->pre[ref].buf[raster_block_offset(BLOCK_8X8, i,
                                                pd->pre[ref].stride)];
@@ -1566,7 +1568,7 @@
                               dst, pd->dst.stride,
                               &mi->bmi[i].as_mv[ref].as_mv,
                               &xd->block_refs[ref]->sf, width, height, ref,
-                              xd->interp_kernel, MV_PRECISION_Q3,
+                              kernel, MV_PRECISION_Q3,
                               mi_col * MI_SIZE + 4 * (i % 2),
                               mi_row * MI_SIZE + 4 * (i / 2));
   }
@@ -2544,6 +2546,7 @@
   int ite, ref;
   // Prediction buffer from second frame.
   uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
+  const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
 
   // Do joint motion search in compound mode to get more accurate mv.
   struct buf_2d backup_yv12[2][MAX_MB_PLANE];
@@ -2597,7 +2600,7 @@
                               &frame_mv[refs[!id]].as_mv,
                               &xd->block_refs[!id]->sf,
                               pw, ph, 0,
-                              xd->interp_kernel, MV_PRECISION_Q3,
+                              kernel, MV_PRECISION_Q3,
                               mi_col * MI_SIZE, mi_row * MI_SIZE);
 
     // Compound motion search on first ref frame.
@@ -2812,7 +2815,6 @@
         int j;
         int64_t rs_rd;
         mbmi->interp_filter = i;
-        xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
         rs = get_switchable_rate(x);
         rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
 
@@ -2883,7 +2885,6 @@
   // Set the appropriate filter
   mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
       cm->interp_filter : *best_filter;
-  xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
   rs = cm->interp_filter == SWITCHABLE ? get_switchable_rate(x) : 0;
 
   if (pred_exists) {
@@ -3394,7 +3395,6 @@
                                                           : cm->interp_filter;
     x->skip = 0;
     set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
-    xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
 
     // Select prediction reference frames.
     for (i = 0; i < MAX_MB_PLANE; i++) {
@@ -3938,7 +3938,6 @@
     // them for this frame.
     mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
                                                           : cm->interp_filter;
-    xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
 
     if (comp_pred) {
       if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
@@ -4061,7 +4060,6 @@
             int newbest, rs;
             int64_t rs_rd;
             mbmi->interp_filter = switchable_filter_index;
-            xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
             tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
                                                  &mbmi->ref_mvs[ref_frame][0],
                                                  second_ref,
@@ -4126,7 +4124,6 @@
 
       mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
                              tmp_best_filter : cm->interp_filter);
-      xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
       if (!pred_exists) {
         // Handles the special case when a filter that is not in the
         // switchable list (bilinear, 6-tap) is indicated at the frame level
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 6f1cdca..7b983f9 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -13,17 +13,32 @@
 #include "vp9/encoder/vp9_onyx_int.h"
 #include "vp9/encoder/vp9_speed_features.h"
 
-#define ALL_INTRA_MODES 0x3FF
-#define INTRA_DC_ONLY 0x01
-#define INTRA_DC_TM ((1 << TM_PRED) | (1 << DC_PRED))
-#define INTRA_DC_H_V ((1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED))
+#define ALL_INTRA_MODES ((1 << DC_PRED) | \
+                         (1 << V_PRED) | (1 << H_PRED) | \
+                         (1 << D45_PRED) | (1 << D135_PRED) | \
+                         (1 << D117_PRED) | (1 << D153_PRED) | \
+                         (1 << D207_PRED) | (1 << D63_PRED) | \
+                         (1 << TM_PRED))
+#define INTRA_DC_ONLY   (1 << DC_PRED)
+#define INTRA_DC_TM     ((1 << TM_PRED) | (1 << DC_PRED))
+#define INTRA_DC_H_V    ((1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED))
 #define INTRA_DC_TM_H_V (INTRA_DC_TM | (1 << V_PRED) | (1 << H_PRED))
 
 // Masks for partially or completely disabling split mode
-#define DISABLE_ALL_SPLIT         0x3F
-#define DISABLE_ALL_INTER_SPLIT   0x1F
-#define DISABLE_COMPOUND_SPLIT    0x18
-#define LAST_AND_INTRA_SPLIT_ONLY 0x1E
+#define DISABLE_ALL_INTER_SPLIT   ((1 << THR_COMP_GA) | \
+                                   (1 << THR_COMP_LA) | \
+                                   (1 << THR_ALTR) | \
+                                   (1 << THR_GOLD) | \
+                                   (1 << THR_LAST))
+
+#define DISABLE_ALL_SPLIT         ((1 << THR_INTRA) | DISABLE_ALL_INTER_SPLIT)
+
+#define DISABLE_COMPOUND_SPLIT    ((1 << THR_COMP_GA) | (1 << THR_COMP_LA))
+
+#define LAST_AND_INTRA_SPLIT_ONLY ((1 << THR_COMP_GA) | \
+                                   (1 << THR_COMP_LA) | \
+                                   (1 << THR_ALTR) | \
+                                   (1 << THR_GOLD))
 
 static void set_good_speed_feature(VP9_COMP *cpi,
                                    VP9_COMMON *cm,
@@ -244,10 +259,10 @@
     sf->min_partition_size = BLOCK_8X8;
     sf->partition_check =
         (cm->current_video_frame % sf->last_partitioning_redo_frequency == 1);
-    sf->force_ref_frame =
+    sf->force_frame_boost = cm->frame_type == KEY_FRAME ||
         (cm->current_video_frame %
             (sf->last_partitioning_redo_frequency << 1) == 1);
-    sf->max_delta_qindex = 15;
+    sf->max_delta_qindex = (cm->frame_type == KEY_FRAME) ? 20 : 15;
     sf->partition_search_type = REFERENCE_PARTITION;
     sf->use_nonrd_pick_mode = 1;
     sf->search_method = FAST_DIAMOND;
@@ -300,7 +315,7 @@
   sf->last_partitioning_redo_frequency = 4;
   sf->disable_split_mask = 0;
   sf->mode_search_skip_flags = 0;
-  sf->force_ref_frame = 0;
+  sf->force_frame_boost = 0;
   sf->max_delta_qindex = 0;
   sf->disable_split_var_thresh = 0;
   sf->disable_filter_search_var_thresh = 0;
@@ -368,4 +383,8 @@
 
   if (sf->disable_split_mask == DISABLE_ALL_SPLIT)
     sf->adaptive_pred_interp_filter = 0;
+
+  if (!cpi->oxcf.frame_periodic_boost) {
+    sf->max_delta_qindex = 0;
+  }
 }
diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h
index 27b11c8..8260439 100644
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -254,7 +254,7 @@
 
   // Use finer quantizer in every other few frames that run variable block
   // partition type search.
-  int force_ref_frame;
+  int force_frame_boost;
 
   // Maximally allowed base quantization index fluctuation.
   int max_delta_qindex;
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index f8a6415..0410273 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -41,7 +41,10 @@
                                             struct scale_factors *scale,
                                             int x, int y) {
   const int which_mv = 0;
-  MV mv = { mv_row, mv_col };
+  const MV mv = { mv_row, mv_col };
+  const InterpKernel *const kernel =
+    vp9_get_interp_kernel(xd->mi[0]->mbmi.interp_filter);
+
   enum mv_precision mv_precision_uv;
   int uv_stride;
   if (uv_block_size == 8) {
@@ -58,7 +61,7 @@
                             scale,
                             16, 16,
                             which_mv,
-                            xd->interp_kernel, MV_PRECISION_Q3, x, y);
+                            kernel, MV_PRECISION_Q3, x, y);
 
   vp9_build_inter_predictor(u_mb_ptr, uv_stride,
                             &pred[256], uv_block_size,
@@ -66,7 +69,7 @@
                             scale,
                             uv_block_size, uv_block_size,
                             which_mv,
-                            xd->interp_kernel, mv_precision_uv, x, y);
+                            kernel, mv_precision_uv, x, y);
 
   vp9_build_inter_predictor(v_mb_ptr, uv_stride,
                             &pred[512], uv_block_size,
@@ -74,7 +77,7 @@
                             scale,
                             uv_block_size, uv_block_size,
                             which_mv,
-                            xd->interp_kernel, mv_precision_uv, x, y);
+                            kernel, mv_precision_uv, x, y);
 }
 
 void vp9_temporal_filter_apply_c(uint8_t *frame1,
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index a9fd8c1..37a214e 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -37,6 +37,7 @@
   unsigned int                lossless;
   unsigned int                frame_parallel_decoding_mode;
   AQ_MODE                     aq_mode;
+  unsigned int                frame_periodic_boost;
 };
 
 struct extraconfig_map {
@@ -65,6 +66,7 @@
       0,                          // lossless
       0,                          // frame_parallel_decoding_mode
       NO_AQ,                      // aq_mode
+      0,                          // frame_periodic_delta_q
     }
   }
 };
@@ -150,7 +152,7 @@
   RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
   RANGE_CHECK_BOOL(extra_cfg, lossless);
   RANGE_CHECK(extra_cfg, aq_mode,           0, AQ_MODE_COUNT - 1);
-
+  RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1);
   RANGE_CHECK_HI(cfg, g_threads,          64);
   RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
   RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_Q);
@@ -360,6 +362,8 @@
 
   oxcf->aq_mode = extra_cfg->aq_mode;
 
+  oxcf->frame_periodic_boost =  extra_cfg->frame_periodic_boost;
+
   oxcf->ss_number_layers = cfg->ss_number_layers;
 
   if (oxcf->ss_number_layers > 1) {
@@ -484,6 +488,7 @@
     MAP(VP9E_SET_FRAME_PARALLEL_DECODING,
         extra_cfg.frame_parallel_decoding_mode);
     MAP(VP9E_SET_AQ_MODE,                 extra_cfg.aq_mode);
+    MAP(VP9E_SET_FRAME_PERIODIC_BOOST,   extra_cfg.frame_periodic_boost);
   }
 
   res = validate_config(ctx, &ctx->cfg, &extra_cfg);
@@ -1094,6 +1099,7 @@
   {VP9E_SET_LOSSLESS,                 set_param},
   {VP9E_SET_FRAME_PARALLEL_DECODING,  set_param},
   {VP9E_SET_AQ_MODE,                  set_param},
+  {VP9E_SET_FRAME_PERIODIC_BOOST,     set_param},
   {VP9_GET_REFERENCE,                 get_reference},
   {VP9E_SET_SVC,                      vp9e_set_svc},
   {VP9E_SET_SVC_PARAMETERS,           vp9e_set_svc_parameters},
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 271589c..3be9454 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -23,27 +23,10 @@
 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
 typedef vpx_codec_stream_info_t  vp9_stream_info_t;
 
-/* Structures for handling memory allocations */
-typedef enum {
-  VP9_SEG_ALG_PRIV = 256,
-  VP9_SEG_MAX
-} mem_seg_id_t;
-#define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0])))
-
-static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
-                             vpx_codec_flags_t flags);
-
-static const mem_req_t vp9_mem_req_segs[] = {
-  {VP9_SEG_ALG_PRIV, 0, 8, VPX_CODEC_MEM_ZERO, priv_sz},
-  {VP9_SEG_MAX, 0, 0, 0, NULL}
-};
-
 struct vpx_codec_alg_priv {
   vpx_codec_priv_t        base;
-  vpx_codec_mmap_t        mmaps[NELEMENTS(vp9_mem_req_segs) - 1];
   vpx_codec_dec_cfg_t     cfg;
   vp9_stream_info_t       si;
-  int                     defer_alloc;
   int                     decoder_init;
   struct VP9Decompressor *pbi;
   int                     postproc_cfg_set;
@@ -66,80 +49,38 @@
   vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
 };
 
-static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
-                             vpx_codec_flags_t flags) {
-  /* Although this declaration is constant, we can't use it in the requested
-   * segments list because we want to define the requested segments list
-   * before defining the private type (so that the number of memory maps is
-   * known)
-   */
-  (void)si;
-  return sizeof(vpx_codec_alg_priv_t);
-}
-
-static void vp9_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) {
-  int i;
-
-  ctx->priv = (vpx_codec_priv_t *)mmap->base;
-  ctx->priv->sz = sizeof(*ctx->priv);
-  ctx->priv->iface = ctx->iface;
-  ctx->priv->alg_priv = (struct vpx_codec_alg_priv *)mmap->base;
-
-  for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++)
-    ctx->priv->alg_priv->mmaps[i].id = vp9_mem_req_segs[i].id;
-
-  ctx->priv->alg_priv->mmaps[0] = *mmap;
-  ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
-  ctx->priv->init_flags = ctx->init_flags;
-
-  if (ctx->config.dec) {
-    /* Update the reference to the config structure to an internal copy. */
-    ctx->priv->alg_priv->cfg = *ctx->config.dec;
-    ctx->config.dec = &ctx->priv->alg_priv->cfg;
-  }
-}
-
-static void vp9_finalize_mmaps(vpx_codec_alg_priv_t *ctx) {
-  /* nothing to clean up */
-}
-
 static vpx_codec_err_t vp9_init(vpx_codec_ctx_t *ctx,
                                 vpx_codec_priv_enc_mr_cfg_t *data) {
-  vpx_codec_err_t res = VPX_CODEC_OK;
-
   // This function only allocates space for the vpx_codec_alg_priv_t
   // structure. More memory may be required at the time the stream
   // information becomes known.
   if (!ctx->priv) {
-    vpx_codec_mmap_t mmap;
+    void *base = vpx_memalign(32, sizeof(vpx_codec_alg_priv_t));
+    if (base == NULL)
+      return VPX_CODEC_MEM_ERROR;
 
-    mmap.id = vp9_mem_req_segs[0].id;
-    mmap.sz = sizeof(vpx_codec_alg_priv_t);
-    mmap.align = vp9_mem_req_segs[0].align;
-    mmap.flags = vp9_mem_req_segs[0].flags;
+    memset(base, 0, sizeof(vpx_codec_alg_priv_t));
+    ctx->priv = (vpx_codec_priv_t *)base;
+    ctx->priv->sz = sizeof(*ctx->priv);
+    ctx->priv->iface = ctx->iface;
+    ctx->priv->alg_priv = (vpx_codec_alg_priv_t *)base;
+    ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
+    ctx->priv->init_flags = ctx->init_flags;
 
-    res = vpx_mmap_alloc(&mmap);
-    if (!res) {
-      vp9_init_ctx(ctx, &mmap);
-
-      ctx->priv->alg_priv->defer_alloc = 1;
+    if (ctx->config.dec) {
+      // Update the reference to the config structure to an internal copy.
+      ctx->priv->alg_priv->cfg = *ctx->config.dec;
+      ctx->config.dec = &ctx->priv->alg_priv->cfg;
     }
   }
 
-  return res;
+  return VPX_CODEC_OK;
 }
 
 static vpx_codec_err_t vp9_destroy(vpx_codec_alg_priv_t *ctx) {
-  int i;
-
   if (ctx->pbi)
     vp9_remove_decompressor(ctx->pbi);
 
-  for (i = NELEMENTS(ctx->mmaps) - 1; i >= 0; i--) {
-    if (ctx->mmaps[i].dtor)
-      ctx->mmaps[i].dtor(&ctx->mmaps[i]);
-  }
-
   return VPX_CODEC_OK;
 }
 
@@ -231,94 +172,59 @@
 
   ctx->img_avail = 0;
 
-  /* Determine the stream parameters. Note that we rely on peek_si to
-   * validate that we have a buffer that does not wrap around the top
-   * of the heap.
-   */
+  // Determine the stream parameters. Note that we rely on peek_si to
+  // validate that we have a buffer that does not wrap around the top
+  // of the heap.
   if (!ctx->si.h)
     res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);
 
-
-  /* Perform deferred allocations, if required */
-  if (!res && ctx->defer_alloc) {
-    int i;
-
-    for (i = 1; !res && i < NELEMENTS(ctx->mmaps); i++) {
-      vpx_codec_dec_cfg_t cfg;
-
-      cfg.w = ctx->si.w;
-      cfg.h = ctx->si.h;
-      ctx->mmaps[i].id = vp9_mem_req_segs[i].id;
-      ctx->mmaps[i].sz = vp9_mem_req_segs[i].sz;
-      ctx->mmaps[i].align = vp9_mem_req_segs[i].align;
-      ctx->mmaps[i].flags = vp9_mem_req_segs[i].flags;
-
-      if (!ctx->mmaps[i].sz)
-        ctx->mmaps[i].sz = vp9_mem_req_segs[i].calc_sz(&cfg,
-                                                       ctx->base.init_flags);
-
-      res = vpx_mmap_alloc(&ctx->mmaps[i]);
-    }
-
-    if (!res)
-      vp9_finalize_mmaps(ctx);
-
-    ctx->defer_alloc = 0;
-  }
-
   /* Initialize the decoder instance on the first frame*/
   if (!res && !ctx->decoder_init) {
-    res = vpx_validate_mmaps(&ctx->si, ctx->mmaps,
-                             vp9_mem_req_segs, NELEMENTS(vp9_mem_req_segs),
-                             ctx->base.init_flags);
+    VP9D_CONFIG oxcf;
+    struct VP9Decompressor *optr;
 
-    if (!res) {
-      VP9D_CONFIG oxcf;
-      struct VP9Decompressor *optr;
+    vp9_initialize_dec();
 
-      vp9_initialize_dec();
+    oxcf.width = ctx->si.w;
+    oxcf.height = ctx->si.h;
+    oxcf.version = 9;
+    oxcf.max_threads = ctx->cfg.threads;
+    oxcf.inv_tile_order = ctx->invert_tile_order;
+    optr = vp9_create_decompressor(&oxcf);
 
-      oxcf.width = ctx->si.w;
-      oxcf.height = ctx->si.h;
-      oxcf.version = 9;
-      oxcf.max_threads = ctx->cfg.threads;
-      oxcf.inv_tile_order = ctx->invert_tile_order;
-      optr = vp9_create_decompressor(&oxcf);
+    // If postprocessing was enabled by the application and a
+    // configuration has not been provided, default it.
+    if (!ctx->postproc_cfg_set &&
+        (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
+      ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
+      ctx->postproc_cfg.deblocking_level = 4;
+      ctx->postproc_cfg.noise_level = 0;
+    }
 
-      // If postprocessing was enabled by the application and a
-      // configuration has not been provided, default it.
-      if (!ctx->postproc_cfg_set &&
-          (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
-        ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
-        ctx->postproc_cfg.deblocking_level = 4;
-        ctx->postproc_cfg.noise_level = 0;
-      }
+    if (!optr) {
+      res = VPX_CODEC_ERROR;
+    } else {
+      VP9D_COMP *const pbi = (VP9D_COMP*)optr;
+      VP9_COMMON *const cm = &pbi->common;
 
-      if (!optr) {
-        res = VPX_CODEC_ERROR;
+      // Set index to not initialized.
+      cm->new_fb_idx = -1;
+
+      if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
+        cm->get_fb_cb = ctx->get_ext_fb_cb;
+        cm->release_fb_cb = ctx->release_ext_fb_cb;
+        cm->cb_priv = ctx->ext_priv;
       } else {
-        VP9D_COMP *const pbi = (VP9D_COMP*)optr;
-        VP9_COMMON *const cm = &pbi->common;
+        cm->get_fb_cb = vp9_get_frame_buffer;
+        cm->release_fb_cb = vp9_release_frame_buffer;
 
-        // Set index to not initialized.
-        cm->new_fb_idx = -1;
-
-        if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
-          cm->get_fb_cb = ctx->get_ext_fb_cb;
-          cm->release_fb_cb = ctx->release_ext_fb_cb;
-          cm->cb_priv = ctx->ext_priv;
-        } else {
-          cm->get_fb_cb = vp9_get_frame_buffer;
-          cm->release_fb_cb = vp9_release_frame_buffer;
-
-          if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
-            vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
-                               "Failed to initialize internal frame buffers");
-          cm->cb_priv = &cm->int_frame_buffers;
-        }
-
-        ctx->pbi = optr;
+        if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
+          vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+                             "Failed to initialize internal frame buffers");
+        cm->cb_priv = &cm->int_frame_buffers;
       }
+
+      ctx->pbi = optr;
     }
 
     ctx->decoder_init = 1;
@@ -496,75 +402,6 @@
   return VPX_CODEC_ERROR;
 }
 
-static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx,
-                                        vpx_codec_mmap_t *mmap,
-                                        vpx_codec_iter_t *iter) {
-  vpx_codec_err_t res;
-  const mem_req_t *seg_iter = (const mem_req_t *)*iter;
-
-  /* Get address of next segment request */
-  do {
-    if (!seg_iter)
-      seg_iter = vp9_mem_req_segs;
-    else if (seg_iter->id != VP9_SEG_MAX)
-      seg_iter++;
-
-    *iter = (vpx_codec_iter_t)seg_iter;
-
-    if (seg_iter->id != VP9_SEG_MAX) {
-      mmap->id = seg_iter->id;
-      mmap->sz = seg_iter->sz;
-      mmap->align = seg_iter->align;
-      mmap->flags = seg_iter->flags;
-
-      if (!seg_iter->sz)
-        mmap->sz = seg_iter->calc_sz(ctx->config.dec, ctx->init_flags);
-
-      res = VPX_CODEC_OK;
-    } else {
-      res = VPX_CODEC_LIST_END;
-    }
-  } while (!mmap->sz && res != VPX_CODEC_LIST_END);
-
-  return res;
-}
-
-static vpx_codec_err_t vp9_xma_set_mmap(vpx_codec_ctx_t *ctx,
-                                        const vpx_codec_mmap_t  *mmap) {
-  vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
-  int i, done;
-
-  if (!ctx->priv) {
-    if (mmap->id == VP9_SEG_ALG_PRIV) {
-      if (!ctx->priv) {
-        vp9_init_ctx(ctx, mmap);
-        res = VPX_CODEC_OK;
-      }
-    }
-  }
-
-  done = 1;
-
-  if (!res && ctx->priv->alg_priv) {
-    for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++) {
-      if (ctx->priv->alg_priv->mmaps[i].id == mmap->id)
-        if (!ctx->priv->alg_priv->mmaps[i].base) {
-          ctx->priv->alg_priv->mmaps[i] = *mmap;
-          res = VPX_CODEC_OK;
-        }
-
-      done &= (ctx->priv->alg_priv->mmaps[i].base != NULL);
-    }
-  }
-
-  if (done && !res) {
-    vp9_finalize_mmaps(ctx->priv->alg_priv);
-    res = ctx->iface->init(ctx, NULL);
-  }
-
-  return res;
-}
-
 static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
                                      va_list args) {
   vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *);
@@ -735,8 +572,8 @@
   vp9_init,         /* vpx_codec_init_fn_t       init; */
   vp9_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
   ctf_maps,         /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
-  vp9_xma_get_mmap, /* vpx_codec_get_mmap_fn_t   get_mmap; */
-  vp9_xma_set_mmap, /* vpx_codec_set_mmap_fn_t   set_mmap; */
+  NOT_IMPLEMENTED,  /* vpx_codec_get_mmap_fn_t   get_mmap; */
+  NOT_IMPLEMENTED,  /* vpx_codec_set_mmap_fn_t   set_mmap; */
   { // NOLINT
     vp9_peek_si,      /* vpx_codec_peek_si_fn_t    peek_si; */
     vp9_get_si,       /* vpx_codec_get_si_fn_t     get_si; */
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index 0b637d4..8944a26 100644
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -192,6 +192,7 @@
   VP9E_SET_TILE_ROWS,
   VP9E_SET_FRAME_PARALLEL_DECODING,
   VP9E_SET_AQ_MODE,
+  VP9E_SET_FRAME_PERIODIC_BOOST,
 
   VP9E_SET_SVC,
   VP9E_SET_SVC_PARAMETERS,
@@ -364,6 +365,8 @@
 
 VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int)
 
+VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PERIODIC_BOOST, unsigned int)
+
 /*! @} - end defgroup vp8_encoder */
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/vpxenc.c b/vpxenc.c
index 19251dc..00d3e3e 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -400,13 +400,17 @@
     NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
 static const arg_def_t aq_mode = ARG_DEF(
     NULL, "aq-mode", 1,
-    "Adaptive q mode (0: off (by default), 1: variance 2: complexity)");
+    "Adaptive q mode (0: off (by default), 1: variance 2: complexity, "
+    "3: cyclic refresh)");
+static const arg_def_t frame_periodic_boost = ARG_DEF(
+    NULL, "frame_boost", 1,
+    "Enable frame periodic boost (0: off (by default), 1: on)");
 
 static const arg_def_t *vp9_args[] = {
   &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh,
   &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type,
   &tune_ssim, &cq_level, &max_intra_rate_pct, &lossless,
-  &frame_parallel_decoding, &aq_mode,
+  &frame_parallel_decoding, &aq_mode, &frame_periodic_boost,
   NULL
 };
 static const int vp9_arg_ctrl_map[] = {
@@ -416,6 +420,7 @@
   VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE,
   VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT,
   VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE,
+  VP9E_SET_FRAME_PERIODIC_BOOST,
   0
 };
 #endif