Import Cobalt 22.master.0.305486
diff --git a/src/.codespellignorelines b/src/.codespellignorelines
new file mode 100644
index 0000000..4e787e0
--- /dev/null
+++ b/src/.codespellignorelines
@@ -0,0 +1 @@
+    vp9WhiteList.get("Technicolor").add("STING");
diff --git a/src/.pre-commit-config.yaml b/src/.pre-commit-config.yaml
index 3813752..174d63a 100644
--- a/src/.pre-commit-config.yaml
+++ b/src/.pre-commit-config.yaml
@@ -5,7 +5,7 @@
 default_language_version:
     python: python3
 
-exclude: '^(base|build|testing|third_party)/'
+exclude: '^(base|build|testing|third_party|tools/gyp)/'
 
 repos:
 -   repo: https://cobalt.googlesource.com/pre-commit-hooks
@@ -21,6 +21,7 @@
     hooks:
     -   id: codespell
         name: Spell Check
+        args: [-x, .codespellignorelines]
         exclude: '^cobalt/content/i18n/platform/'
 
 -   repo: local
@@ -37,8 +38,7 @@
         language: system
         types: [c++]
         args: [--verbose=4, --quiet]
-        exclude: '.*tests?.(cc|h)$'
-        exclude: '^cobalt/bindings/(templates|generated)/'
+        exclude: '(^cobalt/bindings/(templates|generated)/|tests?.(cc|h)$)'
     -   id: cpplint_test
         name: cpplint_test
         entry: cpplint
@@ -48,10 +48,11 @@
         files: '.*tests?.(cc|h)$'
     -   id: yapf
         name: yapf
+        description: Run yapf (the python formatter) in-place on changed files.
         entry: yapf
         language: system
         types: [python]
-        args: [-i]
+        args: [-i, -vv]
         exclude: '\.gypi?$'
     -   id: pylint
         name: pylint
@@ -85,6 +86,7 @@
         types: [file, text]
         stages: [push]
         exclude: '^cobalt/layout_tests/testdata/'
+        exclude_types: [markdown]
     -   id: check-if-starboard-interface-changed
         name: check if starboard interface changed
         entry: python ./precommit_hooks/warn_that_starboard_interface_changed_wrapper.py
diff --git a/src/.pylintrc b/src/.pylintrc
index d955f5c..80f56fe 100644
--- a/src/.pylintrc
+++ b/src/.pylintrc
@@ -72,6 +72,7 @@
         cmp-method,
         coerce-builtin,
         coerce-method,
+        consider-using-f-string,
         delslice-method,
         div-method,
         duplicate-code,
@@ -124,6 +125,7 @@
         raw_input-builtin,
         rdiv-method,
         reduce-builtin,
+        redundant-u-string-prefix,
         relative-import,
         reload-builtin,
         round-builtin,
@@ -150,6 +152,7 @@
         unnecessary-pass,
         unpacking-in-except,
         unspecified-encoding,
+        use-maxsplit-arg,
         useless-else-on-loop,
         useless-object-inheritance,
         useless-suppression,
diff --git a/src/build/toolchain/gcc_toolchain.gni b/src/build/toolchain/gcc_toolchain.gni
index 09af53d..42e2b80 100644
--- a/src/build/toolchain/gcc_toolchain.gni
+++ b/src/build/toolchain/gcc_toolchain.gni
@@ -665,7 +665,7 @@
     ld = cxx
     readelf = "${toolprefix}readelf"
     ar = "${prefix}/llvm-ar"
-    nm = "${prefix}/llvm-nm"
+    nm = "nm"
 
     forward_variables_from(invoker,
                            [
diff --git a/src/cobalt/black_box_tests/black_box_tests.py b/src/cobalt/black_box_tests/black_box_tests.py
index 271b2cc..afd95b1 100644
--- a/src/cobalt/black_box_tests/black_box_tests.py
+++ b/src/cobalt/black_box_tests/black_box_tests.py
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+"""Contains utilities to create black box tests and run them."""
 
 from __future__ import absolute_import
 from __future__ import division
@@ -44,6 +45,7 @@
 # List of blocked ports.
 _RESTRICTED_PORTS = [6000, 6665, 6666, 6667, 6668, 6669, 6697]
 _SERVER_EXIT_TIMEOUT_SECONDS = 30
+_SOCKET_SUCCESS = 0
 # These tests can only be run on platforms whose app launcher can send suspend/
 # resume signals.
 _TESTS_NEEDING_SYSTEM_SIGNAL = [
@@ -60,6 +62,7 @@
 # These tests only need app launchers with webdriver.
 _TESTS_NO_SIGNAL = [
     'allow_eval',
+    'compression_test',
     'disable_eval_with_csp',
     'persistent_cookie',
     'web_debugger',
@@ -81,6 +84,7 @@
 
 
 class BlackBoxTestCase(unittest.TestCase):
+  """Base class for Cobalt black box test cases."""
 
   def __init__(self, *args, **kwargs):
     super(BlackBoxTestCase, self).__init__(*args, **kwargs)
@@ -92,12 +96,12 @@
   @classmethod
   def setUpClass(cls):
     super(BlackBoxTestCase, cls).setUpClass()
-    logging.info('Running ' + cls.__name__)
+    logging.info('Running %s', cls.__name__)
 
   @classmethod
   def tearDownClass(cls):
     super(BlackBoxTestCase, cls).tearDownClass()
-    logging.info('Done ' + cls.__name__)
+    logging.info('Done %s', cls.__name__)
 
   def CreateCobaltRunner(self, url, target_params=None):
     all_target_params = list(target_params) if target_params else []
@@ -191,9 +195,7 @@
         'www2.web-platform.test', 'xn--n8j6ds53lwwkrqhv28a.web-platform.test',
         'xn--lve-6lad.web-platform.test'
     ]
-    self.host_resolve_map = dict([
-        (host, server_binding_address) for host in hosts
-    ])
+    self.host_resolve_map = {host: server_binding_address for host in hosts}
 
   def Run(self):
     if self.proxy_port == '-1':
@@ -202,12 +204,12 @@
     # Temporary means to determine if we are running on CI
     # TODO: Update to IS_CI environment variable or similar
     out_dir = _launcher_params.out_directory
-    is_ci = out_dir and 'mh_lab' in out_dir
+    is_ci = out_dir and 'mh_lab' in out_dir  # pylint: disable=unsupported-membership-test
 
     target = (_launcher_params.platform, _launcher_params.config)
     if is_ci and '{}/{}'.format(*target) in _DISABLED_BLACKBOXTEST_CONFIGS:
-      logging.warning(
-          'Blackbox tests disabled for platform:{} config:{}'.format(*target))
+      logging.warning('Blackbox tests disabled for platform:%s config:%s',
+                      *target)
       return 0
 
     logging.info('Using proxy port: %s', self.proxy_port)
@@ -227,7 +229,6 @@
 
   def GetUnusedPort(self, addresses):
     """Find a free port on the list of addresses by pinging with sockets."""
-    SOCKET_SUCCESS = 0
 
     if not addresses:
       logging.error('Can not find unused port on invalid addresses.')
@@ -245,7 +246,7 @@
         unused = True
         for sock in socks:
           result = sock[1].connect_ex((sock[0], port))
-          if result == SOCKET_SUCCESS:
+          if result == _SOCKET_SUCCESS:
             unused = False
             break
         if unused:
diff --git a/src/cobalt/black_box_tests/testdata/compression.html b/src/cobalt/black_box_tests/testdata/compression.html
new file mode 100644
index 0000000..2ff930d
--- /dev/null
+++ b/src/cobalt/black_box_tests/testdata/compression.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+<head>
+  <title>Verify that compressed files are properly decompressed</title>
+  <script src='black_box_js_test_utils.js'></script>
+</head>
+
+<body>
+  <h1>
+    <span>ID element</span>
+  </h1>
+  <script>
+    // If this file fails to decompress, there will be no call to onEndTest and
+    // the python test will fail on timeout.
+    onEndTest();
+  </script>
+</body>
diff --git a/src/cobalt/black_box_tests/tests/compression_test.py b/src/cobalt/black_box_tests/tests/compression_test.py
new file mode 100644
index 0000000..807b091
--- /dev/null
+++ b/src/cobalt/black_box_tests/tests/compression_test.py
@@ -0,0 +1,147 @@
+# Copyright 2021 The Cobalt Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests if Cobalt properly handles compressed files."""
+
+import os
+import zlib
+
+try:
+  import brotli
+except ImportError:
+  brotli = None
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from cobalt.black_box_tests import black_box_tests
+from cobalt.black_box_tests.threaded_web_server import ThreadedWebServer
+
+
+def encode(raw_content, encoding_type):
+  """Encode content using the algorithm specified by encoding_type."""
+  if encoding_type == 'gzip':
+    return encode_gzip(raw_content)
+  elif encoding_type == 'deflate':
+    return encode_deflate(raw_content)
+  elif encoding_type == 'br':
+    return encode_brotli(raw_content)
+  raise ValueError('Unknown encoding type used [{}].'.format(encoding_type))
+
+
+def encode_gzip(raw_content):
+  compressor = zlib.compressobj(9, zlib.DEFLATED, 16 + zlib.MAX_WBITS)
+  content = compressor.compress(raw_content) + compressor.flush()
+  return content
+
+
+def encode_deflate(raw_content):
+  compressor = zlib.compressobj(9, zlib.DEFLATED)
+  content = compressor.compress(raw_content) + compressor.flush()
+  return content
+
+
+def encode_brotli(raw_content):
+  return brotli.compress(raw_content)
+
+
+def make_request_handler_class(base_path, encoding_type):
+  """RequestHandler that serves files that reside relative to base_path.
+
+  Args:
+    base_path: A path considered to be the root directory.
+    encoding_type: The content encoding type to use to compress served files.
+
+  Returns:
+    A RequestHandler class.
+  """
+
+  class TestDataHTTPRequestHandler(SimpleHTTPRequestHandler):
+    """Handles HTTP requests and serves compressed responses.
+
+    Encodes response files regardless of the 'Accept-Encoding' header in the
+    request. For testing purposes only.
+    """
+
+    _current_working_directory = os.getcwd()
+    _base_path = base_path
+    _encoding_type = encoding_type
+
+    def do_GET(self):  # pylint: disable=invalid-name
+      content = self.get_content()
+      self.wfile.write(content)
+
+    def do_HEAD(self):  # pylint: disable=invalid-name
+      # Run get_content to send the headers, but ignore the returned results
+      self.get_content()
+
+    def translate_path(self, path):
+      """Translate the request path to the file in the testdata directory."""
+
+      potential_path = SimpleHTTPRequestHandler.translate_path(self, path)
+      potential_path = potential_path.replace(self._current_working_directory,
+                                              self._base_path)
+      return potential_path
+
+    def get_content(self):
+      """Gets the contents of the file at path, encodes and returns it."""
+      path = self.translate_path(self.path)
+      modified_date_time = None
+      raw_content = None
+      try:
+        with open(path, 'rb') as f:
+          filestream = os.fstat(f.fileno())
+          modified_date_time = self.date_time_string(filestream.st_mtime)
+          raw_content = f.read()
+      except IOError:
+        self.send_error(404, 'File not found')
+        return None
+
+      content_type = self.guess_type(path)
+      self.send_response(200)
+      self.send_header('Content-type', content_type)
+      self.send_header('Content-Encoding', self._encoding_type)
+
+      content = encode(raw_content, self._encoding_type)
+      content_length = len(content)
+
+      self.send_header('Content-Length', content_length)
+      self.send_header('Last-Modified', modified_date_time)
+      self.end_headers()
+
+      return content
+
+  return TestDataHTTPRequestHandler
+
+
+def execute_test(test_runner, encoding_type):
+  path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+  with ThreadedWebServer(
+      binding_address=test_runner.GetBindingAddress(),
+      handler=make_request_handler_class(path, encoding_type)) as server:
+    url = server.GetURL(file_name='testdata/compression.html')
+
+    with test_runner.CreateCobaltRunner(url=url) as runner:
+      test_runner.assertTrue(runner.JSTestsSucceeded())
+
+
+class CompressionTest(black_box_tests.BlackBoxTestCase):
+  """Verify correct decompression of compressed files."""
+
+  def test_gzip(self):
+    execute_test(self, 'gzip')
+
+  def test_deflate(self):
+    execute_test(self, 'deflate')
+
+  def test_brotli(self):
+    # Skip this test if the brotli module is not available.
+    if brotli:
+      execute_test(self, 'br')
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index f66ed8b..44fc15e 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -1641,7 +1641,7 @@
 void BrowserModule::InitializeSystemWindow() {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::InitializeSystemWindow()");
   DCHECK(!system_window_);
-  if (media_module_) {
+  if (media_module_ && !window_size_.IsEmpty()) {
     system_window_.reset(
         new system_window::SystemWindow(event_dispatcher_, window_size_));
   } else {
diff --git a/src/cobalt/build/gyp_utils.py b/src/cobalt/build/gyp_utils.py
index fc61343..963e560 100644
--- a/src/cobalt/build/gyp_utils.py
+++ b/src/cobalt/build/gyp_utils.py
@@ -39,6 +39,9 @@
   git_get_remote_args = git_prefix + ['config', '--get', 'remote.origin.url']
   remote = subprocess.check_output(git_get_remote_args).strip()
 
+  if remote.endswith('.git'):
+    remote = remote[:-len('.git')]
+
   git_get_revision_args = git_prefix + ['rev-parse', 'HEAD']
   revision = subprocess.check_output(git_get_revision_args).strip()
   return {key: '{}@{}'.format(remote, revision)}
diff --git a/src/cobalt/build/sync_to_build_id.py b/src/cobalt/build/sync_to_build_id.py
index f2fb1f4..d96e4d0 100755
--- a/src/cobalt/build/sync_to_build_id.py
+++ b/src/cobalt/build/sync_to_build_id.py
@@ -118,9 +118,15 @@
 
     (requested_repo, _) = rep_hash.split("@")
     remote_url = _RunGitCommand(["config", "--get", "remote.origin.url"],
-                                cwd=path)[0]
+                                cwd=path)[0].strip().decode("utf-8")
     if requested_repo.endswith(".git"):
-      remote_url += ".git"
+      if remote_url + ".git" == requested_repo:
+        print(("WARNING: You are syncing to {0} instead of {1}. While these "
+               "point to the same repo, the differing extension will cause "
+               "different build ids to be generated. If you need the same "
+               "id, you'll need to specifically clone {0} (note the .git "
+               "extension).").format(requested_repo, remote_url))
+        remote_url += ".git"
 
     if remote_url != requested_repo:
       if args.force and path != git_root:
diff --git a/src/cobalt/content/ssl/certs/2e5ac55d.0 b/src/cobalt/content/ssl/certs/2e5ac55d.0
deleted file mode 100644
index b2e43c9..0000000
--- a/src/cobalt/content/ssl/certs/2e5ac55d.0
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
-rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
-OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
-xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
-7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
-aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
-SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
-ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
-AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
-R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
-JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
-Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
------END CERTIFICATE-----
diff --git a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp b/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
deleted file mode 100644
index 39ad8b2..0000000
--- a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
+++ /dev/null
@@ -1,476 +0,0 @@
-front_end/network/network.js
-front_end/network/SignedExchangeInfoView.js
-front_end/network/ResourceWebSocketFrameView.js
-front_end/network/RequestTimingView.js
-front_end/network/RequestResponseView.js
-front_end/network/RequestPreviewView.js
-front_end/network/RequestInitiatorView.js
-front_end/network/RequestHeadersView.js
-front_end/network/RequestHTMLView.js
-front_end/network/RequestCookiesView.js
-front_end/network/NetworkWaterfallColumn.js
-front_end/network/NetworkTimeCalculator.js
-front_end/network/NetworkSearchScope.js
-front_end/network/NetworkPanel.js
-front_end/network/NetworkOverview.js
-front_end/network/NetworkManageCustomHeadersView.js
-front_end/network/NetworkLogViewColumns.js
-front_end/network/NetworkLogView.js
-front_end/network/NetworkItemView.js
-front_end/network/NetworkFrameGrouper.js
-front_end/network/NetworkDataGridNode.js
-front_end/network/NetworkConfigView.js
-front_end/network/HARWriter.js
-front_end/network/EventSourceMessagesView.js
-front_end/network/BlockedURLsPane.js
-front_end/network/BinaryResourceView.js
-front_end/test_runner/test_runner.js
-front_end/test_runner/TestRunner.js
-front_end/emulation/emulation.js
-front_end/emulation/SensorsView.js
-front_end/emulation/MediaQueryInspector.js
-front_end/emulation/InspectedPagePlaceholder.js
-front_end/emulation/GeolocationsSettingsTab.js
-front_end/emulation/EmulatedDevices.js
-front_end/emulation/DevicesSettingsTab.js
-front_end/emulation/DeviceModeWrapper.js
-front_end/emulation/DeviceModeView.js
-front_end/emulation/DeviceModeToolbar.js
-front_end/emulation/DeviceModeModel.js
-front_end/emulation/AdvancedApp.js
-front_end/inspector_main/inspector_main.js
-front_end/inspector_main/RenderingOptions.js
-front_end/inspector_main/InspectorMain.js
-front_end/js_main/js_main.js
-front_end/js_main/JsMain.js
-front_end/search/search.js
-front_end/search/SearchView.js
-front_end/search/SearchResultsPane.js
-front_end/search/SearchConfig.js
-front_end/screencast/screencast.js
-front_end/screencast/ScreencastView.js
-front_end/screencast/ScreencastApp.js
-front_end/screencast/InputModel.js
-front_end/performance_monitor/performance_monitor.js
-front_end/performance_monitor/PerformanceMonitor.js
-front_end/main/main.js
-front_end/main/SimpleApp.js
-front_end/main/MainImpl.js
-front_end/main/ExecutionContextSelector.js
-front_end/snippets/snippets.js
-front_end/snippets/SnippetsQuickOpen.js
-front_end/snippets/ScriptSnippetFileSystem.js
-front_end/settings/settings.js
-front_end/settings/SettingsScreen.js
-front_end/settings/FrameworkBlackboxSettingsTab.js
-front_end/security/security.js
-front_end/security/SecurityPanel.js
-front_end/security/SecurityModel.js
-front_end/javascript_metadata/javascript_metadata.js
-front_end/javascript_metadata/NativeFunctions.js
-front_end/javascript_metadata/JavaScriptMetadata.js
-front_end/har_importer/har_importer.js
-front_end/har_importer/HARImporter.js
-front_end/har_importer/HARFormat.js
-front_end/browser_debugger/browser_debugger.js
-front_end/browser_debugger/XHRBreakpointsSidebarPane.js
-front_end/browser_debugger/ObjectEventListenersSidebarPane.js
-front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
-front_end/browser_debugger/DOMBreakpointsSidebarPane.js
-front_end/layer_viewer/layer_viewer.js
-front_end/layer_viewer/TransformController.js
-front_end/layer_viewer/PaintProfilerView.js
-front_end/layer_viewer/Layers3DView.js
-front_end/layer_viewer/LayerViewHost.js
-front_end/layer_viewer/LayerTreeOutline.js
-front_end/layer_viewer/LayerDetailsView.js
-front_end/cm_web_modes/cm_web_modes.js
-front_end/cm_web_modes/cm_web_modes_cm.js
-front_end/cm_web_modes/cm_web_modes_headless.js
-front_end/cm_web_modes/css.js
-front_end/cm_web_modes/javascript.js
-front_end/cm_web_modes/xml.js
-front_end/cm_web_modes/htmlmixed.js
-front_end/cm_web_modes/htmlembedded.js
-front_end/text_editor/text_editor.js
-front_end/text_editor/TextEditorAutocompleteController.js
-front_end/text_editor/CodeMirrorUtils.js
-front_end/text_editor/CodeMirrorTextEditor.js
-front_end/quick_open/quick_open.js
-front_end/quick_open/QuickOpen.js
-front_end/quick_open/HelpQuickOpen.js
-front_end/quick_open/FilteredListWidget.js
-front_end/quick_open/CommandMenu.js
-front_end/elements/elements.js
-front_end/elements/elements-legacy.js
-front_end/elements/StylesSidebarPane.js
-front_end/elements/StylePropertyTreeElement.js
-front_end/elements/StylePropertyHighlighter.js
-front_end/elements/PropertiesWidget.js
-front_end/elements/PlatformFontsWidget.js
-front_end/elements/NodeStackTraceWidget.js
-front_end/elements/MetricsSidebarPane.js
-front_end/elements/MarkerDecorator.js
-front_end/elements/InspectElementModeController.js
-front_end/elements/EventListenersWidget.js
-front_end/elements/ElementsTreeOutline.js
-front_end/elements/ElementsTreeElement.js
-front_end/elements/ElementsTreeElementHighlighter.js
-front_end/elements/ElementStatePaneWidget.js
-front_end/elements/ElementsSidebarPane.js
-front_end/elements/ElementsPanel.js
-front_end/elements/ElementsBreadcrumbs.js
-front_end/elements/DOMPath.js
-front_end/elements/DOMLinkifier.js
-front_end/elements/ComputedStyleWidget.js
-front_end/elements/ComputedStyleModel.js
-front_end/elements/ColorSwatchPopoverIcon.js
-front_end/elements/ClassesPaneWidget.js
-front_end/timeline_model/timeline_model.js
-front_end/timeline_model/TracingLayerTree.js
-front_end/timeline_model/TimelineProfileTree.js
-front_end/timeline_model/TimelineModel.js
-front_end/timeline_model/TimelineModelFilter.js
-front_end/timeline_model/TimelineJSProfile.js
-front_end/timeline_model/TimelineIRModel.js
-front_end/timeline_model/TimelineFrameModel.js
-front_end/help/help.js
-front_end/help/ReleaseNoteView.js
-front_end/help/ReleaseNoteText.js
-front_end/help/HelpImpl.js
-front_end/workspace_diff/workspace_diff.js
-front_end/workspace_diff/WorkspaceDiff.js
-front_end/mobile_throttling/mobile_throttling.js
-front_end/mobile_throttling/ThrottlingSettingsTab.js
-front_end/mobile_throttling/ThrottlingPresets.js
-front_end/mobile_throttling/ThrottlingManager.js
-front_end/mobile_throttling/NetworkThrottlingSelector.js
-front_end/mobile_throttling/NetworkPanelIndicator.js
-front_end/mobile_throttling/MobileThrottlingSelector.js
-front_end/event_listeners/event_listeners.js
-front_end/event_listeners/EventListenersView.js
-front_end/event_listeners/EventListenersUtils.js
-front_end/object_ui/object_ui.js
-front_end/object_ui/RemoteObjectPreviewFormatter.js
-front_end/object_ui/ObjectPropertiesSection.js
-front_end/object_ui/ObjectPopoverHelper.js
-front_end/object_ui/JavaScriptREPL.js
-front_end/object_ui/JavaScriptAutocomplete.js
-front_end/object_ui/CustomPreviewComponent.js
-front_end/cookie_table/cookie_table.js
-front_end/cookie_table/CookiesTable.js
-front_end/cm_modes/cm_modes.js
-front_end/cm_modes/DefaultCodeMirrorMimeMode.js
-front_end/cm_modes/clike.js
-front_end/cm_modes/coffeescript.js
-front_end/cm_modes/php.js
-front_end/cm_modes/python.js
-front_end/cm_modes/shell.js
-front_end/cm_modes/livescript.js
-front_end/cm_modes/markdown.js
-front_end/cm_modes/clojure.js
-front_end/cm_modes/jsx.js
-front_end/css_overview/css_overview.js
-front_end/css_overview/CSSOverviewUnusedDeclarations.js
-front_end/css_overview/CSSOverviewStartView.js
-front_end/css_overview/CSSOverviewSidebarPanel.js
-front_end/css_overview/CSSOverviewProcessingView.js
-front_end/css_overview/CSSOverviewPanel.js
-front_end/css_overview/CSSOverviewModel.js
-front_end/css_overview/CSSOverviewController.js
-front_end/css_overview/CSSOverviewCompletedView.js
-front_end/console/console.js
-front_end/console/ConsoleContextSelector.js
-front_end/console/ConsoleFilter.js
-front_end/console/ConsoleSidebar.js
-front_end/console/ConsolePanel.js
-front_end/console/ConsolePinPane.js
-front_end/console/ConsolePrompt.js
-front_end/console/ConsoleView.js
-front_end/console/ConsoleViewMessage.js
-front_end/console/ConsoleViewport.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/XMLView.js
-front_end/source_frame/SourcesTextEditor.js
-front_end/source_frame/SourceFrame.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/SourceCodeDiff.js
-front_end/source_frame/ResourceSourceFrame.js
-front_end/source_frame/PreviewFactory.js
-front_end/source_frame/JSONView.js
-front_end/source_frame/ImageView.js
-front_end/source_frame/FontView.js
-front_end/source_frame/BinaryResourceViewFactory.js
-front_end/inline_editor/inline_editor.js
-front_end/inline_editor/SwatchPopoverHelper.js
-front_end/inline_editor/CSSShadowModel.js
-front_end/inline_editor/CSSShadowEditor.js
-front_end/inline_editor/ColorSwatch.js
-front_end/inline_editor/BezierUI.js
-front_end/inline_editor/BezierEditor.js
-front_end/diff/diff.js
-front_end/diff/diff_match_patch.js
-front_end/diff/DiffWrapper.js
-front_end/formatter/formatter.js
-front_end/formatter/ScriptFormatter.js
-front_end/formatter/FormatterWorkerPool.js
-front_end/color_picker/color_picker.js
-front_end/color_picker/Spectrum.js
-front_end/color_picker/ContrastOverlay.js
-front_end/color_picker/ContrastInfo.js
-front_end/color_picker/ContrastDetails.js
-front_end/cm/cm.js
-front_end/cm/active-line.js
-front_end/cm/brace-fold.js
-front_end/cm/closebrackets.js
-front_end/cm/codemirror.js
-front_end/cm/comment.js
-front_end/cm/foldcode.js
-front_end/cm/foldgutter.js
-front_end/cm/mark-selection.js
-front_end/cm/matchbrackets.js
-front_end/cm/multiplex.js
-front_end/cm/overlay.js
-front_end/formatter_worker.unbundled.js
-front_end/heap_snapshot_worker.unbundled.js
-front_end/heap_snapshot_model/heap_snapshot_model.js
-front_end/heap_snapshot_model/HeapSnapshotModel.js
-front_end/heap_snapshot_worker/heap_snapshot_worker.js
-front_end/heap_snapshot_worker/AllocationProfile.js
-front_end/heap_snapshot_worker/HeapSnapshot.js
-front_end/heap_snapshot_worker/HeapSnapshotLoader.js
-front_end/heap_snapshot_worker/HeapSnapshotWorker.js
-front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
-front_end/text_utils/text_utils.js
-front_end/text_utils/TextUtils.js
-front_end/text_utils/TextRange.js
-front_end/text_utils/Text.js
-front_end/formatter_worker/formatter_worker.js
-front_end/formatter_worker/RelaxedJSONParser.js
-front_end/formatter_worker/JavaScriptOutline.js
-front_end/formatter_worker/JavaScriptFormatter.js
-front_end/formatter_worker/IdentityFormatter.js
-front_end/formatter_worker/HTMLFormatter.js
-front_end/formatter_worker/FormatterWorker.js
-front_end/formatter_worker/FormattedContentBuilder.js
-front_end/formatter_worker/ESTreeWalker.js
-front_end/formatter_worker/CSSRuleParser.js
-front_end/formatter_worker/CSSFormatter.js
-front_end/formatter_worker/AcornTokenizer.js
-front_end/cm_headless/cm_headless.js
-front_end/cm_headless/headlesscodemirror.js
-front_end/data_grid/data_grid.js
-front_end/data_grid/ViewportDataGrid.js
-front_end/data_grid/SortableDataGrid.js
-front_end/data_grid/ShowMoreDataGridNode.js
-front_end/data_grid/DataGrid.js
-front_end/protocol_monitor/protocol_monitor.js
-front_end/protocol_monitor/ProtocolMonitor.js
-front_end/console_counters/console_counters.js
-front_end/console_counters/WarningErrorCounter.js
-front_end/extensions/extensions.js
-front_end/extensions/ExtensionAPI.js
-front_end/extensions/ExtensionPanel.js
-front_end/extensions/ExtensionServer.js
-front_end/extensions/ExtensionTraceProvider.js
-front_end/extensions/ExtensionView.js
-front_end/browser_sdk/browser_sdk.js
-front_end/browser_sdk/LogManager.js
-front_end/persistence/persistence.js
-front_end/persistence/WorkspaceSettingsTab.js
-front_end/persistence/PlatformFileSystem.js
-front_end/persistence/PersistenceUtils.js
-front_end/persistence/PersistenceImpl.js
-front_end/persistence/PersistenceActions.js
-front_end/persistence/NetworkPersistenceManager.js
-front_end/persistence/IsolatedFileSystemManager.js
-front_end/persistence/IsolatedFileSystem.js
-front_end/persistence/FileSystemWorkspaceBinding.js
-front_end/persistence/EditFileSystemView.js
-front_end/persistence/Automapping.js
-front_end/components/components.js
-front_end/components/TargetDetachedDialog.js
-front_end/components/Reload.js
-front_end/components/Linkifier.js
-front_end/components/JSPresentationUtils.js
-front_end/components/ImagePreview.js
-front_end/components/DockController.js
-front_end/bindings/bindings.js
-front_end/bindings/TempFile.js
-front_end/bindings/StylesSourceMapping.js
-front_end/bindings/SASSSourceMapping.js
-front_end/bindings/ResourceUtils.js
-front_end/bindings/ResourceScriptMapping.js
-front_end/bindings/ResourceMapping.js
-front_end/bindings/PresentationConsoleMessageHelper.js
-front_end/bindings/NetworkProject.js
-front_end/bindings/LiveLocation.js
-front_end/bindings/FileUtils.js
-front_end/bindings/DefaultScriptMapping.js
-front_end/bindings/DebuggerWorkspaceBinding.js
-front_end/bindings/CSSWorkspaceBinding.js
-front_end/bindings/ContentProviderBasedProject.js
-front_end/bindings/CompilerScriptMapping.js
-front_end/bindings/BreakpointManager.js
-front_end/bindings/BlackboxManager.js
-front_end/workspace/workspace.js
-front_end/workspace/WorkspaceImpl.js
-front_end/workspace/UISourceCode.js
-front_end/workspace/FileManager.js
-front_end/services/services.js
-front_end/services/ServiceManager.js
-front_end/sdk/sdk.js
-front_end/sdk/TracingModel.js
-front_end/sdk/TracingManager.js
-front_end/sdk/TargetManager.js
-front_end/sdk/Target.js
-front_end/sdk/SourceMapManager.js
-front_end/sdk/SourceMap.js
-front_end/sdk/ServiceWorkerManager.js
-front_end/sdk/ServiceWorkerCacheModel.js
-front_end/sdk/ServerTiming.js
-front_end/sdk/SecurityOriginManager.js
-front_end/sdk/SDKModel.js
-front_end/sdk/Script.js
-front_end/sdk/ScreenCaptureModel.js
-front_end/sdk/RuntimeModel.js
-front_end/sdk/ResourceTreeModel.js
-front_end/sdk/Resource.js
-front_end/sdk/RemoteObject.js
-front_end/sdk/ProfileTreeModel.js
-front_end/sdk/IssuesModel.js
-front_end/sdk/PerformanceMetricsModel.js
-front_end/sdk/PaintProfiler.js
-front_end/sdk/OverlayModel.js
-front_end/sdk/NetworkRequest.js
-front_end/sdk/NetworkManager.js
-front_end/sdk/NetworkLog.js
-front_end/sdk/LogModel.js
-front_end/sdk/LayerTreeBase.js
-front_end/sdk/IsolateManager.js
-front_end/sdk/HeapProfilerModel.js
-front_end/sdk/HARLog.js
-front_end/sdk/FilmStripModel.js
-front_end/sdk/EmulationModel.js
-front_end/sdk/DOMModel.js
-front_end/sdk/DOMDebuggerModel.js
-front_end/sdk/DebuggerModel.js
-front_end/sdk/CSSStyleSheetHeader.js
-front_end/sdk/CSSStyleDeclaration.js
-front_end/sdk/CSSRule.js
-front_end/sdk/CSSProperty.js
-front_end/sdk/CSSModel.js
-front_end/sdk/CSSMetadata.js
-front_end/sdk/CSSMedia.js
-front_end/sdk/CSSMatchedStyles.js
-front_end/sdk/CPUProfilerModel.js
-front_end/sdk/CPUProfileDataModel.js
-front_end/sdk/CookieParser.js
-front_end/sdk/CookieModel.js
-front_end/sdk/CompilerSourceMappingContentProvider.js
-front_end/sdk/ConsoleModel.js
-front_end/sdk/Connections.js
-front_end/sdk/ChildTargetManager.js
-front_end/protocol/protocol.js
-front_end/protocol/NodeURL.js
-front_end/protocol/InspectorBackend.js
-front_end/host/host.js
-front_end/host/UserMetrics.js
-front_end/host/ResourceLoader.js
-front_end/host/Platform.js
-front_end/host/InspectorFrontendHost.js
-front_end/host/InspectorFrontendHostAPI.js
-front_end/dom_extension/DOMExtension.js
-front_end/dom_extension/dom_extension.js
-front_end/root.js
-front_end/Runtime.js
-front_end/platform/utilities.js
-front_end/platform/platform.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ZoomManager.js
-front_end/ui/XWidget.js
-front_end/ui/XLink.js
-front_end/ui/XElement.js
-front_end/ui/Widget.js
-front_end/ui/View.js
-front_end/ui/ViewManager.js
-front_end/ui/UIUtils.js
-front_end/ui/ui.js
-front_end/ui/Treeoutline.js
-front_end/ui/Tooltip.js
-front_end/ui/Toolbar.js
-front_end/ui/ThrottledWidget.js
-front_end/ui/TextPrompt.js
-front_end/ui/TextEditor.js
-front_end/ui/TargetCrashedScreen.js
-front_end/ui/TabbedPane.js
-front_end/ui/SyntaxHighlighter.js
-front_end/ui/SuggestBox.js
-front_end/ui/SplitWidget.js
-front_end/ui/SoftDropDown.js
-front_end/ui/SoftContextMenu.js
-front_end/ui/ShortcutsScreen.js
-front_end/ui/ShortcutRegistry.js
-front_end/ui/SettingsUI.js
-front_end/ui/SegmentedButton.js
-front_end/ui/SearchableView.js
-front_end/ui/RootView.js
-front_end/ui/ResizerWidget.js
-front_end/ui/ReportView.js
-front_end/ui/RemoteDebuggingTerminatedScreen.js
-front_end/ui/ProgressIndicator.js
-front_end/ui/PopoverHelper.js
-front_end/ui/Panel.js
-front_end/ui/ListWidget.js
-front_end/ui/ListModel.js
-front_end/ui/ListControl.js
-front_end/ui/KeyboardShortcut.js
-front_end/ui/InspectorView.js
-front_end/ui/InplaceEditor.js
-front_end/ui/Infobar.js
-front_end/ui/Icon.js
-front_end/ui/HistoryInput.js
-front_end/ui/GlassPane.js
-front_end/ui/Geometry.js
-front_end/ui/Fragment.js
-front_end/ui/ForwardedInputEventHandler.js
-front_end/ui/FilterSuggestionBuilder.js
-front_end/ui/FilterBar.js
-front_end/ui/EmptyWidget.js
-front_end/ui/DropTarget.js
-front_end/ui/Dialog.js
-front_end/ui/ContextMenu.js
-front_end/ui/Context.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ActionRegistry.js
-front_end/ui/Action.js
-front_end/ui/ActionDelegate.js
-front_end/ui/ContextFlavorListener.js
-front_end/root.js
-front_end/common/common.js
-front_end/common/common-legacy.js
-front_end/common/App.js
-front_end/common/AppProvider.js
-front_end/common/CharacterIdMap.js
-front_end/common/Color.js
-front_end/common/ContentProvider.js
-front_end/common/EventTarget.js
-front_end/common/JavaScriptMetaData.js
-front_end/common/Linkifier.js
-front_end/common/Object.js
-front_end/common/Console.js
-front_end/common/ParsedURL.js
-front_end/common/Progress.js
-front_end/common/QueryParamHandler.js
-front_end/common/ResourceType.js
-front_end/common/Revealer.js
-front_end/common/Runnable.js
-front_end/common/SegmentedRange.js
-front_end/common/Settings.js
-front_end/common/StaticContentProvider.js
-front_end/common/StringOutputStream.js
-front_end/common/TextDictionary.js
-front_end/common/Throttler.js
-front_end/common/Trie.js
-front_end/common/UIString.js
-front_end/common/Worker.js
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index 390fc55..a7b2fd9 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -16,8 +16,8 @@
 
 #include <string>
 
-#include "base/time/time.h"
 #include "base/time/default_clock.h"
+#include "base/time/time.h"
 #include "cobalt/browser/stack_size_constants.h"
 #include "cobalt/dom/dom_exception.h"
 #include "cobalt/dom/memory_info.h"
@@ -67,7 +67,7 @@
   return 0.0;
 }
 
-}  //namespace
+}  // namespace
 
 Performance::Performance(script::EnvironmentSettings* settings,
                          const scoped_refptr<base::BasicClock>& clock)
@@ -83,8 +83,8 @@
       resource_timing_secondary_buffer_current_size_(0),
       performance_observer_task_queued_flag_(false),
       add_to_performance_entry_buffer_flag_(false) {
-  unix_at_zero_monotonic_ = GetUnixAtZeroMonotonic(
-      base::DefaultClock::GetInstance(), tick_clock_);
+  unix_at_zero_monotonic_ =
+      GetUnixAtZeroMonotonic(base::DefaultClock::GetInstance(), tick_clock_);
   lifecycle_timing_ = base::MakeRefCounted<PerformanceLifecycleTiming>(
       "lifecycle timing", time_origin());
   // Queue lifecycle timing.
@@ -95,15 +95,15 @@
 
 // static
 DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
-      base::TimeTicks time_origin,
-      base::TimeTicks monotonic_time) {
-  if (monotonic_time.is_null() || time_origin.is_null())
-    return 0.0;
+    base::TimeTicks time_origin, base::TimeTicks monotonic_time) {
+  if (monotonic_time.is_null() || time_origin.is_null()) return 0.0;
   DOMHighResTimeStamp clamped_time =
-      ClampTimeStampMinimumResolution(monotonic_time,
-      Performance::kPerformanceTimerMinResolutionInMicroseconds) -
-      ClampTimeStampMinimumResolution(time_origin,
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+      ClampTimeStampMinimumResolution(
+          monotonic_time,
+          Performance::kPerformanceTimerMinResolutionInMicroseconds) -
+      ClampTimeStampMinimumResolution(
+          time_origin,
+          Performance::kPerformanceTimerMinResolutionInMicroseconds);
 
   return clamped_time;
 }
@@ -140,8 +140,7 @@
 
   // Return the sum of t1 and t2.
   return ClampTimeStampMinimumResolution(
-      t1 + t2,
-      Performance::kPerformanceTimerMinResolutionInMicroseconds);
+      t1 + t2, Performance::kPerformanceTimerMinResolutionInMicroseconds);
 }
 
 void Performance::Mark(const std::string& mark_name,
@@ -382,8 +381,9 @@
   // entry buffer.
   PerformanceEntryList performance_entry_buffer;
   for (const auto& entry : performance_entry_buffer_) {
-    bool should_be_removed = PerformanceEntry::ToEntryTypeEnum(
-        entry->entry_type()) == PerformanceEntry::kResource;
+    bool should_be_removed =
+        PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
+        PerformanceEntry::kResource;
     if (!should_be_removed) {
       performance_entry_buffer.push_back(entry);
     }
@@ -606,8 +606,8 @@
   // 2.Setup the resource timing entry for entry, given initiatorType,
   // requestedURL, timingInfo, and cacheMode.
   scoped_refptr<PerformanceResourceTiming> resource_timing(
-      new PerformanceResourceTiming(timing_info, initiator_type,
-                                    requested_url, this, time_origin_));
+      new PerformanceResourceTiming(timing_info, initiator_type, requested_url,
+                                    this, time_origin_));
   // 2. Queue entry.
   QueuePerformanceEntry(resource_timing);
   // 3. Add entry to global's performance entry buffer.
@@ -621,8 +621,8 @@
 
 void Performance::SetApplicationStartOrPreloadTimestamp(
     bool is_preload, SbTimeMonotonic timestamp) {
-  lifecycle_timing_->SetApplicationStartOrPreloadTimestamp(
-      is_preload, timestamp);
+  lifecycle_timing_->SetApplicationStartOrPreloadTimestamp(is_preload,
+                                                           timestamp);
 }
 
 void Performance::SetDeepLinkTimestamp(SbTimeMonotonic timestamp) {
diff --git a/src/cobalt/dom/performance_test.cc b/src/cobalt/dom/performance_test.cc
index be1e776..4d9d6ce 100644
--- a/src/cobalt/dom/performance_test.cc
+++ b/src/cobalt/dom/performance_test.cc
@@ -25,7 +25,8 @@
       new base::SystemMonotonicClock());
 
   testing::StubEnvironmentSettings environment_settings;
-  scoped_refptr<Performance> performance(new Performance(&environment_settings, clock));
+  scoped_refptr<Performance> performance(
+      new Performance(&environment_settings, clock));
 
   // Test that now returns a result that is within a correct range for the
   // current time.
@@ -46,10 +47,11 @@
       new base::SystemMonotonicClock());
 
   testing::StubEnvironmentSettings environment_settings;
-  scoped_refptr<Performance> performance(new Performance(&environment_settings, clock));
+  scoped_refptr<Performance> performance(
+      new Performance(&environment_settings, clock));
 
   base::TimeTicks current_time_ticks = base::TimeTicks::Now();
-  DOMHighResTimeStamp  current_time = ClampTimeStampMinimumResolution(
+  DOMHighResTimeStamp current_time = ClampTimeStampMinimumResolution(
       current_time_ticks,
       Performance::kPerformanceTimerMinResolutionInMicroseconds);
   DOMHighResTimeStamp current_time_respect_to_time_origin =
diff --git a/src/cobalt/evergreen_tests/__init__.py b/src/cobalt/evergreen_tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cobalt/evergreen_tests/__init__.py
diff --git a/src/cobalt/evergreen_tests/_env.py b/src/cobalt/evergreen_tests/_env.py
new file mode 100644
index 0000000..8a079e2
--- /dev/null
+++ b/src/cobalt/evergreen_tests/_env.py
@@ -0,0 +1,28 @@
+#
+# Copyright 2021 The Cobalt Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""Ask the parent directory to load the project environment."""
+
+from __future__ import print_function
+
+from imp import load_source  # pylint: disable=deprecated-module
+from os import path
+import sys
+
+_ENV = path.abspath(path.join(path.dirname(__file__), path.pardir, '_env.py'))
+if not path.exists(_ENV):
+  print('%s: Can\'t find repo root.\nMissing parent: %s' % (__file__, _ENV))
+  sys.exit(1)
+load_source('', _ENV)
diff --git a/src/cobalt/evergreen_tests/evergreen_tests.py b/src/cobalt/evergreen_tests/evergreen_tests.py
new file mode 100644
index 0000000..38845e8
--- /dev/null
+++ b/src/cobalt/evergreen_tests/evergreen_tests.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+# Copyright 2021 The Cobalt Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""Prepares the host for and then runs the Cobalt Evergreen automated tests."""
+
+import argparse
+import logging
+import os
+import subprocess
+import sys
+
+import _env  # pylint: disable=unused-import
+
+from starboard.tools import abstract_launcher
+from starboard.tools import command_line
+from starboard.tools import log_level
+from starboard.tools.paths import REPOSITORY_ROOT
+
+_DEFAULT_PLATFORM_UNDER_TEST = 'linux'
+
+
+def _Exec(cmd, env=None):
+  try:
+    msg = 'Executing:\n    ' + ' '.join(cmd)
+    logging.info(msg)
+    p = subprocess.Popen(  # pylint: disable=consider-using-with
+        cmd,
+        env=env,
+        stderr=subprocess.STDOUT,
+        universal_newlines=True)
+    p.wait()
+    return p.returncode
+  except KeyboardInterrupt:
+    p.kill()
+    return 1
+
+
+def main():
+  arg_parser = argparse.ArgumentParser()
+  arg_parser.add_argument(
+      '--no-can_mount_tmpfs',
+      dest='can_mount_tmpfs',
+      action='store_false',
+      help='A temporary filesystem cannot be mounted on the target device.')
+  arg_parser.add_argument(
+      '--platform_under_test',
+      default=_DEFAULT_PLATFORM_UNDER_TEST,
+      help='The platform to run the tests on (e.g., linux or raspi).')
+  command_line.AddLauncherArguments(arg_parser)
+  args = arg_parser.parse_args()
+
+  log_level.InitializeLogging(args)
+
+  launcher_params = command_line.CreateLauncherParams(arg_parser)
+
+  # Creating an instance of the Evergreen abstract launcher implementation
+  # generates a staging area in the 'out' directory with a predictable layout
+  # and all of the desired binaries.
+  launcher = abstract_launcher.LauncherFactory(
+      launcher_params.platform,
+      'cobalt',
+      launcher_params.config,
+      device_id=launcher_params.device_id,
+      target_params=launcher_params.target_params,
+      out_directory=launcher_params.out_directory,
+      loader_platform=launcher_params.loader_platform,
+      loader_config=launcher_params.loader_config,
+      loader_target='loader_app',
+      loader_out_directory=launcher_params.loader_out_directory)
+
+  # The automated tests use the |OUT| environment variable as the path to a
+  # known directory structure containing the desired binaries. This path is
+  # generated in the Evergreen abstract launcher implementation.
+  env = os.environ.copy()
+  env['OUT'] = launcher.staging_directory
+
+  args = arg_parser.parse_args()
+
+  # The automated tests also use the |CAN_MOUNT_TMPFS| environment variable.
+  # They assume a temporary filesystem can be mounted unless it's set to false.
+  env['CAN_MOUNT_TMPFS'] = '1' if args.can_mount_tmpfs else '0'
+
+  run_all_tests = os.path.join(REPOSITORY_ROOT,
+                               'starboard/evergreen/testing/run_all_tests.sh')
+  command = [run_all_tests, args.platform_under_test]
+
+  if launcher.device_id:
+    # The automated tests run on this host should target a remote device.
+    command.append(launcher.device_id)
+
+  return _Exec(command, env)
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/src/cobalt/extension/extension_test.cc b/src/cobalt/extension/extension_test.cc
index ef159a7..43b4925 100644
--- a/src/cobalt/extension/extension_test.cc
+++ b/src/cobalt/extension/extension_test.cc
@@ -22,6 +22,7 @@
 #include "cobalt/extension/installation_manager.h"
 #include "cobalt/extension/javascript_cache.h"
 #include "cobalt/extension/media_session.h"
+#include "cobalt/extension/memory_mapped_file.h"
 #include "cobalt/extension/platform_service.h"
 #include "cobalt/extension/updater_notification.h"
 #include "cobalt/extension/url_fetcher_observer.h"
@@ -328,5 +329,25 @@
       << "Extension struct should be a singleton";
 }
 
+TEST(ExtensionTest, MemoryMappedFile) {
+  typedef CobaltExtensionMemoryMappedFileApi ExtensionApi;
+  const char* kExtensionName = kCobaltExtensionMemoryMappedFileName;
+
+  const ExtensionApi* extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  if (!extension_api) {
+    return;
+  }
+
+  EXPECT_STREQ(extension_api->name, kExtensionName);
+  EXPECT_EQ(extension_api->version, 1u);
+  EXPECT_NE(extension_api->MemoryMapFile, nullptr);
+
+  const ExtensionApi* second_extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  EXPECT_EQ(second_extension_api, extension_api)
+      << "Extension struct should be a singleton";
+}
+
 }  // namespace extension
 }  // namespace cobalt
diff --git a/src/cobalt/extension/memory_mapped_file.h b/src/cobalt/extension/memory_mapped_file.h
new file mode 100644
index 0000000..7c1c4bb
--- /dev/null
+++ b/src/cobalt/extension/memory_mapped_file.h
@@ -0,0 +1,58 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#ifndef COBALT_EXTENSION_MEMORY_MAPPED_FILE_H_
+#define COBALT_EXTENSION_MEMORY_MAPPED_FILE_H_
+
+#include <stdint.h>
+
+#include "starboard/memory.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define kCobaltExtensionMemoryMappedFileName \
+  "dev.cobalt.extension.MemoryMappedFile"
+
+typedef struct CobaltExtensionMemoryMappedFileApi {
+  // Name should be the string |kCobaltExtensionMemoryMappedFileName|.
+  // This helps to validate that the extension API is correct.
+  const char* name;
+
+  // This specifies the version of the API that is implemented.
+  uint32_t version;
+
+  // The fields below this point were added in version 1 or later.
+
+  // Memory maps a file at the specified |address| starting at |file_offset|
+  // and  mapping |size| bytes. The |address| argument can be NULL in which
+  // case new memory buffer will be allocated. If a non NULL |address| is
+  // passed the memory should be resreved in advance through |SbMemoryMap|.
+  // To release the memory call |SbMemoryUnmap|.
+  // The |file_offset| must be a multiple of |kSbMemoryPageSize|.
+  // Returns NULL or error.
+  void* (*MemoryMapFile)(void* address, const char* path,
+                         SbMemoryMapFlags flags, int64_t file_offset,
+                         int64_t size);
+
+} CobaltExtensionMemoryMappedFileApi;
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // COBALT_EXTENSION_MEMORY_MAPPED_FILE_H_
diff --git a/src/cobalt/media/base/playback_statistics.cc b/src/cobalt/media/base/playback_statistics.cc
index 2aca335..ca6263d 100644
--- a/src/cobalt/media/base/playback_statistics.cc
+++ b/src/cobalt/media/base/playback_statistics.cc
@@ -127,13 +127,16 @@
                      "", "The error message of the media pipeline error.") {}
 
 PlaybackStatistics::~PlaybackStatistics() {
-  SbAtomicNoBarrier_Increment(&s_active_instances, -1);
+  if (has_active_instance_) {
+    DCHECK(SbAtomicAcquire_Load(&s_active_instances) > 0);
+    SbAtomicNoBarrier_Increment(&s_active_instances, -1);
+  }
 }
 
 void PlaybackStatistics::UpdateVideoConfig(
     const VideoDecoderConfig& video_config) {
-  if (is_initial_config_) {
-    is_initial_config_ = false;
+  if (!has_active_instance_) {
+    has_active_instance_ = true;
 
     SbAtomicNoBarrier_Increment(&s_active_instances, 1);
 
diff --git a/src/cobalt/media/base/playback_statistics.h b/src/cobalt/media/base/playback_statistics.h
index 78808b3..7507b31 100644
--- a/src/cobalt/media/base/playback_statistics.h
+++ b/src/cobalt/media/base/playback_statistics.h
@@ -54,7 +54,7 @@
   base::CVal<bool> is_video_eos_written_;
   base::CVal<PipelineStatus> pipeline_status_;
   base::CVal<std::string> error_message_;
-  bool is_initial_config_ = true;
+  bool has_active_instance_ = false;
   bool is_first_audio_buffer_written_ = false;
   bool is_first_video_buffer_written_ = false;
 };
diff --git a/src/cobalt/network/url_request_context.cc b/src/cobalt/network/url_request_context.cc
index 681f1fc..e8cdf83 100644
--- a/src/cobalt/network/url_request_context.cc
+++ b/src/cobalt/network/url_request_context.cc
@@ -84,6 +84,8 @@
       std::unique_ptr<net::CookieStore>(new net::CookieMonster(
           persistent_cookie_store_, NULL /* channel_id_service */, net_log)));
 
+  set_enable_brotli(true);
+
   base::Optional<net::ProxyConfig> proxy_config;
   if (!custom_proxy.empty()) {
     proxy_config = CreateCustomProxyConfig(custom_proxy);
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
index 4890e72..67fe50a 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.cc
@@ -324,6 +324,10 @@
         LOG(ERROR) << "---- Invalid fallback priority [" << value << "]";
         NOTREACHED();
       }
+    } else if (name_len == 15 &&
+               strncmp("disable_caching", name, name_len) == 0) {
+      family->disable_caching =
+          strcmp("true", value) == 0 || strcmp("1", value) == 0;
     } else {
       LOG(ERROR) << "---- Unsupported family attribute [" << name << "]";
       NOTREACHED();
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
index 8d92c16..6862a5e 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.cc
@@ -91,6 +91,7 @@
   }
 
   character_map_ = base::MakeRefCounted<font_character_map::CharacterMap>();
+  disable_character_map_ = family_info.disable_caching;
 
   family_name_ = family_info.names[0];
   SkTHashMap<SkString, int> styles_index_map;
@@ -392,10 +393,12 @@
               << "(" << style_entry->font_style.weight() << ", "
               << style_entry->font_style.width() << ", "
               << style_entry->font_style.slant() << ")";
+    scoped_refptr<font_character_map::CharacterMap> map =
+        disable_character_map_ ? NULL : character_map_;
     style_entry->typeface.reset(new SkTypeface_CobaltStreamProvider(
         stream_provider, style_entry->face_index, style_entry->font_style,
         style_entry->face_is_fixed_pitch, family_name_,
-        style_entry->disable_synthetic_bolding, character_map_));
+        style_entry->disable_synthetic_bolding, map));
   } else {
     LOG(ERROR) << "Failed to scan font: "
                << style_entry->font_file_path.c_str();
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
index 33ec970..774a90f 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h
@@ -135,6 +135,9 @@
   SkLanguage language_;
   font_character_map::PageRanges page_ranges_;
 
+  // Used when the styles in the styleset have different character mappings.
+  bool disable_character_map_;
+
   // NOTE: The following characters require locking when being accessed.
   bool is_character_map_generated_;
   scoped_refptr<font_character_map::CharacterMap> character_map_;
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
index 422276c..6314e5a 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
@@ -164,7 +164,8 @@
 // determine that a family cannot support a character, without needing to
 // generate a full mapping of the family's characters.
 struct FontFamilyInfo {
-  FontFamilyInfo() : is_fallback_family(true), fallback_priority(0) {}
+  FontFamilyInfo()
+      : is_fallback_family(true), fallback_priority(0), disable_caching(0) {}
 
   SkTArray<SkString> names;
   SkTArray<FontFileInfo> fonts;
@@ -172,6 +173,7 @@
   bool is_fallback_family;
   int fallback_priority;
   font_character_map::PageRanges page_ranges;
+  bool disable_caching;
 };
 
 #endif  // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKFONTUTIL_COBALT_H_
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
index 8f9cce8..a116c2c 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
+++ b/src/cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include <memory>
+#include <utility>
 
 #include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h"
 
@@ -44,16 +45,18 @@
 
 SkGlyphID SkTypeface_Cobalt::characterMapGetGlyphIdForCharacter(
     SkUnichar character) const {
-  CHECK(character_map_);
-
-  // Check whether the character is cached in the character map.
-  font_character_map::Character c = character_map_->Find(character);
-  if (c.is_set) return c.id;
+  if (character_map_) {
+    // Check whether the character is cached in the character map.
+    font_character_map::Character c = character_map_->Find(character);
+    if (c.is_set) return c.id;
+  }
 
   // If the character isn't there, look it up with FreeType, then cache it.
   SkGlyphID glyphs[1] = {0};
   SkTypeface_FreeType::onCharsToGlyphs(&character, 1, glyphs);
-  character_map_->Insert(character, glyphs[0]);
+  if (character_map_) {
+    character_map_->Insert(character, glyphs[0]);
+  }
   return glyphs[0];
 }
 
@@ -119,7 +122,6 @@
   *face_index = face_index_;
   return std::unique_ptr<SkFileMemoryChunkStream>(
       stream_provider_->OpenStream());
-  ;
 }
 
 size_t SkTypeface_CobaltStreamProvider::GetStreamLength() const {
diff --git a/src/cobalt/site/docs/development/setup-linux.md b/src/cobalt/site/docs/development/setup-linux.md
index 9e40a3e..014394d 100644
--- a/src/cobalt/site/docs/development/setup-linux.md
+++ b/src/cobalt/site/docs/development/setup-linux.md
@@ -63,8 +63,8 @@
 
 ```
 $ cd cobalt
-$ git mv src/* ./
-$ git mv src/.* ./
+$ mv src/* ./
+$ mv src/.* ./
 ```
 
 Once you do that, you'll be able to follow the following two steps to have C++
diff --git a/src/cobalt/updater/one_app_only_sandbox.cc b/src/cobalt/updater/one_app_only_sandbox.cc
index 8b31ce4..33e6478 100644
--- a/src/cobalt/updater/one_app_only_sandbox.cc
+++ b/src/cobalt/updater/one_app_only_sandbox.cc
@@ -26,13 +26,17 @@
 #include "cobalt/browser/switches.h"
 #include "cobalt/version.h"
 #include "starboard/event.h"
+#include "starboard/loader_app/app_key.h"
 #include "starboard/system.h"
 
 namespace {
 
+const char kMainAppKey[] = "aHR0cHM6Ly93d3cueW91dHViZS5jb20vdHY=";
+// Use the html instead of url or app key to target the Evergreen cert test
+// page, because there are various urls to launch the test page.
 const char kEvergreenCertTestHtml[] = "evergreen-cert-test.html";
 
-bool is_evergreen_cert_test = false;
+bool is_target_app = false;
 
 cobalt::browser::Application* g_application = NULL;
 bool g_is_startup_switch_set = false;
@@ -75,9 +79,8 @@
   }
   LOG(INFO) << "Concealing application.";
   DCHECK(!g_application);
-  g_application =
-      new cobalt::browser::Application(quit_closure, true /*should_preload*/,
-                                       timestamp);
+  g_application = new cobalt::browser::Application(
+      quit_closure, true /*should_preload*/, timestamp);
   DCHECK(g_application);
 }
 
@@ -91,15 +94,13 @@
   LOG(INFO) << "Starting application.";
 #if SB_API_VERSION >= 13
   DCHECK(!g_application);
-  g_application =
-      new cobalt::browser::Application(quit_closure, false /*not_preload*/,
-                                       timestamp);
+  g_application = new cobalt::browser::Application(
+      quit_closure, false /*not_preload*/, timestamp);
   DCHECK(g_application);
 #else
   if (!g_application) {
-    g_application = new cobalt::browser::Application(quit_closure,
-                                                     false /*should_preload*/,
-                                                     timestamp);
+    g_application = new cobalt::browser::Application(
+        quit_closure, false /*should_preload*/, timestamp);
     DCHECK(g_application);
   } else {
     g_application->Start(timestamp);
@@ -126,7 +127,7 @@
 }  // namespace
 
 void SbEventHandle(const SbEvent* event) {
-  if (is_evergreen_cert_test)
+  if (is_target_app)
     return ::cobalt::wrap_main::BaseEventHandler<
         PreloadApplication, StartApplication, HandleStarboardEvent,
         StopApplication>(event);
@@ -134,19 +135,22 @@
   const SbEventStartData* data = static_cast<SbEventStartData*>(event->data);
   const base::CommandLine command_line(
       data->argument_count, const_cast<const char**>(data->argument_values));
+
   if (command_line.HasSwitch(cobalt::browser::switches::kInitialURL)) {
     std::string url = command_line.GetSwitchValueASCII(
         cobalt::browser::switches::kInitialURL);
-    size_t pos = url.find(kEvergreenCertTestHtml);
-    if (pos != std::string::npos) {
-      // If the url is the Evergreen cert test page, hook up the app lifecycle
-      // functions.
-      is_evergreen_cert_test = true;
-      return ::cobalt::wrap_main::BaseEventHandler<
-          PreloadApplication, StartApplication, HandleStarboardEvent,
-          StopApplication>(event);
+    if (starboard::loader_app::GetAppKey(url) != kMainAppKey &&
+        url.find(kEvergreenCertTestHtml) == std::string::npos) {
+      // If the app is not the main app nor Evergreen cert test page, stop the
+      // app.
+      SbSystemRequestStop(0);
     }
   }
-  // If the url is not the Evergreen cert test page, stop the app.
-  SbSystemRequestStop(0);
+
+  // If the url is the main app or the Evergreen cert test page, hook up the app
+  // lifecycle functions.
+  is_target_app = true;
+  return ::cobalt::wrap_main::BaseEventHandler<
+      PreloadApplication, StartApplication, HandleStarboardEvent,
+      StopApplication>(event);
 }
diff --git a/src/cobalt/updater/one_app_only_sandbox.gyp b/src/cobalt/updater/one_app_only_sandbox.gyp
index f311023..0d99d26 100644
--- a/src/cobalt/updater/one_app_only_sandbox.gyp
+++ b/src/cobalt/updater/one_app_only_sandbox.gyp
@@ -20,6 +20,7 @@
       'dependencies': [
         '<(DEPTH)/cobalt/browser/browser.gyp:browser',
         '<(DEPTH)/net/net.gyp:net',
+        '<(DEPTH)/starboard/loader_app/app_key.gyp:app_key',
         '<(DEPTH)/starboard/starboard.gyp:starboard',
       ],
       'sources': [
diff --git a/src/docker-compose.yml b/src/docker-compose.yml
index cf7b156..7e2364f 100644
--- a/src/docker-compose.yml
+++ b/src/docker-compose.yml
@@ -41,6 +41,37 @@
   IS_CI: ${IS_CI:-0}
 
 services:
+#### Tools
+  pre-commit:
+    build:
+      context: ./docker/precommit_hooks
+      dockerfile: Dockerfile
+    image: pre-commit
+    volumes:
+    - ${COBALT_SRC:-.}:/code/
+    environment:
+      FROM_REF: ${FROM_REF:-HEAD^1}
+      TO_REF: ${TO_REF:-HEAD}
+
+  docsite:
+    build:
+      context: ./docker/docsite
+      dockerfile: Dockerfile
+    container_name: docsite
+    ports:
+      - "4000:4000"
+    volumes:
+      - ${COBALT_SRC:-.}:/code/
+  docsite-build-only:
+    container_name: docsite-build-only
+    environment:
+      # SITE_DST specifies where the files required to deploy the site should be
+      # placed, and by default this is under the "out" directory.
+      - SITE_DST=${SITE_DST:-/cobalt/out/deploy/www}
+    extends:
+      service: docsite
+
+#### Cobalt build containers
   base:
     build:
       args:
diff --git a/src/docker/docsite/Dockerfile b/src/docker/docsite/Dockerfile
index b5b4436..f4682a3 100644
--- a/src/docker/docsite/Dockerfile
+++ b/src/docker/docsite/Dockerfile
@@ -39,4 +39,4 @@
 
 USER defaultuser
 
-CMD /cobalt/third_party/repo-publishing-toolkit-local/preview-site.sh
+CMD /code/third_party/repo-publishing-toolkit-local/preview-site.sh
diff --git a/src/docker/docsite/docker-compose.yml b/src/docker/docsite/docker-compose.yml
deleted file mode 100644
index bc0b6e0..0000000
--- a/src/docker/docsite/docker-compose.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-version: '2.4'
-
-services:
-  docsite:
-    build:
-      context: .
-      dockerfile: Dockerfile
-    container_name: docsite
-    ports:
-      - "4000:4000"
-    volumes:
-      # We use ../../ when the environment variable COBALT_SRC is not set since
-      # this file is located two directories under the root of the repository.
-      - ${COBALT_SRC:-../../}:/cobalt/
-  docsite-build-only:
-    container_name: docsite-build-only
-    environment:
-      # SITE_DST specifies where the files required to deploy the site should be
-      # placed, and by default this is under the "out" directory.
-      - SITE_DST=${SITE_DST:-/cobalt/out/deploy/www}
-    extends:
-      service: docsite
diff --git a/src/precommit_hooks/check_copyright_year.py b/src/precommit_hooks/check_copyright_year.py
index a75e8b9..6e9f489 100755
--- a/src/precommit_hooks/check_copyright_year.py
+++ b/src/precommit_hooks/check_copyright_year.py
@@ -56,6 +56,7 @@
   copyright_re = re.compile(r'Copyright (?P<created>\d{4})'
                             r'(-(?P<current>\d{4}))? (?P<author>[\w\s]+)')
   current_year = datetime.datetime.today().year
+  errors = []
 
   for filename in filenames:
     with open(filename) as f:
@@ -67,29 +68,29 @@
 
         match = copyright_re.search(line)
         if match:
-          ret = False
-
           created_year = int(match.group('created'))
           if filename in new_files and created_year != current_year:
-            ret = True
-            print(f'Copyright header for file {filename}'
-                  f' has wrong year {created_year}')
+            errors.append(f'Copyright header for file {filename}'
+                          f' has wrong year {created_year}')
 
           year = match.group('current')
           if year and int(year) != current_year:
-            ret = True
-            print(f'Copyright header for file {filename}'
-                  f' has wrong ending year {year}')
+            errors.append(f'Copyright header for file {filename}'
+                          f' has wrong ending year {year}')
 
           # Strip to get rid of possible newline
           author = match.group('author').rstrip()
           if author != _ALLOWED_AUTHOR:
-            ret = True
-            print(f'Update author to be "{_ALLOWED_AUTHOR}" instead of '
-                  f'"{author}" for {filename}.')
+            errors.append(f'Update author to be "{_ALLOWED_AUTHOR}" instead of'
+                          f' "{author}" for {filename}.')
+          break
 
-          return ret
-
+  if errors:
+    print()  # Separate errors from warnings by a newline.
+    print('The following copyright errors were found:')
+    for error in errors:
+      print('  ' + error)
+    return True
   return False
 
 
diff --git a/src/starboard/BUILD.gn b/src/starboard/BUILD.gn
index 0902779..04693d8 100644
--- a/src/starboard/BUILD.gn
+++ b/src/starboard/BUILD.gn
@@ -62,6 +62,7 @@
         "//third_party/crashpad/client",
         "//third_party/crashpad/handler",
       ]
+      data_deps = [ "//starboard/loader_app" ]
     }
   }
 }
diff --git a/src/starboard/android/shared/application_android.cc b/src/starboard/android/shared/application_android.cc
index 9d52d26..9c171b1 100644
--- a/src/starboard/android/shared/application_android.cc
+++ b/src/starboard/android/shared/application_android.cc
@@ -247,13 +247,13 @@
       if (window_) {
         window_->native_window = native_window_;
       }
+      // Now that we have the window, signal that the Android UI thread can
+      // continue, before we start or resume the Starboard app.
+      android_command_condition_.Signal();
       // Media playback service is tied to UI window being created/destroyed
       // (rather than to the Activity lifecycle), the service should be
       // stopped before native window being created.
       StopMediaPlaybackService();
-      // Now that we have the window, signal that the Android UI thread can
-      // continue, before we start or resume the Starboard app.
-      android_command_condition_.Signal();
     }
       if (state() == kStateUnstarted) {
         // This is the initial launch, so we have to start Cobalt now that we
@@ -282,10 +282,6 @@
       // early in SendAndroidCommand().
       {
         ScopedLock lock(android_command_mutex_);
-        // Media playback service is tied to UI window being created/destroyed
-        // (rather than to the Activity lifecycle). The service should be
-        // started after window being destroyed.
-        StartMediaPlaybackService();
 // Cobalt can't keep running without a window, even if the Activity
 // hasn't stopped yet. DispatchAndDelete() will inject events as needed
 // if we're not already paused.
@@ -302,6 +298,10 @@
         // Now that we've suspended the Starboard app, and let go of the window,
         // signal that the Android UI thread can continue.
         android_command_condition_.Signal();
+        // Media playback service is tied to UI window being created/destroyed
+        // (rather than to the Activity lifecycle). The service should be
+        // started after window being destroyed.
+        StartMediaPlaybackService();
       }
       break;
 
diff --git a/src/starboard/android/shared/launcher.py b/src/starboard/android/shared/launcher.py
index abd2787..0175159 100644
--- a/src/starboard/android/shared/launcher.py
+++ b/src/starboard/android/shared/launcher.py
@@ -282,7 +282,7 @@
     # TODO: Need to wait until cobalt fully shutdown. Otherwise, it may get
     # dirty logs from previous test, and logs like "***Application Stopped***"
     # will cause unexpected errors.
-    # Simply wait 2s as a temperary solution.
+    # Simply wait 2s as a temporary solution.
     time.sleep(2)
     # Clear logcat
     self._CheckCallAdb('logcat', '-c')
@@ -450,3 +450,7 @@
   def GetDeviceIp(self):
     """Gets the device IP. TODO: Implement."""
     return None
+
+  def GetDeviceOutputPath(self):
+    """Writable path where test targets can output files"""
+    return '/data/data/{}/cache/'.format(_APP_PACKAGE_NAME)
diff --git a/src/starboard/android/shared/media_is_video_supported.cc b/src/starboard/android/shared/media_is_video_supported.cc
index 01c23d2..09895ed 100644
--- a/src/starboard/android/shared/media_is_video_supported.cc
+++ b/src/starboard/android/shared/media_is_video_supported.cc
@@ -42,13 +42,13 @@
     return false;
   }
   JniEnvExt* env = JniEnvExt::Get();
+  ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
 
   // An HDR capable VP9 or AV1 decoder is needed to handle HDR at all.
   bool has_hdr_capable_decoder =
       JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
           "dev/cobalt/media/MediaCodecUtil", "hasHdrCapableVideoDecoder",
-          "(Ljava/lang/String;)Z",
-          env->NewStringStandardUTFOrAbort(mime)) == JNI_TRUE;
+          "(Ljava/lang/String;)Z", j_mime.Get()) == JNI_TRUE;
   if (!has_hdr_capable_decoder) {
     return false;
   }
diff --git a/src/starboard/android/shared/microphone_impl.cc b/src/starboard/android/shared/microphone_impl.cc
index 1972d0e..68c4188 100644
--- a/src/starboard/android/shared/microphone_impl.cc
+++ b/src/starboard/android/shared/microphone_impl.cc
@@ -18,10 +18,12 @@
 #include <SLES/OpenSLES_Android.h>
 
 #include <algorithm>
+#include <cstddef>
 #include <queue>
 
 #include "starboard/android/shared/jni_env_ext.h"
 #include "starboard/common/log.h"
+#include "starboard/common/mutex.h"
 #include "starboard/common/scoped_ptr.h"
 #include "starboard/memory.h"
 #include "starboard/shared/starboard/thread_checker.h"
@@ -83,8 +85,10 @@
   // Keeps track of the microphone's current state.
   State state_;
   // Audio data that has been delivered to the buffer queue.
+  Mutex delivered_queue_mutex_;
   std::queue<int16_t*> delivered_queue_;
   // Audio data that is ready to be read.
+  Mutex ready_queue_mutex_;
   std::queue<int16_t*> ready_queue_;
 };
 
@@ -169,7 +173,10 @@
   for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) {
     int16_t* buffer = new int16_t[kSamplesPerBuffer];
     memset(buffer, 0, kBufferSizeInBytes);
-    delivered_queue_.push(buffer);
+    {
+      ScopedLock lock(delivered_queue_mutex_);
+      delivered_queue_.push(buffer);
+    }
     SLresult result =
         (*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
     if (!CheckReturnValue(result)) {
@@ -245,14 +252,17 @@
 
   int read_bytes = 0;
   scoped_ptr<int16_t> buffer;
-  // Go through the ready queue, reading and sending audio data.
-  while (!ready_queue_.empty() &&
-         audio_data_size - read_bytes >= kBufferSizeInBytes) {
-    buffer.reset(ready_queue_.front());
-    memcpy(static_cast<uint8_t*>(out_audio_data) + read_bytes,
-                 buffer.get(), kBufferSizeInBytes);
-    ready_queue_.pop();
-    read_bytes += kBufferSizeInBytes;
+  {
+    ScopedLock lock(ready_queue_mutex_);
+    // Go through the ready queue, reading and sending audio data.
+    while (!ready_queue_.empty() &&
+           audio_data_size - read_bytes >= kBufferSizeInBytes) {
+      buffer.reset(ready_queue_.front());
+      memcpy(static_cast<uint8_t*>(out_audio_data) + read_bytes, buffer.get(),
+             kBufferSizeInBytes);
+      ready_queue_.pop();
+      read_bytes += kBufferSizeInBytes;
+    }
   }
 
   buffer.reset();
@@ -272,18 +282,29 @@
 }
 
 void SbMicrophoneImpl::SwapAndPublishBuffer() {
-  if (!delivered_queue_.empty()) {
-    // The front item in the delivered queue already has the buffered data, so
-    // move it from the delivered queue to the ready queue for future reads.
-    int16_t* buffer = delivered_queue_.front();
-    delivered_queue_.pop();
+  int16_t* buffer = nullptr;
+  {
+    ScopedLock lock(delivered_queue_mutex_);
+    if (!delivered_queue_.empty()) {
+      // The front item in the delivered queue already has the buffered data, so
+      // move it from the delivered queue to the ready queue for future reads.
+      buffer = delivered_queue_.front();
+      delivered_queue_.pop();
+    }
+  }
+
+  if (buffer != NULL) {
+    ScopedLock lock(ready_queue_mutex_);
     ready_queue_.push(buffer);
   }
 
   if (state_ == kOpened) {
     int16_t* buffer = new int16_t[kSamplesPerBuffer];
     memset(buffer, 0, kBufferSizeInBytes);
-    delivered_queue_.push(buffer);
+    {
+      ScopedLock lock(delivered_queue_mutex_);
+      delivered_queue_.push(buffer);
+    }
     SLresult result =
         (*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
     CheckReturnValue(result);
@@ -437,14 +458,20 @@
     }
   }
 
-  while (!delivered_queue_.empty()) {
-    delete[] delivered_queue_.front();
-    delivered_queue_.pop();
+  {
+    ScopedLock lock(delivered_queue_mutex_);
+    while (!delivered_queue_.empty()) {
+      delete[] delivered_queue_.front();
+      delivered_queue_.pop();
+    }
   }
 
-  while (!ready_queue_.empty()) {
-    delete[] ready_queue_.front();
-    ready_queue_.pop();
+  {
+    ScopedLock lock(ready_queue_mutex_);
+    while (!ready_queue_.empty()) {
+      delete[] ready_queue_.front();
+      ready_queue_.pop();
+    }
   }
 }
 
diff --git a/src/starboard/android/shared/window_get_size.cc b/src/starboard/android/shared/window_get_size.cc
index a6182c4..744e233 100644
--- a/src/starboard/android/shared/window_get_size.cc
+++ b/src/starboard/android/shared/window_get_size.cc
@@ -29,6 +29,10 @@
     return false;
   }
 
+  if (window->native_window == NULL) {
+    SB_DLOG(ERROR) << __FUNCTION__ << ": Native window has been destroyed.";
+    return false;
+  }
   size->width = ANativeWindow_getWidth(window->native_window);
   size->height = ANativeWindow_getHeight(window->native_window);
 
diff --git a/src/starboard/android/x86/gyp_configuration.py b/src/starboard/android/x86/gyp_configuration.py
index 66dad6c..10bd752 100644
--- a/src/starboard/android/x86/gyp_configuration.py
+++ b/src/starboard/android/x86/gyp_configuration.py
@@ -1,4 +1,4 @@
-# Copyright 2016-2020 The Cobalt Authors. All Rights Reserved.
+# Copyright 2016-2021 The Cobalt Authors. All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -52,16 +52,6 @@
           'AudioDecoderTests/*',
           'VideoDecoderTests/*',
 
-          'PlayerComponentsTests/PlayerComponentsTest.Preroll/*',
-          'PlayerComponentsTests/PlayerComponentsTest.Pause/*',
-
-          'PlayerComponentsTests/PlayerComponentsTest.*/2',
-          'PlayerComponentsTests/PlayerComponentsTest.*/4',
-          'PlayerComponentsTests/PlayerComponentsTest.*/9',
-          'PlayerComponentsTests/PlayerComponentsTest.*/11',
-          'PlayerComponentsTests/PlayerComponentsTest.*/16',
-          'PlayerComponentsTests/PlayerComponentsTest.*/17',
-          'PlayerComponentsTests/PlayerComponentsTest.*/20',
-          'PlayerComponentsTests/PlayerComponentsTest.*/21',
+          'PlayerComponentsTests/*',
       ],
   }
diff --git a/src/starboard/build/collect_deploy_content.gypi b/src/starboard/build/collect_deploy_content.gypi
index 4068e57..65953f5 100644
--- a/src/starboard/build/collect_deploy_content.gypi
+++ b/src/starboard/build/collect_deploy_content.gypi
@@ -51,7 +51,7 @@
         'collect_deploy_content_extra_args': [ '--use_absolute_symlinks' ],
       }
     }],
-    ['cobalt_docker_build == 1 and host_os == "win"', {
+    ['cobalt_docker_build == 1 and host_os == "win" and cobalt_fastbuild != 1', {
       'variables': {
         'collect_deploy_content_extra_args': [ '--copy_override' ],
       }
diff --git a/src/starboard/build/collect_deploy_content.py b/src/starboard/build/collect_deploy_content.py
index 3f03b9d..3b4ce71 100755
--- a/src/starboard/build/collect_deploy_content.py
+++ b/src/starboard/build/collect_deploy_content.py
@@ -12,7 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-"""Builds a symlink farm pointing to specified subdirectories of the input dir."""
+"""Builds a symlink farm pointing to specified subdirs of the input dir."""
 
 import argparse
 import logging
@@ -21,7 +21,7 @@
 import sys
 
 import _env  # pylint: disable=unused-import
-import starboard.tools.port_symlink as port_symlink
+from starboard.tools import port_symlink
 from starboard.tools import log_level
 
 # The name of an environment variable that when set to |'1'|, signals to us that
@@ -60,6 +60,7 @@
     raise RuntimeError('Content is %d levels deep (max allowed is %d): %s' %
                        (depth, max_depth, deepest_file))
 
+
 def _CopyTree(src_path, dst_path):
   """Copy tree with a safeguard for windows long path (>260).
 
@@ -74,6 +75,7 @@
       dst_path = prefix + dst_path
   shutil.copytree(src_path, dst_path)
 
+
 def main(argv):
   parser = argparse.ArgumentParser()
   parser.add_argument(
diff --git a/src/starboard/build/install/install_target.gni b/src/starboard/build/install/install_target.gni
index aa7e715..e072622 100644
--- a/src/starboard/build/install/install_target.gni
+++ b/src/starboard/build/install/install_target.gni
@@ -15,8 +15,10 @@
 template("install_target") {
   if (invoker.type == "executable") {
     install_subdir = "bin"
+    source_name = invoker.installable_target_name
   } else if (invoker.type == "shared_library") {
     install_subdir = "lib"
+    source_name = "lib${invoker.installable_target_name}.so"
   } else {
     assert(false, "You can only install an executable or shared library.")
   }
@@ -29,7 +31,7 @@
                            ])
     deps = [ ":$installable_target_name" ]
 
-    sources = [ "$root_out_dir/$installable_target_name" ]
+    sources = [ "$root_out_dir/$source_name" ]
     outputs = [ "$root_out_dir/install/$install_subdir/{{source_file_part}}" ]
   }
 
diff --git a/src/starboard/contrib/linux/stadia/starboard_platform.gyp b/src/starboard/contrib/linux/stadia/starboard_platform.gyp
index ed04709..c1978ee 100644
--- a/src/starboard/contrib/linux/stadia/starboard_platform.gyp
+++ b/src/starboard/contrib/linux/stadia/starboard_platform.gyp
@@ -33,6 +33,8 @@
       '<(DEPTH)/starboard/shared/x11/egl_swap_buffers.cc',
       '<(DEPTH)/starboard/contrib/stadia/get_platform_service_api.cc',
       '<(DEPTH)/starboard/contrib/stadia/get_platform_service_api.h',
+      '<(DEPTH)/starboard/contrib/stadia/stadia_interface.cc',
+      '<(DEPTH)/starboard/contrib/stadia/stadia_interface.h',
       '<(DEPTH)/starboard/shared/x11/player_set_bounds.cc',
       '<(DEPTH)/starboard/shared/x11/window_create.cc',
       '<(DEPTH)/starboard/shared/x11/window_destroy.cc',
diff --git a/src/starboard/contrib/stadia/clients/vendor/public/stadia_export.h b/src/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
index bac4582..234e17c 100644
--- a/src/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
+++ b/src/starboard/contrib/stadia/clients/vendor/public/stadia_export.h
@@ -21,10 +21,10 @@
 // STADIA_EXPORT_FUNCTION(bool, GreaterThan, (int a, int b)) will produce the
 // following statements:
 //     * bool GreaterThan(int a, int b);
-//     * const char* kGreaterThan = "_GreaterThan";
+//     * constexpr const char* kGreaterThan = "_GreaterThan";
 //     * typedef bool (*GreaterThanFunction)(int a, int b);
 #define STADIA_EXPORT_FUNCTION(return_type, name, parameters) \
   return_type name parameters;                                \
-  const char* k##name = "_" #name;                            \
+  constexpr const char* k##name = #name;                      \
   typedef return_type(*name##Function) parameters
 #endif  // STARBOARD_CONTRIB_STADIA_CLIENTS_VENDOR_PUBLIC_STADIA_EXPORT_H_
diff --git a/src/starboard/contrib/stadia/get_platform_service_api.cc b/src/starboard/contrib/stadia/get_platform_service_api.cc
index d4dc0ac..cb73154 100644
--- a/src/starboard/contrib/stadia/get_platform_service_api.cc
+++ b/src/starboard/contrib/stadia/get_platform_service_api.cc
@@ -15,6 +15,7 @@
 #include "starboard/contrib/stadia/get_platform_service_api.h"
 
 #include <algorithm>
+#include <functional>
 #include <memory>
 #include <vector>
 
@@ -22,7 +23,7 @@
 #include "starboard/common/log.h"
 #include "starboard/common/mutex.h"
 #include "starboard/common/string.h"
-#include "starboard/contrib/stadia/clients/vendor/public/stadia_plugin.h"
+#include "starboard/contrib/stadia/stadia_interface.h"
 #include "starboard/event.h"
 #include "starboard/memory.h"
 #include "starboard/window.h"
@@ -44,7 +45,7 @@
 }  // namespace
 
 bool HasPlatformService(const char* name) {
-  return StadiaPluginHas(name);
+  return g_stadia_interface->StadiaPluginHas(name);
 }
 
 CobaltExtensionPlatformService OpenPlatformService(
@@ -57,7 +58,7 @@
   SB_DCHECK(context);
   SB_LOG(INFO) << "Open " << service_name.get();
 
-  if (!StadiaPluginHas(&service_name[0])) {
+  if (!g_stadia_interface->StadiaPluginHas(&service_name[0])) {
     SB_LOG(ERROR) << "Cannot open service. Service not found. "
                   << service_name.get();
     return kCobaltExtensionPlatformServiceInvalid;
@@ -71,7 +72,7 @@
 
       });
 
-  StadiaPlugin* plugin = StadiaPluginOpen(
+  StadiaPlugin* plugin = g_stadia_interface->StadiaPluginOpen(
       name_c_str,
 
       [](const uint8_t* const message, size_t length, void* user_data) -> void {
@@ -90,7 +91,7 @@
 void ClosePlatformService(CobaltExtensionPlatformService service) {
   SB_DCHECK(service);
   auto plugin = reinterpret_cast<StadiaPlugin*>(service);
-  StadiaPluginClose(plugin);
+  g_stadia_interface->StadiaPluginClose(plugin);
 }
 
 void* SendToPlatformService(CobaltExtensionPlatformService service,
@@ -115,11 +116,12 @@
       [](void* context) -> void {
         auto internal_data = std::unique_ptr<StadiaPluginSendToData>(
             static_cast<StadiaPluginSendToData*>(context));
-
         std::vector<uint8_t> plugin_data(internal_data->data);
-        StadiaPluginSendTo(internal_data->plugin,
-                           reinterpret_cast<const char*>(plugin_data.data()),
-                           plugin_data.size());
+
+        g_stadia_interface->StadiaPluginSendTo(
+            internal_data->plugin,
+            reinterpret_cast<const char*>(plugin_data.data()),
+            plugin_data.size());
       },
       send_to_plugin_data.release(), 0);
 
@@ -136,7 +138,7 @@
 }  // namespace
 
 const void* GetPlatformServiceApi() {
-  return &kPlatformServiceApi;
+  return g_stadia_interface == nullptr ? nullptr : &kPlatformServiceApi;
 }
 
 }  // namespace stadia
diff --git a/src/starboard/contrib/stadia/stadia_interface.cc b/src/starboard/contrib/stadia/stadia_interface.cc
new file mode 100644
index 0000000..3b607d7
--- /dev/null
+++ b/src/starboard/contrib/stadia/stadia_interface.cc
@@ -0,0 +1,71 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "starboard/contrib/stadia/stadia_interface.h"
+
+#include <dlfcn.h>
+#include <string>
+
+#include "starboard/common/log.h"
+#include "starboard/memory.h"
+
+namespace starboard {
+namespace contrib {
+namespace stadia {
+
+namespace {
+void* LookupSymbol(void* handle, const std::string& name) {
+  // Note, we assume that a NULL result from dlsym is abnormal in our case
+  // (even though this is not true in the general case).
+  void* symbol = dlsym(handle, name.c_str());
+  if (!symbol) {
+    SB_LOG(ERROR) << "Failed to find symbol for " << name << ": " << dlerror();
+  }
+  return symbol;
+}
+}  // namespace
+
+StadiaInterface::StadiaInterface() {
+  // Try to open the streaming client library.
+  void* lib_ptr = dlopen("libstreaming_client.so", RTLD_LAZY);
+  if (!lib_ptr) {
+    SB_LOG(ERROR) << "Failed to open streaming client library: " << dlerror();
+  }
+  // Try look up the library's entry point.
+  StadiaPluginHas = reinterpret_cast<StadiaPluginHasFunction>(
+      LookupSymbol(lib_ptr, kStadiaPluginHas));
+  StadiaPluginOpen = reinterpret_cast<StadiaPluginOpenFunction>(
+      LookupSymbol(lib_ptr, kStadiaPluginOpen));
+  StadiaPluginSendTo = reinterpret_cast<StadiaPluginSendToFunction>(
+      LookupSymbol(lib_ptr, kStadiaPluginSendTo));
+  StadiaPluginClose = reinterpret_cast<StadiaPluginCloseFunction>(
+      LookupSymbol(lib_ptr, kStadiaPluginClose));
+  StadiaInitialize = reinterpret_cast<StadiaInitializeFunction>(
+      LookupSymbol(lib_ptr, kStadiaInitialize));
+
+  // Return an empty optional if any entry point wasn't found.
+  if (!StadiaPluginHas || !StadiaPluginOpen || !StadiaPluginSendTo ||
+      !StadiaPluginClose || !StadiaInitialize) {
+    SB_LOG(ERROR) << "Failed to look up one or more symbols, "
+                  << "disabling streaming client.";
+  }
+}
+
+}  // namespace stadia
+}  // namespace contrib
+}  // namespace starboard
+
+// By default, the stadia_interface does not exist; it must be instantiated by
+// the application.
+const starboard::contrib::stadia::StadiaInterface* g_stadia_interface = nullptr;
diff --git a/src/starboard/contrib/stadia/stadia_interface.h b/src/starboard/contrib/stadia/stadia_interface.h
new file mode 100644
index 0000000..0fadb6e
--- /dev/null
+++ b/src/starboard/contrib/stadia/stadia_interface.h
@@ -0,0 +1,42 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_CONTRIB_STADIA_STADIA_INTERFACE_H_
+#define STARBOARD_CONTRIB_STADIA_STADIA_INTERFACE_H_
+
+#include "clients/vendor/public/stadia_lifecycle.h"
+#include "clients/vendor/public/stadia_plugin.h"
+
+namespace starboard {
+namespace contrib {
+namespace stadia {
+
+struct StadiaInterface {
+  StadiaPluginHasFunction StadiaPluginHas;
+  StadiaPluginOpenFunction StadiaPluginOpen;
+  StadiaPluginSendToFunction StadiaPluginSendTo;
+  StadiaPluginCloseFunction StadiaPluginClose;
+
+  StadiaInitializeFunction StadiaInitialize;
+
+  StadiaInterface();
+};
+
+}  // namespace stadia
+}  // namespace contrib
+}  // namespace starboard
+
+extern const starboard::contrib::stadia::StadiaInterface* g_stadia_interface;
+
+#endif  // STARBOARD_CONTRIB_STADIA_STADIA_INTERFACE_H_
diff --git a/src/starboard/contrib/stadia/x11/application_stadia_x11.cc b/src/starboard/contrib/stadia/x11/application_stadia_x11.cc
index dde9300..3cf0d36 100644
--- a/src/starboard/contrib/stadia/x11/application_stadia_x11.cc
+++ b/src/starboard/contrib/stadia/x11/application_stadia_x11.cc
@@ -14,7 +14,8 @@
 
 #include "starboard/contrib/stadia/x11/application_stadia_x11.h"
 
-#include "starboard/contrib/stadia/services/vendor/linux/public/stadia_lifecycle.h"
+#include "starboard/contrib/stadia/clients/vendor/public/stadia_lifecycle.h"
+#include "starboard/contrib/stadia/stadia_interface.h"
 #include "starboard/shared/x11/window_internal.h"
 
 namespace starboard {
@@ -22,6 +23,10 @@
 namespace stadia {
 namespace x11 {
 
+namespace {
+const char kEnableStadia[] = "enable-stadia";
+}
+
 using ::starboard::shared::dev_input::DevInput;
 
 constexpr char kAppId[] = "com.google.stadia.linux";
@@ -29,7 +34,11 @@
 SbWindow ApplicationStadiaX11::CreateWindow(const SbWindowOptions* options) {
   SbWindow window =
       starboard::shared::x11::ApplicationX11::CreateWindow(options);
-  StadiaInitialize();
+
+  if (GetCommandLine()->HasSwitch(kEnableStadia)) {
+    g_stadia_interface = new starboard::contrib::stadia::StadiaInterface();
+    g_stadia_interface->StadiaInitialize();
+  }
   return window;
 }
 
diff --git a/src/starboard/contrib/stadia/x11/application_stadia_x11.h b/src/starboard/contrib/stadia/x11/application_stadia_x11.h
index c682cab..e399635 100644
--- a/src/starboard/contrib/stadia/x11/application_stadia_x11.h
+++ b/src/starboard/contrib/stadia/x11/application_stadia_x11.h
@@ -26,9 +26,6 @@
 // This application engine combines the generic queue with the X11 event queue.
 class ApplicationStadiaX11 : public starboard::shared::x11::ApplicationX11 {
  public:
-  ApplicationStadiaX11();
-  ~ApplicationStadiaX11();
-
   SbWindow CreateWindow(const SbWindowOptions* options) override;
 };
 
diff --git a/src/starboard/elf_loader/elf_header_test.cc b/src/starboard/elf_loader/elf_header_test.cc
index a00805b..cb03d42 100644
--- a/src/starboard/elf_loader/elf_header_test.cc
+++ b/src/starboard/elf_loader/elf_header_test.cc
@@ -14,6 +14,8 @@
 
 #include "starboard/elf_loader/elf_header.h"
 
+#include <string>
+
 #include "starboard/common/scoped_ptr.h"
 #include "starboard/elf_loader/file.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -30,7 +32,10 @@
  public:
   DummyFile(const char* buffer, int size) : buffer_(buffer), size_(size) {}
 
-  bool Open(const char* name) { return true; }
+  bool Open(const char* name) {
+    name_ = name;
+    return true;
+  }
   bool ReadFromOffset(int64_t offset, char* buffer, int size) {
     SB_LOG(INFO) << "ReadFromOffset";
     if (offset != 0) {
@@ -46,9 +51,12 @@
   }
   void Close() {}
 
+  const std::string& GetName() { return name_; }
+
  private:
   const char* buffer_;
   int size_;
+  std::string name_;
 };
 
 class ElfHeaderTest : public ::testing::Test {
diff --git a/src/starboard/elf_loader/elf_loader_impl.cc b/src/starboard/elf_loader/elf_loader_impl.cc
index 7445332..cf392a9 100644
--- a/src/starboard/elf_loader/elf_loader_impl.cc
+++ b/src/starboard/elf_loader/elf_loader_impl.cc
@@ -34,8 +34,7 @@
   if (s.size() < suffix.size()) {
     return false;
   }
-  return strcmp(s.c_str() + (s.size() - suffix.size()),
-                            suffix.c_str()) == 0;
+  return strcmp(s.c_str() + (s.size() - suffix.size()), suffix.c_str()) == 0;
 }
 
 }  // namespace
@@ -68,7 +67,18 @@
 
   SB_DLOG(INFO) << "Loaded ELF header";
 
-  program_table_.reset(new ProgramTable());
+  const auto* memory_mapped_file_extension =
+      reinterpret_cast<const CobaltExtensionMemoryMappedFileApi*>(
+          SbSystemGetExtension(kCobaltExtensionMemoryMappedFileName));
+  if (memory_mapped_file_extension &&
+      strcmp(memory_mapped_file_extension->name,
+             kCobaltExtensionMemoryMappedFileName) == 0 &&
+      memory_mapped_file_extension->version >= 1) {
+    program_table_.reset(new ProgramTable(memory_mapped_file_extension));
+  } else {
+    program_table_.reset(new ProgramTable(nullptr));
+  }
+
   program_table_->LoadProgramHeader(elf_header_loader_->GetHeader(),
                                     elf_file_.get());
 
diff --git a/src/starboard/elf_loader/file.h b/src/starboard/elf_loader/file.h
index ad9b701..0fd4a3d 100644
--- a/src/starboard/elf_loader/file.h
+++ b/src/starboard/elf_loader/file.h
@@ -15,6 +15,8 @@
 #ifndef STARBOARD_ELF_LOADER_FILE_H_
 #define STARBOARD_ELF_LOADER_FILE_H_
 
+#include <string>
+
 #include "starboard/types.h"
 
 namespace starboard {
@@ -35,6 +37,9 @@
   // Closes the underlying file.
   virtual void Close() = 0;
 
+  // Returns the name of the file.
+  virtual const std::string& GetName() = 0;
+
   virtual ~File() {}
 };
 
diff --git a/src/starboard/elf_loader/file_impl.cc b/src/starboard/elf_loader/file_impl.cc
index 94ee465..951db5f 100644
--- a/src/starboard/elf_loader/file_impl.cc
+++ b/src/starboard/elf_loader/file_impl.cc
@@ -39,6 +39,7 @@
 
 bool FileImpl::Open(const char* name) {
   SB_DLOG(INFO) << "Loading: " << name;
+  name_ = name;
   file_ = SbFileOpen(name, kSbFileOpenOnly | kSbFileRead, NULL, NULL);
   if (!file_) {
     return false;
@@ -72,5 +73,9 @@
   }
 }
 
+const std::string& FileImpl::GetName() {
+  return name_;
+}
+
 }  // namespace elf_loader
 }  // namespace starboard
diff --git a/src/starboard/elf_loader/file_impl.h b/src/starboard/elf_loader/file_impl.h
index ebd1c92..a6a30bd 100644
--- a/src/starboard/elf_loader/file_impl.h
+++ b/src/starboard/elf_loader/file_impl.h
@@ -16,6 +16,9 @@
 #define STARBOARD_ELF_LOADER_FILE_IMPL_H_
 
 #include "starboard/elf_loader/file.h"
+
+#include <string>
+
 #include "starboard/file.h"
 
 namespace starboard {
@@ -29,9 +32,11 @@
   bool Open(const char* name) override;
   bool ReadFromOffset(int64_t offset, char* buffer, int size) override;
   void Close() override;
+  const std::string& GetName() override;
 
  protected:
   SbFile file_;
+  std::string name_;
 
   FileImpl(const FileImpl&) = delete;
   void operator=(const FileImpl&) = delete;
diff --git a/src/starboard/elf_loader/program_table.cc b/src/starboard/elf_loader/program_table.cc
index 2684338..61d823c 100644
--- a/src/starboard/elf_loader/program_table.cc
+++ b/src/starboard/elf_loader/program_table.cc
@@ -35,14 +35,16 @@
 namespace starboard {
 namespace elf_loader {
 
-ProgramTable::ProgramTable()
+ProgramTable::ProgramTable(
+    const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension)
     : phdr_num_(0),
       phdr_mmap_(NULL),
       phdr_table_(NULL),
       phdr_size_(0),
       load_start_(NULL),
       load_size_(0),
-      base_memory_address_(0) {}
+      base_memory_address_(0),
+      memory_mapped_file_extension_(memory_mapped_file_extension) {}
 
 bool ProgramTable::LoadProgramHeader(const Ehdr* elf_header, File* elf_file) {
   if (!elf_header) {
@@ -77,39 +79,52 @@
 
   SB_DLOG(INFO) << "page_max - page_min=" << page_max - page_min;
 
-#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
-  phdr_mmap_ =
-      SbMemoryMap(phdr_size_, kSbMemoryMapProtectWrite, "program_header");
-  if (!phdr_mmap_) {
-    SB_LOG(ERROR) << "Failed to allocate memory";
-    return false;
-  }
+  if (memory_mapped_file_extension_) {
+    SB_DLOG(INFO) << "Memory mapped file for the program header";
+    phdr_mmap_ = memory_mapped_file_extension_->MemoryMapFile(
+        NULL, elf_file->GetName().c_str(), kSbMemoryMapProtectRead, page_min,
+        phdr_size_);
+    if (!phdr_mmap_) {
+      SB_LOG(ERROR) << "Failed to memory map the program header";
+      return false;
+    }
 
-  SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
-#else
-  SB_CHECK(false);
-#endif
-  if (!elf_file->ReadFromOffset(page_min, reinterpret_cast<char*>(phdr_mmap_),
-                                phdr_size_)) {
-    SB_LOG(ERROR) << "Failed to read program header from file offset: "
-                  << page_min;
-    return false;
-  }
+    SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
+  } else {
 #if SB_API_VERSION >= 12 || SB_HAS(MMAP)
-  bool mp_result =
-      SbMemoryProtect(phdr_mmap_, phdr_size_, kSbMemoryMapProtectRead);
-  SB_DLOG(INFO) << "mp_result=" << mp_result;
-  if (!mp_result) {
-    SB_LOG(ERROR) << "Failed to protect program header";
-    return false;
-  }
+    phdr_mmap_ =
+        SbMemoryMap(phdr_size_, kSbMemoryMapProtectWrite, "program_header");
+    if (!phdr_mmap_) {
+      SB_LOG(ERROR) << "Failed to allocate memory";
+      return false;
+    }
+
+    SB_DLOG(INFO) << "Allocated address=" << phdr_mmap_;
 #else
-  SB_CHECK(false);
+    SB_CHECK(false);
 #endif
+    if (!elf_file->ReadFromOffset(page_min, reinterpret_cast<char*>(phdr_mmap_),
+                                  phdr_size_)) {
+      SB_LOG(ERROR) << "Failed to read program header from file offset: "
+                    << page_min;
+      return false;
+    }
+#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
+    bool mp_result =
+        SbMemoryProtect(phdr_mmap_, phdr_size_, kSbMemoryMapProtectRead);
+    SB_DLOG(INFO) << "mp_result=" << mp_result;
+    if (!mp_result) {
+      SB_LOG(ERROR) << "Failed to protect program header";
+      return false;
+    }
+#else
+    SB_CHECK(false);
+#endif
+  }
 
   phdr_table_ = reinterpret_cast<Phdr*>(reinterpret_cast<char*>(phdr_mmap_) +
                                         page_offset);
-
+  SB_DLOG(INFO) << "phdr_table_=" << phdr_table_;
   return true;
 }
 
@@ -186,20 +201,33 @@
       SB_DLOG(INFO) << "segment prot_flags=" << std::hex << prot_flags;
 
       void* seg_addr = reinterpret_cast<void*>(seg_page_start);
-      bool mp_ret =
-          SbMemoryProtect(seg_addr, file_length, kSbMemoryMapProtectWrite);
-      SB_DLOG(INFO) << "segment vaddress=" << seg_addr;
+      bool mp_ret = false;
+      if (memory_mapped_file_extension_) {
+        SB_DLOG(INFO) << "Using Memory Mapped File for Loading the Segment";
+        void* p = memory_mapped_file_extension_->MemoryMapFile(
+            seg_addr, elf_file->GetName().c_str(), kSbMemoryMapProtectRead,
+            file_page_start, file_length);
+        if (!p) {
+          SB_LOG(ERROR) << "Failed to memory map file: " << elf_file->GetName();
+          return false;
+        }
+      } else {
+        SB_DLOG(INFO) << "Not using Memory Mapped Files";
+        mp_ret =
+            SbMemoryProtect(seg_addr, file_length, kSbMemoryMapProtectWrite);
+        SB_DLOG(INFO) << "segment vaddress=" << seg_addr;
 
-      if (!mp_ret) {
-        SB_LOG(ERROR) << "Failed to unprotect segment";
-        return false;
-      }
-      if (!elf_file->ReadFromOffset(file_page_start,
-                                    reinterpret_cast<char*>(seg_addr),
-                                    file_length)) {
-        SB_DLOG(INFO) << "Failed to read segment from file offset: "
-                      << file_page_start;
-        return false;
+        if (!mp_ret) {
+          SB_LOG(ERROR) << "Failed to unprotect segment";
+          return false;
+        }
+        if (!elf_file->ReadFromOffset(file_page_start,
+                                      reinterpret_cast<char*>(seg_addr),
+                                      file_length)) {
+          SB_DLOG(INFO) << "Failed to read segment from file offset: "
+                        << file_page_start;
+          return false;
+        }
       }
       mp_ret = SbMemoryProtect(seg_addr, file_length, prot_flags);
       SB_DLOG(INFO) << "mp_ret=" << mp_ret;
@@ -314,7 +342,7 @@
     SB_DLOG(INFO) << "Reading at vaddr: " << phdr->p_vaddr;
     *dynamic = reinterpret_cast<Dyn*>(base_memory_address_ + phdr->p_vaddr);
     if (dynamic_count) {
-      *dynamic_count = (size_t)(phdr->p_memsz / sizeof(Dyn));
+      *dynamic_count = static_cast<size_t>((phdr->p_memsz / sizeof(Dyn)));
     }
     if (dynamic_flags) {
       *dynamic_flags = phdr->p_flags;
diff --git a/src/starboard/elf_loader/program_table.h b/src/starboard/elf_loader/program_table.h
index 3741002..08f4231 100644
--- a/src/starboard/elf_loader/program_table.h
+++ b/src/starboard/elf_loader/program_table.h
@@ -17,6 +17,7 @@
 
 #include <vector>
 
+#include "cobalt/extension/memory_mapped_file.h"
 #include "starboard/elf_loader/elf.h"
 #include "starboard/elf_loader/file.h"
 
@@ -36,7 +37,8 @@
 
 class ProgramTable {
  public:
-  ProgramTable();
+  explicit ProgramTable(
+      const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension);
 
   // Loads the program header.
   bool LoadProgramHeader(const Ehdr* elf_header, File* elf_file);
@@ -90,6 +92,8 @@
   // from the ELF file are offsets from this address.
   Addr base_memory_address_;
 
+  const CobaltExtensionMemoryMappedFileApi* memory_mapped_file_extension_;
+
   ProgramTable(const ProgramTable&) = delete;
   void operator=(const ProgramTable&) = delete;
 };
diff --git a/src/starboard/elf_loader/program_table_test.cc b/src/starboard/elf_loader/program_table_test.cc
index 4e56dd7..3a23711 100644
--- a/src/starboard/elf_loader/program_table_test.cc
+++ b/src/starboard/elf_loader/program_table_test.cc
@@ -14,6 +14,7 @@
 
 #include "starboard/elf_loader/program_table.h"
 
+#include <string>
 #include <vector>
 
 #include "starboard/common/scoped_ptr.h"
@@ -41,7 +42,11 @@
   explicit DummyFile(const std::vector<FileChunk>& file_chunks)
       : file_chunks_(file_chunks), read_index_(0) {}
 
-  bool Open(const char* name) { return true; }
+  bool Open(const char* name) {
+    name_ = name;
+    return true;
+  }
+
   bool ReadFromOffset(int64_t offset, char* buffer, int size) {
     SB_LOG(INFO) << "ReadFromOffset offset=" << offset << " size=" << size
                  << " read_index_=" << read_index_;
@@ -65,17 +70,20 @@
   }
   void Close() {}
 
+  const std::string& GetName() { return name_; }
+
  private:
   int file_offset_;
   const char* buffer_;
   int size_;
   std::vector<FileChunk> file_chunks_;
   int read_index_;
+  std::string name_;
 };
 
 class ProgramTableTest : public ::testing::Test {
  protected:
-  ProgramTableTest() { program_table_.reset(new ProgramTable()); }
+  ProgramTableTest() { program_table_.reset(new ProgramTable(nullptr)); }
   ~ProgramTableTest() {}
 
   void HelperMethod() {}
@@ -136,14 +144,13 @@
 
   char program_table_page[PAGE_SIZE];
   memset(program_table_page, 0, sizeof(program_table_page));
-  memcpy(program_table_page, program_table_data,
-               sizeof(program_table_data));
+  memcpy(program_table_page, program_table_data, sizeof(program_table_data));
 
   char segment_file_data1[2 * PAGE_SIZE];
   char segment_file_data2[3 * PAGE_SIZE];
 
   memcpy(segment_file_data1 + 250, dynamic_table_data,
-               sizeof(dynamic_table_data));
+         sizeof(dynamic_table_data));
 
   std::vector<DummyFile::FileChunk> file_chunks;
   file_chunks.push_back(
diff --git a/src/starboard/evergreen/shared/launcher.py b/src/starboard/evergreen/shared/launcher.py
index 3915278..4a90b0c 100644
--- a/src/starboard/evergreen/shared/launcher.py
+++ b/src/starboard/evergreen/shared/launcher.py
@@ -163,11 +163,11 @@
       shutil.rmtree(self.staging_directory)
     os.makedirs(self.staging_directory)
 
-    # out/evergreen_staging/linux-x64x11_devel__evergreen-x64_devel/deploy/elf_loader_sandbox
+    # <outpath>/deploy/elf_loader_sandbox
     staging_directory_loader = os.path.join(self.staging_directory, 'deploy',
                                             self.loader_target)
 
-    # out/evergreen_staging/linux-x64x11_devel__evergreen-x64_devel/deploy/elf_loader_sandbox/content/app/nplb/
+    # <outpath>/deploy/elf_loader_sandbox/content/app/nplb/
     staging_directory_evergreen = os.path.join(staging_directory_loader,
                                                'content', 'app',
                                                self.target_name)
@@ -236,3 +236,6 @@
 
   def GetDeviceIp(self):
     return self.launcher.GetDeviceIp()
+
+  def GetDeviceOutputPath(self):
+    return self.launcher.GetDeviceOutputPath()
diff --git a/src/starboard/evergreen/testing/README.md b/src/starboard/evergreen/testing/README.md
index 69a7590..bbd33fe 100644
--- a/src/starboard/evergreen/testing/README.md
+++ b/src/starboard/evergreen/testing/README.md
@@ -86,7 +86,7 @@
 
 **Python Helper Script**
 
-The Python helper script at `cobalt/tools/buildbot/run_evergreen_tests.py`
+The Python helper script at `cobalt/evergreen_tests/evergreen_tests.py`
 simplifies the process of running the automated tests, and relies on the
 existing abstract launcher infrastructure.
 
@@ -98,7 +98,7 @@
 Then the following command can be used to run the tests.
 
 ```
-python cobalt/tools/buildbot/run_evergreen_tests.py \
+python cobalt/evergreen_tests/evergreen_tests.py \
     -p evergreen-x64 -c qa -P linux-x64x11 -C qa
 ```
 
diff --git a/src/starboard/evergreen/testing/linux/setup.sh b/src/starboard/evergreen/testing/linux/setup.sh
index 0d7eff5..0e7ab41 100755
--- a/src/starboard/evergreen/testing/linux/setup.sh
+++ b/src/starboard/evergreen/testing/linux/setup.sh
@@ -27,10 +27,11 @@
   rm -f ${STORAGE_DIR} 1> /dev/null
 fi
 
-# Mounting a temporary filesystem cannot be done on buildbot since it requires
-# sudo. When run locally, check for the temporary filesystem and create and
-# mount it if it does not exist.
-if [[ -z "${IS_BUILDBOT}" ]] || [[ "${IS_BUILDBOT}" -eq 0 ]]; then
+# If it's possible to mount a temporary filesystem then the temporary filesystem
+# is checked for and created + mounted if it does not exist. It's assumed to be
+# possible unless explicitly declared otherwise via the CAN_MOUNT_TMPFS
+# environment variable.
+if [[ -z "${CAN_MOUNT_TMPFS}" ]] || [[ "${CAN_MOUNT_TMPFS}" -eq 1 ]]; then
   if ! grep -qs "${STORAGE_DIR_TMPFS}" "/proc/mounts"; then
     echo " Missing tmpfs mount at ${STORAGE_DIR_TMPFS}"
 
diff --git a/src/starboard/evergreen/testing/raspi/setup.sh b/src/starboard/evergreen/testing/raspi/setup.sh
index 65c263a..3f484de 100755
--- a/src/starboard/evergreen/testing/raspi/setup.sh
+++ b/src/starboard/evergreen/testing/raspi/setup.sh
@@ -27,8 +27,13 @@
 TAIL="tail"
 WC="wc"
 
+# Prioritize the command-line argument over the environment variable.
+if [[ ! -z "${DEVICE_ID}" ]]; then
+  RASPI_ADDR="${DEVICE_ID}"
+fi
+
 if [[ -z "${RASPI_ADDR}" ]]; then
-  log "info" " Please set the environment variable 'RASPI_ADDR'"
+  log "info" " Please pass in the device id or set the environment variable 'RASPI_ADDR'"
   exit 1
 fi
 
@@ -50,10 +55,11 @@
 # Attempt to unlink the path, ignoring errors.
 eval "${SSH}\"unlink \"${STORAGE_DIR}\"\"" 1> /dev/null
 
-# Mounting a temporary filesystem cannot be done on buildbot since it requires
-# sudo. When run locally, check for the temporary filesystem and create and
-# mount it if it does not exist.
-if [[ -z "${IS_BUILDBOT}" ]] || [[ "${IS_BUILDBOT}" -eq 0 ]]; then
+# If it's possible to mount a temporary filesystem then the temporary filesystem
+# is checked for and created + mounted if it does not exist. It's assumed to be
+# possible unless explicitly declared otherwise via the CAN_MOUNT_TMPFS
+# environment variable.
+if [[ -z "${CAN_MOUNT_TMPFS}" ]] || [[ "${CAN_MOUNT_TMPFS}" -eq 1 ]]; then
   eval "${SSH}\"grep -qs \"${STORAGE_DIR_TMPFS}\" \"/proc/mounts\"\"" 1> /dev/null
 
   if [[ $? -ne 0 ]]; then
diff --git a/src/starboard/evergreen/testing/run_all_tests.sh b/src/starboard/evergreen/testing/run_all_tests.sh
index c59ef84..0d77b64 100755
--- a/src/starboard/evergreen/testing/run_all_tests.sh
+++ b/src/starboard/evergreen/testing/run_all_tests.sh
@@ -19,6 +19,7 @@
 # availability of "find", "grep", "ln", "mv", and "rm".
 
 DIR="$(dirname "${0}")"
+DEVICE_ID="${2}"
 
 if [[ ! -f "${DIR}/setup.sh" ]]; then
   echo "The script 'setup.sh' is required"
diff --git a/src/starboard/evergreen/testing/setup.sh b/src/starboard/evergreen/testing/setup.sh
index 0cf60da..4bef02a 100755
--- a/src/starboard/evergreen/testing/setup.sh
+++ b/src/starboard/evergreen/testing/setup.sh
@@ -26,7 +26,7 @@
 
 log "info" " [==========] Preparing Cobalt."
 
-if [[ $# -ne 1 ]]; then
+if [[ $# -lt 1 ]]; then
   log "error" "A platform must be provided"
   exit 1
 fi
diff --git a/src/starboard/evergreen/testing/tests/out_of_storage_test.sh b/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
index 3e13e55..851b54c 100755
--- a/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
+++ b/src/starboard/evergreen/testing/tests/out_of_storage_test.sh
@@ -23,8 +23,8 @@
 TEST_FILE="test.html"
 
 function run_test() {
-  if [[ ! -z "${IS_BUILDBOT}" ]] && [[ "${IS_BUILDBOT}" -eq 1 ]]; then
-    echo " Cannot mount temporary filesystems on builbot, skipping"
+  if [[ ! -z "${CAN_MOUNT_TMPFS}" ]] && [[ "${CAN_MOUNT_TMPFS}" -eq 0 ]]; then
+    echo " Cannot mount temporary filesystem, skipping"
     return 2
   fi
 
diff --git a/src/starboard/linux/shared/BUILD.gn b/src/starboard/linux/shared/BUILD.gn
index 07cc2eb..7fe8d4a 100644
--- a/src/starboard/linux/shared/BUILD.gn
+++ b/src/starboard/linux/shared/BUILD.gn
@@ -185,6 +185,8 @@
     "//starboard/shared/posix/memory_allocate_aligned_unchecked.cc",
     "//starboard/shared/posix/memory_flush.cc",
     "//starboard/shared/posix/memory_free_aligned.cc",
+    "//starboard/shared/posix/memory_mapped_file.cc",
+    "//starboard/shared/posix/memory_mapped_file.h",
     "//starboard/shared/posix/set_non_blocking_internal.cc",
     "//starboard/shared/posix/socket_accept.cc",
     "//starboard/shared/posix/socket_bind.cc",
@@ -386,6 +388,8 @@
 
   sources += common_player_sources
 
+  sources -= [ "//starboard/shared/starboard/player/player_set_bounds.cc" ]
+
   configs += [
     "//starboard/build/config:starboard_implementation",
     "//third_party/de265_includes",
diff --git a/src/starboard/linux/shared/launcher.py b/src/starboard/linux/shared/launcher.py
index 5cfec50..92001b6 100644
--- a/src/starboard/linux/shared/launcher.py
+++ b/src/starboard/linux/shared/launcher.py
@@ -83,7 +83,7 @@
   def Run(self):
     """Runs launcher's executable."""
 
-    self.proc = subprocess.Popen(
+    self.proc = subprocess.Popen(  # pylint: disable=consider-using-with
         [self.executable] + self.target_command_line_params,
         stdout=self.output_file,
         stderr=self.output_file,
@@ -197,3 +197,7 @@
   def GetDeviceIp(self):
     """Gets the device IP."""
     return self.device_ip
+
+  def GetDeviceOutputPath(self):
+    """Writable path where test targets can output files"""
+    return "/tmp"
diff --git a/src/starboard/linux/shared/starboard_platform.gypi b/src/starboard/linux/shared/starboard_platform.gypi
index 5387624..fef07e1 100644
--- a/src/starboard/linux/shared/starboard_platform.gypi
+++ b/src/starboard/linux/shared/starboard_platform.gypi
@@ -155,6 +155,8 @@
       '<(DEPTH)/starboard/shared/posix/memory_allocate_aligned_unchecked.cc',
       '<(DEPTH)/starboard/shared/posix/memory_flush.cc',
       '<(DEPTH)/starboard/shared/posix/memory_free_aligned.cc',
+      '<(DEPTH)/starboard/shared/posix/memory_mapped_file.cc',
+      '<(DEPTH)/starboard/shared/posix/memory_mapped_file.h',
       '<(DEPTH)/starboard/shared/posix/set_non_blocking_internal.cc',
       '<(DEPTH)/starboard/shared/posix/socket_accept.cc',
       '<(DEPTH)/starboard/shared/posix/socket_bind.cc',
diff --git a/src/starboard/linux/shared/system_get_extensions.cc b/src/starboard/linux/shared/system_get_extensions.cc
index 5c7ac86..3411d93 100644
--- a/src/starboard/linux/shared/system_get_extensions.cc
+++ b/src/starboard/linux/shared/system_get_extensions.cc
@@ -16,7 +16,9 @@
 
 #include "cobalt/extension/configuration.h"
 #include "cobalt/extension/crash_handler.h"
+#include "cobalt/extension/memory_mapped_file.h"
 #include "starboard/common/string.h"
+#include "starboard/shared/posix/memory_mapped_file.h"
 #include "starboard/shared/starboard/crash_handler.h"
 #if SB_IS(EVERGREEN_COMPATIBLE)
 #include "starboard/elf_loader/evergreen_config.h"
@@ -41,5 +43,8 @@
   if (strcmp(name, kCobaltExtensionCrashHandlerName) == 0) {
     return starboard::common::GetCrashHandlerApi();
   }
+  if (strcmp(name, kCobaltExtensionMemoryMappedFileName) == 0) {
+    return starboard::shared::posix::GetMemoryMappedFileApi();
+  }
   return NULL;
 }
diff --git a/src/starboard/linux/x64x11/BUILD.gn b/src/starboard/linux/x64x11/BUILD.gn
index c443ead..ad6b13a 100644
--- a/src/starboard/linux/x64x11/BUILD.gn
+++ b/src/starboard/linux/x64x11/BUILD.gn
@@ -15,13 +15,7 @@
 static_library("starboard_platform") {
   check_includes = false
 
-  sources = [
-    "//starboard/linux/x64x11/main.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.h",
-    "//starboard/shared/starboard/player/video_dmp_writer.cc",
-    "//starboard/shared/starboard/player/video_dmp_writer.h",
-  ]
+  sources = [ "//starboard/linux/x64x11/main.cc" ]
 
   public_deps = [
     "//starboard/linux/x64x11/shared:starboard_platform",
diff --git a/src/starboard/linux/x64x11/egl/BUILD.gn b/src/starboard/linux/x64x11/egl/BUILD.gn
index c443ead..ad6b13a 100644
--- a/src/starboard/linux/x64x11/egl/BUILD.gn
+++ b/src/starboard/linux/x64x11/egl/BUILD.gn
@@ -15,13 +15,7 @@
 static_library("starboard_platform") {
   check_includes = false
 
-  sources = [
-    "//starboard/linux/x64x11/main.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.h",
-    "//starboard/shared/starboard/player/video_dmp_writer.cc",
-    "//starboard/shared/starboard/player/video_dmp_writer.h",
-  ]
+  sources = [ "//starboard/linux/x64x11/main.cc" ]
 
   public_deps = [
     "//starboard/linux/x64x11/shared:starboard_platform",
diff --git a/src/starboard/linux/x64x11/skia/BUILD.gn b/src/starboard/linux/x64x11/skia/BUILD.gn
index cf08201..024e560 100644
--- a/src/starboard/linux/x64x11/skia/BUILD.gn
+++ b/src/starboard/linux/x64x11/skia/BUILD.gn
@@ -20,10 +20,6 @@
     "//starboard/linux/x64x11/skia/configuration.cc",
     "//starboard/linux/x64x11/skia/configuration.h",
     "//starboard/linux/x64x11/skia/system_get_extensions.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.cc",
-    "//starboard/shared/starboard/player/video_dmp_common.h",
-    "//starboard/shared/starboard/player/video_dmp_writer.cc",
-    "//starboard/shared/starboard/player/video_dmp_writer.h",
   ]
 
   public_deps = [
diff --git a/src/starboard/loader_app/loader_app.cc b/src/starboard/loader_app/loader_app.cc
index c1834af..2fdce8f 100644
--- a/src/starboard/loader_app/loader_app.cc
+++ b/src/starboard/loader_app/loader_app.cc
@@ -14,6 +14,7 @@
 
 #include <vector>
 
+#include "cobalt/version.h"
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/configuration.h"
@@ -165,10 +166,25 @@
     const starboard::shared::starboard::CommandLine command_line(
         data->argument_count, const_cast<const char**>(data->argument_values));
 
+    if (command_line.HasSwitch(starboard::loader_app::kLoaderAppVersion)) {
+      std::string versiong_msg = "Loader app version: ";
+      versiong_msg += COBALT_VERSION;
+      versiong_msg += "\n";
+      SbLogRaw(versiong_msg.c_str());
+    }
+
     bool is_evergreen_lite =
         command_line.HasSwitch(starboard::loader_app::kEvergreenLite);
     SB_LOG(INFO) << "is_evergreen_lite=" << is_evergreen_lite;
 
+#if SB_API_VERSION >= 12
+    if (command_line.HasSwitch(starboard::loader_app::kShowSABI)) {
+      std::string sabi = "SABI=";
+      sabi += SB_SABI_JSON_ID;
+      SbLogRaw(sabi.c_str());
+    }
+#endif
+
     std::string alternative_content =
         command_line.GetSwitchValue(starboard::loader_app::kContent);
     SB_LOG(INFO) << "alternative_content=" << alternative_content;
diff --git a/src/starboard/loader_app/loader_app_switches.cc b/src/starboard/loader_app/loader_app_switches.cc
index 36b6f8f..7758dea 100644
--- a/src/starboard/loader_app/loader_app_switches.cc
+++ b/src/starboard/loader_app/loader_app_switches.cc
@@ -20,6 +20,8 @@
 const char kContent[] = "content";
 const char kURL[] = "url";
 const char kEvergreenLite[] = "evergreen_lite";
+const char kLoaderAppVersion[] = "loader_app_version";
+const char kShowSABI[] = "show_sabi";
 
 }  // namespace loader_app
 }  // namespace starboard
diff --git a/src/starboard/loader_app/loader_app_switches.h b/src/starboard/loader_app/loader_app_switches.h
index 45cbf01..22030c5 100644
--- a/src/starboard/loader_app/loader_app_switches.h
+++ b/src/starboard/loader_app/loader_app_switches.h
@@ -32,6 +32,12 @@
 // Run Evergreen Lite by loading the system image and disabling the updater.
 extern const char kEvergreenLite[];
 
+// Print the loader_app version on the command line.
+extern const char kLoaderAppVersion[];
+
+// Print the loader_app Starboard ABI string on the command line.
+extern const char kShowSABI[];
+
 }  // namespace loader_app
 }  // namespace starboard
 
diff --git a/src/starboard/nplb/audio_sink_destroy_test.cc b/src/starboard/nplb/audio_sink_destroy_test.cc
index 81adf21..e90a3d1 100644
--- a/src/starboard/nplb/audio_sink_destroy_test.cc
+++ b/src/starboard/nplb/audio_sink_destroy_test.cc
@@ -18,7 +18,7 @@
 namespace starboard {
 namespace nplb {
 
-TEST(SbAudioSinkCreateTest, DestroyInvalidAudioSink) {
+TEST(SbAudioSinkDestroyTest, DestroyInvalidAudioSink) {
   SbAudioSinkDestroy(kSbAudioSinkInvalid);
 }
 
diff --git a/src/starboard/raspi/shared/cobalt/configuration.py b/src/starboard/raspi/shared/cobalt/configuration.py
index 26f981d..7ecac48 100644
--- a/src/starboard/raspi/shared/cobalt/configuration.py
+++ b/src/starboard/raspi/shared/cobalt/configuration.py
@@ -22,12 +22,6 @@
 class CobaltRaspiConfiguration(cobalt_configuration.CobaltConfiguration):
   """Starboard Raspberry Pi shared Cobalt configuration."""
 
-  def __init__(self, platform_configuration, application_name,
-               application_directory):
-    super(CobaltRaspiConfiguration,
-          self).__init__(platform_configuration, application_name,
-                         application_directory)
-
   def GetPostIncludes(self):
     # If there isn't a configuration.gypi found in the usual place, we'll
     # supplement with our shared implementation.
@@ -56,7 +50,7 @@
         test_filter.TestFilter('renderer_test',
                                'PixelTest.CircularSubPixelBorder'),
         test_filter.TestFilter('renderer_test',
-                               'PixelTest.FilterBlurred100PxText')
+                               'PixelTest.FilterBlurred100PxText'),
     ])
     return filters
 
diff --git a/src/starboard/raspi/shared/gyp_configuration.py b/src/starboard/raspi/shared/gyp_configuration.py
index 158f126..801e730 100644
--- a/src/starboard/raspi/shared/gyp_configuration.py
+++ b/src/starboard/raspi/shared/gyp_configuration.py
@@ -74,9 +74,8 @@
 
     toolchain = os.path.realpath(
         os.path.join(
-            self.raspi_home,
-            'tools/arm-bcm2708/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf'
-        ))
+            self.raspi_home, 'tools/arm-bcm2708/'
+            'gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf'))
     toolchain_bin_dir = os.path.join(toolchain, 'bin')
 
     env_variables = self.host_compiler_environment
@@ -164,6 +163,7 @@
           'SbMediaSetAudioWriteDurationTests/*',
           'SbPlayerWriteSampleTests*',
           'SbUndefinedBehaviorTest.CallThisPointerIsNullRainyDay',
+          'SbSystemGetPropertyTest.FLAKY_ReturnsRequired',
       ],
       'player_filter_tests': [
           # The implementations for the raspberry pi (0 and 2) are incomplete
diff --git a/src/starboard/raspi/shared/launcher.py b/src/starboard/raspi/shared/launcher.py
index 14e11e1..4617abc 100644
--- a/src/starboard/raspi/shared/launcher.py
+++ b/src/starboard/raspi/shared/launcher.py
@@ -365,3 +365,7 @@
   def GetDeviceIp(self):
     """Gets the device IP."""
     return self.device_id
+
+  def GetDeviceOutputPath(self):
+    """Writable path where test targets can output files"""
+    return '/tmp'
diff --git a/src/starboard/shared/dlmalloc/page_internal.h b/src/starboard/shared/dlmalloc/page_internal.h
index b4df31f..e72fd75 100644
--- a/src/starboard/shared/dlmalloc/page_internal.h
+++ b/src/starboard/shared/dlmalloc/page_internal.h
@@ -19,6 +19,7 @@
 #ifndef STARBOARD_SHARED_DLMALLOC_PAGE_INTERNAL_H_
 #define STARBOARD_SHARED_DLMALLOC_PAGE_INTERNAL_H_
 
+#include "starboard/memory.h"
 #include "starboard/shared/internal_only.h"
 #include "starboard/types.h"
 
@@ -115,6 +116,17 @@
 // allocated by dlmalloc isn't counted twice.
 void* SbPageMapUntracked(size_t size_bytes, int flags, const char* name);
 
+// Memory maps a file to the specified |addr| starting with |file_offset| and
+// mapping |size| bytes. The |addr| should be reserved before calling. If
+// NULL |addr| is passed a new memory block would be allocated and the address
+// returned. The file_offset must be a multiple of |kSbMemoryPageSize|.
+// On error returns NULL.
+void* SbPageMapFile(void* addr,
+                    const char* path,
+                    SbMemoryMapFlags flags,
+                    int64_t file_offset,
+                    int64_t size);
+
 // Unmap |size_bytes| of physical pages starting from |virtual_address|,
 // returning true on success. After this, [virtual_address, virtual_address +
 // size_bytes) will not be read/writable. SbUnmap() can unmap multiple
diff --git a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
index ad5ffc5..80ce0d5 100644
--- a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
+++ b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
@@ -227,7 +227,7 @@
   Dav1dSettings dav1d_settings{0};
   dav1d_default_settings(&dav1d_settings);
   // TODO: Verify this setting is optimal.
-  dav1d_settings.n_frame_threads = 8;
+  dav1d_settings.n_threads = 8;
 
   Dav1dPicAllocator allocator;
   allocator.cookie = this;  // dav1d refers to context pointers as "cookie".
diff --git a/src/starboard/shared/linux/page_internal.cc b/src/starboard/shared/linux/page_internal.cc
index de2ff6f..e708839 100644
--- a/src/starboard/shared/linux/page_internal.cc
+++ b/src/starboard/shared/linux/page_internal.cc
@@ -17,8 +17,10 @@
 
 #include "starboard/shared/dlmalloc/page_internal.h"
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <sys/mman.h>
+#include <unistd.h>
 
 #include "starboard/atomic.h"
 #include "starboard/common/log.h"
@@ -86,6 +88,38 @@
   return mem;
 }
 
+void* SbPageMapFile(void* addr,
+                    const char* path,
+                    SbMemoryMapFlags flags,
+                    int64_t file_offset,
+                    int64_t size) {
+  int fd = open(path, O_RDONLY);
+  if (fd == -1) {
+    return nullptr;
+  }
+
+  void* p = nullptr;
+  if (addr != nullptr) {
+    p = mmap(addr, size, SbMemoryMapFlagsToMmapProtect(flags),
+             MAP_PRIVATE | MAP_FIXED, fd, file_offset);
+    if (p == MAP_FAILED) {
+      close(fd);
+      return nullptr;
+    }
+  } else {
+    p = mmap(addr, size, SbMemoryMapFlagsToMmapProtect(flags), MAP_PRIVATE, fd,
+             file_offset);
+    if (p == MAP_FAILED) {
+      close(fd);
+      return nullptr;
+    }
+  }
+  // It is OK to close the file descriptor as the memory
+  // mapping keeps the file open.
+  close(fd);
+  return p;
+}
+
 bool SbPageUnmap(void* ptr, size_t size_bytes) {
   SbAtomicNoBarrier_Increment(&s_tracked_page_count, -GetPageCount(size_bytes));
   return SbPageUnmapUntracked(ptr, size_bytes);
diff --git a/src/starboard/shared/posix/memory_mapped_file.cc b/src/starboard/shared/posix/memory_mapped_file.cc
new file mode 100644
index 0000000..d9a3dfb
--- /dev/null
+++ b/src/starboard/shared/posix/memory_mapped_file.cc
@@ -0,0 +1,39 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "starboard/shared/posix/memory_mapped_file.h"
+
+#include "cobalt/extension/memory_mapped_file.h"
+#include "starboard/common/log.h"
+#include "starboard/shared/dlmalloc/page_internal.h"
+
+namespace starboard {
+namespace shared {
+namespace posix {
+
+namespace {
+
+const CobaltExtensionMemoryMappedFileApi kMemoryMappedFileApi = {
+    kCobaltExtensionMemoryMappedFileName, 1, &SbPageMapFile,
+};
+
+}  // namespace
+
+const void* GetMemoryMappedFileApi() {
+  return &kMemoryMappedFileApi;
+}
+
+}  // namespace posix
+}  // namespace shared
+}  // namespace starboard
diff --git a/src/starboard/shared/posix/memory_mapped_file.h b/src/starboard/shared/posix/memory_mapped_file.h
new file mode 100644
index 0000000..46e47fe
--- /dev/null
+++ b/src/starboard/shared/posix/memory_mapped_file.h
@@ -0,0 +1,28 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_POSIX_MEMORY_MAPPED_FILE_H_
+#define STARBOARD_SHARED_POSIX_MEMORY_MAPPED_FILE_H_
+
+namespace starboard {
+namespace shared {
+namespace posix {
+
+const void* GetMemoryMappedFileApi();
+
+}  // namespace posix
+}  // namespace shared
+}  // namespace starboard
+
+#endif  // STARBOARD_SHARED_POSIX_MEMORY_MAPPED_FILE_H_
diff --git a/src/starboard/tools/abstract_launcher.py b/src/starboard/tools/abstract_launcher.py
index 8a72a2e..85963cb 100644
--- a/src/starboard/tools/abstract_launcher.py
+++ b/src/starboard/tools/abstract_launcher.py
@@ -159,6 +159,11 @@
     """Gets the device IP. Must be implemented in subclasses."""
     pass
 
+  @abc.abstractmethod
+  def GetDeviceOutputPath(self):
+    """Writable path where test targets can output files"""
+    pass
+
   def SupportsSuspendResume(self):
     return False
 
diff --git a/src/starboard/tools/app_launcher_packager.py b/src/starboard/tools/app_launcher_packager.py
index 53ff7d1..37a1e80 100644
--- a/src/starboard/tools/app_launcher_packager.py
+++ b/src/starboard/tools/app_launcher_packager.py
@@ -31,19 +31,18 @@
 import _env  # pylint: disable=unused-import
 from paths import REPOSITORY_ROOT
 from paths import THIRD_PARTY_ROOT
+
 sys.path.append(THIRD_PARTY_ROOT)
-# pylint: disable=g-import-not-at-top,g-bad-import-order
+# pylint: disable=g-import-not-at-top,g-bad-import-order,wrong-import-position
 from starboard.tools import command_line
 from starboard.tools import log_level
 from starboard.tools import port_symlink
 import starboard.tools.platform
 
 # Default python directories to app launcher resources.
-_INCLUDE_FILE_PATTERNS = [
-    ('cobalt', '*.py'),
-    ('starboard', '*.py'),
-    ('starboard/tools', 'platform.py.template')
-]
+_INCLUDE_FILE_PATTERNS = [('cobalt', '*.py'), ('starboard', '*.py'),
+                          ('starboard', '*.pfx'),
+                          ('starboard/tools', 'platform.py.template')]
 
 _INCLUDE_BLACK_BOX_TESTS_PATTERNS = [
     # Black box and web platform tests have non-py assets, so everything
@@ -128,11 +127,11 @@
     # Store posix paths even on Windows so MH Linux hosts can use them.
     # The template has code to re-normalize them when used on Windows hosts.
     platforms_map[p] = platform_path.replace('\\', '/')
-  template = string.Template(
-      open(os.path.join(current_dir, 'platform.py.template')).read())
-  with open(os.path.join(dest_dir, 'platform.py'), 'w+') as f:
-    sub = template.substitute(platforms_map=platforms_map)
-    f.write(sub.encode('utf-8'))
+  with open(os.path.join(current_dir, 'platform.py.template')) as c:
+    template = string.Template(c.read())
+    with open(os.path.join(dest_dir, 'platform.py'), 'w+') as f:
+      sub = template.substitute(platforms_map=platforms_map)
+      f.write(sub.encode('utf-8'))
   logging.info('Finished baking in platform info files.')
 
 
diff --git a/src/starboard/tools/net_args.py b/src/starboard/tools/net_args.py
index b77d658..1948633 100644
--- a/src/starboard/tools/net_args.py
+++ b/src/starboard/tools/net_args.py
@@ -12,37 +12,34 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
 """Example script for getting the Net Args."""
 
 from __future__ import print_function
 
-import pprint
-
 import argparse
 import socket
 import sys
-import thread
 import time
 import threading
 
+
 # Returns |True| if a connection was made and the NetArg payload was delivered.
 # Example:
 #  TryConnectAndSendNetArgs('1.2.3.4', '1234', ['--argument', '--switch=value'])
 def TryConnectAndSendNetArgs(host, port, arg_list):
   arg_string = '\n'.join(arg_list)
-
   try:
-    server_socket = socket.create_connection((host, port), timeout = .5)
-    result = server_socket.sendall(arg_string)
+    server_socket = socket.create_connection((host, port), timeout=.5)
+    server_socket.sendall(arg_string)
     server_socket.close()
     return True
-  except socket.timeout as err:
+  except socket.timeout:
     return False
-  except socket.error as (err_no, err_str):
-    print(err_no, err_str)
+  except socket.error as e:
+    print(e.errno, e.strerror)
     return False
 
+
 class NetArgsThread(threading.Thread):
   """Threaded version of NetArgs"""
 
@@ -71,32 +68,36 @@
       with self.mutex:
         if self.join_called:
           break
-      connected_and_sent = TryConnectAndSendNetArgs(
-          self.host, self.port, self.arg_list)
+      connected_and_sent = TryConnectAndSendNetArgs(self.host, self.port,
+                                                    self.arg_list)
       if connected_and_sent:
         with self.mutex:
           self.args_sent = True
           break
 
+
 def main(argv):
-  parser = argparse.ArgumentParser(description = 'Connects to the weblog.')
-  parser.add_argument('--host', type=str, required = False,
-                      default = 'localhost',
-                      help = "Example localhost or 1.2.3.4")
-  parser.add_argument('--port', type=int, required = False, default = '49355')
-  parser.add_argument('--arg', type=str, required = True)
+  parser = argparse.ArgumentParser(description='Connects to the weblog.')
+  parser.add_argument(
+      '--host',
+      type=str,
+      required=False,
+      default='localhost',
+      help='Example localhost or 1.2.3.4')
+  parser.add_argument('--port', type=int, required=False, default='49355')
+  parser.add_argument('--arg', type=str, required=True)
   args = parser.parse_args(argv)
 
-  net_args_thread = NetArgsThread(
-          args.host, args.port, [args.arg])
+  net_args_thread = NetArgsThread(args.host, args.port, [args.arg])
 
   while not net_args_thread.ArgsSent():
-    print("Waiting to send arg " + args.arg + " to " + str(args.host) +
-          ":" + str(args.port) + "...")
+    print('Waiting to send arg ' + args.arg + ' to ' + str(args.host) + ':' +
+          str(args.port) + '...')
     time.sleep(.5)
 
-  print("Argument", args.arg, "was sent to", \
-        args.host + ":" + str(args.port))
+  print('Argument', args.arg, 'was sent to', \
+        args.host + ':' + str(args.port))
+
 
 if __name__ == '__main__':
   sys.exit(main(sys.argv[1:]))
diff --git a/src/starboard/tools/net_log.py b/src/starboard/tools/net_log.py
index 0b85cfa..aaa9797 100644
--- a/src/starboard/tools/net_log.py
+++ b/src/starboard/tools/net_log.py
@@ -13,24 +13,24 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
 """Example script for getting the Net log."""
 
 from __future__ import print_function
 
 import argparse
-import pprint
 import select
 import socket
 import sys
 import time
 import threading
 
+
 class NetLog:
   """
   Uses a non-blocking socket to establish a connection with a
   NetLog and then will allow the log to be fetched.
   """
+
   def __init__(self, host, port):
     self.host = host
     self.port = port
@@ -47,9 +47,9 @@
         self.server_socket = None
       else:
         return log
-    except socket.error as (err_no, err_str):
-      print(__file__ + ": Socket error while reading log:" \
-            + str(err_no) + " - " + str(err_str))
+    except socket.error as e:
+      print(__file__ + ': Socket error while reading log:' \
+            + str(e.errno) + ' - ' + str(e.strerror))
       self.server_socket = None
       return None
 
@@ -64,28 +64,31 @@
       if len(result) == 0:
         return None
       return result
-    except socket.error as (err_no, err_str):
-      if err_no == 10035:  # Data not ready yet.
+    except socket.error as e:
+      if e.errno == 10035:  # Data not ready yet.
         return ''
       else:
         raise
 
   def _TryCreateSocketConnection(self):
     try:
-      print("Waiting for connection to " + str(self.host) + ':' + str(self.port))
+      print('Waiting for connection to ' + str(self.host) + ':' +
+            str(self.port))
 
-      server_socket = socket.create_connection((self.host, self.port), timeout = 1)
+      server_socket = socket.create_connection((self.host, self.port),
+                                               timeout=1)
       server_socket.setblocking(0)
       return server_socket
-    except socket.timeout as err:
+    except socket.timeout:
       return None
     except socket.error as err:
-      print("Error while trying to create socket: " + str(err))
+      print('Error while trying to create socket: ' + str(err))
       return None
 
 
 class NetLogThread(threading.Thread):
   """Threaded version of NetLog"""
+
   def __init__(self, host, port):
     super(NetLogThread, self).__init__()
     self.web_log = NetLog(host, port)
@@ -111,8 +114,9 @@
         with self.log_mutex:
           self.log.extend(new_log)
 
+
 def TestNetLog(host, port):
-  print("Started...")
+  print('Started...')
   web_log = NetLog(host, port)
 
   while True:
@@ -123,11 +127,14 @@
 
 
 def main(argv):
-  parser = argparse.ArgumentParser(description = 'Connects to the weblog.')
-  parser.add_argument('--host', type=str, required = False,
-                      default = 'localhost',
-                      help = "Example localhost or 1.2.3.4")
-  parser.add_argument('--port', type=int, required = False, default = '49353')
+  parser = argparse.ArgumentParser(description='Connects to the weblog.')
+  parser.add_argument(
+      '--host',
+      type=str,
+      required=False,
+      default='localhost',
+      help='Example localhost or 1.2.3.4')
+  parser.add_argument('--port', type=int, required=False, default='49353')
   args = parser.parse_args(argv)
 
   thread = NetLogThread(args.host, args.port)
@@ -136,13 +143,14 @@
     while True:
       print(thread.GetLog(), end='')
       time.sleep(.1)
-  except KeyboardInterrupt as ki:
-    print("\nUser canceled.")
+  except KeyboardInterrupt:
+    print('\nUser canceled.')
     pass
 
-  print("Waiting to join...")
+  print('Waiting to join...')
   thread.join()
   return 0
 
+
 if __name__ == '__main__':
   sys.exit(main(sys.argv[1:]))
diff --git a/src/starboard/tools/testing/test_runner.py b/src/starboard/tools/testing/test_runner.py
index a4db330..aa98b10 100755
--- a/src/starboard/tools/testing/test_runner.py
+++ b/src/starboard/tools/testing/test_runner.py
@@ -171,7 +171,9 @@
   def Kill(self):
     """Kills the running launcher."""
     try:
+      logging.info("Killing launcher")
       self.launcher.Kill()
+      logging.info("Launcher killed")
     except Exception:  # pylint: disable=broad-except
       sys.stderr.write("Error while killing {}:\n".format(
           self.launcher.target_name))
@@ -184,20 +186,20 @@
     """Runs the launcher, and assigns a return code."""
     return_code = 1
     try:
+      logging.info("Running launcher")
       return_code = self.launcher.Run()
+      logging.info("Finished running launcher")
     except Exception:  # pylint: disable=broad-except
       sys.stderr.write("Error while running {}:\n".format(
           self.launcher.target_name))
       traceback.print_exc(file=sys.stderr)
 
-    self.return_code_lock.acquire()
-    self.return_code = return_code
-    self.return_code_lock.release()
+    with self.return_code_lock:
+      self.return_code = return_code
 
   def GetReturnCode(self):
-    self.return_code_lock.acquire()
-    return_code = self.return_code
-    self.return_code_lock.release()
+    with self.return_code_lock:
+      return_code = self.return_code
     return return_code
 
 
@@ -233,15 +235,20 @@
       self.out_directory = paths.BuildOutputDirectory(self.platform,
                                                       self.config)
     self.coverage_directory = os.path.join(self.out_directory, "coverage")
-    if not self.loader_out_directory and self.loader_platform and self.loader_config:
+    if (not self.loader_out_directory and self.loader_platform and
+        self.loader_config):
       self.loader_out_directory = paths.BuildOutputDirectory(
           self.loader_platform, self.loader_config)
 
+    logging.info("Getting platform configuration")
     self._platform_config = build.GetPlatformConfig(platform)
     if self.loader_platform:
       self._loader_platform_config = build.GetPlatformConfig(loader_platform)
+    logging.info("Got platform configuration")
+    logging.info("Getting application configuration")
     self._app_config = self._platform_config.GetApplicationConfiguration(
         application_name)
+    logging.info("Got application configuration")
     self.application_name = application_name
     self.dry_run = dry_run
     self.xml_output_dir = xml_output_dir
@@ -258,11 +265,12 @@
     _VerifyConfig(self._app_config)
 
     # If a particular test binary has been provided, configure only that one.
+    logging.info("Getting test targets")
     if specified_targets:
       self.test_targets = self._GetSpecifiedTestTargets(specified_targets)
     else:
       self.test_targets = self._GetTestTargets(platform_tests_only)
-
+    logging.info("Got test targets")
     self.test_env_vars = self._GetAllTestEnvVariables()
 
   def _Exec(self, cmd_list, output_file=None):
@@ -272,13 +280,13 @@
       logging.info(msg)
       if output_file:
         with open(output_file, "wb") as out:
-          p = subprocess.Popen(
+          p = subprocess.Popen(  # pylint: disable=consider-using-with
               cmd_list,
               stdout=out,
               universal_newlines=True,
               cwd=self.out_directory)
       else:
-        p = subprocess.Popen(
+        p = subprocess.Popen(  # pylint: disable=consider-using-with
             cmd_list,
             stderr=subprocess.STDOUT,
             universal_newlines=True,
@@ -401,11 +409,32 @@
     if gtest_filter_value:
       test_params.append("--gtest_filter=" + gtest_filter_value)
 
+    def MakeLauncher():
+      return abstract_launcher.LauncherFactory(
+          self.platform,
+          target_name,
+          self.config,
+          device_id=self.device_id,
+          target_params=test_params,
+          output_file=write_pipe,
+          out_directory=self.out_directory,
+          coverage_directory=self.coverage_directory,
+          env_variables=env,
+          loader_platform=self.loader_platform,
+          loader_config=self.loader_config,
+          loader_out_directory=self.loader_out_directory,
+          launcher_args=self.launcher_args)
+
     if self.log_xml_results:
-      # Log the xml results in the current working directory.
+      out_path = MakeLauncher().GetDeviceOutputPath()
       xml_filename = "{}_testoutput.xml".format(target_name)
-      test_params.append("--gtest_output=xml:{}".format(xml_filename))
-      logging.info("Xml results for this test will be logged.")
+      if out_path:
+        xml_path = os.path.join(out_path, xml_filename)
+      else:
+        xml_path = xml_filename
+      test_params.append("--gtest_output=xml:{}".format(xml_path))
+      logging.info(("Xml results for this test will "
+                    "be logged to '%s'."), xml_path)
     elif self.xml_output_dir:
       # Have gtest create and save a test result xml
       xml_output_subdir = os.path.join(self.xml_output_dir, target_name)
@@ -425,20 +454,9 @@
     if self.dry_run:
       test_params.extend(["--gtest_list_tests"])
 
-    launcher = abstract_launcher.LauncherFactory(
-        self.platform,
-        target_name,
-        self.config,
-        device_id=self.device_id,
-        target_params=test_params,
-        output_file=write_pipe,
-        out_directory=self.out_directory,
-        coverage_directory=self.coverage_directory,
-        env_variables=env,
-        loader_platform=self.loader_platform,
-        loader_config=self.loader_config,
-        loader_out_directory=self.loader_out_directory,
-        launcher_args=self.launcher_args)
+    logging.info("Initializing launcher")
+    launcher = MakeLauncher()
+    logging.info("Launcher initialized")
 
     test_reader = TestLineReader(read_pipe)
     test_launcher = TestLauncher(launcher)
@@ -461,7 +479,9 @@
     if test_params:
       sys.stdout.write(" {}\n".format(test_params))
     test_reader.Start()
+    logging.info("Starting test launcher")
     test_launcher.Start()
+    logging.info("Test launcher started")
 
     # Wait for the launcher to exit then close the write pipe, which will
     # cause the reader to exit.
@@ -863,12 +883,14 @@
   if args.dry_run:
     launcher_args.append(abstract_launcher.ARG_DRYRUN)
 
+  logging.info("Initializing test runner")
   runner = TestRunner(args.platform, args.config, args.loader_platform,
                       args.loader_config, args.device_id, args.target_name,
                       target_params, args.out_directory,
                       args.loader_out_directory, args.platform_tests_only,
                       args.application_name, args.dry_run, args.xml_output_dir,
                       args.log_xml_results, launcher_args)
+  logging.info("Test runner initialized")
 
   def Abort(signum, frame):
     del signum, frame  # Unused.
diff --git a/src/testing/gtest/src/gtest.cc b/src/testing/gtest/src/gtest.cc
index 50717b7..e561a3c 100644
--- a/src/testing/gtest/src/gtest.cc
+++ b/src/testing/gtest/src/gtest.cc
@@ -3450,6 +3450,19 @@
   GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);
 };
 
+#if GTEST_OS_STARBOARD
+void WriteOuputFile(const std::string &output_file, const std::string &data) {
+  SbFileError err;
+  starboard::ScopedFile cache_file(
+      output_file.c_str(), kSbFileCreateAlways | kSbFileWrite, NULL, &err);
+  // TODO: Change to SB_DCHECK once all platforms are verified
+  if(err != kSbFileOk) {
+    SB_LOG(ERROR) << "Unable to open file " << output_file << " for XML output";
+  }
+  cache_file.WriteAll(data.c_str(), static_cast<int>(data.size()));
+}
+#endif
+
 // Creates a new XmlUnitTestResultPrinter.
 XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
     : output_file_(output_file) {
@@ -3458,6 +3471,10 @@
     fflush(stderr);
     exit(EXIT_FAILURE);
   }
+#if GTEST_OS_STARBOARD
+  // Ensure file contents get reset between runs, to avoid stale results
+  WriteOuputFile(output_file,"");
+#endif
 }
 
 // Called after the unit test ends.
@@ -3466,10 +3483,8 @@
 #if GTEST_OS_STARBOARD
   std::stringstream stream;
   PrintXmlUnitTest(&stream, unit_test);
-  starboard::ScopedFile cache_file(
-      output_file_.c_str(), kSbFileCreateAlways | kSbFileWrite, NULL, NULL);
-  cache_file.WriteAll(StringStreamToString(&stream).c_str(),
-                      static_cast<int>(StringStreamToString(&stream).size()));
+
+  WriteOuputFile(output_file_, StringStreamToString(&stream));
 #else
   FILE* xmlout = NULL;
   FilePath output_file(output_file_);
diff --git a/src/third_party/libdav1d/include/dav1d/common.h b/src/third_party/libdav1d/include/dav1d/common.h
index b55e939..d81775d 100644
--- a/src/third_party/libdav1d/include/dav1d/common.h
+++ b/src/third_party/libdav1d/include/dav1d/common.h
@@ -1,81 +1,81 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_COMMON_H
-#define DAV1D_COMMON_H
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef DAV1D_API
-    #if defined _WIN32
-      #if defined DAV1D_BUILDING_DLL
-        #define DAV1D_API __declspec(dllexport)
-      #else
-        #define DAV1D_API
-      #endif
-    #else
-      #if __GNUC__ >= 4
-        #define DAV1D_API __attribute__ ((visibility ("default")))
-      #else
-        #define DAV1D_API
-      #endif
-    #endif
-#endif
-
-#if EPERM > 0
-#define DAV1D_ERR(e) (-(e)) ///< Negate POSIX error code.
-#else
-#define DAV1D_ERR(e) (e)
-#endif
-
-/**
- * A reference-counted object wrapper for a user-configurable pointer.
- */
-typedef struct Dav1dUserData {
-    const uint8_t *data; ///< data pointer
-    struct Dav1dRef *ref; ///< allocation origin
-} Dav1dUserData;
-
-/**
- * Input packet metadata which are copied from the input data used to
- * decode each image into the matching structure of the output image
- * returned back to the user. Since these are metadata fields, they
- * can be used for other purposes than the documented ones, they will
- * still be passed from input data to output picture without being
- * used internally.
- */
-typedef struct Dav1dDataProps {
-    int64_t timestamp; ///< container timestamp of input data, INT64_MIN if unknown (default)
-    int64_t duration; ///< container duration of input data, 0 if unknown (default)
-    int64_t offset; ///< stream offset of input data, -1 if unknown (default)
-    size_t size; ///< packet size, default Dav1dData.sz
-    struct Dav1dUserData user_data; ///< user-configurable data, default NULL members
-} Dav1dDataProps;
-
-#endif /* DAV1D_COMMON_H */
+/*

+ * Copyright © 2018, VideoLAN and dav1d authors

+ * Copyright © 2018, Two Orioles, LLC

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright notice, this

+ *    list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef DAV1D_COMMON_H

+#define DAV1D_COMMON_H

+

+#include <errno.h>

+#include <stddef.h>

+#include <stdint.h>

+

+#ifndef DAV1D_API

+    #if defined _WIN32

+      #if defined DAV1D_BUILDING_DLL

+        #define DAV1D_API __declspec(dllexport)

+      #else

+        #define DAV1D_API

+      #endif

+    #else

+      #if __GNUC__ >= 4

+        #define DAV1D_API __attribute__ ((visibility ("default")))

+      #else

+        #define DAV1D_API

+      #endif

+    #endif

+#endif

+

+#if EPERM > 0

+#define DAV1D_ERR(e) (-(e)) ///< Negate POSIX error code.

+#else

+#define DAV1D_ERR(e) (e)

+#endif

+

+/**

+ * A reference-counted object wrapper for a user-configurable pointer.

+ */

+typedef struct Dav1dUserData {

+    const uint8_t *data; ///< data pointer

+    struct Dav1dRef *ref; ///< allocation origin

+} Dav1dUserData;

+

+/**

+ * Input packet metadata which are copied from the input data used to

+ * decode each image into the matching structure of the output image

+ * returned back to the user. Since these are metadata fields, they

+ * can be used for other purposes than the documented ones, they will

+ * still be passed from input data to output picture without being

+ * used internally.

+ */

+typedef struct Dav1dDataProps {

+    int64_t timestamp; ///< container timestamp of input data, INT64_MIN if unknown (default)

+    int64_t duration; ///< container duration of input data, 0 if unknown (default)

+    int64_t offset; ///< stream offset of input data, -1 if unknown (default)

+    size_t size; ///< packet size, default Dav1dData.sz

+    struct Dav1dUserData user_data; ///< user-configurable data, default NULL members

+} Dav1dDataProps;

+

+#endif /* DAV1D_COMMON_H */

diff --git a/src/third_party/libdav1d/include/dav1d/data.h b/src/third_party/libdav1d/include/dav1d/data.h
index f945a04..b532474 100644
--- a/src/third_party/libdav1d/include/dav1d/data.h
+++ b/src/third_party/libdav1d/include/dav1d/data.h
@@ -1,109 +1,109 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_DATA_H
-#define DAV1D_DATA_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "common.h"
-
-typedef struct Dav1dData {
-    const uint8_t *data; ///< data pointer
-    size_t sz; ///< data size
-    struct Dav1dRef *ref; ///< allocation origin
-    Dav1dDataProps m; ///< user provided metadata passed to the output picture
-} Dav1dData;
-
-/**
- * Allocate data.
- *
- * @param data Input context.
- * @param   sz Size of the data that should be allocated.
- *
- * @return Pointer to the allocated buffer on success. NULL on error.
- */
-DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
-
-/**
- * Wrap an existing data array.
- *
- * @param          data Input context.
- * @param           buf The data to be wrapped.
- * @param            sz Size of the data.
- * @param free_callback Function to be called when we release our last
- *                      reference to this data. In this callback, $buf will be
- *                      the $buf argument to this function, and $cookie will
- *                      be the $cookie input argument to this function.
- * @param        cookie Opaque parameter passed to free_callback().
- *
- * @return 0 on success. A negative DAV1D_ERR value on error.
- */
-DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
-                              void (*free_callback)(const uint8_t *buf, void *cookie),
-                              void *cookie);
-
-/**
- * Wrap a user-provided data pointer into a reference counted object.
- *
- * data->m.user_data field will initialized to wrap the provided $user_data
- * pointer.
- *
- * $free_callback will be called on the same thread that released the last
- * reference. If frame threading is used, make sure $free_callback is
- * thread-safe.
- *
- * @param          data Input context.
- * @param     user_data The user data to be wrapped.
- * @param free_callback Function to be called when we release our last
- *                      reference to this data. In this callback, $user_data
- *                      will be the $user_data argument to this function, and
- *                      $cookie will be the $cookie input argument to this
- *                      function.
- * @param        cookie Opaque parameter passed to $free_callback.
- *
- * @return 0 on success. A negative DAV1D_ERR value on error.
- */
-DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
-                                        const uint8_t *user_data,
-                                        void (*free_callback)(const uint8_t *user_data,
-                                                              void *cookie),
-                                        void *cookie);
-
-/**
- * Free the data reference.
- *
- * The reference count for data->m.user_data will be decremented (if it has been
- * initialized with dav1d_data_wrap_user_data). The $data object will be memset
- * to 0.
- *
- * @param data Input context.
- */
-DAV1D_API void dav1d_data_unref(Dav1dData *data);
-
-#endif /* DAV1D_DATA_H */
+/*

+ * Copyright © 2018, VideoLAN and dav1d authors

+ * Copyright © 2018, Two Orioles, LLC

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright notice, this

+ *    list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef DAV1D_DATA_H

+#define DAV1D_DATA_H

+

+#include <stddef.h>

+#include <stdint.h>

+

+#include "common.h"

+

+typedef struct Dav1dData {

+    const uint8_t *data; ///< data pointer

+    size_t sz; ///< data size

+    struct Dav1dRef *ref; ///< allocation origin

+    Dav1dDataProps m; ///< user provided metadata passed to the output picture

+} Dav1dData;

+

+/**

+ * Allocate data.

+ *

+ * @param data Input context.

+ * @param   sz Size of the data that should be allocated.

+ *

+ * @return Pointer to the allocated buffer on success. NULL on error.

+ */

+DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);

+

+/**

+ * Wrap an existing data array.

+ *

+ * @param          data Input context.

+ * @param           buf The data to be wrapped.

+ * @param            sz Size of the data.

+ * @param free_callback Function to be called when we release our last

+ *                      reference to this data. In this callback, $buf will be

+ *                      the $buf argument to this function, and $cookie will

+ *                      be the $cookie input argument to this function.

+ * @param        cookie Opaque parameter passed to free_callback().

+ *

+ * @return 0 on success. A negative DAV1D_ERR value on error.

+ */

+DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,

+                              void (*free_callback)(const uint8_t *buf, void *cookie),

+                              void *cookie);

+

+/**

+ * Wrap a user-provided data pointer into a reference counted object.

+ *

+ * data->m.user_data field will initialized to wrap the provided $user_data

+ * pointer.

+ *

+ * $free_callback will be called on the same thread that released the last

+ * reference. If frame threading is used, make sure $free_callback is

+ * thread-safe.

+ *

+ * @param          data Input context.

+ * @param     user_data The user data to be wrapped.

+ * @param free_callback Function to be called when we release our last

+ *                      reference to this data. In this callback, $user_data

+ *                      will be the $user_data argument to this function, and

+ *                      $cookie will be the $cookie input argument to this

+ *                      function.

+ * @param        cookie Opaque parameter passed to $free_callback.

+ *

+ * @return 0 on success. A negative DAV1D_ERR value on error.

+ */

+DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,

+                                        const uint8_t *user_data,

+                                        void (*free_callback)(const uint8_t *user_data,

+                                                              void *cookie),

+                                        void *cookie);

+

+/**

+ * Free the data reference.

+ *

+ * The reference count for data->m.user_data will be decremented (if it has been

+ * initialized with dav1d_data_wrap_user_data). The $data object will be memset

+ * to 0.

+ *

+ * @param data Input context.

+ */

+DAV1D_API void dav1d_data_unref(Dav1dData *data);

+

+#endif /* DAV1D_DATA_H */

diff --git a/src/third_party/libdav1d/include/dav1d/dav1d.h b/src/third_party/libdav1d/include/dav1d/dav1d.h
index 76558cf..8d3d97c 100644
--- a/src/third_party/libdav1d/include/dav1d/dav1d.h
+++ b/src/third_party/libdav1d/include/dav1d/dav1d.h
@@ -1,210 +1,244 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_H
-#define DAV1D_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <errno.h>
-#include <stdarg.h>
-
-#include "common.h"
-#include "picture.h"
-#include "data.h"
-
-#define DAV1D_API_VERSION_MAJOR 3
-#define DAV1D_API_VERSION_MINOR 1
-#define DAV1D_API_VERSION_PATCH 0
-
-typedef struct Dav1dContext Dav1dContext;
-typedef struct Dav1dRef Dav1dRef;
-
-#define DAV1D_MAX_FRAME_THREADS 256
-#define DAV1D_MAX_TILE_THREADS 64
-
-typedef struct Dav1dLogger {
-    void *cookie; ///< Custom data to pass to the callback.
-    /**
-     * Logger callback. Default prints to stderr. May be NULL to disable logging.
-     *
-     * @param cookie Custom pointer passed to all calls.
-     * @param format The vprintf compatible format string.
-     * @param     ap List of arguments referenced by the format string.
-     */
-    void (*callback)(void *cookie, const char *format, va_list ap);
-} Dav1dLogger;
-
-typedef struct Dav1dSettings {
-    int n_frame_threads;
-    int n_tile_threads;
-    int apply_grain;
-    int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)
-    int all_layers; ///< output all spatial layers of a scalable AV1 biststream
-    unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited)
-    uint8_t reserved[32]; ///< reserved for future use
-    Dav1dPicAllocator allocator;
-    Dav1dLogger logger;
-} Dav1dSettings;
-
-/**
- * Get library version.
- */
-DAV1D_API const char *dav1d_version(void);
-
-/**
- * Initialize settings to default values.
- *
- * @param s Input settings context.
- */
-DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
-
-/**
- * Allocate and open a decoder instance.
- *
- * @param c_out The decoder instance to open. *c_out will be set to the
- *              allocated context.
- * @param     s Input settings context.
- *
- * @note The context must be freed using dav1d_close() when decoding is
- *       finished.
- *
- * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
- */
-DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
-
-/**
- * Parse a Sequence Header OBU from bitstream data.
- *
- * @param out Output Sequence Header.
- * @param buf The data to be parser.
- * @param sz  Size of the data.
- *
- * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
- *
- * @note It is safe to feed this function data containing other OBUs than a
- *       Sequence Header, as they will simply be ignored. If there is more than
- *       one Sequence Header OBU present, only the last will be returned.
- */
-DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,
-                                          const uint8_t *buf, const size_t sz);
-
-/**
- * Feed bitstream data to the decoder.
- *
- * @param   c Input decoder instance.
- * @param  in Input bitstream data. On success, ownership of the reference is
- *            passed to the library.
- *
- * @return
- *         0: Success, and the data was consumed.
- *  DAV1D_ERR(EAGAIN): The data can't be consumed. dav1d_get_picture() should
- *                     be called to get one or more frames before the function
- *                     can consume new data.
- *  other negative DAV1D_ERR codes: Error during decoding or because of invalid
- *                                  passed-in arguments.
- */
-DAV1D_API int dav1d_send_data(Dav1dContext *c, Dav1dData *in);
-
-/**
- * Return a decoded picture.
- *
- * @param   c Input decoder instance.
- * @param out Output frame. The caller assumes ownership of the returned
- *            reference.
- *
- * @return
- *         0: Success, and a frame is returned.
- *  DAV1D_ERR(EAGAIN): Not enough data to output a frame. dav1d_send_data()
- *                     should be called with new input.
- *  other negative DAV1D_ERR codes: Error during decoding or because of invalid
- *                                  passed-in arguments.
- *
- * @note To drain buffered frames from the decoder (i.e. on end of stream),
- *       call this function until it returns DAV1D_ERR(EAGAIN).
- *
- * @code{.c}
- *  Dav1dData data = { 0 };
- *  Dav1dPicture p = { 0 };
- *  int res;
- *
- *  read_data(&data);
- *  do {
- *      res = dav1d_send_data(c, &data);
- *      // Keep going even if the function can't consume the current data
- *         packet. It eventually will after one or more frames have been
- *         returned in this loop.
- *      if (res < 0 && res != DAV1D_ERR(EAGAIN))
- *          free_and_abort();
- *      res = dav1d_get_picture(c, &p);
- *      if (res < 0) {
- *          if (res != DAV1D_ERR(EAGAIN))
- *              free_and_abort();
- *      } else
- *          output_and_unref_picture(&p);
- *  // Stay in the loop as long as there's data to consume.
- *  } while (data.sz || read_data(&data) == SUCCESS);
- *
- *  // Handle EOS by draining all buffered frames.
- *  do {
- *      res = dav1d_get_picture(c, &p);
- *      if (res < 0) {
- *          if (res != DAV1D_ERR(EAGAIN))
- *              free_and_abort();
- *      } else
- *          output_and_unref_picture(&p);
- *  } while (res == 0);
- * @endcode
- */
-DAV1D_API int dav1d_get_picture(Dav1dContext *c, Dav1dPicture *out);
-
-/**
- * Close a decoder instance and free all associated memory.
- *
- * @param c_out The decoder instance to close. *c_out will be set to NULL.
- */
-DAV1D_API void dav1d_close(Dav1dContext **c_out);
-
-/**
- * Flush all delayed frames in decoder and clear internal decoder state,
- * to be used when seeking.
- *
- * @param c Input decoder instance.
- *
- * @note Decoding will start only after a valid sequence header OBU is
- *       delivered to dav1d_send_data().
- *
- */
-DAV1D_API void dav1d_flush(Dav1dContext *c);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif /* DAV1D_H */
+/*

+ * Copyright © 2018-2021, VideoLAN and dav1d authors

+ * Copyright © 2018, Two Orioles, LLC

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright notice, this

+ *    list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef DAV1D_H

+#define DAV1D_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#include <errno.h>

+#include <stdarg.h>

+

+#include "common.h"

+#include "picture.h"

+#include "data.h"

+

+#define DAV1D_API_VERSION_MAJOR 3

+#define DAV1D_API_VERSION_MINOR 1

+#define DAV1D_API_VERSION_PATCH 0

+

+typedef struct Dav1dContext Dav1dContext;

+typedef struct Dav1dRef Dav1dRef;

+

+#define DAV1D_MAX_THREADS 256

+#define DAV1D_MAX_FRAME_DELAY 256

+

+typedef struct Dav1dLogger {

+    void *cookie; ///< Custom data to pass to the callback.

+    /**

+     * Logger callback. May be NULL to disable logging.

+     *

+     * @param cookie Custom pointer passed to all calls.

+     * @param format The vprintf compatible format string.

+     * @param     ap List of arguments referenced by the format string.

+     */

+    void (*callback)(void *cookie, const char *format, va_list ap);

+} Dav1dLogger;

+

+typedef struct Dav1dSettings {

+    int n_threads; ///< number of threads (0 = auto)

+    int max_frame_delay; ///< Set to 1 for low-latency decoding (0 = auto)

+    int apply_grain;

+    int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31)

+    int all_layers; ///< output all spatial layers of a scalable AV1 biststream

+    unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited)

+    Dav1dPicAllocator allocator; ///< Picture allocator callback.

+    Dav1dLogger logger; ///< Logger callback.

+    uint8_t reserved[32]; ///< reserved for future use

+} Dav1dSettings;

+

+/**

+ * Get library version.

+ */

+DAV1D_API const char *dav1d_version(void);

+

+/**

+ * Initialize settings to default values.

+ *

+ * @param s Input settings context.

+ */

+DAV1D_API void dav1d_default_settings(Dav1dSettings *s);

+

+/**

+ * Allocate and open a decoder instance.

+ *

+ * @param c_out The decoder instance to open. *c_out will be set to the

+ *              allocated context.

+ * @param     s Input settings context.

+ *

+ * @note The context must be freed using dav1d_close() when decoding is

+ *       finished.

+ *

+ * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.

+ */

+DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);

+

+/**

+ * Parse a Sequence Header OBU from bitstream data.

+ *

+ * @param out Output Sequence Header.

+ * @param buf The data to be parser.

+ * @param sz  Size of the data.

+ *

+ * @return

+ *                  0: Success, and out is filled with the parsed Sequence Header

+ *                     OBU parameters.

+ *  DAV1D_ERR(ENOENT): No Sequence Header OBUs were found in the buffer.

+ *  other negative DAV1D_ERR codes: Invalid data in the buffer, invalid passed-in

+ *                                  arguments, and other errors during parsing.

+ *

+ * @note It is safe to feed this function data containing other OBUs than a

+ *       Sequence Header, as they will simply be ignored. If there is more than

+ *       one Sequence Header OBU present, only the last will be returned.

+ */

+DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,

+                                          const uint8_t *buf, const size_t sz);

+

+/**

+ * Feed bitstream data to the decoder.

+ *

+ * @param   c Input decoder instance.

+ * @param  in Input bitstream data. On success, ownership of the reference is

+ *            passed to the library.

+ *

+ * @return

+ *         0: Success, and the data was consumed.

+ *  DAV1D_ERR(EAGAIN): The data can't be consumed. dav1d_get_picture() should

+ *                     be called to get one or more frames before the function

+ *                     can consume new data.

+ *  other negative DAV1D_ERR codes: Error during decoding or because of invalid

+ *                                  passed-in arguments.

+ */

+DAV1D_API int dav1d_send_data(Dav1dContext *c, Dav1dData *in);

+

+/**

+ * Return a decoded picture.

+ *

+ * @param   c Input decoder instance.

+ * @param out Output frame. The caller assumes ownership of the returned

+ *            reference.

+ *

+ * @return

+ *         0: Success, and a frame is returned.

+ *  DAV1D_ERR(EAGAIN): Not enough data to output a frame. dav1d_send_data()

+ *                     should be called with new input.

+ *  other negative DAV1D_ERR codes: Error during decoding or because of invalid

+ *                                  passed-in arguments.

+ *

+ * @note To drain buffered frames from the decoder (i.e. on end of stream),

+ *       call this function until it returns DAV1D_ERR(EAGAIN).

+ *

+ * @code{.c}

+ *  Dav1dData data = { 0 };

+ *  Dav1dPicture p = { 0 };

+ *  int res;

+ *

+ *  read_data(&data);

+ *  do {

+ *      res = dav1d_send_data(c, &data);

+ *      // Keep going even if the function can't consume the current data

+ *         packet. It eventually will after one or more frames have been

+ *         returned in this loop.

+ *      if (res < 0 && res != DAV1D_ERR(EAGAIN))

+ *          free_and_abort();

+ *      res = dav1d_get_picture(c, &p);

+ *      if (res < 0) {

+ *          if (res != DAV1D_ERR(EAGAIN))

+ *              free_and_abort();

+ *      } else

+ *          output_and_unref_picture(&p);

+ *  // Stay in the loop as long as there's data to consume.

+ *  } while (data.sz || read_data(&data) == SUCCESS);

+ *

+ *  // Handle EOS by draining all buffered frames.

+ *  do {

+ *      res = dav1d_get_picture(c, &p);

+ *      if (res < 0) {

+ *          if (res != DAV1D_ERR(EAGAIN))

+ *              free_and_abort();

+ *      } else

+ *          output_and_unref_picture(&p);

+ *  } while (res == 0);

+ * @endcode

+ */

+DAV1D_API int dav1d_get_picture(Dav1dContext *c, Dav1dPicture *out);

+

+/**

+ * Close a decoder instance and free all associated memory.

+ *

+ * @param c_out The decoder instance to close. *c_out will be set to NULL.

+ */

+DAV1D_API void dav1d_close(Dav1dContext **c_out);

+

+/**

+ * Flush all delayed frames in decoder and clear internal decoder state,

+ * to be used when seeking.

+ *

+ * @param c Input decoder instance.

+ *

+ * @note Decoding will start only after a valid sequence header OBU is

+ *       delivered to dav1d_send_data().

+ *

+ */

+DAV1D_API void dav1d_flush(Dav1dContext *c);

+

+enum Dav1dEventFlags {

+    /**

+     * The last returned picture contains a reference to a new Sequence Header,

+     * either because it's the start of a new coded sequence, or the decoder was

+     * flushed before it was generated.

+     */

+    DAV1D_EVENT_FLAG_NEW_SEQUENCE =       1 << 0,

+    /**

+     * The last returned picture contains a reference to a Sequence Header with

+     * new operating parameters information for the current coded sequence.

+     */

+    DAV1D_EVENT_FLAG_NEW_OP_PARAMS_INFO = 1 << 1,

+};

+

+/**

+ * Fetch a combination of DAV1D_EVENT_FLAG_* event flags generated by the decoding

+ * process.

+ *

+ * @param c Input decoder instance.

+ * @param flags Where to write the flags.

+ *

+ * @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.

+ *

+ * @note Calling this function will clear all the event flags currently stored in

+ *       the decoder.

+ *

+ */

+DAV1D_API int dav1d_get_event_flags(Dav1dContext *c, enum Dav1dEventFlags *flags);

+

+# ifdef __cplusplus

+}

+# endif

+

+#endif /* DAV1D_H */

diff --git a/src/third_party/libdav1d/include/dav1d/headers.h b/src/third_party/libdav1d/include/dav1d/headers.h
index 4e3bf9e..7ec6cef 100644
--- a/src/third_party/libdav1d/include/dav1d/headers.h
+++ b/src/third_party/libdav1d/include/dav1d/headers.h
@@ -1,430 +1,435 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_HEADERS_H
-#define DAV1D_HEADERS_H
-
-#include <stddef.h>
-
-// Constants from Section 3. "Symbols and abbreviated terms"
-#define DAV1D_MAX_CDEF_STRENGTHS 8
-#define DAV1D_MAX_OPERATING_POINTS 32
-#define DAV1D_MAX_TILE_COLS 64
-#define DAV1D_MAX_TILE_ROWS 64
-#define DAV1D_MAX_SEGMENTS 8
-#define DAV1D_NUM_REF_FRAMES 8
-#define DAV1D_PRIMARY_REF_NONE 7
-#define DAV1D_REFS_PER_FRAME 7
-#define DAV1D_TOTAL_REFS_PER_FRAME (DAV1D_REFS_PER_FRAME + 1)
-
-enum Dav1dObuType {
-    DAV1D_OBU_SEQ_HDR   = 1,
-    DAV1D_OBU_TD        = 2,
-    DAV1D_OBU_FRAME_HDR = 3,
-    DAV1D_OBU_TILE_GRP  = 4,
-    DAV1D_OBU_METADATA  = 5,
-    DAV1D_OBU_FRAME     = 6,
-    DAV1D_OBU_REDUNDANT_FRAME_HDR = 7,
-    DAV1D_OBU_PADDING   = 15,
-};
-
-enum Dav1dTxfmMode {
-    DAV1D_TX_4X4_ONLY,
-    DAV1D_TX_LARGEST,
-    DAV1D_TX_SWITCHABLE,
-    DAV1D_N_TX_MODES,
-};
-
-enum Dav1dFilterMode {
-    DAV1D_FILTER_8TAP_REGULAR,
-    DAV1D_FILTER_8TAP_SMOOTH,
-    DAV1D_FILTER_8TAP_SHARP,
-    DAV1D_N_SWITCHABLE_FILTERS,
-    DAV1D_FILTER_BILINEAR = DAV1D_N_SWITCHABLE_FILTERS,
-    DAV1D_N_FILTERS,
-    DAV1D_FILTER_SWITCHABLE = DAV1D_N_FILTERS,
-};
-
-enum Dav1dAdaptiveBoolean {
-    DAV1D_OFF = 0,
-    DAV1D_ON = 1,
-    DAV1D_ADAPTIVE = 2,
-};
-
-enum Dav1dRestorationType {
-    DAV1D_RESTORATION_NONE,
-    DAV1D_RESTORATION_SWITCHABLE,
-    DAV1D_RESTORATION_WIENER,
-    DAV1D_RESTORATION_SGRPROJ,
-};
-
-enum Dav1dWarpedMotionType {
-    DAV1D_WM_TYPE_IDENTITY,
-    DAV1D_WM_TYPE_TRANSLATION,
-    DAV1D_WM_TYPE_ROT_ZOOM,
-    DAV1D_WM_TYPE_AFFINE,
-};
-
-typedef struct Dav1dWarpedMotionParams {
-    enum Dav1dWarpedMotionType type;
-    int32_t matrix[6];
-    union {
-        struct {
-            int16_t alpha, beta, gamma, delta;
-        };
-        int16_t abcd[4];
-    };
-} Dav1dWarpedMotionParams;
-
-enum Dav1dPixelLayout {
-    DAV1D_PIXEL_LAYOUT_I400, ///< monochrome
-    DAV1D_PIXEL_LAYOUT_I420, ///< 4:2:0 planar
-    DAV1D_PIXEL_LAYOUT_I422, ///< 4:2:2 planar
-    DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 planar
-};
-
-enum Dav1dFrameType {
-    DAV1D_FRAME_TYPE_KEY = 0,    ///< Key Intra frame
-    DAV1D_FRAME_TYPE_INTER = 1,  ///< Inter frame
-    DAV1D_FRAME_TYPE_INTRA = 2,  ///< Non key Intra frame
-    DAV1D_FRAME_TYPE_SWITCH = 3, ///< Switch Inter frame
-};
-
-enum Dav1dColorPrimaries {
-    DAV1D_COLOR_PRI_BT709 = 1,
-    DAV1D_COLOR_PRI_UNKNOWN = 2,
-    DAV1D_COLOR_PRI_BT470M = 4,
-    DAV1D_COLOR_PRI_BT470BG = 5,
-    DAV1D_COLOR_PRI_BT601 = 6,
-    DAV1D_COLOR_PRI_SMPTE240 = 7,
-    DAV1D_COLOR_PRI_FILM = 8,
-    DAV1D_COLOR_PRI_BT2020 = 9,
-    DAV1D_COLOR_PRI_XYZ = 10,
-    DAV1D_COLOR_PRI_SMPTE431 = 11,
-    DAV1D_COLOR_PRI_SMPTE432 = 12,
-    DAV1D_COLOR_PRI_EBU3213 = 22,
-};
-
-enum Dav1dTransferCharacteristics {
-    DAV1D_TRC_BT709 = 1,
-    DAV1D_TRC_UNKNOWN = 2,
-    DAV1D_TRC_BT470M = 4,
-    DAV1D_TRC_BT470BG = 5,
-    DAV1D_TRC_BT601 = 6,
-    DAV1D_TRC_SMPTE240 = 7,
-    DAV1D_TRC_LINEAR = 8,
-    DAV1D_TRC_LOG100 = 9,         ///< logarithmic (100:1 range)
-    DAV1D_TRC_LOG100_SQRT10 = 10, ///< lograithmic (100*sqrt(10):1 range)
-    DAV1D_TRC_IEC61966 = 11,
-    DAV1D_TRC_BT1361 = 12,
-    DAV1D_TRC_SRGB = 13,
-    DAV1D_TRC_BT2020_10BIT = 14,
-    DAV1D_TRC_BT2020_12BIT = 15,
-    DAV1D_TRC_SMPTE2084 = 16,     ///< PQ
-    DAV1D_TRC_SMPTE428 = 17,
-    DAV1D_TRC_HLG = 18,           ///< hybrid log/gamma (BT.2100 / ARIB STD-B67)
-};
-
-enum Dav1dMatrixCoefficients {
-    DAV1D_MC_IDENTITY = 0,
-    DAV1D_MC_BT709 = 1,
-    DAV1D_MC_UNKNOWN = 2,
-    DAV1D_MC_FCC = 4,
-    DAV1D_MC_BT470BG = 5,
-    DAV1D_MC_BT601 = 6,
-    DAV1D_MC_SMPTE240 = 7,
-    DAV1D_MC_SMPTE_YCGCO = 8,
-    DAV1D_MC_BT2020_NCL = 9,
-    DAV1D_MC_BT2020_CL = 10,
-    DAV1D_MC_SMPTE2085 = 11,
-    DAV1D_MC_CHROMAT_NCL = 12, ///< Chromaticity-derived
-    DAV1D_MC_CHROMAT_CL = 13,
-    DAV1D_MC_ICTCP = 14,
-};
-
-enum Dav1dChromaSamplePosition {
-    DAV1D_CHR_UNKNOWN = 0,
-    DAV1D_CHR_VERTICAL = 1,  ///< Horizontally co-located with luma(0, 0)
-                           ///< sample, between two vertical samples
-    DAV1D_CHR_COLOCATED = 2, ///< Co-located with luma(0, 0) sample
-};
-
-typedef struct Dav1dContentLightLevel {
-    int max_content_light_level;
-    int max_frame_average_light_level;
-} Dav1dContentLightLevel;
-
-typedef struct Dav1dMasteringDisplay {
-    ///< 0.16 fixed point
-    uint16_t primaries[3][2];
-    ///< 0.16 fixed point
-    uint16_t white_point[2];
-    ///< 24.8 fixed point
-    uint32_t max_luminance;
-    ///< 18.14 fixed point
-    uint32_t min_luminance;
-} Dav1dMasteringDisplay;
-
-typedef struct Dav1dITUTT35 {
-    uint8_t  country_code;
-    uint8_t  country_code_extension_byte;
-    size_t   payload_size;
-    uint8_t *payload;
-} Dav1dITUTT35;
-
-typedef struct Dav1dSequenceHeader {
-    /**
-     * Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;
-     * 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,
-     * or 12 bits/component at any chroma subsampling.
-     */
-    int profile;
-    /**
-     * Maximum dimensions for this stream. In non-scalable streams, these
-     * are often the actual dimensions of the stream, although that is not
-     * a normative requirement.
-     */
-    int max_width, max_height;
-    enum Dav1dPixelLayout layout; ///< format of the picture
-    enum Dav1dColorPrimaries pri; ///< color primaries (av1)
-    enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
-    enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
-    enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
-    /**
-     * 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not
-     * exactly the same as 'hbd' from the spec; the spec's hbd distinguishes
-     * between 8 (0) and 10-12 (1) bits/component, and another element
-     * (twelve_bit) to distinguish between 10 and 12 bits/component. To get
-     * the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.
-     */
-    int hbd;
-    /**
-     * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
-     * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
-     */
-    int color_range;
-
-    int num_operating_points;
-    struct Dav1dSequenceHeaderOperatingPoint {
-        int major_level, minor_level;
-        int initial_display_delay;
-        int idc;
-        int tier;
-        int decoder_model_param_present;
-        int display_model_param_present;
-    } operating_points[DAV1D_MAX_OPERATING_POINTS];
-
-    int still_picture;
-    int reduced_still_picture_header;
-    int timing_info_present;
-    int num_units_in_tick;
-    int time_scale;
-    int equal_picture_interval;
-    unsigned num_ticks_per_picture;
-    int decoder_model_info_present;
-    int encoder_decoder_buffer_delay_length;
-    int num_units_in_decoding_tick;
-    int buffer_removal_delay_length;
-    int frame_presentation_delay_length;
-    int display_model_info_present;
-    int width_n_bits, height_n_bits;
-    int frame_id_numbers_present;
-    int delta_frame_id_n_bits;
-    int frame_id_n_bits;
-    int sb128;
-    int filter_intra;
-    int intra_edge_filter;
-    int inter_intra;
-    int masked_compound;
-    int warped_motion;
-    int dual_filter;
-    int order_hint;
-    int jnt_comp;
-    int ref_frame_mvs;
-    enum Dav1dAdaptiveBoolean screen_content_tools;
-    enum Dav1dAdaptiveBoolean force_integer_mv;
-    int order_hint_n_bits;
-    int super_res;
-    int cdef;
-    int restoration;
-    int ss_hor, ss_ver, monochrome;
-    int color_description_present;
-    int separate_uv_delta_q;
-    int film_grain_present;
-
-    // Dav1dSequenceHeaders of the same sequence are required to be
-    // bit-identical until this offset. See 7.5 "Ordering of OBUs":
-    //   Within a particular coded video sequence, the contents of
-    //   sequence_header_obu must be bit-identical each time the
-    //   sequence header appears except for the contents of
-    //   operating_parameters_info.
-    struct Dav1dSequenceHeaderOperatingParameterInfo {
-        int decoder_buffer_delay;
-        int encoder_buffer_delay;
-        int low_delay_mode;
-    } operating_parameter_info[DAV1D_MAX_OPERATING_POINTS];
-} Dav1dSequenceHeader;
-
-typedef struct Dav1dSegmentationData {
-    int delta_q;
-    int delta_lf_y_v, delta_lf_y_h, delta_lf_u, delta_lf_v;
-    int ref;
-    int skip;
-    int globalmv;
-} Dav1dSegmentationData;
-
-typedef struct Dav1dSegmentationDataSet {
-    Dav1dSegmentationData d[DAV1D_MAX_SEGMENTS];
-    int preskip;
-    int last_active_segid;
-} Dav1dSegmentationDataSet;
-
-typedef struct Dav1dLoopfilterModeRefDeltas {
-    int mode_delta[2 /* is_zeromv */];
-    int ref_delta[DAV1D_TOTAL_REFS_PER_FRAME];
-} Dav1dLoopfilterModeRefDeltas;
-
-typedef struct Dav1dFilmGrainData {
-    unsigned seed;
-    int num_y_points;
-    uint8_t y_points[14][2 /* value, scaling */];
-    int chroma_scaling_from_luma;
-    int num_uv_points[2];
-    uint8_t uv_points[2][10][2 /* value, scaling */];
-    int scaling_shift;
-    int ar_coeff_lag;
-    int8_t ar_coeffs_y[24];
-    int8_t ar_coeffs_uv[2][25];
-    int ar_coeff_shift;
-    int grain_scale_shift;
-    int uv_mult[2];
-    int uv_luma_mult[2];
-    int uv_offset[2];
-    int overlap_flag;
-    int clip_to_restricted_range;
-} Dav1dFilmGrainData;
-
-typedef struct Dav1dFrameHeader {
-    enum Dav1dFrameType frame_type; ///< type of the picture
-    int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
-    int frame_offset; ///< frame number
-    struct {
-        int present, update;
-        Dav1dFilmGrainData data;
-    } film_grain; ///< film grain parameters
-    int temporal_id, spatial_id; ///< spatial and temporal id of the frame for SVC
-
-    int show_existing_frame;
-    int existing_frame_idx;
-    int frame_id;
-    int frame_presentation_delay;
-    int show_frame;
-    int showable_frame;
-    int error_resilient_mode;
-    int disable_cdf_update;
-    int allow_screen_content_tools;
-    int force_integer_mv;
-    int frame_size_override;
-    int primary_ref_frame;
-    int buffer_removal_time_present;
-    struct Dav1dFrameHeaderOperatingPoint {
-        int buffer_removal_time;
-    } operating_points[DAV1D_MAX_OPERATING_POINTS];
-    int refresh_frame_flags;
-    int render_width, render_height;
-    struct {
-        int width_scale_denominator;
-        int enabled;
-    } super_res;
-    int have_render_size;
-    int allow_intrabc;
-    int frame_ref_short_signaling;
-    int refidx[DAV1D_REFS_PER_FRAME];
-    int hp;
-    enum Dav1dFilterMode subpel_filter_mode;
-    int switchable_motion_mode;
-    int use_ref_frame_mvs;
-    int refresh_context;
-    struct {
-        int uniform;
-        unsigned n_bytes;
-        int min_log2_cols, max_log2_cols, log2_cols, cols;
-        int min_log2_rows, max_log2_rows, log2_rows, rows;
-        uint16_t col_start_sb[DAV1D_MAX_TILE_COLS + 1];
-        uint16_t row_start_sb[DAV1D_MAX_TILE_ROWS + 1];
-        int update;
-    } tiling;
-    struct {
-        int yac;
-        int ydc_delta;
-        int udc_delta, uac_delta, vdc_delta, vac_delta;
-        int qm, qm_y, qm_u, qm_v;
-    } quant;
-    struct {
-        int enabled, update_map, temporal, update_data;
-        Dav1dSegmentationDataSet seg_data;
-        int lossless[DAV1D_MAX_SEGMENTS], qidx[DAV1D_MAX_SEGMENTS];
-    } segmentation;
-    struct {
-        struct {
-            int present;
-            int res_log2;
-        } q;
-        struct {
-            int present;
-            int res_log2;
-            int multi;
-        } lf;
-    } delta;
-    int all_lossless;
-    struct {
-        int level_y[2 /* dir */];
-        int level_u, level_v;
-        int mode_ref_delta_enabled;
-        int mode_ref_delta_update;
-        Dav1dLoopfilterModeRefDeltas mode_ref_deltas;
-        int sharpness;
-    } loopfilter;
-    struct {
-        int damping;
-        int n_bits;
-        int y_strength[DAV1D_MAX_CDEF_STRENGTHS];
-        int uv_strength[DAV1D_MAX_CDEF_STRENGTHS];
-    } cdef;
-    struct {
-        enum Dav1dRestorationType type[3 /* plane */];
-        int unit_size[2 /* y, uv */];
-    } restoration;
-    enum Dav1dTxfmMode txfm_mode;
-    int switchable_comp_refs;
-    int skip_mode_allowed, skip_mode_enabled, skip_mode_refs[2];
-    int warp_motion;
-    int reduced_txtp_set;
-    Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
-} Dav1dFrameHeader;
-
-#endif /* DAV1D_HEADERS_H */
+/*

+ * Copyright © 2018-2020, VideoLAN and dav1d authors

+ * Copyright © 2018, Two Orioles, LLC

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright notice, this

+ *    list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef DAV1D_HEADERS_H

+#define DAV1D_HEADERS_H

+

+#include <stdint.h>

+#include <stddef.h>

+

+// Constants from Section 3. "Symbols and abbreviated terms"

+#define DAV1D_MAX_CDEF_STRENGTHS 8

+#define DAV1D_MAX_OPERATING_POINTS 32

+#define DAV1D_MAX_TILE_COLS 64

+#define DAV1D_MAX_TILE_ROWS 64

+#define DAV1D_MAX_SEGMENTS 8

+#define DAV1D_NUM_REF_FRAMES 8

+#define DAV1D_PRIMARY_REF_NONE 7

+#define DAV1D_REFS_PER_FRAME 7

+#define DAV1D_TOTAL_REFS_PER_FRAME (DAV1D_REFS_PER_FRAME + 1)

+

+enum Dav1dObuType {

+    DAV1D_OBU_SEQ_HDR   = 1,

+    DAV1D_OBU_TD        = 2,

+    DAV1D_OBU_FRAME_HDR = 3,

+    DAV1D_OBU_TILE_GRP  = 4,

+    DAV1D_OBU_METADATA  = 5,

+    DAV1D_OBU_FRAME     = 6,

+    DAV1D_OBU_REDUNDANT_FRAME_HDR = 7,

+    DAV1D_OBU_PADDING   = 15,

+};

+

+enum Dav1dTxfmMode {

+    DAV1D_TX_4X4_ONLY,

+    DAV1D_TX_LARGEST,

+    DAV1D_TX_SWITCHABLE,

+    DAV1D_N_TX_MODES,

+};

+

+enum Dav1dFilterMode {

+    DAV1D_FILTER_8TAP_REGULAR,

+    DAV1D_FILTER_8TAP_SMOOTH,

+    DAV1D_FILTER_8TAP_SHARP,

+    DAV1D_N_SWITCHABLE_FILTERS,

+    DAV1D_FILTER_BILINEAR = DAV1D_N_SWITCHABLE_FILTERS,

+    DAV1D_N_FILTERS,

+    DAV1D_FILTER_SWITCHABLE = DAV1D_N_FILTERS,

+};

+

+enum Dav1dAdaptiveBoolean {

+    DAV1D_OFF = 0,

+    DAV1D_ON = 1,

+    DAV1D_ADAPTIVE = 2,

+};

+

+enum Dav1dRestorationType {

+    DAV1D_RESTORATION_NONE,

+    DAV1D_RESTORATION_SWITCHABLE,

+    DAV1D_RESTORATION_WIENER,

+    DAV1D_RESTORATION_SGRPROJ,

+};

+

+enum Dav1dWarpedMotionType {

+    DAV1D_WM_TYPE_IDENTITY,

+    DAV1D_WM_TYPE_TRANSLATION,

+    DAV1D_WM_TYPE_ROT_ZOOM,

+    DAV1D_WM_TYPE_AFFINE,

+};

+

+typedef struct Dav1dWarpedMotionParams {

+    enum Dav1dWarpedMotionType type;

+    int32_t matrix[6];

+    union {

+        struct {

+            int16_t alpha, beta, gamma, delta;

+        } p;

+        int16_t abcd[4];

+    } u;

+} Dav1dWarpedMotionParams;

+

+enum Dav1dPixelLayout {

+    DAV1D_PIXEL_LAYOUT_I400, ///< monochrome

+    DAV1D_PIXEL_LAYOUT_I420, ///< 4:2:0 planar

+    DAV1D_PIXEL_LAYOUT_I422, ///< 4:2:2 planar

+    DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 planar

+};

+

+enum Dav1dFrameType {

+    DAV1D_FRAME_TYPE_KEY = 0,    ///< Key Intra frame

+    DAV1D_FRAME_TYPE_INTER = 1,  ///< Inter frame

+    DAV1D_FRAME_TYPE_INTRA = 2,  ///< Non key Intra frame

+    DAV1D_FRAME_TYPE_SWITCH = 3, ///< Switch Inter frame

+};

+

+enum Dav1dColorPrimaries {

+    DAV1D_COLOR_PRI_BT709 = 1,

+    DAV1D_COLOR_PRI_UNKNOWN = 2,

+    DAV1D_COLOR_PRI_BT470M = 4,

+    DAV1D_COLOR_PRI_BT470BG = 5,

+    DAV1D_COLOR_PRI_BT601 = 6,

+    DAV1D_COLOR_PRI_SMPTE240 = 7,

+    DAV1D_COLOR_PRI_FILM = 8,

+    DAV1D_COLOR_PRI_BT2020 = 9,

+    DAV1D_COLOR_PRI_XYZ = 10,

+    DAV1D_COLOR_PRI_SMPTE431 = 11,

+    DAV1D_COLOR_PRI_SMPTE432 = 12,

+    DAV1D_COLOR_PRI_EBU3213 = 22,

+    DAV1D_COLOR_PRI_RESERVED = 255,

+};

+

+enum Dav1dTransferCharacteristics {

+    DAV1D_TRC_BT709 = 1,

+    DAV1D_TRC_UNKNOWN = 2,

+    DAV1D_TRC_BT470M = 4,

+    DAV1D_TRC_BT470BG = 5,

+    DAV1D_TRC_BT601 = 6,

+    DAV1D_TRC_SMPTE240 = 7,

+    DAV1D_TRC_LINEAR = 8,

+    DAV1D_TRC_LOG100 = 9,         ///< logarithmic (100:1 range)

+    DAV1D_TRC_LOG100_SQRT10 = 10, ///< lograithmic (100*sqrt(10):1 range)

+    DAV1D_TRC_IEC61966 = 11,

+    DAV1D_TRC_BT1361 = 12,

+    DAV1D_TRC_SRGB = 13,

+    DAV1D_TRC_BT2020_10BIT = 14,

+    DAV1D_TRC_BT2020_12BIT = 15,

+    DAV1D_TRC_SMPTE2084 = 16,     ///< PQ

+    DAV1D_TRC_SMPTE428 = 17,

+    DAV1D_TRC_HLG = 18,           ///< hybrid log/gamma (BT.2100 / ARIB STD-B67)

+    DAV1D_TRC_RESERVED = 255,

+};

+

+enum Dav1dMatrixCoefficients {

+    DAV1D_MC_IDENTITY = 0,

+    DAV1D_MC_BT709 = 1,

+    DAV1D_MC_UNKNOWN = 2,

+    DAV1D_MC_FCC = 4,

+    DAV1D_MC_BT470BG = 5,

+    DAV1D_MC_BT601 = 6,

+    DAV1D_MC_SMPTE240 = 7,

+    DAV1D_MC_SMPTE_YCGCO = 8,

+    DAV1D_MC_BT2020_NCL = 9,

+    DAV1D_MC_BT2020_CL = 10,

+    DAV1D_MC_SMPTE2085 = 11,

+    DAV1D_MC_CHROMAT_NCL = 12, ///< Chromaticity-derived

+    DAV1D_MC_CHROMAT_CL = 13,

+    DAV1D_MC_ICTCP = 14,

+    DAV1D_MC_RESERVED = 255,

+};

+

+enum Dav1dChromaSamplePosition {

+    DAV1D_CHR_UNKNOWN = 0,

+    DAV1D_CHR_VERTICAL = 1,  ///< Horizontally co-located with luma(0, 0)

+                           ///< sample, between two vertical samples

+    DAV1D_CHR_COLOCATED = 2, ///< Co-located with luma(0, 0) sample

+};

+

+typedef struct Dav1dContentLightLevel {

+    int max_content_light_level;

+    int max_frame_average_light_level;

+} Dav1dContentLightLevel;

+

+typedef struct Dav1dMasteringDisplay {

+    ///< 0.16 fixed point

+    uint16_t primaries[3][2];

+    ///< 0.16 fixed point

+    uint16_t white_point[2];

+    ///< 24.8 fixed point

+    uint32_t max_luminance;

+    ///< 18.14 fixed point

+    uint32_t min_luminance;

+} Dav1dMasteringDisplay;

+

+typedef struct Dav1dITUTT35 {

+    uint8_t  country_code;

+    uint8_t  country_code_extension_byte;

+    size_t   payload_size;

+    uint8_t *payload;

+} Dav1dITUTT35;

+

+typedef struct Dav1dSequenceHeader {

+    /**

+     * Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;

+     * 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,

+     * or 12 bits/component at any chroma subsampling.

+     */

+    int profile;

+    /**

+     * Maximum dimensions for this stream. In non-scalable streams, these

+     * are often the actual dimensions of the stream, although that is not

+     * a normative requirement.

+     */

+    int max_width, max_height;

+    enum Dav1dPixelLayout layout; ///< format of the picture

+    enum Dav1dColorPrimaries pri; ///< color primaries (av1)

+    enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)

+    enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)

+    enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)

+    /**

+     * 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not

+     * exactly the same as 'hbd' from the spec; the spec's hbd distinguishes

+     * between 8 (0) and 10-12 (1) bits/component, and another element

+     * (twelve_bit) to distinguish between 10 and 12 bits/component. To get

+     * the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.

+     */

+    int hbd;

+    /**

+     * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of

+     * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).

+     */

+    int color_range;

+

+    int num_operating_points;

+    struct Dav1dSequenceHeaderOperatingPoint {

+        int major_level, minor_level;

+        int initial_display_delay;

+        int idc;

+        int tier;

+        int decoder_model_param_present;

+        int display_model_param_present;

+    } operating_points[DAV1D_MAX_OPERATING_POINTS];

+

+    int still_picture;

+    int reduced_still_picture_header;

+    int timing_info_present;

+    int num_units_in_tick;

+    int time_scale;

+    int equal_picture_interval;

+    unsigned num_ticks_per_picture;

+    int decoder_model_info_present;

+    int encoder_decoder_buffer_delay_length;

+    int num_units_in_decoding_tick;

+    int buffer_removal_delay_length;

+    int frame_presentation_delay_length;

+    int display_model_info_present;

+    int width_n_bits, height_n_bits;

+    int frame_id_numbers_present;

+    int delta_frame_id_n_bits;

+    int frame_id_n_bits;

+    int sb128;

+    int filter_intra;

+    int intra_edge_filter;

+    int inter_intra;

+    int masked_compound;

+    int warped_motion;

+    int dual_filter;

+    int order_hint;

+    int jnt_comp;

+    int ref_frame_mvs;

+    enum Dav1dAdaptiveBoolean screen_content_tools;

+    enum Dav1dAdaptiveBoolean force_integer_mv;

+    int order_hint_n_bits;

+    int super_res;

+    int cdef;

+    int restoration;

+    int ss_hor, ss_ver, monochrome;

+    int color_description_present;

+    int separate_uv_delta_q;

+    int film_grain_present;

+

+    // Dav1dSequenceHeaders of the same sequence are required to be

+    // bit-identical until this offset. See 7.5 "Ordering of OBUs":

+    //   Within a particular coded video sequence, the contents of

+    //   sequence_header_obu must be bit-identical each time the

+    //   sequence header appears except for the contents of

+    //   operating_parameters_info.

+    struct Dav1dSequenceHeaderOperatingParameterInfo {

+        int decoder_buffer_delay;

+        int encoder_buffer_delay;

+        int low_delay_mode;

+    } operating_parameter_info[DAV1D_MAX_OPERATING_POINTS];

+} Dav1dSequenceHeader;

+

+typedef struct Dav1dSegmentationData {

+    int delta_q;

+    int delta_lf_y_v, delta_lf_y_h, delta_lf_u, delta_lf_v;

+    int ref;

+    int skip;

+    int globalmv;

+} Dav1dSegmentationData;

+

+typedef struct Dav1dSegmentationDataSet {

+    Dav1dSegmentationData d[DAV1D_MAX_SEGMENTS];

+    int preskip;

+    int last_active_segid;

+} Dav1dSegmentationDataSet;

+

+typedef struct Dav1dLoopfilterModeRefDeltas {

+    int mode_delta[2 /* is_zeromv */];

+    int ref_delta[DAV1D_TOTAL_REFS_PER_FRAME];

+} Dav1dLoopfilterModeRefDeltas;

+

+typedef struct Dav1dFilmGrainData {

+    unsigned seed;

+    int num_y_points;

+    uint8_t y_points[14][2 /* value, scaling */];

+    int chroma_scaling_from_luma;

+    int num_uv_points[2];

+    uint8_t uv_points[2][10][2 /* value, scaling */];

+    int scaling_shift;

+    int ar_coeff_lag;

+    int8_t ar_coeffs_y[24];

+    int8_t ar_coeffs_uv[2][25 + 3 /* padding for alignment purposes */];

+    uint64_t ar_coeff_shift;

+    int grain_scale_shift;

+    int uv_mult[2];

+    int uv_luma_mult[2];

+    int uv_offset[2];

+    int overlap_flag;

+    int clip_to_restricted_range;

+} Dav1dFilmGrainData;

+

+typedef struct Dav1dFrameHeader {

+    struct {

+        Dav1dFilmGrainData data;

+        int present, update;

+    } film_grain; ///< film grain parameters

+    enum Dav1dFrameType frame_type; ///< type of the picture

+    int width[2 /* { coded_width, superresolution_upscaled_width } */], height;

+    int frame_offset; ///< frame number

+    int temporal_id; ///< temporal id of the frame for SVC

+    int spatial_id; ///< spatial id of the frame for SVC

+

+    int show_existing_frame;

+    int existing_frame_idx;

+    int frame_id;

+    int frame_presentation_delay;

+    int show_frame;

+    int showable_frame;

+    int error_resilient_mode;

+    int disable_cdf_update;

+    int allow_screen_content_tools;

+    int force_integer_mv;

+    int frame_size_override;

+    int primary_ref_frame;

+    int buffer_removal_time_present;

+    struct Dav1dFrameHeaderOperatingPoint {

+        int buffer_removal_time;

+    } operating_points[DAV1D_MAX_OPERATING_POINTS];

+    int refresh_frame_flags;

+    int render_width, render_height;

+    struct {

+        int width_scale_denominator;

+        int enabled;

+    } super_res;

+    int have_render_size;

+    int allow_intrabc;

+    int frame_ref_short_signaling;

+    int refidx[DAV1D_REFS_PER_FRAME];

+    int hp;

+    enum Dav1dFilterMode subpel_filter_mode;

+    int switchable_motion_mode;

+    int use_ref_frame_mvs;

+    int refresh_context;

+    struct {

+        int uniform;

+        unsigned n_bytes;

+        int min_log2_cols, max_log2_cols, log2_cols, cols;

+        int min_log2_rows, max_log2_rows, log2_rows, rows;

+        uint16_t col_start_sb[DAV1D_MAX_TILE_COLS + 1];

+        uint16_t row_start_sb[DAV1D_MAX_TILE_ROWS + 1];

+        int update;

+    } tiling;

+    struct {

+        int yac;

+        int ydc_delta;

+        int udc_delta, uac_delta, vdc_delta, vac_delta;

+        int qm, qm_y, qm_u, qm_v;

+    } quant;

+    struct {

+        int enabled, update_map, temporal, update_data;

+        Dav1dSegmentationDataSet seg_data;

+        int lossless[DAV1D_MAX_SEGMENTS], qidx[DAV1D_MAX_SEGMENTS];

+    } segmentation;

+    struct {

+        struct {

+            int present;

+            int res_log2;

+        } q;

+        struct {

+            int present;

+            int res_log2;

+            int multi;

+        } lf;

+    } delta;

+    int all_lossless;

+    struct {

+        int level_y[2 /* dir */];

+        int level_u, level_v;

+        int mode_ref_delta_enabled;

+        int mode_ref_delta_update;

+        Dav1dLoopfilterModeRefDeltas mode_ref_deltas;

+        int sharpness;

+    } loopfilter;

+    struct {

+        int damping;

+        int n_bits;

+        int y_strength[DAV1D_MAX_CDEF_STRENGTHS];

+        int uv_strength[DAV1D_MAX_CDEF_STRENGTHS];

+    } cdef;

+    struct {

+        enum Dav1dRestorationType type[3 /* plane */];

+        int unit_size[2 /* y, uv */];

+    } restoration;

+    enum Dav1dTxfmMode txfm_mode;

+    int switchable_comp_refs;

+    int skip_mode_allowed, skip_mode_enabled, skip_mode_refs[2];

+    int warp_motion;

+    int reduced_txtp_set;

+    Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];

+} Dav1dFrameHeader;

+

+#endif /* DAV1D_HEADERS_H */

diff --git a/src/third_party/libdav1d/include/dav1d/picture.h b/src/third_party/libdav1d/include/dav1d/picture.h
index 08746f3..68ef6d5 100644
--- a/src/third_party/libdav1d/include/dav1d/picture.h
+++ b/src/third_party/libdav1d/include/dav1d/picture.h
@@ -1,141 +1,144 @@
-/*
- * Copyright © 2018, VideoLAN and dav1d authors
- * Copyright © 2018, Two Orioles, LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAV1D_PICTURE_H
-#define DAV1D_PICTURE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "common.h"
-#include "headers.h"
-
-/* Number of bytes to align AND pad picture memory buffers by, so that SIMD
- * implementations can over-read by a few bytes, and use aligned read/write
- * instructions. */
-#define DAV1D_PICTURE_ALIGNMENT 64
-
-typedef struct Dav1dPictureParameters {
-    int w; ///< width (in pixels)
-    int h; ///< height (in pixels)
-    enum Dav1dPixelLayout layout; ///< format of the picture
-    int bpc; ///< bits per pixel component (8 or 10)
-} Dav1dPictureParameters;
-
-typedef struct Dav1dPicture {
-    Dav1dSequenceHeader *seq_hdr;
-    Dav1dFrameHeader *frame_hdr;
-
-    /**
-     * Pointers to planar image data (Y is [0], U is [1], V is [2]). The data
-     * should be bytes (for 8 bpc) or words (for 10 bpc). In case of words
-     * containing 10 bpc image data, the pixels should be located in the LSB
-     * bits, so that values range between [0, 1023]; the upper bits should be
-     * zero'ed out.
-     */
-    void *data[3];
-
-    /**
-     * Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
-     */
-    ptrdiff_t stride[2];
-
-    Dav1dPictureParameters p;
-    Dav1dDataProps m;
-
-    /**
-     * High Dynamic Range Content Light Level metadata applying to this picture,
-     * as defined in section 5.8.3 and 6.7.3
-     */
-    Dav1dContentLightLevel *content_light;
-    /**
-     * High Dynamic Range Mastering Display Color Volume metadata applying to
-     * this picture, as defined in section 5.8.4 and 6.7.4
-     */
-    Dav1dMasteringDisplay *mastering_display;
-    /**
-     * ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
-     */
-    Dav1dITUTT35 *itut_t35;
-
-    uintptr_t reserved[4]; ///< reserved for future use
-
-    struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref; ///< Frame parameter allocation origins
-    struct Dav1dRef *content_light_ref, *mastering_display_ref, *itut_t35_ref; ///< Metadata allocation origins
-    uintptr_t reserved_ref[4]; ///< reserved for future use
-    struct Dav1dRef *ref; ///< Frame data allocation origin
-
-    void *allocator_data; ///< pointer managed by the allocator
-} Dav1dPicture;
-
-typedef struct Dav1dPicAllocator {
-    void *cookie; ///< custom data to pass to the allocator callbacks.
-    /**
-     * Allocate the picture buffer based on the Dav1dPictureParameters.
-     *
-     * The data[0], data[1] and data[2] must be DAV1D_PICTURE_ALIGNMENT byte
-     * aligned and with a pixel width/height multiple of 128 pixels. Any
-     * allocated memory area should also be padded by DAV1D_PICTURE_ALIGNMENT
-     * bytes.
-     * data[1] and data[2] must share the same stride[1].
-     *
-     * This function will be called on the main thread (the thread which calls
-     * dav1d_get_picture()).
-     *
-     * @param  pic The picture to allocate the buffer for. The callback needs to
-     *             fill the picture data[0], data[1], data[2], stride[0] and
-     *             stride[1].
-     *             The allocator can fill the pic allocator_data pointer with
-     *             a custom pointer that will be passed to
-     *             release_picture_callback().
-     * @param cookie Custom pointer passed to all calls.
-     *
-     * @note No fields other than data, stride and allocator_data must be filled
-     *       by this callback.
-     * @return 0 on success. A negative DAV1D_ERR value on error.
-     */
-    int (*alloc_picture_callback)(Dav1dPicture *pic, void *cookie);
-    /**
-     * Release the picture buffer.
-     *
-     * If frame threading is used, this function may be called by the main
-     * thread (the thread which calls dav1d_get_picture()) or any of the frame
-     * threads and thus must be thread-safe. If frame threading is not used,
-     * this function will only be called on the main thread.
-     *
-     * @param pic    The picture that was filled by alloc_picture_callback().
-     * @param cookie Custom pointer passed to all calls.
-     */
-    void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);
-} Dav1dPicAllocator;
-
-/**
- * Release reference to a picture.
- */
-DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);
-
-#endif /* DAV1D_PICTURE_H */
+/*

+ * Copyright © 2018-2020, VideoLAN and dav1d authors

+ * Copyright © 2018, Two Orioles, LLC

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright notice, this

+ *    list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright notice,

+ *    this list of conditions and the following disclaimer in the documentation

+ *    and/or other materials provided with the distribution.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR

+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

+

+#ifndef DAV1D_PICTURE_H

+#define DAV1D_PICTURE_H

+

+#include <stddef.h>

+#include <stdint.h>

+

+#include "common.h"

+#include "headers.h"

+

+/* Number of bytes to align AND pad picture memory buffers by, so that SIMD

+ * implementations can over-read by a few bytes, and use aligned read/write

+ * instructions. */

+#define DAV1D_PICTURE_ALIGNMENT 64

+

+typedef struct Dav1dPictureParameters {

+    int w; ///< width (in pixels)

+    int h; ///< height (in pixels)

+    enum Dav1dPixelLayout layout; ///< format of the picture

+    int bpc; ///< bits per pixel component (8 or 10)

+} Dav1dPictureParameters;

+

+typedef struct Dav1dPicture {

+    Dav1dSequenceHeader *seq_hdr;

+    Dav1dFrameHeader *frame_hdr;

+

+    /**

+     * Pointers to planar image data (Y is [0], U is [1], V is [2]). The data

+     * should be bytes (for 8 bpc) or words (for 10 bpc). In case of words

+     * containing 10 bpc image data, the pixels should be located in the LSB

+     * bits, so that values range between [0, 1023]; the upper bits should be

+     * zero'ed out.

+     */

+    void *data[3];

+

+    /**

+     * Number of bytes between 2 lines in data[] for luma [0] or chroma [1].

+     */

+    ptrdiff_t stride[2];

+

+    Dav1dPictureParameters p;

+    Dav1dDataProps m;

+

+    /**

+     * High Dynamic Range Content Light Level metadata applying to this picture,

+     * as defined in section 5.8.3 and 6.7.3

+     */

+    Dav1dContentLightLevel *content_light;

+    /**

+     * High Dynamic Range Mastering Display Color Volume metadata applying to

+     * this picture, as defined in section 5.8.4 and 6.7.4

+     */

+    Dav1dMasteringDisplay *mastering_display;

+    /**

+     * ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2

+     */

+    Dav1dITUTT35 *itut_t35;

+

+    uintptr_t reserved[4]; ///< reserved for future use

+

+    struct Dav1dRef *frame_hdr_ref; ///< Dav1dFrameHeader allocation origin

+    struct Dav1dRef *seq_hdr_ref; ///< Dav1dSequenceHeader allocation origin

+    struct Dav1dRef *content_light_ref; ///< Dav1dContentLightLevel allocation origin

+    struct Dav1dRef *mastering_display_ref; ///< Dav1dMasteringDisplay allocation origin

+    struct Dav1dRef *itut_t35_ref; ///< Dav1dITUTT35 allocation origin

+    uintptr_t reserved_ref[4]; ///< reserved for future use

+    struct Dav1dRef *ref; ///< Frame data allocation origin

+

+    void *allocator_data; ///< pointer managed by the allocator

+} Dav1dPicture;

+

+typedef struct Dav1dPicAllocator {

+    void *cookie; ///< custom data to pass to the allocator callbacks.

+    /**

+     * Allocate the picture buffer based on the Dav1dPictureParameters.

+     *

+     * The data[0], data[1] and data[2] must be DAV1D_PICTURE_ALIGNMENT byte

+     * aligned and with a pixel width/height multiple of 128 pixels. Any

+     * allocated memory area should also be padded by DAV1D_PICTURE_ALIGNMENT

+     * bytes.

+     * data[1] and data[2] must share the same stride[1].

+     *

+     * This function will be called on the main thread (the thread which calls

+     * dav1d_get_picture()).

+     *

+     * @param  pic The picture to allocate the buffer for. The callback needs to

+     *             fill the picture data[0], data[1], data[2], stride[0] and

+     *             stride[1].

+     *             The allocator can fill the pic allocator_data pointer with

+     *             a custom pointer that will be passed to

+     *             release_picture_callback().

+     * @param cookie Custom pointer passed to all calls.

+     *

+     * @note No fields other than data, stride and allocator_data must be filled

+     *       by this callback.

+     * @return 0 on success. A negative DAV1D_ERR value on error.

+     */

+    int (*alloc_picture_callback)(Dav1dPicture *pic, void *cookie);

+    /**

+     * Release the picture buffer.

+     *

+     * If frame threading is used, this function may be called by the main

+     * thread (the thread which calls dav1d_get_picture()) or any of the frame

+     * threads and thus must be thread-safe. If frame threading is not used,

+     * this function will only be called on the main thread.

+     *

+     * @param pic    The picture that was filled by alloc_picture_callback().

+     * @param cookie Custom pointer passed to all calls.

+     */

+    void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);

+} Dav1dPicAllocator;

+

+/**

+ * Release reference to a picture.

+ */

+DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);

+

+#endif /* DAV1D_PICTURE_H */

diff --git a/src/tools/download_from_gcs.py b/src/tools/download_from_gcs.py
index 9c79dfb..4a49502 100755
--- a/src/tools/download_from_gcs.py
+++ b/src/tools/download_from_gcs.py
@@ -57,11 +57,13 @@
   context = create_default_context()
 
   try:
-    res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url)
+    res = urllib.urlopen(
+        url, context=context) if context else urllib.urlopen(url)
   except urllib.URLError:
-    from ssl import _create_unverified_context
+    from ssl import _create_unverified_context  # pylint:disable=import-outside-toplevel
     context = _create_unverified_context()
-    res = urllib.urlopen(url, context=context) if context else urllib.urlopen(url)
+    res = urllib.urlopen(
+        url, context=context) if context else urllib.urlopen(url)
 
   if not res:
     logging.error('Could not reach %s', url)
diff --git a/src/tools/download_from_gcs_test.py b/src/tools/download_from_gcs_test.py
index 6c5b4b8..65a0eaf 100755
--- a/src/tools/download_from_gcs_test.py
+++ b/src/tools/download_from_gcs_test.py
@@ -18,7 +18,7 @@
 import tempfile
 import unittest
 
-import tools.download_from_gcs as download_from_gcs
+from tools import download_from_gcs
 
 _BUCKET = 'chromium-clang-format'
 _HASH_FILE_EXT = '.sha1'
@@ -52,7 +52,7 @@
 
   def setUp(self):
     self.test_file = os.path.join(_TEST_PATH, _TEST_FILE)
-    self.output_directory = tempfile.TemporaryDirectory()
+    self.output_directory = tempfile.TemporaryDirectory()  # pylint:disable=consider-using-with
     self.output_file = os.path.join(self.output_directory.name, 'output')
     self.bucket = _BUCKET
 
@@ -74,7 +74,7 @@
 
   def setUp(self):
     self.test_directory = os.path.join(_TEST_PATH, _TEST_DIRECTORY)
-    self.output_directory = tempfile.TemporaryDirectory()
+    self.output_directory = tempfile.TemporaryDirectory()  # pylint:disable=consider-using-with
     self.bucket = _BUCKET
 
   def tearDown(self):
diff --git a/src/tools/gyp/pylib/gyp/msvs_emulation.py b/src/tools/gyp/pylib/gyp/msvs_emulation.py
index 84f4ff6..ba2812c 100755
--- a/src/tools/gyp/pylib/gyp/msvs_emulation.py
+++ b/src/tools/gyp/pylib/gyp/msvs_emulation.py
@@ -747,7 +747,8 @@
       'cell_.*',
       'sn_.*',
       'sce_.*',
-      'is_docker', # TODO(agmenon): needed for ninja to invoke docker-specific logic
+      'is_docker', # needed for ninja to invoke docker-specific logic
+      'is_ci',     # needed for ninja to exlcude some logic on GKE
   )
   env = {}
   for line in output_of_set.splitlines():