Merge m-c to fx-team, a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 05 Aug 2016 14:06:23 -0700
changeset 308499 ba6d10b9a178a5700620a48b77b152908d4f8781
parent 308498 f54fea6078ddf0023a4307a25264c6ece653e503 (current diff)
parent 308422 6b65dd49d4f045c0a9753ce60bdb4b7b4aaedcf8 (diff)
child 308500 1646172ac6e709f5abdecbd8edbb53a54392428a
push id80347
push userkwierso@gmail.com
push dateSun, 07 Aug 2016 07:17:22 +0000
treeherdermozilla-inbound@d42aacfe34af [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team, a=merge
.eslintignore
media/ffvpx/libavcodec/avdct.c
media/ffvpx/libavcodec/bsf.c
media/ffvpx/libavcodec/options_table.h
media/ffvpx/libavutil/opt.c
modules/libpref/init/all.js
testing/mozharness/test/helper_files/archives/archive.tar
testing/mozharness/test/helper_files/archives/archive.tar.bz2
testing/mozharness/test/helper_files/archives/archive.tar.gz
testing/mozharness/test/helper_files/archives/archive.zip
testing/mozharness/test/helper_files/archives/archive_invalid_filename.zip
testing/mozharness/test/helper_files/archives/reference/bin/script.sh
testing/mozharness/test/helper_files/archives/reference/lorem.txt
testing/mozharness/test/helper_files/create_archives.sh
testing/web-platform/meta/XMLHttpRequest/send-accept.htm.ini
testing/web-platform/meta/html/semantics/forms/textfieldselection/selection.html.ini
--- a/.eslintignore
+++ b/.eslintignore
@@ -121,19 +121,21 @@ devtools/server/actors/**
 !devtools/server/actors/webbrowser.js
 !devtools/server/actors/webextension.js
 !devtools/server/actors/styles.js
 !devtools/server/actors/string.js
 !devtools/server/actors/csscoverage.js
 devtools/server/performance/**
 devtools/server/tests/**
 devtools/shared/*.js
+!devtools/shared/async-utils.js
 !devtools/shared/css-lexer.js
 !devtools/shared/defer.js
 !devtools/shared/event-emitter.js
+!devtools/shared/indentation.js
 !devtools/shared/loader-plugin-raw.jsm
 !devtools/shared/task.js
 devtools/shared/*.jsm
 !devtools/shared/Loader.jsm
 devtools/shared/apps/**
 devtools/shared/client/**
 devtools/shared/discovery/**
 devtools/shared/gcli/**
--- a/accessible/tests/mochitest/jsat/test_content_text.html
+++ b/accessible/tests/mochitest/jsat/test_content_text.html
@@ -63,26 +63,26 @@
              { android_todo: true /* Bug 980512 */})],
 
           // Editable text tests.
           [ContentMessages.focusSelector('textarea'),
            new ExpectedAnnouncement('editing'),
            new ExpectedEditState({
             editing: true,
             multiline: true,
-            atStart: true,
-            atEnd: false
+            atStart: false,
+            atEnd: true
            }),
            new ExpectedCursorChange(
             ['Please refrain from Mayoneggs during this salmonella scare.',
              {string: 'textarea'}]),
-           new ExpectedTextSelectionChanged(0, 0)
+           new ExpectedTextSelectionChanged(59, 59)
           ],
           [ContentMessages.activateCurrent(10),
-           new ExpectedTextCaretChanged(0, 10),
+           new ExpectedTextCaretChanged(10, 59),
            new ExpectedEditState({ editing: true,
              multiline: true,
              atStart: false,
              atEnd: false }),
            new ExpectedTextSelectionChanged(10, 10)],
           [ContentMessages.activateCurrent(20),
            new ExpectedTextCaretChanged(10, 20),
            new ExpectedTextSelectionChanged(20, 20)
@@ -131,28 +131,30 @@
            new ExpectedClickAction(),
            new ExpectedAnnouncement('editing'),
            new ExpectedEditState({
             editing: true,
             multiline: false,
             atStart: true,
             atEnd: true
            }, { focused: 'input[type=text]' }),
+           new ExpectedTextSelectionChanged(0, 0),
            new ExpectedTextSelectionChanged(0, 0)
            ],
           [ContentMessages.simpleMovePrevious,
            new ExpectedCursorChange(
             ['So we don\'t get dessert?', {string: 'label'}]),
            new ExpectedAnnouncement('navigating'),
            new ExpectedEditState({
             editing: false,
             multiline: false,
             atStart: true,
             atEnd: false
-           }, { focused: 'html' })],
+           },{ focused: 'html' })
+         ],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(
             [{ string : 'entry' }],
             { focused: 'html'})],
           [ContentMessages.activateCurrent(0),
            new ExpectedClickAction(),
            new ExpectedAnnouncement('editing'),
            new ExpectedEditState({
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1345,18 +1345,27 @@ pref("media.gmp.trial-create.enabled", t
 
 #ifdef MOZ_ADOBE_EME
 pref("media.gmp-eme-adobe.visible", true);
 pref("media.gmp-eme-adobe.enabled", true);
 #endif
 
 #ifdef MOZ_WIDEVINE_EME
 pref("media.gmp-widevinecdm.visible", true);
+// On Linux Widevine is visible but disabled by default. This is because
+// enabling Widevine downloads a proprietary binary, which users on an open
+// source operating system didn't opt into. The first time a site using EME
+// is encountered, the user will be prompted to enable EME, whereupon the
+// EME plugin binary will be downloaded if permission is granted.
+#ifdef XP_LINUX
+pref("media.gmp-widevinecdm.enabled", false);
+#else
 pref("media.gmp-widevinecdm.enabled", true);
 #endif
+#endif
 
 // Play with different values of the decay time and get telemetry,
 // 0 means to randomize (and persist) the experiment value in users' profiles,
 // -1 means no experiment is run and we use the preferred value for frecency (6h)
 pref("browser.cache.frecency_experiment", 0);
 
 pref("browser.translation.detectLanguage", false);
 pref("browser.translation.neverForLanguages", "");
--- a/browser/config/mozconfigs/macosx-universal/common-opt
+++ b/browser/config/mozconfigs/macosx-universal/common-opt
@@ -13,15 +13,10 @@ ac_add_options --with-mozilla-api-keyfil
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
-# Enable Widevine CDMs on MacOSX in Mozilla builds.
-# Enabled here on the assumption that downstream vendors will not be using
-# these build configs.
-ac_add_options --enable-eme=widevine
-
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
--- a/browser/config/mozconfigs/win32/common-opt
+++ b/browser/config/mozconfigs/win32/common-opt
@@ -26,15 +26,17 @@ export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 . $topsrcdir/build/win32/mozconfig.vs-latest
 
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
-# Enable Adobe Primetime and Widevine CDMs on 32-bit Windows in Mozilla builds.
+# Enable Adobe Primetime CDM on 32-bit Windows in Mozilla builds.
 # Enabled here on the assumption that downstream vendors will not be using
 # these build configs.
-ac_add_options --enable-eme=adobe,widevine
+# Note: Widevine is automatically enabled by the build, and can be
+# disabled with -widevine.
+ac_add_options --enable-eme=+adobe
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
--- a/browser/config/mozconfigs/win64/common-opt
+++ b/browser/config/mozconfigs/win64/common-opt
@@ -24,15 +24,17 @@ export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 # Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
 ac_add_options --enable-warnings-as-errors
 
 . $topsrcdir/build/win64/mozconfig.vs-latest
 
-# Enable Adobe Primetime and Widevine CDMs on 64-bit Windows in Mozilla builds.
+# Enable Adobe Primetime CDM on 64-bit Windows in Mozilla builds.
 # Enabled here on the assumption that downstream vendors will not be using
 # these build configs.
-ac_add_options --enable-eme=adobe,widevine
+# Note: Widevine is automatically enabled by the build, and can be
+# disabled with -widevine.
+ac_add_options --enable-eme=+adobe
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
--- a/devtools/client/inspector/breadcrumbs.js
+++ b/devtools/client/inspector/breadcrumbs.js
@@ -17,20 +17,18 @@ const {waitForTick} = require("devtools/
 const ELLIPSIS = Services.prefs.getComplexValue(
     "intl.ellipsis",
     Ci.nsIPrefLocalizedString).data;
 const MAX_LABEL_LENGTH = 40;
 
 const NS_XHTML = "http://www.w3.org/1999/xhtml";
 const SCROLL_REPEAT_MS = 100;
 
-loader.lazyRequireGetter(this, "EventEmitter",
-                         "devtools/shared/event-emitter");
-loader.lazyRequireGetter(this, "KeyShortcuts",
-                         "devtools/client/shared/key-shortcuts", true);
+const EventEmitter = require("devtools/shared/event-emitter");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
 
 /**
  * Component to replicate functionality of XUL arrowscrollbox
  * for breadcrumbs
  *
  * @param {Window} win The window containing the breadcrumbs
  * @parem {DOMNode} container The element in which to put the scroll box
  */
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -22,24 +22,20 @@ const {OutputParser} = require("devtools
 const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 const {createChild} = require("devtools/client/inspector/shared/utils");
 const {gDevTools} = require("devtools/client/framework/devtools");
 /* eslint-disable mozilla/reject-some-requires */
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 /* eslint-enable mozilla/reject-some-requires */
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
-loader.lazyRequireGetter(this, "overlays",
-  "devtools/client/inspector/shared/style-inspector-overlays");
-loader.lazyRequireGetter(this, "StyleInspectorMenu",
-  "devtools/client/inspector/shared/style-inspector-menu");
-loader.lazyRequireGetter(this, "KeyShortcuts",
-  "devtools/client/shared/key-shortcuts", true);
-loader.lazyRequireGetter(this, "LayoutView",
-  "devtools/client/inspector/layout/layout", true);
+const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
+const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
+const {LayoutView} = require("devtools/client/inspector/layout/layout");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyGetter(CssComputedView, "_strings", function () {
   return Services.strings.createBundle(
     "chrome://devtools-shared/locale/styleinspector.properties");
 });
--- a/devtools/client/inspector/inspector-commands.js
+++ b/devtools/client/inspector/inspector-commands.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const l10n = require("gcli/l10n");
-loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
+const {gDevTools} = require("devtools/client/framework/devtools");
 /* eslint-disable mozilla/reject-some-requires */
 const {EyeDropper, HighlighterEnvironment} = require("devtools/server/actors/highlighters");
 /* eslint-enable mozilla/reject-some-requires */
 const Telemetry = require("devtools/client/shared/telemetry");
 
 exports.items = [{
   item: "command",
   runAt: "client",
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -1,15 +1,13 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Experimenting with 100 char long lines */
-/* eslint max-len: [2, 100, 2, {ignoreUrls: true, "ignorePattern": "\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-"}] */ // eslint-disable-line
 
 "use strict";
 
 /* eslint-disable mozilla/reject-some-requires */
 const {Cc, Ci} = require("chrome");
 /* eslint-enable mozilla/reject-some-requires */
 
 var Services = require("Services");
@@ -22,27 +20,27 @@ var {KeyShortcuts} = require("devtools/c
 var {Task} = require("devtools/shared/task");
 const {initCssProperties} = require("devtools/shared/fronts/css-properties");
 const nodeConstants = require("devtools/shared/dom-node-constants");
 const Telemetry = require("devtools/client/shared/telemetry");
 
 const Menu = require("devtools/client/framework/menu");
 const MenuItem = require("devtools/client/framework/menu-item");
 
-loader.lazyRequireGetter(this, "CSS", "CSS");
+const CSS = require("CSS");
 
-loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
-loader.lazyRequireGetter(this, "ComputedViewTool", "devtools/client/inspector/computed/computed", true);
-loader.lazyRequireGetter(this, "FontInspector", "devtools/client/inspector/fonts/fonts", true);
-loader.lazyRequireGetter(this, "HTMLBreadcrumbs", "devtools/client/inspector/breadcrumbs", true);
-loader.lazyRequireGetter(this, "InspectorSearch", "devtools/client/inspector/inspector-search", true);
-loader.lazyRequireGetter(this, "MarkupView", "devtools/client/inspector/markup/markup", true);
-loader.lazyRequireGetter(this, "RuleViewTool", "devtools/client/inspector/rules/rules", true);
-loader.lazyRequireGetter(this, "ToolSidebar", "devtools/client/inspector/toolsidebar", true);
-loader.lazyRequireGetter(this, "ViewHelpers", "devtools/client/shared/widgets/view-helpers", true);
+const {CommandUtils} = require("devtools/client/shared/developer-toolbar");
+const {ComputedViewTool} = require("devtools/client/inspector/computed/computed");
+const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
+const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
+const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
+const {MarkupView} = require("devtools/client/inspector/markup/markup");
+const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
+const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
+const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
 
 loader.lazyGetter(this, "strings", () => {
   return Services.strings.createBundle("chrome://devtools/locale/inspector.properties");
 });
 loader.lazyGetter(this, "toolboxStrings", () => {
   return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
 });
 loader.lazyGetter(this, "clipboardHelper", () => {
@@ -211,17 +209,18 @@ InspectorPanel.prototype = {
     this.breadcrumbs = new HTMLBreadcrumbs(this);
 
     if (this.target.isLocalTab) {
       // Show a warning when the debugger is paused.
       // We show the warning only when the inspector
       // is selected.
       this.updateDebuggerPausedWarning = () => {
         let notificationBox = this._toolbox.getNotificationBox();
-        let notification = notificationBox.getNotificationWithValue("inspector-script-paused");
+        let notification =
+            notificationBox.getNotificationWithValue("inspector-script-paused");
         if (!notification && this._toolbox.currentToolId == "inspector" &&
             this._toolbox.threadClient.paused) {
           let message = strings.GetStringFromName("debuggerPausedWarning.message");
           notificationBox.appendNotification(message,
             "inspector-script-paused", "", notificationBox.PRIORITY_WARNING_HIGH);
         }
 
         if (notification && this._toolbox.currentToolId != "inspector") {
@@ -1512,29 +1511,33 @@ InspectorPanel.prototype = {
   copyImageDataUri: function () {
     let container = this.markup.getContainer(this.selection.nodeFront);
     if (container && container.isPreviewable()) {
       container.copyImageDataUri();
     }
   },
 
   /**
-   * Copy the content of a longString (via a promise resolving a LongStringActor) to the clipboard
-   * @param  {Promise} longStringActorPromise promise expected to resolve a LongStringActor instance
-   * @return {Promise} promise resolving (with no argument) when the string is sent to the clipboard
+   * Copy the content of a longString (via a promise resolving a
+   * LongStringActor) to the clipboard
+   * @param  {Promise} longStringActorPromise promise expected to
+   *         resolve a LongStringActor instance
+   * @return {Promise} promise resolving (with no argument) when the
+   *         string is sent to the clipboard
    */
   _copyLongString: function (longStringActorPromise) {
     return this._getLongString(longStringActorPromise).then(string => {
       clipboardHelper.copyString(string);
     }).catch(e => console.error(e));
   },
 
   /**
    * Retrieve the content of a longString (via a promise resolving a LongStringActor)
-   * @param  {Promise} longStringActorPromise promise expected to resolve a LongStringActor instance
+   * @param  {Promise} longStringActorPromise promise expected to
+   *         resolve a LongStringActor instance
    * @return {Promise} promise resolving with the retrieved string as argument
    */
   _getLongString: function (longStringActorPromise) {
     return longStringActorPromise.then(longStringActor => {
       return longStringActor.string().then(string => {
         longStringActor.release().catch(e => console.error(e));
         return string;
       });
--- a/devtools/client/inspector/inspector-search.js
+++ b/devtools/client/inspector/inspector-search.js
@@ -5,19 +5,19 @@
 "use strict";
 
 /* eslint-disable mozilla/reject-some-requires */
 const {Ci} = require("chrome");
 /* eslint-enable mozilla/reject-some-requires */
 const promise = require("promise");
 const {Task} = require("devtools/shared/task");
 
-loader.lazyGetter(this, "system", () => require("devtools/shared/system"));
-loader.lazyGetter(this, "EventEmitter", () => require("devtools/shared/event-emitter"));
-loader.lazyGetter(this, "AutocompletePopup", () => require("devtools/client/shared/autocomplete-popup").AutocompletePopup);
+const system = require("devtools/shared/system");
+const EventEmitter = require("devtools/shared/event-emitter");
+const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
 
 // Maximum number of selector suggestions shown in the panel.
 const MAX_SUGGESTIONS = 15;
 
 /**
  * Converts any input field into a document search box.
  *
  * @param {InspectorPanel} inspector The InspectorPanel whose `walker` attribute
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -56,20 +56,18 @@ const {KeyShortcuts} = require("devtools
 const {template} = require("devtools/shared/gcli/templater");
 const nodeConstants = require("devtools/shared/dom-node-constants");
 const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants");
 /* eslint-disable mozilla/reject-some-requires */
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 /* eslint-enable mozilla/reject-some-requires */
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
-loader.lazyRequireGetter(this, "CSS", "CSS");
-loader.lazyGetter(this, "AutocompletePopup", () => {
-  return require("devtools/client/shared/autocomplete-popup").AutocompletePopup;
-});
+const CSS = require("CSS");
+const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 
 /**
  * Vocabulary for the purposes of this file:
  *
  * MarkupContainer - the structure that holds an editor and its
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -24,38 +24,32 @@ const {OutputParser} = require("devtools
 const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 const {ElementStyle} = require("devtools/client/inspector/rules/models/element-style");
 const {Rule} = require("devtools/client/inspector/rules/models/rule");
 const {RuleEditor} = require("devtools/client/inspector/rules/views/rule-editor");
 const {createChild, promiseWarn, throttle} = require("devtools/client/inspector/shared/utils");
 const {gDevTools} = require("devtools/client/framework/devtools");
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
-loader.lazyRequireGetter(this, "overlays",
-  "devtools/client/inspector/shared/style-inspector-overlays");
-loader.lazyRequireGetter(this, "EventEmitter",
-  "devtools/shared/event-emitter");
-loader.lazyRequireGetter(this, "StyleInspectorMenu",
-  "devtools/client/inspector/shared/style-inspector-menu");
-loader.lazyRequireGetter(this, "KeyShortcuts",
-  "devtools/client/shared/key-shortcuts", true);
+const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
+const EventEmitter = require("devtools/shared/event-emitter");
+const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
 
 XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function () {
   return Cc["@mozilla.org/widget/clipboardhelper;1"]
     .getService(Ci.nsIClipboardHelper);
 });
 
 XPCOMUtils.defineLazyGetter(this, "_strings", function () {
   return Services.strings.createBundle(
     "chrome://devtools-shared/locale/styleinspector.properties");
 });
 
-loader.lazyGetter(this, "AutocompletePopup", function () {
-  return require("devtools/client/shared/autocomplete-popup").AutocompletePopup;
-});
+const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
 
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 const PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
 const PREF_DEFAULT_COLOR_UNIT = "devtools.defaultColorUnit";
 const PREF_ENABLE_MDN_DOCS_TOOLTIP =
       "devtools.inspector.mdnDocsTooltip.enabled";
 const FILTER_CHANGED_TIMEOUT = 150;
 
--- a/devtools/client/inspector/shared/style-inspector-menu.js
+++ b/devtools/client/inspector/shared/style-inspector-menu.js
@@ -9,18 +9,17 @@
 
 const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 const Services = require("Services");
 const {Task} = require("devtools/shared/task");
 
 const Menu = require("devtools/client/framework/menu");
 const MenuItem = require("devtools/client/framework/menu-item");
 
-loader.lazyRequireGetter(this, "overlays",
-  "devtools/client/inspector/shared/style-inspector-overlays");
+const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
 loader.lazyServiceGetter(this, "clipboardHelper",
   "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
 loader.lazyGetter(this, "_strings", () => {
   return Services.strings
   .createBundle("chrome://devtools-shared/locale/styleinspector.properties");
 });
 
 const PREF_ENABLE_MDN_DOCS_TOOLTIP =
--- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
@@ -9,34 +9,34 @@ function test() {
   initNetMonitor(CURL_URL).then(([aTab, aDebuggee, aMonitor]) => {
     info("Starting test... ");
 
     const EXPECTED_POSIX_RESULT = [
       "curl",
       "'" + SIMPLE_SJS + "'",
       "-H 'Host: example.com'",
       "-H 'User-Agent: " + navigator.userAgent + "'",
-      "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'",
+      "-H 'Accept: */*'",
       "-H 'Accept-Language: " + navigator.language + "'",
       "--compressed",
       "-H 'x-custom-header-1: Custom value'",
       "-H 'x-custom-header-2: 8.8.8.8'",
       "-H 'x-custom-header-3: Mon, 3 Mar 2014 11:11:11 GMT'",
       "-H 'Referer: " + CURL_URL + "'",
       "-H 'Connection: keep-alive'",
       "-H 'Pragma: no-cache'",
       "-H 'Cache-Control: no-cache'"
     ].join(" ");
 
     const EXPECTED_WIN_RESULT = [
       "curl",
       '"' + SIMPLE_SJS + '"',
       '-H "Host: example.com"',
       '-H "User-Agent: ' + navigator.userAgent + '"',
-      '-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"',
+      '-H "Accept: */*"',
       '-H "Accept-Language: ' + navigator.language + '"',
       "--compressed",
       '-H "x-custom-header-1: Custom value"',
       '-H "x-custom-header-2: 8.8.8.8"',
       '-H "x-custom-header-3: Mon, 3 Mar 2014 11:11:11 GMT"',
       '-H "Referer: ' + CURL_URL + '"',
       '-H "Connection: keep-alive"',
       '-H "Pragma: no-cache"',
--- a/devtools/shared/async-utils.js
+++ b/devtools/shared/async-utils.js
@@ -8,17 +8,16 @@
  * Helpers for async functions. Async functions are generator functions that are
  * run by Tasks. An async function returns a Promise for the resolution of the
  * function. When the function returns, the promise is resolved with the
  * returned value. If it throws the promise rejects with the thrown error.
  *
  * See Task documentation at https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Task.jsm.
  */
 
-var {Cu} = require("chrome");
 var {Task} = require("devtools/shared/task");
 var Promise = require("promise");
 
 /**
  * Create an async function that only executes once per instance of an object.
  * Once called on a given object, the same promise will be returned for any
  * future calls for that object.
  *
@@ -49,17 +48,17 @@ exports.asyncOnce = function asyncOnce(f
  * @param  Boolean useCapture
  *         Should we initiate the capture phase?
  * @return Promise
  *         The promise resolved with the event object when the event first
  *         happens
  */
 exports.listenOnce = function listenOnce(element, event, useCapture) {
   return new Promise(function (resolve, reject) {
-    var onEvent = function (ev) {
+    let onEvent = function (ev) {
       element.removeEventListener(event, onEvent, useCapture);
       resolve(ev);
     };
     element.addEventListener(event, onEvent, useCapture);
   });
 };
 
 /**
--- a/devtools/shared/indentation.js
+++ b/devtools/shared/indentation.js
@@ -1,17 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
 /* vim:set ts=2 sw=2 sts=2 et tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const { Cu } = require("chrome");
 const Services = require("Services");
 
 const EXPAND_TAB = "devtools.editor.expandtab";
 const TAB_SIZE = "devtools.editor.tabsize";
 const DETECT_INDENT = "devtools.editor.detectindentation";
 const DETECT_INDENT_MAX_LINES = 500;
 
 /**
--- a/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
+++ b/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js
@@ -114,17 +114,17 @@ function setPermissions() {
       sendAsyncMessage('test:InputMethod:oninput', {
         from: 'input',
         value: this.value
       });
     };
 
     input.onblur = function() {
       // "Expected" lost of focus since the test is finished.
-      if (input.value === '#0#1hello') {
+      if (input.value === 'hello#0#1') {
         return;
       }
 
       sendAsyncMessage('test:InputMethod:oninput', {
         from: 'input',
         error: true,
         value: 'Unexpected lost of focus on the input frame!'
       });
@@ -223,17 +223,17 @@ function next(msg) {
 
         case 'im1':
           is(false, 'Shouldn\'t be hearing anything from second frame.');
 
           break;
 
         case 'input':
           if (gFrameMsgCounts.input === 1) {
-            is(value, '#0hello',
+            is(value, 'hello#0',
               'Failed to get correct input from the first iframe.');
           } else {
             ok(false, 'Unexpected multiple messages from input.')
           }
 
           break;
       }
 
@@ -278,17 +278,17 @@ function next(msg) {
           } else {
             ok(false, 'Unexpected multiple messages from im0.')
           }
 
           break;
 
         case 'input':
           if (gFrameMsgCounts.input === 2) {
-            is(value, '#0#1hello',
+            is(value, 'hello#0#1',
                'Failed to get correct input from the second iframe.');
           } else {
             ok(false, 'Unexpected multiple messages from input.')
           }
           break;
       }
 
       if (gFrameMsgCounts.input !== 2 ||
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1680,17 +1680,21 @@ int32_t
 CanvasRenderingContext2D::GetHeight() const
 {
   return mHeight;
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
 {
-  ClearTarget();
+  bool retainBuffer = false;
+  if (aWidth == mWidth && aHeight == mHeight) {
+    retainBuffer = true;
+  }
+  ClearTarget(retainBuffer);
 
   // Zero sized surfaces can cause problems.
   mZero = false;
   if (aHeight == 0) {
     aHeight = 1;
     mZero = true;
   }
   if (aWidth == 0) {
@@ -1699,20 +1703,33 @@ CanvasRenderingContext2D::SetDimensions(
   }
   mWidth = aWidth;
   mHeight = aHeight;
 
   return NS_OK;
 }
 
 void
-CanvasRenderingContext2D::ClearTarget()
-{
+CanvasRenderingContext2D::ClearTarget(bool aRetainBuffer)
+{
+  RefPtr<PersistentBufferProvider> provider = mBufferProvider;
+  if (aRetainBuffer && provider) {
+    // We should reset the buffer data before reusing the buffer.
+    if (mTarget) {
+      mTarget->SetTransform(Matrix());
+    }
+    ClearRect(0, 0, mWidth, mHeight);
+  }
+
   Reset();
 
+  if (aRetainBuffer) {
+    mBufferProvider = provider;
+  }
+
   mResetLayer = true;
 
   // set up the initial canvas defaults
   mStyleStack.Clear();
   mPathBuilder = nullptr;
   mPath = nullptr;
   mDSPathBuilder = nullptr;
 
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -652,17 +652,17 @@ protected:
   /**
    * Cf. OnStableState.
    */
   void ScheduleStableStateCallback();
 
   /**
    * Disposes an old target and prepares to lazily create a new target.
    */
-  void ClearTarget();
+  void ClearTarget(bool aRetainBuffer = false);
 
   /*
    * Returns the target to the buffer provider. i.e. this will queue a frame for
    * rendering.
    */
   void ReturnTarget();
 
   /**
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -5652,18 +5652,18 @@ HTMLInputElement::SetRangeText(const nsA
     return;
   }
 
   int32_t start, end;
   aRv = GetSelectionRange(&start, &end);
   if (aRv.Failed()) {
     nsTextEditorState* state = GetEditorState();
     if (state && state->IsSelectionCached()) {
-      start = state->GetSelectionProperties().mStart;
-      end = state->GetSelectionProperties().mEnd;
+      start = state->GetSelectionProperties().GetStart();
+      end = state->GetSelectionProperties().GetEnd();
       aRv = NS_OK;
     }
   }
 
   SetRangeText(aReplacement, start, end, mozilla::dom::SelectionMode::Preserve,
                aRv, start, end);
 }
 
@@ -5695,18 +5695,18 @@ HTMLInputElement::SetRangeText(const nsA
     aEnd = inputValueLength;
   }
 
   if (aSelectionStart == -1 && aSelectionEnd == -1) {
     aRv = GetSelectionRange(&aSelectionStart, &aSelectionEnd);
     if (aRv.Failed()) {
       nsTextEditorState* state = GetEditorState();
       if (state && state->IsSelectionCached()) {
-        aSelectionStart = state->GetSelectionProperties().mStart;
-        aSelectionEnd = state->GetSelectionProperties().mEnd;
+        aSelectionStart = state->GetSelectionProperties().GetStart();
+        aSelectionEnd = state->GetSelectionProperties().GetEnd();
         aRv = NS_OK;
       }
     }
   }
 
   if (aStart <= aEnd) {
     value.Replace(aStart, aEnd - aStart, aReplacement);
     nsresult rv =
@@ -5765,17 +5765,17 @@ HTMLInputElement::GetSelectionStart(Erro
 {
   int32_t selEnd, selStart;
   aRv = GetSelectionRange(&selStart, &selEnd);
 
   if (aRv.Failed()) {
     nsTextEditorState* state = GetEditorState();
     if (state && state->IsSelectionCached()) {
       aRv = NS_OK;
-      return state->GetSelectionProperties().mStart;
+      return state->GetSelectionProperties().GetStart();
     }
   }
 
   return selStart;
 }
 
 NS_IMETHODIMP
 HTMLInputElement::GetSelectionStart(int32_t* aSelectionStart)
@@ -5787,17 +5787,17 @@ HTMLInputElement::GetSelectionStart(int3
   return rv.StealNSResult();
 }
 
 void
 HTMLInputElement::SetSelectionStart(int32_t aSelectionStart, ErrorResult& aRv)
 {
   nsTextEditorState* state = GetEditorState();
   if (state && state->IsSelectionCached()) {
-    state->GetSelectionProperties().mStart = aSelectionStart;
+    state->GetSelectionProperties().SetStart(aSelectionStart);
     return;
   }
 
   nsAutoString direction;
   aRv = GetSelectionDirection(direction);
   if (aRv.Failed()) {
     return;
   }
@@ -5829,17 +5829,17 @@ HTMLInputElement::GetSelectionEnd(ErrorR
 {
   int32_t selStart, selEnd;
   aRv = GetSelectionRange(&selStart, &selEnd);
 
   if (aRv.Failed()) {
     nsTextEditorState* state = GetEditorState();
     if (state && state->IsSelectionCached()) {
       aRv = NS_OK;
-      return state->GetSelectionProperties().mEnd;
+      return state->GetSelectionProperties().GetEnd();
     }
   }
 
   return selEnd;
 }
 
 NS_IMETHODIMP
 HTMLInputElement::GetSelectionEnd(int32_t* aSelectionEnd)
@@ -5851,17 +5851,17 @@ HTMLInputElement::GetSelectionEnd(int32_
   return rv.StealNSResult();
 }
 
 void
 HTMLInputElement::SetSelectionEnd(int32_t aSelectionEnd, ErrorResult& aRv)
 {
   nsTextEditorState* state = GetEditorState();
   if (state && state->IsSelectionCached()) {
-    state->GetSelectionProperties().mEnd = aSelectionEnd;
+    state->GetSelectionProperties().SetEnd(aSelectionEnd);
     return;
   }
 
   nsAutoString direction;
   aRv = GetSelectionDirection(direction);
   if (aRv.Failed()) {
     return;
   }
@@ -5935,17 +5935,17 @@ HTMLInputElement::GetSelectionDirection(
     if (NS_SUCCEEDED(rv)) {
       DirectionToName(dir, aDirection);
     }
   }
 
   if (NS_FAILED(rv)) {
     nsTextEditorState* state = GetEditorState();
     if (state && state->IsSelectionCached()) {
-      DirectionToName(state->GetSelectionProperties().mDirection, aDirection);
+      DirectionToName(state->GetSelectionProperties().GetDirection(), aDirection);
       return;
     }
   }
 
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
@@ -5964,17 +5964,17 @@ HTMLInputElement::SetSelectionDirection(
   nsTextEditorState* state = GetEditorState();
   if (state && state->IsSelectionCached()) {
     nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eNone;
     if (aDirection.EqualsLiteral("forward")) {
       dir = nsITextControlFrame::eForward;
     } else if (aDirection.EqualsLiteral("backward")) {
       dir = nsITextControlFrame::eBackward;
     }
-    state->GetSelectionProperties().mDirection = dir;
+    state->GetSelectionProperties().SetDirection(dir);
     return;
   }
 
   int32_t start, end;
   aRv = GetSelectionRange(&start, &end);
   if (!aRv.Failed()) {
     aRv = SetSelectionRange(start, end, aDirection);
   }
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1207,17 +1207,17 @@ void HTMLMediaElement::SelectResource()
       NS_ASSERTION(!mIsLoadingFromSourceChildren,
         "Should think we're not loading from source children by default");
 
       RemoveMediaElementFromURITable();
       mLoadingSrc = uri;
       mMediaSource = mSrcMediaSource;
       UpdatePreloadAction();
       if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
-          !IsMediaStreamURI(mLoadingSrc)) {
+          !IsMediaStreamURI(mLoadingSrc) && !mMediaSource) {
         // preload:none media, suspend the load here before we make any
         // network requests.
         SuspendLoad();
         return;
       }
 
       rv = LoadResource();
       if (NS_SUCCEEDED(rv)) {
@@ -1362,17 +1362,17 @@ void HTMLMediaElement::LoadFromSourceChi
 
     RemoveMediaElementFromURITable();
     mLoadingSrc = uri;
     mMediaSource = childSrc->GetSrcMediaSource();
     NS_ASSERTION(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING,
                  "Network state should be loading");
 
     if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
-        !IsMediaStreamURI(mLoadingSrc)) {
+        !IsMediaStreamURI(mLoadingSrc) && !mMediaSource) {
       // preload:none media, suspend the load here before we make any
       // network requests.
       SuspendLoad();
       return;
     }
 
     if (NS_SUCCEEDED(LoadResource())) {
       return;
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -666,17 +666,17 @@ HTMLTextAreaElement::GetSelectionStart(i
 
 uint32_t
 HTMLTextAreaElement::GetSelectionStart(ErrorResult& aError)
 {
   int32_t selStart, selEnd;
   nsresult rv = GetSelectionRange(&selStart, &selEnd);
 
   if (NS_FAILED(rv) && mState.IsSelectionCached()) {
-    return mState.GetSelectionProperties().mStart;
+    return mState.GetSelectionProperties().GetStart();
   }
   if (NS_FAILED(rv)) {
     aError.Throw(rv);
   }
   return selStart;
 }
 
 NS_IMETHODIMP
@@ -686,17 +686,17 @@ HTMLTextAreaElement::SetSelectionStart(i
   SetSelectionStart(aSelectionStart, error);
   return error.StealNSResult();
 }
 
 void
 HTMLTextAreaElement::SetSelectionStart(uint32_t aSelectionStart, ErrorResult& aError)
 {
   if (mState.IsSelectionCached()) {
-    mState.GetSelectionProperties().mStart = aSelectionStart;
+    mState.GetSelectionProperties().SetStart(aSelectionStart);
     return;
   }
 
   nsAutoString direction;
   nsresult rv = GetSelectionDirection(direction);
   if (NS_FAILED(rv)) {
     aError.Throw(rv);
     return;
@@ -729,17 +729,17 @@ HTMLTextAreaElement::GetSelectionEnd(int
 
 uint32_t
 HTMLTextAreaElement::GetSelectionEnd(ErrorResult& aError)
 {
   int32_t selStart, selEnd;
   nsresult rv = GetSelectionRange(&selStart, &selEnd);
 
   if (NS_FAILED(rv) && mState.IsSelectionCached()) {
-    return mState.GetSelectionProperties().mEnd;
+    return mState.GetSelectionProperties().GetEnd();
   }
   if (NS_FAILED(rv)) {
     aError.Throw(rv);
   }
   return selEnd;
 }
 
 NS_IMETHODIMP
@@ -749,17 +749,17 @@ HTMLTextAreaElement::SetSelectionEnd(int
   SetSelectionEnd(aSelectionEnd, error);
   return error.StealNSResult();
 }
 
 void
 HTMLTextAreaElement::SetSelectionEnd(uint32_t aSelectionEnd, ErrorResult& aError)
 {
   if (mState.IsSelectionCached()) {
-    mState.GetSelectionProperties().mEnd = aSelectionEnd;
+    mState.GetSelectionProperties().SetEnd(aSelectionEnd);
     return;
   }
 
   nsAutoString direction;
   nsresult rv = GetSelectionDirection(direction);
   if (NS_FAILED(rv)) {
     aError.Throw(rv);
     return;
@@ -826,17 +826,17 @@ HTMLTextAreaElement::GetSelectionDirecti
     rv = textControlFrame->GetSelectionRange(nullptr, nullptr, &dir);
     if (NS_SUCCEEDED(rv)) {
       DirectionToName(dir, aDirection);
     }
   }
 
   if (NS_FAILED(rv)) {
     if (mState.IsSelectionCached()) {
-      DirectionToName(mState.GetSelectionProperties().mDirection, aDirection);
+      DirectionToName(mState.GetSelectionProperties().GetDirection(), aDirection);
       return;
     }
     aError.Throw(rv);
   }
 }
 
 NS_IMETHODIMP
 HTMLTextAreaElement::SetSelectionDirection(const nsAString& aDirection)
@@ -851,17 +851,17 @@ HTMLTextAreaElement::SetSelectionDirecti
 {
   if (mState.IsSelectionCached()) {
     nsITextControlFrame::SelectionDirection dir = nsITextControlFrame::eNone;
     if (aDirection.EqualsLiteral("forward")) {
       dir = nsITextControlFrame::eForward;
     } else if (aDirection.EqualsLiteral("backward")) {
       dir = nsITextControlFrame::eBackward;
     }
-    mState.GetSelectionProperties().mDirection = dir;
+    mState.GetSelectionProperties().SetDirection(dir);
     return;
   }
 
   int32_t start, end;
   nsresult rv = GetSelectionRange(&start, &end);
   if (NS_SUCCEEDED(rv)) {
     rv = SetSelectionRange(start, end, aDirection);
   }
@@ -918,18 +918,18 @@ HTMLTextAreaElement::SetSelectionRange(u
 void
 HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
                                   ErrorResult& aRv)
 {
   int32_t start, end;
   aRv = GetSelectionRange(&start, &end);
   if (aRv.Failed()) {
     if (mState.IsSelectionCached()) {
-      start = mState.GetSelectionProperties().mStart;
-      end = mState.GetSelectionProperties().mEnd;
+      start = mState.GetSelectionProperties().GetStart();
+      end = mState.GetSelectionProperties().GetEnd();
       aRv = NS_OK;
     }
   }
 
   SetRangeText(aReplacement, start, end, mozilla::dom::SelectionMode::Preserve,
                aRv, start, end);
 }
 
@@ -956,18 +956,18 @@ HTMLTextAreaElement::SetRangeText(const 
   if (aEnd > inputValueLength) {
     aEnd = inputValueLength;
   }
 
   if (aSelectionStart == -1 && aSelectionEnd == -1) {
     aRv = GetSelectionRange(&aSelectionStart, &aSelectionEnd);
     if (aRv.Failed()) {
       if (mState.IsSelectionCached()) {
-        aSelectionStart = mState.GetSelectionProperties().mStart;
-        aSelectionEnd = mState.GetSelectionProperties().mEnd;
+        aSelectionStart = mState.GetSelectionProperties().GetStart();
+        aSelectionEnd = mState.GetSelectionProperties().GetEnd();
         aRv = NS_OK;
       }
     }
   }
 
   if (aStart <= aEnd) {
     value.Replace(aStart, aEnd - aStart, aReplacement);
     nsresult rv =
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -98,21 +98,23 @@ public:
 
     AutoHideSelectionChanges hideSelectionChanges
       (mFrame->GetConstFrameSelection());
 
     if (mFrame) {
       // SetSelectionRange leads to Selection::AddRange which flushes Layout -
       // need to block script to avoid nested PrepareEditor calls (bug 642800).
       nsAutoScriptBlocker scriptBlocker;
-       nsTextEditorState::SelectionProperties& properties =
-         mTextEditorState->GetSelectionProperties();
-       mFrame->SetSelectionRange(properties.mStart,
-                                 properties.mEnd,
-                                 properties.mDirection);
+      nsTextEditorState::SelectionProperties& properties =
+        mTextEditorState->GetSelectionProperties();
+      if (properties.IsDirty()) {
+        mFrame->SetSelectionRange(properties.GetStart(),
+                                  properties.GetEnd(),
+                                  properties.GetDirection());
+      }
       if (!mTextEditorState->mSelectionRestoreEagerInit) {
         mTextEditorState->HideSelectionIfBlurred();
       }
       mTextEditorState->mSelectionRestoreEagerInit = false;
     }
 
     if (mTextEditorState) {
       mTextEditorState->FinishedRestoringSelection();
@@ -1604,30 +1606,36 @@ nsTextEditorState::UnbindFromFrame(nsTex
   }
 
   // Save our selection state if needed.
   // Note that nsTextControlFrame::GetSelectionRange attempts to initialize the
   // editor before grabbing the range, and because this is not an acceptable
   // side effect for unbinding from a text control frame, we need to call
   // GetSelectionRange before calling DestroyEditor, and only if
   // mEditorInitialized indicates that we actually have an editor available.
+  int32_t start = 0, end = 0;
+  nsITextControlFrame::SelectionDirection direction =
+    nsITextControlFrame::eForward;
   if (mEditorInitialized) {
     HTMLInputElement* number = GetParentNumberControl(aFrame);
     if (number) {
       // If we are inside a number control, cache the selection on the
       // parent control, because this text editor state will be destroyed
       // together with the native anonymous text control.
       SelectionProperties props;
-      mBoundFrame->GetSelectionRange(&props.mStart, &props.mEnd,
-                                     &props.mDirection);
+      mBoundFrame->GetSelectionRange(&start, &end, &direction);
+      props.SetStart(start);
+      props.SetEnd(end);
+      props.SetDirection(direction);
       number->SetSelectionProperties(props);
     } else {
-      mBoundFrame->GetSelectionRange(&mSelectionProperties.mStart,
-                                     &mSelectionProperties.mEnd,
-                                     &mSelectionProperties.mDirection);
+      mBoundFrame->GetSelectionRange(&start, &end, &direction);
+      mSelectionProperties.SetStart(start);
+      mSelectionProperties.SetEnd(end);
+      mSelectionProperties.SetDirection(direction);
       mSelectionCached = true;
     }
   }
 
   // Destroy our editor
   DestroyEditor();
 
   // Clean up the controller
--- a/dom/html/nsTextEditorState.h
+++ b/dom/html/nsTextEditorState.h
@@ -193,38 +193,74 @@ public:
     return mTextCtrlElement->GetRows();
   }
 
   // placeholder methods
   void UpdatePlaceholderVisibility(bool aNotify);
   bool GetPlaceholderVisibility() {
     return mPlaceholderVisibility;
   }
-  void UpdatePlaceholderText(bool aNotify); 
+  void UpdatePlaceholderText(bool aNotify);
 
   /**
    * Get the maxlength attribute
    * @param aMaxLength the value of the max length attr
    * @returns false if attr not defined
    */
   bool GetMaxLength(int32_t* aMaxLength);
 
   void ClearValueCache() { mCachedValue.Truncate(); }
 
   void HideSelectionIfBlurred();
 
   struct SelectionProperties {
-    SelectionProperties() : mStart(0), mEnd(0),
-      mDirection(nsITextControlFrame::eForward) {}
-    bool IsDefault() const {
-      return mStart == 0 && mEnd == 0 &&
-             mDirection == nsITextControlFrame::eForward;
-    }
-    int32_t mStart, mEnd;
-    nsITextControlFrame::SelectionDirection mDirection;
+    public:
+      SelectionProperties() : mStart(0), mEnd(0),
+        mDirection(nsITextControlFrame::eForward) {}
+      bool IsDefault() const
+      {
+        return mStart == 0 && mEnd == 0 &&
+               mDirection == nsITextControlFrame::eForward;
+      }
+      int32_t GetStart() const
+      {
+        return mStart;
+      }
+      void SetStart(int32_t value)
+      {
+        mIsDirty = true;
+        mStart = value;
+      }
+      int32_t GetEnd() const
+      {
+        return mEnd;
+      }
+      void SetEnd(int32_t value)
+      {
+        mIsDirty = true;
+        mEnd = value;
+      }
+      nsITextControlFrame::SelectionDirection GetDirection() const
+      {
+        return mDirection;
+      }
+      void SetDirection(nsITextControlFrame::SelectionDirection value)
+      {
+        mIsDirty = true;
+        mDirection = value;
+      }
+      // return true only if mStart, mEnd, or mDirection have been modified
+      bool IsDirty() const
+      {
+        return mIsDirty;
+      }
+    private:
+      int32_t mStart, mEnd;
+      bool mIsDirty = false;
+      nsITextControlFrame::SelectionDirection mDirection;
   };
 
   bool IsSelectionCached() const;
   SelectionProperties& GetSelectionProperties();
   void WillInitEagerly() { mSelectionRestoreEagerInit = true; }
   bool HasNeverInitializedBefore() const { return !mEverInited; }
 
   void UpdateEditableState(bool aNotify) {
--- a/dom/html/test/test_bug332246.html
+++ b/dom/html/test/test_bug332246.html
@@ -32,40 +32,44 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 332246 **/
 
+function isWithFuzz(itIs, itShouldBe, fuzz, description) {
+  ok(Math.abs(itIs - itShouldBe) <= fuzz, `${description} - expected a value between ${itShouldBe - fuzz} and ${itShouldBe + fuzz}, got ${itIs}`);
+}
+
 var a1 = document.getElementById('a1');
 var a2 = document.getElementById('a2');
-is(a1.scrollHeight, 400, "Wrong a1.scrollHeight");
+isWithFuzz(a1.scrollHeight, 400, 1, "Wrong a1.scrollHeight");
 is(a1.offsetHeight, 100, "Wrong a1.offsetHeight");
 a2.scrollIntoView(true);
 is(a1.scrollTop, 100, "Wrong scrollTop value after a2.scrollIntoView(true)");
 a2.scrollIntoView(false);
 is(a1.scrollTop, 200, "Wrong scrollTop value after a2.scrollIntoView(false)");
 
 var b1 = document.getElementById('b1');
 var b2 = document.getElementById('b2');
-is(b1.scrollHeight, 420, "Wrong b1.scrollHeight");
+isWithFuzz(b1.scrollHeight, 420, 1, "Wrong b1.scrollHeight");
 is(b1.offsetHeight, 100, "Wrong b1.offsetHeight");
 b2.scrollIntoView(true);
 is(b1.scrollTop, 100, "Wrong scrollTop value after b2.scrollIntoView(true)");
 b2.scrollIntoView(false);
 is(b1.scrollTop, 220, "Wrong scrollTop value after b2.scrollIntoView(false)");
 
 var c1 = document.getElementById('c1');
 var c2 = document.getElementById('c2');
-is(c1.scrollHeight, 320, "Wrong c1.scrollHeight");
+isWithFuzz(c1.scrollHeight, 320, 1, "Wrong c1.scrollHeight");
 is(c1.offsetHeight, 100, "Wrong c1.offsetHeight");
 c2.scrollIntoView(true);
 is(c1.scrollTop, 100, "Wrong scrollTop value after c2.scrollIntoView(true)");
 c2.scrollIntoView(false);
-is(c1.scrollTop, 220, "Wrong scrollTop value after c2.scrollIntoView(false)");
+isWithFuzz(c1.scrollTop, 220, 1, "Wrong scrollTop value after c2.scrollIntoView(false)");
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/html/test/test_bug674558.html
+++ b/dom/html/test/test_bug674558.html
@@ -46,18 +46,18 @@ function startTest() {
 }
 
 function test(ctor) {
   var elem = ctor();
   ok(true, "Testing " + name(elem));
 
   ok("selectionDirection" in elem, "elem should have the selectionDirection property");
 
-  is(elem.selectionStart, 0, "Default value");
-  is(elem.selectionEnd, 0, "Default value");
+  is(elem.selectionStart, elem.value.length, "Default value");
+  is(elem.selectionEnd, elem.value.length, "Default value");
   is(elem.selectionDirection, "forward", "Default value");
 
   var content = document.getElementById("content");
   content.appendChild(elem);
 
   function flush() { document.body.clientWidth; }
   function hide() {
     content.style.display = "none";
@@ -65,18 +65,18 @@ function test(ctor) {
   }
   function show() {
     content.style.display = "";
     flush();
   }
 
   elem.value = "foobar";
 
-  is(elem.selectionStart, 0, "Default value");
-  is(elem.selectionEnd, 0, "Default value");
+  is(elem.selectionStart, elem.value.length, "Default value");
+  is(elem.selectionEnd, elem.value.length, "Default value");
   is(elem.selectionDirection, "forward", "Default value");
 
   elem.setSelectionRange(1, 3);
   is(elem.selectionStart, 1, "Correct value");
   is(elem.selectionEnd, 3, "Correct value");
   is(elem.selectionDirection, "forward", "If not set, should default to forward");
 
   hide();
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -141,23 +141,26 @@ NS_IMPL_ISUPPORTS(MediaMemoryTracker, ns
 NS_IMPL_ISUPPORTS0(MediaDecoder)
 
 
 void
 MediaDecoder::ResourceCallback::Connect(MediaDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mDecoder = aDecoder;
+  mTimer = do_CreateInstance("@mozilla.org/timer;1");
 }
 
 void
 MediaDecoder::ResourceCallback::Disconnect()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mDecoder = nullptr;
+  mTimer->Cancel();
+  mTimer = nullptr;
 }
 
 MediaDecoderOwner*
 MediaDecoder::ResourceCallback::GetMediaOwner() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   return mDecoder ? mDecoder->GetOwner() : nullptr;
 }
@@ -212,23 +215,40 @@ MediaDecoder::ResourceCallback::NotifyDe
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
     if (self->mDecoder) {
       self->mDecoder->DecodeError();
     }
   });
   AbstractThread::MainThread()->Dispatch(r.forget());
 }
 
+/* static */ void
+MediaDecoder::ResourceCallback::TimerCallback(nsITimer* aTimer, void* aClosure)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  ResourceCallback* thiz = static_cast<ResourceCallback*>(aClosure);
+  MOZ_ASSERT(thiz->mDecoder);
+  thiz->mDecoder->NotifyDataArrived();
+  thiz->mTimerArmed = false;
+}
+
 void
 MediaDecoder::ResourceCallback::NotifyDataArrived()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (mDecoder) {
-    mDecoder->NotifyDataArrived();
+  if (!mDecoder || mTimerArmed) {
+    return;
   }
+  // In situations where these notifications come from stochastic network
+  // activity, we can save significant computation by throttling the
+  // calls to MediaDecoder::NotifyDataArrived() which will update the buffer
+  // ranges of the reader.
+  mTimerArmed = true;
+  mTimer->InitWithFuncCallback(
+    TimerCallback, this, sDelay, nsITimer::TYPE_ONE_SHOT);
 }
 
 void
 MediaDecoder::ResourceCallback::NotifyBytesDownloaded()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mDecoder) {
     mDecoder->NotifyBytesDownloaded();
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -65,16 +65,20 @@ public:
       : mAtEnd(aAtEnd), mEventVisibility(aEventVisibility) {}
     bool mAtEnd;
     MediaDecoderEventVisibility mEventVisibility;
   };
 
   // Used to register with MediaResource to receive notifications which will
   // be forwarded to MediaDecoder.
   class ResourceCallback : public MediaResourceCallback {
+    // Throttle calls to MediaDecoder::NotifyDataArrived()
+    // to be at most once per 500ms.
+    static const uint32_t sDelay = 500;
+
   public:
     // Start to receive notifications from ResourceCallback.
     void Connect(MediaDecoder* aDecoder);
     // Called upon shutdown to stop receiving notifications.
     void Disconnect();
 
   private:
     /* MediaResourceCallback functions */
@@ -87,18 +91,22 @@ public:
     void NotifyDecodeError() override;
     void NotifyDataArrived() override;
     void NotifyBytesDownloaded() override;
     void NotifyDataEnded(nsresult aStatus) override;
     void NotifyPrincipalChanged() override;
     void NotifySuspendedStatusChanged() override;
     void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) override;
 
+    static void TimerCallback(nsITimer* aTimer, void* aClosure);
+
     // The decoder to send notifications. Main-thread only.
     MediaDecoder* mDecoder = nullptr;
+    nsCOMPtr<nsITimer> mTimer;
+    bool mTimerArmed = false;
   };
 
   typedef MozPromise<SeekResolveValue, bool /* aIgnored */, /* IsExclusive = */ true> SeekPromise;
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   // Enumeration for the valid play states (see mPlayState)
   enum PlayState {
--- a/dom/presentation/PresentationRequest.cpp
+++ b/dom/presentation/PresentationRequest.cpp
@@ -7,18 +7,21 @@
 #include "PresentationRequest.h"
 
 #include "ControllerConnectionCollection.h"
 #include "mozilla/dom/PresentationRequestBinding.h"
 #include "mozilla/dom/PresentationConnectionAvailableEvent.h"
 #include "mozilla/dom/Promise.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsCycleCollectionParticipant.h"
+#include "nsIDocument.h"
 #include "nsIPresentationService.h"
+#include "nsIURI.h"
 #include "nsIUUIDGenerator.h"
+#include "nsNetUtil.h"
 #include "nsSandboxFlags.h"
 #include "nsServiceManagerUtils.h"
 #include "PresentationAvailability.h"
 #include "PresentationCallbacks.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -26,16 +29,41 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(Prese
                                    mAvailability)
 
 NS_IMPL_ADDREF_INHERITED(PresentationRequest, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(PresentationRequest, DOMEventTargetHelper)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PresentationRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
+static nsresult
+GetAbsoluteURL(const nsAString& aUrl,
+               nsIURI* aBaseUri,
+               nsIDocument* aDocument,
+               nsAString& aAbsoluteUrl)
+{
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_NewURI(getter_AddRefs(uri),
+                          aUrl,
+                          aDocument ? aDocument->GetDocumentCharacterSet().get()
+                                    : nullptr,
+                          aBaseUri);
+
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  nsAutoCString spec;
+  uri->GetSpec(spec);
+
+  aAbsoluteUrl = NS_ConvertUTF8toUTF16(spec);
+
+  return NS_OK;
+}
+
 /* static */ already_AddRefed<PresentationRequest>
 PresentationRequest::Constructor(const GlobalObject& aGlobal,
                                  const nsAString& aUrl,
                                  ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
@@ -43,17 +71,28 @@ PresentationRequest::Constructor(const G
   }
 
   // Ensure the URL is not empty.
   if (NS_WARN_IF(aUrl.IsEmpty())) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return nullptr;
   }
 
-  RefPtr<PresentationRequest> request = new PresentationRequest(window, aUrl);
+  // Resolve relative URL to absolute URL
+  nsCOMPtr<nsIURI> baseUri = window->GetDocBaseURI();
+
+  nsAutoString absoluteUrl;
+  nsresult rv = GetAbsoluteURL(aUrl, baseUri, window->GetExtantDoc(), absoluteUrl);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return nullptr;
+  }
+
+  RefPtr<PresentationRequest> request =
+    new PresentationRequest(window, absoluteUrl);
   return NS_WARN_IF(!request->Init()) ? nullptr : request.forget();
 }
 
 PresentationRequest::PresentationRequest(nsPIDOMWindowInner* aWindow,
                                          const nsAString& aUrl)
   : DOMEventTargetHelper(aWindow)
   , mUrl(aUrl)
 {
--- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.html
+++ b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.html
@@ -103,17 +103,17 @@ function setup() {
   });
 
   return Promise.resolve();
 }
 
 function testCreateRequest() {
   return new Promise(function(aResolve, aReject) {
     info('Sender: --- testCreateRequest ---');
-    request = new PresentationRequest(receiverUrl);
+    request = new PresentationRequest("file_presentation_1ua_receiver.html");
     request.getAvailability().then((aAvailability) => {
       aAvailability.onchange = function() {
         aAvailability.onchange = null;
         ok(aAvailability.value, "Sender: Device should be available.");
         aResolve();
       }
     }).catch((aError) => {
       ok(false, "Sender: Error occurred when getting availability: " + aError);
@@ -127,16 +127,17 @@ function testCreateRequest() {
 
 function testStartConnection() {
   return new Promise(function(aResolve, aReject) {
     request.start().then((aConnection) => {
       connection = aConnection;
       ok(connection, "Sender: Connection should be available.");
       ok(connection.id, "Sender: Connection ID should be set.");
       is(connection.state, "connecting", "The initial state should be connecting.");
+      is(connection.url, receiverUrl, "request URL should be expanded to absolute URL");
       connection.onconnect = function() {
         connection.onconnect = null;
         is(connection.state, "connected", "Connection should be connected.");
         presentationId = connection.id;
         aResolve();
       };
     }).catch((aError) => {
       ok(false, "Sender: Error occurred when establishing a connection: " + aError);
--- a/dom/presentation/tests/mochitest/test_presentation_dc_sender.html
+++ b/dom/presentation/tests/mochitest/test_presentation_dc_sender.html
@@ -17,17 +17,17 @@
 
 var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
 var frameScript = SpecialPowers.isMainProcess() ? gScript : contentScript;
 var request;
 var connection;
 
 function testSetup() {
   return new Promise(function(aResolve, aReject) {
-    request = new PresentationRequest("http://example.com");
+    request = new PresentationRequest("http://example.com/");
 
     request.getAvailability().then(
       function(aAvailability) {
         aAvailability.onchange = function() {
           aAvailability.onchange = null;
           ok(aAvailability.value, "Device should be available.");
           aResolve();
         }
@@ -179,17 +179,17 @@ function testReconnect() {
     info('--- testReconnect ---');
     gScript.addMessageListener('control-channel-established', function controlChannelEstablished() {
       gScript.removeMessageListener('control-channel-established', controlChannelEstablished);
       gScript.sendAsyncMessage("trigger-control-channel-open");
     });
 
     gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) {
       gScript.removeMessageListener('start-reconnect', startReconnectHandler);
-      is(url, "http://example.com", "URLs should be the same.")
+      is(url, "http://example.com/", "URLs should be the same.")
       gScript.sendAsyncMessage('trigger-reconnected-acked', url);
     });
 
     gScript.addMessageListener('offer-sent', function offerSentHandler(aIsValid) {
       gScript.removeMessageListener('offer-sent', offerSentHandler);
       ok(aIsValid, "A valid offer is sent out.");
       gScript.sendAsyncMessage('trigger-incoming-answer');
     });
--- a/dom/presentation/tests/mochitest/test_presentation_reconnect.html
+++ b/dom/presentation/tests/mochitest/test_presentation_reconnect.html
@@ -39,17 +39,17 @@ function testSetup() {
           commandHandler[command.name](command);
         }
       } else if (/^DONE$/.exec(message)) {
         window.removeEventListener('message', listener);
         SimpleTest.finish();
       }
     }, false);
 
-    request = new PresentationRequest("http://example.com");
+    request = new PresentationRequest("http://example.com/");
 
     request.getAvailability().then(
       function(aAvailability) {
         aAvailability.onchange = function() {
           aAvailability.onchange = null;
           ok(aAvailability.value, "Device should be available.");
           aResolve();
         }
@@ -296,17 +296,17 @@ function testReconnectIframeClosedConnec
   });
 }
 
 function testReconnect() {
   return new Promise(function(aResolve, aReject) {
     info('--- testReconnect ---');
     gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) {
       gScript.removeMessageListener('start-reconnect', startReconnectHandler);
-      is(url, "http://example.com", "URLs should be the same.");
+      is(url, "http://example.com/", "URLs should be the same.");
       gScript.sendAsyncMessage('trigger-reconnected-acked', url);
     });
 
     request.reconnect(connection.id).then(
       function(aConnection) {
         ok(aConnection, "Connection should be available.");
         ok(aConnection.id, "Connection ID should be set.");
         is(aConnection.state, "connecting", "The initial state should be connecting.");
--- a/dom/presentation/tests/mochitest/test_presentation_tcp_sender.html
+++ b/dom/presentation/tests/mochitest/test_presentation_tcp_sender.html
@@ -15,17 +15,17 @@
 'use strict';
 
 var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
 var request;
 var connection;
 
 function testSetup() {
   return new Promise(function(aResolve, aReject) {
-    request = new PresentationRequest("http://example.com");
+    request = new PresentationRequest("http://example.com/");
 
     request.getAvailability().then(
       function(aAvailability) {
         aAvailability.onchange = function() {
           aAvailability.onchange = null;
           ok(aAvailability.value, "Device should be available.");
           aResolve();
         }
@@ -173,17 +173,17 @@ function testReconnect() {
     info('--- testReconnect ---');
     gScript.addMessageListener('control-channel-established', function controlChannelEstablished() {
       gScript.removeMessageListener('control-channel-established', controlChannelEstablished);
       gScript.sendAsyncMessage("trigger-control-channel-open");
     });
 
     gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) {
       gScript.removeMessageListener('start-reconnect', startReconnectHandler);
-      is(url, "http://example.com", "URLs should be the same.")
+      is(url, "http://example.com/", "URLs should be the same.")
       gScript.sendAsyncMessage('trigger-reconnected-acked', url);
     });
 
     gScript.addMessageListener('offer-sent', function offerSentHandler() {
       gScript.removeMessageListener('offer-sent', offerSentHandler);
       gScript.sendAsyncMessage('trigger-incoming-transport');
     });
 
--- a/dom/tests/mochitest/general/test_offsets.html
+++ b/dom/tests/mochitest/general/test_offsets.html
@@ -7,18 +7,22 @@
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
 
 <style>
   input {
     box-sizing: content-box;
   }
 </style>
 </head>
+
+<!-- We set a transform on the body element so that it creates a reference frame.
+     This makes sure that snapping of scrolled areas for the contained elements
+     is not influenced by offsets outside of this document. -->
 <body id="body" onload="setTimeout(testElements, 0, 'testelements', SimpleTest.finish);"
-      style="margin: 1px; border: 2px solid black; padding: 4px;">
+      style="margin: 1px; border: 2px solid black; padding: 4px; transform: translateY(1px);">
 
 <div id="testelements" style="margin: 0; border: 0; padding: 0;">
   <div id="div1" style="margin: 0; margin-left: 6px; margin-top: 2px; border: 1px solid green; padding: 6px; width: 50px; height: 20px"
          _offsetLeft="13" _offsetTop="9" _offsetWidth="64" _offsetHeight="34"
          _scrollWidth="62" _scrollHeight="32"
          _clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32"></div>
   <div id="noscroll" style="margin: 2px; border: 1px solid blue; padding: 3px;"
        _offsetLeft="10" _offsetTop="12" _offsetWidth="64" _offsetHeight="34"
@@ -50,17 +54,17 @@
   <div id="fixed" style="position: fixed; margin: 2px; border: 1px solid orange; padding: 7px; left: 87px; top: 12px;">
     This is some fixed positioned text.
     <div id="fixed-block" _offsetParent="fixed">
       <div id="fixed-replaced" _offsetParent="fixed" style="margin: 1px; border: 0; padding: 3px;"></div>
     </div>
   </div>
 
   <div id="scrollbox"
-       style="overflow: scroll; padding-left: 0px; margin: 3px; border: 4px solid green; max-width: 80px; max-height: 70px;"
+       style="overflow: scroll; padding-left: 0px; margin: 3px; border: 4px solid green; max-width: 80px; max-height: 70px"
        _scrollWidth="62" _scrollHeight="32"
        _clientLeft="1" _clientTop="1" _clientWidth="62" _clientHeight="32"><p id="p1" style="margin: 0; padding: 0;">One</p>
     <p id="p2">Two</p>
     <p id="scrollchild">Three</p>
     <p id="lastlinebox" style="margin: 0; padding: 0;"><input id="lastline" type="button"
                                style="margin: 0px; border: 2px solid red;"
                                value="This button is much longer than the others">
   </p></div>
--- a/dom/tests/mochitest/general/test_offsets.js
+++ b/dom/tests/mochitest/general/test_offsets.js
@@ -176,22 +176,35 @@ function checkClientState(element, left,
 }
 
 function checkCoord(element, type, val, testname)
 {
   if (val != -10000)
     is(element[type], Math.round(val), testname + " " + type);
 }
 
+function checkCoordFuzzy(element, type, val, fuzz, testname)
+{
+  if (val != -10000)
+    ok(Math.abs(element[type] - Math.round(val)) <= fuzz, testname + " " + type);
+}
+
 function checkCoords(element, type, left, top, width, height, testname)
 {
   checkCoord(element, type + "Left", left, testname);
   checkCoord(element, type + "Top", top, testname);
-  checkCoord(element, type + "Width", width, testname);
-  checkCoord(element, type + "Height", height, testname);
+
+  if (type == "scroll") {
+    // scrollWidth and scrollHeight can deviate by 1 pixel due to snapping.
+    checkCoordFuzzy(element, type + "Width", width, 1, testname);
+    checkCoordFuzzy(element, type + "Height", height, 1, testname);
+  } else {
+    checkCoord(element, type + "Width", width, testname);
+    checkCoord(element, type + "Height", height, testname);
+  }
 
   if (element instanceof SVGElement)
     return;
 
   if (element.id == "outerpopup" && !element.parentNode.open) // closed popup
     return;
 
   if (element.id == "div-displaynone" || element.id == "nonappended") // hidden elements
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2470,16 +2470,25 @@ XMLHttpRequestMainThread::SendInternal(c
 
     if (!IsSystemXHR()) {
       nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
       nsCOMPtr<nsIDocument> doc = owner ? owner->GetExtantDoc() : nullptr;
       nsContentUtils::SetFetchReferrerURIWithPolicy(mPrincipal, doc,
                                                     httpChannel, mozilla::net::RP_Default);
     }
 
+    // If the user hasn't overridden the Accept header, set it to */* as per spec
+    nsAutoCString acceptHeader;
+    GetAuthorRequestHeaderValue("accept", acceptHeader);
+    if (acceptHeader.IsVoid()) {
+      httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
+                                    NS_LITERAL_CSTRING("*/*"),
+                                    false);
+    }
+
     // Some extensions override the http protocol handler and provide their own
     // implementation. The channels returned from that implementation doesn't
     // seem to always implement the nsIUploadChannel2 interface, presumably
     // because it's a new interface.
     // Eventually we should remove this and simply require that http channels
     // implement the new interface.
     // See bug 529041
     nsCOMPtr<nsIUploadChannel2> uploadChannel2 =
@@ -3509,20 +3518,20 @@ XMLHttpRequestMainThread::EnsureXPCOMifi
 }
 
 bool
 XMLHttpRequestMainThread::ShouldBlockAuthPrompt()
 {
   // Verify that it's ok to prompt for credentials here, per spec
   // http://xhr.spec.whatwg.org/#the-send%28%29-method
 
-  for (RequestHeader& requestHeader : mAuthorRequestHeaders) {
-    if (requestHeader.name.EqualsLiteral("authorization")) {
-      return true;
-    }
+  nsAutoCString contentType;
+  GetAuthorRequestHeaderValue("authorization", contentType);
+  if (!contentType.IsVoid()) {
+    return true;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
 
--- a/gfx/src/nsRect.cpp
+++ b/gfx/src/nsRect.cpp
@@ -1,30 +1,44 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsRect.h"
 #include "mozilla/gfx/Types.h"          // for NS_SIDE_BOTTOM, etc
+#include "mozilla/CheckedInt.h"         // for CheckedInt
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsString.h"               // for nsAutoString, etc
 #include "nsMargin.h"                   // for nsMargin
 
 static_assert((int(NS_SIDE_TOP) == 0) &&
               (int(NS_SIDE_RIGHT) == 1) &&
               (int(NS_SIDE_BOTTOM) == 2) &&
               (int(NS_SIDE_LEFT) == 3),
               "The mozilla::css::Side sequence must match the nsMargin nscoord sequence");
 
 const mozilla::gfx::IntRect& GetMaxSizedIntRect() {
   static const mozilla::gfx::IntRect r(0, 0, INT32_MAX, INT32_MAX);
   return r;
 }
 
+
+bool nsRect::Overflows() const {
+#ifdef NS_COORD_IS_FLOAT
+  return false;
+#else
+  mozilla::CheckedInt<int32_t> xMost = this->x;
+  xMost += this->width;
+  mozilla::CheckedInt<int32_t> yMost = this->y;
+  yMost += this->height;
+  return !xMost.isValid() || !yMost.isValid();
+#endif
+}
+
 #ifdef DEBUG
 // Diagnostics
 
 FILE* operator<<(FILE* out, const nsRect& rect)
 {
   nsAutoString tmp;
 
   // Output the coordinates in fractional pixels so they're easier to read
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -124,16 +124,19 @@ struct nsRect :
   {
     *this = aRect1.SaturatingUnion(aRect2);
   }
   void SaturatingUnionRectEdges(const nsRect& aRect1, const nsRect& aRect2)
   {
     *this = aRect1.SaturatingUnionEdges(aRect2);
   }
 
+  // Return whether this rect's right or bottom edge overflow int32.
+  bool Overflows() const;
+
   /**
    * Return this rect scaled to a different appunits per pixel (APP) ratio.
    * In the RoundOut version we make the rect the smallest rect containing the
    * unrounded result. In the RoundIn version we make the rect the largest rect
    * contained in the unrounded result.
    * @param aFromAPP the APP to scale from
    * @param aToAPP the APP to scale to
    * @note this can turn an empty rectangle into a non-empty rectangle
--- a/gfx/ycbcr/YCbCrUtils.cpp
+++ b/gfx/ycbcr/YCbCrUtils.cpp
@@ -113,17 +113,16 @@ ConvertYCbCrToRGB(const layers::PlanarYC
                         aData.mPicSize.width,
                         aData.mPicSize.height,
                         aDestSize.width,
                         aDestSize.height,
                         aData.mYStride,
                         aData.mCbCrStride,
                         aStride,
                         yuvtype,
-                        ROTATE_0,
                         FILTER_BILINEAR);
   } else { // no prescale
 #if defined(HAVE_YCBCR_TO_RGB565)
     if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
       ConvertYCbCrToRGB565(aData.mYChannel,
                            aData.mCbChannel,
                            aData.mCrChannel,
                            aDestBuffer,
--- a/gfx/ycbcr/moz.build
+++ b/gfx/ycbcr/moz.build
@@ -4,16 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'YCbCrUtils.h',
 ]
 
 UNIFIED_SOURCES += [
+    'scale_yuv_argb.cpp',
     'ycbcr_to_rgb565.cpp',
     'YCbCrUtils.cpp',
     'yuv_convert.cpp',
     'yuv_row_c.cpp',
     'yuv_row_table.cpp',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/scale_yuv_argb.cpp
@@ -0,0 +1,1105 @@
+/*
+ *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
+ *  Copyright 2016 Mozilla Foundation
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS. All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "libyuv/scale.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "libyuv/cpu_id.h"
+#include "libyuv/row.h"
+#include "libyuv/scale_row.h"
+#include "libyuv/video_common.h"
+
+#ifdef __cplusplus
+namespace libyuv {
+extern "C" {
+#endif
+
+// YUV to RGB conversion and scaling functions were implemented by referencing
+// scale_argb.cc
+//
+// libyuv already has ScaleYUVToARGBBilinearUp(), but its implementation is not
+// completed yet. Implementations of the functions are based on it.
+// At first, ScaleYUVToARGBBilinearUp() was implemented by modidying the
+// libyuv's one. Then all another functions were implemented similarly.
+//
+// Function relationship between yuv_convert.cpp abd scale_argb.cc are like
+// the followings
+//  - ScaleYUVToARGBDown2()      <-- ScaleARGBDown2()
+//  - ScaleYUVToARGBDownEven()   <-- ScaleARGBDownEven()
+//  - ScaleYUVToARGBBilinearDown() <-- ScaleARGBBilinearDown()
+//  - ScaleYUVToARGBBilinearUp() <-- ScaleARGBBilinearUp() and ScaleYUVToARGBBilinearUp() in libyuv
+//  - ScaleYUVToARGBSimple()     <-- ScaleARGBSimple()
+//  - ScaleYUVToARGB()           <-- ScaleARGB() // Removed some function calls for simplicity.
+//  - YUVToARGBScale()           <-- ARGBScale()
+//
+// Callings and selections of InterpolateRow() and ScaleARGBFilterCols() were
+// kept as same as possible.
+//
+// The followings changes were done to each scaling functions.
+//
+// -[1] Allocate YUV conversion buffer and use it as source buffer of scaling.
+//      Its usage is borrowed from the libyuv's ScaleYUVToARGBBilinearUp().
+// -[2] Conversion from YUV to RGB was abstracted as YUVBuferIter.
+//      It is for handling multiple yuv color formats.
+// -[3] Modified scaling functions as to handle YUV conversion buffer and
+//      use YUVBuferIter.
+// -[4] Color conversion function selections in YUVBuferIter were borrowed from
+//      I444ToARGBMatrix(), I422ToARGBMatrix() and I420ToARGBMatrix() 
+
+static __inline int Abs(int v) {
+  return v >= 0 ? v : -v;
+}
+
+struct YUVBuferIter {
+  int src_width;
+  int src_height;
+  int src_stride_y;
+  int src_stride_u;
+  int src_stride_v;
+  const uint8* src_y;
+  const uint8* src_u;
+  const uint8* src_v;
+
+  uint32 src_fourcc;
+  int y_index;
+  const uint8* src_row_y;
+  const uint8* src_row_u;
+  const uint8* src_row_v;
+
+  void (*YUVToARGBRow)(const uint8* y_buf,
+                       const uint8* u_buf,
+                       const uint8* v_buf,
+                       uint8* rgb_buf,
+                       const struct YuvConstants* yuvconstants,
+                       int width);
+  void (*MoveTo)(YUVBuferIter& iter, int y_index);
+  void (*MoveToNextRow)(YUVBuferIter& iter);
+};
+
+void YUVBuferIter_InitI422(YUVBuferIter& iter) {
+  iter.YUVToARGBRow = I422ToARGBRow_C;
+#if defined(HAS_I422TOARGBROW_SSSE3)
+  if (TestCpuFlag(kCpuHasSSSE3)) {
+    iter.YUVToARGBRow = I422ToARGBRow_Any_SSSE3;
+    if (IS_ALIGNED(iter.src_width, 8)) {
+      iter.YUVToARGBRow = I422ToARGBRow_SSSE3;
+    }
+  }
+#endif
+#if defined(HAS_I422TOARGBROW_AVX2)
+  if (TestCpuFlag(kCpuHasAVX2)) {
+    iter.YUVToARGBRow = I422ToARGBRow_Any_AVX2;
+    if (IS_ALIGNED(iter.src_width, 16)) {
+      iter.YUVToARGBRow = I422ToARGBRow_AVX2;
+    }
+  }
+#endif
+#if defined(HAS_I422TOARGBROW_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    iter.YUVToARGBRow = I422ToARGBRow_Any_NEON;
+    if (IS_ALIGNED(iter.src_width, 8)) {
+      iter.YUVToARGBRow = I422ToARGBRow_NEON;
+    }
+  }
+#endif
+#if defined(HAS_I422TOARGBROW_DSPR2)
+  if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(iter.src_width, 4) &&
+      IS_ALIGNED(iter.src_y, 4) && IS_ALIGNED(iter.src_stride_y, 4) &&
+      IS_ALIGNED(iter.src_u, 2) && IS_ALIGNED(iter.src_stride_u, 2) &&
+      IS_ALIGNED(iter.src_v, 2) && IS_ALIGNED(iter.src_stride_v, 2) {
+    // Always satisfy IS_ALIGNED(argb_cnv_row, 4) && IS_ALIGNED(argb_cnv_rowstride, 4)
+    iter.YUVToARGBRow = I422ToARGBRow_DSPR2;
+  }
+#endif
+}
+
+void YUVBuferIter_InitI444(YUVBuferIter& iter) {
+  iter.YUVToARGBRow = I444ToARGBRow_C;
+#if defined(HAS_I444TOARGBROW_SSSE3)
+  if (TestCpuFlag(kCpuHasSSSE3)) {
+    iter.YUVToARGBRow = I444ToARGBRow_Any_SSSE3;
+    if (IS_ALIGNED(iter.src_width, 8)) {
+      iter.YUVToARGBRow = I444ToARGBRow_SSSE3;
+    }
+  }
+#endif
+#if defined(HAS_I444TOARGBROW_AVX2)
+  if (TestCpuFlag(kCpuHasAVX2)) {
+    iter.YUVToARGBRow = I444ToARGBRow_Any_AVX2;
+    if (IS_ALIGNED(iter.src_width, 16)) {
+      iter.YUVToARGBRow = I444ToARGBRow_AVX2;
+    }
+  }
+#endif
+#if defined(HAS_I444TOARGBROW_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    iter.YUVToARGBRow = I444ToARGBRow_Any_NEON;
+    if (IS_ALIGNED(iter.src_width, 8)) {
+      iter.YUVToARGBRow = I444ToARGBRow_NEON;
+    }
+  }
+#endif
+}
+
+
+static void YUVBuferIter_MoveToForI444(YUVBuferIter& iter, int y_index) {
+  iter.y_index = y_index;
+  iter.src_row_y = iter.src_y + y_index * iter.src_stride_y;
+  iter.src_row_u = iter.src_u + y_index * iter.src_stride_u;
+  iter.src_row_v = iter.src_v + y_index * iter.src_stride_v;
+}
+
+static void YUVBuferIter_MoveToNextRowForI444(YUVBuferIter& iter) {
+  iter.src_row_y += iter.src_stride_y;
+  iter.src_row_u += iter.src_stride_u;
+  iter.src_row_v += iter.src_stride_v;
+  iter.y_index++;
+}
+
+static void YUVBuferIter_MoveToForI422(YUVBuferIter& iter, int y_index) {
+  iter.y_index = y_index;
+  iter.src_row_y = iter.src_y + y_index * iter.src_stride_y;
+  iter.src_row_u = iter.src_u + y_index * iter.src_stride_u;
+  iter.src_row_v = iter.src_v + y_index * iter.src_stride_v;
+}
+
+static void YUVBuferIter_MoveToNextRowForI422(YUVBuferIter& iter) {
+  iter.src_row_y += iter.src_stride_y;
+  iter.src_row_u += iter.src_stride_u;
+  iter.src_row_v += iter.src_stride_v;
+  iter.y_index++;
+}
+
+static void YUVBuferIter_MoveToForI420(YUVBuferIter& iter, int y_index) {
+  const int kYShift = 1;  // Shift Y by 1 to convert Y plane to UV coordinate.
+  int uv_y_index = y_index >> kYShift;
+
+  iter.y_index = y_index;
+  iter.src_row_y = iter.src_y + y_index * iter.src_stride_y;
+  iter.src_row_u = iter.src_u + uv_y_index * iter.src_stride_u;
+  iter.src_row_v = iter.src_v + uv_y_index * iter.src_stride_v;
+}
+
+static void YUVBuferIter_MoveToNextRowForI420(YUVBuferIter& iter) {
+  iter.src_row_y += iter.src_stride_y;
+  if (iter.y_index & 1) {
+    iter.src_row_u += iter.src_stride_u;
+    iter.src_row_v += iter.src_stride_v;
+  }
+  iter.y_index++;
+}
+
+static __inline void YUVBuferIter_ConvertToARGBRow(YUVBuferIter& iter, uint8* argb_row) {
+  iter.YUVToARGBRow(iter.src_row_y, iter.src_row_u, iter.src_row_v, argb_row, &kYuvI601Constants, iter.src_width);
+}
+
+void YUVBuferIter_Init(YUVBuferIter& iter, uint32 src_fourcc) {
+  iter.src_fourcc = src_fourcc;
+  iter.y_index = 0;
+  iter.src_row_y = iter.src_y;
+  iter.src_row_u = iter.src_u;
+  iter.src_row_v = iter.src_v;
+
+  if (src_fourcc == FOURCC_I444) {
+    YUVBuferIter_InitI444(iter);
+    iter.MoveTo = YUVBuferIter_MoveToForI444;
+    iter.MoveToNextRow = YUVBuferIter_MoveToNextRowForI444;
+  } else if(src_fourcc == FOURCC_I422){
+    YUVBuferIter_InitI422(iter);
+    iter.MoveTo = YUVBuferIter_MoveToForI422;
+    iter.MoveToNextRow = YUVBuferIter_MoveToNextRowForI422;
+  } else {
+    assert(src_fourcc == FOURCC_I420); // Should be FOURCC_I420
+    YUVBuferIter_InitI422(iter);
+    iter.MoveTo = YUVBuferIter_MoveToForI420;
+    iter.MoveToNextRow = YUVBuferIter_MoveToNextRowForI420;
+  }
+}
+
+// ScaleARGB ARGB, 1/2
+// This is an optimized version for scaling down a ARGB to 1/2 of
+// its original size.
+static void ScaleYUVToARGBDown2(int src_width, int src_height,
+                                int dst_width, int dst_height,
+                                int src_stride_y,
+                                int src_stride_u,
+                                int src_stride_v,
+                                int dst_stride_argb,
+                                const uint8* src_y,
+                                const uint8* src_u,
+                                const uint8* src_v,
+                                uint8* dst_argb,
+                                int x, int dx, int y, int dy,
+                                enum FilterMode filtering,
+                                uint32 src_fourcc) {
+  int j;
+
+  // Allocate 2 rows of ARGB for source conversion.
+  const int kRowSize = (src_width * 4 + 15) & ~15;
+  align_buffer_64(argb_cnv_row, kRowSize * 2);
+  uint8* argb_cnv_rowptr = argb_cnv_row;
+  int argb_cnv_rowstride = kRowSize;
+
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+
+  void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride,
+                            uint8* dst_argb, int dst_width) =
+    filtering == kFilterNone ? ScaleARGBRowDown2_C :
+        (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_C :
+        ScaleARGBRowDown2Box_C);
+  assert(dx == 65536 * 2);  // Test scale factor of 2.
+  assert((dy & 0x1ffff) == 0);  // Test vertical scale is multiple of 2.
+  // Advance to odd row, even column.
+  int yi = y >> 16;
+  iter.MoveTo(iter, yi);
+  ptrdiff_t x_offset;
+  if (filtering == kFilterBilinear) {
+    x_offset = (x >> 16) * 4;
+  } else {
+    x_offset = ((x >> 16) - 1) * 4;
+  }
+#if defined(HAS_SCALEARGBROWDOWN2_SSE2)
+  if (TestCpuFlag(kCpuHasSSE2)) {
+    ScaleARGBRowDown2 = filtering == kFilterNone ? ScaleARGBRowDown2_Any_SSE2 :
+        (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_SSE2 :
+        ScaleARGBRowDown2Box_Any_SSE2);
+    if (IS_ALIGNED(dst_width, 4)) {
+      ScaleARGBRowDown2 = filtering == kFilterNone ? ScaleARGBRowDown2_SSE2 :
+          (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_SSE2 :
+          ScaleARGBRowDown2Box_SSE2);
+    }
+  }
+
+#endif
+#if defined(HAS_SCALEARGBROWDOWN2_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBRowDown2 = filtering == kFilterNone ? ScaleARGBRowDown2_Any_NEON :
+        (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_NEON :
+        ScaleARGBRowDown2Box_Any_NEON);
+    if (IS_ALIGNED(dst_width, 8)) {
+      ScaleARGBRowDown2 = filtering == kFilterNone ? ScaleARGBRowDown2_NEON :
+          (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_NEON :
+          ScaleARGBRowDown2Box_NEON);
+    }
+  }
+#endif
+
+  const int dyi = dy >> 16;
+  int lastyi = yi;
+  YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+  // Prepare next row if necessary
+  if (filtering != kFilterLinear) {
+    if ((yi + dyi) < (src_height - 1)) {
+      iter.MoveTo(iter, yi + dyi);
+      YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+    } else {
+      argb_cnv_rowstride = 0;
+    }
+  }
+
+  if (filtering == kFilterLinear) {
+    argb_cnv_rowstride = 0;
+  }
+  const int max_yi = src_height - 1;
+  const int max_yi_minus_dyi = max_yi - dyi;
+  for (j = 0; j < dst_height; ++j) {
+    if (yi != lastyi) {
+      if (yi > max_yi) {
+        yi = max_yi;
+      }
+      if (yi != lastyi) {
+        if (filtering == kFilterLinear) {
+          iter.MoveTo(iter, yi);
+          YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          lastyi = yi;
+        } else {
+          // Prepare current row
+          if (yi == iter.y_index) {
+            argb_cnv_rowptr = argb_cnv_rowptr + argb_cnv_rowstride;
+            argb_cnv_rowstride = - argb_cnv_rowstride;
+          } else {
+            iter.MoveTo(iter, yi);
+            argb_cnv_rowptr = argb_cnv_row;
+            argb_cnv_rowstride = kRowSize;
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          }
+          // Prepare next row if necessary
+          if (iter.y_index  < max_yi) {
+            int next_yi = yi < max_yi_minus_dyi ? yi + dyi : max_yi;
+            iter.MoveTo(iter, next_yi);
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+          } else {
+            argb_cnv_rowstride = 0;
+          }
+          lastyi = yi;
+        }
+      }
+    }
+    ScaleARGBRowDown2(argb_cnv_rowptr + x_offset, argb_cnv_rowstride, dst_argb, dst_width);
+    dst_argb += dst_stride_argb;
+    yi += dyi;
+  }
+
+  free_aligned_buffer_64(argb_cnv_row);
+}
+
+// ScaleARGB ARGB Even
+// This is an optimized version for scaling down a ARGB to even
+// multiple of its original size.
+static void ScaleYUVToARGBDownEven(int src_width, int src_height,
+                                   int dst_width, int dst_height,
+                                   int src_stride_y,
+                                   int src_stride_u,
+                                   int src_stride_v,
+                                   int dst_stride_argb,
+                                   const uint8* src_y,
+                                   const uint8* src_u,
+                                   const uint8* src_v,
+                                   uint8* dst_argb,
+                                   int x, int dx, int y, int dy,
+                                   enum FilterMode filtering,
+                                   uint32 src_fourcc) {
+  int j;
+  // Allocate 2 rows of ARGB for source conversion.
+  const int kRowSize = (src_width * 4 + 15) & ~15;
+  align_buffer_64(argb_cnv_row, kRowSize * 2);
+  uint8* argb_cnv_rowptr = argb_cnv_row;
+  int argb_cnv_rowstride = kRowSize;
+
+  int col_step = dx >> 16;
+  void (*ScaleARGBRowDownEven)(const uint8* src_argb, ptrdiff_t src_stride,
+                               int src_step, uint8* dst_argb, int dst_width) =
+      filtering ? ScaleARGBRowDownEvenBox_C : ScaleARGBRowDownEven_C;
+  assert(IS_ALIGNED(src_width, 2));
+  assert(IS_ALIGNED(src_height, 2));
+  int yi = y >> 16;
+  const ptrdiff_t x_offset = (x >> 16) * 4;
+
+#if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2)
+  if (TestCpuFlag(kCpuHasSSE2)) {
+    ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_SSE2 :
+        ScaleARGBRowDownEven_Any_SSE2;
+    if (IS_ALIGNED(dst_width, 4)) {
+      ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_SSE2 :
+          ScaleARGBRowDownEven_SSE2;
+    }
+  }
+#endif
+#if defined(HAS_SCALEARGBROWDOWNEVEN_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_NEON :
+        ScaleARGBRowDownEven_Any_NEON;
+    if (IS_ALIGNED(dst_width, 4)) {
+      ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_NEON :
+          ScaleARGBRowDownEven_NEON;
+    }
+  }
+#endif
+
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+
+  const int dyi = dy >> 16;
+  int lastyi = yi;
+  YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+  // Prepare next row if necessary
+  if (filtering != kFilterLinear) {
+    if ((yi + dyi) < (src_height - 1)) {
+      iter.MoveTo(iter, yi + dyi);
+      YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+    } else {
+      argb_cnv_rowstride = 0;
+    }
+  }
+
+  if (filtering == kFilterLinear) {
+    argb_cnv_rowstride = 0;
+  }
+  const int max_yi = src_height - 1;
+  const int max_yi_minus_dyi = max_yi - dyi;
+  for (j = 0; j < dst_height; ++j) {
+    if (yi != lastyi) {
+      if (yi > max_yi) {
+        yi = max_yi;
+      }
+      if (yi != lastyi) {
+        if (filtering == kFilterLinear) {
+          iter.MoveTo(iter, yi);
+          YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          lastyi = yi;
+        } else {
+          // Prepare current row
+          if (yi == iter.y_index) {
+            argb_cnv_rowptr = argb_cnv_rowptr + argb_cnv_rowstride;
+            argb_cnv_rowstride = - argb_cnv_rowstride;
+          } else {
+            iter.MoveTo(iter, yi);
+            argb_cnv_rowptr = argb_cnv_row;
+            argb_cnv_rowstride = kRowSize;
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          }
+          // Prepare next row if necessary
+          if (iter.y_index  < max_yi) {
+            int next_yi = yi < max_yi_minus_dyi ? yi + dyi : max_yi;
+            iter.MoveTo(iter, next_yi);
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+          } else {
+            argb_cnv_rowstride = 0;
+          }
+          lastyi = yi;
+        }
+      }
+    }
+    ScaleARGBRowDownEven(argb_cnv_rowptr + x_offset, argb_cnv_rowstride, col_step, dst_argb, dst_width);
+    dst_argb += dst_stride_argb;
+    yi += dyi;
+  }
+  free_aligned_buffer_64(argb_cnv_row);
+}
+
+// Scale YUV to ARGB down with bilinear interpolation.
+static void ScaleYUVToARGBBilinearDown(int src_width, int src_height,
+                                       int dst_width, int dst_height,
+                                       int src_stride_y,
+                                       int src_stride_u,
+                                       int src_stride_v,
+                                       int dst_stride_argb,
+                                       const uint8* src_y,
+                                       const uint8* src_u,
+                                       const uint8* src_v,
+                                       uint8* dst_argb,
+                                       int x, int dx, int y, int dy,
+                                       enum FilterMode filtering,
+                                       uint32 src_fourcc) {
+  int j;
+  void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
+      ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
+      InterpolateRow_C;
+  void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb,
+      int dst_width, int x, int dx) =
+      (src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C;
+  int64 xlast = x + (int64)(dst_width - 1) * dx;
+  int64 xl = (dx >= 0) ? x : xlast;
+  int64 xr = (dx >= 0) ? xlast : x;
+  int clip_src_width;
+  xl = (xl >> 16) & ~3;  // Left edge aligned.
+  xr = (xr >> 16) + 1;  // Right most pixel used.  Bilinear uses 2 pixels.
+  xr = (xr + 1 + 3) & ~3;  // 1 beyond 4 pixel aligned right most pixel.
+  if (xr > src_width) {
+    xr = src_width;
+  }
+  clip_src_width = (int)(xr - xl) * 4;  // Width aligned to 4.
+  const ptrdiff_t xl_offset = xl * 4;
+  x -= (int)(xl << 16);
+
+  // Allocate 2 row of ARGB for source conversion.
+  const int kRowSize = (src_width * 4 + 15) & ~15;
+  align_buffer_64(argb_cnv_row, kRowSize * 2);
+  uint8* argb_cnv_rowptr = argb_cnv_row; 
+  int argb_cnv_rowstride = kRowSize;
+
+#if defined(HAS_INTERPOLATEROW_SSSE3)
+  if (TestCpuFlag(kCpuHasSSSE3)) {
+    InterpolateRow = InterpolateRow_Any_SSSE3;
+    if (IS_ALIGNED(clip_src_width, 16)) {
+      InterpolateRow = InterpolateRow_SSSE3;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_AVX2)
+  if (TestCpuFlag(kCpuHasAVX2)) {
+    InterpolateRow = InterpolateRow_Any_AVX2;
+    if (IS_ALIGNED(clip_src_width, 32)) {
+      InterpolateRow = InterpolateRow_AVX2;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    InterpolateRow = InterpolateRow_Any_NEON;
+    if (IS_ALIGNED(clip_src_width, 16)) {
+      InterpolateRow = InterpolateRow_NEON;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_DSPR2)
+  if (TestCpuFlag(kCpuHasDSPR2) &&
+      IS_ALIGNED(src_argb, 4) && IS_ALIGNED(argb_cnv_rowstride, 4)) {
+    InterpolateRow = InterpolateRow_Any_DSPR2;
+    if (IS_ALIGNED(clip_src_width, 4)) {
+      InterpolateRow = InterpolateRow_DSPR2;
+    }
+  }
+#endif
+#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3)
+  if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) {
+    ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3;
+  }
+#endif
+#if defined(HAS_SCALEARGBFILTERCOLS_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBFilterCols = ScaleARGBFilterCols_Any_NEON;
+    if (IS_ALIGNED(dst_width, 4)) {
+      ScaleARGBFilterCols = ScaleARGBFilterCols_NEON;
+    }
+  }
+#endif
+
+  int yi = y >> 16;
+
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+  iter.MoveTo(iter, yi);
+
+  // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear.
+  // Allocate a row of ARGB.
+  align_buffer_64(row, clip_src_width * 4);
+
+  int lastyi = yi;
+  YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+  // Prepare next row if necessary
+  if (filtering != kFilterLinear) {
+    if ((yi + 1) < src_height) {
+      iter.MoveToNextRow(iter);
+      YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+    } else {
+      argb_cnv_rowstride = 0;
+    }
+  }
+
+  const int max_y = (src_height - 1) << 16;
+  const int max_yi = src_height - 1;
+  for (j = 0; j < dst_height; ++j) {
+    yi = y >> 16;
+    if (yi != lastyi) {
+      if (y > max_y) {
+        y = max_y;
+        yi = y >> 16;
+      }
+      if (yi != lastyi) {
+        if (filtering == kFilterLinear) {
+          iter.MoveTo(iter, yi);
+          YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          lastyi = yi;
+        } else {
+          // Prepare current row
+          if (yi == iter.y_index) {
+            argb_cnv_rowptr = argb_cnv_rowptr + argb_cnv_rowstride;
+            argb_cnv_rowstride = - argb_cnv_rowstride;
+          } else {
+            iter.MoveTo(iter, yi);
+            argb_cnv_rowptr = argb_cnv_row;
+            argb_cnv_rowstride = kRowSize;
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr);
+          }
+          // Prepare next row if necessary
+          if (iter.y_index < max_yi) {
+            iter.MoveToNextRow(iter);
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_rowptr + argb_cnv_rowstride);
+          } else {
+            argb_cnv_rowstride = 0;
+          }
+          lastyi = yi;
+        }
+      }
+    }
+    if (filtering == kFilterLinear) {
+      ScaleARGBFilterCols(dst_argb, argb_cnv_rowptr + xl_offset, dst_width, x, dx);
+    } else {
+      int yf = (y >> 8) & 255;
+      InterpolateRow(row, argb_cnv_rowptr + xl_offset, argb_cnv_rowstride, clip_src_width, yf);
+      ScaleARGBFilterCols(dst_argb, row, dst_width, x, dx);
+    }
+    dst_argb += dst_stride_argb;
+    y += dy;
+  }
+  free_aligned_buffer_64(row);
+  free_aligned_buffer_64(argb_cnv_row);
+}
+
+// Scale YUV to ARGB up with bilinear interpolation.
+static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
+                                     int dst_width, int dst_height,
+                                     int src_stride_y,
+                                     int src_stride_u,
+                                     int src_stride_v,
+                                     int dst_stride_argb,
+                                     const uint8* src_y,
+                                     const uint8* src_u,
+                                     const uint8* src_v,
+                                     uint8* dst_argb,
+                                     int x, int dx, int y, int dy,
+                                     enum FilterMode filtering,
+                                     uint32 src_fourcc) {
+  int j;
+  void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
+      ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
+      InterpolateRow_C;
+  void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb,
+      int dst_width, int x, int dx) =
+      filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C;
+  const int max_y = (src_height - 1) << 16;
+
+  // Allocate 1 row of ARGB for source conversion.
+  align_buffer_64(argb_cnv_row, src_width * 4);
+
+#if defined(HAS_INTERPOLATEROW_SSSE3)
+  if (TestCpuFlag(kCpuHasSSSE3)) {
+    InterpolateRow = InterpolateRow_Any_SSSE3;
+    if (IS_ALIGNED(dst_width, 4)) {
+      InterpolateRow = InterpolateRow_SSSE3;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_AVX2)
+  if (TestCpuFlag(kCpuHasAVX2)) {
+    InterpolateRow = InterpolateRow_Any_AVX2;
+    if (IS_ALIGNED(dst_width, 8)) {
+      InterpolateRow = InterpolateRow_AVX2;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    InterpolateRow = InterpolateRow_Any_NEON;
+    if (IS_ALIGNED(dst_width, 4)) {
+      InterpolateRow = InterpolateRow_NEON;
+    }
+  }
+#endif
+#if defined(HAS_INTERPOLATEROW_DSPR2)
+  if (TestCpuFlag(kCpuHasDSPR2) &&
+      IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
+    InterpolateRow = InterpolateRow_DSPR2;
+  }
+#endif
+  if (src_width >= 32768) {
+    ScaleARGBFilterCols = filtering ?
+        ScaleARGBFilterCols64_C : ScaleARGBCols64_C;
+  }
+#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3)
+  if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) {
+    ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3;
+  }
+#endif
+#if defined(HAS_SCALEARGBFILTERCOLS_NEON)
+  if (filtering && TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBFilterCols = ScaleARGBFilterCols_Any_NEON;
+    if (IS_ALIGNED(dst_width, 4)) {
+      ScaleARGBFilterCols = ScaleARGBFilterCols_NEON;
+    }
+  }
+#endif
+#if defined(HAS_SCALEARGBCOLS_SSE2)
+  if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) {
+    ScaleARGBFilterCols = ScaleARGBCols_SSE2;
+  }
+#endif
+#if defined(HAS_SCALEARGBCOLS_NEON)
+  if (!filtering && TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBFilterCols = ScaleARGBCols_Any_NEON;
+    if (IS_ALIGNED(dst_width, 8)) {
+      ScaleARGBFilterCols = ScaleARGBCols_NEON;
+    }
+  }
+#endif
+  if (!filtering && src_width * 2 == dst_width && x < 0x8000) {
+    ScaleARGBFilterCols = ScaleARGBColsUp2_C;
+#if defined(HAS_SCALEARGBCOLSUP2_SSE2)
+    if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) {
+      ScaleARGBFilterCols = ScaleARGBColsUp2_SSE2;
+    }
+#endif
+  }
+
+  if (y > max_y) {
+    y = max_y;
+  }
+
+  int yi = y >> 16;
+
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+  iter.MoveTo(iter, yi);
+
+  // Allocate 2 rows of ARGB.
+  const int kRowSize = (dst_width * 4 + 15) & ~15;
+  align_buffer_64(row, kRowSize * 2);
+
+  uint8* rowptr = row;
+  int rowstride = kRowSize;
+  int lastyi = yi;
+
+  YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+  ScaleARGBFilterCols(rowptr, argb_cnv_row, dst_width, x, dx);
+
+  if (filtering == kFilterLinear) {
+    rowstride = 0;
+  }
+  // Prepare next row if necessary
+  if (filtering != kFilterLinear) {
+    if ((yi + 1) < src_height) {
+      iter.MoveToNextRow(iter);
+      YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+      ScaleARGBFilterCols(rowptr + rowstride, argb_cnv_row, dst_width, x, dx);
+    }else {
+      rowstride = 0;
+    }
+  }
+
+  const int max_yi = src_height - 1;
+  for (j = 0; j < dst_height; ++j) {
+    yi = y >> 16;
+    if (yi != lastyi) {
+      if (y > max_y) {
+        y = max_y;
+        yi = y >> 16;
+      }
+      if (yi != lastyi) {
+        if (filtering == kFilterLinear) {
+            iter.MoveToNextRow(iter);
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+            ScaleARGBFilterCols(rowptr, argb_cnv_row, dst_width, x, dx);
+        } else {
+          // Prepare next row if necessary
+          if (yi < max_yi) {
+            iter.MoveToNextRow(iter);
+            rowptr += rowstride;
+            rowstride = -rowstride;
+            // TODO(fbarchard): Convert the clipped region of row.
+            YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+            ScaleARGBFilterCols(rowptr + rowstride, argb_cnv_row, dst_width, x, dx);
+          } else {
+            rowstride = 0;
+          }
+        }
+        lastyi = yi;
+      }
+    }
+    if (filtering == kFilterLinear) {
+      InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0);
+    } else {
+      int yf = (y >> 8) & 255;
+      InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf);
+    }
+    dst_argb += dst_stride_argb;
+    y += dy;
+  }
+  free_aligned_buffer_64(row);
+  free_aligned_buffer_64(argb_cnv_row);
+}
+
+// Scale ARGB to/from any dimensions, without interpolation.
+// Fixed point math is used for performance: The upper 16 bits
+// of x and dx is the integer part of the source position and
+// the lower 16 bits are the fixed decimal part.
+
+static void ScaleYUVToARGBSimple(int src_width, int src_height,
+                                 int dst_width, int dst_height,
+                                 int src_stride_y,
+                                 int src_stride_u,
+                                 int src_stride_v,
+                                 int dst_stride_argb,
+                                 const uint8* src_y,
+                                 const uint8* src_u,
+                                 const uint8* src_v,
+                                 uint8* dst_argb,
+                                 int x, int dx, int y, int dy,
+                                 uint32 src_fourcc) {
+  int j;
+  void (*ScaleARGBCols)(uint8* dst_argb, const uint8* src_argb,
+      int dst_width, int x, int dx) =
+      (src_width >= 32768) ? ScaleARGBCols64_C : ScaleARGBCols_C;
+
+  // Allocate 1 row of ARGB for source conversion.
+  align_buffer_64(argb_cnv_row, src_width * 4);
+
+#if defined(HAS_SCALEARGBCOLS_SSE2)
+  if (TestCpuFlag(kCpuHasSSE2) && src_width < 32768) {
+    ScaleARGBCols = ScaleARGBCols_SSE2;
+  }
+#endif
+#if defined(HAS_SCALEARGBCOLS_NEON)
+  if (TestCpuFlag(kCpuHasNEON)) {
+    ScaleARGBCols = ScaleARGBCols_Any_NEON;
+    if (IS_ALIGNED(dst_width, 8)) {
+      ScaleARGBCols = ScaleARGBCols_NEON;
+    }
+  }
+#endif
+  if (src_width * 2 == dst_width && x < 0x8000) {
+    ScaleARGBCols = ScaleARGBColsUp2_C;
+#if defined(HAS_SCALEARGBCOLSUP2_SSE2)
+    if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) {
+      ScaleARGBCols = ScaleARGBColsUp2_SSE2;
+    }
+#endif
+  }
+
+  int yi = y >> 16;
+
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+  iter.MoveTo(iter, yi);
+
+  int lasty = yi;
+  YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+
+  for (j = 0; j < dst_height; ++j) {
+    yi = y >> 16;
+    if (yi != lasty) {
+      iter.MoveTo(iter, yi);
+      YUVBuferIter_ConvertToARGBRow(iter, argb_cnv_row);
+      lasty = yi;
+    }
+    ScaleARGBCols(dst_argb, argb_cnv_row, dst_width, x, dx);
+    dst_argb += dst_stride_argb;
+    y += dy;
+  }
+  free_aligned_buffer_64(argb_cnv_row);
+}
+
+static void YUVToARGBCopy(const uint8* src_y, int src_stride_y,
+                          const uint8* src_u, int src_stride_u,
+                          const uint8* src_v, int src_stride_v,
+                          int src_width, int src_height,
+                          uint8* dst_argb, int dst_stride_argb,
+                          int dst_width, int dst_height,
+                          uint32 src_fourcc)
+{
+  YUVBuferIter iter;
+  iter.src_width = src_width;
+  iter.src_height = src_height;
+  iter.src_stride_y = src_stride_y;
+  iter.src_stride_u = src_stride_u;
+  iter.src_stride_v = src_stride_v;
+  iter.src_y = src_y;
+  iter.src_u = src_u;
+  iter.src_v = src_v;
+  YUVBuferIter_Init(iter, src_fourcc);
+
+  for (int j = 0; j < dst_height; ++j) {
+    YUVBuferIter_ConvertToARGBRow(iter, dst_argb);
+    iter.MoveToNextRow(iter);
+    dst_argb += dst_stride_argb;
+  }
+}
+
+static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
+                           const uint8* src_u, int src_stride_u,
+                           const uint8* src_v, int src_stride_v,
+                           int src_width, int src_height,
+                           uint8* dst_argb, int dst_stride_argb,
+                           int dst_width, int dst_height,
+                           enum FilterMode filtering,
+                           uint32 src_fourcc)
+{
+  // Initial source x/y coordinate and step values as 16.16 fixed point.
+  int x = 0;
+  int y = 0;
+  int dx = 0;
+  int dy = 0;
+  // ARGB does not support box filter yet, but allow the user to pass it.
+  // Simplify filtering when possible.
+  filtering = ScaleFilterReduce(src_width, src_height,
+                                dst_width, dst_height,
+                                filtering);
+  ScaleSlope(src_width, src_height, dst_width, dst_height, filtering,
+             &x, &y, &dx, &dy);
+
+  // Special case for integer step values.
+  if (((dx | dy) & 0xffff) == 0) {
+    if (!dx || !dy) {  // 1 pixel wide and/or tall.
+      filtering = kFilterNone;
+    } else {
+      // Optimized even scale down. ie 2, 4, 6, 8, 10x.
+      if (!(dx & 0x10000) && !(dy & 0x10000)) {
+        if (dx == 0x20000) {
+          // Optimized 1/2 downsample.
+          ScaleYUVToARGBDown2(src_width, src_height,
+                              dst_width, dst_height,
+                              src_stride_y,
+                              src_stride_u,
+                              src_stride_v,
+                              dst_stride_argb,
+                              src_y,
+                              src_u,
+                              src_v,
+                              dst_argb,
+                              x, dx, y, dy,
+                              filtering,
+                              src_fourcc);
+          return;
+        }
+        ScaleYUVToARGBDownEven(src_width, src_height,
+                               dst_width, dst_height,
+                               src_stride_y,
+                               src_stride_u,
+                               src_stride_v,
+                               dst_stride_argb,
+                               src_y,
+                               src_u,
+                               src_v,
+                               dst_argb,
+                               x, dx, y, dy,
+                               filtering,
+                               src_fourcc);
+        return;
+      }
+      // Optimized odd scale down. ie 3, 5, 7, 9x.
+      if ((dx & 0x10000) && (dy & 0x10000)) {
+        filtering = kFilterNone;
+        if (dx == 0x10000 && dy == 0x10000) {
+          // Straight conversion and copy.
+          YUVToARGBCopy(src_y, src_stride_y,
+                        src_u, src_stride_u,
+                        src_v, src_stride_v,
+                        src_width, src_height,
+                        dst_argb, dst_stride_argb,
+                        dst_width, dst_height,
+                        src_fourcc);
+          return;
+        }
+      }
+    }
+  }
+  if (filtering && dy < 65536) {
+    ScaleYUVToARGBBilinearUp(src_width, src_height,
+                             dst_width, dst_height,
+                             src_stride_y,
+                             src_stride_u,
+                             src_stride_v,
+                             dst_stride_argb,
+                             src_y,
+                             src_u,
+                             src_v,
+                             dst_argb,
+                             x, dx, y, dy,
+                             filtering,
+                             src_fourcc);
+    return;
+  }
+  if (filtering) {
+    ScaleYUVToARGBBilinearDown(src_width, src_height,
+                               dst_width, dst_height,
+                               src_stride_y,
+                               src_stride_u,
+                               src_stride_v,
+                               dst_stride_argb,
+                               src_y,
+                               src_u,
+                               src_v,
+                               dst_argb,
+                               x, dx, y, dy,
+                               filtering,
+                               src_fourcc);
+    return;
+  }
+  ScaleYUVToARGBSimple(src_width, src_height,
+                       dst_width, dst_height,
+                       src_stride_y,
+                       src_stride_u,
+                       src_stride_v,
+                       dst_stride_argb,
+                       src_y,
+                       src_u,
+                       src_v,
+                       dst_argb,
+                       x, dx, y, dy,
+                       src_fourcc);
+}
+
+bool IsConvertSupported(uint32 src_fourcc)
+{
+  if (src_fourcc == FOURCC_I444 ||
+      src_fourcc == FOURCC_I422 ||
+      src_fourcc == FOURCC_I420) {
+    return true;
+  }
+  return false;
+}
+
+LIBYUV_API
+int YUVToARGBScale(const uint8* src_y, int src_stride_y,
+                   const uint8* src_u, int src_stride_u,
+                   const uint8* src_v, int src_stride_v,
+                   uint32 src_fourcc,
+                   int src_width, int src_height,
+                   uint8* dst_argb, int dst_stride_argb,
+                   int dst_width, int dst_height,
+                   enum FilterMode filtering)
+{
+  if (!src_y || !src_u || !src_v ||
+      src_width == 0 || src_height == 0 ||
+      !dst_argb || dst_width <= 0 || dst_height <= 0) {
+    return -1;
+  }
+  if (!IsConvertSupported(src_fourcc)) {
+    return -1;
+  }
+  ScaleYUVToARGB(src_y, src_stride_y,
+                 src_u, src_stride_u,
+                 src_v, src_stride_v,
+                 src_width, src_height,
+                 dst_argb, dst_stride_argb,
+                 dst_width, dst_height,
+                 filtering,
+                 src_fourcc);
+  return 0;
+}
+
+#ifdef __cplusplus
+}  // extern "C"
+}  // namespace libyuv
+#endif
new file mode 100644
--- /dev/null
+++ b/gfx/ycbcr/scale_yuv_argb.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright 2012 The LibYuv Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS. All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef INCLUDE_LIBYUV_SCALE_YUV_ARGB_H_  // NOLINT
+#define INCLUDE_LIBYUV_SCALE_YUV_ARGB_H_
+
+#include "libyuv/basic_types.h"
+#include "libyuv/scale.h"  // For FilterMode
+
+#ifdef __cplusplus
+namespace libyuv {
+extern "C" {
+#endif
+
+int YUVToARGBScale(const uint8* src_y, int src_stride_y,
+                   const uint8* src_u, int src_stride_u,
+                   const uint8* src_v, int src_stride_v,
+                   uint32 src_fourcc,
+                   int src_width, int src_height,
+                   uint8* dst_argb, int dst_stride_argb,
+                   int dst_width, int dst_height,
+                   enum FilterMode filtering);
+
+#ifdef __cplusplus
+}  // extern "C"
+}  // namespace libyuv
+#endif
+
+#endif  // INCLUDE_LIBYUV_SCALE_YUV_ARGB_H_  NOLINT
--- a/gfx/ycbcr/yuv_convert.cpp
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -15,45 +15,59 @@
 //
 // ARGB pixel format is output, which on little endian is stored as BGRA.
 // The alpha is set to 255, allowing the application to use RGBA or RGB32.
 
 #include "yuv_convert.h"
 
 #include "gfxPrefs.h"
 #include "libyuv.h"
+#include "scale_yuv_argb.h"
 // Header for low level row functions.
 #include "yuv_row.h"
 #include "mozilla/SSE.h"
 
 namespace mozilla {
 
 namespace gfx {
 
 // 16.16 fixed point arithmetic
 const int kFractionBits = 16;
 const int kFractionMax = 1 << kFractionBits;
 const int kFractionMask = ((1 << kFractionBits) - 1);
 
 YUVType TypeFromSize(int ywidth,
-                              int yheight,
-                              int cbcrwidth,
-                              int cbcrheight)
+                     int yheight,
+                     int cbcrwidth,
+                     int cbcrheight)
 {
   if (ywidth == cbcrwidth && yheight == cbcrheight) {
     return YV24;
   }
   else if ((ywidth + 1) / 2 == cbcrwidth && yheight == cbcrheight) {
     return YV16;
   }
   else {
     return YV12;
   }
 }
 
+libyuv::FourCC FourCCFromYUVType(YUVType aYUVType)
+{
+  if (aYUVType == YV24) {
+    return libyuv::FOURCC_I444;
+  } else if (aYUVType == YV16) {
+    return libyuv::FOURCC_I422;
+  } else if (aYUVType == YV12) {
+    return libyuv::FOURCC_I420;
+  } else {
+    return libyuv::FOURCC_ANY;
+  }
+}
+
 // Convert a frame of YUV to 32 bit ARGB.
 void ConvertYCbCrToRGB32(const uint8* y_buf,
                          const uint8* u_buf,
                          const uint8* v_buf,
                          uint8* rgb_buf,
                          int pic_x,
                          int pic_y,
                          int pic_width,
@@ -238,18 +252,61 @@ void ScaleYCbCrToRGB32(const uint8* y_bu
                        int source_width,
                        int source_height,
                        int width,
                        int height,
                        int y_pitch,
                        int uv_pitch,
                        int rgb_pitch,
                        YUVType yuv_type,
-                       Rotate view_rotate,
                        ScaleFilter filter) {
+
+  bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
+                        (supports_mmx() && supports_sse() && !supports_sse3());
+  if (use_deprecated) {
+    ScaleYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf,
+                                 rgb_buf,
+                                 source_width, source_height,
+                                 width, height,
+                                 y_pitch, uv_pitch,
+                                 rgb_pitch,
+                                 yuv_type,
+                                 ROTATE_0,
+                                 filter);
+    return;
+  }
+
+  DebugOnly<int> err =
+    libyuv::YUVToARGBScale(y_buf, y_pitch,
+                           u_buf, uv_pitch,
+                           v_buf, uv_pitch,
+                           FourCCFromYUVType(yuv_type),
+                           source_width, source_height,
+                           rgb_buf, rgb_pitch,
+                           width, height,
+                           libyuv::kFilterBilinear);
+  MOZ_ASSERT(!err);
+  return;
+}
+
+// Scale a frame of YUV to 32 bit ARGB.
+void ScaleYCbCrToRGB32_deprecated(const uint8* y_buf,
+                                  const uint8* u_buf,
+                                  const uint8* v_buf,
+                                  uint8* rgb_buf,
+                                  int source_width,
+                                  int source_height,
+                                  int width,
+                                  int height,
+                                  int y_pitch,
+                                  int uv_pitch,
+                                  int rgb_pitch,
+                                  YUVType yuv_type,
+                                  Rotate view_rotate,
+                                  ScaleFilter filter) {
   bool has_mmx = supports_mmx();
 
   // 4096 allows 3 buffers to fit in 12k.
   // Helps performance on CPU with 16K L1 cache.
   // Large enough for 3830x2160 and 30" displays which are 2560x1600.
   const int kFilterBufferSize = 4096;
   // Disable filtering if the screen is too big (to avoid buffer overflows).
   // This should never happen to regular users: they don't have monitors
--- a/gfx/ycbcr/yuv_convert.h
+++ b/gfx/ycbcr/yuv_convert.h
@@ -79,15 +79,29 @@ void ScaleYCbCrToRGB32(const uint8* ypla
                        int source_width,
                        int source_height,
                        int width,
                        int height,
                        int ystride,
                        int uvstride,
                        int rgbstride,
                        YUVType yuv_type,
-                       Rotate view_rotate,
                        ScaleFilter filter);
 
+void ScaleYCbCrToRGB32_deprecated(const uint8* yplane,
+                                  const uint8* uplane,
+                                  const uint8* vplane,
+                                  uint8* rgbframe,
+                                  int source_width,
+                                  int source_height,
+                                  int width,
+                                  int height,
+                                  int ystride,
+                                  int uvstride,
+                                  int rgbstride,
+                                  YUVType yuv_type,
+                                  Rotate view_rotate,
+                                  ScaleFilter filter);
+
 } // namespace gfx
 } // namespace mozilla
  
 #endif  // MEDIA_BASE_YUV_CONVERT_H_
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -667,17 +667,17 @@ js::Nursery::collect(JSRuntime* rt, JS::
     endProfile(ProfileKey::Total);
     minorGcCount_++;
 
     int64_t totalTime = profileTimes_[ProfileKey::Total];
     rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime);
     rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, reason);
     if (totalTime > 1000)
         rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason);
-    rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, nurserySize());
+    rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, sizeOfHeapCommitted());
 
     rt->gc.stats.endNurseryCollection(reason);
     TraceMinorGCEnd();
 
     if (enableProfiling_ && totalTime >= profileThreshold_) {
         static int printedHeader = 0;
         if ((printedHeader++ % 200) == 0) {
             fprintf(stderr, "MinorGC:               Reason  PRate Size ");
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -165,16 +165,19 @@ class Nursery
 
     /* Resize an existing object buffer. */
     void* reallocateBuffer(JSObject* obj, void* oldBuffer,
                            uint32_t oldBytes, uint32_t newBytes);
 
     /* Free an object buffer. */
     void freeBuffer(void* buffer);
 
+    /* The maximum number of bytes allowed to reside in nursery buffers. */
+    static const size_t MaxNurseryBufferSize = 1024;
+
     typedef Vector<ObjectGroup*, 0, SystemAllocPolicy> ObjectGroupList;
 
     /*
      * Do a minor collection, optionally specifying a list to store groups which
      * should be pretenured afterwards.
      */
     void collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList* pretenureGroups);
 
@@ -341,19 +344,16 @@ class Nursery
     struct SweepAction;
     SweepAction* sweepActions_;
 
 #ifdef JS_GC_ZEAL
     struct Canary;
     Canary* lastCanary_;
 #endif
 
-    /* The maximum number of bytes allowed to reside in nursery buffers. */
-    static const size_t MaxNurseryBufferSize = 1024;
-
     /* The amount of space in the mapped nursery available to allocations. */
     static const size_t NurseryChunkUsableSize = gc::ChunkSize - sizeof(gc::ChunkTrailer);
 
     struct NurseryChunkLayout {
         char data[NurseryChunkUsableSize];
         gc::ChunkTrailer trailer;
         uintptr_t start() const { return uintptr_t(&data); }
         uintptr_t end() const { return uintptr_t(&trailer); }
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -5497,18 +5497,22 @@ GetTemplateObjectForNative(JSContext* cx
             // don't end up with a template whose structure might change later.
             res.set(NewFullyAllocatedArrayForCallingAllocationSite(cx, count, TenuredObject));
             if (!res)
                 return false;
             return true;
         }
     }
 
-    if (args.length() == 1 && args[0].isInt32() && args[0].toInt32() >= 0) {
-        uint32_t len = args[0].toInt32();
+    if (args.length() == 1) {
+        size_t len = 0;
+
+        if (args[0].isInt32() && args[0].toInt32() >= 0)
+            len = args[0].toInt32();
+
         if (TypedArrayObject::GetTemplateObjectForNative(cx, native, len, res))
             return !!res;
     }
 
     if (native == js::array_slice) {
         if (args.thisv().isObject()) {
             JSObject* obj = &args.thisv().toObject();
             if (!obj->isSingleton()) {
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5419,17 +5419,44 @@ CodeGenerator::visitNewTypedArray(LNewTy
 
     OutOfLineCode* ool = oolCallVM(TypedArrayConstructorOneArgInfo, lir,
                                    ArgList(ImmGCPtr(templateObject), Imm32(n)),
                                    StoreRegisterTo(objReg));
 
     masm.createGCObject(objReg, tempReg, templateObject, initialHeap,
                         ool->entry(), /*initContents*/true, /*convertDoubleElements*/false);
 
-    masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(), ttemplate);
+    masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(),
+                             ttemplate, TypedArrayLength::Fixed);
+
+    masm.bind(ool->rejoin());
+}
+
+void
+CodeGenerator::visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir)
+{
+    Register lengthReg = ToRegister(lir->length());
+    Register objReg = ToRegister(lir->output());
+    Register tempReg = ToRegister(lir->temp());
+    LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
+
+    JSObject* templateObject = lir->mir()->templateObject();
+    gc::InitialHeap initialHeap = lir->mir()->initialHeap();
+
+    TypedArrayObject* ttemplate = &templateObject->as<TypedArrayObject>();
+
+    OutOfLineCode* ool = oolCallVM(TypedArrayConstructorOneArgInfo, lir,
+                                   ArgList(ImmGCPtr(templateObject), lengthReg),
+                                   StoreRegisterTo(objReg));
+
+    masm.createGCObject(objReg, tempReg, templateObject, initialHeap,
+                        ool->entry(), /*initContents*/true, /*convertDoubleElements*/false);
+
+    masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(),
+                             ttemplate, TypedArrayLength::Dynamic);
 
     masm.bind(ool->rejoin());
 }
 
 // Out-of-line object allocation for JSOP_NEWOBJECT.
 class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator>
 {
     LNewObject* lir_;
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -190,16 +190,17 @@ class CodeGenerator final : public CodeG
     void visitDoubleToInt32(LDoubleToInt32* lir);
     void visitFloat32ToInt32(LFloat32ToInt32* lir);
     void visitNewArrayCallVM(LNewArray* lir);
     void visitNewArray(LNewArray* lir);
     void visitOutOfLineNewArray(OutOfLineNewArray* ool);
     void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
     void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
     void visitNewTypedArray(LNewTypedArray* lir);
+    void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
     void visitNewObjectVMCall(LNewObject* lir);
     void visitNewObject(LNewObject* lir);
     void visitOutOfLineNewObject(OutOfLineNewObject* ool);
     void visitNewTypedObject(LNewTypedObject* lir);
     void visitSimdBox(LSimdBox* lir);
     void visitSimdUnbox(LSimdUnbox* lir);
     void visitNewDeclEnvObject(LNewDeclEnvObject* lir);
     void visitNewCallObject(LNewCallObject* lir);
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -243,16 +243,27 @@ void
 LIRGenerator::visitNewTypedArray(MNewTypedArray* ins)
 {
     LNewTypedArray* lir = new(alloc()) LNewTypedArray(temp(), temp());
     define(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
+LIRGenerator::visitNewTypedArrayDynamicLength(MNewTypedArrayDynamicLength* ins)
+{
+    MDefinition* length = ins->length();
+    MOZ_ASSERT(length->type() == MIRType::Int32);
+
+    LNewTypedArrayDynamicLength* lir = new(alloc()) LNewTypedArrayDynamicLength(useRegister(length), temp());
+    define(lir, ins);
+    assignSafepoint(lir, ins);
+}
+
+void
 LIRGenerator::visitNewObject(MNewObject* ins)
 {
     LNewObject* lir = new(alloc()) LNewObject(temp());
     define(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -70,16 +70,17 @@ class LIRGenerator : public LIRGenerator
     void visitCallee(MCallee* callee);
     void visitIsConstructing(MIsConstructing* ins);
     void visitGoto(MGoto* ins);
     void visitTableSwitch(MTableSwitch* tableswitch);
     void visitNewArray(MNewArray* ins);
     void visitNewArrayCopyOnWrite(MNewArrayCopyOnWrite* ins);
     void visitNewArrayDynamicLength(MNewArrayDynamicLength* ins);
     void visitNewTypedArray(MNewTypedArray* ins);
+    void visitNewTypedArrayDynamicLength(MNewTypedArrayDynamicLength* ins);
     void visitNewObject(MNewObject* ins);
     void visitNewTypedObject(MNewTypedObject* ins);
     void visitNewDeclEnvObject(MNewDeclEnvObject* ins);
     void visitNewCallObject(MNewCallObject* ins);
     void visitNewSingletonCallObject(MNewSingletonCallObject* ins);
     void visitNewStringObject(MNewStringObject* ins);
     void visitNewDerivedTypedObject(MNewDerivedTypedObject* ins);
     void visitInitElem(MInitElem* ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2299,50 +2299,55 @@ IonBuilder::inlineTypedArray(CallInfo& c
     if (callInfo.argc() != 1)
         return InliningStatus_NotInlined;
 
     MDefinition* arg = callInfo.getArg(0);
 
     if (arg->type() != MIRType::Int32)
         return InliningStatus_NotInlined;
 
-    if (!arg->maybeConstantValue())
-        return InliningStatus_NotInlined;
-
     JSObject* templateObject = inspector->getTemplateObjectForNative(pc, native);
 
     if (!templateObject) {
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeNoTemplateObj);
         return InliningStatus_NotInlined;
     }
 
     MOZ_ASSERT(templateObject->is<TypedArrayObject>());
     TypedArrayObject* obj = &templateObject->as<TypedArrayObject>();
 
     // Do not optimize when we see a template object with a singleton type,
     // since it hits at most once.
     if (templateObject->isSingleton())
         return InliningStatus_NotInlined;
 
-    // Negative lengths must throw a RangeError.  (We don't track that this
-    // might have previously thrown, when determining whether to inline, so we
-    // have to deal with this error case when inlining.)
-    int32_t providedLen = arg->maybeConstantValue()->toInt32();
-    if (providedLen < 0)
-        return InliningStatus_NotInlined;
-
-    uint32_t len = AssertedCast<uint32_t>(providedLen);
-
-    if (obj->length() != len)
-        return InliningStatus_NotInlined;
-
-    callInfo.setImplicitlyUsedUnchecked();
-
-    MInstruction* ins = MNewTypedArray::New(alloc(), constraints(), obj,
-                                            obj->group()->initialHeap(constraints()));
+    MInstruction* ins = nullptr;
+
+    if (!arg->isConstant()) {
+        callInfo.setImplicitlyUsedUnchecked();
+        ins = MNewTypedArrayDynamicLength::New(alloc(), constraints(), templateObject,
+                                               templateObject->group()->initialHeap(constraints()),
+                                               arg);
+    } else {
+        // Negative lengths must throw a RangeError.  (We don't track that this
+        // might have previously thrown, when determining whether to inline, so we
+        // have to deal with this error case when inlining.)
+        int32_t providedLen = arg->maybeConstantValue()->toInt32();
+        if (providedLen < 0)
+            return InliningStatus_NotInlined;
+
+        uint32_t len = AssertedCast<uint32_t>(providedLen);
+
+        if (obj->length() != len)
+            return InliningStatus_NotInlined;
+
+        callInfo.setImplicitlyUsedUnchecked();
+        ins = MNewTypedArray::New(alloc(), constraints(), obj,
+                                  obj->group()->initialHeap(constraints()));
+    }
 
     current->add(ins);
     current->push(ins);
     if (!resumeAfter(ins))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3333,16 +3333,60 @@ class MNewTypedArray : public MNullaryIn
         return initialHeap_;
     }
 
     virtual AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
 };
 
+class MNewTypedArrayDynamicLength
+  : public MUnaryInstruction,
+    public IntPolicy<0>::Data
+{
+    CompilerObject templateObject_;
+    gc::InitialHeap initialHeap_;
+
+    MNewTypedArrayDynamicLength(CompilerConstraintList* constraints, JSObject* templateObject,
+                           gc::InitialHeap initialHeap, MDefinition* length)
+      : MUnaryInstruction(length),
+        templateObject_(templateObject),
+        initialHeap_(initialHeap)
+    {
+        setGuard(); // Need to throw if length is negative.
+        setResultType(MIRType::Object);
+        if (!templateObject->isSingleton())
+            setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
+    }
+
+  public:
+    INSTRUCTION_HEADER(NewTypedArrayDynamicLength)
+
+    static MNewTypedArrayDynamicLength* New(TempAllocator& alloc, CompilerConstraintList* constraints,
+                                            JSObject* templateObject, gc::InitialHeap initialHeap,
+                                            MDefinition* length)
+    {
+        return new(alloc) MNewTypedArrayDynamicLength(constraints, templateObject, initialHeap, length);
+    }
+
+    MDefinition* length() const {
+        return getOperand(0);
+    }
+    JSObject* templateObject() const {
+        return templateObject_;
+    }
+    gc::InitialHeap initialHeap() const {
+        return initialHeap_;
+    }
+
+    virtual AliasSet getAliasSet() const override {
+        return AliasSet::None();
+    }
+};
+
 class MNewObject
   : public MUnaryInstruction,
     public NoTypePolicy::Data
 {
   public:
     enum Mode { ObjectLiteral, ObjectCreate };
 
   private:
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -125,16 +125,17 @@ namespace jit {
     _(ExtendInt32ToInt64)                                                   \
     _(Int64ToFloatingPoint)                                                 \
     _(ToString)                                                             \
     _(ToObjectOrNull)                                                       \
     _(NewArray)                                                             \
     _(NewArrayCopyOnWrite)                                                  \
     _(NewArrayDynamicLength)                                                \
     _(NewTypedArray)                                                        \
+    _(NewTypedArrayDynamicLength)                                           \
     _(NewObject)                                                            \
     _(NewTypedObject)                                                       \
     _(NewDeclEnvObject)                                                     \
     _(NewCallObject)                                                        \
     _(NewSingletonCallObject)                                               \
     _(NewStringObject)                                                      \
     _(ObjectState)                                                          \
     _(ArrayState)                                                           \
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1048,42 +1048,61 @@ AllocateObjectBufferWithInit(JSContext* 
             return; \
         break;
 JS_FOR_EACH_TYPED_ARRAY(CREATE_TYPED_ARRAY)
 #undef CREATE_TYPED_ARRAY
       default:
         MOZ_CRASH("Unsupported TypedArray type");
     }
 
-    void* buf = AllocateObjectBuffer<char>(cx, obj, nbytes);
+    nbytes = JS_ROUNDUP(nbytes, sizeof(Value));
+
+    // Elements can only be stored in the nursery since typed arrays have a
+    // finalizer that frees the memory, but the finalizer is only called for
+    // tenured objects. Allocating the memory in the nursery is done to avoid
+    // memory leaks.
+    if (nbytes > Nursery::MaxNurseryBufferSize)
+        return;
+
+    Nursery& nursery = cx->runtime()->gc.nursery;
+    void* buf = nursery.allocateBuffer(obj->zone(), nbytes);
     if (buf) {
-        obj->initPrivate(buf);
-        memset(buf, 0, nbytes);
+        if (nursery.isInside(buf) || obj->isTenured()) {
+            obj->initPrivate(buf);
+            memset(buf, 0, nbytes);
+        } else {
+            // If the nursery is full, |allocateBuffer| will try to allocate
+            // the memory in the tenured heap. This will leak memory when the
+            // object is not tenured since the finalizer will not be called for
+            // non-tenured objects.
+            nursery.removeMallocedBuffer(buf);
+            js_free(buf);
+        }
     }
 }
 
 void
 MacroAssembler::initTypedArraySlots(Register obj, Register temp, Register lengthReg,
                                     LiveRegisterSet liveRegs, Label* fail,
-                                    TypedArrayObject* templateObj)
+                                    TypedArrayObject* templateObj, TypedArrayLength lengthKind)
 {
     MOZ_ASSERT(templateObj->hasPrivate());
     MOZ_ASSERT(!templateObj->hasBuffer());
 
     size_t dataSlotOffset = TypedArrayObject::dataOffset();
     size_t dataOffset = TypedArrayObject::dataOffset() + sizeof(HeapSlot);
 
     static_assert(TypedArrayObject::FIXED_DATA_START == TypedArrayObject::DATA_SLOT + 1,
                     "fixed inline element data assumed to begin after the data slot");
 
     // Initialise data elements to zero.
     int32_t length = templateObj->length();
     size_t nbytes = length * templateObj->bytesPerElement();
 
-    if (dataOffset + nbytes <= JSObject::MAX_BYTE_SIZE) {
+    if (lengthKind == TypedArrayLength::Fixed && dataOffset + nbytes <= JSObject::MAX_BYTE_SIZE) {
         MOZ_ASSERT(dataOffset + nbytes <= templateObj->tenuredSizeOfThis());
 
         // Store data elements inside the remaining JSObject slots.
         computeEffectiveAddress(Address(obj, dataOffset), temp);
         storePtr(temp, Address(obj, dataSlotOffset));
 
         // Write enough zero pointers into fixed data to zero every
         // element.  (This zeroes past the end of a byte count that's
@@ -1092,17 +1111,18 @@ MacroAssembler::initTypedArraySlots(Regi
         // and we won't inline unless the desired memory fits in that
         // space.)
         static_assert(sizeof(HeapSlot) == 8, "Assumed 8 bytes alignment");
 
         size_t numZeroPointers = ((nbytes + 7) & ~0x7) / sizeof(char *);
         for (size_t i = 0; i < numZeroPointers; i++)
             storePtr(ImmWord(0), Address(obj, dataOffset + i * sizeof(char *)));
     } else {
-        move32(Imm32(length), lengthReg);
+        if (lengthKind == TypedArrayLength::Fixed)
+            move32(Imm32(length), lengthReg);
 
         // Allocate a buffer on the heap to store the data elements.
         liveRegs.addUnchecked(temp);
         liveRegs.addUnchecked(obj);
         liveRegs.addUnchecked(lengthReg);
         PushRegsInMask(liveRegs);
         setupUnalignedABICall(temp);
         loadJSContext(temp);
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -30,16 +30,17 @@
 # error "Unknown architecture!"
 #endif
 #include "jit/AtomicOp.h"
 #include "jit/IonInstrumentation.h"
 #include "jit/JitCompartment.h"
 #include "jit/VMFunctions.h"
 #include "vm/ProxyObject.h"
 #include "vm/Shape.h"
+#include "vm/TypedArrayObject.h"
 #include "vm/UnboxedObject.h"
 
 using mozilla::FloatingPoint;
 
 // * How to read/write MacroAssembler method declarations:
 //
 // The following macros are made to avoid #ifdef around each method declarations
 // of the Macro Assembler, and they are also used as an hint on the location of
@@ -1638,17 +1639,17 @@ class MacroAssembler : public MacroAssem
     void createGCObject(Register result, Register temp, JSObject* templateObj,
                         gc::InitialHeap initialHeap, Label* fail, bool initContents = true,
                         bool convertDoubleElements = false);
 
     void initGCThing(Register obj, Register temp, JSObject* templateObj,
                      bool initContents = true, bool convertDoubleElements = false);
     void initTypedArraySlots(Register obj, Register temp, Register lengthReg,
                              LiveRegisterSet liveRegs, Label* fail,
-                             TypedArrayObject* templateObj);
+                             TypedArrayObject* templateObj, TypedArrayLength lengthKind);
 
     void initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject);
 
     void newGCString(Register result, Register temp, Label* fail);
     void newGCFatInlineString(Register result, Register temp, Label* fail);
 
     // Compares two strings for equality based on the JSOP.
     // This checks for identical pointers, atoms and length and fails for everything else.
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -1080,16 +1080,38 @@ class LNewTypedArray : public LInstructi
         return getTemp(1);
     }
 
     MNewTypedArray* mir() const {
         return mir_->toNewTypedArray();
     }
 };
 
+class LNewTypedArrayDynamicLength : public LInstructionHelper<1, 1, 1>
+{
+  public:
+    LIR_HEADER(NewTypedArrayDynamicLength)
+
+    explicit LNewTypedArrayDynamicLength(const LAllocation& length, const LDefinition& temp) {
+        setOperand(0, length);
+        setTemp(0, temp);
+    }
+
+    const LAllocation* length() {
+        return getOperand(0);
+    }
+    const LDefinition* temp() {
+        return getTemp(0);
+    }
+
+    MNewTypedArrayDynamicLength* mir() const {
+        return mir_->toNewTypedArrayDynamicLength();
+    }
+};
+
 class LNewObject : public LInstructionHelper<1, 0, 1>
 {
   public:
     LIR_HEADER(NewObject)
 
     explicit LNewObject(const LDefinition& temp) {
         setTemp(0, temp);
     }
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -63,16 +63,17 @@
     _(IsConstructing)               \
     _(TableSwitch)                  \
     _(TableSwitchV)                 \
     _(Goto)                         \
     _(NewArray)                     \
     _(NewArrayCopyOnWrite)          \
     _(NewArrayDynamicLength)        \
     _(NewTypedArray)                \
+    _(NewTypedArrayDynamicLength)   \
     _(ArraySplice)                  \
     _(NewObject)                    \
     _(NewTypedObject)               \
     _(NewDeclEnvObject)             \
     _(NewCallObject)                \
     _(NewSingletonCallObject)       \
     _(NewStringObject)              \
     _(NewDerivedTypedObject)        \
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -1045,18 +1045,16 @@ if test "$HAVE_64BIT_BUILD" ; then
 else
     AC_DEFINE(JS_NUNBOX32)
 fi
 
 MOZ_ARG_DISABLE_BOOL(ion,
 [  --disable-ion      Disable use of the IonMonkey JIT],
   ENABLE_ION= )
 
-AC_SUBST(ENABLE_METHODJIT_SPEW)
-
 AC_SUBST(ENABLE_ION)
 
 if test -n "$COMPILE_ENVIRONMENT"; then
     MOZ_COMPILER_OPTS
 fi
 
 if test -z "$SKIP_COMPILER_CHECKS"; then
 dnl Checks for typedefs, structures, and compiler characteristics.
@@ -1657,20 +1655,16 @@ MOZ_ARG_HEADER(Individual module options
 
 dnl ========================================================
 dnl =
 dnl = Debugging Options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Debugging and Optimizations)
 
-if test "$ENABLE_METHODJIT_SPEW"; then
-    AC_DEFINE(JS_METHODJIT_SPEW)
-fi
-
 dnl ========================================================
 dnl = Enable code optimization. ON by default.
 dnl ========================================================
 if test -z "$MOZ_OPTIMIZE_FLAGS"; then
 	MOZ_OPTIMIZE_FLAGS="-O"
 fi
 
 MOZ_ARG_ENABLE_STRING(optimize,
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -249,17 +249,17 @@ AllocateArrayBufferContents(JSContext* c
     return ArrayBufferObject::BufferContents::create<ArrayBufferObject::PLAIN>(p);
 }
 
 static void
 NoteViewBufferWasDetached(ArrayBufferViewObject* view,
                           ArrayBufferObject::BufferContents newContents,
                           JSContext* cx)
 {
-    view->notifyBufferDetached(newContents.data());
+    view->notifyBufferDetached(cx, newContents.data());
 
     // Notify compiled jit code that the base pointer has moved.
     MarkObjectStateChange(cx, view);
 }
 
 /* static */ bool
 ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
                           BufferContents newContents)
@@ -1074,25 +1074,25 @@ JSObject::is<js::ArrayBufferViewObject>(
 template <>
 bool
 JSObject::is<js::ArrayBufferObjectMaybeShared>() const
 {
     return is<ArrayBufferObject>() || is<SharedArrayBufferObject>();
 }
 
 void
-ArrayBufferViewObject::notifyBufferDetached(void* newData)
+ArrayBufferViewObject::notifyBufferDetached(JSContext* cx, void* newData)
 {
     MOZ_ASSERT(newData != nullptr);
     if (is<DataViewObject>()) {
         as<DataViewObject>().notifyBufferDetached(newData);
     } else if (is<TypedArrayObject>()) {
         if (as<TypedArrayObject>().isSharedMemory())
             return;
-        as<TypedArrayObject>().notifyBufferDetached(newData);
+        as<TypedArrayObject>().notifyBufferDetached(cx, newData);
     } else {
         as<OutlineTypedObject>().notifyBufferDetached(newData);
     }
 }
 
 uint8_t*
 ArrayBufferViewObject::dataPointerUnshared()
 {
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -383,17 +383,17 @@ typedef MutableHandle<ArrayBufferObject*
  * Common definitions shared by all array buffer views.
  */
 
 class ArrayBufferViewObject : public JSObject
 {
   public:
     static ArrayBufferObjectMaybeShared* bufferObject(JSContext* cx, Handle<ArrayBufferViewObject*> obj);
 
-    void notifyBufferDetached(void* newData);
+    void notifyBufferDetached(JSContext* cx, void* newData);
 
 #ifdef DEBUG
     bool isSharedMemory();
 #endif
 
     // By construction we only need unshared variants here.  See
     // comments in ArrayBufferObject.cpp.
     uint8_t* dataPointerUnshared();
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -38,16 +38,17 @@
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/SelfHosting.h"
 #include "vm/TypedArrayCommon.h"
 #include "vm/WrapperObject.h"
 
 #include "jsatominlines.h"
 
+#include "gc/Nursery-inl.h"
 #include "gc/StoreBuffer-inl.h"
 #include "vm/ArrayBufferObject-inl.h"
 #include "vm/NativeObject-inl.h"
 #include "vm/Shape-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
@@ -72,21 +73,29 @@ TypedArrayObject::lengthOffset()
 
 /* static */ int
 TypedArrayObject::dataOffset()
 {
     return NativeObject::getPrivateDataOffset(DATA_SLOT);
 }
 
 void
-TypedArrayObject::notifyBufferDetached(void* newData)
+TypedArrayObject::notifyBufferDetached(JSContext* cx, void* newData)
 {
     MOZ_ASSERT(!isSharedMemory());
     setFixedSlot(TypedArrayObject::LENGTH_SLOT, Int32Value(0));
     setFixedSlot(TypedArrayObject::BYTEOFFSET_SLOT, Int32Value(0));
+
+    // Free the data slot pointer if has no inline data
+    Nursery& nursery = cx->runtime()->gc.nursery;
+    if (!hasBuffer() && !hasInlineElements() && !nursery.isInside(elements())) {
+        nursery.removeMallocedBuffer(elements());
+        js_free(elements());
+    }
+
     setPrivate(newData);
 }
 
 /* static */ bool
 TypedArrayObject::is(HandleValue v)
 {
     return v.isObject() && v.toObject().is<TypedArrayObject>();
 }
@@ -101,16 +110,24 @@ TypedArrayObject::ensureHasBuffer(JSCont
     if (!buffer)
         return false;
 
     if (!buffer->addView(cx, tarray))
         return false;
 
     // tarray is not shared, because if it were it would have a buffer.
     memcpy(buffer->dataPointer(), tarray->viewDataUnshared(), tarray->byteLength());
+
+    // Free the data slot pointer if has no inline data
+    Nursery& nursery = cx->runtime()->gc.nursery;
+    if (!tarray->hasInlineElements() && !nursery.isInside(tarray->elements())) {
+        nursery.removeMallocedBuffer(tarray->elements());
+        js_free(tarray->elements());
+    }
+
     tarray->setPrivate(buffer->dataPointer());
 
     tarray->setFixedSlot(TypedArrayObject::BUFFER_SLOT, ObjectValue(*buffer));
 
     // Notify compiled jit code that the base pointer has moved.
     MarkObjectStateChange(cx, tarray);
 
     return true;
@@ -129,18 +146,18 @@ TypedArrayObject::finalize(FreeOp* fop, 
     MOZ_ASSERT(!IsInsideNursery(obj));
     TypedArrayObject* curObj = &obj->as<TypedArrayObject>();
 
     // Typed arrays with a buffer object do not need to be free'd
     if (curObj->hasBuffer())
         return;
 
     // Free the data slot pointer if it does not point into the old JSObject.
-    if (!curObj->hasInlineElements()) {
-        MOZ_ASSERT(!fop->runtime()->gc.nursery.isInside(curObj->elements()));
+    Nursery& nursery = fop->runtime()->gc.nursery;
+    if (!curObj->hasInlineElements() && !nursery.isInside(curObj->elements())) {
         js_free(curObj->elements());
     }
 }
 
 /* static */ void
 TypedArrayObject::objectMoved(JSObject* obj, const JSObject* old)
 {
     TypedArrayObject* newObj = &obj->as<TypedArrayObject>();
@@ -157,16 +174,17 @@ TypedArrayObject::objectMoved(JSObject* 
 
 /* static */ size_t
 TypedArrayObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* obj, const JSObject* old,
                                            gc::AllocKind newAllocKind)
 {
     TypedArrayObject* newObj = &obj->as<TypedArrayObject>();
     const TypedArrayObject* oldObj = &old->as<TypedArrayObject>();
     MOZ_ASSERT(newObj->elements() == oldObj->elements());
+    MOZ_ASSERT(obj->isTenured());
 
     // Typed arrays with a buffer object do not need an update.
     if (oldObj->hasBuffer())
         return 0;
 
     Nursery& nursery = trc->runtime()->gc.nursery;
     void* buf = oldObj->elements();
 
@@ -189,19 +207,21 @@ JS_FOR_EACH_TYPED_ARRAY(OBJECT_MOVED_TYP
       default:
         MOZ_CRASH("Unsupported TypedArray type");
     }
 
     if (dataOffset() + nbytes <= GetGCKindBytes(newAllocKind)) {
         newObj->setInlineElements();
     } else {
         AutoEnterOOMUnsafeRegion oomUnsafe;
-        uint8_t* data = newObj->zone()->pod_malloc<uint8_t>(nbytes);
+        nbytes = JS_ROUNDUP(nbytes, sizeof(Value));
+        void* data = newObj->zone()->pod_malloc<uint8_t>(nbytes);
         if (!data)
             oomUnsafe.crash("Failed to allocate typed array elements while tenuring.");
+        MOZ_ASSERT(!nursery.isInside(data));
         newObj->initPrivate(data);
     }
 
     mozilla::PodCopy(newObj->elements(), oldObj->elements(), nbytes);
 
     // Set a forwarding pointer for the element buffers in case they were
     // preserved on the stack by Ion.
     nursery.maybeSetForwardingPointer(trc, oldObj->elements(), newObj->elements(), true);
@@ -558,97 +578,91 @@ class TypedArrayObjectTemplate : public 
             return nullptr;
         }
 
         TypedArrayObject* tarray = &tmp->as<TypedArrayObject>();
         // Template objects do not need memory for its elements, since there
         // won't be any elements to store. Therefore, we set the pointer to the
         // inline data and avoid allocating memory that will never be used.
         void* buf = tarray->fixedData(FIXED_DATA_START);
-        initTypedArraySlots(tarray, len, buf, allocKind);
+        initTypedArraySlots(cx, tarray, len, buf, allocKind);
 
         return tarray;
     }
 
     static void
-    initTypedArraySlots(TypedArrayObject* tarray, uint32_t len, void* buf,
-                        AllocKind allocKind)
+    initTypedArraySlots(JSContext* cx, TypedArrayObject* tarray, uint32_t len,
+                        void* buf, AllocKind allocKind)
     {
         tarray->setFixedSlot(TypedArrayObject::BUFFER_SLOT, NullValue());
         tarray->setFixedSlot(TypedArrayObject::LENGTH_SLOT, Int32Value(AssertedCast<int32_t>(len)));
         tarray->setFixedSlot(TypedArrayObject::BYTEOFFSET_SLOT, Int32Value(0));
 
         // Verify that the private slot is at the expected place.
         MOZ_ASSERT(tarray->numFixedSlots() == TypedArrayObject::DATA_SLOT);
 
         if (buf) {
+#ifdef DEBUG
+            Nursery& nursery = cx->runtime()->gc.nursery;
+            MOZ_ASSERT_IF(!nursery.isInside(buf) && !tarray->hasInlineElements(),
+                          tarray->isTenured());
+#endif
             tarray->initPrivate(buf);
         } else {
             size_t nbytes = len * sizeof(NativeType);
 #ifdef DEBUG
             size_t dataOffset = TypedArrayObject::dataOffset();
             size_t offset = dataOffset + sizeof(HeapSlot);
             MOZ_ASSERT(offset + nbytes <= GetGCKindBytes(allocKind));
 #endif
 
             void* data = tarray->fixedData(FIXED_DATA_START);
             tarray->initPrivate(data);
             memset(data, 0, nbytes);
         }
     }
 
-    static void*
-    allocateTypedArrayElementsBuffer(JSContext* cx, uint32_t len)
-    {
-        if (len == 0)
-            return nullptr;
-
-        void* buf = cx->runtime()->pod_callocCanGC<HeapSlot>(len);
-        if (!buf) {
-            ReportOutOfMemory(cx);
-            return nullptr;
-        }
-        return buf;
-    }
-
     static TypedArrayObject*
     makeTypedArrayWithTemplate(JSContext* cx, TypedArrayObject* templateObj, uint32_t len)
     {
         size_t nbytes;
         if (!js::CalculateAllocSize<NativeType>(len, &nbytes))
             return nullptr;
 
-        MOZ_ASSERT(nbytes < TypedArrayObject::SINGLETON_BYTE_LENGTH);
         bool fitsInline = nbytes <= INLINE_BUFFER_LIMIT;
 
         AutoSetNewObjectMetadata metadata(cx);
 
         const Class* clasp = templateObj->group()->clasp();
         gc::AllocKind allocKind = !fitsInline
                                   ? GetGCObjectKind(clasp)
                                   : AllocKindForLazyBuffer(len * sizeof(NativeType));
         MOZ_ASSERT(CanBeFinalizedInBackground(allocKind, clasp));
         allocKind = GetBackgroundAllocKind(allocKind);
         RootedObjectGroup group(cx, templateObj->group());
 
-        NewObjectKind newKind = GenericObject;
+        NewObjectKind newKind = TenuredObject;
 
         ScopedJSFreePtr<void> buf;
-        if (!fitsInline) {
-            buf = allocateTypedArrayElementsBuffer(cx, len);
-            if (!buf)
+        if (!fitsInline && len > 0) {
+            buf = cx->zone()->pod_malloc<uint8_t>(nbytes);
+            if (!buf) {
+                ReportOutOfMemory(cx);
                 return nullptr;
-        }
+            }
+
+            memset(buf, 0, nbytes);
+         }
 
         RootedObject tmp(cx, NewObjectWithGroup<TypedArrayObject>(cx, group, allocKind, newKind));
         if (!tmp)
             return nullptr;
 
         TypedArrayObject* obj = &tmp->as<TypedArrayObject>();
-        initTypedArraySlots(obj, len, buf.forget(), allocKind);
+        initTypedArraySlots(cx, obj, len, buf.forget(), allocKind);
 
         return obj;
     }
 
     /*
      * new [Type]Array(length)
      * new [Type]Array(otherTypedArray)
      * new [Type]Array(JSArray)
@@ -1246,21 +1260,21 @@ TypedArrayConstructor(JSContext* cx, uns
 /* static */ bool
 TypedArrayObject::GetTemplateObjectForNative(JSContext* cx, Native native, uint32_t len,
                                              MutableHandleObject res)
 {
 #define CHECK_TYPED_ARRAY_CONSTRUCTOR(T, N) \
     if (native == &TypedArrayObjectTemplate<T>::class_constructor) { \
         size_t nbytes; \
         if (!js::CalculateAllocSize<T>(len, &nbytes)) \
-            return false; \
+            return true; \
         \
         if (nbytes < TypedArrayObject::SINGLETON_BYTE_LENGTH) { \
             res.set(TypedArrayObjectTemplate<T>::makeTemplateObject(cx, len)); \
-            return !!res; \
+            return true; \
         } \
     }
 JS_FOR_EACH_TYPED_ARRAY(CHECK_TYPED_ARRAY_CONSTRUCTOR)
 #undef CHECK_TYPED_ARRAY_CONSTRUCTOR
     return false;
 }
 
 /*
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -26,16 +26,18 @@
     macro(float, Float32) \
     macro(double, Float64) \
     macro(uint8_clamped, Uint8Clamped)
 
 typedef struct JSProperty JSProperty;
 
 namespace js {
 
+enum class TypedArrayLength { Fixed, Dynamic };
+
 /*
  * TypedArrayObject
  *
  * The non-templated base class for the specific typed implementations.
  * This class holds all the member variables that are used by
  * the subclasses.
  */
 
@@ -165,17 +167,17 @@ class TypedArrayObject : public NativeOb
     void setInlineElements();
     uint8_t* elements() const {
         return *(uint8_t **)((((char *)this) + this->dataOffset()));
     }
 
     Value getElement(uint32_t index);
     static void setElement(TypedArrayObject& obj, uint32_t index, double d);
 
-    void notifyBufferDetached(void* newData);
+    void notifyBufferDetached(JSContext* cx, void* newData);
 
     static bool
     GetTemplateObjectForNative(JSContext* cx, Native native, uint32_t len,
                                MutableHandleObject res);
 
     /*
      * Byte length above which created typed arrays and data views will have
      * singleton types regardless of the context in which they are created.
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -3696,17 +3696,17 @@ ContainerState::ComputeOpaqueRect(nsDisp
         RelativeTo::ScrollFrame);
     if (!usingDisplayport) {
       // No async scrolling, so all that matters is that the layer contents
       // cover the scrollport.
       displayport = sf->GetScrollPortRect();
     }
     nsIFrame* scrollFrame = do_QueryFrame(sf);
     displayport += scrollFrame->GetOffsetToCrossDoc(mContainerReferenceFrame);
-    if (opaque.Contains(displayport)) {
+    if (opaquePixels.Contains(ScaleRegionToNearestPixels(displayport))) {
       *aOpaqueForAnimatedGeometryRootParent = true;
     }
   }
   return opaquePixels;
 }
 
 static const DisplayItemScrollClip*
 InnermostScrollClipApplicableToAGR(const DisplayItemScrollClip* aItemScrollClip,
@@ -4701,17 +4701,17 @@ FrameLayerBuilder::CheckInLayerTreeCompr
 }
 
 void
 ContainerState::CollectOldLayers()
 {
   for (Layer* layer = mContainerLayer->GetFirstChild(); layer;
        layer = layer->GetNextSibling()) {
     NS_ASSERTION(!layer->HasUserData(&gMaskLayerUserData),
-                 "Mask layer in layer tree; could not be recycled.");
+                 "Mask layers should not be part of the layer tree.");
     if (layer->HasUserData(&gPaintedDisplayItemLayerUserData)) {
       NS_ASSERTION(layer->AsPaintedLayer(), "Wrong layer type");
       mPaintedLayersAvailableForRecycling.PutEntry(static_cast<PaintedLayer*>(layer));
     }
 
     if (Layer* maskLayer = layer->GetMaskLayer()) {
       NS_ASSERTION(maskLayer->GetType() == Layer::TYPE_IMAGE,
                    "Could not recycle mask layer, unsupported layer type.");
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -165,16 +165,19 @@ typedef nsStyleTransformMatrix::Transfor
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationMaxRatio;
 /* static */ bool nsLayoutUtils::sFontSizeInflationForceEnabled;
 /* static */ bool nsLayoutUtils::sFontSizeInflationDisabledInMasterProcess;
 /* static */ bool nsLayoutUtils::sInvalidationDebuggingIsEnabled;
 /* static */ bool nsLayoutUtils::sCSSVariablesEnabled;
 /* static */ bool nsLayoutUtils::sInterruptibleReflowEnabled;
 /* static */ bool nsLayoutUtils::sSVGTransformBoxEnabled;
 /* static */ bool nsLayoutUtils::sTextCombineUprightDigitsEnabled;
+#ifdef MOZ_STYLO
+/* static */ bool nsLayoutUtils::sStyloEnabled;
+#endif
 
 static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID;
 
 typedef nsDataHashtable<nsUint64HashKey, nsIContent*> ContentMap;
 static ContentMap* sContentMap = nullptr;
 static ContentMap& GetContentMap() {
   if (!sContentMap) {
     sContentMap = new ContentMap();
@@ -7835,16 +7838,20 @@ nsLayoutUtils::Initialize()
   Preferences::AddBoolVarCache(&sCSSVariablesEnabled,
                                "layout.css.variables.enabled");
   Preferences::AddBoolVarCache(&sInterruptibleReflowEnabled,
                                "layout.interruptible-reflow.enabled");
   Preferences::AddBoolVarCache(&sSVGTransformBoxEnabled,
                                "svg.transform-box.enabled");
   Preferences::AddBoolVarCache(&sTextCombineUprightDigitsEnabled,
                                "layout.css.text-combine-upright-digits.enabled");
+#ifdef MOZ_STYLO
+  Preferences::AddBoolVarCache(&sStyloEnabled,
+                               "layout.css.servo.enabled");
+#endif
 
   for (auto& callback : kPrefCallbacks) {
     Preferences::RegisterCallbackAndCall(callback.func, callback.name);
   }
   nsComputedDOMStyle::RegisterPrefChangeCallbacks();
 }
 
 /* static */
@@ -9332,12 +9339,12 @@ nsLayoutUtils::GetCumulativeApzCallbackT
     content = frame ? frame->GetContent() : nullptr;
   }
   return delta;
 }
 
 /* static */ bool
 nsLayoutUtils::SupportsServoStyleBackend(nsIDocument* aDocument)
 {
-  return nsPresContext::StyloEnabled() &&
+  return StyloEnabled() &&
          aDocument->IsHTMLOrXHTML() &&
          static_cast<nsDocument*>(aDocument)->IsContentDocument();
 }
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2416,16 +2416,27 @@ public:
   static bool SVGTransformBoxEnabled() {
     return sSVGTransformBoxEnabled;
   }
 
   static bool TextCombineUprightDigitsEnabled() {
     return sTextCombineUprightDigitsEnabled;
   }
 
+  // Stylo (the Servo backend for Gecko's style system) is generally enabled
+  // or disabled at compile-time. However, we provide the additional capability
+  // to disable it dynamically in stylo-enabled builds via a pref.
+  static bool StyloEnabled() {
+#ifdef MOZ_STYLO
+    return sStyloEnabled;
+#else
+    return false;
+#endif
+  }
+
   /**
    * See comment above "font.size.inflation.mappingIntercept" in
    * modules/libpref/src/init/all.js .
    */
   static int32_t FontSizeInflationMappingIntercept() {
     return sFontSizeInflationMappingIntercept;
   }
 
@@ -2856,16 +2867,19 @@ private:
   static uint32_t sFontSizeInflationMaxRatio;
   static bool sFontSizeInflationForceEnabled;
   static bool sFontSizeInflationDisabledInMasterProcess;
   static bool sInvalidationDebuggingIsEnabled;
   static bool sCSSVariablesEnabled;
   static bool sInterruptibleReflowEnabled;
   static bool sSVGTransformBoxEnabled;
   static bool sTextCombineUprightDigitsEnabled;
+#ifdef MOZ_STYLO
+  static bool sStyloEnabled;
+#endif
 
   /**
    * Helper function for LogTestDataForPaint().
    */
   static void DoLogTestDataForPaint(mozilla::layers::LayerManager* aManager,
                                     ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue);
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1101,30 +1101,16 @@ public:
   bool HasWarnedAboutTooLargeDashedOrDottedRadius() const {
     return mHasWarnedAboutTooLargeDashedOrDottedRadius;
   }
 
   void SetHasWarnedAboutTooLargeDashedOrDottedRadius() {
     mHasWarnedAboutTooLargeDashedOrDottedRadius = true;
   }
 
-  static bool StyloEnabled()
-  {
-    // Stylo (the Servo backend for Gecko's style system) is generally enabled
-    // or disabled at compile-time. However, we provide the additional capability
-    // to disable it dynamically in stylo-enabled builds via an environmental
-    // variable.
-#ifdef MOZ_STYLO
-    static bool disabled = PR_GetEnv("MOZ_DISABLE_STYLO");
-    return !disabled;
-#else
-    return false;
-#endif
-  }
-
 protected:
   friend class nsRunnableMethod<nsPresContext>;
   void ThemeChangedInternal();
   void SysColorChangedInternal();
 
   // update device context's resolution from the widget
   void UIResolutionChangedInternal();
 
--- a/layout/base/tests/bug1082486-1.html
+++ b/layout/base/tests/bug1082486-1.html
@@ -6,15 +6,24 @@
      /* Eliminate the blue glow when focusing the element. */
      input {
        background: none;
        border: none;
        outline: none;
      }
      </style>
   </head>
-  <body onload="document.getElementById('i').focus();">
+  <body onload="focusInput();">
+    <script>
+      function focusInput() {
+        var inp = document.getElementById('i');
+        inp.selectionStart = 0;
+        inp.selectionEnd = 0;
+        inp.focus();
+      }
+    </script>
+
     <a target="_blank" href="https://bugzil.la/1082486">Mozilla Bug 1082486</a>
 
     <!-- The caret will not be seen when the input is focused. -->
     <input id='i' value="abcdefghd" style="text-indent: -10px">
   </body>
 </html>
--- a/layout/base/tests/bug646382-1-ref.html
+++ b/layout/base/tests/bug646382-1-ref.html
@@ -2,16 +2,18 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   </head>
   <body onload="start()">
     <textarea onfocus="done()" style="-moz-appearance: none">س</textarea>
     <script>
       var textarea = document.querySelector("textarea");
       function start() {
+        textarea.selectionStart = 0;
+        textarea.selectionEnd = 0;
         textarea.focus();
       }
       function done() {
         document.documentElement.removeAttribute("class");
       }
     </script>
   </body>
 </html>
--- a/layout/base/tests/bug646382-2-ref.html
+++ b/layout/base/tests/bug646382-2-ref.html
@@ -1,14 +1,16 @@
 <html class="reftest-wait">
   <body onload="start()">
     <textarea dir="rtl" onfocus="done()" style="-moz-appearance: none">s</textarea>
     <script>
       var textarea = document.querySelector("textarea");
       function start() {
+        textarea.selectionStart = 0;
+        textarea.selectionEnd = 0;
         textarea.focus();
       }
       function done() {
         document.documentElement.removeAttribute("class");
       }
     </script>
   </body>
 </html>
--- a/layout/base/tests/bug664087-1-ref.html
+++ b/layout/base/tests/bug664087-1-ref.html
@@ -4,16 +4,18 @@
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   </head>
   <body onload="start()">
     <textarea rows="3" onfocus="done()" spellcheck="false" style="-moz-appearance: none">אב
 ג</textarea>
     <script>
       var textarea = document.querySelector("textarea");
       function start() {
+        textarea.selectionStart = 0;
+        textarea.selectionEnd = 0;
         textarea.focus();
       }
       function done() {
         synthesizeKey("VK_LEFT", {});
         synthesizeKey("VK_LEFT", {});
         document.documentElement.removeAttribute("class");
       }
     </script>
--- a/layout/base/tests/bug664087-2-ref.html
+++ b/layout/base/tests/bug664087-2-ref.html
@@ -4,16 +4,18 @@
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   </head>
   <body onload="start()">
     <textarea dir="rtl" onfocus="done()" spellcheck="false" style="-moz-appearance: none">ab
 c</textarea>
     <script>
       var textarea = document.querySelector("textarea");
       function start() {
+        textarea.selectionStart = 0;
+        textarea.selectionEnd = 0;
         textarea.focus();
       }
       function done() {
         synthesizeKey("VK_RIGHT", {});
         synthesizeKey("VK_RIGHT", {});
         document.documentElement.removeAttribute("class");
       }
     </script>
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -298,19 +298,23 @@ nsTextControlFrame::EnsureEditorInitiali
     nsresult rv = txtCtrl->CreateEditor();
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ENSURE_STATE(weakFrame.IsAlive());
 
     // Set mEditorHasBeenInitialized so that subsequent calls will use the
     // editor.
     mEditorHasBeenInitialized = true;
 
-    // Set the selection to the beginning of the text field.
+    nsAutoString val;
+    txtCtrl->GetTextEditorValue(val, true);
+    int32_t length = val.Length();
+
+    // Set the selection to the end of the text field. (bug 1287655)
     if (weakFrame.IsAlive()) {
-      SetSelectionEndPoints(0, 0);
+      SetSelectionEndPoints(length, length);
     }
   }
   NS_ENSURE_STATE(weakFrame.IsAlive());
   return NS_OK;
 }
 
 nsresult
 nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
@@ -421,17 +425,17 @@ nsTextControlFrame::AppendAnonymousConte
   nsIContent* root = txtCtrl->GetRootEditorNode();
   if (root) {
     aElements.AppendElement(root);
   }
 
   nsIContent* placeholder = txtCtrl->GetPlaceholderNode();
   if (placeholder && !(aFilter & nsIContent::eSkipPlaceholderContent))
     aElements.AppendElement(placeholder);
-  
+
 }
 
 nscoord
 nsTextControlFrame::GetPrefISize(nsRenderingContext* aRenderingContext)
 {
     DebugOnly<nscoord> result = 0;
     DISPLAY_PREF_WIDTH(this, result);
 
@@ -922,49 +926,49 @@ nsTextControlFrame::SetSelectionRange(in
 
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionStart(int32_t aSelectionStart)
 {
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  int32_t selStart = 0, selEnd = 0; 
+  int32_t selStart = 0, selEnd = 0;
 
   rv = GetSelectionRange(&selStart, &selEnd);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aSelectionStart > selEnd) {
     // Collapse to the new start point.
-    selEnd = aSelectionStart; 
+    selEnd = aSelectionStart;
   }
 
   selStart = aSelectionStart;
-  
+
   return SetSelectionEndPoints(selStart, selEnd);
 }
 
 NS_IMETHODIMP
 nsTextControlFrame::SetSelectionEnd(int32_t aSelectionEnd)
 {
   nsresult rv = EnsureEditorInitialized();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  int32_t selStart = 0, selEnd = 0; 
+  int32_t selStart = 0, selEnd = 0;
 
   rv = GetSelectionRange(&selStart, &selEnd);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aSelectionEnd < selStart) {
     // Collapse to the new end point.
-    selStart = aSelectionEnd; 
+    selStart = aSelectionEnd;
   }
 
   selEnd = aSelectionEnd;
-  
+
   return SetSelectionEndPoints(selStart, selEnd);
 }
 
 nsresult
 nsTextControlFrame::OffsetToDOMPoint(int32_t aOffset,
                                      nsIDOMNode** aResult,
                                      int32_t* aPosition)
 {
@@ -1041,17 +1045,17 @@ nsTextControlFrame::GetSelectionRange(in
     *aDirection = eNone;
   }
 
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
   nsISelectionController* selCon = txtCtrl->GetSelectionController();
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
   nsCOMPtr<nsISelection> selection;
-  rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
+  rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
   dom::Selection* sel = selection->AsSelection();
   if (aDirection) {
     nsDirection direction = sel->GetSelectionDirection();
     if (direction == eDirNext) {
       *aDirection = eForward;
@@ -1180,17 +1184,17 @@ nsTextControlFrame::GetText(nsString& aT
   }
   return rv;
 }
 
 
 nsresult
 nsTextControlFrame::GetPhonetic(nsAString& aPhonetic)
 {
-  aPhonetic.Truncate(0); 
+  aPhonetic.Truncate(0);
 
   nsCOMPtr<nsIEditor> editor;
   nsresult rv = GetEditor(getter_AddRefs(editor));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIEditorIMESupport> imeSupport = do_QueryInterface(editor);
   if (imeSupport) {
     nsCOMPtr<nsIPhonetic> phonetic = do_QueryInterface(imeSupport);
--- a/layout/forms/test/bug287446_subframe.html
+++ b/layout/forms/test/bug287446_subframe.html
@@ -13,23 +13,23 @@
 
       window.addEventListener("message",
         function(evt) {
           var t = $("target");
           if (evt.data == "start") {
             doIs(t.value, "Test", "Shouldn't have lost our initial value");
             t.focus();
             sendString("Foo");
-            doIs(t.value, "FooTest", "Typing should work");
+            doIs(t.value, "TestFoo", "Typing should work");
             window.parent.postMessage("c", "*");
           } else {
             doIs(evt.data, "continue", "Unexpected message");
-            doIs(t.value, "FooTest", "Shouldn't have lost our typed value");
+            doIs(t.value, "TestFoo", "Shouldn't have lost our typed value");
             sendString("Bar");
-            doIs(t.value, "BarFooTest", "Typing should still work");
+            doIs(t.value, "TestFooBar", "Typing should still work");
             window.parent.postMessage("f", "*");
           }
         },
         "false");
       
     </script>
   </head>
   <body>
--- a/layout/forms/test/test_bug353539.html
+++ b/layout/forms/test/test_bug353539.html
@@ -33,16 +33,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 353539 **/
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function() {
   var area = document.getElementById("area");
 
   is(area.scrollTop, 0, "The textarea should not be scrolled initially");
+  area.selectionStart = 0;
+  area.selectionEnd = 0;
   area.focus();
   setTimeout(function() {
     is(area.scrollTop, 0, "The textarea's insertion point should not be scrolled into view");
 
     SimpleTest.finish();
   }, 0);
 });
 
--- a/layout/forms/test/test_bug534785.html
+++ b/layout/forms/test/test_bug534785.html
@@ -28,27 +28,27 @@ SimpleTest.waitForExplicitFinish();
 
 SimpleTest.waitForFocus(function() {
   var i = document.querySelector("input");
   i.addEventListener("focus", function() {
     is(i.value, "test", "Sanity check");
 
     is(document.activeElement, i, "Should be focused before frame reconstruction");
     synthesizeKey("1", {});
-    is(i.value, "1test", "Can accept keyboard events before frame reconstruction");
+    is(i.value, "test1", "Can accept keyboard events before frame reconstruction");
 
     // force frame reconstruction
     i.style.display = "none";
     document.offsetHeight;
     i.style.display = "";
     document.offsetHeight;
 
     is(document.activeElement, i, "Should be focused after frame reconstruction");
     synthesizeKey("2", {});
-    is(i.value, "12test", "Can accept keyboard events after frame reconstruction");
+    is(i.value, "test12", "Can accept keyboard events after frame reconstruction");
 
     // Make sure reframing happens gracefully
     var reframeDiv = document.getElementById("reframe");
     var textAreaWithoutValue = reframeDiv.querySelectorAll("textarea")[0];
     var textAreaWithValue = reframeDiv.querySelectorAll("textarea")[1];
     var inputWithoutValue = reframeDiv.querySelectorAll("input")[0];
     var inputWithValue = reframeDiv.querySelectorAll("input")[1];
     reframeDiv.style.display = "none";
--- a/layout/forms/test/test_bug542914.html
+++ b/layout/forms/test/test_bug542914.html
@@ -75,19 +75,19 @@ function runTests(callback, type) {
   document.body.offsetHeight;
 
   // Make sure dynamically injected inputs work as expected
   is(d.value, "", "Dynamic control's initial value should be empty");
   d.value = "new";
   d.focus();
   is(d.value, "new", "Dynamic control's value can be set before initialization");
   sendChar("x");
-  is(d.value, "xnew", "Dynamic control accepts keyboard input without explicit initialization");
+  is(d.value, "newx", "Dynamic control accepts keyboard input without explicit initialization");
   $("display").removeChild(d);
-  is(d.value, "xnew", "Dynamic control retains value after being removed from the document");
+  is(d.value, "newx", "Dynamic control retains value after being removed from the document");
 
   callback();
 }
 
 var gPreviousType = "text";
 function setTypes(aType) {
   var content = document.getElementById("display");
   content.innerHTML = content.innerHTML.replace(gPreviousType, aType);
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -385,18 +385,18 @@ nsHTMLScrollFrame::TryLayout(ScrollReflo
     compositionSize.width /= resolution;
     compositionSize.height /= resolution;
     visualScrollPortSize = nsSize(std::max(0, compositionSize.width - vScrollbarDesiredWidth),
                                   std::max(0, compositionSize.height - hScrollbarDesiredHeight));
   }
 
   if (!aForce) {
     nsRect scrolledRect =
-      mHelper.GetScrolledRectInternal(aState->mContentsOverflowAreas.ScrollableOverflow(),
-                                     scrollPortSize);
+      mHelper.GetUnsnappedScrolledRectInternal(aState->mContentsOverflowAreas.ScrollableOverflow(),
+                                               scrollPortSize);
     nscoord oneDevPixel = aState->mBoxState.PresContext()->DevPixelsToAppUnits(1);
 
     // If the style is HIDDEN then we already know that aAssumeHScroll is false
     if (aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
       bool wantHScrollbar =
         aState->mStyles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
         scrolledRect.XMost() >= visualScrollPortSize.width + oneDevPixel ||
         scrolledRect.x <= -oneDevPixel;
@@ -681,18 +681,18 @@ nsHTMLScrollFrame::ReflowContents(Scroll
   // where the ideal case doesn't have a scrollbar?
   if ((aState->mReflowedContentsWithHScrollbar || aState->mReflowedContentsWithVScrollbar) &&
       aState->mStyles.mVertical != NS_STYLE_OVERFLOW_SCROLL &&
       aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_SCROLL) {
     nsSize insideBorderSize =
       ComputeInsideBorderSize(aState,
                               nsSize(kidDesiredSize.Width(), kidDesiredSize.Height()));
     nsRect scrolledRect =
-      mHelper.GetScrolledRectInternal(kidDesiredSize.ScrollableOverflow(),
-                                     insideBorderSize);
+      mHelper.GetUnsnappedScrolledRectInternal(kidDesiredSize.ScrollableOverflow(),
+                                               insideBorderSize);
     if (nsRect(nsPoint(0, 0), insideBorderSize).Contains(scrolledRect)) {
       // Let's pretend we had no scrollbars coming in here
       ReflowScrolledFrame(aState, false, false, &kidDesiredSize, false);
     }
   }
 
   // Try vertical scrollbar settings that leave the vertical scrollbar unchanged.
   // Do this first because changing the vertical scrollbar setting is expensive,
@@ -733,18 +733,18 @@ nsHTMLScrollFrame::PlaceScrollArea(const
   nsIFrame *scrolledFrame = mHelper.mScrolledFrame;
   // Set the x,y of the scrolled frame to the correct value
   scrolledFrame->SetPosition(mHelper.mScrollPort.TopLeft() - aScrollPosition);
 
   nsRect scrolledArea;
   // Preserve the width or height of empty rects
   nsSize portSize = mHelper.mScrollPort.Size();
   nsRect scrolledRect =
-    mHelper.GetScrolledRectInternal(aState.mContentsOverflowAreas.ScrollableOverflow(),
-                                   portSize);
+    mHelper.GetUnsnappedScrolledRectInternal(aState.mContentsOverflowAreas.ScrollableOverflow(),
+                                             portSize);
   scrolledArea.UnionRectEdges(scrolledRect,
                               nsRect(nsPoint(0,0), portSize));
 
   // Store the new overflow area. Note that this changes where an outline
   // of the scrolled frame would be painted, but scrolled frames can't have
   // outlines (the outline would go on this scrollframe instead).
   // Using FinishAndStoreOverflow is needed so the overflow rect
   // gets set correctly.  It also messes with the overflow rect in the
@@ -3301,17 +3301,23 @@ ScrollFrameHelper::BuildDisplayList(nsDi
         if (mClipAllDescendants) {
           inactiveScrollClip = clipStateForScrollClip.InsertInactiveScrollClipForContentDescendants(aBuilder, sf);
         } else {
           inactiveScrollClip = clipStateForScrollClip.InsertInactiveScrollClipForContainingBlockDescendants(aBuilder, sf);
         }
         MOZ_ASSERT(!inactiveScrollClip->mIsAsyncScrollable);
       }
 
-      DisplayListClipState::AutoSaveRestore displayPortClipState(aBuilder);
+      // Clip our contents to the unsnapped scrolled rect. This makes sure that
+      // we don't have display items over the subpixel seam at the edge of the
+      // scrolled area.
+      DisplayListClipState::AutoSaveRestore scrolledRectClipState(aBuilder);
+      nsRect scrolledRectClip =
+        GetUnsnappedScrolledRectInternal(mScrolledFrame->GetScrollableOverflowRect(),
+                                         mScrollPort.Size()) + mScrolledFrame->GetPosition();
       if (usingDisplayPort) {
         // Clip the contents to the display port.
         // The dirty rect already acts kind of like a clip, in that
         // FrameLayerBuilder intersects item bounds and opaque regions with
         // it, but it doesn't have the consistent snapping behavior of a
         // true clip.
         // For a case where this makes a difference, imagine the following
         // scenario: The display port has an edge that falls on a fractional
@@ -3319,18 +3325,20 @@ ScrollFrameHelper::BuildDisplayList(nsDi
         // whole display port up until that fractional edge, and there is a
         // transparent display item that overlaps the edge. We want to prevent
         // this transparent item from enlarging the scrolled layer's visible
         // region beyond its opaque region. The dirty rect doesn't do that -
         // it gets rounded out, whereas a true clip gets rounded to nearest
         // pixels.
         // If there is no display port, we don't need this because the clip
         // from the scroll port is still applied.
-        displayPortClipState.ClipContainingBlockDescendants(dirtyRect + aBuilder->ToReferenceFrame(mOuter));
+        scrolledRectClip = scrolledRectClip.Intersect(dirtyRect);
       }
+      scrolledRectClipState.ClipContainingBlockDescendants(
+        scrolledRectClip + aBuilder->ToReferenceFrame(mOuter));
 
       mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
     }
 
     if (contentBoxClipForNonCaretContent) {
       DisplayListClipState::AutoSaveRestore contentBoxClipState(aBuilder);
       if (mClipAllDescendants) {
         contentBoxClipState.ClipContentDescendants(*contentBoxClipForNonCaretContent);
@@ -5561,53 +5569,112 @@ ScrollFrameHelper::GetBorderRadii(const 
     ReduceRadii(border.left, border.bottom,
                 aRadii[NS_CORNER_BOTTOM_LEFT_X],
                 aRadii[NS_CORNER_BOTTOM_LEFT_Y]);
   }
 
   return true;
 }
 
+static nscoord
+SnapCoord(nscoord aCoord, double aRes, nscoord aAppUnitsPerPixel)
+{
+  double snappedToLayerPixels = NS_round((aRes*aCoord)/aAppUnitsPerPixel);
+  return NSToCoordRoundWithClamp(snappedToLayerPixels*aAppUnitsPerPixel/aRes);
+}
+
 nsRect
 ScrollFrameHelper::GetScrolledRect() const
 {
   nsRect result =
-    GetScrolledRectInternal(mScrolledFrame->GetScrollableOverflowRect(),
-                            mScrollPort.Size());
+    GetUnsnappedScrolledRectInternal(mScrolledFrame->GetScrollableOverflowRect(),
+                                     mScrollPort.Size());
 
   if (result.width < mScrollPort.width) {
     NS_WARNING("Scrolled rect smaller than scrollport?");
   }
   if (result.height < mScrollPort.height) {
     NS_WARNING("Scrolled rect smaller than scrollport?");
   }
+
+  // Expand / contract the result by up to half a layer pixel so that scrolling
+  // to the right / bottom edge does not change the layer pixel alignment of
+  // the scrolled contents.
+  // For that, we first convert the scroll port and the scrolled rect to rects
+  // relative to the reference frame, since that's the space where painting does
+  // snapping.
+  nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
+  nsIFrame* referenceFrame = nsLayoutUtils::GetReferenceFrame(mOuter);
+  nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(referenceFrame);
+  nsRect scrollPort(mScrollPort.TopLeft() + toReferenceFrame, scrollPortSize);
+  nsRect scrolledRect = result + scrollPort.TopLeft();
+
+  if (scrollPort.Overflows() || scrolledRect.Overflows()) {
+    return result;
+  }
+
+  // Now, snap the bottom right corner of both of these rects.
+  // We snap to layer pixels, so we need to respect the layer's scale.
+  nscoord appUnitsPerDevPixel = mScrolledFrame->PresContext()->AppUnitsPerDevPixel();
+  gfxSize scale = FrameLayerBuilder::GetPaintedLayerScaleForFrame(mScrolledFrame);
+  if (scale.IsEmpty()) {
+    scale = gfxSize(1.0f, 1.0f);
+  }
+
+  // Compute bounds for the scroll position, and computed the snapped scrolled
+  // rect from the scroll position bounds.
+  nscoord snappedScrolledAreaBottom = SnapCoord(scrolledRect.YMost(), scale.height, appUnitsPerDevPixel);
+  nscoord snappedScrollPortBottom = SnapCoord(scrollPort.YMost(), scale.height, appUnitsPerDevPixel);
+  nscoord maximumScrollOffsetY = snappedScrolledAreaBottom - snappedScrollPortBottom;
+  result.SetBottomEdge(scrollPort.height + maximumScrollOffsetY);
+
+  if (GetScrolledFrameDir() == NS_STYLE_DIRECTION_LTR) {
+    nscoord snappedScrolledAreaRight = SnapCoord(scrolledRect.XMost(), scale.width, appUnitsPerDevPixel);
+    nscoord snappedScrollPortRight = SnapCoord(scrollPort.XMost(), scale.width, appUnitsPerDevPixel);
+    nscoord maximumScrollOffsetX = snappedScrolledAreaRight - snappedScrollPortRight;
+    result.SetRightEdge(scrollPort.width + maximumScrollOffsetX);
+  } else {
+    // In RTL, the scrolled area's right edge is at scrollPort.XMost(),
+    // and the scrolled area's x position is zero or negative. We want
+    // the right edge to stay flush with the scroll port, so we snap the
+    // left edge.
+    nscoord snappedScrolledAreaLeft = SnapCoord(scrolledRect.x, scale.width, appUnitsPerDevPixel);
+    nscoord snappedScrollPortLeft = SnapCoord(scrollPort.x, scale.width, appUnitsPerDevPixel);
+    nscoord minimumScrollOffsetX = snappedScrolledAreaLeft - snappedScrollPortLeft;
+    result.SetLeftEdge(minimumScrollOffsetX);
+  }
+
   return result;
 }
 
-nsRect
-ScrollFrameHelper::GetScrolledRectInternal(const nsRect& aScrolledFrameOverflowArea,
-                                               const nsSize& aScrollPortSize) const
-{
-  uint8_t frameDir = IsLTR() ? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
-
+
+uint8_t
+ScrollFrameHelper::GetScrolledFrameDir() const
+{
   // If the scrolled frame has unicode-bidi: plaintext, the paragraph
   // direction set by the text content overrides the direction of the frame
   if (mScrolledFrame->StyleTextReset()->mUnicodeBidi &
       NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
     nsIFrame* childFrame = mScrolledFrame->PrincipalChildList().FirstChild();
     if (childFrame) {
-      frameDir =
-        (nsBidiPresUtils::ParagraphDirection(childFrame) == NSBIDI_LTR)
+      return (nsBidiPresUtils::ParagraphDirection(childFrame) == NSBIDI_LTR)
           ? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
     }
   }
 
+  return IsLTR() ? NS_STYLE_DIRECTION_LTR : NS_STYLE_DIRECTION_RTL;
+}
+
+nsRect
+ScrollFrameHelper::GetUnsnappedScrolledRectInternal(const nsRect& aScrolledFrameOverflowArea,
+                                                    const nsSize& aScrollPortSize) const
+{
   return nsLayoutUtils::GetScrolledRect(mScrolledFrame,
                                         aScrolledFrameOverflowArea,
-                                        aScrollPortSize, frameDir);
+                                        aScrollPortSize, GetScrolledFrameDir());
 }
 
 nsMargin
 ScrollFrameHelper::GetActualScrollbarSizes() const
 {
   nsRect r = mOuter->GetPaddingRect() - mOuter->GetPosition();
 
   return nsMargin(mScrollPort.y - r.y,
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -303,28 +303,28 @@ public:
    * Currently it allows scrolling down and to the right for
    * nsHTMLScrollFrames with LTR directionality and for all
    * nsXULScrollFrames, and allows scrolling down and to the left for
    * nsHTMLScrollFrames with RTL directionality.
    */
   nsRect GetScrolledRect() const;
 
   /**
-   * GetScrolledRectInternal is designed to encapsulate deciding which
+   * GetUnsnappedScrolledRectInternal is designed to encapsulate deciding which
    * directions of overflow should be reachable by scrolling and which
    * should not.  Callers should NOT depend on it having any particular
    * behavior (although nsXULScrollFrame currently does).
    * 
    * Currently it allows scrolling down and to the right for
    * nsHTMLScrollFrames with LTR directionality and for all
    * nsXULScrollFrames, and allows scrolling down and to the left for
    * nsHTMLScrollFrames with RTL directionality.
    */
-  nsRect GetScrolledRectInternal(const nsRect& aScrolledOverflowArea,
-                                 const nsSize& aScrollPortSize) const;
+  nsRect GetUnsnappedScrolledRectInternal(const nsRect& aScrolledOverflowArea,
+                                          const nsSize& aScrollPortSize) const;
 
   uint32_t GetScrollbarVisibility() const {
     return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) |
            (mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0);
   }
   nsMargin GetActualScrollbarSizes() const;
   nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
   nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState,
@@ -617,16 +617,17 @@ protected:
                           nsIScrollbarMediator::ScrollSnapMode aSnap
                             = nsIScrollbarMediator::DISABLE_SNAP);
 
   void CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin = nullptr);
 
   bool HasPluginFrames();
   bool HasPerspective() const;
   bool HasBgAttachmentLocal() const;
+  uint8_t GetScrolledFrameDir() const;
 
   static void EnsureFrameVisPrefsCached();
   static bool sFrameVisPrefsCached;
   // The number of scrollports wide/high to expand when tracking frame visibility.
   static uint32_t sHorzExpandScrollPort;
   static uint32_t sVertExpandScrollPort;
   // The fraction of the scrollport we allow to scroll by before we schedule
   // an update of frame visibility.
--- a/layout/generic/test/test_bug784410.html
+++ b/layout/generic/test/test_bug784410.html
@@ -4,17 +4,17 @@
   <title>Test bug 784410</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script src="/tests/SimpleTest/paint_listener.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
-<div id="outer" style="overflow:auto; height:200px; border:2px dotted black;" onscroll="doneScroll()">
+<div id="outer" style="overflow:auto; height:200px; border:2px dotted black; transform: translateY(1px)" onscroll="doneScroll()">
   <div id="d" style="overflow:auto; height:102px;" onscroll="doneScroll()">
     <div id="inner" style="height:100.1px; border:1px solid black; background:yellow;">Hello</div>
   </div>
   <div style="height:500px;"></div>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript;version=1.7">
 var sel = window.getSelection();
--- a/layout/generic/test/test_bug791616.html
+++ b/layout/generic/test/test_bug791616.html
@@ -6,17 +6,17 @@
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <style>
 #t {
     overflow: auto;
     position: absolute;
     left: 200px;
     top: 100px;
-    font: 14px/1.1em "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace;
+    font: 14px/1.3em "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace;
 }
   </style>
 </head>
 <body>
 <p id="display"></p>
 <div id="t" contenteditable>
   <div>66666666666666</div>
   <div id="target">777777777777777777777777777777777777777</div>
--- a/layout/reftests/bugs/240933-1.html
+++ b/layout/reftests/bugs/240933-1.html
@@ -7,13 +7,13 @@
 
 </textarea>
 <textarea id="tb">
 
 abc
 
 </textarea>
 
-<div id="coords1">0</div>
-<div id="coords2">0</div>
+<div id="coords1">6</div>
+<div id="coords2">6</div>
 
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/scrolling/fractional-scroll-area-invalidation.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en" reftest-async-scroll>
+<meta charset="utf-8">
+<title>Make sure the scrolled layer is not invalidated when you scroll all the way to the bottom</title>
+
+<style>
+
+body {
+  margin: 0;
+}
+
+.scrollbox {
+  margin: 50px;
+  width: 200px;
+  height: 200px;
+  overflow: auto;
+}
+
+.scrolled-contents {
+  height: 150.2px;
+  padding-top: 150px;
+}
+
+.reftest-no-paint {
+  margin: 0 20px;
+  border: 1px solid blue;
+  height: 25px;
+}
+
+</style>
+
+<body>
+
+<div class="scrollbox"
+     reftest-displayport-x="0" reftest-displayport-y="0"
+     reftest-displayport-w="200" reftest-displayport-h="200"
+     reftest-async-scroll-x="0" reftest-async-scroll-y="0">
+  <div class="scrolled-contents">
+    <div class="reftest-no-paint">
+      <!-- This element has the magic "reftest-no-paint" class which
+           constitutes the actual test here. -->
+    </div>
+  </div>
+</div>
+
+<script>
+
+var scrollbox = document.querySelector(".scrollbox");
+scrollbox.scrollTop = 2;
+scrollbox.scrollTop = 1;
+scrollbox.scrollTop = 0;
+
+function doTest() {
+  scrollbox.scrollTop = 999;
+  document.documentElement.removeAttribute("class");
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/scrolling/fractional-scroll-area.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>Fractional scroll area position / size</title>
+
+<style>
+
+body {
+  margin: 0;
+}
+
+#scrollbox {
+  width: 200px;
+  overflow: hidden;
+  background: red;
+}
+
+#scrolled-content {
+  background: lime;
+  box-sizing: border-box;
+  border: solid black;
+  border-width: 1px 0;
+}
+
+</style>
+
+<div id="scrollbox">
+  <div id="scrolled-content"></div>
+</div>
+
+<script>
+
+function getFloatQueryParams(defaultValues) {
+  let result = Object.assign({}, defaultValues);
+  for (let chunk of location.search.substr(1).split("&")) {
+    let parts = chunk.split("=");
+    result[parts[0]] = parseFloat(parts[1]);
+  }
+  return result;
+}
+
+let params = getFloatQueryParams({
+  top: 0,
+  outerBottom: 100,
+  innerBottom: 100,
+  borderTop: 0,
+  borderBottom: 0,
+  scrollBefore: 0,
+  scrollAfter: undefined,
+  offsetAfter: undefined,
+});
+
+let scrollArea = document.getElementById("scrollbox");
+let scrolledContent = document.getElementById("scrolled-content");
+
+scrollArea.style.marginTop = params.top + "px";
+scrollArea.style.height = (params.outerBottom - params.top) + "px";
+scrolledContent.style.height =  (params.innerBottom - params.top) + "px";
+
+scrollArea.scrollTop = 1;
+scrollArea.scrollTop = 2;
+scrollArea.scrollTop = params.scrollBefore;
+
+window.addEventListener("MozReftestInvalidate", function () {
+  if (params.scrollAfter !== undefined) {
+    scrollArea.scrollTop = params.scrollAfter;
+  }
+  if (params.offsetAfter !== undefined) {
+    document.body.style.marginTop = params.offsetAfter + "px";
+  }
+  document.documentElement.className = "";
+});
+
+</script>
--- a/layout/reftests/scrolling/reftest.list
+++ b/layout/reftests/scrolling/reftest.list
@@ -31,8 +31,57 @@ fuzzy-if(Android,5,20000) == uncovering-
 skip-if(B2G||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,121,3721) == less-than-scrollbar-height.html less-than-scrollbar-height-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) == huge-horizontal-overflow.html huge-horizontal-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) == huge-vertical-overflow.html huge-vertical-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 fuzzy-if(asyncPan&&!layersGPUAccelerated,102,6818) == iframe-scrolling-attr-1.html iframe-scrolling-attr-ref.html
 skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,6818) == iframe-scrolling-attr-2.html iframe-scrolling-attr-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 == frame-scrolling-attr-1.html frame-scrolling-attr-ref.html
 fuzzy-if(asyncPan&&!layersGPUAccelerated,102,2420) == frame-scrolling-attr-2.html frame-scrolling-attr-ref.html
 == move-item.html move-item-ref.html # bug 1125750
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=199.6 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=199.6&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=100&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=-0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
+!= fractional-scroll-area-invalidation.html about:blank
--- a/layout/reftests/text-overflow/reftest.list
+++ b/layout/reftests/text-overflow/reftest.list
@@ -17,17 +17,17 @@ skip-if(B2G||Mulet) random-if(/^Windows\
 HTTP(..) == marker-shadow.html marker-shadow-ref.html
 == aligned-baseline.html aligned-baseline-ref.html
 skip-if(Android||B2G) fuzzy-if(skiaContent,1,5) == clipped-elements.html clipped-elements-ref.html
 HTTP(..) == theme-overflow.html theme-overflow-ref.html
 skip-if(B2G||Mulet) HTTP(..) == table-cell.html table-cell-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(Mulet) fuzzy-if(gtkWidget,10,32) HTTP(..) == two-value-syntax.html two-value-syntax-ref.html # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables
 skip-if(B2G||Mulet) HTTP(..) == single-value.html single-value-ref.html  # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if(B2G||Mulet) fuzzy-if(gtkWidget,10,2) HTTP(..) == atomic-under-marker.html atomic-under-marker-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
-fuzzy(1,702) skip-if(Android||B2G||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+fuzzy(1,2616) skip-if(Android||B2G||Mulet) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 HTTP(..) == combobox-zoom.html combobox-zoom-ref.html
 
 # The vertical-text pref setting can be removed after bug 1138384 lands
 pref(layout.css.vertical-text.enabled,true) == vertical-decorations-1.html vertical-decorations-1-ref.html
 pref(layout.css.vertical-text.enabled,true) == vertical-decorations-2.html vertical-decorations-2-ref.html
 pref(layout.css.vertical-text.enabled,true) != vertical-decorations-1.html vertical-decorations-1-2-notref.html
 pref(layout.css.vertical-text.enabled,true) != vertical-decorations-2.html vertical-decorations-1-2-notref.html
 pref(layout.css.vertical-text.enabled,true) == vertical-decorations-3.html vertical-decorations-3-ref.html
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -64,19 +64,34 @@ TryToStartImageLoadOnValue(const nsCSSVa
 #ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
     // The 'mask-image' property accepts local reference URIs.
     // For example,
     //   mask-image: url(#mask_id); // refer to a SVG mask element, whose id is
     //                              // "mask_id", in the current document.
     // For such 'mask-image' values (pointing to an in-document element),
     // there is no need to trigger image download.
     if (aProperty == eCSSProperty_mask_image) {
-      nsIURI* docURI = aDocument->GetDocumentURI();
+      // Filter out all fragment URLs.
+      // Since nsCSSValue::GetURLStructValue runs much faster than
+      // nsIURI::EqualsExceptRef bellow, we get performance gain by this
+      // early return.
+      URLValue* urlValue = aValue.GetURLStructValue();
+      if (urlValue->GetLocalURLFlag()) {
+        return;
+      }
+
+      // Even though urlValue is not a fragment URL, it might still refer to
+      // an internal resource.
+      // For example, aDocument base URL is "http://foo/index.html" and
+      // intentionally references a mask-image at
+      // url(http://foo/index.html#mask) which still refers to a resource in
+      // aDocument.
       nsIURI* imageURI = aValue.GetURLValue();
       if (imageURI) {
+        nsIURI* docURI = aDocument->GetDocumentURI();
         bool isEqualExceptRef = false;
         nsresult  rv = imageURI->EqualsExceptRef(docURI, &isEqualExceptRef);
         if (NS_SUCCEEDED(rv) && isEqualExceptRef) {
           return;
         }
       }
     }
 #endif
--- a/media/ffvpx/changes.patch
+++ b/media/ffvpx/changes.patch
@@ -45,8 +45,21 @@ index 9fb8d0a..97ad3b9 100644
      rgba_color[3] = 255;
  
      if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
 -        int rgba = av_get_random_seed();
 +        int rgba = 0xffffffff; /* av_get_random_seed(); */
          rgba_color[0] = rgba >> 24;
          rgba_color[1] = rgba >> 16;
          rgba_color[2] = rgba >> 8;
+diff --git a/media/ffvpx/libavcodec/options.c b/media/ffvpx/libavcodec/options.c
+index d8e3dbf..f25df2a 100644
+--- a/media/ffvpx/libavcodec/options.c
++++ b/media/ffvpx/libavcodec/options.c
+@@ -34,7 +34,7 @@
+ #include <string.h>
+ 
+ FF_DISABLE_DEPRECATION_WARNINGS
+-#include "options_table.h"
++#include "ff_options_table.h"
+ FF_ENABLE_DEPRECATION_WARNINGS
+ 
+ static const char* context_to_name(void* ptr) {
--- a/media/ffvpx/libavcodec/avcodec.symbols
+++ b/media/ffvpx/libavcodec/avcodec.symbols
@@ -77,19 +77,16 @@ av_vorbis_parse_reset
 av_xiphlacing
 avcodec_align_dimensions
 avcodec_align_dimensions2
 avcodec_alloc_context3
 avcodec_chroma_pos_to_enum
 avcodec_close
 avcodec_configuration
 avcodec_copy_context
-avcodec_dct_alloc
-avcodec_dct_get_class
-avcodec_dct_init
 avcodec_decode_audio4
 avcodec_decode_subtitle2
 avcodec_decode_video2
 avcodec_default_execute
 avcodec_default_execute2
 avcodec_default_get_buffer2
 avcodec_default_get_format
 avcodec_descriptor_get
deleted file mode 100644
--- a/media/ffvpx/libavcodec/avdct.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "avcodec.h"
-#include "idctdsp.h"
-#include "fdctdsp.h"
-#include "pixblockdsp.h"
-#include "avdct.h"
-
-#define OFFSET(x) offsetof(AVDCT,x)
-#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
-//these names are too long to be readable
-#define V AV_OPT_FLAG_VIDEO_PARAM
-#define A AV_OPT_FLAG_AUDIO_PARAM
-#define E AV_OPT_FLAG_ENCODING_PARAM
-#define D AV_OPT_FLAG_DECODING_PARAM
-
-static const AVOption avdct_options[] = {
-{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
-{"fastint", "fast integer (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"mmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
-{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
-{"faan", "floating point AAN DCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
-
-{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"int", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simple", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplemmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"arm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#if FF_API_ARCH_SH4
-{"sh4", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
-{"simplearm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv5te", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv6", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simpleneon", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#if FF_API_ARCH_ALPHA
-{"simplealpha", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
-#if FF_API_UNUSED_MEMBERS
-{"ipp", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
-{"xvid", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"xvidmmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"faani", "floating point AAN IDCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
-{"simpleauto", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
-
-{"bits_per_sample", "", OFFSET(bits_per_sample), AV_OPT_TYPE_INT, {.i64 = 8 }, 0, 14, 0,},
-{NULL},
-};
-
-static const AVClass avdct_class = {
-    .class_name              = "AVDCT",
-    .option                  = avdct_options,
-    .version                 = LIBAVUTIL_VERSION_INT,
-};
-
-const AVClass *avcodec_dct_get_class(void)
-{
-    return &avdct_class;
-}
-
-AVDCT *avcodec_dct_alloc(void)
-{
-    AVDCT *dsp = av_mallocz(sizeof(AVDCT));
-
-    if (!dsp)
-        return NULL;
-
-    dsp->av_class = &avdct_class;
-    av_opt_set_defaults(dsp);
-
-    return dsp;
-}
-
-int avcodec_dct_init(AVDCT *dsp)
-{
-    AVCodecContext *avctx = avcodec_alloc_context3(NULL);
-
-    if (!avctx)
-        return AVERROR(ENOMEM);
-
-    avctx->idct_algo = dsp->idct_algo;
-    avctx->dct_algo  = dsp->dct_algo;
-    avctx->bits_per_raw_sample = dsp->bits_per_sample;
-
-#define COPY(src, name) memcpy(&dsp->name, &src.name, sizeof(dsp->name))
-
-#if CONFIG_IDCTDSP
-    {
-        IDCTDSPContext idsp;
-        ff_idctdsp_init(&idsp, avctx);
-        COPY(idsp, idct);
-        COPY(idsp, idct_permutation);
-    }
-#endif
-
-#if CONFIG_FDCTDSP
-    {
-        FDCTDSPContext fdsp;
-        ff_fdctdsp_init(&fdsp, avctx);
-        COPY(fdsp, fdct);
-    }
-#endif
-
-#if CONFIG_PIXBLOCKDSP
-    {
-        PixblockDSPContext pdsp;
-        ff_pixblockdsp_init(&pdsp, avctx);
-        COPY(pdsp, get_pixels);
-    }
-#endif
-
-    avcodec_close(avctx);
-    av_free(avctx);
-
-    return 0;
-}
deleted file mode 100644
--- a/media/ffvpx/libavcodec/bsf.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-
-#include "libavutil/log.h"
-#include "libavutil/mem.h"
-#include "libavutil/opt.h"
-
-#include "avcodec.h"
-#include "bsf.h"
-
-struct AVBSFInternal {
-    AVPacket *buffer_pkt;
-    int eof;
-};
-
-void av_bsf_free(AVBSFContext **pctx)
-{
-    AVBSFContext *ctx;
-
-    if (!pctx || !*pctx)
-        return;
-    ctx = *pctx;
-
-    if (ctx->filter->close)
-        ctx->filter->close(ctx);
-    if (ctx->filter->priv_class && ctx->priv_data)
-        av_opt_free(ctx->priv_data);
-
-    av_opt_free(ctx);
-
-    av_packet_free(&ctx->internal->buffer_pkt);
-    av_freep(&ctx->internal);
-    av_freep(&ctx->priv_data);
-
-    avcodec_parameters_free(&ctx->par_in);
-    avcodec_parameters_free(&ctx->par_out);
-
-    av_freep(pctx);
-}
-
-static void *bsf_child_next(void *obj, void *prev)
-{
-    AVBSFContext *ctx = obj;
-    if (!prev && ctx->filter->priv_class)
-        return ctx->priv_data;
-    return NULL;
-}
-
-static const AVClass bsf_class = {
-    .class_name       = "AVBSFContext",
-    .item_name        = av_default_item_name,
-    .version          = LIBAVUTIL_VERSION_INT,
-    .child_next       = bsf_child_next,
-    .child_class_next = ff_bsf_child_class_next,
-};
-
-const AVClass *av_bsf_get_class(void)
-{
-    return &bsf_class;
-}
-
-int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
-{
-    AVBSFContext *ctx;
-    int ret;
-
-    ctx = av_mallocz(sizeof(*ctx));
-    if (!ctx)
-        return AVERROR(ENOMEM);
-
-    ctx->av_class = &bsf_class;
-    ctx->filter   = filter;
-
-    ctx->par_in  = avcodec_parameters_alloc();
-    ctx->par_out = avcodec_parameters_alloc();
-    if (!ctx->par_in || !ctx->par_out) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    ctx->internal = av_mallocz(sizeof(*ctx->internal));
-    if (!ctx->internal) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    ctx->internal->buffer_pkt = av_packet_alloc();
-    if (!ctx->internal->buffer_pkt) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    av_opt_set_defaults(ctx);
-
-    /* allocate priv data and init private options */
-    if (filter->priv_data_size) {
-        ctx->priv_data = av_mallocz(filter->priv_data_size);
-        if (!ctx->priv_data) {
-            ret = AVERROR(ENOMEM);
-            goto fail;
-        }
-        if (filter->priv_class) {
-            *(const AVClass **)ctx->priv_data = filter->priv_class;
-            av_opt_set_defaults(ctx->priv_data);
-        }
-    }
-
-    *pctx = ctx;
-    return 0;
-fail:
-    av_bsf_free(&ctx);
-    return ret;
-}
-
-int av_bsf_init(AVBSFContext *ctx)
-{
-    int ret, i;
-
-    /* check that the codec is supported */
-    if (ctx->filter->codec_ids) {
-        for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++)
-            if (ctx->par_in->codec_id == ctx->filter->codec_ids[i])
-                break;
-        if (ctx->filter->codec_ids[i] == AV_CODEC_ID_NONE) {
-            const AVCodecDescriptor *desc = avcodec_descriptor_get(ctx->par_in->codec_id);
-            av_log(ctx, AV_LOG_ERROR, "Codec '%s' (%d) is not supported by the "
-                   "bitstream filter '%s'. Supported codecs are: ",
-                   desc ? desc->name : "unknown", ctx->par_in->codec_id, ctx->filter->name);
-            for (i = 0; ctx->filter->codec_ids[i] != AV_CODEC_ID_NONE; i++) {
-                desc = avcodec_descriptor_get(ctx->filter->codec_ids[i]);
-                av_log(ctx, AV_LOG_ERROR, "%s (%d) ",
-                       desc ? desc->name : "unknown", ctx->filter->codec_ids[i]);
-            }
-            av_log(ctx, AV_LOG_ERROR, "\n");
-            return AVERROR(EINVAL);
-        }
-    }
-
-    /* initialize output parameters to be the same as input
-     * init below might overwrite that */
-    ret = avcodec_parameters_copy(ctx->par_out, ctx->par_in);
-    if (ret < 0)
-        return ret;
-
-    ctx->time_base_out = ctx->time_base_in;
-
-    if (ctx->filter->init) {
-        ret = ctx->filter->init(ctx);
-        if (ret < 0)
-            return ret;
-    }
-
-    return 0;
-}
-
-int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
-{
-    if (!pkt || !pkt->data) {
-        ctx->internal->eof = 1;
-        return 0;
-    }
-
-    if (ctx->internal->eof) {
-        av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n");
-        return AVERROR(EINVAL);
-    }
-
-    if (ctx->internal->buffer_pkt->data ||
-        ctx->internal->buffer_pkt->side_data_elems)
-        return AVERROR(EAGAIN);
-
-    av_packet_move_ref(ctx->internal->buffer_pkt, pkt);
-
-    return 0;
-}
-
-int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
-{
-    return ctx->filter->filter(ctx, pkt);
-}
-
-int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
-{
-    AVBSFInternal *in = ctx->internal;
-    AVPacket *tmp_pkt;
-
-    if (in->eof)
-        return AVERROR_EOF;
-
-    if (!ctx->internal->buffer_pkt->data &&
-        !ctx->internal->buffer_pkt->side_data_elems)
-        return AVERROR(EAGAIN);
-
-    tmp_pkt = av_packet_alloc();
-    if (!tmp_pkt)
-        return AVERROR(ENOMEM);
-
-    *pkt = ctx->internal->buffer_pkt;
-    ctx->internal->buffer_pkt = tmp_pkt;
-
-    return 0;
-}
new file mode 100644
--- /dev/null
+++ b/media/ffvpx/libavcodec/ff_options_table.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_OPTIONS_TABLE_H
+#define AVCODEC_OPTIONS_TABLE_H
+
+#include "libavutil/opt.h"
+static const AVOption avcodec_options[] = {
+{NULL},
+};
+
+#endif /* AVCODEC_OPTIONS_TABLE_H */
--- a/media/ffvpx/libavcodec/moz.build
+++ b/media/ffvpx/libavcodec/moz.build
@@ -8,17 +8,16 @@
 # moz.build file.
 if CONFIG['FFVPX_ASFLAGS']:
     DIRS += ['x86']
 
 SharedLibrary('mozavcodec')
 SOURCES += [
     'allcodecs.c',
     'audioconvert.c',
-    'avdct.c',
     'avpacket.c',
     'avpicture.c',
     'bitstream.c',
     'codec_desc.c',
     'dummy_funcs.c',
     'h264pred.c',
     'imgconvert.c',
     'log2_tab.c',
--- a/media/ffvpx/libavcodec/options.c
+++ b/media/ffvpx/libavcodec/options.c
@@ -29,17 +29,17 @@
 #include "libavutil/avassert.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
 #include <float.h>              /* FLT_MIN, FLT_MAX */
 #include <string.h>
 
 FF_DISABLE_DEPRECATION_WARNINGS
-#include "options_table.h"
+#include "ff_options_table.h"
 FF_ENABLE_DEPRECATION_WARNINGS
 
 static const char* context_to_name(void* ptr) {
     AVCodecContext *avc= ptr;
 
     if(avc && avc->codec && avc->codec->name)
         return avc->codec->name;
     else
deleted file mode 100644
--- a/media/ffvpx/libavcodec/options_table.h
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_OPTIONS_TABLE_H
-#define AVCODEC_OPTIONS_TABLE_H
-
-#include <float.h>
-#include <limits.h>
-#include <stdint.h>
-
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "version.h"
-
-#define OFFSET(x) offsetof(AVCodecContext,x)
-#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
-//these names are too long to be readable
-#define V AV_OPT_FLAG_VIDEO_PARAM
-#define A AV_OPT_FLAG_AUDIO_PARAM
-#define S AV_OPT_FLAG_SUBTITLE_PARAM
-#define E AV_OPT_FLAG_ENCODING_PARAM
-#define D AV_OPT_FLAG_DECODING_PARAM
-
-#define AV_CODEC_DEFAULT_BITRATE 200*1000
-
-static const AVOption avcodec_options[] = {
-{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
-{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
-{"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far "
-       "ratecontrol is willing to deviate from the target average bitrate value. This is not related "
-       "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
-       OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
-{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"},
-{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" },
-{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
-{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
-#if FF_API_GMC
-{"gmc", "use gmc", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GMC }, INT_MIN, INT_MAX, V|E, "flags"},
-#endif
-#if FF_API_MV0
-{"mv0", "always try a mb with mv=<0,0>", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_MV0 }, INT_MIN, INT_MAX, V|E, "flags"},
-#endif
-#if FF_API_INPUT_PRESERVED
-{"input_preserved", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INPUT_PRESERVED }, INT_MIN, INT_MAX, 0, "flags"},
-#endif
-{"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
-{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
-{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
-#if FF_API_EMU_EDGE
-{"emu_edge", "do not draw edges", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_EMU_EDGE }, INT_MIN, INT_MAX, 0, "flags"},
-#endif
-{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
-{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"},
-#if FF_API_NORMALIZE_AQP
-{"naq", "normalize adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_NORMALIZE_AQP }, INT_MIN, INT_MAX, V|E, "flags"},
-#endif
-{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
-{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
-{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
-{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
-{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
-{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
-{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
-{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
-{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
-{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
-{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
-{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
-{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"},
-{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, V|D, "flags2"},
-{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, "flags2"},
-#if FF_API_MOTION_EST
-{"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
-{"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"epzs", "EPZS motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"esa", "esa motion estimation (alias for full)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"tesa", "tesa motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_TESA }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"dia", "diamond motion estimation (alias for EPZS)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"log", "log motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_LOG }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"phods", "phods motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_PHODS }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
-#endif
-{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
-{"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
-{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
-{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
-{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
-{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
-{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. "
-          "Recommended range for default rc_eq: 0.0-1.0",
-          OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
-{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
-{"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
-{"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
-{"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
-{"bf", "set maximum number of B-frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E},
-{"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
-#if FF_API_RC_STRATEGY
-{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-#if FF_API_PRIVATE_OPT
-{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
-{"ps", "RTP payload size in bytes", OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-#if FF_API_STAT_BITS
-{"mv_bits", NULL, OFFSET(mv_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"header_bits", NULL, OFFSET(header_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"i_tex_bits", NULL, OFFSET(i_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"p_tex_bits", NULL, OFFSET(p_tex_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"i_count", NULL, OFFSET(i_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"p_count", NULL, OFFSET(p_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"skip_count", NULL, OFFSET(skip_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"misc_bits", NULL, OFFSET(misc_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"frame_bits", NULL, OFFSET(frame_bits), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif
-{"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
-{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
-#if FF_API_OLD_MSMPEG4
-{"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
-#endif
-{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
-{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
-#if FF_API_AC_VLC
-{"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
-#endif
-{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
-{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
-{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
-{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
-{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
-{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
-{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
-{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
-{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
-{"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
-{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"careful",    "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
-{"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#if FF_API_PRIVATE_OPT
-{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-#if FF_API_MPV_OPT
-{"qsquish", "deprecated, use encoder private options instead", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E},
-{"rc_qmod_amp",  "deprecated, use encoder private options instead", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-{"rc_qmod_freq", "deprecated, use encoder private options instead", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#if FF_API_MPV_OPT
-{"rc_eq", "deprecated, use encoder private options instead", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E},
-#endif
-{"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E},
-{"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
-            OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
-#if FF_API_MPV_OPT
-{"rc_buf_aggressivity", "deprecated, use encoder private options instead", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E},
-#endif
-{"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
-{"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
-#if FF_API_MPV_OPT
-{"rc_init_cplx", "deprecated, use encoder private options instead", OFFSET(rc_initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-#endif
-{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
-{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
-{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
-{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
-{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
-{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
-{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
-{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#if FF_API_ARCH_SH4
-{"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
-{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#if FF_API_ARCH_ALPHA
-{"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
-#if FF_API_UNUSED_MEMBERS
-{"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif /* FF_API_UNUSED_MEMBERS */
-{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
-{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
-{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"},
-{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
-{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"},
-{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#if FF_API_PRIVATE_OPT
-{"pred", "prediction method", OFFSET(prediction_method), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "pred"},
-{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_LEFT }, INT_MIN, INT_MAX, V|E, "pred"},
-{"plane", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_PLANE }, INT_MIN, INT_MAX, V|E, "pred"},
-{"median", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PRED_MEDIAN }, INT_MIN, INT_MAX, V|E, "pred"},
-#endif
-{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
-{"sar",    "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
-{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
-{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
-{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
-{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
-{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
-{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
-#if FF_API_DEBUG_MV
-{"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
-#endif
-{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
-{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"},
-{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
-{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
-#if FF_API_UNUSED_MEMBERS
-{"pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PTS }, INT_MIN, INT_MAX, V|D, "debug"},
-#endif /* FF_API_UNUSED_MEMBERS */
-{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
-{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
-{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
-{"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
-{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
-{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
-{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"},
-#if FF_API_VISMV
-{"vismv", "visualize motion vectors (MVs) (deprecated)", OFFSET(debug_mv), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
-{"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-{"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
-#endif
-{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#if FF_API_PRIVATE_OPT
-{"preme", "pre motion estimation", OFFSET(pre_me), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-#if CONFIG_SNOW_ENCODER
-{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-#endif
-{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
-#if FF_API_AFD
-{"dtg_active_format", NULL, OFFSET(dtg_active_format), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif
-{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#if FF_API_QUANT_BIAS
-{"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
-{"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
-#endif
-{"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-#if FF_API_CODER_TYPE
-{"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
-{"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
-{"ac", "arithmetic coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_AC }, INT_MIN, INT_MAX, V|E, "coder"},
-{"raw", "raw (no encoding)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RAW }, INT_MIN, INT_MAX, V|E, "coder"},
-{"rle", "run-length coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_RLE }, INT_MIN, INT_MAX, V|E, "coder"},
-#if FF_API_UNUSED_MEMBERS
-{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
-#endif /* FF_API_UNUSED_MEMBERS */
-#endif /* FF_API_CODER_TYPE */
-#if FF_API_PRIVATE_OPT
-{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#if FF_API_XVMC
-{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif /* FF_API_XVMC */
-{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
-{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
-{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
-#if FF_API_STREAM_CODEC_TAG
-{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif
-#if FF_API_PRIVATE_OPT
-{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-#if FF_API_MPV_OPT
-{"lmin", "deprecated, use encoder private options instead", OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 =  0 }, 0, INT_MAX, V|E},
-{"lmax", "deprecated, use encoder private options instead", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 =  0 }, 0, INT_MAX, V|E},
-#endif
-#if FF_API_PRIVATE_OPT
-{"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"},
-#if FF_API_ERROR_RATE
-{"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
-{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
-#if FF_API_MPV_OPT
-{"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E},
-{"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
-{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
-{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
-{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
-{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "profile"},
-{"aac_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_MAIN }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_ssr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_SSR }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_ltp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LTP }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"},
-{"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"},
-{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
-{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"},
-{"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
-{"mpeg4_sp",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
-{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"},
-{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"},
-{"mpeg4_asp",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
-{"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
-{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
-{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
-#if FF_API_PRIVATE_OPT
-{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-#endif
-#if FF_API_MPV_OPT
-{"border_mask", "deprecated, use encoder private options instead", OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E},
-#endif
-{"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
-{"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
-#if FF_API_PRIVATE_OPT
-{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), AV_OPT_TYPE_INT, {.i64 = 256 }, INT_MIN, INT_MAX, V|E},
-#endif
-{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"skip_idct"       , "skip IDCT/dequantization for the selected frames",    OFFSET(skip_idct),        AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"skip_frame"      , "skip decoding for the selected frames",               OFFSET(skip_frame),       AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"none"            , "discard no frame",                    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE    }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"default"         , "discard useless frames",              0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"noref"           , "discard all non-reference frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF  }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"bidir"           , "discard all bidirectional frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR   }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"nokey"           , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY  }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"nointra"         , "discard all frames except I frames",  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"all"             , "discard all frames",                  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL     }, INT_MIN, INT_MAX, V|D, "avdiscard"},
-{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E},
-#if FF_API_PRIVATE_OPT
-{"brd_scale", "downscale frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 10, V|E},
-#endif
-{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E},
-{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E},
-#if FF_API_PRIVATE_OPT
-{"chromaoffset", "chroma QP offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
-{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-#if FF_API_UNUSED_MEMBERS
-{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E},
-#endif /* FF_API_UNUSED_MEMBERS */
-{"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
-#if FF_API_PRIVATE_OPT
-{"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E},
-#endif
-{"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
-#if FF_API_PRIVATE_OPT
-{"min_prediction_order", NULL, OFFSET(min_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
-{"max_prediction_order", NULL, OFFSET(max_prediction_order), AV_OPT_TYPE_INT, {.i64 = -1 }, INT_MIN, INT_MAX, A|E},
-{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = -1 }, -1, INT64_MAX, V|E},
-#endif
-{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
-{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"},
-{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E},
-{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use),  AV_OPT_TYPE_FLOAT, {.dbl = 3 },     0.0, FLT_MAX, V|E},
-{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D},
-{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D, "color_primaries_type"},
-{"bt709",       "BT.709",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 },        INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"unspecified", "Unspecified",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"bt470m",      "BT.470 M",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M },       INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"bt470bg",     "BT.470 BG",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG },      INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"smpte170m",   "SMPTE 170 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"smpte240m",   "SMPTE 240 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"film",        "Film",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM },         INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"bt2020",      "BT.2020",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 },       INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"smpte428_1",  "SMPTE ST 428-1", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
-{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, V|E|D, "color_trc_type"},
-{"bt709",        "BT.709",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 },        INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"unspecified",  "Unspecified",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"gamma22",      "BT.470 M",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 },      INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"gamma28",      "BT.470 BG",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 },      INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"smpte170m",    "SMPTE 170 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"smpte240m",    "SMPTE 240 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"linear",       "Linear",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR },       INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"log",          "Log",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG },          INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"log_sqrt",     "Log square root",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT },     INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"iec61966_2_4", "IEC 61966-2-4",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"bt1361",       "BT.1361",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG },   INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"iec61966_2_1", "IEC 61966-2-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"smpte2084",    "SMPTE ST 2084",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 },  INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"smpte428_1",   "SMPTE ST 428-1",   0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
-{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, V|E|D, "colorspace_type"},
-{"rgb",         "RGB",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB },         INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"bt709",       "BT.709",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 },       INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"fcc",         "FCC",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC },         INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"bt470bg",     "BT.470 BG",   0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG },     INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"smpte170m",   "SMPTE 170 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M },   INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"smpte240m",   "SMPTE 240 M", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M },   INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"ycocg",       "YCOCG",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCOCG },       INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"bt2020_ncl",  "BT.2020 NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL },  INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"bt2020_cl",   "BT.2020 CL",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL },   INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
-{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, AVCOL_RANGE_NB-1, V|E|D, "color_range_type"},
-{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
-{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
-{"jpeg", "JPEG (2^n-1)",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
-{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D, "chroma_sample_location_type"},
-{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"left",        "Left",        0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT },        INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"center",      "Center",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER },      INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"topleft",     "Top-left",    0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT },     INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"top",         "Top",         0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP },         INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"bottomleft",  "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT },  INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"bottom",      "Bottom",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM },      INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
-{"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
-{"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
-{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"},
-{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
-{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
-{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
-{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN },              INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"ef", "Effects",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS },           INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"vi", "Visually Impaired",  0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"hi", "Hearing Impaired",   0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED },  INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"di", "Dialogue",           0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE },          INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"co", "Commentary",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY },        INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"em", "Emergency",          0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY },         INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"vo", "Voice Over",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER },        INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"ka", "Karaoke",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE },           INT_MIN, INT_MAX, A|E, "audio_service_type"},
-{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"},
-{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
-{"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, S|D},
-{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"},
-{"do_nothing",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING},  INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
-{"auto",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC},   INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
-{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
-#if FF_API_ASS_TIMING
-{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, 0, 1, S|D, "sub_text_format"},
-#else
-{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D, "sub_text_format"},
-#endif
-{"ass",              NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS},              INT_MIN, INT_MAX, S|D, "sub_text_format"},
-#if FF_API_ASS_TIMING
-{"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"},
-#endif
-{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D },
-#if FF_API_SIDEDATA_ONLY_PKT
-{"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, A|V|E },
-#endif
-{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D },
-{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" },
-{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" },
-{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" },
-{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" },
-{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
-{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
-{"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E},
-{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL },  CHAR_MIN, CHAR_MAX, A|V|S|D },
-{"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
-{"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
-{NULL},
-};
-
-#undef A
-#undef V
-#undef S
-#undef E
-#undef D
-#undef DEFAULT
-#undef OFFSET
-
-#endif /* AVCODEC_OPTIONS_TABLE_H */
--- a/media/ffvpx/libavutil/dummy_funcs.c
+++ b/media/ffvpx/libavutil/dummy_funcs.c
@@ -1,19 +1,81 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "avutil.h"
+#include "opt.h"
 
 // cpu_internal.c
 int ff_get_cpu_flags_aarch64(void) { return 0; }
 int ff_get_cpu_flags_arm(void) { return 0; }
 int ff_get_cpu_flags_ppc(void) { return 0; }
 
 // float_dsp.c
 #include "float_dsp.h"
 void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp) {}
 void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp) {}
 void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict) {}
 void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp) {}
+
+// opt.c
+int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) { return 0; }
+void av_opt_set_defaults(void *s) {}
+void av_opt_set_defaults2(void *s, int mask, int flags) {}
+int av_set_options_string(void *ctx, const char *opts,
+                          const char *key_val_sep, const char *pairs_sep) { return 0; }
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand,
+                           const char *key_val_sep, const char *pairs_sep) { return 0; }
+void av_opt_free(void *obj) {}
+int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { return 0; }
+int av_opt_set_dict(void *obj, struct AVDictionary **options) { return 0; }
+int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags) { return 0; }
+int av_opt_get_key_value(const char **ropts,
+                         const char *key_val_sep, const char *pairs_sep,
+                         unsigned flags,
+                         char **rkey, char **rval) { return 0; }
+int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int       *flags_out) { return 0; }
+int av_opt_eval_int   (void *obj, const AVOption *o, const char *val, int       *int_out) { return 0; }
+int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t   *int64_out) { return 0; }
+int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float     *float_out) { return 0; }
+int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double    *double_out) { return 0; }
+int av_opt_eval_q     (void *obj, const AVOption *o, const char *val, AVRational *q_out) { return 0; }
+const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
+                            int opt_flags, int search_flags) { return 0; }
+const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
+                             int opt_flags, int search_flags, void **target_obj) { return 0; }
+const AVOption *av_opt_next(const void *obj, const AVOption *prev) { return 0; }
+void *av_opt_child_next(void *obj, void *prev) { return 0; }
+const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) { return 0; }
+int av_opt_set         (void *obj, const char *name, const char *val, int search_flags) { return 0; }
+int av_opt_set_int     (void *obj, const char *name, int64_t     val, int search_flags) { return 0; }
+int av_opt_set_double  (void *obj, const char *name, double      val, int search_flags) { return 0; }
+int av_opt_set_q       (void *obj, const char *name, AVRational  val, int search_flags) { return 0; }
+int av_opt_set_bin     (void *obj, const char *name, const uint8_t *val, int size, int search_flags) { return 0; }
+int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags) { return 0; }
+int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags) { return 0; }
+int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags) { return 0; }
+int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags) { return 0; }
+int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags) { return 0; }
+int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags) { return 0; }
+int av_opt_get         (void *obj, const char *name, int search_flags, uint8_t **out_val) { return 0; }
+int av_opt_get_int     (void *obj, const char *name, int search_flags, int64_t *out_val) { return 0; }
+int av_opt_get_double  (void *obj, const char *name, int search_flags, double *out_val) { return 0; }
+int av_opt_get_q       (void *obj, const char *name, int search_flags, AVRational *out_val) { return 0; }
+int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out) { return 0; }
+int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt) { return 0; }
+int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt) { return 0; }
+int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val) { return 0; }
+int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout) { return 0; }
+int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) { return 0; }
+void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name) { return 0; }
+void av_opt_freep_ranges(AVOptionRanges **ranges) {}
+int av_opt_query_ranges(AVOptionRanges **b, void *obj, const char *key, int flags) { return 0; }
+int av_opt_copy(void *dest, const void *src) { return 0; }
+int av_opt_query_ranges_default(AVOptionRanges **b, void *obj, const char *key, int flags) { return 0; }
+int av_opt_is_set_to_default(void *obj, const AVOption *o) { return 0; }
+int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) { return 0; }
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
+                     const char key_val_sep, const char pairs_sep) { return 0; }
--- a/media/ffvpx/libavutil/moz.build
+++ b/media/ffvpx/libavutil/moz.build
@@ -33,17 +33,16 @@ SOURCES += [
     'imgutils.c',
     'integer.c',
     'intmath.c',
     'lls.c',
     'log.c',
     'log2_tab.c',
     'mathematics.c',
     'mem.c',
-    'opt.c',
     'parseutils.c',
     'pixdesc.c',
     'pixelutils.c',
     'rational.c',
     'reverse.c',
     'samplefmt.c',
     'threadmessage.c',
     'time.c',
deleted file mode 100644
--- a/media/ffvpx/libavutil/opt.c
+++ /dev/null
@@ -1,1994 +0,0 @@
-/*
- * AVOptions
- * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * AVOptions
- * @author Michael Niedermayer <michaelni@gmx.at>
- */
-
-#include "avutil.h"
-#include "avassert.h"
-#include "avstring.h"
-#include "channel_layout.h"
-#include "common.h"
-#include "dict.h"
-#include "eval.h"
-#include "log.h"
-#include "parseutils.h"
-#include "pixdesc.h"
-#include "mathematics.h"
-#include "opt.h"
-#include "samplefmt.h"
-#include "bprint.h"
-
-#include <float.h>
-
-const AVOption *av_opt_next(const void *obj, const AVOption *last)
-{
-    const AVClass *class;
-    if (!obj)
-        return NULL;
-    class = *(const AVClass**)obj;
-    if (!last && class && class->option && class->option[0].name)
-        return class->option;
-    if (last && last[1].name)
-        return ++last;
-    return NULL;
-}
-
-static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
-{
-    switch (o->type) {
-    case AV_OPT_TYPE_FLAGS:
-        *intnum = *(unsigned int*)dst;
-        return 0;
-    case AV_OPT_TYPE_PIXEL_FMT:
-        *intnum = *(enum AVPixelFormat *)dst;
-        return 0;
-    case AV_OPT_TYPE_SAMPLE_FMT:
-        *intnum = *(enum AVSampleFormat *)dst;
-        return 0;
-    case AV_OPT_TYPE_BOOL:
-    case AV_OPT_TYPE_INT:
-        *intnum = *(int *)dst;
-        return 0;
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-    case AV_OPT_TYPE_DURATION:
-    case AV_OPT_TYPE_INT64:
-        *intnum = *(int64_t *)dst;
-        return 0;
-    case AV_OPT_TYPE_FLOAT:
-        *num = *(float *)dst;
-        return 0;
-    case AV_OPT_TYPE_DOUBLE:
-        *num = *(double *)dst;
-        return 0;
-    case AV_OPT_TYPE_RATIONAL:
-        *intnum = ((AVRational *)dst)->num;
-        *den    = ((AVRational *)dst)->den;
-        return 0;
-    case AV_OPT_TYPE_CONST:
-        *num = o->default_val.dbl;
-        return 0;
-    }
-    return AVERROR(EINVAL);
-}
-
-static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
-{
-    if (o->type != AV_OPT_TYPE_FLAGS &&
-        (o->max * den < num * intnum || o->min * den > num * intnum)) {
-        num = den ? num * intnum / den : (num * intnum ? INFINITY : NAN);
-        av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
-               num, o->name, o->min, o->max);
-        return AVERROR(ERANGE);
-    }
-    if (o->type == AV_OPT_TYPE_FLAGS) {
-        double d = num*intnum/den;
-        if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
-            av_log(obj, AV_LOG_ERROR,
-                   "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
-                   num*intnum/den, o->name);
-            return AVERROR(ERANGE);
-        }
-    }
-
-    switch (o->type) {
-    case AV_OPT_TYPE_PIXEL_FMT:
-        *(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
-        break;
-    case AV_OPT_TYPE_SAMPLE_FMT:
-        *(enum AVSampleFormat *)dst = llrint(num / den) * intnum;
-        break;
-    case AV_OPT_TYPE_BOOL:
-    case AV_OPT_TYPE_FLAGS:
-    case AV_OPT_TYPE_INT:
-        *(int *)dst = llrint(num / den) * intnum;
-        break;
-    case AV_OPT_TYPE_DURATION:
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-    case AV_OPT_TYPE_INT64:
-        *(int64_t *)dst = llrint(num / den) * intnum;
-        break;
-    case AV_OPT_TYPE_FLOAT:
-        *(float *)dst = num * intnum / den;
-        break;
-    case AV_OPT_TYPE_DOUBLE:
-        *(double    *)dst = num * intnum / den;
-        break;
-    case AV_OPT_TYPE_RATIONAL:
-    case AV_OPT_TYPE_VIDEO_RATE:
-        if ((int) num == num)
-            *(AVRational *)dst = (AVRational) { num *intnum, den };
-        else
-            *(AVRational *)dst = av_d2q(num * intnum / den, 1 << 24);
-        break;
-    default:
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int hexchar2int(char c) {
-    if (c >= '0' && c <= '9')
-        return c - '0';
-    if (c >= 'a' && c <= 'f')
-        return c - 'a' + 10;
-    if (c >= 'A' && c <= 'F')
-        return c - 'A' + 10;
-    return -1;
-}
-
-static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
-{
-    int *lendst = (int *)(dst + 1);
-    uint8_t *bin, *ptr;
-    int len;
-
-    av_freep(dst);
-    *lendst = 0;
-
-    if (!val || !(len = strlen(val)))
-        return 0;
-
-    if (len & 1)
-        return AVERROR(EINVAL);
-    len /= 2;
-
-    ptr = bin = av_malloc(len);
-    if (!ptr)
-        return AVERROR(ENOMEM);
-    while (*val) {
-        int a = hexchar2int(*val++);
-        int b = hexchar2int(*val++);
-        if (a < 0 || b < 0) {
-            av_free(bin);
-            return AVERROR(EINVAL);
-        }
-        *ptr++ = (a << 4) | b;
-    }
-    *dst    = bin;
-    *lendst = len;
-
-    return 0;
-}
-
-static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
-{
-    av_freep(dst);
-    *dst = av_strdup(val);
-    return *dst ? 0 : AVERROR(ENOMEM);
-}
-
-#define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
-                              opt->type == AV_OPT_TYPE_CONST || \
-                              opt->type == AV_OPT_TYPE_FLAGS || \
-                              opt->type == AV_OPT_TYPE_INT)     \
-                             ? opt->default_val.i64             \
-                             : opt->default_val.dbl)
-
-static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
-{
-    int ret = 0;
-    int num, den;
-    char c;
-
-    if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
-        if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
-            return ret;
-        ret = 0;
-    }
-
-    for (;;) {
-        int i = 0;
-        char buf[256];
-        int cmd = 0;
-        double d;
-        int64_t intnum = 1;
-
-        if (o->type == AV_OPT_TYPE_FLAGS) {
-            if (*val == '+' || *val == '-')
-                cmd = *(val++);
-            for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
-                buf[i] = val[i];
-            buf[i] = 0;
-        }
-
-        {
-            const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, 0);
-            int res;
-            int ci = 0;
-            double const_values[64];
-            const char * const_names[64];
-            if (o_named && o_named->type == AV_OPT_TYPE_CONST)
-                d = DEFAULT_NUMVAL(o_named);
-            else {
-                if (o->unit) {
-                    for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
-                        if (o_named->type == AV_OPT_TYPE_CONST &&
-                            o_named->unit &&
-                            !strcmp(o_named->unit, o->unit)) {
-                            if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
-                                av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
-                                return AVERROR_PATCHWELCOME;
-                            }
-                            const_names [ci  ] = o_named->name;
-                            const_values[ci++] = DEFAULT_NUMVAL(o_named);
-                        }
-                    }
-                }
-                const_names [ci  ] = "default";
-                const_values[ci++] = DEFAULT_NUMVAL(o);
-                const_names [ci  ] = "max";
-                const_values[ci++] = o->max;
-                const_names [ci  ] = "min";
-                const_values[ci++] = o->min;
-                const_names [ci  ] = "none";
-                const_values[ci++] = 0;
-                const_names [ci  ] = "all";
-                const_values[ci++] = ~0;
-                const_names [ci] = NULL;
-                const_values[ci] = 0;
-
-                res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
-                                            const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
-                if (res < 0) {
-                    av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
-                    return res;
-                }
-            }
-        }
-        if (o->type == AV_OPT_TYPE_FLAGS) {
-            read_number(o, dst, NULL, NULL, &intnum);
-            if (cmd == '+')
-                d = intnum | (int64_t)d;
-            else if (cmd == '-')
-                d = intnum &~(int64_t)d;
-        }
-
-        if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
-            return ret;
-        val += i;
-        if (!i || !*val)
-            return 0;
-    }
-
-    return 0;
-}
-
-static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst)
-{
-    int ret;
-
-    if (!val || !strcmp(val, "none")) {
-        dst[0] =
-        dst[1] = 0;
-        return 0;
-    }
-    ret = av_parse_video_size(dst, dst + 1, val);
-    if (ret < 0)
-        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
-    return ret;
-}
-
-static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst)
-{
-    int ret;
-    if (!val) {
-        ret = AVERROR(EINVAL);
-    } else {
-        ret = av_parse_video_rate(dst, val);
-    }
-    if (ret < 0)
-        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val);
-    return ret;
-}
-
-static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst)
-{
-    int ret;
-
-    if (!val) {
-        return 0;
-    } else {
-        ret = av_parse_color(dst, val, -1, obj);
-        if (ret < 0)
-            av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val);
-        return ret;
-    }
-    return 0;
-}
-
-static const char *get_bool_name(int val)
-{
-    if (val < 0)
-        return "auto";
-    return val ? "true" : "false";
-}
-
-static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst)
-{
-    int n;
-
-    if (!val)
-        return 0;
-
-    if (!strcmp(val, "auto")) {
-        n = -1;
-    } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) {
-        n = 1;
-    } else if (av_match_name(val, "false,n,no,disable,disabled,off")) {
-        n = 0;
-    } else {
-        char *end = NULL;
-        n = strtol(val, &end, 10);
-        if (val + strlen(val) != end)
-            goto fail;
-    }
-
-    if (n < o->min || n > o->max)
-        goto fail;
-
-    *dst = n;
-    return 0;
-
-fail:
-    av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val);
-    return AVERROR(EINVAL);
-}
-
-static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst,
-                          int fmt_nb, int ((*get_fmt)(const char *)), const char *desc)
-{
-    int fmt, min, max;
-
-    if (!val || !strcmp(val, "none")) {
-        fmt = -1;
-    } else {
-        fmt = get_fmt(val);
-        if (fmt == -1) {
-            char *tail;
-            fmt = strtol(val, &tail, 0);
-            if (*tail || (unsigned)fmt >= fmt_nb) {
-                av_log(obj, AV_LOG_ERROR,
-                       "Unable to parse option value \"%s\" as %s\n", val, desc);
-                return AVERROR(EINVAL);
-            }
-        }
-    }
-
-    min = FFMAX(o->min, -1);
-    max = FFMIN(o->max, fmt_nb-1);
-
-    // hack for compatibility with old ffmpeg
-    if(min == 0 && max == 0) {
-        min = -1;
-        max = fmt_nb-1;
-    }
-
-    if (fmt < min || fmt > max) {
-        av_log(obj, AV_LOG_ERROR,
-               "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
-               fmt, o->name, desc, min, max);
-        return AVERROR(ERANGE);
-    }
-
-    *(int *)dst = fmt;
-    return 0;
-}
-
-static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
-{
-    return set_string_fmt(obj, o, val, dst,
-                          AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format");
-}
-
-static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
-{
-    return set_string_fmt(obj, o, val, dst,
-                          AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
-}
-
-int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
-{
-    int ret = 0;
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (!val && (o->type != AV_OPT_TYPE_STRING &&
-                 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
-                 o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
-                 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
-                 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
-        return AVERROR(EINVAL);
-
-    if (o->flags & AV_OPT_FLAG_READONLY)
-        return AVERROR(EINVAL);
-
-    dst = ((uint8_t *)target_obj) + o->offset;
-    switch (o->type) {
-    case AV_OPT_TYPE_BOOL:
-        return set_string_bool(obj, o, val, dst);
-    case AV_OPT_TYPE_STRING:
-        return set_string(obj, o, val, dst);
-    case AV_OPT_TYPE_BINARY:
-        return set_string_binary(obj, o, val, dst);
-    case AV_OPT_TYPE_FLAGS:
-    case AV_OPT_TYPE_INT:
-    case AV_OPT_TYPE_INT64:
-    case AV_OPT_TYPE_FLOAT:
-    case AV_OPT_TYPE_DOUBLE:
-    case AV_OPT_TYPE_RATIONAL:
-        return set_string_number(obj, target_obj, o, val, dst);
-    case AV_OPT_TYPE_IMAGE_SIZE:
-        return set_string_image_size(obj, o, val, dst);
-    case AV_OPT_TYPE_VIDEO_RATE: {
-        AVRational tmp;
-        ret = set_string_video_rate(obj, o, val, &tmp);
-        if (ret < 0)
-            return ret;
-        return write_number(obj, o, dst, 1, tmp.den, tmp.num);
-    }
-    case AV_OPT_TYPE_PIXEL_FMT:
-        return set_string_pixel_fmt(obj, o, val, dst);
-    case AV_OPT_TYPE_SAMPLE_FMT:
-        return set_string_sample_fmt(obj, o, val, dst);
-    case AV_OPT_TYPE_DURATION:
-        if (!val) {
-            *(int64_t *)dst = 0;
-            return 0;
-        } else {
-            if ((ret = av_parse_time(dst, val, 1)) < 0)
-                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val);
-            return ret;
-        }
-        break;
-    case AV_OPT_TYPE_COLOR:
-        return set_string_color(obj, o, val, dst);
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-        if (!val || !strcmp(val, "none")) {
-            *(int64_t *)dst = 0;
-        } else {
-            int64_t cl = av_get_channel_layout(val);
-            if (!cl) {
-                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
-                ret = AVERROR(EINVAL);
-            }
-            *(int64_t *)dst = cl;
-            return ret;
-        }
-        break;
-    }
-
-    av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
-    return AVERROR(EINVAL);
-}
-
-#define OPT_EVAL_NUMBER(name, opttype, vartype)                         \
-int av_opt_eval_ ## name(void *obj, const AVOption *o,                  \
-                         const char *val, vartype *name ## _out)        \
-{                                                                       \
-    if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)    \
-        return AVERROR(EINVAL);                                         \
-    return set_string_number(obj, obj, o, val, name ## _out);           \
-}
-
-OPT_EVAL_NUMBER(flags,  AV_OPT_TYPE_FLAGS,    int)
-OPT_EVAL_NUMBER(int,    AV_OPT_TYPE_INT,      int)
-OPT_EVAL_NUMBER(int64,  AV_OPT_TYPE_INT64,    int64_t)
-OPT_EVAL_NUMBER(float,  AV_OPT_TYPE_FLOAT,    float)
-OPT_EVAL_NUMBER(double, AV_OPT_TYPE_DOUBLE,   double)
-OPT_EVAL_NUMBER(q,      AV_OPT_TYPE_RATIONAL, AVRational)
-
-static int set_number(void *obj, const char *name, double num, int den, int64_t intnum,
-                      int search_flags)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-
-    if (o->flags & AV_OPT_FLAG_READONLY)
-        return AVERROR(EINVAL);
-
-    dst = ((uint8_t *)target_obj) + o->offset;
-    return write_number(obj, o, dst, num, den, intnum);
-}
-
-int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
-{
-    return set_number(obj, name, 1, 1, val, search_flags);
-}
-
-int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
-{
-    return set_number(obj, name, val, 1, 1, search_flags);
-}
-
-int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags)
-{
-    return set_number(obj, name, val.num, val.den, 1, search_flags);
-}
-
-int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
-{
-    void *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    uint8_t *ptr;
-    uint8_t **dst;
-    int *lendst;
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-
-    if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY)
-        return AVERROR(EINVAL);
-
-    ptr = len ? av_malloc(len) : NULL;
-    if (len && !ptr)
-        return AVERROR(ENOMEM);
-
-    dst    = (uint8_t **)(((uint8_t *)target_obj) + o->offset);
-    lendst = (int *)(dst + 1);
-
-    av_free(*dst);
-    *dst    = ptr;
-    *lendst = len;
-    if (len)
-        memcpy(ptr, val, len);
-
-    return 0;
-}
-
-int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags)
-{
-    void *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value set by option '%s' is not an image size.\n", o->name);
-        return AVERROR(EINVAL);
-    }
-    if (w<0 || h<0) {
-        av_log(obj, AV_LOG_ERROR,
-               "Invalid negative size value %dx%d for size '%s'\n", w, h, o->name);
-        return AVERROR(EINVAL);
-    }
-    *(int *)(((uint8_t *)target_obj)             + o->offset) = w;
-    *(int *)(((uint8_t *)target_obj+sizeof(int)) + o->offset) = h;
-    return 0;
-}
-
-int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags)
-{
-    void *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value set by option '%s' is not a video rate.\n", o->name);
-        return AVERROR(EINVAL);
-    }
-    if (val.num <= 0 || val.den <= 0)
-        return AVERROR(EINVAL);
-    return set_number(obj, name, val.num, val.den, 1, search_flags);
-}
-
-static int set_format(void *obj, const char *name, int fmt, int search_flags,
-                      enum AVOptionType type, const char *desc, int nb_fmts)
-{
-    void *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0,
-                                     search_flags, &target_obj);
-    int min, max;
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != type) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value set by option '%s' is not a %s format", name, desc);
-        return AVERROR(EINVAL);
-    }
-
-    min = FFMAX(o->min, -1);
-    max = FFMIN(o->max, nb_fmts-1);
-
-    if (fmt < min || fmt > max) {
-        av_log(obj, AV_LOG_ERROR,
-               "Value %d for parameter '%s' out of %s format range [%d - %d]\n",
-               fmt, name, desc, min, max);
-        return AVERROR(ERANGE);
-    }
-    *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;
-    return 0;
-}
-
-int av_opt_set_pixel_fmt(void *obj, const char *name, enum AVPixelFormat fmt, int search_flags)
-{
-    return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
-}
-
-int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
-{
-    return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
-}
-
-int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
-{
-    void *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value set by option '%s' is not a channel layout.\n", o->name);
-        return AVERROR(EINVAL);
-    }
-    *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
-    return 0;
-}
-
-int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
-                        int search_flags)
-{
-    void *target_obj;
-    AVDictionary **dst;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->flags & AV_OPT_FLAG_READONLY)
-        return AVERROR(EINVAL);
-
-    dst = (AVDictionary **)(((uint8_t *)target_obj) + o->offset);
-    av_dict_free(dst);
-    av_dict_copy(dst, val, 0);
-
-    return 0;
-}
-
-static void format_duration(char *buf, size_t size, int64_t d)
-{
-    char *e;
-
-    av_assert0(size >= 25);
-    if (d < 0 && d != INT64_MIN) {
-        *(buf++) = '-';
-        size--;
-        d = -d;
-    }
-    if (d == INT64_MAX)
-        snprintf(buf, size, "INT64_MAX");
-    else if (d == INT64_MIN)
-        snprintf(buf, size, "INT64_MIN");
-    else if (d > (int64_t)3600*1000000)
-        snprintf(buf, size, "%"PRId64":%02d:%02d.%06d", d / 3600000000,
-                 (int)((d / 60000000) % 60),
-                 (int)((d / 1000000) % 60),
-                 (int)(d % 1000000));
-    else if (d > 60*1000000)
-        snprintf(buf, size, "%d:%02d.%06d",
-                 (int)(d / 60000000),
-                 (int)((d / 1000000) % 60),
-                 (int)(d % 1000000));
-    else
-        snprintf(buf, size, "%d.%06d",
-                 (int)(d / 1000000),
-                 (int)(d % 1000000));
-    e = buf + strlen(buf);
-    while (e > buf && e[-1] == '0')
-        *(--e) = 0;
-    if (e > buf && e[-1] == '.')
-        *(--e) = 0;
-}
-
-int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    uint8_t *bin, buf[128];
-    int len, i, ret;
-    int64_t i64;
-
-    if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
-        return AVERROR_OPTION_NOT_FOUND;
-
-    dst = (uint8_t *)target_obj + o->offset;
-
-    buf[0] = 0;
-    switch (o->type) {
-    case AV_OPT_TYPE_BOOL:
-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
-        break;
-    case AV_OPT_TYPE_FLAGS:
-        ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);
-        break;
-    case AV_OPT_TYPE_INT:
-        ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
-        break;
-    case AV_OPT_TYPE_INT64:
-        ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
-        break;
-    case AV_OPT_TYPE_FLOAT:
-        ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst);
-        break;
-    case AV_OPT_TYPE_DOUBLE:
-        ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst);
-        break;
-    case AV_OPT_TYPE_VIDEO_RATE:
-    case AV_OPT_TYPE_RATIONAL:
-        ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
-        break;
-    case AV_OPT_TYPE_CONST:
-        ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl);
-        break;
-    case AV_OPT_TYPE_STRING:
-        if (*(uint8_t **)dst) {
-            *out_val = av_strdup(*(uint8_t **)dst);
-        } else if (search_flags & AV_OPT_ALLOW_NULL) {
-            *out_val = NULL;
-            return 0;
-        } else {
-            *out_val = av_strdup("");
-        }
-        return *out_val ? 0 : AVERROR(ENOMEM);
-    case AV_OPT_TYPE_BINARY:
-        if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
-            *out_val = NULL;
-            return 0;
-        }
-        len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
-        if ((uint64_t)len * 2 + 1 > INT_MAX)
-            return AVERROR(EINVAL);
-        if (!(*out_val = av_malloc(len * 2 + 1)))
-            return AVERROR(ENOMEM);
-        if (!len) {
-            *out_val[0] = '\0';
-            return 0;
-        }
-        bin = *(uint8_t **)dst;
-        for (i = 0; i < len; i++)
-            snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
-        return 0;
-    case AV_OPT_TYPE_IMAGE_SIZE:
-        ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
-        break;
-    case AV_OPT_TYPE_PIXEL_FMT:
-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
-        break;
-    case AV_OPT_TYPE_SAMPLE_FMT:
-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
-        break;
-    case AV_OPT_TYPE_DURATION:
-        i64 = *(int64_t *)dst;
-        format_duration(buf, sizeof(buf), i64);
-        ret = strlen(buf); // no overflow possible, checked by an assert
-        break;
-    case AV_OPT_TYPE_COLOR:
-        ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
-                       (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
-                       (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
-        break;
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-        i64 = *(int64_t *)dst;
-        ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
-        break;
-    default:
-        return AVERROR(EINVAL);
-    }
-
-    if (ret >= sizeof(buf))
-        return AVERROR(EINVAL);
-    *out_val = av_strdup(buf);
-    return *out_val ? 0 : AVERROR(ENOMEM);
-}
-
-static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
-                      int search_flags)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    if (!o || !target_obj)
-        goto error;
-
-    dst = ((uint8_t *)target_obj) + o->offset;
-
-    if (o_out) *o_out= o;
-
-    return read_number(o, dst, num, den, intnum);
-
-error:
-    *den    =
-    *intnum = 0;
-    return -1;
-}
-
-int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
-{
-    int64_t intnum = 1;
-    double num = 1;
-    int ret, den = 1;
-
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
-        return ret;
-    *out_val = num * intnum / den;
-    return 0;
-}
-
-int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
-{
-    int64_t intnum = 1;
-    double num = 1;
-    int ret, den = 1;
-
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
-        return ret;
-    *out_val = num * intnum / den;
-    return 0;
-}
-
-int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
-{
-    int64_t intnum = 1;
-    double num = 1;
-    int ret, den = 1;
-
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
-        return ret;
-
-    if (num == 1.0 && (int)intnum == intnum)
-        *out_val = (AVRational){intnum, den};
-    else
-        *out_val = av_d2q(num*intnum/den, 1<<24);
-    return 0;
-}
-
-int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value for option '%s' is not an image size.\n", name);
-        return AVERROR(EINVAL);
-    }
-
-    dst = ((uint8_t*)target_obj) + o->offset;
-    if (w_out) *w_out = *(int *)dst;
-    if (h_out) *h_out = *((int *)dst+1);
-    return 0;
-}
-
-int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
-{
-    int64_t intnum = 1;
-    double     num = 1;
-    int   ret, den = 1;
-
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
-        return ret;
-
-    if (num == 1.0 && (int)intnum == intnum)
-        *out_val = (AVRational) { intnum, den };
-    else
-        *out_val = av_d2q(num * intnum / den, 1 << 24);
-    return 0;
-}
-
-static int get_format(void *obj, const char *name, int search_flags, int *out_fmt,
-                      enum AVOptionType type, const char *desc)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != type) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value for option '%s' is not a %s format.\n", desc, name);
-        return AVERROR(EINVAL);
-    }
-
-    dst = ((uint8_t*)target_obj) + o->offset;
-    *out_fmt = *(int *)dst;
-    return 0;
-}
-
-int av_opt_get_pixel_fmt(void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt)
-{
-    return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
-}
-
-int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
-{
-    return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
-}
-
-int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
-{
-    void *dst, *target_obj;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
-        av_log(obj, AV_LOG_ERROR,
-               "The value for option '%s' is not a channel layout.\n", name);
-        return AVERROR(EINVAL);
-    }
-
-    dst = ((uint8_t*)target_obj) + o->offset;
-    *cl = *(int64_t *)dst;
-    return 0;
-}
-
-int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val)
-{
-    void *target_obj;
-    AVDictionary *src;
-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-
-    if (!o || !target_obj)
-        return AVERROR_OPTION_NOT_FOUND;
-    if (o->type != AV_OPT_TYPE_DICT)
-        return AVERROR(EINVAL);
-
-    src = *(AVDictionary **)(((uint8_t *)target_obj) + o->offset);
-    av_dict_copy(out_val, src, 0);
-
-    return 0;
-}
-
-int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
-{
-    const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0);
-    const AVOption *flag  = av_opt_find(obj, flag_name,
-                                        field ? field->unit : NULL, 0, 0);
-    int64_t res;
-
-    if (!field || !flag || flag->type != AV_OPT_TYPE_CONST ||
-        av_opt_get_int(obj, field_name, 0, &res) < 0)
-        return 0;
-    return res & flag->default_val.i64;
-}
-
-static void log_value(void *av_log_obj, int level, double d)
-{
-    if      (d == INT_MAX) {
-        av_log(av_log_obj, level, "INT_MAX");
-    } else if (d == INT_MIN) {
-        av_log(av_log_obj, level, "INT_MIN");
-    } else if (d == UINT32_MAX) {
-        av_log(av_log_obj, level, "UINT32_MAX");
-    } else if (d == (double)INT64_MAX) {
-        av_log(av_log_obj, level, "I64_MAX");
-    } else if (d == INT64_MIN) {
-        av_log(av_log_obj, level, "I64_MIN");
-    } else if (d == FLT_MAX) {
-        av_log(av_log_obj, level, "FLT_MAX");
-    } else if (d == FLT_MIN) {
-        av_log(av_log_obj, level, "FLT_MIN");
-    } else if (d == -FLT_MAX) {
-        av_log(av_log_obj, level, "-FLT_MAX");
-    } else if (d == -FLT_MIN) {
-        av_log(av_log_obj, level, "-FLT_MIN");
-    } else if (d == DBL_MAX) {
-        av_log(av_log_obj, level, "DBL_MAX");
-    } else if (d == DBL_MIN) {
-        av_log(av_log_obj, level, "DBL_MIN");
-    } else if (d == -DBL_MAX) {
-        av_log(av_log_obj, level, "-DBL_MAX");
-    } else if (d == -DBL_MIN) {
-        av_log(av_log_obj, level, "-DBL_MIN");
-    } else {
-        av_log(av_log_obj, level, "%g", d);
-    }
-}
-
-static const char *get_opt_const_name(void *obj, const char *unit, int64_t value)
-{
-    const AVOption *opt = NULL;
-
-    if (!unit)
-        return NULL;
-    while ((opt = av_opt_next(obj, opt)))
-        if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
-            opt->default_val.i64 == value)
-            return opt->name;
-    return NULL;
-}
-
-static char *get_opt_flags_string(void *obj, const char *unit, int64_t value)
-{
-    const AVOption *opt = NULL;
-    char flags[512];
-
-    flags[0] = 0;
-    if (!unit)
-        return NULL;
-    while ((opt = av_opt_next(obj, opt))) {
-        if (opt->type == AV_OPT_TYPE_CONST && !strcmp(opt->unit, unit) &&
-            opt->default_val.i64 & value) {
-            if (flags[0])
-                av_strlcatf(flags, sizeof(flags), "+");
-            av_strlcatf(flags, sizeof(flags), "%s", opt->name);
-        }
-    }
-    if (flags[0])
-        return av_strdup(flags);
-    return NULL;
-}
-
-static void opt_list(void *obj, void *av_log_obj, const char *unit,
-                     int req_flags, int rej_flags)
-{
-    const AVOption *opt = NULL;
-    AVOptionRanges *r;
-    int i;
-
-    while ((opt = av_opt_next(obj, opt))) {
-        if (!(opt->flags & req_flags) || (opt->flags & rej_flags))
-            continue;
-
-        /* Don't print CONST's on level one.
-         * Don't print anything but CONST's on level two.
-         * Only print items from the requested unit.
-         */
-        if (!unit && opt->type == AV_OPT_TYPE_CONST)
-            continue;
-        else if (unit && opt->type != AV_OPT_TYPE_CONST)
-            continue;
-        else if (unit && opt->type == AV_OPT_TYPE_CONST && strcmp(unit, opt->unit))
-            continue;
-        else if (unit && opt->type == AV_OPT_TYPE_CONST)
-            av_log(av_log_obj, AV_LOG_INFO, "     %-15s ", opt->name);
-        else
-            av_log(av_log_obj, AV_LOG_INFO, "  %s%-17s ",
-                   (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-",
-                   opt->name);
-
-        switch (opt->type) {
-            case AV_OPT_TYPE_FLAGS:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
-                break;
-            case AV_OPT_TYPE_INT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
-                break;
-            case AV_OPT_TYPE_INT64:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
-                break;
-            case AV_OPT_TYPE_DOUBLE:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
-                break;
-            case AV_OPT_TYPE_FLOAT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
-                break;
-            case AV_OPT_TYPE_STRING:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
-                break;
-            case AV_OPT_TYPE_RATIONAL:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
-                break;
-            case AV_OPT_TYPE_BINARY:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
-                break;
-            case AV_OPT_TYPE_IMAGE_SIZE:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
-                break;
-            case AV_OPT_TYPE_VIDEO_RATE:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
-                break;
-            case AV_OPT_TYPE_PIXEL_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
-                break;
-            case AV_OPT_TYPE_SAMPLE_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
-                break;
-            case AV_OPT_TYPE_DURATION:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
-                break;
-            case AV_OPT_TYPE_COLOR:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
-                break;
-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
-                break;
-            case AV_OPT_TYPE_BOOL:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
-                break;
-            case AV_OPT_TYPE_CONST:
-            default:
-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
-                break;
-        }
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT)         ? 'X' : '.');
-        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY)       ? 'R' : '.');
-
-        if (opt->help)
-            av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help);
-
-        if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
-            switch (opt->type) {
-            case AV_OPT_TYPE_INT:
-            case AV_OPT_TYPE_INT64:
-            case AV_OPT_TYPE_DOUBLE:
-            case AV_OPT_TYPE_FLOAT:
-            case AV_OPT_TYPE_RATIONAL:
-                for (i = 0; i < r->nb_ranges; i++) {
-                    av_log(av_log_obj, AV_LOG_INFO, " (from ");
-                    log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_min);
-                    av_log(av_log_obj, AV_LOG_INFO, " to ");
-                    log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
-                    av_log(av_log_obj, AV_LOG_INFO, ")");
-                }
-                break;
-            }
-            av_opt_freep_ranges(&r);
-        }
-
-        if (opt->type != AV_OPT_TYPE_CONST  &&
-            opt->type != AV_OPT_TYPE_BINARY &&
-                !((opt->type == AV_OPT_TYPE_COLOR      ||
-                   opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
-                   opt->type == AV_OPT_TYPE_STRING     ||
-                   opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
-                  !opt->default_val.str)) {
-            av_log(av_log_obj, AV_LOG_INFO, " (default ");
-            switch (opt->type) {
-            case AV_OPT_TYPE_BOOL:
-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid"));
-                break;
-            case AV_OPT_TYPE_FLAGS: {
-                char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
-                if (def_flags) {
-                    av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
-                    av_freep(&def_flags);
-                } else {
-                    av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
-                }
-                break;
-            }
-            case AV_OPT_TYPE_DURATION: {
-                char buf[25];
-                format_duration(buf, sizeof(buf), opt->default_val.i64);
-                av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
-                break;
-            }
-            case AV_OPT_TYPE_INT:
-            case AV_OPT_TYPE_INT64: {
-                const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
-                if (def_const)
-                    av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
-                else
-                    log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
-                break;
-            }
-            case AV_OPT_TYPE_DOUBLE:
-            case AV_OPT_TYPE_FLOAT:
-                log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
-                break;
-            case AV_OPT_TYPE_RATIONAL: {
-                AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
-                av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
-                break;
-            case AV_OPT_TYPE_PIXEL_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
-                break;
-            case AV_OPT_TYPE_SAMPLE_FMT:
-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
-                break;
-            case AV_OPT_TYPE_COLOR:
-            case AV_OPT_TYPE_IMAGE_SIZE:
-            case AV_OPT_TYPE_STRING:
-            case AV_OPT_TYPE_VIDEO_RATE:
-                av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
-                break;
-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
-                av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
-                break;
-            }
-            av_log(av_log_obj, AV_LOG_INFO, ")");
-        }
-
-        av_log(av_log_obj, AV_LOG_INFO, "\n");
-        if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
-            opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags);
-    }
-}
-
-int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
-{
-    if (!obj)
-        return -1;
-
-    av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass **)obj)->class_name);
-
-    opt_list(obj, av_log_obj, NULL, req_flags, rej_flags);
-
-    return 0;
-}
-
-void av_opt_set_defaults(void *s)
-{
-    av_opt_set_defaults2(s, 0, 0);
-}
-
-void av_opt_set_defaults2(void *s, int mask, int flags)
-{
-    const AVOption *opt = NULL;
-    while ((opt = av_opt_next(s, opt))) {
-        void *dst = ((uint8_t*)s) + opt->offset;
-
-        if ((opt->flags & mask) != flags)
-            continue;
-
-        if (opt->flags & AV_OPT_FLAG_READONLY)
-            continue;
-
-        switch (opt->type) {
-            case AV_OPT_TYPE_CONST:
-                /* Nothing to be done here */
-                break;
-            case AV_OPT_TYPE_BOOL:
-            case AV_OPT_TYPE_FLAGS:
-            case AV_OPT_TYPE_INT:
-            case AV_OPT_TYPE_INT64:
-            case AV_OPT_TYPE_DURATION:
-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
-            case AV_OPT_TYPE_PIXEL_FMT:
-            case AV_OPT_TYPE_SAMPLE_FMT:
-                write_number(s, opt, dst, 1, 1, opt->default_val.i64);
-                break;
-            case AV_OPT_TYPE_DOUBLE:
-            case AV_OPT_TYPE_FLOAT: {
-                double val;
-                val = opt->default_val.dbl;
-                write_number(s, opt, dst, val, 1, 1);
-            }
-            break;
-            case AV_OPT_TYPE_RATIONAL: {
-                AVRational val;
-                val = av_d2q(opt->default_val.dbl, INT_MAX);
-                write_number(s, opt, dst, 1, val.den, val.num);
-            }
-            break;
-            case AV_OPT_TYPE_COLOR:
-                set_string_color(s, opt, opt->default_val.str, dst);
-                break;
-            case AV_OPT_TYPE_STRING:
-                set_string(s, opt, opt->default_val.str, dst);
-                break;
-            case AV_OPT_TYPE_IMAGE_SIZE:
-                set_string_image_size(s, opt, opt->default_val.str, dst);
-                break;
-            case AV_OPT_TYPE_VIDEO_RATE:
-                set_string_video_rate(s, opt, opt->default_val.str, dst);
-                break;
-            case AV_OPT_TYPE_BINARY:
-                set_string_binary(s, opt, opt->default_val.str, dst);
-                break;
-            case AV_OPT_TYPE_DICT:
-                /* Cannot set defaults for these types */
-            break;
-        default:
-            av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n",
-                   opt->type, opt->name);
-        }
-    }
-}
-
-/**
- * Store the value in the field in ctx that is named like key.
- * ctx must be an AVClass context, storing is done using AVOptions.
- *
- * @param buf the string to parse, buf will be updated to point at the
- * separator just after the parsed key/value pair
- * @param key_val_sep a 0-terminated list of characters used to
- * separate key from value
- * @param pairs_sep a 0-terminated list of characters used to separate
- * two pairs from each other
- * @return 0 if the key/value pair has been successfully parsed and
- * set, or a negative value corresponding to an AVERROR code in case
- * of error:
- * AVERROR(EINVAL) if the key/value pair cannot be parsed,
- * the error code issued by av_opt_set() if the key/value pair
- * cannot be set
- */
-static int parse_key_value_pair(void *ctx, const char **buf,
-                                const char *key_val_sep, const char *pairs_sep)
-{
-    char *key = av_get_token(buf, key_val_sep);
-    char *val;
-    int ret;
-
-    if (!key)
-        return AVERROR(ENOMEM);
-
-    if (*key && strspn(*buf, key_val_sep)) {
-        (*buf)++;
-        val = av_get_token(buf, pairs_sep);
-        if (!val) {
-            av_freep(&key);
-            return AVERROR(ENOMEM);
-        }
-    } else {
-        av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
-        av_free(key);
-        return AVERROR(EINVAL);
-    }
-
-    av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
-
-    ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
-    if (ret == AVERROR_OPTION_NOT_FOUND)
-        av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
-
-    av_free(key);
-    av_free(val);
-    return ret;
-}
-
-int av_set_options_string(void *ctx, const char *opts,
-                          const char *key_val_sep, const char *pairs_sep)
-{
-    int ret, count = 0;
-
-    if (!opts)
-        return 0;
-
-    while (*opts) {
-        if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
-            return ret;
-        count++;
-
-        if (*opts)
-            opts++;
-    }
-
-    return count;
-}
-
-#define WHITESPACES " \n\t\r"
-
-static int is_key_char(char c)
-{
-    return (unsigned)((c | 32) - 'a') < 26 ||
-           (unsigned)(c - '0') < 10 ||
-           c == '-' || c == '_' || c == '/' || c == '.';
-}
-
-/**
- * Read a key from a string.
- *
- * The key consists of is_key_char characters and must be terminated by a
- * character from the delim string; spaces are ignored.
- *
- * @return  0 for success (even with ellipsis), <0 for failure
- */
-static int get_key(const char **ropts, const char *delim, char **rkey)
-{
-    const char *opts = *ropts;
-    const char *key_start, *key_end;
-
-    key_start = opts += strspn(opts, WHITESPACES);
-    while (is_key_char(*opts))
-        opts++;
-    key_end = opts;
-    opts += strspn(opts, WHITESPACES);
-    if (!*opts || !strchr(delim, *opts))
-        return AVERROR(EINVAL);
-    opts++;
-    if (!(*rkey = av_malloc(key_end - key_start + 1)))
-        return AVERROR(ENOMEM);
-    memcpy(*rkey, key_start, key_end - key_start);
-    (*rkey)[key_end - key_start] = 0;
-    *ropts = opts;
-    return 0;
-}
-
-int av_opt_get_key_value(const char **ropts,
-                         const char *key_val_sep, const char *pairs_sep,
-                         unsigned flags,
-                         char **rkey, char **rval)
-{
-    int ret;
-    char *key = NULL, *val;
-    const char *opts = *ropts;
-
-    if ((ret = get_key(&opts, key_val_sep, &key)) < 0 &&
-        !(flags & AV_OPT_FLAG_IMPLICIT_KEY))
-        return AVERROR(EINVAL);
-    if (!(val = av_get_token(&opts, pairs_sep))) {
-        av_free(key);
-        return AVERROR(ENOMEM);
-    }
-    *ropts = opts;
-    *rkey  = key;
-    *rval  = val;
-    return 0;
-}
-
-int av_opt_set_from_string(void *ctx, const char *opts,
-                           const char *const *shorthand,
-                           const char *key_val_sep, const char *pairs_sep)
-{
-    int ret, count = 0;
-    const char *dummy_shorthand = NULL;
-    char *av_uninit(parsed_key), *av_uninit(value);
-    const char *key;
-
-    if (!opts)
-        return 0;
-    if (!shorthand)
-        shorthand = &dummy_shorthand;
-
-    while (*opts) {
-        ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
-                                   *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
-                                   &parsed_key, &value);
-        if (ret < 0) {
-            if (ret == AVERROR(EINVAL))
-                av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
-            else
-                av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
-                       av_err2str(ret));
-            return ret;
-        }
-        if (*opts)
-            opts++;
-        if (parsed_key) {
-            key = parsed_key;
-            while (*shorthand) /* discard all remaining shorthand */
-                shorthand++;
-        } else {
-            key = *(shorthand++);
-        }
-
-        av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
-        if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
-            if (ret == AVERROR_OPTION_NOT_FOUND)
-                av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
-            av_free(value);
-            av_free(parsed_key);
-            return ret;
-        }
-
-        av_free(value);
-        av_free(parsed_key);
-        count++;
-    }
-    return count;
-}
-
-void av_opt_free(void *obj)
-{
-    const AVOption *o = NULL;
-    while ((o = av_opt_next(obj, o))) {
-        switch (o->type) {
-        case AV_OPT_TYPE_STRING:
-        case AV_OPT_TYPE_BINARY:
-            av_freep((uint8_t *)obj + o->offset);
-            break;
-
-        case AV_OPT_TYPE_DICT:
-            av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
-            break;
-
-        default:
-            break;
-        }
-    }
-}
-
-int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
-{
-    AVDictionaryEntry *t = NULL;
-    AVDictionary    *tmp = NULL;
-    int ret = 0;
-
-    if (!options)
-        return 0;
-
-    while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
-        ret = av_opt_set(obj, t->key, t->value, search_flags);
-        if (ret == AVERROR_OPTION_NOT_FOUND)
-            ret = av_dict_set(&tmp, t->key, t->value, 0);
-        if (ret < 0) {
-            av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
-            av_dict_free(&tmp);
-            return ret;
-        }
-        ret = 0;
-    }
-    av_dict_free(options);
-    *options = tmp;
-    return ret;
-}
-
-int av_opt_set_dict(void *obj, AVDictionary **options)
-{
-    return av_opt_set_dict2(obj, options, 0);
-}
-
-const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
-                            int opt_flags, int search_flags)
-{
-    return av_opt_find2(obj, name, unit, opt_flags, search_flags, NULL);
-}
-
-const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
-                             int opt_flags, int search_flags, void **target_obj)
-{
-    const AVClass  *c;
-    const AVOption *o = NULL;
-
-    if(!obj)
-        return NULL;
-
-    c= *(AVClass**)obj;
-
-    if (!c)
-        return NULL;
-
-    if (search_flags & AV_OPT_SEARCH_CHILDREN) {
-        if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
-            const AVClass *child = NULL;
-            while (child = av_opt_child_class_next(c, child))
-                if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
-                    return o;
-        } else {
-            void *child = NULL;
-            while (child = av_opt_child_next(obj, child))
-                if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))
-                    return o;
-        }
-    }
-
-    while (o = av_opt_next(obj, o)) {
-        if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
-            ((!unit && o->type != AV_OPT_TYPE_CONST) ||
-             (unit  && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
-            if (target_obj) {
-                if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
-                    *target_obj = obj;
-                else
-                    *target_obj = NULL;
-            }
-            return o;
-        }
-    }
-    return NULL;
-}
-
-void *av_opt_child_next(void *obj, void *prev)
-{
-    const AVClass *c = *(AVClass **)obj;
-    if (c->child_next)
-        return c->child_next(obj, prev);
-    return NULL;
-}
-
-const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
-{
-    if (parent->child_class_next)
-        return parent->child_class_next(prev);
-    return NULL;
-}
-
-void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
-{
-    const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
-    if(!opt)
-        return NULL;
-    return (uint8_t*)obj + opt->offset;
-}
-
-static int opt_size(enum AVOptionType type)
-{
-    switch(type) {
-    case AV_OPT_TYPE_BOOL:
-    case AV_OPT_TYPE_INT:
-    case AV_OPT_TYPE_FLAGS:
-        return sizeof(int);
-    case AV_OPT_TYPE_DURATION:
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-    case AV_OPT_TYPE_INT64:
-        return sizeof(int64_t);
-    case AV_OPT_TYPE_DOUBLE:
-        return sizeof(double);
-    case AV_OPT_TYPE_FLOAT:
-        return sizeof(float);
-    case AV_OPT_TYPE_STRING:
-        return sizeof(uint8_t*);
-    case AV_OPT_TYPE_VIDEO_RATE:
-    case AV_OPT_TYPE_RATIONAL:
-        return sizeof(AVRational);
-    case AV_OPT_TYPE_BINARY:
-        return sizeof(uint8_t*) + sizeof(int);
-    case AV_OPT_TYPE_IMAGE_SIZE:
-        return sizeof(int[2]);
-    case AV_OPT_TYPE_PIXEL_FMT:
-        return sizeof(enum AVPixelFormat);
-    case AV_OPT_TYPE_SAMPLE_FMT:
-        return sizeof(enum AVSampleFormat);
-    case AV_OPT_TYPE_COLOR:
-        return 4;
-    }
-    return AVERROR(EINVAL);
-}
-
-int av_opt_copy(void *dst, const void *src)
-{
-    const AVOption *o = NULL;
-    const AVClass *c;
-    int ret = 0;
-
-    if (!src)
-        return AVERROR(EINVAL);
-
-    c = *(AVClass **)src;
-    if (!c || c != *(AVClass **)dst)
-        return AVERROR(EINVAL);
-
-    while ((o = av_opt_next(src, o))) {
-        void *field_dst = (uint8_t *)dst + o->offset;
-        void *field_src = (uint8_t *)src + o->offset;
-        uint8_t **field_dst8 = (uint8_t **)field_dst;
-        uint8_t **field_src8 = (uint8_t **)field_src;
-
-        if (o->type == AV_OPT_TYPE_STRING) {
-            if (*field_dst8 != *field_src8)
-                av_freep(field_dst8);
-            *field_dst8 = av_strdup(*field_src8);
-            if (*field_src8 && !*field_dst8)
-                ret = AVERROR(ENOMEM);
-        } else if (o->type == AV_OPT_TYPE_BINARY) {
-            int len = *(int *)(field_src8 + 1);
-            if (*field_dst8 != *field_src8)
-                av_freep(field_dst8);
-            *field_dst8 = av_memdup(*field_src8, len);
-            if (len && !*field_dst8) {
-                ret = AVERROR(ENOMEM);
-                len = 0;
-            }
-            *(int *)(field_dst8 + 1) = len;
-        } else if (o->type == AV_OPT_TYPE_CONST) {
-            // do nothing
-        } else if (o->type == AV_OPT_TYPE_DICT) {
-            AVDictionary **sdict = (AVDictionary **) field_src;
-            AVDictionary **ddict = (AVDictionary **) field_dst;
-            if (*sdict != *ddict)
-                av_dict_free(ddict);
-            *ddict = NULL;
-            av_dict_copy(ddict, *sdict, 0);
-            if (av_dict_count(*sdict) != av_dict_count(*ddict))
-                ret = AVERROR(ENOMEM);
-        } else {
-            int size = opt_size(o->type);
-            if (size < 0)
-                ret = size;
-            else
-                memcpy(field_dst, field_src, size);
-        }
-    }
-    return ret;
-}
-
-int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
-{
-    int ret;
-    const AVClass *c = *(AVClass**)obj;
-    int (*callback)(AVOptionRanges **, void *obj, const char *key, int flags) = NULL;
-
-    if (c->version > (52 << 16 | 11 << 8))
-        callback = c->query_ranges;
-
-    if (!callback)
-        callback = av_opt_query_ranges_default;
-
-    ret = callback(ranges_arg, obj, key, flags);
-    if (ret >= 0) {
-        if (!(flags & AV_OPT_MULTI_COMPONENT_RANGE))
-            ret = 1;
-        (*ranges_arg)->nb_components = ret;
-    }
-    return ret;
-}
-
-int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
-{
-    AVOptionRanges *ranges = av_mallocz(sizeof(*ranges));
-    AVOptionRange **range_array = av_mallocz(sizeof(void*));
-    AVOptionRange *range = av_mallocz(sizeof(*range));
-    const AVOption *field = av_opt_find(obj, key, NULL, 0, flags);
-    int ret;
-
-    *ranges_arg = NULL;
-
-    if (!ranges || !range || !range_array || !field) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    ranges->range = range_array;
-    ranges->range[0] = range;
-    ranges->nb_ranges = 1;
-    ranges->nb_components = 1;
-    range->is_range = 1;
-    range->value_min = field->min;
-    range->value_max = field->max;
-
-    switch (field->type) {
-    case AV_OPT_TYPE_BOOL:
-    case AV_OPT_TYPE_INT:
-    case AV_OPT_TYPE_INT64:
-    case AV_OPT_TYPE_PIXEL_FMT:
-    case AV_OPT_TYPE_SAMPLE_FMT:
-    case AV_OPT_TYPE_FLOAT:
-    case AV_OPT_TYPE_DOUBLE:
-    case AV_OPT_TYPE_DURATION:
-    case AV_OPT_TYPE_COLOR:
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-        break;
-    case AV_OPT_TYPE_STRING:
-        range->component_min = 0;
-        range->component_max = 0x10FFFF; // max unicode value
-        range->value_min = -1;
-        range->value_max = INT_MAX;
-        break;
-    case AV_OPT_TYPE_RATIONAL:
-        range->component_min = INT_MIN;
-        range->component_max = INT_MAX;
-        break;
-    case AV_OPT_TYPE_IMAGE_SIZE:
-        range->component_min = 0;
-        range->component_max = INT_MAX/128/8;
-        range->value_min = 0;
-        range->value_max = INT_MAX/8;
-        break;
-    case AV_OPT_TYPE_VIDEO_RATE:
-        range->component_min = 1;
-        range->component_max = INT_MAX;
-        range->value_min = 1;
-        range->value_max = INT_MAX;
-        break;
-    default:
-        ret = AVERROR(ENOSYS);
-        goto fail;
-    }
-
-    *ranges_arg = ranges;
-    return 1;
-fail:
-    av_free(ranges);
-    av_free(range);
-    av_free(range_array);
-    return ret;
-}
-
-void av_opt_freep_ranges(AVOptionRanges **rangesp)
-{
-    int i;
-    AVOptionRanges *ranges = *rangesp;
-
-    if (!ranges)
-        return;
-
-    for (i = 0; i < ranges->nb_ranges * ranges->nb_components; i++) {
-        AVOptionRange *range = ranges->range[i];
-        if (range) {
-            av_freep(&range->str);
-            av_freep(&ranges->range[i]);
-        }
-    }
-    av_freep(&ranges->range);
-    av_freep(rangesp);
-}
-
-int av_opt_is_set_to_default(void *obj, const AVOption *o)
-{
-    int64_t i64;
-    double d, d2;
-    float f;
-    AVRational q;
-    int ret, w, h;
-    char *str;
-    void *dst;
-
-    if (!o || !obj)
-        return AVERROR(EINVAL);
-
-    dst = ((uint8_t*)obj) + o->offset;
-
-    switch (o->type) {
-    case AV_OPT_TYPE_CONST:
-        return 1;
-    case AV_OPT_TYPE_BOOL:
-    case AV_OPT_TYPE_FLAGS:
-    case AV_OPT_TYPE_PIXEL_FMT:
-    case AV_OPT_TYPE_SAMPLE_FMT:
-    case AV_OPT_TYPE_INT:
-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
-    case AV_OPT_TYPE_DURATION:
-    case AV_OPT_TYPE_INT64:
-        read_number(o, dst, NULL, NULL, &i64);
-        return o->default_val.i64 == i64;
-    case AV_OPT_TYPE_STRING:
-        str = *(char **)dst;
-        if (str == o->default_val.str) //2 NULLs
-            return 1;
-        if (!str || !o->default_val.str) //1 NULL
-            return 0;
-        return !strcmp(str, o->default_val.str);
-    case AV_OPT_TYPE_DOUBLE:
-        read_number(o, dst, &d, NULL, NULL);
-        return o->default_val.dbl == d;
-    case AV_OPT_TYPE_FLOAT:
-        read_number(o, dst, &d, NULL, NULL);
-        f = o->default_val.dbl;
-        d2 = f;
-        return d2 == d;
-    case AV_OPT_TYPE_RATIONAL:
-        q = av_d2q(o->default_val.dbl, INT_MAX);
-        return !av_cmp_q(*(AVRational*)dst, q);
-    case AV_OPT_TYPE_BINARY: {
-        struct {
-            uint8_t *data;
-            int size;
-        } tmp = {0};
-        int opt_size = *(int *)((void **)dst + 1);
-        void *opt_ptr = *(void **)dst;
-        if (!opt_size && (!o->default_val.str || !strlen(o->default_val.str)))
-            return 1;
-        if (!opt_size ||  !o->default_val.str || !strlen(o->default_val.str ))
-            return 0;
-        if (opt_size != strlen(o->default_val.str) / 2)
-            return 0;
-        ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);
-        if (!ret)
-            ret = !memcmp(opt_ptr, tmp.data, tmp.size);
-        av_free(tmp.data);
-        return ret;
-    }
-    case AV_OPT_TYPE_DICT:
-        /* Binary and dict have not default support yet. Any pointer is not default. */
-        return !!(*(void **)dst);
-    case AV_OPT_TYPE_IMAGE_SIZE:
-        if (!o->default_val.str || !strcmp(o->default_val.str, "none"))
-            w = h = 0;
-        else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)
-            return ret;
-        return (w == *(int *)dst) && (h == *((int *)dst+1));
-    case AV_OPT_TYPE_VIDEO_RATE:
-        q = (AVRational){0, 0};
-        if (o->default_val.str) {
-            if ((ret = av_parse_video_rate(&q, o->default_val.str)) < 0)
-                return ret;
-        }
-        return !av_cmp_q(*(AVRational*)dst, q);
-    case AV_OPT_TYPE_COLOR: {
-        uint8_t color[4] = {0, 0, 0, 0};
-        if (o->default_val.str) {
-            if ((ret = av_parse_color(color, o->default_val.str, -1, NULL)) < 0)
-                return ret;
-        }
-        return !memcmp(color, dst, sizeof(color));
-    }
-    default:
-        av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);
-        break;
-    }
-    return AVERROR_PATCHWELCOME;
-}
-
-int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
-{
-    const AVOption *o;
-    void *target;
-    if (!obj)
-        return AVERROR(EINVAL);
-    o = av_opt_find2(obj, name, NULL, 0, search_flags, &target);
-    if (!o)
-        return AVERROR_OPTION_NOT_FOUND;
-    return av_opt_is_set_to_default(target, o);
-}
-
-int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
-                     const char key_val_sep, const char pairs_sep)
-{
-    const AVOption *o = NULL;
-    uint8_t *buf;
-    AVBPrint bprint;
-    int ret, cnt = 0;
-    const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
-
-    if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
-        pairs_sep == '\\' || key_val_sep == '\\') {
-        av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
-        return AVERROR(EINVAL);
-    }
-
-    if (!obj || !buffer)
-        return AVERROR(EINVAL);
-
-    *buffer = NULL;
-    av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
-
-    while (o = av_opt_next(obj, o)) {
-        if (o->type == AV_OPT_TYPE_CONST)
-            continue;
-        if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
-            continue;
-        else if (((o->flags & opt_flags) != opt_flags))
-            continue;
-        if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
-            continue;
-        if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
-            av_bprint_finalize(&bprint, NULL);
-            return ret;
-        }
-        if (buf) {
-            if (cnt++)
-                av_bprint_append_data(&bprint, &pairs_sep, 1);
-            av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
-            av_bprint_append_data(&bprint, &key_val_sep, 1);
-            av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
-            av_freep(&buf);
-        }
-    }
-    av_bprint_finalize(&bprint, buffer);
-    return 0;
-}
--- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java
+++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/datahandling/DataStorageManager.java
@@ -262,17 +262,17 @@ public class DataStorageManager {
     }
 
     public synchronized boolean isDirEmpty() {
         return (mFileList.mFiles == null || mFileList.mFiles.length < 1);
     }
 
     /* Pass filename returned from dataToSend() */
     public synchronized boolean delete(String filename) {
-        if (filename == MEMORY_BUFFER_NAME) {
+        if (filename.equals(MEMORY_BUFFER_NAME)) {
             mCurrentReportsSendBuffer = null;
             return true;
         }
 
         final File file = new File(mReportsDir, filename);
         final boolean ok = file.delete();
         mFileList.update(mReportsDir);
         return ok;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5497,8 +5497,13 @@ pref("media.seekToNextFrame.enabled", tr
 #if !defined(RELEASE_BUILD)
 pref("osfile.reset_worker_delay", 30000);
 #endif
 
 #if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
 pref("dom.webkitBlink.dirPicker.enabled", true);
 pref("dom.webkitBlink.filesystem.enabled", true);
 #endif
+
+#ifdef MOZ_STYLO
+// Is the Servo-backed style system enabled?
+pref("layout.css.servo.enabled", true);
+#endif
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -64,16 +64,17 @@ do {                             \
   return NS_ERROR_ILLEGAL_VALUE; \
   } while (0)
 
 Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t version)
   : mSocketTransport(aSocketTransport)
   , mSegmentReader(nullptr)
   , mSegmentWriter(nullptr)
   , mNextStreamID(3) // 1 is reserved for Updgrade handshakes
+  , mLastPushedID(0)
   , mConcurrentHighWater(0)
   , mDownstreamState(BUFFERING_OPENING_SETTINGS)
   , mInputFrameBufferSize(kDefaultBufferSize)
   , mInputFrameBufferUsed(0)
   , mInputFrameDataSize(0)
   , mInputFrameDataRead(0)
   , mInputFrameFinal(false)
   , mInputFrameType(0)
@@ -1547,16 +1548,22 @@ Http2Session::RecvPushPromise(Http2Sessi
     nsresult rv = self->ParsePadding(paddingControlBytes, paddingLength);
     if (NS_FAILED(rv)) {
       return rv;
     }
     promiseLen = 4;
     promisedID = NetworkEndian::readUint32(
         self->mInputFrameBuffer.get() + kFrameHeaderBytes + paddingControlBytes);
     promisedID &= 0x7fffffff;
+    if (promisedID <= self->mLastPushedID) {
+      LOG3(("Http2Session::RecvPushPromise %p ID too low %u expected > %u.\n",
+            self, promisedID, self->mLastPushedID));
+      RETURN_SESSION_ERROR(self, PROTOCOL_ERROR);
+    }
+    self->mLastPushedID = promisedID;
   }
 
   uint32_t associatedID = self->mInputFrameID;
 
   if (self->mInputFrameFlags & kFlag_END_PUSH_PROMISE) {
     self->mExpectedPushPromiseID = 0;
     self->mContinuedPromiseStream = 0;
   } else {
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -312,16 +312,17 @@ private:
   // These are temporary state variables to hold the argument to
   // Read/WriteSegments so it can be accessed by On(read/write)segment
   // further up the stack.
   nsAHttpSegmentReader       *mSegmentReader;
   nsAHttpSegmentWriter       *mSegmentWriter;
 
   uint32_t          mSendingChunkSize;        /* the transmission chunk size */
   uint32_t          mNextStreamID;            /* 24 bits */
+  uint32_t          mLastPushedID;
   uint32_t          mConcurrentHighWater;     /* max parallelism on session */
   uint32_t          mPushAllowance;           /* rwin for unmatched pushes */
 
   internalStateType mDownstreamState; /* in frame, between frames, etc..  */
 
   // Maintain 2 indexes - one by stream ID, one by transaction pointer.
   // There are also several lists of streams: ready to write, queued due to
   // max parallelism, streams that need to force a read for push, and the full
--- a/testing/firefox-ui/tests/puppeteer/manifest.ini
+++ b/testing/firefox-ui/tests/puppeteer/manifest.ini
@@ -15,8 +15,9 @@ tags = remote
 [test_about_window.py]
 [test_menubar.py]
 [test_notifications.py]
 [test_page_info_window.py]
 [test_tabbar.py]
 [test_toolbars.py]
 tags = remote
 [test_windows.py]
+skip-if = e10s # Bug 1292471
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -10,34 +10,29 @@
 script.py, along with config.py and log.py, represents the core of
 mozharness.
 """
 
 import codecs
 from contextlib import contextmanager
 import datetime
 import errno
-import fnmatch
-import functools
 import gzip
 import inspect
-import itertools
 import os
 import platform
 import pprint
 import re
 import shutil
 import socket
 import subprocess
 import sys
-import tarfile
 import time
 import traceback
 import urllib2
-import zipfile
 import httplib
 import urlparse
 import hashlib
 if os.name == 'nt':
     try:
         import win32file
         import win32api
         PYWIN32 = True
@@ -47,20 +42,20 @@ if os.name == 'nt':
 try:
     import simplejson as json
     assert json
 except ImportError:
     import json
 
 from mozprocess import ProcessHandler
 from mozharness.base.config import BaseConfig
+from mozharness.base.errors import ZipErrorList
 from mozharness.base.log import SimpleFileLogger, MultiFileLogger, \
     LogMixin, OutputParser, DEBUG, INFO, ERROR, FATAL
 
-
 def platform_name():
     pm = PlatformMixin()
 
     if pm._is_linux() and pm._is_64_bit():
         return 'linux64'
     elif pm._is_linux() and not pm._is_64_bit():
         return 'linux'
     elif pm._is_darwin():
@@ -453,38 +448,49 @@ class ScriptMixin(PlatformMixin):
             kwargs = {"url": url, "file_name": file_name}
 
         return self.retry(
             download_func,
             kwargs=kwargs,
             **retry_args
         )
 
-    def download_unpack(self, url, extract_to, extract_dirs=None,
-                        error_level=FATAL):
-        """Generic method to download and extract a compressed file.
+    def download_unzip(self, url, parent_dir, target_unzip_dirs=None, halt_on_failure=True):
+        """Generic method to download and extract a zip file.
 
         The downloaded file will always be saved to the working directory and is not getting
         deleted after extracting.
 
         Args:
             url (str): URL where the file to be downloaded is located.
-            extract_to (str): directory where the downloaded file will
+            parent_dir (str): directory where the downloaded file will
                               be extracted to.
-            extract_dirs (list, optional): directories inside the archive to extract.
-                                           Defaults to `None`.
-            error_level (str, optional): log level to use in case an error occurs.
-                                         Defaults to `FATAL`.
+            target_unzip_dirs (list, optional): directories inside the zip file to extract.
+                                                Defaults to `None`.
+            halt_on_failure (bool, optional): whether or not to redefine the
+                                              log level as `FATAL` on errors. Defaults to True.
 
         """
         dirs = self.query_abs_dirs()
-        archive = self.download_file(url, parent_dir=dirs['abs_work_dir'],
-                                     error_level=error_level)
-        self.unpack(archive, extract_to, extract_dirs=extract_dirs,
-                    error_level=error_level)
+        zipfile = self.download_file(url, parent_dir=dirs['abs_work_dir'],
+                                     error_level=FATAL)
+
+        command = self.query_exe('unzip', return_type='list')
+        # Always overwrite to not get an input in a hidden pipe if files already exist
+        command.extend(['-q', '-o', zipfile, '-d', parent_dir])
+        if target_unzip_dirs:
+            command.extend(target_unzip_dirs)
+        # TODO error_list: http://www.info-zip.org/mans/unzip.html#DIAGNOSTICS
+        # unzip return code 11 is 'no matching files were found'
+        self.run_command(command,
+                         error_list=ZipErrorList,
+                         halt_on_failure=halt_on_failure,
+                         fatal_exit_code=3,
+                         success_codes=[0, 11],
+                         )
 
     def load_json_url(self, url, error_level=None, *args, **kwargs):
         """ Returns a json object from a url (it retries). """
         contents = self._retry_download(
             url=url, error_level=error_level, *args, **kwargs
         )
         return json.loads(contents.read())
 
@@ -1094,17 +1100,17 @@ class ScriptMixin(PlatformMixin):
             throw_exception (bool, optional): whether or not to raise an
               exception if the return value of the command doesn't match
               any of the `success_codes`. Defaults to False.
             output_parser (OutputParser, optional): lets you provide an
               instance of your own OutputParser subclass. Defaults to `OutputParser`.
             output_timeout (int): amount of seconds to wait for output before
               the process is killed.
             fatal_exit_code (int, optional): call `self.fatal` if the return value
-              of the command is not in `success_codes`. Defaults to 2.
+              of the command is not on in `success_codes`. Defaults to 2.
             error_level (str, optional): log level name to use on error. Defaults
               to `ERROR`.
             **kwargs: Arbitrary keyword arguments.
 
         Returns:
             int: -1 on error.
             Any: `command` return value is returned otherwise.
         """
@@ -1386,79 +1392,36 @@ class ScriptMixin(PlatformMixin):
         except OSError:
             try:
                 open(file_name, 'w').close()
             except IOError as e:
                 msg = "I/O error(%s): %s" % (e.errno, e.strerror)
                 self.log(msg, error_level=error_level)
         os.utime(file_name, times)
 
-    def unpack(self, filename, extract_to, extract_dirs=None,
-               error_level=ERROR, fatal_exit_code=2, verbose=False):
-        """The method allows to extract a file regardless of its extension.
+    def unpack(self, filename, extract_to):
+        '''
+        This method allows us to extract a file regardless of its extension
 
         Args:
             filename (str): filename of the compressed file.
             extract_to (str): where to extract the compressed file.
-            extract_dirs (list, optional): directories inside the archive file to extract.
-                                           Defaults to `None`.
-            fatal_exit_code (int, optional): call `self.fatal` if the return value
-              of the command is not in `success_codes`. Defaults to 2.
-            verbose (bool, optional): whether or not extracted content should be displayed.
-                                      Defaults to False.
-
-        Raises:
-            IOError: on `filename` file not found.
-
-        """
-        def _filter_entries(namelist):
-            """Filter entries of the archive based on the specified list of to extract dirs."""
-            filter_partial = functools.partial(fnmatch.filter, namelist)
-            for entry in itertools.chain(*map(filter_partial, extract_dirs or ['*'])):
-                yield entry
-
-        if not os.path.isfile(filename):
-            raise IOError('Could not find file to extract: %s' % filename)
-
-        if zipfile.is_zipfile(filename):
-            try:
-                self.info('Using ZipFile to extract {} to {}'.format(filename, extract_to))
-                with zipfile.ZipFile(filename) as bundle:
-                    for entry in _filter_entries(bundle.namelist()):
-                        if verbose:
-                            self.info(' %s' % entry)
-                        bundle.extract(entry, path=extract_to)
-
-                        # ZipFile doesn't preserve permissions during extraction:
-                        # http://bugs.python.org/issue15795
-                        fname = os.path.realpath(os.path.join(extract_to, entry))
-                        mode = bundle.getinfo(entry).external_attr >> 16 & 0x1FF
-                        # Only set permissions if attributes are available. Otherwise all
-                        # permissions will be removed eg. on Windows.
-                        if mode:
-                            os.chmod(fname, mode)
-            except zipfile.BadZipfile as e:
-                self.log('%s (%s)' % (e.message, filename),
-                         level=error_level, exit_code=fatal_exit_code)
-
-        # Bug 1211882 - is_tarfile cannot be trusted for dmg files
-        elif tarfile.is_tarfile(filename) and not filename.lower().endswith('.dmg'):
-            try:
-                self.info('Using TarFile to extract {} to {}'.format(filename, extract_to))
-                with tarfile.open(filename) as bundle:
-                    for entry in _filter_entries(bundle.getnames()):
-                        if verbose:
-                            self.info(' %s' % entry)
-                        bundle.extract(entry, path=extract_to)
-            except tarfile.TarError as e:
-                self.log('%s (%s)' % (e.message, filename),
-                         level=error_level, exit_code=fatal_exit_code)
+        '''
+        # XXX: Make sure that filename has a extension of one of our supported file formats
+        m = re.search('\.tar\.(bz2|gz)$', filename)
+        if m:
+            command = self.query_exe('tar', return_type='list')
+            tar_cmd = "jxfv"
+            if m.group(1) == "gz":
+                tar_cmd = "zxfv"
+            command.extend([tar_cmd, filename, "-C", extract_to])
+            self.run_command(command, halt_on_failure=True)
         else:
-            self.log('No extraction method found for: %s' % filename,
-                     level=error_level, exit_code=fatal_exit_code)
+            # XXX implement
+            pass
 
 
 def PreScriptRun(func):
     """Decorator for methods that will be called before script execution.
 
     Each method on a BaseScript having this decorator will be called at the
     beginning of BaseScript.run().
 
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
@@ -158,24 +158,25 @@ class FirefoxMediaTestsBase(TestingMixin
 
     def download_and_extract(self):
         """Overriding method from TestingMixin for more specific behavior.
 
         We use the test_packages_url command line argument to check where to get the
         harness, puppeteer, and tests from and how to set them up.
 
         """
-        extract_dirs = ['config/*',
-                        'external-media-tests/*',
-                        'marionette/*',
-                        'mozbase/*',
-                        'puppeteer/*',
-                        'tools/wptserve/*',
-                        ]
-        super(FirefoxMediaTestsBase, self).download_and_extract(extract_dirs=extract_dirs)
+        target_unzip_dirs = ['config/*',
+                             'external-media-tests/*',
+                             'marionette/*',
+                             'mozbase/*',
+                             'puppeteer/*',
+                             'tools/wptserve/*',
+                             ]
+        super(FirefoxMediaTestsBase, self).download_and_extract(
+                target_unzip_dirs=target_unzip_dirs)
 
     def query_abs_dirs(self):
         if self.abs_dirs:
             return self.abs_dirs
         abs_dirs = super(FirefoxMediaTestsBase, self).query_abs_dirs()
         dirs = {
             'abs_test_install_dir' : os.path.join(abs_dirs['abs_work_dir'],
                                                     'tests')
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
@@ -148,24 +148,24 @@ class FirefoxUITests(TestingMixin, VCSTo
 
     def download_and_extract(self):
         """Overriding method from TestingMixin for more specific behavior.
 
         We use the test_packages_url command line argument to check where to get the
         harness, puppeteer, and tests from and how to set them up.
 
         """
-        extract_dirs = ['config/*',
-                        'firefox-ui/*',
-                        'marionette/*',
-                        'mozbase/*',
-                        'puppeteer/*',
-                        'tools/wptserve/*',
-                        ]
-        super(FirefoxUITests, self).download_and_extract(extract_dirs=extract_dirs)
+        target_unzip_dirs = ['config/*',
+                             'firefox-ui/*',
+                             'marionette/*',
+                             'mozbase/*',
+                             'puppeteer/*',
+                             'tools/wptserve/*',
+                             ]
+        super(FirefoxUITests, self).download_and_extract(target_unzip_dirs=target_unzip_dirs)
 
     def query_abs_dirs(self):
         if self.abs_dirs:
             return self.abs_dirs
 
         abs_dirs = super(FirefoxUITests, self).query_abs_dirs()
         abs_tests_install_dir = os.path.join(abs_dirs['abs_work_dir'], 'tests')
 
@@ -294,16 +294,63 @@ class FirefoxUITests(TestingMixin, VCSTo
 
     def run_tests(self):
         """Run all the tests"""
         return self.run_test(
             binary_path=self.binary_path,
             env=self.query_env(),
         )
 
+    def download_unzip(self, url, parent_dir, target_unzip_dirs=None, halt_on_failure=True):
+        """Overwritten method from BaseScript until bug 1258539 is fixed.
+
+        The downloaded file will always be saved to the working directory and is not getting
+        deleted after extracting.
+
+        Args:
+            url (str): URL where the file to be downloaded is located.
+            parent_dir (str): directory where the downloaded file will
+                              be extracted to.
+            target_unzip_dirs (list, optional): directories inside the zip file to extract.
+                                                Defaults to `None`.
+            halt_on_failure (bool, optional): whether or not to redefine the
+                                              log level as `FATAL` on errors. Defaults to True.
+
+        """
+        import fnmatch
+        import itertools
+        import functools
+        import zipfile
+
+        def _filter_entries(namelist):
+            """Filter entries of the archive based on the specified list of extract_dirs."""
+            filter_partial = functools.partial(fnmatch.filter, namelist)
+            for entry in itertools.chain(*map(filter_partial, target_unzip_dirs or ['*'])):
+                yield entry
+
+        dirs = self.query_abs_dirs()
+        zip = self.download_file(url, parent_dir=dirs['abs_work_dir'],
+                                 error_level=FATAL)
+
+        try:
+            self.info('Using ZipFile to extract {0} to {1}'.format(zip, parent_dir))
+            with zipfile.ZipFile(zip) as bundle:
+                for entry in _filter_entries(bundle.namelist()):
+                    bundle.extract(entry, path=parent_dir)
+
+                    # ZipFile doesn't preserve permissions: http://bugs.python.org/issue15795
+                    fname = os.path.realpath(os.path.join(parent_dir, entry))
+                    mode = bundle.getinfo(entry).external_attr >> 16 & 0x1FF
+                    # Only set permissions if attributes are available.
+                    if mode:
+                        os.chmod(fname, mode)
+        except zipfile.BadZipfile as e:
+            self.log('{0} ({1})'.format(e.message, zip),
+                     level=FATAL, exit_code=2)
+
 
 class FirefoxUIFunctionalTests(FirefoxUITests):
 
     cli_script = 'cli_functional.py'
     default_tests = [
         os.path.join('puppeteer', 'manifest.ini'),
         os.path.join('functional', 'manifest.ini'),
     ]
--- a/testing/mozharness/mozharness/mozilla/testing/talos.py
+++ b/testing/mozharness/mozharness/mozilla/testing/talos.py
@@ -282,23 +282,23 @@ class Talos(TestingMixin, MercurialScrip
         if c.get('run_local'):
             self.talos_path = os.path.dirname(self.talos_json)
 
         src_talos_webdir = os.path.join(self.talos_path, 'talos')
 
         if self.query_pagesets_url():
             self.info("Downloading pageset...")
             src_talos_pageset = os.path.join(src_talos_webdir, 'tests')
-            self.download_unpack(self.pagesets_url, src_talos_pageset)
+            self.download_unzip(self.pagesets_url, src_talos_pageset)
 
     # Action methods. {{{1
     # clobber defined in BaseScript
     # read_buildbot_config defined in BuildbotMixin
 
-    def download_and_extract(self, extract_dirs=None, suite_categories=None):
+    def download_and_extract(self, target_unzip_dirs=None, suite_categories=None):
         return super(Talos, self).download_and_extract(
             suite_categories=['common', 'talos']
         )
 
     def create_virtualenv(self, **kwargs):
         """VirtualenvMixin.create_virtualenv() assuemes we're using
         self.config['virtualenv_modules']. Since we are installing
         talos from its source, we have to wrap that method here."""
--- a/testing/mozharness/mozharness/mozilla/testing/testbase.py
+++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py
@@ -396,16 +396,27 @@ You can set this by:
 
 1. specifying --test-url URL, or
 2. running via buildbot and running the read-buildbot-config action
 
 """
         if message:
             self.fatal(message + "Can't run download-and-extract... exiting")
 
+        if self.config.get("developer_mode") and self._is_darwin():
+            # Bug 1066700 only affects Mac users that try to run mozharness locally
+            version = self._query_binary_version(
+                    regex=re.compile("UnZip\ (\d+\.\d+)\ .*", re.MULTILINE),
+                    cmd=[self.query_exe('unzip'), '-v']
+            )
+            if not version >= 6:
+                self.fatal("We require a more recent version of unzip to unpack our tests.zip files.\n"
+                        "You are currently using version %s. Please update to at least 6.0.\n"
+                        "You can visit http://www.info-zip.org/UnZip.html" % version)
+
     def _read_packages_manifest(self):
         dirs = self.query_abs_dirs()
         source = self.download_file(self.test_packages_url,
                                     parent_dir=dirs['abs_work_dir'],
                                     error_level=FATAL)
 
         with self.opened(os.path.realpath(source)) as (fh, err):
             package_requirements = json.load(fh)
@@ -413,17 +424,17 @@ 2. running via buildbot and running the 
                 self.fatal("There was an error reading test package requirements from %s "
                            "requirements: `%s` - error: `%s`" % (source,
                                                                  package_requirements or 'None',
                                                                  err or 'No error'))
         self.info("Using the following test package requirements:\n%s" %
                   pprint.pformat(package_requirements))
         return package_requirements
 
-    def _download_test_packages(self, suite_categories, extract_dirs):
+    def _download_test_packages(self, suite_categories, target_unzip_dirs):
         # Some platforms define more suite categories/names than others.
         # This is a difference in the convention of the configs more than
         # to how these tests are run, so we pave over these differences here.
         aliases = {
             'robocop': 'mochitest',
             'mochitest-chrome': 'mochitest',
             'mochitest-media': 'mochitest',
             'mochitest-plain-clipboard': 'mochitest',
@@ -449,31 +460,31 @@ 2. running via buildbot and running the 
                 # If we don't harness specific requirements, assume the common zip
                 # has everything we need to run tests for this suite.
                 target_packages = package_requirements['common']
 
             self.info("Downloading packages: %s for test suite category: %s" %
                       (target_packages, category))
             for file_name in target_packages:
                 target_dir = test_install_dir
-                unpack_dirs = extract_dirs
+                unzip_dirs = target_unzip_dirs
                 if "jsshell-" in file_name or file_name == "target.jsshell.zip":
                     self.info("Special-casing the jsshell zip file")
-                    unpack_dirs = None
+                    unzip_dirs = None
                     target_dir = dirs['abs_test_bin_dir']
                 url = self.query_build_dir_url(file_name)
-                self.download_unpack(url, target_dir,
-                                     extract_dirs=unpack_dirs)
+                self.download_unzip(url, target_dir,
+                                     target_unzip_dirs=unzip_dirs)
 
-    def _download_test_zip(self, extract_dirs=None):
+    def _download_test_zip(self, target_unzip_dirs=None):
         dirs = self.query_abs_dirs()
         test_install_dir = dirs.get('abs_test_install_dir',
                                     os.path.join(dirs['abs_work_dir'], 'tests'))
-        self.download_unpack(self.test_url, test_install_dir,
-                             extract_dirs=extract_dirs)
+        self.download_unzip(self.test_url, test_install_dir,
+                             target_unzip_dirs=target_unzip_dirs)
 
     def structured_output(self, suite_category):
         """Defines whether structured logging is in use in this configuration. This
         may need to be replaced with data from a different config at the resolution
         of bug 1070041 and related bugs.
         """
         return ('structured_suites' in self.config and
                 suite_category in self.config['structured_suites'])
@@ -510,19 +521,19 @@ 2. running via buildbot and running the 
         if self.config.get('download_symbols') == 'ondemand':
             self.symbols_path = self.symbols_url
             return
         if not self.symbols_path:
             self.symbols_path = os.path.join(dirs['abs_work_dir'], 'symbols')
 
         self.set_buildbot_property("symbols_url", self.symbols_url,
                                    write_to_file=True)
-        self.download_unpack(self.symbols_url, self.symbols_path)
+        self.download_unzip(self.symbols_url, self.symbols_path)
 
-    def download_and_extract(self, extract_dirs=None, suite_categories=None):
+    def download_and_extract(self, target_unzip_dirs=None, suite_categories=None):
         """
         download and extract test zip / download installer
         """
         # Swap plain http for https when we're downloading from ftp
         # See bug 957502 and friends
         from_ = "http://ftp.mozilla.org"
         to_ = "https://ftp-ssl.mozilla.org"
         for attr in 'symbols_url', 'installer_url', 'test_packages_url', 'test_url':
@@ -535,27 +546,27 @@ 2. running via buildbot and running the 
         if 'test_url' in self.config:
             # A user has specified a test_url directly, any test_packages_url will
             # be ignored.
             if self.test_packages_url:
                 self.error('Test data will be downloaded from "%s", the specified test '
                            ' package data at "%s" will be ignored.' %
                            (self.config.get('test_url'), self.test_packages_url))
 
-            self._download_test_zip(extract_dirs)
+            self._download_test_zip(target_unzip_dirs)
         else:
             if not self.test_packages_url:
                 # The caller intends to download harness specific packages, but doesn't know
                 # where the packages manifest is located. This is the case when the
                 # test package manifest isn't set as a buildbot property, which is true
                 # for some self-serve jobs and platforms using parse_make_upload.
                 self.test_packages_url = self.query_prefixed_build_dir_url('.test_packages.json')
 
             suite_categories = suite_categories or ['common']
-            self._download_test_packages(suite_categories, extract_dirs)
+            self._download_test_packages(suite_categories, target_unzip_dirs)
 
         self._download_installer()
         if self.config.get('download_symbols'):
             self._download_and_extract_symbols()
 
     # create_virtualenv is in VirtualenvMixin.
 
     def preflight_install(self):
--- a/testing/mozharness/mozharness/mozilla/testing/unittest.py
+++ b/testing/mozharness/mozharness/mozilla/testing/unittest.py
@@ -230,17 +230,17 @@ class EmulatorMixin(object):
             unzip_cmd = [unzip, '-q', os.path.join(dirs['abs_work_dir'], "emulator.zip")]
             self.run_command(unzip_cmd, cwd=dirs['abs_emulator_dir'], halt_on_failure=True,
                              fatal_exit_code=3)
 
     def install_emulator(self):
         dirs = self.query_abs_dirs()
         self.mkdir_p(dirs['abs_emulator_dir'])
         if self.config.get('emulator_url'):
-            self.download_unpack(self.config['emulator_url'], dirs['abs_emulator_dir'])
+            self.download_unzip(self.config['emulator_url'], dirs['abs_emulator_dir'])
         elif self.config.get('emulator_manifest'):
             manifest_path = self.create_tooltool_manifest(self.config['emulator_manifest'])
             do_unzip = True
             if 'unpack' in self.config['emulator_manifest']:
                 do_unzip = False
             self.install_emulator_from_tooltool(manifest_path, do_unzip)
         elif self.buildbot_config:
             props = self.buildbot_config.get('properties')
--- a/testing/mozharness/scripts/b2g_emulator_unittest.py
+++ b/testing/mozharness/scripts/b2g_emulator_unittest.py
@@ -206,17 +206,18 @@ class B2GEmulatorTest(TestingMixin, VCSM
 
         self.mkdir_p(dirs['abs_emulator_dir'])
         tar = self.query_exe('tar', return_type='list')
         self.run_command(tar + ['zxf', self.installer_path],
                          cwd=dirs['abs_emulator_dir'],
                          error_list=TarErrorList,
                          halt_on_failure=True, fatal_exit_code=3)
 
-        self.download_unpack(self.config['xre_url'], dirs['abs_xre_dir'])
+        self.download_unzip(self.config['xre_url'],
+                             dirs['abs_xre_dir'])
 
         if self.config.get('busybox_url'):
             self.download_file(self.config['busybox_url'],
                                file_name='busybox',
                                parent_dir=dirs['abs_work_dir'])
             self.busybox_path = os.path.join(dirs['abs_work_dir'], 'busybox')
 
     @PreScriptAction('create-virtualenv')
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -475,30 +475,30 @@ class DesktopUnittest(TestingMixin, Merc
 
     def download_and_extract(self):
         """
         download and extract test zip / download installer
         optimizes which subfolders to extract from tests zip
         """
         c = self.config
 
-        extract_dirs = None
+        target_unzip_dirs = None
         if c['specific_tests_zip_dirs']:
-            extract_dirs = list(c['minimum_tests_zip_dirs'])
+            target_unzip_dirs = list(c['minimum_tests_zip_dirs'])
             for category in c['specific_tests_zip_dirs'].keys():
                 if c['run_all_suites'] or self._query_specified_suites(category) \
                         or 'run-tests' not in self.actions:
-                    extract_dirs.extend(c['specific_tests_zip_dirs'][category])
+                    target_unzip_dirs.extend(c['specific_tests_zip_dirs'][category])
 
         if c.get('run_all_suites'):
             target_categories = SUITE_CATEGORIES
         else:
             target_categories = [cat for cat in SUITE_CATEGORIES
                                  if self._query_specified_suites(cat) is not None]
-        super(DesktopUnittest, self).download_and_extract(extract_dirs=extract_dirs,
+        super(DesktopUnittest, self).download_and_extract(target_unzip_dirs=target_unzip_dirs,
                                                           suite_categories=target_categories)
 
     def stage_files(self):
         for category in SUITE_CATEGORIES:
             suites = self._query_specified_suites(category)
             stage = getattr(self, '_stage_{}'.format(category), None)
             if suites and stage:
                 stage(suites)
--- a/testing/mozharness/scripts/web_platform_tests.py
+++ b/testing/mozharness/scripts/web_platform_tests.py
@@ -161,22 +161,22 @@ class WebPlatformTest(TestingMixin, Merc
                                       str_format_values=str_format_values))
         cmd.extend(self.query_tests_args(try_tests,
                                          str_format_values=str_format_values))
 
         return cmd
 
     def download_and_extract(self):
         super(WebPlatformTest, self).download_and_extract(
-            extract_dirs=["bin/*",
-                          "config/*",
-                          "mozbase/*",
-                          "marionette/*",
-                          "tools/wptserve/*",
-                          "web-platform/*"],
+            target_unzip_dirs=["bin/*",
+                               "config/*",
+                               "mozbase/*",
+                               "marionette/*",
+                               "tools/wptserve/*",
+                               "web-platform/*"],
             suite_categories=["web-platform"])
 
     def run_tests(self):
         dirs = self.query_abs_dirs()
         cmd = self._query_cmd()
 
         parser = StructuredOutputParser(config=self.config,
                                         log_obj=self.log_obj,
deleted file mode 100644
index 1dc094198f3198c38e6c04dd9ea98dacecced1e1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index c393ea4b881cc0ce9bd4d05e2368a162f4da9d78..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 0fbfa39b1c76ae868fc8b67d3c76d199fd0c24eb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index aa2fb34c1658128d6a25f0f40b5ae646b198ea7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 20bdc5acdf11e3c466c5b59090d1aaa52b721d31..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100755
--- a/testing/mozharness/test/helper_files/archives/reference/bin/script.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-echo Hello world!
deleted file mode 100644
--- a/testing/mozharness/test/helper_files/archives/reference/lorem.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-Lorem ipsum dolor sit amet.
deleted file mode 100755
--- a/testing/mozharness/test/helper_files/create_archives.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-# Script to auto-generate the different archive types under the archives directory.
-
-cd archives
-
-rm archive.*
-
-tar cf archive.tar -C reference .
-gzip -fk archive.tar >archive.tar.gz
-bzip2 -fk archive.tar >archive.tar.bz2
-cd reference && zip ../archive.zip -r * && cd ..
--- a/testing/mozharness/test/test_base_script.py
+++ b/testing/mozharness/test/test_base_script.py
@@ -1,14 +1,12 @@
 import gc
 import mock
 import os
 import re
-import shutil
-import tempfile
 import types
 import unittest
 PYWIN32 = False
 if os.name == 'nt':
     try:
         import win32file
         PYWIN32 = True
     except:
@@ -16,37 +14,32 @@ if os.name == 'nt':
 
 
 import mozharness.base.errors as errors
 import mozharness.base.log as log
 from mozharness.base.log import DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL, IGNORE
 import mozharness.base.script as script
 from mozharness.base.config import parse_config_file
 
-
-here = os.path.dirname(os.path.abspath(__file__))
-
 test_string = '''foo
 bar
 baz'''
 
 
 class CleanupObj(script.ScriptMixin, log.LogMixin):
     def __init__(self):
         super(CleanupObj, self).__init__()
         self.log_obj = None
         self.config = {'log_level': ERROR}
 
 
-def cleanup(files=None):
-    files = files or []
-    files.extend(('test_logs', 'test_dir', 'tmpfile_stdout', 'tmpfile_stderr'))
+def cleanup():
     gc.collect()
     c = CleanupObj()
-    for f in files:
+    for f in ('test_logs', 'test_dir', 'tmpfile_stdout', 'tmpfile_stderr'):
         c.rmtree(f)
 
 
 def get_debug_script_obj():
     s = script.BaseScript(config={'log_type': 'multi',
                                   'log_level': DEBUG},
                           initial_config_file='test/test.json')
     return s
@@ -58,23 +51,22 @@ def _post_fatal(self, **kwargs):
     fh.close()
 
 
 # TestScript {{{1
 class TestScript(unittest.TestCase):
     def setUp(self):
         cleanup()
         self.s = None
-        self.tmpdir = tempfile.mkdtemp(suffix='.mozharness')
 
     def tearDown(self):
         # Close the logfile handles, or windows can't remove the logs
         if hasattr(self, 's') and isinstance(self.s, object):
             del(self.s)
-        cleanup([self.tmpdir])
+        cleanup()
 
     # test _dump_config_hierarchy() when --dump-config-hierarchy is passed
     def test_dump_config_hierarchy_valid_files_len(self):
         try:
             self.s = script.BaseScript(
                 initial_config_file='test/test.json',
                 option_args=['--cfg', 'test/test_override.py,test/test_override2.py'],
                 config={'dump_config_hierarchy': True}
@@ -254,48 +246,16 @@ class TestScript(unittest.TestCase):
                 'regex': re.compile(',$'), 'level': IGNORE,
             }, {
                 'substr': ']$', 'level': WARNING,
             }])
         error_logsize = os.path.getsize("test_logs/test_error.log")
         self.assertTrue(error_logsize > 0,
                         msg="error list not working properly")
 
-    def test_unpack(self):
-        self.s = get_debug_script_obj()
-
-        archives_path = os.path.join(here, 'helper_files', 'archives')
-
-        # Test basic decompression
-        for archive in ('archive.tar', 'archive.tar.bz2', 'archive.tar.gz', 'archive.zip'):
-            self.s.unpack(os.path.join(archives_path, archive), self.tmpdir)
-            self.assertIn('script.sh', os.listdir(os.path.join(self.tmpdir, 'bin')))
-            self.assertIn('lorem.txt', os.listdir(self.tmpdir))
-            shutil.rmtree(self.tmpdir)
-
-        # Test permissions for extracted entries from zip archive
-        self.s.unpack(os.path.join(archives_path, 'archive.zip'), self.tmpdir)
-        file_stats = os.stat(os.path.join(self.tmpdir, 'bin', 'script.sh'))
-        orig_fstats = os.stat(os.path.join(archives_path, 'reference', 'bin', 'script.sh'))
-        self.assertEqual(file_stats.st_mode, orig_fstats.st_mode)
-        shutil.rmtree(self.tmpdir)
-
-        # Test extract specific dirs only
-        self.s.unpack(os.path.join(archives_path, 'archive.zip'), self.tmpdir,
-                      extract_dirs=['bin/*'])
-        self.assertIn('bin', os.listdir(self.tmpdir))
-        self.assertNotIn('lorem.txt', os.listdir(self.tmpdir))
-        shutil.rmtree(self.tmpdir)
-
-        # Test for invalid filenames (Windows only)
-        if PYWIN32:
-            with self.assertRaises(IOError):
-                self.s.unpack(os.path.join(archives_path, 'archive_invalid_filename.zip'),
-                              self.tmpdir)
-
 
 # TestHelperFunctions {{{1
 class TestHelperFunctions(unittest.TestCase):
     temp_file = "test_dir/mozilla"
 
     def setUp(self):
         cleanup()
         self.s = None
deleted file mode 100644
--- a/testing/web-platform/meta/XMLHttpRequest/send-accept.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[send-accept.htm]
-  type: testharness
-  [XMLHttpRequest: send() - Accept]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/forms/textfieldselection/selection.html.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[selection.html]
-  type: testharness
-  [test SelectionStart offset for input]
-    expected: FAIL
-    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1287655
-
-  [test SelectionStart offset for textarea]
-    expected: FAIL
-    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1287655
-
-  [test SelectionEnd offset for input]
-    expected: FAIL
-    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1287655
-
-  [test SelectionEnd offset for textarea]
-    expected: FAIL
-    bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1287655
-
--- a/testing/web-platform/meta/media-source/mediasource-preload.html.ini
+++ b/testing/web-platform/meta/media-source/mediasource-preload.html.ini
@@ -1,12 +1,9 @@
 [mediasource-preload.html]
   type: testharness
   expected: TIMEOUT
-  [sourceopen occurs with element preload=none]
-    expected: TIMEOUT
-
   [error occurs with bogus blob URL (revoked MediaSource object URL) and element preload=none]
     expected: TIMEOUT
 
   [erro