From 68569dee1416593955c1570d638b3d9250b33012 Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Mon, 15 Oct 2018 21:45:30 -0500
Subject: Import aom library

This is the reference implementation for the Alliance for Open Media's av1 video code.

The commit used was 4d668d7feb1f8abd809d1bca0418570a7f142a36.
---
 third_party/aom/examples/analyzer.cc         | 695 +++++++++++++++++++++++++++
 third_party/aom/examples/aom_cx_set_ref.c    | 323 +++++++++++++
 third_party/aom/examples/decode_to_md5.c     | 133 +++++
 third_party/aom/examples/decode_with_drops.c | 149 ++++++
 third_party/aom/examples/encoder_util.c      | 139 ++++++
 third_party/aom/examples/encoder_util.h      |  36 ++
 third_party/aom/examples/inspect.c           | 678 ++++++++++++++++++++++++++
 third_party/aom/examples/lossless_encoder.c  | 139 ++++++
 third_party/aom/examples/resize_util.c       | 124 +++++
 third_party/aom/examples/set_maps.c          | 210 ++++++++
 third_party/aom/examples/simple_decoder.c    | 150 ++++++
 third_party/aom/examples/simple_encoder.c    | 250 ++++++++++
 third_party/aom/examples/twopass_encoder.c   | 255 ++++++++++
 13 files changed, 3281 insertions(+)
 create mode 100644 third_party/aom/examples/analyzer.cc
 create mode 100644 third_party/aom/examples/aom_cx_set_ref.c
 create mode 100644 third_party/aom/examples/decode_to_md5.c
 create mode 100644 third_party/aom/examples/decode_with_drops.c
 create mode 100644 third_party/aom/examples/encoder_util.c
 create mode 100644 third_party/aom/examples/encoder_util.h
 create mode 100644 third_party/aom/examples/inspect.c
 create mode 100644 third_party/aom/examples/lossless_encoder.c
 create mode 100644 third_party/aom/examples/resize_util.c
 create mode 100644 third_party/aom/examples/set_maps.c
 create mode 100644 third_party/aom/examples/simple_decoder.c
 create mode 100644 third_party/aom/examples/simple_encoder.c
 create mode 100644 third_party/aom/examples/twopass_encoder.c

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/analyzer.cc b/third_party/aom/examples/analyzer.cc
new file mode 100644
index 000000000..591aaf25e
--- /dev/null
+++ b/third_party/aom/examples/analyzer.cc
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#include <wx/wx.h>
+#include <wx/aboutdlg.h>
+#include <wx/cmdline.h>
+#include <wx/dcbuffer.h>
+#include "./tools_common.h"
+#include "./video_reader.h"
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+#include "av1/decoder/accounting.h"
+#include "av1/common/onyxc_int.h"
+#include "av1/decoder/inspection.h"
+
+#define OD_SIGNMASK(a) (-((a) < 0))
+#define OD_FLIPSIGNI(a, b) (((a) + OD_SIGNMASK(b)) ^ OD_SIGNMASK(b))
+#define OD_DIV_ROUND(x, y) (((x) + OD_FLIPSIGNI((y) >> 1, x)) / (y))
+
+enum {
+  OD_LUMA_MASK = 1 << 0,
+  OD_CB_MASK = 1 << 1,
+  OD_CR_MASK = 1 << 2,
+  OD_ALL_MASK = OD_LUMA_MASK | OD_CB_MASK | OD_CR_MASK
+};
+
+class AV1Decoder {
+ private:
+  FILE *input;
+  wxString path;
+
+  AvxVideoReader *reader;
+  const AvxVideoInfo *info;
+  const AvxInterface *decoder;
+
+  insp_frame_data frame_data;
+
+  aom_codec_ctx_t codec;
+  bool show_padding;
+
+ public:
+  aom_image_t *image;
+  int frame;
+
+  int plane_mask;
+
+  AV1Decoder();
+  ~AV1Decoder();
+
+  bool open(const wxString &path);
+  void close();
+  bool step();
+
+  int getWidthPadding() const;
+  int getHeightPadding() const;
+  void togglePadding();
+  int getWidth() const;
+  int getHeight() const;
+
+  bool getAccountingStruct(Accounting **acct);
+  bool setInspectionCallback();
+
+  static void inspect(void *decoder, void *data);
+};
+
+AV1Decoder::AV1Decoder()
+    : reader(NULL), info(NULL), decoder(NULL), show_padding(false), image(NULL),
+      frame(0) {}
+
+AV1Decoder::~AV1Decoder() {}
+
+void AV1Decoder::togglePadding() { show_padding = !show_padding; }
+
+bool AV1Decoder::open(const wxString &path) {
+  reader = aom_video_reader_open(path.mb_str());
+  if (!reader) {
+    fprintf(stderr, "Failed to open %s for reading.", path.mb_str().data());
+    return false;
+  }
+  this->path = path;
+  info = aom_video_reader_get_info(reader);
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) {
+    fprintf(stderr, "Unknown input codec.");
+    return false;
+  }
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) {
+    fprintf(stderr, "Failed to initialize decoder.");
+    return false;
+  }
+  ifd_init(&frame_data, info->frame_width, info->frame_height);
+  setInspectionCallback();
+  return true;
+}
+
+void AV1Decoder::close() {}
+
+bool AV1Decoder::step() {
+  if (aom_video_reader_read_frame(reader)) {
+    size_t frame_size;
+    const unsigned char *frame_data;
+    frame_data = aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame_data, frame_size, NULL, 0)) {
+      fprintf(stderr, "Failed to decode frame.");
+      return false;
+    } else {
+      aom_codec_iter_t iter = NULL;
+      image = aom_codec_get_frame(&codec, &iter);
+      if (image != NULL) {
+        frame++;
+        return true;
+      }
+      return false;
+    }
+  }
+  return false;
+}
+
+int AV1Decoder::getWidth() const {
+  return info->frame_width + 2 * getWidthPadding();
+}
+
+int AV1Decoder::getWidthPadding() const {
+  return show_padding
+             ? AOMMAX(info->frame_width + 16,
+                      ALIGN_POWER_OF_TWO(info->frame_width, 6)) -
+                   info->frame_width
+             : 0;
+}
+
+int AV1Decoder::getHeight() const {
+  return info->frame_height + 2 * getHeightPadding();
+}
+
+int AV1Decoder::getHeightPadding() const {
+  return show_padding
+             ? AOMMAX(info->frame_height + 16,
+                      ALIGN_POWER_OF_TWO(info->frame_height, 6)) -
+                   info->frame_height
+             : 0;
+}
+
+bool AV1Decoder::getAccountingStruct(Accounting **accounting) {
+  return aom_codec_control(&codec, AV1_GET_ACCOUNTING, accounting) ==
+         AOM_CODEC_OK;
+}
+
+bool AV1Decoder::setInspectionCallback() {
+  aom_inspect_init ii;
+  ii.inspect_cb = AV1Decoder::inspect;
+  ii.inspect_ctx = (void *)this;
+  return aom_codec_control(&codec, AV1_SET_INSPECTION_CALLBACK, &ii) ==
+         AOM_CODEC_OK;
+}
+
+void AV1Decoder::inspect(void *pbi, void *data) {
+  AV1Decoder *decoder = (AV1Decoder *)data;
+  ifd_inspect(&decoder->frame_data, pbi);
+}
+
+#define MIN_ZOOM (1)
+#define MAX_ZOOM (4)
+
+class AnalyzerPanel : public wxPanel {
+  DECLARE_EVENT_TABLE()
+
+ private:
+  AV1Decoder decoder;
+  const wxString path;
+
+  int zoom;
+  unsigned char *pixels;
+
+  const bool bit_accounting;
+  double *bpp_q3;
+
+  int plane_mask;
+
+  // The display size is the decode size, scaled by the zoom.
+  int getDisplayWidth() const;
+  int getDisplayHeight() const;
+
+  bool updateDisplaySize();
+
+  void computeBitsPerPixel();
+
+ public:
+  AnalyzerPanel(wxWindow *parent, const wxString &path,
+                const bool bit_accounting);
+  ~AnalyzerPanel();
+
+  bool open(const wxString &path);
+  void close();
+  void render();
+  void togglePadding();
+  bool nextFrame();
+  void refresh();
+
+  int getZoom() const;
+  bool setZoom(int zoom);
+
+  void setShowPlane(bool show_plane, int mask);
+
+  void onPaint(wxPaintEvent &event);  // NOLINT
+};
+
+BEGIN_EVENT_TABLE(AnalyzerPanel, wxPanel)
+EVT_PAINT(AnalyzerPanel::onPaint)
+END_EVENT_TABLE()
+
+AnalyzerPanel::AnalyzerPanel(wxWindow *parent, const wxString &path,
+                             const bool bit_accounting)
+    : wxPanel(parent), path(path), zoom(0), pixels(NULL),
+      bit_accounting(bit_accounting), bpp_q3(NULL), plane_mask(OD_ALL_MASK) {}
+
+AnalyzerPanel::~AnalyzerPanel() { close(); }
+
+void AnalyzerPanel::setShowPlane(bool show_plane, int mask) {
+  if (show_plane) {
+    plane_mask |= mask;
+  } else {
+    plane_mask &= ~mask;
+  }
+}
+
+void AnalyzerPanel::render() {
+  aom_image_t *img = decoder.image;
+  int y_stride = img->stride[0];
+  int cb_stride = img->stride[1];
+  int cr_stride = img->stride[2];
+  int p_stride = 3 * getDisplayWidth();
+  unsigned char *y_row = img->planes[0];
+  unsigned char *cb_row = img->planes[1];
+  unsigned char *cr_row = img->planes[2];
+  unsigned char *p_row = pixels;
+  int y_width_padding = decoder.getWidthPadding();
+  int cb_width_padding = y_width_padding >> 1;
+  int cr_width_padding = y_width_padding >> 1;
+  int y_height_padding = decoder.getHeightPadding();
+  int cb_height_padding = y_height_padding >> 1;
+  int cr_height_padding = y_height_padding >> 1;
+  for (int j = 0; j < decoder.getHeight(); j++) {
+    unsigned char *y = y_row - y_stride * y_height_padding;
+    unsigned char *cb = cb_row - cb_stride * cb_height_padding;
+    unsigned char *cr = cr_row - cr_stride * cr_height_padding;
+    unsigned char *p = p_row;
+    for (int i = 0; i < decoder.getWidth(); i++) {
+      int64_t yval;
+      int64_t cbval;
+      int64_t crval;
+      int pmask;
+      unsigned rval;
+      unsigned gval;
+      unsigned bval;
+      yval = *(y - y_width_padding);
+      cbval = *(cb - cb_width_padding);
+      crval = *(cr - cr_width_padding);
+      pmask = plane_mask;
+      if (pmask & OD_LUMA_MASK) {
+        yval -= 16;
+      } else {
+        yval = 128;
+      }
+      cbval = ((pmask & OD_CB_MASK) >> 1) * (cbval - 128);
+      crval = ((pmask & OD_CR_MASK) >> 2) * (crval - 128);
+      /*This is intentionally slow and very accurate.*/
+      rval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
+                              2916394880000LL * yval + 4490222169144LL * crval,
+                              9745792000LL),
+                       65535);
+      gval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(2916394880000LL * yval -
+                                                    534117096223LL * cbval -
+                                                    1334761232047LL * crval,
+                                                9745792000LL),
+                       65535);
+      bval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
+                              2916394880000LL * yval + 5290866304968LL * cbval,
+                              9745792000LL),
+                       65535);
+      unsigned char *px_row = p;
+      for (int v = 0; v < zoom; v++) {
+        unsigned char *px = px_row;
+        for (int u = 0; u < zoom; u++) {
+          *(px + 0) = (unsigned char)(rval >> 8);
+          *(px + 1) = (unsigned char)(gval >> 8);
+          *(px + 2) = (unsigned char)(bval >> 8);
+          px += 3;
+        }
+        px_row += p_stride;
+      }
+      int dc = ((y - y_row) & 1) | (1 - img->x_chroma_shift);
+      y++;
+      cb += dc;
+      cr += dc;
+      p += zoom * 3;
+    }
+    int dc = -((j & 1) | (1 - img->y_chroma_shift));
+    y_row += y_stride;
+    cb_row += dc & cb_stride;
+    cr_row += dc & cr_stride;
+    p_row += zoom * p_stride;
+  }
+}
+
+void AnalyzerPanel::computeBitsPerPixel() {
+  Accounting *acct;
+  double bpp_total;
+  int totals_q3[MAX_SYMBOL_TYPES] = { 0 };
+  int sym_count[MAX_SYMBOL_TYPES] = { 0 };
+  decoder.getAccountingStruct(&acct);
+  for (int j = 0; j < decoder.getHeight(); j++) {
+    for (int i = 0; i < decoder.getWidth(); i++) {
+      bpp_q3[j * decoder.getWidth() + i] = 0.0;
+    }
+  }
+  bpp_total = 0;
+  for (int i = 0; i < acct->syms.num_syms; i++) {
+    AccountingSymbol *s;
+    s = &acct->syms.syms[i];
+    totals_q3[s->id] += s->bits;
+    sym_count[s->id] += s->samples;
+  }
+  printf("=== Frame: %-3i ===\n", decoder.frame - 1);
+  for (int i = 0; i < acct->syms.dictionary.num_strs; i++) {
+    if (totals_q3[i]) {
+      printf("%30s = %10.3f (%f bit/symbol)\n", acct->syms.dictionary.strs[i],
+             (float)totals_q3[i] / 8, (float)totals_q3[i] / 8 / sym_count[i]);
+    }
+  }
+  printf("\n");
+}
+
+void AnalyzerPanel::togglePadding() {
+  decoder.togglePadding();
+  updateDisplaySize();
+}
+
+bool AnalyzerPanel::nextFrame() {
+  if (decoder.step()) {
+    refresh();
+    return true;
+  }
+  return false;
+}
+
+void AnalyzerPanel::refresh() {
+  if (bit_accounting) {
+    computeBitsPerPixel();
+  }
+  render();
+}
+
+int AnalyzerPanel::getDisplayWidth() const { return zoom * decoder.getWidth(); }
+
+int AnalyzerPanel::getDisplayHeight() const {
+  return zoom * decoder.getHeight();
+}
+
+bool AnalyzerPanel::updateDisplaySize() {
+  unsigned char *p = (unsigned char *)malloc(
+      sizeof(*p) * 3 * getDisplayWidth() * getDisplayHeight());
+  if (p == NULL) {
+    return false;
+  }
+  free(pixels);
+  pixels = p;
+  SetSize(getDisplayWidth(), getDisplayHeight());
+  return true;
+}
+
+bool AnalyzerPanel::open(const wxString &path) {
+  if (!decoder.open(path)) {
+    return false;
+  }
+  if (!setZoom(MIN_ZOOM)) {
+    return false;
+  }
+  if (bit_accounting) {
+    bpp_q3 = (double *)malloc(sizeof(*bpp_q3) * decoder.getWidth() *
+                              decoder.getHeight());
+    if (bpp_q3 == NULL) {
+      fprintf(stderr, "Could not allocate memory for bit accounting\n");
+      close();
+      return false;
+    }
+  }
+  if (!nextFrame()) {
+    close();
+    return false;
+  }
+  SetFocus();
+  return true;
+}
+
+void AnalyzerPanel::close() {
+  decoder.close();
+  free(pixels);
+  pixels = NULL;
+  free(bpp_q3);
+  bpp_q3 = NULL;
+}
+
+int AnalyzerPanel::getZoom() const { return zoom; }
+
+bool AnalyzerPanel::setZoom(int z) {
+  if (z <= MAX_ZOOM && z >= MIN_ZOOM && zoom != z) {
+    int old_zoom = zoom;
+    zoom = z;
+    if (!updateDisplaySize()) {
+      zoom = old_zoom;
+      return false;
+    }
+    return true;
+  }
+  return false;
+}
+
+void AnalyzerPanel::onPaint(wxPaintEvent &) {
+  wxBitmap bmp(wxImage(getDisplayWidth(), getDisplayHeight(), pixels, true));
+  wxBufferedPaintDC dc(this, bmp);
+}
+
+class AnalyzerFrame : public wxFrame {
+  DECLARE_EVENT_TABLE()
+
+ private:
+  AnalyzerPanel *panel;
+  const bool bit_accounting;
+
+  wxMenu *fileMenu;
+  wxMenu *viewMenu;
+  wxMenu *playbackMenu;
+
+ public:
+  AnalyzerFrame(const bool bit_accounting);  // NOLINT
+
+  void onOpen(wxCommandEvent &event);   // NOLINT
+  void onClose(wxCommandEvent &event);  // NOLINT
+  void onQuit(wxCommandEvent &event);   // NOLINT
+
+  void onTogglePadding(wxCommandEvent &event);  // NOLINT
+  void onZoomIn(wxCommandEvent &event);         // NOLINT
+  void onZoomOut(wxCommandEvent &event);        // NOLINT
+  void onActualSize(wxCommandEvent &event);     // NOLINT
+
+  void onToggleViewMenuCheckBox(wxCommandEvent &event);          // NOLINT
+  void onResetAndToggleViewMenuCheckBox(wxCommandEvent &event);  // NOLINT
+
+  void onNextFrame(wxCommandEvent &event);  // NOLINT
+  void onGotoFrame(wxCommandEvent &event);  // NOLINT
+  void onRestart(wxCommandEvent &event);    // NOLINT
+
+  void onAbout(wxCommandEvent &event);  // NOLINT
+
+  bool open(const wxString &path);
+  bool setZoom(int zoom);
+  void updateViewMenu();
+};
+
+enum {
+  wxID_NEXT_FRAME = 6000,
+  wxID_SHOW_Y,
+  wxID_SHOW_U,
+  wxID_SHOW_V,
+  wxID_GOTO_FRAME,
+  wxID_RESTART,
+  wxID_ACTUAL_SIZE,
+  wxID_PADDING
+};
+
+BEGIN_EVENT_TABLE(AnalyzerFrame, wxFrame)
+EVT_MENU(wxID_OPEN, AnalyzerFrame::onOpen)
+EVT_MENU(wxID_CLOSE, AnalyzerFrame::onClose)
+EVT_MENU(wxID_EXIT, AnalyzerFrame::onQuit)
+EVT_MENU(wxID_PADDING, AnalyzerFrame::onTogglePadding)
+EVT_MENU(wxID_ZOOM_IN, AnalyzerFrame::onZoomIn)
+EVT_MENU(wxID_ZOOM_OUT, AnalyzerFrame::onZoomOut)
+EVT_MENU(wxID_ACTUAL_SIZE, AnalyzerFrame::onActualSize)
+EVT_MENU(wxID_SHOW_Y, AnalyzerFrame::onResetAndToggleViewMenuCheckBox)
+EVT_MENU(wxID_SHOW_U, AnalyzerFrame::onResetAndToggleViewMenuCheckBox)
+EVT_MENU(wxID_SHOW_V, AnalyzerFrame::onResetAndToggleViewMenuCheckBox)
+EVT_MENU(wxID_NEXT_FRAME, AnalyzerFrame::onNextFrame)
+EVT_MENU(wxID_GOTO_FRAME, AnalyzerFrame::onGotoFrame)
+EVT_MENU(wxID_RESTART, AnalyzerFrame::onRestart)
+EVT_MENU(wxID_ABOUT, AnalyzerFrame::onAbout)
+END_EVENT_TABLE()
+
+AnalyzerFrame::AnalyzerFrame(const bool bit_accounting)
+    : wxFrame(NULL, wxID_ANY, _("AV1 Stream Analyzer"), wxDefaultPosition,
+              wxDefaultSize, wxDEFAULT_FRAME_STYLE),
+      panel(NULL), bit_accounting(bit_accounting) {
+  wxMenuBar *mb = new wxMenuBar();
+
+  fileMenu = new wxMenu();
+  fileMenu->Append(wxID_OPEN, _("&Open...\tCtrl-O"), _("Open daala file"));
+  fileMenu->Append(wxID_CLOSE, _("&Close\tCtrl-W"), _("Close daala file"));
+  fileMenu->Enable(wxID_CLOSE, false);
+  fileMenu->Append(wxID_EXIT, _("E&xit\tCtrl-Q"), _("Quit this program"));
+  mb->Append(fileMenu, _("&File"));
+
+  wxAcceleratorEntry entries[2];
+  entries[0].Set(wxACCEL_CTRL, (int)'=', wxID_ZOOM_IN);
+  entries[1].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'-', wxID_ZOOM_OUT);
+  wxAcceleratorTable accel(2, entries);
+  this->SetAcceleratorTable(accel);
+
+  viewMenu = new wxMenu();
+  +viewMenu->Append(wxID_PADDING, _("Toggle padding\tCtrl-p"),
+                    _("Show padding"));
+  viewMenu->Append(wxID_ZOOM_IN, _("Zoom-In\tCtrl-+"), _("Double image size"));
+  viewMenu->Append(wxID_ZOOM_OUT, _("Zoom-Out\tCtrl--"), _("Half image size"));
+  viewMenu->Append(wxID_ACTUAL_SIZE, _("Actual size\tCtrl-0"),
+                   _("Actual size of the frame"));
+  viewMenu->AppendSeparator();
+  viewMenu->AppendCheckItem(wxID_SHOW_Y, _("&Y plane\tCtrl-Y"),
+                            _("Show Y plane"));
+  viewMenu->AppendCheckItem(wxID_SHOW_U, _("&U plane\tCtrl-U"),
+                            _("Show U plane"));
+  viewMenu->AppendCheckItem(wxID_SHOW_V, _("&V plane\tCtrl-V"),
+                            _("Show V plane"));
+  mb->Append(viewMenu, _("&View"));
+
+  playbackMenu = new wxMenu();
+  playbackMenu->Append(wxID_NEXT_FRAME, _("Next frame\tCtrl-."),
+                       _("Go to next frame"));
+  /*playbackMenu->Append(wxID_RESTART, _("&Restart\tCtrl-R"),
+                       _("Set video to frame 0"));
+  playbackMenu->Append(wxID_GOTO_FRAME, _("Jump to Frame\tCtrl-J"),
+                       _("Go to frame number"));*/
+  mb->Append(playbackMenu, _("&Playback"));
+
+  wxMenu *helpMenu = new wxMenu();
+  helpMenu->Append(wxID_ABOUT, _("&About...\tF1"), _("Show about dialog"));
+  mb->Append(helpMenu, _("&Help"));
+
+  SetMenuBar(mb);
+
+  CreateStatusBar(1);
+}
+
+void AnalyzerFrame::onOpen(wxCommandEvent &WXUNUSED(event)) {
+  wxFileDialog openFileDialog(this, _("Open file"), wxEmptyString,
+                              wxEmptyString, _("AV1 files (*.ivf)|*.ivf"),
+                              wxFD_OPEN | wxFD_FILE_MUST_EXIST);
+  if (openFileDialog.ShowModal() != wxID_CANCEL) {
+    open(openFileDialog.GetPath());
+  }
+}
+
+void AnalyzerFrame::onClose(wxCommandEvent &WXUNUSED(event)) {}
+
+void AnalyzerFrame::onQuit(wxCommandEvent &WXUNUSED(event)) { Close(true); }
+
+void AnalyzerFrame::onTogglePadding(wxCommandEvent &WXUNUSED(event)) {
+  panel->togglePadding();
+  SetClientSize(panel->GetSize());
+  panel->render();
+  panel->Refresh();
+}
+
+void AnalyzerFrame::onZoomIn(wxCommandEvent &WXUNUSED(event)) {
+  setZoom(panel->getZoom() + 1);
+}
+
+void AnalyzerFrame::onZoomOut(wxCommandEvent &WXUNUSED(event)) {
+  setZoom(panel->getZoom() - 1);
+}
+
+void AnalyzerFrame::onActualSize(wxCommandEvent &WXUNUSED(event)) {
+  setZoom(MIN_ZOOM);
+}
+
+void AnalyzerFrame::onToggleViewMenuCheckBox(wxCommandEvent &event) {  // NOLINT
+  GetMenuBar()->Check(event.GetId(), event.IsChecked());
+  updateViewMenu();
+}
+
+void AnalyzerFrame::onResetAndToggleViewMenuCheckBox(
+    wxCommandEvent &event) {  // NOLINT
+  int id = event.GetId();
+  if (id != wxID_SHOW_Y && id != wxID_SHOW_U && id != wxID_SHOW_V) {
+    GetMenuBar()->Check(wxID_SHOW_Y, true);
+    GetMenuBar()->Check(wxID_SHOW_U, true);
+    GetMenuBar()->Check(wxID_SHOW_V, true);
+  }
+  onToggleViewMenuCheckBox(event);
+}
+
+void AnalyzerFrame::onNextFrame(wxCommandEvent &WXUNUSED(event)) {
+  panel->nextFrame();
+  panel->Refresh(false);
+}
+
+void AnalyzerFrame::onGotoFrame(wxCommandEvent &WXUNUSED(event)) {}
+
+void AnalyzerFrame::onRestart(wxCommandEvent &WXUNUSED(event)) {}
+
+void AnalyzerFrame::onAbout(wxCommandEvent &WXUNUSED(event)) {
+  wxAboutDialogInfo info;
+  info.SetName(_("AV1 Bitstream Analyzer"));
+  info.SetVersion(_("0.1-beta"));
+  info.SetDescription(
+      _("This program implements a bitstream analyzer for AV1"));
+  info.SetCopyright(
+      wxT("(C) 2017 Alliance for Open Media <negge@mozilla.com>"));
+  wxAboutBox(info);
+}
+
+bool AnalyzerFrame::open(const wxString &path) {
+  panel = new AnalyzerPanel(this, path, bit_accounting);
+  if (panel->open(path)) {
+    SetClientSize(panel->GetSize());
+    return true;
+  } else {
+    delete panel;
+    return false;
+  }
+}
+
+bool AnalyzerFrame::setZoom(int zoom) {
+  if (panel->setZoom(zoom)) {
+    GetMenuBar()->Enable(wxID_ACTUAL_SIZE, zoom != MIN_ZOOM);
+    GetMenuBar()->Enable(wxID_ZOOM_IN, zoom != MAX_ZOOM);
+    GetMenuBar()->Enable(wxID_ZOOM_OUT, zoom != MIN_ZOOM);
+    SetClientSize(panel->GetSize());
+    panel->render();
+    panel->Refresh();
+    return true;
+  }
+  return false;
+}
+
+void AnalyzerFrame::updateViewMenu() {
+  panel->setShowPlane(GetMenuBar()->IsChecked(wxID_SHOW_Y), OD_LUMA_MASK);
+  panel->setShowPlane(GetMenuBar()->IsChecked(wxID_SHOW_U), OD_CB_MASK);
+  panel->setShowPlane(GetMenuBar()->IsChecked(wxID_SHOW_V), OD_CR_MASK);
+  SetClientSize(panel->GetSize());
+  panel->render();
+  panel->Refresh(false);
+}
+
+class Analyzer : public wxApp {
+ private:
+  AnalyzerFrame *frame;
+
+ public:
+  void OnInitCmdLine(wxCmdLineParser &parser);    // NOLINT
+  bool OnCmdLineParsed(wxCmdLineParser &parser);  // NOLINT
+};
+
+static const wxCmdLineEntryDesc CMD_LINE_DESC[] = {
+  { wxCMD_LINE_SWITCH, _("h"), _("help"), _("Display this help and exit."),
+    wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+  { wxCMD_LINE_SWITCH, _("a"), _("bit-accounting"), _("Enable bit accounting"),
+    wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
+  { wxCMD_LINE_PARAM, NULL, NULL, _("input.ivf"), wxCMD_LINE_VAL_STRING,
+    wxCMD_LINE_PARAM_OPTIONAL },
+  { wxCMD_LINE_NONE }
+};
+
+void Analyzer::OnInitCmdLine(wxCmdLineParser &parser) {  // NOLINT
+  parser.SetDesc(CMD_LINE_DESC);
+  parser.SetSwitchChars(_("-"));
+}
+
+bool Analyzer::OnCmdLineParsed(wxCmdLineParser &parser) {  // NOLINT
+  bool bit_accounting = parser.Found(_("a"));
+  if (bit_accounting && !CONFIG_ACCOUNTING) {
+    fprintf(stderr,
+            "Bit accounting support not found.  "
+            "Recompile with:\n./configure --enable-accounting\n");
+    return false;
+  }
+  frame = new AnalyzerFrame(parser.Found(_("a")));
+  frame->Show();
+  if (parser.GetParamCount() > 0) {
+    return frame->open(parser.GetParam(0));
+  }
+  return true;
+}
+
+void usage_exit(void) {
+  fprintf(stderr, "uhh\n");
+  exit(EXIT_FAILURE);
+}
+
+IMPLEMENT_APP(Analyzer)
diff --git a/third_party/aom/examples/aom_cx_set_ref.c b/third_party/aom/examples/aom_cx_set_ref.c
new file mode 100644
index 000000000..ff24fa14a
--- /dev/null
+++ b/third_party/aom/examples/aom_cx_set_ref.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// AV1 Set Reference Frame
+// ============================
+//
+// This is an example demonstrating how to overwrite the AV1 encoder's
+// internal reference frame. In the sample we set the last frame to the
+// current frame. This technique could be used to bounce between two cameras.
+//
+// The decoder would also have to set the reference frame to the same value
+// on the same frame, or the video will become corrupt. The 'test_decode'
+// variable is set to 1 in this example that tests if the encoder and decoder
+// results are matching.
+//
+// Usage
+// -----
+// This example encodes a raw video. And the last argument passed in specifies
+// the frame number to update the reference frame on. For example, run
+// examples/aom_cx_set_ref av1 352 288 in.yuv out.ivf 4 30
+// The parameter is parsed as follows:
+//
+//
+// Extra Variables
+// ---------------
+// This example maintains the frame number passed on the command line
+// in the `update_frame_num` variable.
+//
+//
+// Configuration
+// -------------
+//
+// The reference frame is updated on the frame specified on the command
+// line.
+//
+// Observing The Effects
+// ---------------------
+// The encoder and decoder results should be matching when the same reference
+// frame setting operation is done in both encoder and decoder. Otherwise,
+// the encoder/decoder mismatch would be seen.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aomcx.h"
+#include "aom/aom_decoder.h"
+#include "aom/aom_encoder.h"
+#include "examples/encoder_util.h"
+#include "./tools_common.h"
+#include "./video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit() {
+  fprintf(stderr,
+          "Usage: %s <codec> <width> <height> <infile> <outfile> "
+          "<frame> <limit(optional)>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
+                           unsigned int frame_out, int *mismatch_seen) {
+  aom_image_t enc_img, dec_img;
+  struct av1_ref_frame ref_enc, ref_dec;
+
+  if (*mismatch_seen) return;
+
+  ref_enc.idx = 0;
+  ref_dec.idx = 0;
+  if (aom_codec_control(encoder, AV1_GET_REFERENCE, &ref_enc))
+    die_codec(encoder, "Failed to get encoder reference frame");
+  enc_img = ref_enc.img;
+  if (aom_codec_control(decoder, AV1_GET_REFERENCE, &ref_dec))
+    die_codec(decoder, "Failed to get decoder reference frame");
+  dec_img = ref_dec.img;
+
+  if (!aom_compare_img(&enc_img, &dec_img)) {
+    int y[4], u[4], v[4];
+
+    *mismatch_seen = 1;
+
+    aom_find_mismatch(&enc_img, &dec_img, y, u, v);
+    printf(
+        "Encode/decode mismatch on frame %d at"
+        " Y[%d, %d] {%d/%d},"
+        " U[%d, %d] {%d/%d},"
+        " V[%d, %d] {%d/%d}",
+        frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
+        v[2], v[3]);
+  }
+
+  aom_img_free(&enc_img);
+  aom_img_free(&dec_img);
+}
+
+static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
+                        unsigned int frame_in, AvxVideoWriter *writer,
+                        int test_decode, aom_codec_ctx_t *dcodec,
+                        unsigned int *frame_out, int *mismatch_seen) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  int got_data;
+  const aom_codec_err_t res =
+      aom_codec_encode(ecodec, img, frame_in, 1, 0, AOM_DL_GOOD_QUALITY);
+  if (res != AOM_CODEC_OK) die_codec(ecodec, "Failed to encode frame");
+
+  got_data = 0;
+
+  while ((pkt = aom_codec_get_cx_data(ecodec, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+
+      if (!(pkt->data.frame.flags & AOM_FRAME_IS_FRAGMENT)) {
+        *frame_out += 1;
+      }
+
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts)) {
+        die_codec(ecodec, "Failed to write compressed frame");
+      }
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+      got_data = 1;
+
+      // Decode 1 frame.
+      if (test_decode) {
+        if (aom_codec_decode(dcodec, pkt->data.frame.buf,
+                             (unsigned int)pkt->data.frame.sz, NULL, 0))
+          die_codec(dcodec, "Failed to decode frame.");
+      }
+    }
+  }
+
+  // Mismatch checking
+  if (got_data && test_decode) {
+    testing_decode(ecodec, dcodec, *frame_out, mismatch_seen);
+  }
+
+  return got_pkts;
+}
+
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  // Encoder
+  aom_codec_ctx_t ecodec;
+  aom_codec_enc_cfg_t cfg;
+  unsigned int frame_in = 0;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  AvxVideoInfo info;
+  AvxVideoWriter *writer = NULL;
+  const AvxInterface *encoder = NULL;
+
+  // Test encoder/decoder mismatch.
+  int test_decode = 1;
+  // Decoder
+  aom_codec_ctx_t dcodec;
+  unsigned int frame_out = 0;
+
+  // The frame number to set reference frame on
+  unsigned int update_frame_num = 0;
+  int mismatch_seen = 0;
+
+  const int fps = 30;
+  const int bitrate = 500;
+
+  const char *codec_arg = NULL;
+  const char *width_arg = NULL;
+  const char *height_arg = NULL;
+  const char *infile_arg = NULL;
+  const char *outfile_arg = NULL;
+  const char *update_frame_num_arg = NULL;
+  unsigned int limit = 0;
+  exec_name = argv[0];
+
+  // Clear explicitly, as simply assigning "{ 0 }" generates
+  // "missing-field-initializers" warning in some compilers.
+  memset(&ecodec, 0, sizeof(ecodec));
+  memset(&cfg, 0, sizeof(cfg));
+  memset(&info, 0, sizeof(info));
+
+  if (argc < 7) die("Invalid number of arguments");
+
+  codec_arg = argv[1];
+  width_arg = argv[2];
+  height_arg = argv[3];
+  infile_arg = argv[4];
+  outfile_arg = argv[5];
+  update_frame_num_arg = argv[6];
+
+  encoder = get_aom_encoder_by_name(codec_arg);
+  if (!encoder) die("Unsupported codec.");
+
+  update_frame_num = (unsigned int)strtoul(update_frame_num_arg, NULL, 0);
+  // In AV1, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
+  // allocated while calling aom_codec_encode(), thus, setting reference for
+  // 1st frame isn't supported.
+  if (update_frame_num <= 1) {
+    die("Couldn't parse frame number '%s'\n", update_frame_num_arg);
+  }
+
+  if (argc > 7) {
+    limit = (unsigned int)strtoul(argv[7], NULL, 0);
+    if (update_frame_num > limit)
+      die("Update frame number couldn't larger than limit\n");
+  }
+
+  info.codec_fourcc = encoder->fourcc;
+  info.frame_width = (int)strtol(width_arg, NULL, 0);
+  info.frame_height = (int)strtol(height_arg, NULL, 0);
+  info.time_base.numerator = 1;
+  info.time_base.denominator = fps;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image.");
+  }
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&ecodec, "Failed to get default codec config.");
+
+  cfg.g_w = info.frame_width;
+  cfg.g_h = info.frame_height;
+  cfg.g_timebase.num = info.time_base.numerator;
+  cfg.g_timebase.den = info.time_base.denominator;
+  cfg.rc_target_bitrate = bitrate;
+  cfg.g_lag_in_frames = 3;
+
+  writer = aom_video_writer_open(outfile_arg, kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing.", outfile_arg);
+
+  if (!(infile = fopen(infile_arg, "rb")))
+    die("Failed to open %s for reading.", infile_arg);
+
+  if (aom_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
+    die_codec(&ecodec, "Failed to initialize encoder");
+
+  // Disable alt_ref.
+  if (aom_codec_control(&ecodec, AOME_SET_ENABLEAUTOALTREF, 0))
+    die_codec(&ecodec, "Failed to set enable auto alt ref");
+
+  if (test_decode) {
+    const AvxInterface *decoder = get_aom_decoder_by_name(codec_arg);
+    if (aom_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
+      die_codec(&dcodec, "Failed to initialize decoder.");
+  }
+
+  // Encode frames.
+  while (aom_img_read(&raw, infile)) {
+    if (limit && frame_in >= limit) break;
+    if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
+      aom_ref_frame_t ref;
+      ref.frame_type = AOM_LAST_FRAME;
+      ref.img = raw;
+      // Set reference frame in encoder.
+      if (aom_codec_control(&ecodec, AOM_SET_REFERENCE, &ref))
+        die_codec(&ecodec, "Failed to set reference frame");
+      printf(" <SET_REF>");
+
+      // If set_reference in decoder is commented out, the enc/dec mismatch
+      // would be seen.
+      if (test_decode) {
+        if (aom_codec_control(&dcodec, AOM_SET_REFERENCE, &ref))
+          die_codec(&dcodec, "Failed to set reference frame");
+      }
+    }
+
+    encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
+                 &frame_out, &mismatch_seen);
+    frame_in++;
+    if (mismatch_seen) break;
+  }
+
+  // Flush encoder.
+  if (!mismatch_seen)
+    while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
+                        &frame_out, &mismatch_seen)) {
+    }
+
+  printf("\n");
+  fclose(infile);
+  printf("Processed %d frames.\n", frame_out);
+
+  if (test_decode) {
+    if (!mismatch_seen)
+      printf("Encoder/decoder results are matching.\n");
+    else
+      printf("Encoder/decoder results are NOT matching.\n");
+  }
+
+  if (test_decode)
+    if (aom_codec_destroy(&dcodec))
+      die_codec(&dcodec, "Failed to destroy decoder");
+
+  aom_img_free(&raw);
+  if (aom_codec_destroy(&ecodec))
+    die_codec(&ecodec, "Failed to destroy encoder.");
+
+  aom_video_writer_close(writer);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/decode_to_md5.c b/third_party/aom/examples/decode_to_md5.c
new file mode 100644
index 000000000..5ab253209
--- /dev/null
+++ b/third_party/aom/examples/decode_to_md5.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Frame-by-frame MD5 Checksum
+// ===========================
+//
+// This example builds upon the simple decoder loop to show how checksums
+// of the decoded output can be generated. These are used for validating
+// decoder implementations against the reference implementation, for example.
+//
+// MD5 algorithm
+// -------------
+// The Message-Digest 5 (MD5) is a well known hash function. We have provided
+// an implementation derived from the RSA Data Security, Inc. MD5 Message-Digest
+// Algorithm for your use. Our implmentation only changes the interface of this
+// reference code. You must include the `md5_utils.h` header for access to these
+// functions.
+//
+// Processing The Decoded Data
+// ---------------------------
+// Each row of the image is passed to the MD5 accumulator. First the Y plane
+// is processed, then U, then V. It is important to honor the image's `stride`
+// values.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aomdx.h"
+#include "aom/aom_decoder.h"
+
+#include "../md5_utils.h"
+#include "../tools_common.h"
+#include "../video_reader.h"
+#include "./aom_config.h"
+
+static void get_image_md5(const aom_image_t *img, unsigned char digest[16]) {
+  int plane, y;
+  MD5Context md5;
+
+  MD5Init(&md5);
+
+  for (plane = 0; plane < 3; ++plane) {
+    const unsigned char *buf = img->planes[plane];
+    const int stride = img->stride[plane];
+    const int w = plane ? (img->d_w + 1) >> 1 : img->d_w;
+    const int h = plane ? (img->d_h + 1) >> 1 : img->d_h;
+
+    for (y = 0; y < h; ++y) {
+      MD5Update(&md5, buf, w);
+      buf += stride;
+    }
+  }
+
+  MD5Final(digest, &md5);
+}
+
+static void print_md5(FILE *stream, unsigned char digest[16]) {
+  int i;
+
+  for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]);
+}
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  int frame_cnt = 0;
+  FILE *outfile = NULL;
+  aom_codec_ctx_t codec;
+  AvxVideoReader *reader = NULL;
+  const AvxVideoInfo *info = NULL;
+  const AvxInterface *decoder = NULL;
+
+  exec_name = argv[0];
+
+  if (argc != 3) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  if (!(outfile = fopen(argv[2], "wb")))
+    die("Failed to open %s for writing.", argv[2]);
+
+  info = aom_video_reader_get_info(reader);
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder");
+
+  while (aom_video_reader_read_frame(reader)) {
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    size_t frame_size = 0;
+    const unsigned char *frame =
+        aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+      die_codec(&codec, "Failed to decode frame");
+
+    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+      unsigned char digest[16];
+
+      get_image_md5(img, digest);
+      print_md5(outfile, digest);
+      fprintf(outfile, "  img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
+              ++frame_cnt);
+    }
+  }
+
+  printf("Processed %d frames.\n", frame_cnt);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_reader_close(reader);
+
+  fclose(outfile);
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/decode_with_drops.c b/third_party/aom/examples/decode_with_drops.c
new file mode 100644
index 000000000..45e0fb027
--- /dev/null
+++ b/third_party/aom/examples/decode_with_drops.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Decode With Drops Example
+// =========================
+//
+// This is an example utility which drops a series of frames, as specified
+// on the command line. This is useful for observing the error recovery
+// features of the codec.
+//
+// Usage
+// -----
+// This example adds a single argument to the `simple_decoder` example,
+// which specifies the range or pattern of frames to drop. The parameter is
+// parsed as follows:
+//
+// Dropping A Range Of Frames
+// --------------------------
+// To drop a range of frames, specify the starting frame and the ending
+// frame to drop, separated by a dash. The following command will drop
+// frames 5 through 10 (base 1).
+//
+//  $ ./decode_with_drops in.ivf out.i420 5-10
+//
+//
+// Dropping A Pattern Of Frames
+// ----------------------------
+// To drop a pattern of frames, specify the number of frames to drop and
+// the number of frames after which to repeat the pattern, separated by
+// a forward-slash. The following command will drop 3 of 7 frames.
+// Specifically, it will decode 4 frames, then drop 3 frames, and then
+// repeat.
+//
+//  $ ./decode_with_drops in.ivf out.i420 3/7
+//
+//
+// Extra Variables
+// ---------------
+// This example maintains the pattern passed on the command line in the
+// `n`, `m`, and `is_range` variables:
+//
+//
+// Making The Drop Decision
+// ------------------------
+// The example decides whether to drop the frame based on the current
+// frame number, immediately before decoding the frame.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aomdx.h"
+#include "aom/aom_decoder.h"
+
+#include "../tools_common.h"
+#include "../video_reader.h"
+#include "./aom_config.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name);
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  int frame_cnt = 0;
+  FILE *outfile = NULL;
+  aom_codec_ctx_t codec;
+  const AvxInterface *decoder = NULL;
+  AvxVideoReader *reader = NULL;
+  const AvxVideoInfo *info = NULL;
+  int n = 0;
+  int m = 0;
+  int is_range = 0;
+  char *nptr = NULL;
+
+  exec_name = argv[0];
+
+  if (argc != 4) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  if (!(outfile = fopen(argv[2], "wb")))
+    die("Failed to open %s for writing.", argv[2]);
+
+  n = (int)strtol(argv[3], &nptr, 0);
+  m = (int)strtol(nptr + 1, NULL, 0);
+  is_range = (*nptr == '-');
+  if (!n || !m || (*nptr != '-' && *nptr != '/'))
+    die("Couldn't parse pattern %s.\n", argv[3]);
+
+  info = aom_video_reader_get_info(reader);
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  while (aom_video_reader_read_frame(reader)) {
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    size_t frame_size = 0;
+    int skip;
+    const unsigned char *frame =
+        aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+      die_codec(&codec, "Failed to decode frame.");
+
+    ++frame_cnt;
+
+    skip = (is_range && frame_cnt >= n && frame_cnt <= m) ||
+           (!is_range && m - (frame_cnt - 1) % m <= n);
+
+    if (!skip) {
+      putc('.', stdout);
+
+      while ((img = aom_codec_get_frame(&codec, &iter)) != NULL)
+        aom_img_write(img, outfile);
+    } else {
+      putc('X', stdout);
+    }
+
+    fflush(stdout);
+  }
+
+  printf("Processed %d frames.\n", frame_cnt);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
+         info->frame_width, info->frame_height, argv[2]);
+
+  aom_video_reader_close(reader);
+  fclose(outfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/encoder_util.c b/third_party/aom/examples/encoder_util.c
new file mode 100644
index 000000000..1aa3a7eef
--- /dev/null
+++ b/third_party/aom/examples/encoder_util.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Utility functions used by encoder binaries.
+
+#include <assert.h>
+#include <string.h>
+
+#include "./encoder_util.h"
+#include "aom/aom_integer.h"
+
+#define mmin(a, b) ((a) < (b) ? (a) : (b))
+
+static void find_mismatch_plane(const aom_image_t *const img1,
+                                const aom_image_t *const img2, int plane,
+                                int use_highbitdepth, int loc[4]) {
+  const unsigned char *const p1 = img1->planes[plane];
+  const int p1_stride = img1->stride[plane] >> use_highbitdepth;
+  const unsigned char *const p2 = img2->planes[plane];
+  const int p2_stride = img2->stride[plane] >> use_highbitdepth;
+  const uint32_t bsize = 64;
+  const int is_y_plane = (plane == AOM_PLANE_Y);
+  const uint32_t bsizex = is_y_plane ? bsize : bsize >> img1->x_chroma_shift;
+  const uint32_t bsizey = is_y_plane ? bsize : bsize >> img1->y_chroma_shift;
+  const uint32_t c_w =
+      is_y_plane ? img1->d_w
+                 : (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
+  const uint32_t c_h =
+      is_y_plane ? img1->d_h
+                 : (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
+  assert(img1->d_w == img2->d_w && img1->d_h == img2->d_h);
+  assert(img1->x_chroma_shift == img2->x_chroma_shift &&
+         img1->y_chroma_shift == img2->y_chroma_shift);
+  loc[0] = loc[1] = loc[2] = loc[3] = -1;
+  int match = 1;
+  uint32_t i, j;
+  for (i = 0; match && i < c_h; i += bsizey) {
+    for (j = 0; match && j < c_w; j += bsizex) {
+      const int si =
+          is_y_plane ? mmin(i + bsizey, c_h) - i : mmin(i + bsizey, c_h - i);
+      const int sj =
+          is_y_plane ? mmin(j + bsizex, c_w) - j : mmin(j + bsizex, c_w - j);
+      int k, l;
+      for (k = 0; match && k < si; ++k) {
+        for (l = 0; match && l < sj; ++l) {
+          const int row = i + k;
+          const int col = j + l;
+          const int offset1 = row * p1_stride + col;
+          const int offset2 = row * p2_stride + col;
+          const int val1 = use_highbitdepth
+                               ? p1[2 * offset1] | (p1[2 * offset1 + 1] << 8)
+                               : p1[offset1];
+          const int val2 = use_highbitdepth
+                               ? p2[2 * offset2] | (p2[2 * offset2 + 1] << 8)
+                               : p2[offset2];
+          if (val1 != val2) {
+            loc[0] = row;
+            loc[1] = col;
+            loc[2] = val1;
+            loc[3] = val2;
+            match = 0;
+            break;
+          }
+        }
+      }
+    }
+  }
+}
+
+static void find_mismatch_helper(const aom_image_t *const img1,
+                                 const aom_image_t *const img2,
+                                 int use_highbitdepth, int yloc[4], int uloc[4],
+                                 int vloc[4]) {
+#if !CONFIG_HIGHBITDEPTH
+  assert(!use_highbitdepth);
+#endif  // !CONFIG_HIGHBITDEPTH
+  find_mismatch_plane(img1, img2, AOM_PLANE_Y, use_highbitdepth, yloc);
+  find_mismatch_plane(img1, img2, AOM_PLANE_U, use_highbitdepth, uloc);
+  find_mismatch_plane(img1, img2, AOM_PLANE_V, use_highbitdepth, vloc);
+}
+
+#if CONFIG_HIGHBITDEPTH
+void aom_find_mismatch_high(const aom_image_t *const img1,
+                            const aom_image_t *const img2, int yloc[4],
+                            int uloc[4], int vloc[4]) {
+  find_mismatch_helper(img1, img2, 1, yloc, uloc, vloc);
+}
+#endif
+
+void aom_find_mismatch(const aom_image_t *const img1,
+                       const aom_image_t *const img2, int yloc[4], int uloc[4],
+                       int vloc[4]) {
+  find_mismatch_helper(img1, img2, 0, yloc, uloc, vloc);
+}
+
+int aom_compare_img(const aom_image_t *const img1,
+                    const aom_image_t *const img2) {
+  uint32_t l_w = img1->d_w;
+  uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
+  const uint32_t c_h =
+      (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
+  uint32_t i;
+  int match = 1;
+
+  match &= (img1->fmt == img2->fmt);
+  match &= (img1->d_w == img2->d_w);
+  match &= (img1->d_h == img2->d_h);
+#if CONFIG_HIGHBITDEPTH
+  if (img1->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
+    l_w *= 2;
+    c_w *= 2;
+  }
+#endif
+
+  for (i = 0; i < img1->d_h; ++i)
+    match &= (memcmp(img1->planes[AOM_PLANE_Y] + i * img1->stride[AOM_PLANE_Y],
+                     img2->planes[AOM_PLANE_Y] + i * img2->stride[AOM_PLANE_Y],
+                     l_w) == 0);
+
+  for (i = 0; i < c_h; ++i)
+    match &= (memcmp(img1->planes[AOM_PLANE_U] + i * img1->stride[AOM_PLANE_U],
+                     img2->planes[AOM_PLANE_U] + i * img2->stride[AOM_PLANE_U],
+                     c_w) == 0);
+
+  for (i = 0; i < c_h; ++i)
+    match &= (memcmp(img1->planes[AOM_PLANE_V] + i * img1->stride[AOM_PLANE_V],
+                     img2->planes[AOM_PLANE_V] + i * img2->stride[AOM_PLANE_V],
+                     c_w) == 0);
+
+  return match;
+}
diff --git a/third_party/aom/examples/encoder_util.h b/third_party/aom/examples/encoder_util.h
new file mode 100644
index 000000000..38deef03d
--- /dev/null
+++ b/third_party/aom/examples/encoder_util.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Utility functions used by encoder binaries.
+
+#ifndef EXAMPLES_ENCODER_UTIL_H_
+#define EXAMPLES_ENCODER_UTIL_H_
+
+#include "./aom_config.h"
+#include "aom/aom_image.h"
+
+// Returns mismatch location (?loc[0],?loc[1]) and the values at that location
+// in img1 (?loc[2]) and img2 (?loc[3]).
+#if CONFIG_HIGHBITDEPTH
+void aom_find_mismatch_high(const aom_image_t *const img1,
+                            const aom_image_t *const img2, int yloc[4],
+                            int uloc[4], int vloc[4]);
+#endif  // CONFIG_HIGHBITDEPTH
+
+void aom_find_mismatch(const aom_image_t *const img1,
+                       const aom_image_t *const img2, int yloc[4], int uloc[4],
+                       int vloc[4]);
+
+// Returns 1 if the two images match.
+int aom_compare_img(const aom_image_t *const img1,
+                    const aom_image_t *const img2);
+
+#endif  // EXAMPLES_ENCODER_UTIL_H_
diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
new file mode 100644
index 000000000..345c0884d
--- /dev/null
+++ b/third_party/aom/examples/inspect.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Inspect Decoder
+// ================
+//
+// This is a simple decoder loop that writes JSON stats to stdout. This tool
+// can also be compiled with Emscripten and used as a library.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./args.h"
+#ifdef __EMSCRIPTEN__
+#include <emscripten.h>
+#else
+#define EMSCRIPTEN_KEEPALIVE
+#endif
+
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+
+#include "../tools_common.h"
+#include "../video_reader.h"
+#include "./aom_config.h"
+// #include "av1/av1_dx_iface.c"
+#include "../av1/common/onyxc_int.h"
+#if CONFIG_ACCOUNTING
+#include "../av1/decoder/accounting.h"
+#endif
+#include "../av1/decoder/inspection.h"
+
+#include "../video_common.h"
+
+// Max JSON buffer size.
+const int MAX_BUFFER = 1024 * 1024 * 32;
+
+typedef enum {
+  ACCOUNTING_LAYER = 1,
+  BLOCK_SIZE_LAYER = 1 << 1,
+  TRANSFORM_SIZE_LAYER = 1 << 2,
+  TRANSFORM_TYPE_LAYER = 1 << 3,
+  MODE_LAYER = 1 << 4,
+  SKIP_LAYER = 1 << 5,
+  FILTER_LAYER = 1 << 6,
+  CDEF_LAYER = 1 << 7,
+  REFERENCE_FRAME_LAYER = 1 << 8,
+  MOTION_VECTORS_LAYER = 1 << 9,
+  UV_MODE_LAYER = 1 << 10,
+  ALL_LAYERS = (1 << 11) - 1
+} LayerType;
+
+static LayerType layers = 0;
+
+static int stop_after = 0;
+static int compress = 0;
+
+static const arg_def_t limit_arg =
+    ARG_DEF(NULL, "limit", 1, "Stop decoding after n frames");
+static const arg_def_t dump_all_arg = ARG_DEF("A", "all", 0, "Dump All");
+static const arg_def_t compress_arg =
+    ARG_DEF("x", "compress", 0, "Compress JSON using RLE");
+static const arg_def_t dump_accounting_arg =
+    ARG_DEF("a", "accounting", 0, "Dump Accounting");
+static const arg_def_t dump_block_size_arg =
+    ARG_DEF("bs", "blockSize", 0, "Dump Block Size");
+static const arg_def_t dump_motion_vectors_arg =
+    ARG_DEF("mv", "motionVectors", 0, "Dump Motion Vectors");
+static const arg_def_t dump_transform_size_arg =
+    ARG_DEF("ts", "transformSize", 0, "Dump Transform Size");
+static const arg_def_t dump_transform_type_arg =
+    ARG_DEF("tt", "transformType", 0, "Dump Transform Type");
+static const arg_def_t dump_mode_arg = ARG_DEF("m", "mode", 0, "Dump Mode");
+static const arg_def_t dump_uv_mode_arg =
+    ARG_DEF("uvm", "uv_mode", 0, "Dump UV Intra Prediction Modes");
+static const arg_def_t dump_skip_arg = ARG_DEF("s", "skip", 0, "Dump Skip");
+static const arg_def_t dump_filter_arg =
+    ARG_DEF("f", "filter", 0, "Dump Filter");
+static const arg_def_t dump_cdef_arg = ARG_DEF("c", "cdef", 0, "Dump CDEF");
+static const arg_def_t dump_reference_frame_arg =
+    ARG_DEF("r", "referenceFrame", 0, "Dump Reference Frame");
+static const arg_def_t usage_arg = ARG_DEF("h", "help", 0, "Help");
+
+static const arg_def_t *main_args[] = { &limit_arg,
+                                        &dump_all_arg,
+                                        &compress_arg,
+#if CONFIG_ACCOUNTING
+                                        &dump_accounting_arg,
+#endif
+                                        &dump_block_size_arg,
+                                        &dump_transform_size_arg,
+                                        &dump_transform_type_arg,
+                                        &dump_mode_arg,
+                                        &dump_uv_mode_arg,
+                                        &dump_skip_arg,
+                                        &dump_filter_arg,
+#if CONFIG_CDEF
+                                        &dump_cdef_arg,
+#endif
+                                        &dump_reference_frame_arg,
+                                        &dump_motion_vectors_arg,
+                                        &usage_arg,
+                                        NULL };
+#define ENUM(name) \
+  { #name, name }
+#define LAST_ENUM \
+  { NULL, 0 }
+typedef struct map_entry {
+  const char *name;
+  int value;
+} map_entry;
+
+const map_entry refs_map[] = { ENUM(INTRA_FRAME),  ENUM(LAST_FRAME),
+#if CONFIG_EXT_REFS
+                               ENUM(LAST2_FRAME),  ENUM(LAST3_FRAME),
+                               ENUM(GOLDEN_FRAME), ENUM(BWDREF_FRAME),
+                               ENUM(ALTREF_FRAME),
+#else
+                               ENUM(GOLDEN_FRAME), ENUM(ALTREF_FRAME),
+#endif
+                               LAST_ENUM };
+
+const map_entry block_size_map[] = {
+#if CONFIG_CB4X4
+  ENUM(BLOCK_2X2),    ENUM(BLOCK_2X4),    ENUM(BLOCK_4X2),
+#endif
+  ENUM(BLOCK_4X4),    ENUM(BLOCK_4X8),    ENUM(BLOCK_8X4),
+  ENUM(BLOCK_8X8),    ENUM(BLOCK_8X16),   ENUM(BLOCK_16X8),
+  ENUM(BLOCK_16X16),  ENUM(BLOCK_16X32),  ENUM(BLOCK_32X16),
+  ENUM(BLOCK_32X32),  ENUM(BLOCK_32X64),  ENUM(BLOCK_64X32),
+  ENUM(BLOCK_64X64),
+#if CONFIG_EXT_PARTITION
+  ENUM(BLOCK_64X128), ENUM(BLOCK_128X64), ENUM(BLOCK_128X128),
+#endif
+  LAST_ENUM
+};
+
+const map_entry tx_size_map[] = {
+#if CONFIG_CB4X4
+  ENUM(TX_2X2),
+#endif
+  ENUM(TX_4X4),   ENUM(TX_8X8),   ENUM(TX_16X16), ENUM(TX_32X32),
+#if CONFIG_TX64X64
+  ENUM(TX_64X64),
+#endif
+  ENUM(TX_4X8),   ENUM(TX_8X4),   ENUM(TX_8X16),  ENUM(TX_16X8),
+  ENUM(TX_16X32), ENUM(TX_32X16), ENUM(TX_4X16),  ENUM(TX_16X4),
+  ENUM(TX_8X32),  ENUM(TX_32X8),  LAST_ENUM
+};
+
+const map_entry tx_type_map[] = { ENUM(DCT_DCT),
+                                  ENUM(ADST_DCT),
+                                  ENUM(DCT_ADST),
+                                  ENUM(ADST_ADST),
+#if CONFIG_EXT_TX
+                                  ENUM(FLIPADST_DCT),
+                                  ENUM(DCT_FLIPADST),
+                                  ENUM(FLIPADST_FLIPADST),
+                                  ENUM(ADST_FLIPADST),
+                                  ENUM(FLIPADST_ADST),
+                                  ENUM(IDTX),
+                                  ENUM(V_DCT),
+                                  ENUM(H_DCT),
+                                  ENUM(V_ADST),
+                                  ENUM(H_ADST),
+                                  ENUM(V_FLIPADST),
+                                  ENUM(H_FLIPADST),
+#endif
+                                  LAST_ENUM };
+
+const map_entry prediction_mode_map[] = {
+  ENUM(DC_PRED),        ENUM(V_PRED),
+  ENUM(H_PRED),         ENUM(D45_PRED),
+  ENUM(D135_PRED),      ENUM(D117_PRED),
+  ENUM(D153_PRED),      ENUM(D207_PRED),
+  ENUM(D63_PRED),
+#if CONFIG_ALT_INTRA
+  ENUM(SMOOTH_PRED),
+#endif
+  ENUM(TM_PRED),        ENUM(NEARESTMV),
+  ENUM(NEARMV),         ENUM(ZEROMV),
+  ENUM(NEWMV),
+#if CONFIG_EXT_INTER
+  ENUM(NEWFROMNEARMV),  ENUM(NEAREST_NEARESTMV),
+  ENUM(NEAREST_NEARMV), ENUM(NEAR_NEARESTMV),
+  ENUM(NEAR_NEARMV),    ENUM(NEAREST_NEWMV),
+  ENUM(NEW_NEARESTMV),  ENUM(NEAR_NEWMV),
+  ENUM(NEW_NEARMV),     ENUM(ZERO_ZEROMV),
+  ENUM(NEW_NEWMV),
+#endif
+  ENUM(INTRA_INVALID),  LAST_ENUM
+};
+
+#define NO_SKIP 0
+#define SKIP 1
+
+const map_entry skip_map[] = { ENUM(SKIP), ENUM(NO_SKIP), LAST_ENUM };
+
+const map_entry config_map[] = { ENUM(MI_SIZE), LAST_ENUM };
+
+static const char *exec_name;
+
+insp_frame_data frame_data;
+int frame_count = 0;
+int decoded_frame_count = 0;
+aom_codec_ctx_t codec;
+AvxVideoReader *reader = NULL;
+const AvxVideoInfo *info = NULL;
+aom_image_t *img = NULL;
+
+void on_frame_decoded_dump(char *json) {
+#ifdef __EMSCRIPTEN__
+  EM_ASM_({ Module.on_frame_decoded_json($0); }, json);
+#else
+  printf("%s", json);
+#endif
+}
+
+// Writing out the JSON buffer using snprintf is very slow, especially when
+// compiled with emscripten, these functions speed things up quite a bit.
+int put_str(char *buffer, const char *str) {
+  int i;
+  for (i = 0; str[i] != '\0'; i++) {
+    buffer[i] = str[i];
+  }
+  return i;
+}
+
+int put_num(char *buffer, char prefix, int num, char suffix) {
+  int i = 0;
+  char *buf = buffer;
+  int is_neg = 0;
+  if (prefix) {
+    buf[i++] = prefix;
+  }
+  if (num == 0) {
+    buf[i++] = '0';
+  } else {
+    if (num < 0) {
+      num = -num;
+      is_neg = 1;
+    }
+    int s = i;
+    while (num != 0) {
+      buf[i++] = '0' + (num % 10);
+      num = num / 10;
+    }
+    if (is_neg) {
+      buf[i++] = '-';
+    }
+    int e = i - 1;
+    while (s < e) {
+      int t = buf[s];
+      buf[s] = buf[e];
+      buf[e] = t;
+      s++;
+      e--;
+    }
+  }
+  if (suffix) {
+    buf[i++] = suffix;
+  }
+  return i;
+}
+
+int put_map(char *buffer, const map_entry *map) {
+  char *buf = buffer;
+  const map_entry *entry = map;
+  while (entry->name != NULL) {
+    *(buf++) = '"';
+    buf += put_str(buf, entry->name);
+    *(buf++) = '"';
+    buf += put_num(buf, ':', entry->value, 0);
+    entry++;
+    if (entry->name != NULL) {
+      *(buf++) = ',';
+    }
+  }
+  return buf - buffer;
+}
+
+int put_reference_frame(char *buffer) {
+  const int mi_rows = frame_data.mi_rows;
+  const int mi_cols = frame_data.mi_cols;
+  char *buf = buffer;
+  int r, c, t;
+  buf += put_str(buf, "  \"referenceFrameMap\": {");
+  buf += put_map(buf, refs_map);
+  buf += put_str(buf, "},\n");
+  buf += put_str(buf, "  \"referenceFrame\": [");
+  for (r = 0; r < mi_rows; ++r) {
+    *(buf++) = '[';
+    for (c = 0; c < mi_cols; ++c) {
+      insp_mi_data *mi = &frame_data.mi_grid[r * mi_cols + c];
+      buf += put_num(buf, '[', mi->ref_frame[0], 0);
+      buf += put_num(buf, ',', mi->ref_frame[1], ']');
+      if (compress) {  // RLE
+        for (t = c + 1; t < mi_cols; ++t) {
+          insp_mi_data *next_mi = &frame_data.mi_grid[r * mi_cols + t];
+          if (mi->ref_frame[0] != next_mi->ref_frame[0] ||
+              mi->ref_frame[1] != next_mi->ref_frame[1]) {
+            break;
+          }
+        }
+        if (t - c > 1) {
+          *(buf++) = ',';
+          buf += put_num(buf, '[', t - c - 1, ']');
+          c = t - 1;
+        }
+      }
+      if (c < mi_cols - 1) *(buf++) = ',';
+    }
+    *(buf++) = ']';
+    if (r < mi_rows - 1) *(buf++) = ',';
+  }
+  buf += put_str(buf, "],\n");
+  return buf - buffer;
+}
+
+int put_motion_vectors(char *buffer) {
+  const int mi_rows = frame_data.mi_rows;
+  const int mi_cols = frame_data.mi_cols;
+  char *buf = buffer;
+  int r, c, t;
+  buf += put_str(buf, "  \"motionVectors\": [");
+  for (r = 0; r < mi_rows; ++r) {
+    *(buf++) = '[';
+    for (c = 0; c < mi_cols; ++c) {
+      insp_mi_data *mi = &frame_data.mi_grid[r * mi_cols + c];
+      buf += put_num(buf, '[', mi->mv[0].col, 0);
+      buf += put_num(buf, ',', mi->mv[0].row, 0);
+      buf += put_num(buf, ',', mi->mv[1].col, 0);
+      buf += put_num(buf, ',', mi->mv[1].row, ']');
+      if (compress) {  // RLE
+        for (t = c + 1; t < mi_cols; ++t) {
+          insp_mi_data *next_mi = &frame_data.mi_grid[r * mi_cols + t];
+          if (mi->mv[0].col != next_mi->mv[0].col ||
+              mi->mv[0].row != next_mi->mv[0].row ||
+              mi->mv[1].col != next_mi->mv[1].col ||
+              mi->mv[1].row != next_mi->mv[1].row) {
+            break;
+          }
+        }
+        if (t - c > 1) {
+          *(buf++) = ',';
+          buf += put_num(buf, '[', t - c - 1, ']');
+          c = t - 1;
+        }
+      }
+      if (c < mi_cols - 1) *(buf++) = ',';
+    }
+    *(buf++) = ']';
+    if (r < mi_rows - 1) *(buf++) = ',';
+  }
+  buf += put_str(buf, "],\n");
+  return buf - buffer;
+}
+
+int put_block_info(char *buffer, const map_entry *map, const char *name,
+                   size_t offset) {
+  const int mi_rows = frame_data.mi_rows;
+  const int mi_cols = frame_data.mi_cols;
+  char *buf = buffer;
+  int r, c, t, v;
+  if (map) {
+    buf += snprintf(buf, MAX_BUFFER, "  \"%sMap\": {", name);
+    buf += put_map(buf, map);
+    buf += put_str(buf, "},\n");
+  }
+  buf += snprintf(buf, MAX_BUFFER, "  \"%s\": [", name);
+  for (r = 0; r < mi_rows; ++r) {
+    *(buf++) = '[';
+    for (c = 0; c < mi_cols; ++c) {
+      insp_mi_data *curr_mi = &frame_data.mi_grid[r * mi_cols + c];
+      v = *(((int8_t *)curr_mi) + offset);
+      buf += put_num(buf, 0, v, 0);
+      if (compress) {  // RLE
+        for (t = c + 1; t < mi_cols; ++t) {
+          insp_mi_data *next_mi = &frame_data.mi_grid[r * mi_cols + t];
+          if (v != *(((int8_t *)next_mi) + offset)) {
+            break;
+          }
+        }
+        if (t - c > 1) {
+          *(buf++) = ',';
+          buf += put_num(buf, '[', t - c - 1, ']');
+          c = t - 1;
+        }
+      }
+      if (c < mi_cols - 1) *(buf++) = ',';
+    }
+    *(buf++) = ']';
+    if (r < mi_rows - 1) *(buf++) = ',';
+  }
+  buf += put_str(buf, "],\n");
+  return buf - buffer;
+}
+
+#if CONFIG_ACCOUNTING
+int put_accounting(char *buffer) {
+  char *buf = buffer;
+  int i;
+  const Accounting *accounting = frame_data.accounting;
+  if (accounting == NULL) {
+    printf("XXX\n");
+    return 0;
+  }
+  const int num_syms = accounting->syms.num_syms;
+  const int num_strs = accounting->syms.dictionary.num_strs;
+  buf += put_str(buf, "  \"symbolsMap\": [");
+  for (i = 0; i < num_strs; i++) {
+    buf += snprintf(buf, MAX_BUFFER, "\"%s\"",
+                    accounting->syms.dictionary.strs[i]);
+    if (i < num_strs - 1) *(buf++) = ',';
+  }
+  buf += put_str(buf, "],\n");
+  buf += put_str(buf, "  \"symbols\": [\n    ");
+  AccountingSymbolContext context;
+  context.x = -2;
+  context.y = -2;
+  AccountingSymbol *sym;
+  for (i = 0; i < num_syms; i++) {
+    sym = &accounting->syms.syms[i];
+    if (memcmp(&context, &sym->context, sizeof(AccountingSymbolContext)) != 0) {
+      buf += put_num(buf, '[', sym->context.x, 0);
+      buf += put_num(buf, ',', sym->context.y, ']');
+    } else {
+      buf += put_num(buf, '[', sym->id, 0);
+      buf += put_num(buf, ',', sym->bits, 0);
+      buf += put_num(buf, ',', sym->samples, ']');
+    }
+    context = sym->context;
+    if (i < num_syms - 1) *(buf++) = ',';
+  }
+  buf += put_str(buf, "],\n");
+  return buf - buffer;
+}
+#endif
+
+void inspect(void *pbi, void *data) {
+  /* Fetch frame data. */
+  ifd_inspect(&frame_data, pbi);
+  (void)data;
+  // We allocate enough space and hope we don't write out of bounds. Totally
+  // unsafe but this speeds things up, especially when compiled to Javascript.
+  char *buffer = aom_malloc(MAX_BUFFER);
+  char *buf = buffer;
+  buf += put_str(buf, "{\n");
+  if (layers & BLOCK_SIZE_LAYER) {
+    buf += put_block_info(buf, block_size_map, "blockSize",
+                          offsetof(insp_mi_data, sb_type));
+  }
+  if (layers & TRANSFORM_SIZE_LAYER) {
+    buf += put_block_info(buf, tx_size_map, "transformSize",
+                          offsetof(insp_mi_data, tx_size));
+  }
+  if (layers & TRANSFORM_TYPE_LAYER) {
+    buf += put_block_info(buf, tx_type_map, "transformType",
+                          offsetof(insp_mi_data, tx_type));
+  }
+  if (layers & MODE_LAYER) {
+    buf += put_block_info(buf, prediction_mode_map, "mode",
+                          offsetof(insp_mi_data, mode));
+  }
+  if (layers & UV_MODE_LAYER) {
+    buf += put_block_info(buf, prediction_mode_map, "uv_mode",
+                          offsetof(insp_mi_data, uv_mode));
+  }
+  if (layers & SKIP_LAYER) {
+    buf += put_block_info(buf, skip_map, "skip", offsetof(insp_mi_data, skip));
+  }
+  if (layers & FILTER_LAYER) {
+    buf += put_block_info(buf, NULL, "filter", offsetof(insp_mi_data, filter));
+  }
+#if CONFIG_CDEF
+  if (layers & CDEF_LAYER) {
+    buf += put_block_info(buf, NULL, "cdef_level",
+                          offsetof(insp_mi_data, cdef_level));
+    buf += put_block_info(buf, NULL, "cdef_strength",
+                          offsetof(insp_mi_data, cdef_strength));
+  }
+#endif
+  if (layers & MOTION_VECTORS_LAYER) {
+    buf += put_motion_vectors(buf);
+  }
+  if (layers & REFERENCE_FRAME_LAYER) {
+    buf += put_reference_frame(buf);
+  }
+#if CONFIG_ACCOUNTING
+  if (layers & ACCOUNTING_LAYER) {
+    buf += put_accounting(buf);
+  }
+#endif
+  buf += snprintf(buf, MAX_BUFFER, "  \"frame\": %d,\n", decoded_frame_count);
+  buf += snprintf(buf, MAX_BUFFER, "  \"showFrame\": %d,\n",
+                  frame_data.show_frame);
+  buf += snprintf(buf, MAX_BUFFER, "  \"frameType\": %d,\n",
+                  frame_data.frame_type);
+  buf += snprintf(buf, MAX_BUFFER, "  \"baseQIndex\": %d,\n",
+                  frame_data.base_qindex);
+  buf += snprintf(buf, MAX_BUFFER, "  \"tileCols\": %d,\n",
+                  frame_data.tile_mi_cols);
+  buf += snprintf(buf, MAX_BUFFER, "  \"tileRows\": %d,\n",
+                  frame_data.tile_mi_rows);
+  buf += put_str(buf, "  \"config\": {");
+  buf += put_map(buf, config_map);
+  buf += put_str(buf, "},\n");
+  buf += snprintf(buf, MAX_BUFFER, "  \"configString\": \"%s\"\n",
+                  aom_codec_build_config());
+  decoded_frame_count++;
+  buf += put_str(buf, "},\n");
+  *(buf++) = 0;
+  on_frame_decoded_dump(buffer);
+  aom_free(buffer);
+}
+
+void ifd_init_cb() {
+  aom_inspect_init ii;
+  ii.inspect_cb = inspect;
+  ii.inspect_ctx = NULL;
+  aom_codec_control(&codec, AV1_SET_INSPECTION_CALLBACK, &ii);
+}
+
+EMSCRIPTEN_KEEPALIVE
+int open_file(char *file) {
+  if (file == NULL) {
+    // The JS analyzer puts the .ivf file at this location.
+    file = "/tmp/input.ivf";
+  }
+  reader = aom_video_reader_open(file);
+  if (!reader) die("Failed to open %s for reading.", file);
+  info = aom_video_reader_get_info(reader);
+  const AvxInterface *decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+  fprintf(stderr, "Using %s\n",
+          aom_codec_iface_name(decoder->codec_interface()));
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+  ifd_init(&frame_data, info->frame_width, info->frame_height);
+  ifd_init_cb();
+  return EXIT_SUCCESS;
+}
+
+EMSCRIPTEN_KEEPALIVE
+int read_frame() {
+  if (!aom_video_reader_read_frame(reader)) return EXIT_FAILURE;
+  img = NULL;
+  aom_codec_iter_t iter = NULL;
+  size_t frame_size = 0;
+  const unsigned char *frame = aom_video_reader_get_frame(reader, &frame_size);
+  if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0) !=
+      AOM_CODEC_OK) {
+    die_codec(&codec, "Failed to decode frame.");
+  }
+  img = aom_codec_get_frame(&codec, &iter);
+  if (img == NULL) {
+    return EXIT_FAILURE;
+  }
+  ++frame_count;
+  return EXIT_SUCCESS;
+}
+
+EMSCRIPTEN_KEEPALIVE
+const char *get_aom_codec_build_config() { return aom_codec_build_config(); }
+
+EMSCRIPTEN_KEEPALIVE
+int get_bit_depth() { return img->bit_depth; }
+
+EMSCRIPTEN_KEEPALIVE
+unsigned char *get_plane(int plane) { return img->planes[plane]; }
+
+EMSCRIPTEN_KEEPALIVE
+int get_plane_stride(int plane) { return img->stride[plane]; }
+
+EMSCRIPTEN_KEEPALIVE
+int get_plane_width(int plane) { return aom_img_plane_width(img, plane); }
+
+EMSCRIPTEN_KEEPALIVE
+int get_plane_height(int plane) { return aom_img_plane_height(img, plane); }
+
+EMSCRIPTEN_KEEPALIVE
+int get_frame_width() { return info->frame_width; }
+
+EMSCRIPTEN_KEEPALIVE
+int get_frame_height() { return info->frame_height; }
+
+static void parse_args(char **argv) {
+  char **argi, **argj;
+  struct arg arg;
+  (void)dump_accounting_arg;
+  (void)dump_cdef_arg;
+  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
+    arg.argv_step = 1;
+    if (arg_match(&arg, &dump_block_size_arg, argi)) layers |= BLOCK_SIZE_LAYER;
+#if CONFIG_ACCOUNTING
+    else if (arg_match(&arg, &dump_accounting_arg, argi))
+      layers |= ACCOUNTING_LAYER;
+#endif
+    else if (arg_match(&arg, &dump_transform_size_arg, argi))
+      layers |= TRANSFORM_SIZE_LAYER;
+    else if (arg_match(&arg, &dump_transform_type_arg, argi))
+      layers |= TRANSFORM_TYPE_LAYER;
+    else if (arg_match(&arg, &dump_mode_arg, argi))
+      layers |= MODE_LAYER;
+    else if (arg_match(&arg, &dump_uv_mode_arg, argi))
+      layers |= UV_MODE_LAYER;
+    else if (arg_match(&arg, &dump_skip_arg, argi))
+      layers |= SKIP_LAYER;
+    else if (arg_match(&arg, &dump_filter_arg, argi))
+      layers |= FILTER_LAYER;
+#if CONFIG_CDEF
+    else if (arg_match(&arg, &dump_cdef_arg, argi))
+      layers |= CDEF_LAYER;
+#endif
+    else if (arg_match(&arg, &dump_reference_frame_arg, argi))
+      layers |= REFERENCE_FRAME_LAYER;
+    else if (arg_match(&arg, &dump_motion_vectors_arg, argi))
+      layers |= MOTION_VECTORS_LAYER;
+    else if (arg_match(&arg, &dump_all_arg, argi))
+      layers |= ALL_LAYERS;
+    else if (arg_match(&arg, &compress_arg, argi))
+      compress = 1;
+    else if (arg_match(&arg, &usage_arg, argi))
+      usage_exit();
+    else if (arg_match(&arg, &limit_arg, argi))
+      stop_after = arg_parse_uint(&arg);
+    else
+      argj++;
+  }
+}
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s src_filename <options>\n", exec_name);
+  fprintf(stderr, "\nOptions:\n");
+  arg_show_usage(stderr, main_args);
+  exit(EXIT_FAILURE);
+}
+
+EMSCRIPTEN_KEEPALIVE
+int main(int argc, char **argv) {
+  exec_name = argv[0];
+  parse_args(argv);
+  if (argc >= 2) {
+    open_file(argv[1]);
+    printf("[\n");
+    while (1) {
+      if (stop_after && (decoded_frame_count >= stop_after)) break;
+      if (read_frame()) break;
+    }
+    printf("null\n");
+    printf("]");
+  } else {
+    usage_exit();
+  }
+}
+
+EMSCRIPTEN_KEEPALIVE
+void quit() {
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+  aom_video_reader_close(reader);
+}
+
+EMSCRIPTEN_KEEPALIVE
+void set_layers(LayerType v) { layers = v; }
+
+EMSCRIPTEN_KEEPALIVE
+void set_compress(int v) { compress = v; }
diff --git a/third_party/aom/examples/lossless_encoder.c b/third_party/aom/examples/lossless_encoder.c
new file mode 100644
index 000000000..32ab18a16
--- /dev/null
+++ b/third_party/aom/examples/lossless_encoder.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+#include "aom/aomcx.h"
+
+#include "../tools_common.h"
+#include "../video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "lossless_encoder: Example demonstrating lossless "
+          "encoding feature. Supports raw input only.\n");
+  fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
+                        int frame_index, int flags, AvxVideoWriter *writer) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(codec, img, frame_index, 1, flags, AOM_DL_GOOD_QUALITY);
+  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
+
+  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts)) {
+        die_codec(codec, "Failed to write compressed frame");
+      }
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  int frame_count = 0;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  AvxVideoInfo info;
+  AvxVideoWriter *writer = NULL;
+  const AvxInterface *encoder = NULL;
+  const int fps = 30;
+
+  exec_name = argv[0];
+
+  // Clear explicitly, as simply assigning "{ 0 }" generates
+  // "missing-field-initializers" warning in some compilers.
+  memset(&info, 0, sizeof(info));
+
+  if (argc < 5) die("Invalid number of arguments");
+
+  encoder = get_aom_encoder_by_name("av1");
+  if (!encoder) die("Unsupported codec.");
+
+  info.codec_fourcc = encoder->fourcc;
+  info.frame_width = (int)strtol(argv[1], NULL, 0);
+  info.frame_height = (int)strtol(argv[2], NULL, 0);
+  info.time_base.numerator = 1;
+  info.time_base.denominator = fps;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image.");
+  }
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = info.frame_width;
+  cfg.g_h = info.frame_height;
+  cfg.g_timebase.num = info.time_base.numerator;
+  cfg.g_timebase.den = info.time_base.denominator;
+
+  writer = aom_video_writer_open(argv[4], kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing.", argv[4]);
+
+  if (!(infile = fopen(argv[3], "rb")))
+    die("Failed to open %s for reading.", argv[3]);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+
+  if (aom_codec_control_(&codec, AV1E_SET_LOSSLESS, 1))
+    die_codec(&codec, "Failed to use lossless mode");
+
+  // Encode frames.
+  while (aom_img_read(&raw, infile)) {
+    encode_frame(&codec, &raw, frame_count++, 0, writer);
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, 0, writer)) {
+  }
+
+  printf("\n");
+  fclose(infile);
+  printf("Processed %d frames.\n", frame_count);
+
+  aom_img_free(&raw);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_writer_close(writer);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/resize_util.c b/third_party/aom/examples/resize_util.c
new file mode 100644
index 000000000..5485691a8
--- /dev/null
+++ b/third_party/aom/examples/resize_util.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../tools_common.h"
+#include "../av1/encoder/av1_resize.h"
+
+static const char *exec_name = NULL;
+
+static void usage() {
+  printf("Usage:\n");
+  printf("%s <input_yuv> <width>x<height> <target_width>x<target_height> ",
+         exec_name);
+  printf("<output_yuv> [<frames>]\n");
+}
+
+void usage_exit(void) {
+  usage();
+  exit(EXIT_FAILURE);
+}
+
+static int parse_dim(char *v, int *width, int *height) {
+  char *x = strchr(v, 'x');
+  if (x == NULL) x = strchr(v, 'X');
+  if (x == NULL) return 0;
+  *width = atoi(v);
+  *height = atoi(&x[1]);
+  if (*width <= 0 || *height <= 0)
+    return 0;
+  else
+    return 1;
+}
+
+int main(int argc, char *argv[]) {
+  char *fin, *fout;
+  FILE *fpin, *fpout;
+  uint8_t *inbuf, *outbuf;
+  uint8_t *inbuf_u, *outbuf_u;
+  uint8_t *inbuf_v, *outbuf_v;
+  int f, frames;
+  int width, height, target_width, target_height;
+
+  exec_name = argv[0];
+
+  if (argc < 5) {
+    printf("Incorrect parameters:\n");
+    usage();
+    return 1;
+  }
+
+  fin = argv[1];
+  fout = argv[4];
+  if (!parse_dim(argv[2], &width, &height)) {
+    printf("Incorrect parameters: %s\n", argv[2]);
+    usage();
+    return 1;
+  }
+  if (!parse_dim(argv[3], &target_width, &target_height)) {
+    printf("Incorrect parameters: %s\n", argv[3]);
+    usage();
+    return 1;
+  }
+
+  fpin = fopen(fin, "rb");
+  if (fpin == NULL) {
+    printf("Can't open file %s to read\n", fin);
+    usage();
+    return 1;
+  }
+  fpout = fopen(fout, "wb");
+  if (fpout == NULL) {
+    printf("Can't open file %s to write\n", fout);
+    usage();
+    return 1;
+  }
+  if (argc >= 6)
+    frames = atoi(argv[5]);
+  else
+    frames = INT_MAX;
+
+  printf("Input size:  %dx%d\n", width, height);
+  printf("Target size: %dx%d, Frames: ", target_width, target_height);
+  if (frames == INT_MAX)
+    printf("All\n");
+  else
+    printf("%d\n", frames);
+
+  inbuf = (uint8_t *)malloc(width * height * 3 / 2);
+  outbuf = (uint8_t *)malloc(target_width * target_height * 3 / 2);
+  inbuf_u = inbuf + width * height;
+  inbuf_v = inbuf_u + width * height / 4;
+  outbuf_u = outbuf + target_width * target_height;
+  outbuf_v = outbuf_u + target_width * target_height / 4;
+  f = 0;
+  while (f < frames) {
+    if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1) break;
+    av1_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2, height,
+                        width, outbuf, target_width, outbuf_u, outbuf_v,
+                        target_width / 2, target_height, target_width);
+    fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
+    f++;
+  }
+  printf("%d frames processed\n", f);
+  fclose(fpin);
+  fclose(fpout);
+
+  free(inbuf);
+  free(outbuf);
+  return 0;
+}
diff --git a/third_party/aom/examples/set_maps.c b/third_party/aom/examples/set_maps.c
new file mode 100644
index 000000000..e88cd426f
--- /dev/null
+++ b/third_party/aom/examples/set_maps.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// AOM Set Active and ROI Maps
+// ===========================
+//
+// This is an example demonstrating how to control the AOM encoder's
+// ROI and Active maps.
+//
+// ROI (Reigon of Interest) maps are a way for the application to assign
+// each macroblock in the image to a region, and then set quantizer and
+// filtering parameters on that image.
+//
+// Active maps are a way for the application to specify on a
+// macroblock-by-macroblock basis whether there is any activity in that
+// macroblock.
+//
+//
+// Configuration
+// -------------
+// An ROI map is set on frame 22. If the width of the image in macroblocks
+// is evenly divisble by 4, then the output will appear to have distinct
+// columns, where the quantizer, loopfilter, and static threshold differ
+// from column to column.
+//
+// An active map is set on frame 33. If the width of the image in macroblocks
+// is evenly divisble by 4, then the output will appear to have distinct
+// columns, where one column will have motion and the next will not.
+//
+// The active map is cleared on frame 44.
+//
+// Observing The Effects
+// ---------------------
+// Use the `simple_decoder` example to decode this sample, and observe
+// the change in the image at frames 22, 33, and 44.
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aomcx.h"
+#include "aom/aom_encoder.h"
+
+#include "../tools_common.h"
+#include "../video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static void set_active_map(const aom_codec_enc_cfg_t *cfg,
+                           aom_codec_ctx_t *codec) {
+  unsigned int i;
+  aom_active_map_t map = { 0, 0, 0 };
+
+  map.rows = (cfg->g_h + 15) / 16;
+  map.cols = (cfg->g_w + 15) / 16;
+
+  map.active_map = (uint8_t *)malloc(map.rows * map.cols);
+  for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2;
+
+  if (aom_codec_control(codec, AOME_SET_ACTIVEMAP, &map))
+    die_codec(codec, "Failed to set active map");
+
+  free(map.active_map);
+}
+
+static void unset_active_map(const aom_codec_enc_cfg_t *cfg,
+                             aom_codec_ctx_t *codec) {
+  aom_active_map_t map = { 0, 0, 0 };
+
+  map.rows = (cfg->g_h + 15) / 16;
+  map.cols = (cfg->g_w + 15) / 16;
+  map.active_map = NULL;
+
+  if (aom_codec_control(codec, AOME_SET_ACTIVEMAP, &map))
+    die_codec(codec, "Failed to set active map");
+}
+
+static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
+                        int frame_index, AvxVideoWriter *writer) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(codec, img, frame_index, 1, 0, AOM_DL_GOOD_QUALITY);
+  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
+
+  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts)) {
+        die_codec(codec, "Failed to write compressed frame");
+      }
+
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  int frame_count = 0;
+  const int limit = 30;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  AvxVideoInfo info;
+  AvxVideoWriter *writer = NULL;
+  const AvxInterface *encoder = NULL;
+  const int fps = 2;  // TODO(dkovalev) add command line argument
+  const double bits_per_pixel_per_frame = 0.067;
+
+  exec_name = argv[0];
+  if (argc != 6) die("Invalid number of arguments");
+
+  memset(&info, 0, sizeof(info));
+
+  encoder = get_aom_encoder_by_name(argv[1]);
+  if (encoder == NULL) {
+    die("Unsupported codec.");
+  }
+  assert(encoder != NULL);
+  info.codec_fourcc = encoder->fourcc;
+  info.frame_width = (int)strtol(argv[2], NULL, 0);
+  info.frame_height = (int)strtol(argv[3], NULL, 0);
+  info.time_base.numerator = 1;
+  info.time_base.denominator = fps;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image.");
+  }
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = info.frame_width;
+  cfg.g_h = info.frame_height;
+  cfg.g_timebase.num = info.time_base.numerator;
+  cfg.g_timebase.den = info.time_base.denominator;
+  cfg.rc_target_bitrate =
+      (unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000);
+  cfg.g_lag_in_frames = 0;
+
+  writer = aom_video_writer_open(argv[5], kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing.", argv[5]);
+
+  if (!(infile = fopen(argv[4], "rb")))
+    die("Failed to open %s for reading.", argv[4]);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+
+  // Encode frames.
+  while (aom_img_read(&raw, infile) && frame_count < limit) {
+    ++frame_count;
+
+    if (frame_count == 11) {
+      set_active_map(&cfg, &codec);
+    } else if (frame_count == 22) {
+      unset_active_map(&cfg, &codec);
+    }
+
+    encode_frame(&codec, &raw, frame_count, writer);
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, writer)) {
+  }
+
+  printf("\n");
+  fclose(infile);
+  printf("Processed %d frames.\n", frame_count);
+
+  aom_img_free(&raw);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_writer_close(writer);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/simple_decoder.c b/third_party/aom/examples/simple_decoder.c
new file mode 100644
index 000000000..33a894539
--- /dev/null
+++ b/third_party/aom/examples/simple_decoder.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Simple Decoder
+// ==============
+//
+// This is an example of a simple decoder loop. It takes an input file
+// containing the compressed data (in IVF format), passes it through the
+// decoder, and writes the decompressed frames to disk. Other decoder
+// examples build upon this one.
+//
+// The details of the IVF format have been elided from this example for
+// simplicity of presentation, as IVF files will not generally be used by
+// your application. In general, an IVF file consists of a file header,
+// followed by a variable number of frames. Each frame consists of a frame
+// header followed by a variable length payload. The length of the payload
+// is specified in the first four bytes of the frame header. The payload is
+// the raw compressed data.
+//
+// Standard Includes
+// -----------------
+// For decoders, you only have to include `aom_decoder.h` and then any
+// header files for the specific codecs you use. In this case, we're using
+// aom.
+//
+// Initializing The Codec
+// ----------------------
+// The libaom decoder is initialized by the call to aom_codec_dec_init().
+// Determining the codec interface to use is handled by AvxVideoReader and the
+// functions prefixed with aom_video_reader_. Discussion of those functions is
+// beyond the scope of this example, but the main gist is to open the input file
+// and parse just enough of it to determine if it's a AVx file and which AVx
+// codec is contained within the file.
+// Note the NULL pointer passed to aom_codec_dec_init(). We do that in this
+// example because we want the algorithm to determine the stream configuration
+// (width/height) and allocate memory automatically.
+//
+// Decoding A Frame
+// ----------------
+// Once the frame has been read into memory, it is decoded using the
+// `aom_codec_decode` function. The call takes a pointer to the data
+// (`frame`) and the length of the data (`frame_size`). No application data
+// is associated with the frame in this example, so the `user_priv`
+// parameter is NULL. The `deadline` parameter is left at zero for this
+// example. This parameter is generally only used when doing adaptive post
+// processing.
+//
+// Codecs may produce a variable number of output frames for every call to
+// `aom_codec_decode`. These frames are retrieved by the
+// `aom_codec_get_frame` iterator function. The iterator variable `iter` is
+// initialized to NULL each time `aom_codec_decode` is called.
+// `aom_codec_get_frame` is called in a loop, returning a pointer to a
+// decoded image or NULL to indicate the end of list.
+//
+// Processing The Decoded Data
+// ---------------------------
+// In this example, we simply write the encoded data to disk. It is
+// important to honor the image's `stride` values.
+//
+// Cleanup
+// -------
+// The `aom_codec_destroy` call frees any memory allocated by the codec.
+//
+// Error Handling
+// --------------
+// This example does not special case any error return codes. If there was
+// an error, a descriptive message is printed and the program exits. With
+// few exceptions, aom_codec functions return an enumerated error status,
+// with the value `0` indicating success.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_decoder.h"
+
+#include "../tools_common.h"
+#include "../video_reader.h"
+#include "./aom_config.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  int frame_cnt = 0;
+  FILE *outfile = NULL;
+  aom_codec_ctx_t codec;
+  AvxVideoReader *reader = NULL;
+  const AvxInterface *decoder = NULL;
+  const AvxVideoInfo *info = NULL;
+
+  exec_name = argv[0];
+
+  if (argc != 3) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  if (!(outfile = fopen(argv[2], "wb")))
+    die("Failed to open %s for writing.", argv[2]);
+
+  info = aom_video_reader_get_info(reader);
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  while (aom_video_reader_read_frame(reader)) {
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    size_t frame_size = 0;
+    const unsigned char *frame =
+        aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+      die_codec(&codec, "Failed to decode frame.");
+
+    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+      aom_img_write(img, outfile);
+      ++frame_cnt;
+    }
+  }
+
+  printf("Processed %d frames.\n", frame_cnt);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+
+  printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
+         info->frame_width, info->frame_height, argv[2]);
+
+  aom_video_reader_close(reader);
+
+  fclose(outfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/simple_encoder.c b/third_party/aom/examples/simple_encoder.c
new file mode 100644
index 000000000..996f6dacf
--- /dev/null
+++ b/third_party/aom/examples/simple_encoder.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Simple Encoder
+// ==============
+//
+// This is an example of a simple encoder loop. It takes an input file in
+// YV12 format, passes it through the encoder, and writes the compressed
+// frames to disk in IVF format. Other decoder examples build upon this
+// one.
+//
+// The details of the IVF format have been elided from this example for
+// simplicity of presentation, as IVF files will not generally be used by
+// your application. In general, an IVF file consists of a file header,
+// followed by a variable number of frames. Each frame consists of a frame
+// header followed by a variable length payload. The length of the payload
+// is specified in the first four bytes of the frame header. The payload is
+// the raw compressed data.
+//
+// Standard Includes
+// -----------------
+// For encoders, you only have to include `aom_encoder.h` and then any
+// header files for the specific codecs you use. In this case, we're using
+// aom.
+//
+// Getting The Default Configuration
+// ---------------------------------
+// Encoders have the notion of "usage profiles." For example, an encoder
+// may want to publish default configurations for both a video
+// conferencing application and a best quality offline encoder. These
+// obviously have very different default settings. Consult the
+// documentation for your codec to see if it provides any default
+// configurations. All codecs provide a default configuration, number 0,
+// which is valid for material in the vacinity of QCIF/QVGA.
+//
+// Updating The Configuration
+// ---------------------------------
+// Almost all applications will want to update the default configuration
+// with settings specific to their usage. Here we set the width and height
+// of the video file to that specified on the command line. We also scale
+// the default bitrate based on the ratio between the default resolution
+// and the resolution specified on the command line.
+//
+// Initializing The Codec
+// ----------------------
+// The encoder is initialized by the following code.
+//
+// Encoding A Frame
+// ----------------
+// The frame is read as a continuous block (size width * height * 3 / 2)
+// from the input file. If a frame was read (the input file has not hit
+// EOF) then the frame is passed to the encoder. Otherwise, a NULL
+// is passed, indicating the End-Of-Stream condition to the encoder. The
+// `frame_cnt` is reused as the presentation time stamp (PTS) and each
+// frame is shown for one frame-time in duration. The flags parameter is
+// unused in this example.
+
+// Forced Keyframes
+// ----------------
+// Keyframes can be forced by setting the AOM_EFLAG_FORCE_KF bit of the
+// flags passed to `aom_codec_control()`. In this example, we force a
+// keyframe every <keyframe-interval> frames. Note, the output stream can
+// contain additional keyframes beyond those that have been forced using the
+// AOM_EFLAG_FORCE_KF flag because of automatic keyframe placement by the
+// encoder.
+//
+// Processing The Encoded Data
+// ---------------------------
+// Each packet of type `AOM_CODEC_CX_FRAME_PKT` contains the encoded data
+// for this frame. We write a IVF frame header, followed by the raw data.
+//
+// Cleanup
+// -------
+// The `aom_codec_destroy` call frees any memory allocated by the codec.
+//
+// Error Handling
+// --------------
+// This example does not special case any error return codes. If there was
+// an error, a descriptive message is printed and the program exits. With
+// few exeptions, aom_codec functions return an enumerated error status,
+// with the value `0` indicating success.
+//
+// Error Resiliency Features
+// -------------------------
+// Error resiliency is controlled by the g_error_resilient member of the
+// configuration structure. Use the `decode_with_drops` example to decode with
+// frames 5-10 dropped. Compare the output for a file encoded with this example
+// versus one encoded with the `simple_encoder` example.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+
+#include "../tools_common.h"
+#include "../video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <codec> <width> <height> <infile> <outfile> "
+          "<keyframe-interval> <error-resilient> <frames to encode>\n"
+          "See comments in simple_encoder.c for more information.\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
+                        int frame_index, int flags, AvxVideoWriter *writer) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(codec, img, frame_index, 1, flags, AOM_DL_GOOD_QUALITY);
+  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
+
+  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts)) {
+        die_codec(codec, "Failed to write compressed frame");
+      }
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+// TODO(tomfinegan): Improve command line parsing and add args for bitrate/fps.
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  int frame_count = 0;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  AvxVideoInfo info;
+  AvxVideoWriter *writer = NULL;
+  const AvxInterface *encoder = NULL;
+  const int fps = 30;
+  const int bitrate = 200;
+  int keyframe_interval = 0;
+  int max_frames = 0;
+  int frames_encoded = 0;
+  const char *codec_arg = NULL;
+  const char *width_arg = NULL;
+  const char *height_arg = NULL;
+  const char *infile_arg = NULL;
+  const char *outfile_arg = NULL;
+  const char *keyframe_interval_arg = NULL;
+
+  exec_name = argv[0];
+
+  // Clear explicitly, as simply assigning "{ 0 }" generates
+  // "missing-field-initializers" warning in some compilers.
+  memset(&info, 0, sizeof(info));
+
+  if (argc != 9) die("Invalid number of arguments");
+
+  codec_arg = argv[1];
+  width_arg = argv[2];
+  height_arg = argv[3];
+  infile_arg = argv[4];
+  outfile_arg = argv[5];
+  keyframe_interval_arg = argv[6];
+  max_frames = (int)strtol(argv[8], NULL, 0);
+
+  encoder = get_aom_encoder_by_name(codec_arg);
+  if (!encoder) die("Unsupported codec.");
+
+  info.codec_fourcc = encoder->fourcc;
+  info.frame_width = (int)strtol(width_arg, NULL, 0);
+  info.frame_height = (int)strtol(height_arg, NULL, 0);
+  info.time_base.numerator = 1;
+  info.time_base.denominator = fps;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image.");
+  }
+
+  keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0);
+  if (keyframe_interval < 0) die("Invalid keyframe interval value.");
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = info.frame_width;
+  cfg.g_h = info.frame_height;
+  cfg.g_timebase.num = info.time_base.numerator;
+  cfg.g_timebase.den = info.time_base.denominator;
+  cfg.rc_target_bitrate = bitrate;
+  cfg.g_error_resilient = (aom_codec_er_flags_t)strtoul(argv[7], NULL, 0);
+
+  writer = aom_video_writer_open(outfile_arg, kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing.", outfile_arg);
+
+  if (!(infile = fopen(infile_arg, "rb")))
+    die("Failed to open %s for reading.", infile_arg);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+
+  // Encode frames.
+  while (aom_img_read(&raw, infile)) {
+    int flags = 0;
+    if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
+      flags |= AOM_EFLAG_FORCE_KF;
+    encode_frame(&codec, &raw, frame_count++, flags, writer);
+    frames_encoded++;
+    if (max_frames > 0 && frames_encoded >= max_frames) break;
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, 0, writer)) continue;
+
+  printf("\n");
+  fclose(infile);
+  printf("Processed %d frames.\n", frame_count);
+
+  aom_img_free(&raw);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_writer_close(writer);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/twopass_encoder.c b/third_party/aom/examples/twopass_encoder.c
new file mode 100644
index 000000000..e767bb5d7
--- /dev/null
+++ b/third_party/aom/examples/twopass_encoder.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Two Pass Encoder
+// ================
+//
+// This is an example of a two pass encoder loop. It takes an input file in
+// YV12 format, passes it through the encoder twice, and writes the compressed
+// frames to disk in IVF format. It builds upon the simple_encoder example.
+//
+// Twopass Variables
+// -----------------
+// Twopass mode needs to track the current pass number and the buffer of
+// statistics packets.
+//
+// Updating The Configuration
+// ---------------------------------
+// In two pass mode, the configuration has to be updated on each pass. The
+// statistics buffer is passed on the last pass.
+//
+// Encoding A Frame
+// ----------------
+// Encoding a frame in two pass mode is identical to the simple encoder
+// example.
+//
+// Processing Statistics Packets
+// -----------------------------
+// Each packet of type `AOM_CODEC_CX_FRAME_PKT` contains the encoded data
+// for this frame. We write a IVF frame header, followed by the raw data.
+//
+//
+// Pass Progress Reporting
+// -----------------------------
+// It's sometimes helpful to see when each pass completes.
+//
+//
+// Clean-up
+// -----------------------------
+// Destruction of the encoder instance must be done on each pass. The
+// raw image should be destroyed at the end as usual.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+
+#include "../tools_common.h"
+#include "../video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <codec> <width> <height> <infile> <outfile> "
+          "<limit(optional)>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
+                           aom_codec_pts_t pts, unsigned int duration,
+                           aom_enc_frame_flags_t flags, unsigned int deadline,
+                           aom_fixed_buf_t *stats) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(ctx, img, pts, duration, flags, deadline);
+  if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
+
+  while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_STATS_PKT) {
+      const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf;
+      const size_t pkt_size = pkt->data.twopass_stats.sz;
+      stats->buf = realloc(stats->buf, stats->sz + pkt_size);
+      memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size);
+      stats->sz += pkt_size;
+    }
+  }
+
+  return got_pkts;
+}
+
+static int encode_frame(aom_codec_ctx_t *ctx, const aom_image_t *img,
+                        aom_codec_pts_t pts, unsigned int duration,
+                        aom_enc_frame_flags_t flags, unsigned int deadline,
+                        AvxVideoWriter *writer) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(ctx, img, pts, duration, flags, deadline);
+  if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
+
+  while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
+    got_pkts = 1;
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts))
+        die_codec(ctx, "Failed to write compressed frame.");
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
+                             const AvxInterface *encoder,
+                             const aom_codec_enc_cfg_t *cfg, int limit) {
+  aom_codec_ctx_t codec;
+  int frame_count = 0;
+  aom_fixed_buf_t stats = { NULL, 0 };
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+
+  // Calculate frame statistics.
+  while (aom_img_read(raw, infile) && frame_count < limit) {
+    ++frame_count;
+    get_frame_stats(&codec, raw, frame_count, 1, 0, AOM_DL_GOOD_QUALITY,
+                    &stats);
+  }
+
+  // Flush encoder.
+  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, AOM_DL_GOOD_QUALITY,
+                         &stats)) {
+  }
+
+  printf("Pass 0 complete. Processed %d frames.\n", frame_count);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  return stats;
+}
+
+static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
+                  const AvxInterface *encoder, const aom_codec_enc_cfg_t *cfg,
+                  int limit) {
+  AvxVideoInfo info = { encoder->fourcc,
+                        cfg->g_w,
+                        cfg->g_h,
+                        { cfg->g_timebase.num, cfg->g_timebase.den } };
+  AvxVideoWriter *writer = NULL;
+  aom_codec_ctx_t codec;
+  int frame_count = 0;
+
+  writer = aom_video_writer_open(outfile_name, kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing", outfile_name);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+
+  // Encode frames.
+  while (aom_img_read(raw, infile) && frame_count < limit) {
+    ++frame_count;
+    encode_frame(&codec, raw, frame_count, 1, 0, AOM_DL_GOOD_QUALITY, writer);
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, 1, 0, AOM_DL_GOOD_QUALITY, writer)) {
+  }
+
+  printf("\n");
+
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_writer_close(writer);
+
+  printf("Pass 1 complete. Processed %d frames.\n", frame_count);
+}
+
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  int w, h;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  aom_fixed_buf_t stats;
+
+  const AvxInterface *encoder = NULL;
+  const int fps = 30;       // TODO(dkovalev) add command line argument
+  const int bitrate = 200;  // kbit/s TODO(dkovalev) add command line argument
+  const char *const codec_arg = argv[1];
+  const char *const width_arg = argv[2];
+  const char *const height_arg = argv[3];
+  const char *const infile_arg = argv[4];
+  const char *const outfile_arg = argv[5];
+  int limit = 0;
+  exec_name = argv[0];
+
+  if (argc < 6) die("Invalid number of arguments");
+
+  if (argc > 6) limit = (int)strtol(argv[6], NULL, 0);
+
+  if (limit == 0) limit = 100;
+
+  encoder = get_aom_encoder_by_name(codec_arg);
+  if (!encoder) die("Unsupported codec.");
+
+  w = (int)strtol(width_arg, NULL, 0);
+  h = (int)strtol(height_arg, NULL, 0);
+
+  if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
+    die("Invalid frame size: %dx%d", w, h);
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, w, h, 1))
+    die("Failed to allocate image", w, h);
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  // Configuration
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = w;
+  cfg.g_h = h;
+  cfg.g_timebase.num = 1;
+  cfg.g_timebase.den = fps;
+  cfg.rc_target_bitrate = bitrate;
+
+  if (!(infile = fopen(infile_arg, "rb")))
+    die("Failed to open %s for reading", infile_arg);
+
+  // Pass 0
+  cfg.g_pass = AOM_RC_FIRST_PASS;
+  stats = pass0(&raw, infile, encoder, &cfg, limit);
+
+  // Pass 1
+  rewind(infile);
+  cfg.g_pass = AOM_RC_LAST_PASS;
+  cfg.rc_twopass_stats_in = stats;
+  pass1(&raw, infile, outfile_arg, encoder, &cfg, limit);
+  free(stats.buf);
+
+  aom_img_free(&raw);
+  fclose(infile);
+
+  return EXIT_SUCCESS;
+}
-- 
cgit v1.2.3


From df9477dfa60ebb5d31bc142e58ce46535c17abce Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Wed, 17 Oct 2018 05:59:08 -0500
Subject: Update aom to slightly newer commit ID

---
 third_party/aom/examples/inspect.c  | 83 +++++++++++++++++++++++++------------
 third_party/aom/examples/set_maps.c |  6 +--
 2 files changed, 60 insertions(+), 29 deletions(-)

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
index 345c0884d..294e478af 100644
--- a/third_party/aom/examples/inspect.c
+++ b/third_party/aom/examples/inspect.c
@@ -27,17 +27,17 @@
 #endif
 
 #include "aom/aom_decoder.h"
+#include "./aom_config.h"
+#if CONFIG_ACCOUNTING
+#include "../av1/decoder/accounting.h"
+#endif
+#include "../av1/decoder/inspection.h"
 #include "aom/aomdx.h"
 
 #include "../tools_common.h"
 #include "../video_reader.h"
-#include "./aom_config.h"
 // #include "av1/av1_dx_iface.c"
 #include "../av1/common/onyxc_int.h"
-#if CONFIG_ACCOUNTING
-#include "../av1/decoder/accounting.h"
-#endif
-#include "../av1/decoder/inspection.h"
 
 #include "../video_common.h"
 
@@ -56,7 +56,8 @@ typedef enum {
   REFERENCE_FRAME_LAYER = 1 << 8,
   MOTION_VECTORS_LAYER = 1 << 9,
   UV_MODE_LAYER = 1 << 10,
-  ALL_LAYERS = (1 << 11) - 1
+  CFL_LAYER = 1 << 11,
+  ALL_LAYERS = (1 << 12) - 1
 } LayerType;
 
 static LayerType layers = 0;
@@ -86,6 +87,10 @@ static const arg_def_t dump_skip_arg = ARG_DEF("s", "skip", 0, "Dump Skip");
 static const arg_def_t dump_filter_arg =
     ARG_DEF("f", "filter", 0, "Dump Filter");
 static const arg_def_t dump_cdef_arg = ARG_DEF("c", "cdef", 0, "Dump CDEF");
+#if CONFIG_CFL
+static const arg_def_t dump_cfl_arg =
+    ARG_DEF("cfl", "chroma_from_luma", 0, "Dump Chroma from Luma Alphas");
+#endif
 static const arg_def_t dump_reference_frame_arg =
     ARG_DEF("r", "referenceFrame", 0, "Dump Reference Frame");
 static const arg_def_t usage_arg = ARG_DEF("h", "help", 0, "Help");
@@ -105,6 +110,9 @@ static const arg_def_t *main_args[] = { &limit_arg,
                                         &dump_filter_arg,
 #if CONFIG_CDEF
                                         &dump_cdef_arg,
+#endif
+#if CONFIG_CFL
+                                        &dump_cfl_arg,
 #endif
                                         &dump_reference_frame_arg,
                                         &dump_motion_vectors_arg,
@@ -145,7 +153,7 @@ const map_entry block_size_map[] = {
 };
 
 const map_entry tx_size_map[] = {
-#if CONFIG_CB4X4
+#if CONFIG_CHROMA_2X2
   ENUM(TX_2X2),
 #endif
   ENUM(TX_4X4),   ENUM(TX_8X8),   ENUM(TX_16X16), ENUM(TX_32X32),
@@ -177,28 +185,39 @@ const map_entry tx_type_map[] = { ENUM(DCT_DCT),
 #endif
                                   LAST_ENUM };
 
-const map_entry prediction_mode_map[] = {
-  ENUM(DC_PRED),        ENUM(V_PRED),
-  ENUM(H_PRED),         ENUM(D45_PRED),
-  ENUM(D135_PRED),      ENUM(D117_PRED),
-  ENUM(D153_PRED),      ENUM(D207_PRED),
-  ENUM(D63_PRED),
+const map_entry prediction_mode_map[] = { ENUM(DC_PRED),
+                                          ENUM(V_PRED),
+                                          ENUM(H_PRED),
+                                          ENUM(D45_PRED),
+                                          ENUM(D135_PRED),
+                                          ENUM(D117_PRED),
+                                          ENUM(D153_PRED),
+                                          ENUM(D207_PRED),
+                                          ENUM(D63_PRED),
 #if CONFIG_ALT_INTRA
-  ENUM(SMOOTH_PRED),
-#endif
-  ENUM(TM_PRED),        ENUM(NEARESTMV),
-  ENUM(NEARMV),         ENUM(ZEROMV),
-  ENUM(NEWMV),
+                                          ENUM(SMOOTH_PRED),
+#if CONFIG_SMOOTH_HV
+                                          ENUM(SMOOTH_V_PRED),
+                                          ENUM(SMOOTH_H_PRED),
+#endif  // CONFIG_SMOOTH_HV
+#endif  // CONFIG_ALT_INTRA
+                                          ENUM(TM_PRED),
+                                          ENUM(NEARESTMV),
+                                          ENUM(NEARMV),
+                                          ENUM(ZEROMV),
+                                          ENUM(NEWMV),
 #if CONFIG_EXT_INTER
-  ENUM(NEWFROMNEARMV),  ENUM(NEAREST_NEARESTMV),
-  ENUM(NEAREST_NEARMV), ENUM(NEAR_NEARESTMV),
-  ENUM(NEAR_NEARMV),    ENUM(NEAREST_NEWMV),
-  ENUM(NEW_NEARESTMV),  ENUM(NEAR_NEWMV),
-  ENUM(NEW_NEARMV),     ENUM(ZERO_ZEROMV),
-  ENUM(NEW_NEWMV),
+                                          ENUM(NEAREST_NEARESTMV),
+                                          ENUM(NEAR_NEARMV),
+                                          ENUM(NEAREST_NEWMV),
+                                          ENUM(NEW_NEARESTMV),
+                                          ENUM(NEAR_NEWMV),
+                                          ENUM(NEW_NEARMV),
+                                          ENUM(ZERO_ZEROMV),
+                                          ENUM(NEW_NEWMV),
 #endif
-  ENUM(INTRA_INVALID),  LAST_ENUM
-};
+                                          ENUM(INTRA_INVALID),
+                                          LAST_ENUM };
 
 #define NO_SKIP 0
 #define SKIP 1
@@ -488,6 +507,14 @@ void inspect(void *pbi, void *data) {
     buf += put_block_info(buf, NULL, "cdef_strength",
                           offsetof(insp_mi_data, cdef_strength));
   }
+#endif
+#if CONFIG_CFL
+  if (layers & CFL_LAYER) {
+    buf += put_block_info(buf, NULL, "cfl_alpha_idx",
+                          offsetof(insp_mi_data, cfl_alpha_idx));
+    buf += put_block_info(buf, NULL, "cfl_alpha_sign",
+                          offsetof(insp_mi_data, cfl_alpha_sign));
+  }
 #endif
   if (layers & MOTION_VECTORS_LAYER) {
     buf += put_motion_vectors(buf);
@@ -620,6 +647,10 @@ static void parse_args(char **argv) {
 #if CONFIG_CDEF
     else if (arg_match(&arg, &dump_cdef_arg, argi))
       layers |= CDEF_LAYER;
+#endif
+#if CONFIG_CFL
+    else if (arg_match(&arg, &dump_cfl_arg, argi))
+      layers |= CFL_LAYER;
 #endif
     else if (arg_match(&arg, &dump_reference_frame_arg, argi))
       layers |= REFERENCE_FRAME_LAYER;
diff --git a/third_party/aom/examples/set_maps.c b/third_party/aom/examples/set_maps.c
index e88cd426f..3a54e5f96 100644
--- a/third_party/aom/examples/set_maps.c
+++ b/third_party/aom/examples/set_maps.c
@@ -123,7 +123,7 @@ int main(int argc, char **argv) {
   aom_codec_ctx_t codec;
   aom_codec_enc_cfg_t cfg;
   int frame_count = 0;
-  const int limit = 30;
+  const int limit = 15;
   aom_image_t raw;
   aom_codec_err_t res;
   AvxVideoInfo info;
@@ -184,9 +184,9 @@ int main(int argc, char **argv) {
   while (aom_img_read(&raw, infile) && frame_count < limit) {
     ++frame_count;
 
-    if (frame_count == 11) {
+    if (frame_count == 5) {
       set_active_map(&cfg, &codec);
-    } else if (frame_count == 22) {
+    } else if (frame_count == 11) {
       unset_active_map(&cfg, &codec);
     }
 
-- 
cgit v1.2.3


From 7369c7d7a5eed32963d8af37658286617919f91c Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Thu, 18 Oct 2018 06:04:57 -0500
Subject: Update aom to commit id f5bdeac22930ff4c6b219be49c843db35970b918

---
 third_party/aom/examples/analyzer.cc | 52 +++++++++++++++++++++++++++---------
 third_party/aom/examples/inspect.c   | 45 ++++++++++++++++++++++++++++---
 2 files changed, 80 insertions(+), 17 deletions(-)

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/analyzer.cc b/third_party/aom/examples/analyzer.cc
index 591aaf25e..ae0801964 100644
--- a/third_party/aom/examples/analyzer.cc
+++ b/third_party/aom/examples/analyzer.cc
@@ -233,13 +233,17 @@ void AnalyzerPanel::setShowPlane(bool show_plane, int mask) {
 
 void AnalyzerPanel::render() {
   aom_image_t *img = decoder.image;
-  int y_stride = img->stride[0];
-  int cb_stride = img->stride[1];
-  int cr_stride = img->stride[2];
+  const int hbd = !!(img->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
+  int y_stride = img->stride[0] >> hbd;
+  int cb_stride = img->stride[1] >> hbd;
+  int cr_stride = img->stride[2] >> hbd;
   int p_stride = 3 * getDisplayWidth();
   unsigned char *y_row = img->planes[0];
   unsigned char *cb_row = img->planes[1];
   unsigned char *cr_row = img->planes[2];
+  uint16_t *y_row16 = reinterpret_cast<uint16_t *>(y_row);
+  uint16_t *cb_row16 = reinterpret_cast<uint16_t *>(cb_row);
+  uint16_t *cr_row16 = reinterpret_cast<uint16_t *>(cr_row);
   unsigned char *p_row = pixels;
   int y_width_padding = decoder.getWidthPadding();
   int cb_width_padding = y_width_padding >> 1;
@@ -251,6 +255,9 @@ void AnalyzerPanel::render() {
     unsigned char *y = y_row - y_stride * y_height_padding;
     unsigned char *cb = cb_row - cb_stride * cb_height_padding;
     unsigned char *cr = cr_row - cr_stride * cr_height_padding;
+    uint16_t *y16 = y_row16 - y_stride * y_height_padding;
+    uint16_t *cb16 = cb_row16 - cb_stride * cb_height_padding;
+    uint16_t *cr16 = cr_row16 - cr_stride * cr_height_padding;
     unsigned char *p = p_row;
     for (int i = 0; i < decoder.getWidth(); i++) {
       int64_t yval;
@@ -260,9 +267,15 @@ void AnalyzerPanel::render() {
       unsigned rval;
       unsigned gval;
       unsigned bval;
-      yval = *(y - y_width_padding);
-      cbval = *(cb - cb_width_padding);
-      crval = *(cr - cr_width_padding);
+      if (hbd) {
+        yval = *(y16 - y_width_padding);
+        cbval = *(cb16 - cb_width_padding);
+        crval = *(cr16 - cr_width_padding);
+      } else {
+        yval = *(y - y_width_padding);
+        cbval = *(cb - cb_width_padding);
+        crval = *(cr - cr_width_padding);
+      }
       pmask = plane_mask;
       if (pmask & OD_LUMA_MASK) {
         yval -= 16;
@@ -296,16 +309,29 @@ void AnalyzerPanel::render() {
         }
         px_row += p_stride;
       }
-      int dc = ((y - y_row) & 1) | (1 - img->x_chroma_shift);
-      y++;
-      cb += dc;
-      cr += dc;
+      if (hbd) {
+        int dc = ((y16 - y_row16) & 1) | (1 - img->x_chroma_shift);
+        y16++;
+        cb16 += dc;
+        cr16 += dc;
+      } else {
+        int dc = ((y - y_row) & 1) | (1 - img->x_chroma_shift);
+        y++;
+        cb += dc;
+        cr += dc;
+      }
       p += zoom * 3;
     }
     int dc = -((j & 1) | (1 - img->y_chroma_shift));
-    y_row += y_stride;
-    cb_row += dc & cb_stride;
-    cr_row += dc & cr_stride;
+    if (hbd) {
+      y_row16 += y_stride;
+      cb_row16 += dc & cb_stride;
+      cr_row16 += dc & cr_stride;
+    } else {
+      y_row += y_stride;
+      cb_row += dc & cb_stride;
+      cr_row += dc & cr_stride;
+    }
     p_row += zoom * p_stride;
   }
 }
diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
index 294e478af..e5c28711f 100644
--- a/third_party/aom/examples/inspect.c
+++ b/third_party/aom/examples/inspect.c
@@ -138,7 +138,7 @@ const map_entry refs_map[] = { ENUM(INTRA_FRAME),  ENUM(LAST_FRAME),
                                LAST_ENUM };
 
 const map_entry block_size_map[] = {
-#if CONFIG_CB4X4
+#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
   ENUM(BLOCK_2X2),    ENUM(BLOCK_2X4),    ENUM(BLOCK_4X2),
 #endif
   ENUM(BLOCK_4X4),    ENUM(BLOCK_4X8),    ENUM(BLOCK_8X4),
@@ -219,6 +219,22 @@ const map_entry prediction_mode_map[] = { ENUM(DC_PRED),
                                           ENUM(INTRA_INVALID),
                                           LAST_ENUM };
 
+#if CONFIG_CFL
+const map_entry uv_prediction_mode_map[] = {
+  ENUM(UV_DC_PRED),       ENUM(UV_V_PRED),        ENUM(UV_H_PRED),
+  ENUM(UV_D45_PRED),      ENUM(UV_D135_PRED),     ENUM(UV_D117_PRED),
+  ENUM(UV_D153_PRED),     ENUM(UV_D207_PRED),     ENUM(UV_D63_PRED),
+#if CONFIG_ALT_INTRA
+  ENUM(UV_SMOOTH_PRED),
+#if CONFIG_SMOOTH_HV
+  ENUM(UV_SMOOTH_V_PRED), ENUM(UV_SMOOTH_H_PRED),
+#endif  // CONFIG_SMOOTH_HV
+#endif  // CONFIG_ALT_INTRA
+  ENUM(UV_TM_PRED),       ENUM(UV_MODE_INVALID),  LAST_ENUM
+};
+#else
+#define uv_prediction_mode_map prediction_mode_map
+#endif
 #define NO_SKIP 0
 #define SKIP 1
 
@@ -254,6 +270,20 @@ int put_str(char *buffer, const char *str) {
   return i;
 }
 
+int put_str_with_escape(char *buffer, const char *str) {
+  int i;
+  int j = 0;
+  for (i = 0; str[i] != '\0'; i++) {
+    if (str[i] < ' ') {
+      continue;
+    } else if (str[i] == '"' || str[i] == '\\') {
+      buffer[j++] = '\\';
+    }
+    buffer[j++] = str[i];
+  }
+  return j;
+}
+
 int put_num(char *buffer, char prefix, int num, char suffix) {
   int i = 0;
   char *buf = buffer;
@@ -491,7 +521,7 @@ void inspect(void *pbi, void *data) {
                           offsetof(insp_mi_data, mode));
   }
   if (layers & UV_MODE_LAYER) {
-    buf += put_block_info(buf, prediction_mode_map, "uv_mode",
+    buf += put_block_info(buf, uv_prediction_mode_map, "uv_mode",
                           offsetof(insp_mi_data, uv_mode));
   }
   if (layers & SKIP_LAYER) {
@@ -541,8 +571,9 @@ void inspect(void *pbi, void *data) {
   buf += put_str(buf, "  \"config\": {");
   buf += put_map(buf, config_map);
   buf += put_str(buf, "},\n");
-  buf += snprintf(buf, MAX_BUFFER, "  \"configString\": \"%s\"\n",
-                  aom_codec_build_config());
+  buf += put_str(buf, "  \"configString\": \"");
+  buf += put_str_with_escape(buf, aom_codec_build_config());
+  buf += put_str(buf, "\"\n");
   decoded_frame_count++;
   buf += put_str(buf, "},\n");
   *(buf++) = 0;
@@ -602,6 +633,12 @@ const char *get_aom_codec_build_config() { return aom_codec_build_config(); }
 EMSCRIPTEN_KEEPALIVE
 int get_bit_depth() { return img->bit_depth; }
 
+EMSCRIPTEN_KEEPALIVE
+int get_bits_per_sample() { return img->bps; }
+
+EMSCRIPTEN_KEEPALIVE
+int get_image_format() { return img->fmt; }
+
 EMSCRIPTEN_KEEPALIVE
 unsigned char *get_plane(int plane) { return img->planes[plane]; }
 
-- 
cgit v1.2.3


From ec910d81405c736a4490383a250299a7837c2e64 Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Thu, 18 Oct 2018 21:53:44 -0500
Subject: Update aom to commit id e87fb2378f01103d5d6e477a4ef6892dc714e614

---
 third_party/aom/examples/aom_cx_set_ref.c     |   8 +-
 third_party/aom/examples/inspect.c            |  73 ++--
 third_party/aom/examples/lightfield_decoder.c | 188 ++++++++++
 third_party/aom/examples/lightfield_encoder.c | 480 ++++++++++++++++++++++++++
 4 files changed, 705 insertions(+), 44 deletions(-)
 create mode 100644 third_party/aom/examples/lightfield_decoder.c
 create mode 100644 third_party/aom/examples/lightfield_encoder.c

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/aom_cx_set_ref.c b/third_party/aom/examples/aom_cx_set_ref.c
index ff24fa14a..456e81300 100644
--- a/third_party/aom/examples/aom_cx_set_ref.c
+++ b/third_party/aom/examples/aom_cx_set_ref.c
@@ -270,18 +270,18 @@ int main(int argc, char **argv) {
   while (aom_img_read(&raw, infile)) {
     if (limit && frame_in >= limit) break;
     if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
-      aom_ref_frame_t ref;
-      ref.frame_type = AOM_LAST_FRAME;
+      av1_ref_frame_t ref;
+      ref.idx = 0;
       ref.img = raw;
       // Set reference frame in encoder.
-      if (aom_codec_control(&ecodec, AOM_SET_REFERENCE, &ref))
+      if (aom_codec_control(&ecodec, AV1_SET_REFERENCE, &ref))
         die_codec(&ecodec, "Failed to set reference frame");
       printf(" <SET_REF>");
 
       // If set_reference in decoder is commented out, the enc/dec mismatch
       // would be seen.
       if (test_decode) {
-        if (aom_codec_control(&dcodec, AOM_SET_REFERENCE, &ref))
+        if (aom_codec_control(&dcodec, AV1_SET_REFERENCE, &ref))
           die_codec(&dcodec, "Failed to set reference frame");
       }
     }
diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
index e5c28711f..74e770b84 100644
--- a/third_party/aom/examples/inspect.c
+++ b/third_party/aom/examples/inspect.c
@@ -148,6 +148,11 @@ const map_entry block_size_map[] = {
   ENUM(BLOCK_64X64),
 #if CONFIG_EXT_PARTITION
   ENUM(BLOCK_64X128), ENUM(BLOCK_128X64), ENUM(BLOCK_128X128),
+#endif
+  ENUM(BLOCK_4X16),   ENUM(BLOCK_16X4),   ENUM(BLOCK_8X32),
+  ENUM(BLOCK_32X8),   ENUM(BLOCK_16X64),  ENUM(BLOCK_64X16),
+#if CONFIG_EXT_PARTITION
+  ENUM(BLOCK_32X128), ENUM(BLOCK_128X32),
 #endif
   LAST_ENUM
 };
@@ -161,8 +166,12 @@ const map_entry tx_size_map[] = {
   ENUM(TX_64X64),
 #endif
   ENUM(TX_4X8),   ENUM(TX_8X4),   ENUM(TX_8X16),  ENUM(TX_16X8),
-  ENUM(TX_16X32), ENUM(TX_32X16), ENUM(TX_4X16),  ENUM(TX_16X4),
-  ENUM(TX_8X32),  ENUM(TX_32X8),  LAST_ENUM
+  ENUM(TX_16X32), ENUM(TX_32X16),
+#if CONFIG_TX64X64
+  ENUM(TX_32X64), ENUM(TX_64X32),
+#endif  // CONFIG_TX64X64
+  ENUM(TX_4X16),  ENUM(TX_16X4),  ENUM(TX_8X32),  ENUM(TX_32X8),
+  LAST_ENUM
 };
 
 const map_entry tx_type_map[] = { ENUM(DCT_DCT),
@@ -185,52 +194,36 @@ const map_entry tx_type_map[] = { ENUM(DCT_DCT),
 #endif
                                   LAST_ENUM };
 
-const map_entry prediction_mode_map[] = { ENUM(DC_PRED),
-                                          ENUM(V_PRED),
-                                          ENUM(H_PRED),
-                                          ENUM(D45_PRED),
-                                          ENUM(D135_PRED),
-                                          ENUM(D117_PRED),
-                                          ENUM(D153_PRED),
-                                          ENUM(D207_PRED),
-                                          ENUM(D63_PRED),
-#if CONFIG_ALT_INTRA
-                                          ENUM(SMOOTH_PRED),
+const map_entry prediction_mode_map[] = {
+  ENUM(DC_PRED),       ENUM(V_PRED),        ENUM(H_PRED),
+  ENUM(D45_PRED),      ENUM(D135_PRED),     ENUM(D117_PRED),
+  ENUM(D153_PRED),     ENUM(D207_PRED),     ENUM(D63_PRED),
+  ENUM(SMOOTH_PRED),
 #if CONFIG_SMOOTH_HV
-                                          ENUM(SMOOTH_V_PRED),
-                                          ENUM(SMOOTH_H_PRED),
+  ENUM(SMOOTH_V_PRED), ENUM(SMOOTH_H_PRED),
 #endif  // CONFIG_SMOOTH_HV
-#endif  // CONFIG_ALT_INTRA
-                                          ENUM(TM_PRED),
-                                          ENUM(NEARESTMV),
-                                          ENUM(NEARMV),
-                                          ENUM(ZEROMV),
-                                          ENUM(NEWMV),
-#if CONFIG_EXT_INTER
-                                          ENUM(NEAREST_NEARESTMV),
-                                          ENUM(NEAR_NEARMV),
-                                          ENUM(NEAREST_NEWMV),
-                                          ENUM(NEW_NEARESTMV),
-                                          ENUM(NEAR_NEWMV),
-                                          ENUM(NEW_NEARMV),
-                                          ENUM(ZERO_ZEROMV),
-                                          ENUM(NEW_NEWMV),
-#endif
-                                          ENUM(INTRA_INVALID),
-                                          LAST_ENUM };
+  ENUM(TM_PRED),       ENUM(NEARESTMV),     ENUM(NEARMV),
+  ENUM(ZEROMV),        ENUM(NEWMV),         ENUM(NEAREST_NEARESTMV),
+  ENUM(NEAR_NEARMV),   ENUM(NEAREST_NEWMV), ENUM(NEW_NEARESTMV),
+  ENUM(NEAR_NEWMV),    ENUM(NEW_NEARMV),    ENUM(ZERO_ZEROMV),
+  ENUM(NEW_NEWMV),     ENUM(INTRA_INVALID), LAST_ENUM
+};
 
 #if CONFIG_CFL
 const map_entry uv_prediction_mode_map[] = {
-  ENUM(UV_DC_PRED),       ENUM(UV_V_PRED),        ENUM(UV_H_PRED),
-  ENUM(UV_D45_PRED),      ENUM(UV_D135_PRED),     ENUM(UV_D117_PRED),
-  ENUM(UV_D153_PRED),     ENUM(UV_D207_PRED),     ENUM(UV_D63_PRED),
-#if CONFIG_ALT_INTRA
-  ENUM(UV_SMOOTH_PRED),
+  ENUM(UV_DC_PRED),       ENUM(UV_V_PRED),
+  ENUM(UV_H_PRED),        ENUM(UV_D45_PRED),
+  ENUM(UV_D135_PRED),     ENUM(UV_D117_PRED),
+  ENUM(UV_D153_PRED),     ENUM(UV_D207_PRED),
+  ENUM(UV_D63_PRED),      ENUM(UV_SMOOTH_PRED),
 #if CONFIG_SMOOTH_HV
   ENUM(UV_SMOOTH_V_PRED), ENUM(UV_SMOOTH_H_PRED),
 #endif  // CONFIG_SMOOTH_HV
-#endif  // CONFIG_ALT_INTRA
-  ENUM(UV_TM_PRED),       ENUM(UV_MODE_INVALID),  LAST_ENUM
+  ENUM(UV_TM_PRED),
+#if CONFIG_CFL
+  ENUM(UV_CFL_PRED),
+#endif
+  ENUM(UV_MODE_INVALID),  LAST_ENUM
 };
 #else
 #define uv_prediction_mode_map prediction_mode_map
diff --git a/third_party/aom/examples/lightfield_decoder.c b/third_party/aom/examples/lightfield_decoder.c
new file mode 100644
index 000000000..8743df9bc
--- /dev/null
+++ b/third_party/aom/examples/lightfield_decoder.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Lightfield Decoder
+// ==================
+//
+// This is an example of a simple lightfield decoder. It builds upon the
+// simple_decoder.c example.  It takes an input file containing the compressed
+// data (in webm format), treating it as a lightfield instead of a video and
+// will decode a single lightfield tile. The lf_width and lf_height arguments
+// are the number of lightfield images in each dimension. The tile to decode
+// is specified by the tile_u, tile_v, tile_s, tile_t arguments. The tile_u,
+// tile_v specify the image and tile_s, tile_t specify the tile in the image.
+// After running the lightfield encoder, run lightfield decoder to decode a
+// single tile:
+// examples/lightfield_decoder vase10x10.webm vase_tile.yuv 10 10 3 4 5 10 5
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+
+#include "../tools_common.h"
+#include "../video_reader.h"
+#include "./aom_config.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <infile> <outfile> <lf_width> <lf_height> <tlie_u>"
+          " <tile_v> <tile_s> <tile_t> <lf_blocksize>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+aom_image_t *aom_img_copy(aom_image_t *src, aom_image_t *dst) {
+  dst = aom_img_alloc(dst, src->fmt, src->d_w, src->d_h, 16);
+
+  int plane;
+
+  for (plane = 0; plane < 3; ++plane) {
+    uint8_t *src_buf = src->planes[plane];
+    const int src_stride = src->stride[plane];
+    const int src_w = plane == 0 ? src->d_w : src->d_w >> 1;
+    const int src_h = plane == 0 ? src->d_h : src->d_h >> 1;
+
+    uint8_t *dst_buf = dst->planes[plane];
+    const int dst_stride = dst->stride[plane];
+    int y;
+
+    for (y = 0; y < src_h; ++y) {
+      memcpy(dst_buf, src_buf, src_w);
+      src_buf += src_stride;
+      dst_buf += dst_stride;
+    }
+  }
+  return dst;
+}
+
+int main(int argc, char **argv) {
+  int frame_cnt = 0;
+  FILE *outfile = NULL;
+  aom_codec_ctx_t codec;
+  AvxVideoReader *reader = NULL;
+  const AvxInterface *decoder = NULL;
+  const AvxVideoInfo *info = NULL;
+  const char *lf_width_arg;
+  const char *lf_height_arg;
+  const char *tile_u_arg;
+  const char *tile_v_arg;
+  const char *tile_s_arg;
+  const char *tile_t_arg;
+  const char *lf_blocksize_arg;
+  int lf_width, lf_height;
+  int tile_u, tile_v, tile_s, tile_t;
+  int lf_blocksize;
+  int u_blocks;
+  int v_blocks;
+
+  exec_name = argv[0];
+
+  if (argc != 10) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  if (!(outfile = fopen(argv[2], "wb")))
+    die("Failed to open %s for writing.", argv[2]);
+
+  lf_width_arg = argv[3];
+  lf_height_arg = argv[4];
+  tile_u_arg = argv[5];
+  tile_v_arg = argv[6];
+  tile_s_arg = argv[7];
+  tile_t_arg = argv[8];
+  lf_blocksize_arg = argv[9];
+  lf_width = (int)strtol(lf_width_arg, NULL, 0);
+  lf_height = (int)strtol(lf_height_arg, NULL, 0);
+  tile_u = (int)strtol(tile_u_arg, NULL, 0);
+  tile_v = (int)strtol(tile_v_arg, NULL, 0);
+  tile_s = (int)strtol(tile_s_arg, NULL, 0);
+  tile_t = (int)strtol(tile_t_arg, NULL, 0);
+  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
+
+  info = aom_video_reader_get_info(reader);
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  // How many reference images we need to encode.
+  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
+  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
+  aom_image_t *reference_images =
+      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
+  for (int bv = 0; bv < v_blocks; ++bv) {
+    for (int bu = 0; bu < u_blocks; ++bu) {
+      aom_video_reader_read_frame(reader);
+      aom_codec_iter_t iter = NULL;
+      aom_image_t *img = NULL;
+      size_t frame_size = 0;
+      const unsigned char *frame =
+          aom_video_reader_get_frame(reader, &frame_size);
+      if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+        die_codec(&codec, "Failed to decode frame.");
+
+      while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+        aom_img_copy(img, &reference_images[bu + bv * u_blocks]);
+        char name[1024];
+        snprintf(name, sizeof(name), "ref_%d_%d.yuv", bu, bv);
+        printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
+        FILE *ref_file = fopen(name, "wb");
+        aom_img_write(img, ref_file);
+        fclose(ref_file);
+        ++frame_cnt;
+      }
+    }
+  }
+
+  int decode_frame_index = tile_v * lf_width + tile_u;
+  do {
+    aom_video_reader_read_frame(reader);
+  } while (frame_cnt++ != decode_frame_index);
+  size_t frame_size = 0;
+  const unsigned char *frame = aom_video_reader_get_frame(reader, &frame_size);
+
+  int ref_bu = tile_u / lf_blocksize;
+  int ref_bv = tile_v / lf_blocksize;
+  int ref_bi = ref_bu + ref_bv * u_blocks;
+  av1_ref_frame_t ref;
+  ref.idx = 0;
+  ref.img = reference_images[ref_bi];
+  // This is too slow for real lightfield rendering.  This copies the
+  // reference image bytes.  We need a way to just set a pointer
+  // in order to make this fast enough.
+  if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref)) {
+    die_codec(&codec, "Failed to set reference image.");
+  }
+  aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, tile_t);
+  aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, tile_s);
+  aom_codec_err_t aom_status =
+      aom_codec_decode(&codec, frame, frame_size, NULL, 0);
+  if (aom_status) die_codec(&codec, "Failed to decode tile.");
+  aom_codec_iter_t iter = NULL;
+  aom_image_t *img = aom_codec_get_frame(&codec, &iter);
+  aom_img_write(img, outfile);
+
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+  aom_video_reader_close(reader);
+  fclose(outfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/lightfield_encoder.c b/third_party/aom/examples/lightfield_encoder.c
new file mode 100644
index 000000000..0a424db8c
--- /dev/null
+++ b/third_party/aom/examples/lightfield_encoder.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2017, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Lightfield Encoder
+// ==================
+//
+// This is an example of a simple lightfield encoder.  It builds upon the
+// twopass_encoder.c example. It takes an input file in YV12 format,
+// treating it as a planar lightfield instead of a video. The img_width
+// and img_height arguments are the dimensions of the lightfield images,
+// while the lf_width and lf_height arguments are the number of
+// lightfield images in each dimension. The lf_blocksize determines the
+// number of reference images used for MCP. For example, 5 means that there
+// is a reference image for every 5x5 lightfield image block. All images
+// within a block will use the center image in that block as the reference
+// image for MCP.
+// Run "make test" to download lightfield test data: vase10x10.yuv.
+// Run lightfield encoder to encode whole lightfield:
+// examples/lightfield_encoder 1024 1024 vase10x10.yuv vase10x10.webm 10 10 5
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+#include "aom/aomcx.h"
+#include "av1/common/enums.h"
+
+#include "../tools_common.h"
+#include "../video_writer.h"
+
+static const char *exec_name;
+static const unsigned int deadline = AOM_DL_GOOD_QUALITY;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <img_width> <img_height> <infile> <outfile> "
+          "<lf_width> <lf_height> <lf_blocksize>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static aom_image_t *aom_img_copy(aom_image_t *src, aom_image_t *dst) {
+  dst = aom_img_alloc(dst, src->fmt, src->d_w, src->d_h, 16);
+
+  int plane;
+
+  for (plane = 0; plane < 3; ++plane) {
+    unsigned char *src_buf = src->planes[plane];
+    const int src_stride = src->stride[plane];
+    const int src_w = plane == 0 ? src->d_w : src->d_w >> 1;
+    const int src_h = plane == 0 ? src->d_h : src->d_h >> 1;
+
+    unsigned char *dst_buf = dst->planes[plane];
+    const int dst_stride = dst->stride[plane];
+    int y;
+
+    for (y = 0; y < src_h; ++y) {
+      memcpy(dst_buf, src_buf, src_w);
+      src_buf += src_stride;
+      dst_buf += dst_stride;
+    }
+  }
+  return dst;
+}
+
+static int aom_img_size_bytes(aom_image_t *img) {
+  int image_size_bytes = 0;
+  int plane;
+  for (plane = 0; plane < 3; ++plane) {
+    const int stride = img->stride[plane];
+    const int w = aom_img_plane_width(img, plane) *
+                  ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
+    const int h = aom_img_plane_height(img, plane);
+    image_size_bytes += (w + stride) * h;
+  }
+  return image_size_bytes;
+}
+
+static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
+                           aom_codec_pts_t pts, unsigned int duration,
+                           aom_enc_frame_flags_t flags, unsigned int dl,
+                           aom_fixed_buf_t *stats) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(ctx, img, pts, duration, flags, dl);
+  if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
+
+  while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_STATS_PKT) {
+      const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf;
+      const size_t pkt_size = pkt->data.twopass_stats.sz;
+      stats->buf = realloc(stats->buf, stats->sz + pkt_size);
+      memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size);
+      stats->sz += pkt_size;
+    }
+  }
+
+  return got_pkts;
+}
+
+static int encode_frame(aom_codec_ctx_t *ctx, const aom_image_t *img,
+                        aom_codec_pts_t pts, unsigned int duration,
+                        aom_enc_frame_flags_t flags, unsigned int dl,
+                        AvxVideoWriter *writer) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(ctx, img, pts, duration, flags, dl);
+  if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
+
+  while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
+    got_pkts = 1;
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+
+      if (!aom_video_writer_write_frame(writer, pkt->data.frame.buf,
+                                        pkt->data.frame.sz,
+                                        pkt->data.frame.pts))
+        die_codec(ctx, "Failed to write compressed frame.");
+      printf(keyframe ? "K" : ".");
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
+                             const AvxInterface *encoder,
+                             const aom_codec_enc_cfg_t *cfg, int lf_width,
+                             int lf_height, int lf_blocksize) {
+  aom_codec_ctx_t codec;
+  int frame_count = 0;
+  int image_size_bytes = 0;
+  int u_blocks, v_blocks;
+  int bu, bv;
+  aom_fixed_buf_t stats = { NULL, 0 };
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
+    die_codec(&codec, "Failed to set frame parallel decoding");
+  if (aom_codec_control(&codec, AOME_SET_ENABLEAUTOALTREF, 0))
+    die_codec(&codec, "Failed to turn off auto altref");
+  if (aom_codec_control(&codec, AV1E_SET_SINGLE_TILE_DECODING, 1))
+    die_codec(&codec, "Failed to turn on single tile decoding");
+
+  image_size_bytes = aom_img_size_bytes(raw);
+
+  // How many reference images we need to encode.
+  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
+  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
+  aom_image_t *reference_images =
+      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
+  for (bv = 0; bv < v_blocks; ++bv) {
+    for (bu = 0; bu < u_blocks; ++bu) {
+      const int block_u_min = bu * lf_blocksize;
+      const int block_v_min = bv * lf_blocksize;
+      int block_u_end = (bu + 1) * lf_blocksize;
+      int block_v_end = (bv + 1) * lf_blocksize;
+      int u_block_size, v_block_size;
+      int block_ref_u, block_ref_v;
+      struct av1_ref_frame ref_frame;
+
+      block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
+      block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
+      u_block_size = block_u_end - block_u_min;
+      v_block_size = block_v_end - block_v_min;
+      block_ref_u = block_u_min + u_block_size / 2;
+      block_ref_v = block_v_min + v_block_size / 2;
+      fseek(infile, (block_ref_u + block_ref_v * lf_width) * image_size_bytes,
+            SEEK_SET);
+      aom_img_read(raw, infile);
+      if (aom_codec_control(&codec, AOME_USE_REFERENCE,
+                            AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
+        die_codec(&codec, "Failed to set reference flags");
+      // Reference frames can be encoded encoded without tiles.
+      ++frame_count;
+      get_frame_stats(&codec, raw, frame_count, 1,
+                      AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
+                      &stats);
+      ref_frame.idx = 0;
+      aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
+      aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
+    }
+  }
+  for (bv = 0; bv < v_blocks; ++bv) {
+    for (bu = 0; bu < u_blocks; ++bu) {
+      const int block_u_min = bu * lf_blocksize;
+      const int block_v_min = bv * lf_blocksize;
+      int block_u_end = (bu + 1) * lf_blocksize;
+      int block_v_end = (bv + 1) * lf_blocksize;
+      int u, v;
+      block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
+      block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
+      for (v = block_v_min; v < block_v_end; ++v) {
+        for (u = block_u_min; u < block_u_end; ++u) {
+          // This was a work around for a bug in libvpx.  I'm not sure if this
+          // same bug exists in current version of av1.  Need to call this,
+          // otherwise the default is to not use any reference frames.  Then
+          // if you don't have at least one AOM_EFLAG_NO_REF_* flag, all frames
+          // will be intra encoded.  I'm not sure why the default is not to use
+          // any reference frames.  It looks like there is something about the
+          // way I encode the reference frames above that sets that as
+          // default...
+          if (aom_codec_control(&codec, AOME_USE_REFERENCE,
+                                AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
+            die_codec(&codec, "Failed to set reference flags");
+
+          // Set tile size to 64 pixels. The tile_columns and
+          // tile_rows in the tile coding are overloaded to represent
+          // tile_width and tile_height, that range from 1 to 64, in the unit
+          // of 64 pixels.
+          if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 1))
+            die_codec(&codec, "Failed to set tile width");
+          if (aom_codec_control(&codec, AV1E_SET_TILE_ROWS, 1))
+            die_codec(&codec, "Failed to set tile height");
+
+          av1_ref_frame_t ref;
+          ref.idx = 0;
+          ref.img = reference_images[bv * u_blocks + bu];
+          if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref))
+            die_codec(&codec, "Failed to set reference frame");
+
+          fseek(infile, (u + v * lf_width) * image_size_bytes, SEEK_SET);
+          aom_img_read(raw, infile);
+          ++frame_count;
+          get_frame_stats(&codec, raw, frame_count, 1,
+                          AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                              AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY |
+                              AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF,
+                          deadline, &stats);
+        }
+      }
+    }
+  }
+  // Flush encoder.
+  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, deadline, &stats)) {
+  }
+
+  printf("Pass 0 complete. Processed %d frames.\n", frame_count);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  return stats;
+}
+
+static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
+                  const AvxInterface *encoder, const aom_codec_enc_cfg_t *cfg,
+                  int lf_width, int lf_height, int lf_blocksize) {
+  AvxVideoInfo info = { encoder->fourcc,
+                        cfg->g_w,
+                        cfg->g_h,
+                        { cfg->g_timebase.num, cfg->g_timebase.den } };
+  AvxVideoWriter *writer = NULL;
+  aom_codec_ctx_t codec;
+  int frame_count = 0;
+  int image_size_bytes;
+  int bu, bv;
+  int u_blocks, v_blocks;
+
+  writer = aom_video_writer_open(outfile_name, kContainerIVF, &info);
+  if (!writer) die("Failed to open %s for writing", outfile_name);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
+    die_codec(&codec, "Failed to set frame parallel decoding");
+  if (aom_codec_control(&codec, AOME_SET_ENABLEAUTOALTREF, 0))
+    die_codec(&codec, "Failed to turn off auto altref");
+  if (aom_codec_control(&codec, AV1E_SET_SINGLE_TILE_DECODING, 1))
+    die_codec(&codec, "Failed to turn on single tile decoding");
+
+  image_size_bytes = aom_img_size_bytes(raw);
+  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
+  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
+  aom_image_t *reference_images =
+      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
+  // Encode reference images first.
+  printf("Encoding Reference Images\n");
+  for (bv = 0; bv < v_blocks; ++bv) {
+    for (bu = 0; bu < u_blocks; ++bu) {
+      const int block_u_min = bu * lf_blocksize;
+      const int block_v_min = bv * lf_blocksize;
+      int block_u_end = (bu + 1) * lf_blocksize;
+      int block_v_end = (bv + 1) * lf_blocksize;
+      int u_block_size, v_block_size;
+      int block_ref_u, block_ref_v;
+      struct av1_ref_frame ref_frame;
+
+      block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
+      block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
+      u_block_size = block_u_end - block_u_min;
+      v_block_size = block_v_end - block_v_min;
+      block_ref_u = block_u_min + u_block_size / 2;
+      block_ref_v = block_v_min + v_block_size / 2;
+      fseek(infile, (block_ref_u + block_ref_v * lf_width) * image_size_bytes,
+            SEEK_SET);
+      aom_img_read(raw, infile);
+      if (aom_codec_control(&codec, AOME_USE_REFERENCE,
+                            AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
+        die_codec(&codec, "Failed to set reference flags");
+      // Reference frames may be encoded without tiles.
+      ++frame_count;
+      printf("Encoding reference image %d of %d\n", bv * u_blocks + bu,
+             u_blocks * v_blocks);
+      encode_frame(&codec, raw, frame_count, 1,
+                   AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
+                   writer);
+      ref_frame.idx = 0;
+      aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
+      aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
+    }
+  }
+
+  for (bv = 0; bv < v_blocks; ++bv) {
+    for (bu = 0; bu < u_blocks; ++bu) {
+      const int block_u_min = bu * lf_blocksize;
+      const int block_v_min = bv * lf_blocksize;
+      int block_u_end = (bu + 1) * lf_blocksize;
+      int block_v_end = (bv + 1) * lf_blocksize;
+      int u, v;
+      block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
+      block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
+      for (v = block_v_min; v < block_v_end; ++v) {
+        for (u = block_u_min; u < block_u_end; ++u) {
+          // This was a work around for a bug in libvpx.  I'm not sure if this
+          // same bug exists in current version of av1.  Need to call this,
+          // otherwise the default is to not use any reference frames.  Then
+          // if you don't have at least one AOM_EFLAG_NO_REF_* flag, all frames
+          // will be intra encoded.  I'm not sure why the default is not to use
+          // any reference frames.  It looks like there is something about the
+          // way I encode the reference frames above that sets that as
+          // default...
+          if (aom_codec_control(&codec, AOME_USE_REFERENCE,
+                                AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
+            die_codec(&codec, "Failed to set reference flags");
+
+          // Set tile size to 64 pixels. The tile_columns and
+          // tile_rows in the tile coding are overloaded to represent tile_width
+          // and tile_height, that range from 1 to 64, in the unit of 64 pixels.
+          if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 1))
+            die_codec(&codec, "Failed to set tile width");
+          if (aom_codec_control(&codec, AV1E_SET_TILE_ROWS, 1))
+            die_codec(&codec, "Failed to set tile height");
+
+          av1_ref_frame_t ref;
+          ref.idx = 0;
+          ref.img = reference_images[bv * u_blocks + bu];
+          if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref))
+            die_codec(&codec, "Failed to set reference frame");
+          fseek(infile, (u + v * lf_width) * image_size_bytes, SEEK_SET);
+          aom_img_read(raw, infile);
+          ++frame_count;
+
+          printf("Encoding image %d of %d\n",
+                 frame_count - (u_blocks * v_blocks), lf_width * lf_height);
+          encode_frame(&codec, raw, frame_count, 1,
+                       AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                           AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY |
+                           AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF,
+                       deadline, writer);
+        }
+      }
+    }
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, 1, 0, deadline, writer)) {
+  }
+
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  aom_video_writer_close(writer);
+
+  printf("Pass 1 complete. Processed %d frames.\n", frame_count);
+}
+
+int main(int argc, char **argv) {
+  FILE *infile = NULL;
+  int w, h;
+  // The number of lightfield images in the u and v dimensions.
+  int lf_width, lf_height;
+  // Defines how many images refer to the same reference image for MCP.
+  // lf_blocksize X lf_blocksize images will all use the reference image
+  // in the middle of the block of images.
+  int lf_blocksize;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  aom_image_t raw;
+  aom_codec_err_t res;
+  aom_fixed_buf_t stats;
+
+  const AvxInterface *encoder = NULL;
+  const int fps = 30;
+  const int bitrate = 200;  // kbit/s
+  const char *const width_arg = argv[1];
+  const char *const height_arg = argv[2];
+  const char *const infile_arg = argv[3];
+  const char *const outfile_arg = argv[4];
+  const char *const lf_width_arg = argv[5];
+  const char *const lf_height_arg = argv[6];
+  const char *lf_blocksize_arg = argv[7];
+  exec_name = argv[0];
+
+  if (argc < 8) die("Invalid number of arguments");
+
+  encoder = get_aom_encoder_by_name("av1");
+  if (!encoder) die("Unsupported codec.");
+
+  w = (int)strtol(width_arg, NULL, 0);
+  h = (int)strtol(height_arg, NULL, 0);
+  lf_width = (int)strtol(lf_width_arg, NULL, 0);
+  lf_height = (int)strtol(lf_height_arg, NULL, 0);
+  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
+  lf_blocksize = lf_blocksize < lf_width ? lf_blocksize : lf_width;
+  lf_blocksize = lf_blocksize < lf_height ? lf_blocksize : lf_height;
+
+  if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
+    die("Invalid frame size: %dx%d", w, h);
+  if (lf_width <= 0 || lf_height <= 0)
+    die("Invalid lf_width and/or lf_height: %dx%d", lf_width, lf_height);
+  if (lf_blocksize <= 0) die("Invalid lf_blocksize: %d", lf_blocksize);
+
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, w, h, 1))
+    die("Failed to allocate image", w, h);
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  // Configuration
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = w;
+  cfg.g_h = h;
+  cfg.g_timebase.num = 1;
+  cfg.g_timebase.den = fps;
+  cfg.rc_target_bitrate = bitrate;
+  cfg.g_error_resilient = AOM_ERROR_RESILIENT_DEFAULT;
+  // Need to set lag_in_frames to 1 or 0.  Otherwise the frame flags get
+  // overridden after the first frame in encode_frame_to_data_rate() (see where
+  // get_frame_flags() is called).
+  cfg.g_lag_in_frames = 0;
+  cfg.kf_mode = AOM_KF_DISABLED;
+  cfg.large_scale_tile = 1;
+
+  if (!(infile = fopen(infile_arg, "rb")))
+    die("Failed to open %s for reading", infile_arg);
+
+  // Pass 0
+  cfg.g_pass = AOM_RC_FIRST_PASS;
+  stats = pass0(&raw, infile, encoder, &cfg, lf_width, lf_height, lf_blocksize);
+
+  // Pass 1
+  rewind(infile);
+  cfg.g_pass = AOM_RC_LAST_PASS;
+  cfg.rc_twopass_stats_in = stats;
+  pass1(&raw, infile, outfile_arg, encoder, &cfg, lf_width, lf_height,
+        lf_blocksize);
+  free(stats.buf);
+
+  aom_img_free(&raw);
+  fclose(infile);
+
+  return EXIT_SUCCESS;
+}
-- 
cgit v1.2.3


From bbcc64772580c8a979288791afa02d30bc476d2e Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Fri, 19 Oct 2018 21:52:15 -0500
Subject: Update aom to v1.0.0

Update aom to commit id d14c5bb4f336ef1842046089849dee4a301fbbf0.
---
 third_party/aom/examples/analyzer.cc               |  58 +--
 third_party/aom/examples/aom_cx_set_ref.c          | 119 ++++--
 third_party/aom/examples/decode_to_md5.c           |  12 +-
 third_party/aom/examples/decode_with_drops.c       |  13 +-
 third_party/aom/examples/encoder_util.c            |  45 +--
 third_party/aom/examples/encoder_util.h            |   3 -
 third_party/aom/examples/inspect.c                 | 260 +++++++------
 .../aom/examples/lightfield_bitstream_parsing.c    | 343 +++++++++++++++++
 third_party/aom/examples/lightfield_decoder.c      | 233 ++++++-----
 third_party/aom/examples/lightfield_encoder.c      | 323 ++++++++--------
 .../aom/examples/lightfield_tile_list_decoder.c    | 172 +++++++++
 third_party/aom/examples/lossless_encoder.c        |   7 +-
 third_party/aom/examples/noise_model.c             | 426 +++++++++++++++++++++
 third_party/aom/examples/resize_util.c             |   4 +-
 third_party/aom/examples/scalable_decoder.c        | 185 +++++++++
 third_party/aom/examples/scalable_encoder.c        | 289 ++++++++++++++
 third_party/aom/examples/set_maps.c                |  10 +-
 third_party/aom/examples/simple_decoder.c          |  12 +-
 third_party/aom/examples/simple_encoder.c          |   7 +-
 third_party/aom/examples/twopass_encoder.c         |  26 +-
 20 files changed, 2041 insertions(+), 506 deletions(-)
 create mode 100644 third_party/aom/examples/lightfield_bitstream_parsing.c
 create mode 100644 third_party/aom/examples/lightfield_tile_list_decoder.c
 create mode 100644 third_party/aom/examples/noise_model.c
 create mode 100644 third_party/aom/examples/scalable_decoder.c
 create mode 100644 third_party/aom/examples/scalable_encoder.c

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/analyzer.cc b/third_party/aom/examples/analyzer.cc
index ae0801964..6a42eca24 100644
--- a/third_party/aom/examples/analyzer.cc
+++ b/third_party/aom/examples/analyzer.cc
@@ -12,13 +12,14 @@
 #include <wx/aboutdlg.h>
 #include <wx/cmdline.h>
 #include <wx/dcbuffer.h>
-#include "./tools_common.h"
-#include "./video_reader.h"
+
 #include "aom/aom_decoder.h"
 #include "aom/aomdx.h"
-#include "av1/decoder/accounting.h"
 #include "av1/common/onyxc_int.h"
+#include "av1/decoder/accounting.h"
 #include "av1/decoder/inspection.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
 
 #define OD_SIGNMASK(a) (-((a) < 0))
 #define OD_FLIPSIGNI(a, b) (((a) + OD_SIGNMASK(b)) ^ OD_SIGNMASK(b))
@@ -108,7 +109,7 @@ bool AV1Decoder::step() {
     size_t frame_size;
     const unsigned char *frame_data;
     frame_data = aom_video_reader_get_frame(reader, &frame_size);
-    if (aom_codec_decode(&codec, frame_data, frame_size, NULL, 0)) {
+    if (aom_codec_decode(&codec, frame_data, frame_size, NULL)) {
       fprintf(stderr, "Failed to decode frame.");
       return false;
     } else {
@@ -129,11 +130,10 @@ int AV1Decoder::getWidth() const {
 }
 
 int AV1Decoder::getWidthPadding() const {
-  return show_padding
-             ? AOMMAX(info->frame_width + 16,
-                      ALIGN_POWER_OF_TWO(info->frame_width, 6)) -
-                   info->frame_width
-             : 0;
+  return show_padding ? AOMMAX(info->frame_width + 16,
+                               ALIGN_POWER_OF_TWO(info->frame_width, 6)) -
+                            info->frame_width
+                      : 0;
 }
 
 int AV1Decoder::getHeight() const {
@@ -141,11 +141,10 @@ int AV1Decoder::getHeight() const {
 }
 
 int AV1Decoder::getHeightPadding() const {
-  return show_padding
-             ? AOMMAX(info->frame_height + 16,
-                      ALIGN_POWER_OF_TWO(info->frame_height, 6)) -
-                   info->frame_height
-             : 0;
+  return show_padding ? AOMMAX(info->frame_height + 16,
+                               ALIGN_POWER_OF_TWO(info->frame_height, 6)) -
+                            info->frame_height
+                      : 0;
 }
 
 bool AV1Decoder::getAccountingStruct(Accounting **accounting) {
@@ -285,19 +284,22 @@ void AnalyzerPanel::render() {
       cbval = ((pmask & OD_CB_MASK) >> 1) * (cbval - 128);
       crval = ((pmask & OD_CR_MASK) >> 2) * (crval - 128);
       /*This is intentionally slow and very accurate.*/
-      rval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
-                              2916394880000LL * yval + 4490222169144LL * crval,
-                              9745792000LL),
-                       65535);
-      gval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(2916394880000LL * yval -
-                                                    534117096223LL * cbval -
-                                                    1334761232047LL * crval,
-                                                9745792000LL),
-                       65535);
-      bval = OD_CLAMPI(0, (int32_t)OD_DIV_ROUND(
-                              2916394880000LL * yval + 5290866304968LL * cbval,
-                              9745792000LL),
+      rval = OD_CLAMPI(
+          0,
+          (int32_t)OD_DIV_ROUND(
+              2916394880000LL * yval + 4490222169144LL * crval, 9745792000LL),
+          65535);
+      gval = OD_CLAMPI(0,
+                       (int32_t)OD_DIV_ROUND(2916394880000LL * yval -
+                                                 534117096223LL * cbval -
+                                                 1334761232047LL * crval,
+                                             9745792000LL),
                        65535);
+      bval = OD_CLAMPI(
+          0,
+          (int32_t)OD_DIV_ROUND(
+              2916394880000LL * yval + 5290866304968LL * cbval, 9745792000LL),
+          65535);
       unsigned char *px_row = p;
       for (int v = 0; v < zoom; v++) {
         unsigned char *px = px_row;
@@ -701,8 +703,8 @@ bool Analyzer::OnCmdLineParsed(wxCmdLineParser &parser) {  // NOLINT
   bool bit_accounting = parser.Found(_("a"));
   if (bit_accounting && !CONFIG_ACCOUNTING) {
     fprintf(stderr,
-            "Bit accounting support not found.  "
-            "Recompile with:\n./configure --enable-accounting\n");
+            "Bit accounting support not found. "
+            "Recompile with:\n./cmake -DCONFIG_ACCOUNTING=1\n");
     return false;
   }
   frame = new AnalyzerFrame(parser.Found(_("a")));
diff --git a/third_party/aom/examples/aom_cx_set_ref.c b/third_party/aom/examples/aom_cx_set_ref.c
index 456e81300..e02e94c07 100644
--- a/third_party/aom/examples/aom_cx_set_ref.c
+++ b/third_party/aom/examples/aom_cx_set_ref.c
@@ -51,12 +51,14 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "aom/aomcx.h"
 #include "aom/aom_decoder.h"
 #include "aom/aom_encoder.h"
+#include "aom/aomcx.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
 #include "examples/encoder_util.h"
-#include "./tools_common.h"
-#include "./video_writer.h"
+
+#define AOM_BORDER_IN_PIXELS 288
 
 static const char *exec_name;
 
@@ -71,25 +73,41 @@ void usage_exit() {
 static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
                            unsigned int frame_out, int *mismatch_seen) {
   aom_image_t enc_img, dec_img;
-  struct av1_ref_frame ref_enc, ref_dec;
 
   if (*mismatch_seen) return;
 
-  ref_enc.idx = 0;
-  ref_dec.idx = 0;
-  if (aom_codec_control(encoder, AV1_GET_REFERENCE, &ref_enc))
+  /* Get the internal reference frame */
+  if (aom_codec_control(encoder, AV1_GET_NEW_FRAME_IMAGE, &enc_img))
     die_codec(encoder, "Failed to get encoder reference frame");
-  enc_img = ref_enc.img;
-  if (aom_codec_control(decoder, AV1_GET_REFERENCE, &ref_dec))
+  if (aom_codec_control(decoder, AV1_GET_NEW_FRAME_IMAGE, &dec_img))
     die_codec(decoder, "Failed to get decoder reference frame");
-  dec_img = ref_dec.img;
+
+  if ((enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) !=
+      (dec_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH)) {
+    if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
+      aom_image_t enc_hbd_img;
+      aom_img_alloc(&enc_hbd_img, enc_img.fmt - AOM_IMG_FMT_HIGHBITDEPTH,
+                    enc_img.d_w, enc_img.d_h, 16);
+      aom_img_truncate_16_to_8(&enc_hbd_img, &enc_img);
+      enc_img = enc_hbd_img;
+    }
+    if (dec_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
+      aom_image_t dec_hbd_img;
+      aom_img_alloc(&dec_hbd_img, dec_img.fmt - AOM_IMG_FMT_HIGHBITDEPTH,
+                    dec_img.d_w, dec_img.d_h, 16);
+      aom_img_truncate_16_to_8(&dec_hbd_img, &dec_img);
+      dec_img = dec_hbd_img;
+    }
+  }
 
   if (!aom_compare_img(&enc_img, &dec_img)) {
     int y[4], u[4], v[4];
+    if (enc_img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
+      aom_find_mismatch_high(&enc_img, &dec_img, y, u, v);
+    } else {
+      aom_find_mismatch(&enc_img, &dec_img, y, u, v);
+    }
 
-    *mismatch_seen = 1;
-
-    aom_find_mismatch(&enc_img, &dec_img, y, u, v);
     printf(
         "Encode/decode mismatch on frame %d at"
         " Y[%d, %d] {%d/%d},"
@@ -97,6 +115,7 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
         " V[%d, %d] {%d/%d}",
         frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
         v[2], v[3]);
+    *mismatch_seen = 1;
   }
 
   aom_img_free(&enc_img);
@@ -106,13 +125,13 @@ static void testing_decode(aom_codec_ctx_t *encoder, aom_codec_ctx_t *decoder,
 static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
                         unsigned int frame_in, AvxVideoWriter *writer,
                         int test_decode, aom_codec_ctx_t *dcodec,
-                        unsigned int *frame_out, int *mismatch_seen) {
+                        unsigned int *frame_out, int *mismatch_seen,
+                        aom_image_t *ext_ref) {
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
   int got_data;
-  const aom_codec_err_t res =
-      aom_codec_encode(ecodec, img, frame_in, 1, 0, AOM_DL_GOOD_QUALITY);
+  const aom_codec_err_t res = aom_codec_encode(ecodec, img, frame_in, 1, 0);
   if (res != AOM_CODEC_OK) die_codec(ecodec, "Failed to encode frame");
 
   got_data = 0;
@@ -139,8 +158,13 @@ static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
       // Decode 1 frame.
       if (test_decode) {
         if (aom_codec_decode(dcodec, pkt->data.frame.buf,
-                             (unsigned int)pkt->data.frame.sz, NULL, 0))
+                             (unsigned int)pkt->data.frame.sz, NULL))
           die_codec(dcodec, "Failed to decode frame.");
+
+        // Copy out first decoded frame, and use it as reference later.
+        if (*frame_out == 1 && ext_ref != NULL)
+          if (aom_codec_control(dcodec, AV1_GET_NEW_FRAME_IMAGE, ext_ref))
+            die_codec(dcodec, "Failed to get decoder new frame");
       }
     }
   }
@@ -160,10 +184,16 @@ int main(int argc, char **argv) {
   aom_codec_enc_cfg_t cfg;
   unsigned int frame_in = 0;
   aom_image_t raw;
+  aom_image_t raw_shift;
+  aom_image_t ext_ref;
   aom_codec_err_t res;
   AvxVideoInfo info;
   AvxVideoWriter *writer = NULL;
   const AvxInterface *encoder = NULL;
+  int flags = 0;
+  int allocated_raw_shift = 0;
+  aom_img_fmt_t raw_fmt = AOM_IMG_FMT_I420;
+  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
 
   // Test encoder/decoder mismatch.
   int test_decode = 1;
@@ -225,13 +255,21 @@ int main(int argc, char **argv) {
   info.time_base.numerator = 1;
   info.time_base.denominator = fps;
 
-  if (info.frame_width <= 0 || info.frame_height <= 0 ||
-      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+  if (info.frame_width <= 0 || info.frame_height <= 0) {
     die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
   }
 
-  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, info.frame_width,
-                     info.frame_height, 1)) {
+  // In this test, the bit depth of input video is 8-bit, and the input format
+  // is AOM_IMG_FMT_I420.
+  if (!aom_img_alloc(&raw, raw_fmt, info.frame_width, info.frame_height, 32)) {
+    die("Failed to allocate image.");
+  }
+
+  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  // Allocate memory with the border so that it can be used as a reference.
+  if (!aom_img_alloc_with_border(&ext_ref, ref_fmt, info.frame_width,
+                                 info.frame_height, 32, 8,
+                                 AOM_BORDER_IN_PIXELS)) {
     die("Failed to allocate image.");
   }
 
@@ -246,6 +284,11 @@ int main(int argc, char **argv) {
   cfg.g_timebase.den = info.time_base.denominator;
   cfg.rc_target_bitrate = bitrate;
   cfg.g_lag_in_frames = 3;
+  cfg.g_bit_depth = AOM_BITS_8;
+
+  flags |= (cfg.g_bit_depth > AOM_BITS_8 || !CONFIG_LOWBITDEPTH)
+               ? AOM_CODEC_USE_HIGHBITDEPTH
+               : 0;
 
   writer = aom_video_writer_open(outfile_arg, kContainerIVF, &info);
   if (!writer) die("Failed to open %s for writing.", outfile_arg);
@@ -253,7 +296,7 @@ int main(int argc, char **argv) {
   if (!(infile = fopen(infile_arg, "rb")))
     die("Failed to open %s for reading.", infile_arg);
 
-  if (aom_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
+  if (aom_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, flags))
     die_codec(&ecodec, "Failed to initialize encoder");
 
   // Disable alt_ref.
@@ -269,25 +312,43 @@ int main(int argc, char **argv) {
   // Encode frames.
   while (aom_img_read(&raw, infile)) {
     if (limit && frame_in >= limit) break;
+    aom_image_t *frame_to_encode;
+
+    if (!CONFIG_LOWBITDEPTH) {
+      // Need to allocate larger buffer to use hbd internal.
+      int input_shift = 0;
+      if (!allocated_raw_shift) {
+        aom_img_alloc(&raw_shift, raw_fmt | AOM_IMG_FMT_HIGHBITDEPTH,
+                      info.frame_width, info.frame_height, 32);
+        allocated_raw_shift = 1;
+      }
+      aom_img_upshift(&raw_shift, &raw, input_shift);
+      frame_to_encode = &raw_shift;
+    } else {
+      frame_to_encode = &raw;
+    }
+
     if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
       av1_ref_frame_t ref;
       ref.idx = 0;
-      ref.img = raw;
+      ref.use_external_ref = 0;
+      ref.img = ext_ref;
       // Set reference frame in encoder.
       if (aom_codec_control(&ecodec, AV1_SET_REFERENCE, &ref))
-        die_codec(&ecodec, "Failed to set reference frame");
+        die_codec(&ecodec, "Failed to set encoder reference frame");
       printf(" <SET_REF>");
 
       // If set_reference in decoder is commented out, the enc/dec mismatch
       // would be seen.
       if (test_decode) {
+        ref.use_external_ref = 1;
         if (aom_codec_control(&dcodec, AV1_SET_REFERENCE, &ref))
-          die_codec(&dcodec, "Failed to set reference frame");
+          die_codec(&dcodec, "Failed to set decoder reference frame");
       }
     }
 
-    encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
-                 &frame_out, &mismatch_seen);
+    encode_frame(&ecodec, frame_to_encode, frame_in, writer, test_decode,
+                 &dcodec, &frame_out, &mismatch_seen, &ext_ref);
     frame_in++;
     if (mismatch_seen) break;
   }
@@ -295,7 +356,7 @@ int main(int argc, char **argv) {
   // Flush encoder.
   if (!mismatch_seen)
     while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
-                        &frame_out, &mismatch_seen)) {
+                        &frame_out, &mismatch_seen, NULL)) {
     }
 
   printf("\n");
@@ -313,6 +374,8 @@ int main(int argc, char **argv) {
     if (aom_codec_destroy(&dcodec))
       die_codec(&dcodec, "Failed to destroy decoder");
 
+  if (allocated_raw_shift) aom_img_free(&raw_shift);
+  aom_img_free(&ext_ref);
   aom_img_free(&raw);
   if (aom_codec_destroy(&ecodec))
     die_codec(&ecodec, "Failed to destroy encoder.");
diff --git a/third_party/aom/examples/decode_to_md5.c b/third_party/aom/examples/decode_to_md5.c
index 5ab253209..bc127b78d 100644
--- a/third_party/aom/examples/decode_to_md5.c
+++ b/third_party/aom/examples/decode_to_md5.c
@@ -34,13 +34,11 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "aom/aomdx.h"
 #include "aom/aom_decoder.h"
-
-#include "../md5_utils.h"
-#include "../tools_common.h"
-#include "../video_reader.h"
-#include "./aom_config.h"
+#include "aom/aomdx.h"
+#include "common/md5_utils.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
 
 static void get_image_md5(const aom_image_t *img, unsigned char digest[16]) {
   int plane, y;
@@ -110,7 +108,7 @@ int main(int argc, char **argv) {
     size_t frame_size = 0;
     const unsigned char *frame =
         aom_video_reader_get_frame(reader, &frame_size);
-    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame");
 
     while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
diff --git a/third_party/aom/examples/decode_with_drops.c b/third_party/aom/examples/decode_with_drops.c
index 45e0fb027..214401958 100644
--- a/third_party/aom/examples/decode_with_drops.c
+++ b/third_party/aom/examples/decode_with_drops.c
@@ -57,12 +57,10 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "aom/aomdx.h"
 #include "aom/aom_decoder.h"
-
-#include "../tools_common.h"
-#include "../video_reader.h"
-#include "./aom_config.h"
+#include "aom/aomdx.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
 
 static const char *exec_name;
 
@@ -116,9 +114,6 @@ int main(int argc, char **argv) {
     int skip;
     const unsigned char *frame =
         aom_video_reader_get_frame(reader, &frame_size);
-    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
-      die_codec(&codec, "Failed to decode frame.");
-
     ++frame_cnt;
 
     skip = (is_range && frame_cnt >= n && frame_cnt <= m) ||
@@ -126,6 +121,8 @@ int main(int argc, char **argv) {
 
     if (!skip) {
       putc('.', stdout);
+      if (aom_codec_decode(&codec, frame, frame_size, NULL))
+        die_codec(&codec, "Failed to decode frame.");
 
       while ((img = aom_codec_get_frame(&codec, &iter)) != NULL)
         aom_img_write(img, outfile);
diff --git a/third_party/aom/examples/encoder_util.c b/third_party/aom/examples/encoder_util.c
index 1aa3a7eef..e43b37250 100644
--- a/third_party/aom/examples/encoder_util.c
+++ b/third_party/aom/examples/encoder_util.c
@@ -11,10 +11,11 @@
 
 // Utility functions used by encoder binaries.
 
+#include "examples/encoder_util.h"
+
 #include <assert.h>
 #include <string.h>
 
-#include "./encoder_util.h"
 #include "aom/aom_integer.h"
 
 #define mmin(a, b) ((a) < (b) ? (a) : (b))
@@ -40,6 +41,7 @@ static void find_mismatch_plane(const aom_image_t *const img1,
   assert(img1->x_chroma_shift == img2->x_chroma_shift &&
          img1->y_chroma_shift == img2->y_chroma_shift);
   loc[0] = loc[1] = loc[2] = loc[3] = -1;
+  if (img1->monochrome && img2->monochrome && plane) return;
   int match = 1;
   uint32_t i, j;
   for (i = 0; match && i < c_h; i += bsizey) {
@@ -79,21 +81,16 @@ static void find_mismatch_helper(const aom_image_t *const img1,
                                  const aom_image_t *const img2,
                                  int use_highbitdepth, int yloc[4], int uloc[4],
                                  int vloc[4]) {
-#if !CONFIG_HIGHBITDEPTH
-  assert(!use_highbitdepth);
-#endif  // !CONFIG_HIGHBITDEPTH
   find_mismatch_plane(img1, img2, AOM_PLANE_Y, use_highbitdepth, yloc);
   find_mismatch_plane(img1, img2, AOM_PLANE_U, use_highbitdepth, uloc);
   find_mismatch_plane(img1, img2, AOM_PLANE_V, use_highbitdepth, vloc);
 }
 
-#if CONFIG_HIGHBITDEPTH
 void aom_find_mismatch_high(const aom_image_t *const img1,
                             const aom_image_t *const img2, int yloc[4],
                             int uloc[4], int vloc[4]) {
   find_mismatch_helper(img1, img2, 1, yloc, uloc, vloc);
 }
-#endif
 
 void aom_find_mismatch(const aom_image_t *const img1,
                        const aom_image_t *const img2, int yloc[4], int uloc[4],
@@ -103,37 +100,37 @@ void aom_find_mismatch(const aom_image_t *const img1,
 
 int aom_compare_img(const aom_image_t *const img1,
                     const aom_image_t *const img2) {
+  assert(img1->cp == img2->cp);
+  assert(img1->tc == img2->tc);
+  assert(img1->mc == img2->mc);
+  assert(img1->monochrome == img2->monochrome);
+
+  int num_planes = img1->monochrome ? 1 : 3;
+
   uint32_t l_w = img1->d_w;
   uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
   const uint32_t c_h =
       (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
-  uint32_t i;
   int match = 1;
 
   match &= (img1->fmt == img2->fmt);
   match &= (img1->d_w == img2->d_w);
   match &= (img1->d_h == img2->d_h);
-#if CONFIG_HIGHBITDEPTH
   if (img1->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
     l_w *= 2;
     c_w *= 2;
   }
-#endif
-
-  for (i = 0; i < img1->d_h; ++i)
-    match &= (memcmp(img1->planes[AOM_PLANE_Y] + i * img1->stride[AOM_PLANE_Y],
-                     img2->planes[AOM_PLANE_Y] + i * img2->stride[AOM_PLANE_Y],
-                     l_w) == 0);
-
-  for (i = 0; i < c_h; ++i)
-    match &= (memcmp(img1->planes[AOM_PLANE_U] + i * img1->stride[AOM_PLANE_U],
-                     img2->planes[AOM_PLANE_U] + i * img2->stride[AOM_PLANE_U],
-                     c_w) == 0);
-
-  for (i = 0; i < c_h; ++i)
-    match &= (memcmp(img1->planes[AOM_PLANE_V] + i * img1->stride[AOM_PLANE_V],
-                     img2->planes[AOM_PLANE_V] + i * img2->stride[AOM_PLANE_V],
-                     c_w) == 0);
+
+  for (int plane = 0; plane < num_planes; ++plane) {
+    uint32_t height = plane ? c_h : img1->d_h;
+    uint32_t width = plane ? c_w : l_w;
+
+    for (uint32_t i = 0; i < height; ++i) {
+      match &=
+          (memcmp(img1->planes[plane] + i * img1->stride[plane],
+                  img2->planes[plane] + i * img2->stride[plane], width) == 0);
+    }
+  }
 
   return match;
 }
diff --git a/third_party/aom/examples/encoder_util.h b/third_party/aom/examples/encoder_util.h
index 38deef03d..966f5e004 100644
--- a/third_party/aom/examples/encoder_util.h
+++ b/third_party/aom/examples/encoder_util.h
@@ -14,16 +14,13 @@
 #ifndef EXAMPLES_ENCODER_UTIL_H_
 #define EXAMPLES_ENCODER_UTIL_H_
 
-#include "./aom_config.h"
 #include "aom/aom_image.h"
 
 // Returns mismatch location (?loc[0],?loc[1]) and the values at that location
 // in img1 (?loc[2]) and img2 (?loc[3]).
-#if CONFIG_HIGHBITDEPTH
 void aom_find_mismatch_high(const aom_image_t *const img1,
                             const aom_image_t *const img2, int yloc[4],
                             int uloc[4], int vloc[4]);
-#endif  // CONFIG_HIGHBITDEPTH
 
 void aom_find_mismatch(const aom_image_t *const img1,
                        const aom_image_t *const img2, int yloc[4], int uloc[4],
diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
index 74e770b84..4887fc4a3 100644
--- a/third_party/aom/examples/inspect.c
+++ b/third_party/aom/examples/inspect.c
@@ -19,27 +19,27 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "./args.h"
 #ifdef __EMSCRIPTEN__
 #include <emscripten.h>
 #else
 #define EMSCRIPTEN_KEEPALIVE
 #endif
 
+#include "config/aom_config.h"
+
 #include "aom/aom_decoder.h"
-#include "./aom_config.h"
-#if CONFIG_ACCOUNTING
-#include "../av1/decoder/accounting.h"
-#endif
-#include "../av1/decoder/inspection.h"
 #include "aom/aomdx.h"
+#include "av1/common/onyxc_int.h"
 
-#include "../tools_common.h"
-#include "../video_reader.h"
-// #include "av1/av1_dx_iface.c"
-#include "../av1/common/onyxc_int.h"
+#if CONFIG_ACCOUNTING
+#include "av1/decoder/accounting.h"
+#endif
 
-#include "../video_common.h"
+#include "av1/decoder/inspection.h"
+#include "common/args.h"
+#include "common/tools_common.h"
+#include "common/video_common.h"
+#include "common/video_reader.h"
 
 // Max JSON buffer size.
 const int MAX_BUFFER = 1024 * 1024 * 32;
@@ -57,7 +57,10 @@ typedef enum {
   MOTION_VECTORS_LAYER = 1 << 9,
   UV_MODE_LAYER = 1 << 10,
   CFL_LAYER = 1 << 11,
-  ALL_LAYERS = (1 << 12) - 1
+  DUAL_FILTER_LAYER = 1 << 12,
+  Q_INDEX_LAYER = 1 << 13,
+  SEGMENT_ID_LAYER = 1 << 14,
+  ALL_LAYERS = (1 << 15) - 1
 } LayerType;
 
 static LayerType layers = 0;
@@ -87,12 +90,16 @@ static const arg_def_t dump_skip_arg = ARG_DEF("s", "skip", 0, "Dump Skip");
 static const arg_def_t dump_filter_arg =
     ARG_DEF("f", "filter", 0, "Dump Filter");
 static const arg_def_t dump_cdef_arg = ARG_DEF("c", "cdef", 0, "Dump CDEF");
-#if CONFIG_CFL
 static const arg_def_t dump_cfl_arg =
     ARG_DEF("cfl", "chroma_from_luma", 0, "Dump Chroma from Luma Alphas");
-#endif
+static const arg_def_t dump_dual_filter_type_arg =
+    ARG_DEF("df", "dualFilterType", 0, "Dump Dual Filter Type");
 static const arg_def_t dump_reference_frame_arg =
     ARG_DEF("r", "referenceFrame", 0, "Dump Reference Frame");
+static const arg_def_t dump_delta_q_arg =
+    ARG_DEF("dq", "delta_q", 0, "Dump QIndex");
+static const arg_def_t dump_seg_id_arg =
+    ARG_DEF("si", "seg_id", 0, "Dump Segment ID");
 static const arg_def_t usage_arg = ARG_DEF("h", "help", 0, "Help");
 
 static const arg_def_t *main_args[] = { &limit_arg,
@@ -108,14 +115,13 @@ static const arg_def_t *main_args[] = { &limit_arg,
                                         &dump_uv_mode_arg,
                                         &dump_skip_arg,
                                         &dump_filter_arg,
-#if CONFIG_CDEF
                                         &dump_cdef_arg,
-#endif
-#if CONFIG_CFL
+                                        &dump_dual_filter_type_arg,
                                         &dump_cfl_arg,
-#endif
                                         &dump_reference_frame_arg,
                                         &dump_motion_vectors_arg,
+                                        &dump_delta_q_arg,
+                                        &dump_seg_id_arg,
                                         &usage_arg,
                                         NULL };
 #define ENUM(name) \
@@ -127,58 +133,35 @@ typedef struct map_entry {
   int value;
 } map_entry;
 
-const map_entry refs_map[] = { ENUM(INTRA_FRAME),  ENUM(LAST_FRAME),
-#if CONFIG_EXT_REFS
-                               ENUM(LAST2_FRAME),  ENUM(LAST3_FRAME),
-                               ENUM(GOLDEN_FRAME), ENUM(BWDREF_FRAME),
-                               ENUM(ALTREF_FRAME),
-#else
-                               ENUM(GOLDEN_FRAME), ENUM(ALTREF_FRAME),
-#endif
-                               LAST_ENUM };
+const map_entry refs_map[] = {
+  ENUM(INTRA_FRAME),   ENUM(LAST_FRAME),   ENUM(LAST2_FRAME),
+  ENUM(LAST3_FRAME),   ENUM(GOLDEN_FRAME), ENUM(BWDREF_FRAME),
+  ENUM(ALTREF2_FRAME), ENUM(ALTREF_FRAME), LAST_ENUM
+};
 
 const map_entry block_size_map[] = {
-#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
-  ENUM(BLOCK_2X2),    ENUM(BLOCK_2X4),    ENUM(BLOCK_4X2),
-#endif
-  ENUM(BLOCK_4X4),    ENUM(BLOCK_4X8),    ENUM(BLOCK_8X4),
-  ENUM(BLOCK_8X8),    ENUM(BLOCK_8X16),   ENUM(BLOCK_16X8),
-  ENUM(BLOCK_16X16),  ENUM(BLOCK_16X32),  ENUM(BLOCK_32X16),
-  ENUM(BLOCK_32X32),  ENUM(BLOCK_32X64),  ENUM(BLOCK_64X32),
-  ENUM(BLOCK_64X64),
-#if CONFIG_EXT_PARTITION
-  ENUM(BLOCK_64X128), ENUM(BLOCK_128X64), ENUM(BLOCK_128X128),
-#endif
-  ENUM(BLOCK_4X16),   ENUM(BLOCK_16X4),   ENUM(BLOCK_8X32),
-  ENUM(BLOCK_32X8),   ENUM(BLOCK_16X64),  ENUM(BLOCK_64X16),
-#if CONFIG_EXT_PARTITION
-  ENUM(BLOCK_32X128), ENUM(BLOCK_128X32),
-#endif
-  LAST_ENUM
+  ENUM(BLOCK_4X4),     ENUM(BLOCK_4X8),    ENUM(BLOCK_8X4),
+  ENUM(BLOCK_8X8),     ENUM(BLOCK_8X16),   ENUM(BLOCK_16X8),
+  ENUM(BLOCK_16X16),   ENUM(BLOCK_16X32),  ENUM(BLOCK_32X16),
+  ENUM(BLOCK_32X32),   ENUM(BLOCK_32X64),  ENUM(BLOCK_64X32),
+  ENUM(BLOCK_64X64),   ENUM(BLOCK_64X128), ENUM(BLOCK_128X64),
+  ENUM(BLOCK_128X128), ENUM(BLOCK_4X16),   ENUM(BLOCK_16X4),
+  ENUM(BLOCK_8X32),    ENUM(BLOCK_32X8),   ENUM(BLOCK_16X64),
+  ENUM(BLOCK_64X16),   LAST_ENUM
 };
 
 const map_entry tx_size_map[] = {
-#if CONFIG_CHROMA_2X2
-  ENUM(TX_2X2),
-#endif
   ENUM(TX_4X4),   ENUM(TX_8X8),   ENUM(TX_16X16), ENUM(TX_32X32),
-#if CONFIG_TX64X64
-  ENUM(TX_64X64),
-#endif
-  ENUM(TX_4X8),   ENUM(TX_8X4),   ENUM(TX_8X16),  ENUM(TX_16X8),
-  ENUM(TX_16X32), ENUM(TX_32X16),
-#if CONFIG_TX64X64
-  ENUM(TX_32X64), ENUM(TX_64X32),
-#endif  // CONFIG_TX64X64
-  ENUM(TX_4X16),  ENUM(TX_16X4),  ENUM(TX_8X32),  ENUM(TX_32X8),
-  LAST_ENUM
+  ENUM(TX_64X64), ENUM(TX_4X8),   ENUM(TX_8X4),   ENUM(TX_8X16),
+  ENUM(TX_16X8),  ENUM(TX_16X32), ENUM(TX_32X16), ENUM(TX_32X64),
+  ENUM(TX_64X32), ENUM(TX_4X16),  ENUM(TX_16X4),  ENUM(TX_8X32),
+  ENUM(TX_32X8),  LAST_ENUM
 };
 
 const map_entry tx_type_map[] = { ENUM(DCT_DCT),
                                   ENUM(ADST_DCT),
                                   ENUM(DCT_ADST),
                                   ENUM(ADST_ADST),
-#if CONFIG_EXT_TX
                                   ENUM(FLIPADST_DCT),
                                   ENUM(DCT_FLIPADST),
                                   ENUM(FLIPADST_FLIPADST),
@@ -191,43 +174,35 @@ const map_entry tx_type_map[] = { ENUM(DCT_DCT),
                                   ENUM(H_ADST),
                                   ENUM(V_FLIPADST),
                                   ENUM(H_FLIPADST),
-#endif
                                   LAST_ENUM };
+const map_entry dual_filter_map[] = { ENUM(REG_REG),       ENUM(REG_SMOOTH),
+                                      ENUM(REG_SHARP),     ENUM(SMOOTH_REG),
+                                      ENUM(SMOOTH_SMOOTH), ENUM(SMOOTH_SHARP),
+                                      ENUM(SHARP_REG),     ENUM(SHARP_SMOOTH),
+                                      ENUM(SHARP_SHARP),   LAST_ENUM };
 
 const map_entry prediction_mode_map[] = {
-  ENUM(DC_PRED),       ENUM(V_PRED),        ENUM(H_PRED),
-  ENUM(D45_PRED),      ENUM(D135_PRED),     ENUM(D117_PRED),
-  ENUM(D153_PRED),     ENUM(D207_PRED),     ENUM(D63_PRED),
-  ENUM(SMOOTH_PRED),
-#if CONFIG_SMOOTH_HV
-  ENUM(SMOOTH_V_PRED), ENUM(SMOOTH_H_PRED),
-#endif  // CONFIG_SMOOTH_HV
-  ENUM(TM_PRED),       ENUM(NEARESTMV),     ENUM(NEARMV),
-  ENUM(ZEROMV),        ENUM(NEWMV),         ENUM(NEAREST_NEARESTMV),
-  ENUM(NEAR_NEARMV),   ENUM(NEAREST_NEWMV), ENUM(NEW_NEARESTMV),
-  ENUM(NEAR_NEWMV),    ENUM(NEW_NEARMV),    ENUM(ZERO_ZEROMV),
-  ENUM(NEW_NEWMV),     ENUM(INTRA_INVALID), LAST_ENUM
+  ENUM(DC_PRED),     ENUM(V_PRED),        ENUM(H_PRED),
+  ENUM(D45_PRED),    ENUM(D135_PRED),     ENUM(D113_PRED),
+  ENUM(D157_PRED),   ENUM(D203_PRED),     ENUM(D67_PRED),
+  ENUM(SMOOTH_PRED), ENUM(SMOOTH_V_PRED), ENUM(SMOOTH_H_PRED),
+  ENUM(PAETH_PRED),  ENUM(NEARESTMV),     ENUM(NEARMV),
+  ENUM(GLOBALMV),    ENUM(NEWMV),         ENUM(NEAREST_NEARESTMV),
+  ENUM(NEAR_NEARMV), ENUM(NEAREST_NEWMV), ENUM(NEW_NEARESTMV),
+  ENUM(NEAR_NEWMV),  ENUM(NEW_NEARMV),    ENUM(GLOBAL_GLOBALMV),
+  ENUM(NEW_NEWMV),   ENUM(INTRA_INVALID), LAST_ENUM
 };
 
-#if CONFIG_CFL
 const map_entry uv_prediction_mode_map[] = {
   ENUM(UV_DC_PRED),       ENUM(UV_V_PRED),
   ENUM(UV_H_PRED),        ENUM(UV_D45_PRED),
-  ENUM(UV_D135_PRED),     ENUM(UV_D117_PRED),
-  ENUM(UV_D153_PRED),     ENUM(UV_D207_PRED),
-  ENUM(UV_D63_PRED),      ENUM(UV_SMOOTH_PRED),
-#if CONFIG_SMOOTH_HV
+  ENUM(UV_D135_PRED),     ENUM(UV_D113_PRED),
+  ENUM(UV_D157_PRED),     ENUM(UV_D203_PRED),
+  ENUM(UV_D67_PRED),      ENUM(UV_SMOOTH_PRED),
   ENUM(UV_SMOOTH_V_PRED), ENUM(UV_SMOOTH_H_PRED),
-#endif  // CONFIG_SMOOTH_HV
-  ENUM(UV_TM_PRED),
-#if CONFIG_CFL
-  ENUM(UV_CFL_PRED),
-#endif
+  ENUM(UV_PAETH_PRED),    ENUM(UV_CFL_PRED),
   ENUM(UV_MODE_INVALID),  LAST_ENUM
 };
-#else
-#define uv_prediction_mode_map prediction_mode_map
-#endif
 #define NO_SKIP 0
 #define SKIP 1
 
@@ -327,7 +302,7 @@ int put_map(char *buffer, const map_entry *map) {
       *(buf++) = ',';
     }
   }
-  return buf - buffer;
+  return (int)(buf - buffer);
 }
 
 int put_reference_frame(char *buffer) {
@@ -365,7 +340,7 @@ int put_reference_frame(char *buffer) {
     if (r < mi_rows - 1) *(buf++) = ',';
   }
   buf += put_str(buf, "],\n");
-  return buf - buffer;
+  return (int)(buf - buffer);
 }
 
 int put_motion_vectors(char *buffer) {
@@ -404,15 +379,19 @@ int put_motion_vectors(char *buffer) {
     if (r < mi_rows - 1) *(buf++) = ',';
   }
   buf += put_str(buf, "],\n");
-  return buf - buffer;
+  return (int)(buf - buffer);
 }
 
 int put_block_info(char *buffer, const map_entry *map, const char *name,
-                   size_t offset) {
+                   size_t offset, int len) {
   const int mi_rows = frame_data.mi_rows;
   const int mi_cols = frame_data.mi_cols;
   char *buf = buffer;
-  int r, c, t, v;
+  int r, c, t, i;
+  if (compress && len == 1) {
+    die("Can't encode scalars as arrays when RLE compression is enabled.");
+    return -1;
+  }
   if (map) {
     buf += snprintf(buf, MAX_BUFFER, "  \"%sMap\": {", name);
     buf += put_map(buf, map);
@@ -422,13 +401,36 @@ int put_block_info(char *buffer, const map_entry *map, const char *name,
   for (r = 0; r < mi_rows; ++r) {
     *(buf++) = '[';
     for (c = 0; c < mi_cols; ++c) {
-      insp_mi_data *curr_mi = &frame_data.mi_grid[r * mi_cols + c];
-      v = *(((int8_t *)curr_mi) + offset);
-      buf += put_num(buf, 0, v, 0);
+      insp_mi_data *mi = &frame_data.mi_grid[r * mi_cols + c];
+      int16_t *v = (int16_t *)(((int8_t *)mi) + offset);
+      if (len == 0) {
+        buf += put_num(buf, 0, v[0], 0);
+      } else {
+        buf += put_str(buf, "[");
+        for (i = 0; i < len; i++) {
+          buf += put_num(buf, 0, v[i], 0);
+          if (i < len - 1) {
+            buf += put_str(buf, ",");
+          }
+        }
+        buf += put_str(buf, "]");
+      }
       if (compress) {  // RLE
         for (t = c + 1; t < mi_cols; ++t) {
           insp_mi_data *next_mi = &frame_data.mi_grid[r * mi_cols + t];
-          if (v != *(((int8_t *)next_mi) + offset)) {
+          int16_t *nv = (int16_t *)(((int8_t *)next_mi) + offset);
+          int same = 0;
+          if (len == 0) {
+            same = v[0] == nv[0];
+          } else {
+            for (i = 0; i < len; i++) {
+              same = v[i] == nv[i];
+              if (!same) {
+                break;
+              }
+            }
+          }
+          if (!same) {
             break;
           }
         }
@@ -444,7 +446,7 @@ int put_block_info(char *buffer, const map_entry *map, const char *name,
     if (r < mi_rows - 1) *(buf++) = ',';
   }
   buf += put_str(buf, "],\n");
-  return buf - buffer;
+  return (int)(buf - buffer);
 }
 
 #if CONFIG_ACCOUNTING
@@ -484,7 +486,7 @@ int put_accounting(char *buffer) {
     if (i < num_syms - 1) *(buf++) = ',';
   }
   buf += put_str(buf, "],\n");
-  return buf - buffer;
+  return (int)(buf - buffer);
 }
 #endif
 
@@ -499,51 +501,62 @@ void inspect(void *pbi, void *data) {
   buf += put_str(buf, "{\n");
   if (layers & BLOCK_SIZE_LAYER) {
     buf += put_block_info(buf, block_size_map, "blockSize",
-                          offsetof(insp_mi_data, sb_type));
+                          offsetof(insp_mi_data, sb_type), 0);
   }
   if (layers & TRANSFORM_SIZE_LAYER) {
     buf += put_block_info(buf, tx_size_map, "transformSize",
-                          offsetof(insp_mi_data, tx_size));
+                          offsetof(insp_mi_data, tx_size), 0);
   }
   if (layers & TRANSFORM_TYPE_LAYER) {
     buf += put_block_info(buf, tx_type_map, "transformType",
-                          offsetof(insp_mi_data, tx_type));
+                          offsetof(insp_mi_data, tx_type), 0);
+  }
+  if (layers & DUAL_FILTER_LAYER) {
+    buf += put_block_info(buf, dual_filter_map, "dualFilterType",
+                          offsetof(insp_mi_data, dual_filter_type), 0);
   }
   if (layers & MODE_LAYER) {
     buf += put_block_info(buf, prediction_mode_map, "mode",
-                          offsetof(insp_mi_data, mode));
+                          offsetof(insp_mi_data, mode), 0);
   }
   if (layers & UV_MODE_LAYER) {
     buf += put_block_info(buf, uv_prediction_mode_map, "uv_mode",
-                          offsetof(insp_mi_data, uv_mode));
+                          offsetof(insp_mi_data, uv_mode), 0);
   }
   if (layers & SKIP_LAYER) {
-    buf += put_block_info(buf, skip_map, "skip", offsetof(insp_mi_data, skip));
+    buf +=
+        put_block_info(buf, skip_map, "skip", offsetof(insp_mi_data, skip), 0);
   }
   if (layers & FILTER_LAYER) {
-    buf += put_block_info(buf, NULL, "filter", offsetof(insp_mi_data, filter));
+    buf +=
+        put_block_info(buf, NULL, "filter", offsetof(insp_mi_data, filter), 2);
   }
-#if CONFIG_CDEF
   if (layers & CDEF_LAYER) {
     buf += put_block_info(buf, NULL, "cdef_level",
-                          offsetof(insp_mi_data, cdef_level));
+                          offsetof(insp_mi_data, cdef_level), 0);
     buf += put_block_info(buf, NULL, "cdef_strength",
-                          offsetof(insp_mi_data, cdef_strength));
+                          offsetof(insp_mi_data, cdef_strength), 0);
   }
-#endif
-#if CONFIG_CFL
   if (layers & CFL_LAYER) {
     buf += put_block_info(buf, NULL, "cfl_alpha_idx",
-                          offsetof(insp_mi_data, cfl_alpha_idx));
+                          offsetof(insp_mi_data, cfl_alpha_idx), 0);
     buf += put_block_info(buf, NULL, "cfl_alpha_sign",
-                          offsetof(insp_mi_data, cfl_alpha_sign));
+                          offsetof(insp_mi_data, cfl_alpha_sign), 0);
+  }
+  if (layers & Q_INDEX_LAYER) {
+    buf += put_block_info(buf, NULL, "delta_q",
+                          offsetof(insp_mi_data, current_qindex), 0);
+  }
+  if (layers & SEGMENT_ID_LAYER) {
+    buf += put_block_info(buf, NULL, "seg_id",
+                          offsetof(insp_mi_data, segment_id), 0);
   }
-#endif
   if (layers & MOTION_VECTORS_LAYER) {
     buf += put_motion_vectors(buf);
   }
   if (layers & REFERENCE_FRAME_LAYER) {
-    buf += put_reference_frame(buf);
+    buf += put_block_info(buf, refs_map, "referenceFrame",
+                          offsetof(insp_mi_data, ref_frame), 2);
   }
 #if CONFIG_ACCOUNTING
   if (layers & ACCOUNTING_LAYER) {
@@ -561,6 +574,10 @@ void inspect(void *pbi, void *data) {
                   frame_data.tile_mi_cols);
   buf += snprintf(buf, MAX_BUFFER, "  \"tileRows\": %d,\n",
                   frame_data.tile_mi_rows);
+  buf += snprintf(buf, MAX_BUFFER, "  \"deltaQPresentFlag\": %d,\n",
+                  frame_data.delta_q_present_flag);
+  buf += snprintf(buf, MAX_BUFFER, "  \"deltaQRes\": %d,\n",
+                  frame_data.delta_q_res);
   buf += put_str(buf, "  \"config\": {");
   buf += put_map(buf, config_map);
   buf += put_str(buf, "},\n");
@@ -608,15 +625,18 @@ int read_frame() {
   aom_codec_iter_t iter = NULL;
   size_t frame_size = 0;
   const unsigned char *frame = aom_video_reader_get_frame(reader, &frame_size);
-  if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0) !=
+  if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL) !=
       AOM_CODEC_OK) {
     die_codec(&codec, "Failed to decode frame.");
   }
-  img = aom_codec_get_frame(&codec, &iter);
-  if (img == NULL) {
+  int got_any_frames = 0;
+  while ((img = aom_codec_get_frame(&codec, &iter))) {
+    ++frame_count;
+    got_any_frames = 1;
+  }
+  if (!got_any_frames) {
     return EXIT_FAILURE;
   }
-  ++frame_count;
   return EXIT_SUCCESS;
 }
 
@@ -674,18 +694,20 @@ static void parse_args(char **argv) {
       layers |= SKIP_LAYER;
     else if (arg_match(&arg, &dump_filter_arg, argi))
       layers |= FILTER_LAYER;
-#if CONFIG_CDEF
     else if (arg_match(&arg, &dump_cdef_arg, argi))
       layers |= CDEF_LAYER;
-#endif
-#if CONFIG_CFL
     else if (arg_match(&arg, &dump_cfl_arg, argi))
       layers |= CFL_LAYER;
-#endif
     else if (arg_match(&arg, &dump_reference_frame_arg, argi))
       layers |= REFERENCE_FRAME_LAYER;
     else if (arg_match(&arg, &dump_motion_vectors_arg, argi))
       layers |= MOTION_VECTORS_LAYER;
+    else if (arg_match(&arg, &dump_dual_filter_type_arg, argi))
+      layers |= DUAL_FILTER_LAYER;
+    else if (arg_match(&arg, &dump_delta_q_arg, argi))
+      layers |= Q_INDEX_LAYER;
+    else if (arg_match(&arg, &dump_seg_id_arg, argi))
+      layers |= SEGMENT_ID_LAYER;
     else if (arg_match(&arg, &dump_all_arg, argi))
       layers |= ALL_LAYERS;
     else if (arg_match(&arg, &compress_arg, argi))
diff --git a/third_party/aom/examples/lightfield_bitstream_parsing.c b/third_party/aom/examples/lightfield_bitstream_parsing.c
new file mode 100644
index 000000000..d13f3f172
--- /dev/null
+++ b/third_party/aom/examples/lightfield_bitstream_parsing.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Lightfield Bitstream Parsing
+// ============================
+//
+// This is an lightfield bitstream parsing example. It takes an input file
+// containing the whole compressed lightfield bitstream(ivf file), and parses it
+// and constructs and outputs a new bitstream that can be decoded by an AV1
+// decoder. The output bitstream contains tile list OBUs. The lf_width and
+// lf_height arguments are the number of lightfield images in each dimension.
+// The lf_blocksize determines the number of reference images used.
+// After running the lightfield encoder, run lightfield bitstream parsing:
+// examples/lightfield_bitstream_parsing vase10x10.ivf vase_tile_list.ivf 10 10
+// 5
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_decoder.h"
+#include "aom/aom_encoder.h"
+#include "aom/aom_integer.h"
+#include "aom/aomdx.h"
+#include "aom_dsp/bitwriter_buffer.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
+#include "common/video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(
+      stderr,
+      "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize> \n",
+      exec_name);
+  exit(EXIT_FAILURE);
+}
+
+#define ALIGN_POWER_OF_TWO(value, n) \
+  (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
+
+// SB size: 64x64
+const uint8_t output_frame_width_in_tiles_minus_1 = 512 / 64 - 1;
+const uint8_t output_frame_height_in_tiles_minus_1 = 512 / 64 - 1;
+
+// Spec:
+// typedef struct {
+//   uint8_t anchor_frame_idx;
+//   uint8_t tile_row;
+//   uint8_t tile_col;
+//   uint16_t coded_tile_data_size_minus_1;
+//   uint8_t *coded_tile_data;
+// } TILE_LIST_ENTRY;
+
+// Tile list entry provided by the application
+typedef struct {
+  int image_idx;
+  int reference_idx;
+  int tile_col;
+  int tile_row;
+} TILE_LIST_INFO;
+
+// M references: 0 - M-1; N images(including references): 0 - N-1;
+// Note: order the image index incrementally, so that we only go through the
+// bitstream once to construct the tile list.
+const int num_tile_lists = 2;
+const uint16_t tile_count_minus_1 = 9 - 1;
+const TILE_LIST_INFO tile_list[2][9] = {
+  { { 16, 0, 4, 5 },
+    { 83, 3, 13, 2 },
+    { 57, 2, 2, 6 },
+    { 31, 1, 11, 5 },
+    { 2, 0, 7, 4 },
+    { 77, 3, 9, 9 },
+    { 49, 1, 0, 1 },
+    { 6, 0, 3, 10 },
+    { 63, 2, 5, 8 } },
+  { { 65, 2, 11, 1 },
+    { 42, 1, 3, 7 },
+    { 88, 3, 8, 4 },
+    { 76, 3, 1, 15 },
+    { 1, 0, 2, 2 },
+    { 19, 0, 5, 6 },
+    { 60, 2, 4, 0 },
+    { 25, 1, 11, 15 },
+    { 50, 2, 5, 4 } },
+};
+
+int main(int argc, char **argv) {
+  aom_codec_ctx_t codec;
+  AvxVideoReader *reader = NULL;
+  AvxVideoWriter *writer = NULL;
+  const AvxInterface *decoder = NULL;
+  const AvxVideoInfo *info = NULL;
+  const char *lf_width_arg;
+  const char *lf_height_arg;
+  const char *lf_blocksize_arg;
+  int width, height;
+  int lf_width, lf_height;
+  int lf_blocksize;
+  int u_blocks, v_blocks;
+  int n, i;
+  aom_codec_pts_t pts;
+
+  exec_name = argv[0];
+  if (argc != 6) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  lf_width_arg = argv[3];
+  lf_height_arg = argv[4];
+  lf_blocksize_arg = argv[5];
+
+  lf_width = (int)strtol(lf_width_arg, NULL, 0);
+  lf_height = (int)strtol(lf_height_arg, NULL, 0);
+  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
+
+  info = aom_video_reader_get_info(reader);
+  width = info->frame_width;
+  height = info->frame_height;
+
+  // The writer to write out ivf file in tile list OBU, which can be decoded by
+  // AV1 decoder.
+  writer = aom_video_writer_open(argv[2], kContainerIVF, info);
+  if (!writer) die("Failed to open %s for writing", argv[2]);
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  // Decode anchor frames.
+  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
+
+  // How many anchor frames we have.
+  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
+  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
+
+  int num_references = v_blocks * u_blocks;
+  for (i = 0; i < num_references; ++i) {
+    aom_video_reader_read_frame(reader);
+
+    size_t frame_size = 0;
+    const unsigned char *frame =
+        aom_video_reader_get_frame(reader, &frame_size);
+    pts = (aom_codec_pts_t)aom_video_reader_get_frame_pts(reader);
+
+    // Copy references bitstream directly.
+    if (!aom_video_writer_write_frame(writer, frame, frame_size, pts))
+      die_codec(&codec, "Failed to copy compressed anchor frame.");
+
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
+      die_codec(&codec, "Failed to decode frame.");
+  }
+
+  // Decode camera frames.
+  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 1);
+  aom_codec_control_(&codec, AV1D_EXT_TILE_DEBUG, 1);
+
+  FILE *infile = aom_video_reader_get_file(reader);
+  // Record the offset of the first camera image.
+  const FileOffset camera_frame_pos = ftello(infile);
+
+  // Read out the first camera frame.
+  aom_video_reader_read_frame(reader);
+
+  // Copy first camera frame for getting camera frame header. This is done
+  // only once.
+  {
+    size_t frame_size = 0;
+    const unsigned char *frame =
+        aom_video_reader_get_frame(reader, &frame_size);
+    pts = (aom_codec_pts_t)aom_video_reader_get_frame_pts(reader);
+    aom_tile_data frame_header_info = { 0, NULL, 0 };
+
+    // Need to decode frame header to get camera frame header info. So, here
+    // decoding 1 tile is enough.
+    aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, 0);
+    aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, 0);
+
+    aom_codec_err_t aom_status =
+        aom_codec_decode(&codec, frame, frame_size, NULL);
+    if (aom_status) die_codec(&codec, "Failed to decode tile.");
+
+    aom_codec_control_(&codec, AV1D_GET_FRAME_HEADER_INFO, &frame_header_info);
+
+    size_t obu_size_offset =
+        (uint8_t *)frame_header_info.coded_tile_data - frame;
+    size_t length_field_size = frame_header_info.coded_tile_data_size;
+    // Remove ext-tile tile info.
+    uint32_t frame_header_size = (uint32_t)frame_header_info.extra_size - 1;
+    size_t bytes_to_copy =
+        obu_size_offset + length_field_size + frame_header_size;
+
+    unsigned char *frame_hdr_buf = (unsigned char *)malloc(bytes_to_copy);
+    if (frame_hdr_buf == NULL)
+      die_codec(&codec, "Failed to allocate frame header buffer.");
+
+    memcpy(frame_hdr_buf, frame, bytes_to_copy);
+
+    // Update frame header OBU size.
+    size_t bytes_written = 0;
+    if (aom_uleb_encode_fixed_size(
+            frame_header_size, length_field_size, length_field_size,
+            frame_hdr_buf + obu_size_offset, &bytes_written))
+      die_codec(&codec, "Failed to encode the tile list obu size.");
+
+    // Copy camera frame header bitstream.
+    if (!aom_video_writer_write_frame(writer, frame_hdr_buf, bytes_to_copy,
+                                      pts))
+      die_codec(&codec, "Failed to copy compressed camera frame header.");
+  }
+
+  // Allocate a buffer to store tile list bitstream. Image format
+  // AOM_IMG_FMT_I420.
+  size_t data_sz =
+      ALIGN_POWER_OF_TWO(width, 5) * ALIGN_POWER_OF_TWO(height, 5) * 12 / 8;
+  unsigned char *tl_buf = (unsigned char *)malloc(data_sz);
+  if (tl_buf == NULL) die_codec(&codec, "Failed to allocate tile list buffer.");
+
+  aom_codec_pts_t tl_pts = pts;
+
+  // Process 1 tile list.
+  for (n = 0; n < num_tile_lists; n++) {
+    unsigned char *tl = tl_buf;
+    struct aom_write_bit_buffer wb = { tl, 0 };
+    unsigned char *saved_obu_size_loc = NULL;
+    uint32_t tile_list_obu_header_size = 0;
+    uint32_t tile_list_obu_size = 0;
+
+    // Write the tile list OBU header that is 1 byte long.
+    aom_wb_write_literal(&wb, 0, 1);  // forbidden bit.
+    aom_wb_write_literal(&wb, 8, 4);  // tile list OBU: "1000"
+    aom_wb_write_literal(&wb, 0, 1);  // obu_extension = 0
+    aom_wb_write_literal(&wb, 1, 1);  // obu_has_size_field
+    aom_wb_write_literal(&wb, 0, 1);  // reserved
+    tl++;
+    tile_list_obu_header_size++;
+
+    // Write the OBU size using a fixed length_field_size of 4 bytes.
+    saved_obu_size_loc = tl;
+    aom_wb_write_literal(&wb, 0, 32);
+    tl += 4;
+    tile_list_obu_header_size += 4;
+
+    // write_tile_list_obu()
+    aom_wb_write_literal(&wb, output_frame_width_in_tiles_minus_1, 8);
+    aom_wb_write_literal(&wb, output_frame_height_in_tiles_minus_1, 8);
+    aom_wb_write_literal(&wb, tile_count_minus_1, 16);
+    tl += 4;
+    tile_list_obu_size += 4;
+
+    // Write each tile's data
+    for (i = 0; i <= tile_count_minus_1; i++) {
+      aom_tile_data tile_data = { 0, NULL, 0 };
+
+      int image_idx = tile_list[n][i].image_idx;
+      int ref_idx = tile_list[n][i].reference_idx;
+      int tc = tile_list[n][i].tile_col;
+      int tr = tile_list[n][i].tile_row;
+      int frame_cnt = -1;
+
+      // Reset bit writer to the right location.
+      wb.bit_buffer = tl;
+      wb.bit_offset = 0;
+
+      // Seek to the first camera image.
+      fseeko(infile, camera_frame_pos, SEEK_SET);
+
+      // Read out the camera image
+      while (frame_cnt != image_idx) {
+        aom_video_reader_read_frame(reader);
+        frame_cnt++;
+      }
+
+      size_t frame_size = 0;
+      const unsigned char *frame =
+          aom_video_reader_get_frame(reader, &frame_size);
+
+      aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, tr);
+      aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, tc);
+
+      aom_codec_err_t aom_status =
+          aom_codec_decode(&codec, frame, frame_size, NULL);
+      if (aom_status) die_codec(&codec, "Failed to decode tile.");
+
+      aom_codec_control_(&codec, AV1D_GET_TILE_DATA, &tile_data);
+
+      // Copy over tile info.
+      //  uint8_t anchor_frame_idx;
+      //  uint8_t tile_row;
+      //  uint8_t tile_col;
+      //  uint16_t coded_tile_data_size_minus_1;
+      //  uint8_t *coded_tile_data;
+      uint32_t tile_info_bytes = 5;
+      aom_wb_write_literal(&wb, ref_idx, 8);
+      aom_wb_write_literal(&wb, tr, 8);
+      aom_wb_write_literal(&wb, tc, 8);
+      aom_wb_write_literal(&wb, (int)tile_data.coded_tile_data_size - 1, 16);
+      tl += tile_info_bytes;
+
+      memcpy(tl, (uint8_t *)tile_data.coded_tile_data,
+             tile_data.coded_tile_data_size);
+      tl += tile_data.coded_tile_data_size;
+
+      tile_list_obu_size +=
+          tile_info_bytes + (uint32_t)tile_data.coded_tile_data_size;
+    }
+
+    // Write tile list OBU size.
+    size_t bytes_written = 0;
+    if (aom_uleb_encode_fixed_size(tile_list_obu_size, 4, 4, saved_obu_size_loc,
+                                   &bytes_written))
+      die_codec(&codec, "Failed to encode the tile list obu size.");
+
+    // Copy the tile list.
+    if (!aom_video_writer_write_frame(
+            writer, tl_buf, tile_list_obu_header_size + tile_list_obu_size,
+            tl_pts))
+      die_codec(&codec, "Failed to copy compressed tile list.");
+
+    tl_pts++;
+  }
+
+  free(tl_buf);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+  aom_video_writer_close(writer);
+  aom_video_reader_close(reader);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/lightfield_decoder.c b/third_party/aom/examples/lightfield_decoder.c
index 8743df9bc..625cddcac 100644
--- a/third_party/aom/examples/lightfield_decoder.c
+++ b/third_party/aom/examples/lightfield_decoder.c
@@ -14,14 +14,14 @@
 //
 // This is an example of a simple lightfield decoder. It builds upon the
 // simple_decoder.c example.  It takes an input file containing the compressed
-// data (in webm format), treating it as a lightfield instead of a video and
+// data (in ivf format), treating it as a lightfield instead of a video and
 // will decode a single lightfield tile. The lf_width and lf_height arguments
 // are the number of lightfield images in each dimension. The tile to decode
 // is specified by the tile_u, tile_v, tile_s, tile_t arguments. The tile_u,
 // tile_v specify the image and tile_s, tile_t specify the tile in the image.
 // After running the lightfield encoder, run lightfield decoder to decode a
 // single tile:
-// examples/lightfield_decoder vase10x10.webm vase_tile.yuv 10 10 3 4 5 10 5
+// examples/lightfield_decoder vase10x10.ivf vase_reference.yuv 10 10 5
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -29,47 +29,57 @@
 
 #include "aom/aom_decoder.h"
 #include "aom/aomdx.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
 
-#include "../tools_common.h"
-#include "../video_reader.h"
-#include "./aom_config.h"
+#define MAX_EXTERNAL_REFERENCES 128
+#define AOM_BORDER_IN_PIXELS 288
 
 static const char *exec_name;
 
 void usage_exit(void) {
-  fprintf(stderr,
-          "Usage: %s <infile> <outfile> <lf_width> <lf_height> <tlie_u>"
-          " <tile_v> <tile_s> <tile_t> <lf_blocksize>\n",
-          exec_name);
+  fprintf(
+      stderr,
+      "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize>\n",
+      exec_name);
   exit(EXIT_FAILURE);
 }
 
-aom_image_t *aom_img_copy(aom_image_t *src, aom_image_t *dst) {
-  dst = aom_img_alloc(dst, src->fmt, src->d_w, src->d_h, 16);
-
-  int plane;
-
-  for (plane = 0; plane < 3; ++plane) {
-    uint8_t *src_buf = src->planes[plane];
-    const int src_stride = src->stride[plane];
-    const int src_w = plane == 0 ? src->d_w : src->d_w >> 1;
-    const int src_h = plane == 0 ? src->d_h : src->d_h >> 1;
-
-    uint8_t *dst_buf = dst->planes[plane];
-    const int dst_stride = dst->stride[plane];
-    int y;
-
-    for (y = 0; y < src_h; ++y) {
-      memcpy(dst_buf, src_buf, src_w);
-      src_buf += src_stride;
-      dst_buf += dst_stride;
-    }
-  }
-  return dst;
-}
+// Tile list entry provided by the application
+typedef struct {
+  int image_idx;
+  int reference_idx;
+  int tile_col;
+  int tile_row;
+} TILE_LIST_INFO;
+
+// M references: 0 - M-1; N images(including references): 0 - N-1;
+// Note: order the image index incrementally, so that we only go through the
+// bitstream once to construct the tile list.
+const int num_tile_lists = 2;
+const uint16_t tile_count_minus_1 = 9 - 1;
+const TILE_LIST_INFO tile_list[2][9] = {
+  { { 16, 0, 4, 5 },
+    { 83, 3, 13, 2 },
+    { 57, 2, 2, 6 },
+    { 31, 1, 11, 5 },
+    { 2, 0, 7, 4 },
+    { 77, 3, 9, 9 },
+    { 49, 1, 0, 1 },
+    { 6, 0, 3, 10 },
+    { 63, 2, 5, 8 } },
+  { { 65, 2, 11, 1 },
+    { 42, 1, 3, 7 },
+    { 88, 3, 8, 4 },
+    { 76, 3, 1, 15 },
+    { 1, 0, 2, 2 },
+    { 19, 0, 5, 6 },
+    { 60, 2, 4, 0 },
+    { 25, 1, 11, 15 },
+    { 50, 2, 5, 4 } },
+};
 
 int main(int argc, char **argv) {
-  int frame_cnt = 0;
   FILE *outfile = NULL;
   aom_codec_ctx_t codec;
   AvxVideoReader *reader = NULL;
@@ -77,20 +87,20 @@ int main(int argc, char **argv) {
   const AvxVideoInfo *info = NULL;
   const char *lf_width_arg;
   const char *lf_height_arg;
-  const char *tile_u_arg;
-  const char *tile_v_arg;
-  const char *tile_s_arg;
-  const char *tile_t_arg;
   const char *lf_blocksize_arg;
+  int width, height;
   int lf_width, lf_height;
-  int tile_u, tile_v, tile_s, tile_t;
   int lf_blocksize;
   int u_blocks;
   int v_blocks;
+  aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
+  size_t frame_size = 0;
+  const unsigned char *frame = NULL;
+  int n, i;
 
   exec_name = argv[0];
 
-  if (argc != 10) die("Invalid number of arguments.");
+  if (argc != 6) die("Invalid number of arguments.");
 
   reader = aom_video_reader_open(argv[1]);
   if (!reader) die("Failed to open %s for reading.", argv[1]);
@@ -100,86 +110,113 @@ int main(int argc, char **argv) {
 
   lf_width_arg = argv[3];
   lf_height_arg = argv[4];
-  tile_u_arg = argv[5];
-  tile_v_arg = argv[6];
-  tile_s_arg = argv[7];
-  tile_t_arg = argv[8];
-  lf_blocksize_arg = argv[9];
+  lf_blocksize_arg = argv[5];
   lf_width = (int)strtol(lf_width_arg, NULL, 0);
   lf_height = (int)strtol(lf_height_arg, NULL, 0);
-  tile_u = (int)strtol(tile_u_arg, NULL, 0);
-  tile_v = (int)strtol(tile_v_arg, NULL, 0);
-  tile_s = (int)strtol(tile_s_arg, NULL, 0);
-  tile_t = (int)strtol(tile_t_arg, NULL, 0);
   lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
 
   info = aom_video_reader_get_info(reader);
+  width = info->frame_width;
+  height = info->frame_height;
 
   decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
   if (!decoder) die("Unknown input codec.");
-
   printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
 
   if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
     die_codec(&codec, "Failed to initialize decoder.");
 
-  // How many reference images we need to encode.
+  // How many anchor frames we have.
   u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
   v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-  aom_image_t *reference_images =
-      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
-  for (int bv = 0; bv < v_blocks; ++bv) {
-    for (int bu = 0; bu < u_blocks; ++bu) {
-      aom_video_reader_read_frame(reader);
-      aom_codec_iter_t iter = NULL;
-      aom_image_t *img = NULL;
-      size_t frame_size = 0;
-      const unsigned char *frame =
-          aom_video_reader_get_frame(reader, &frame_size);
-      if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
-        die_codec(&codec, "Failed to decode frame.");
-
-      while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
-        aom_img_copy(img, &reference_images[bu + bv * u_blocks]);
-        char name[1024];
-        snprintf(name, sizeof(name), "ref_%d_%d.yuv", bu, bv);
-        printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
-        FILE *ref_file = fopen(name, "wb");
-        aom_img_write(img, ref_file);
-        fclose(ref_file);
-        ++frame_cnt;
-      }
+
+  int num_references = v_blocks * u_blocks;
+
+  // Allocate memory to store decoded references.
+  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
+  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  // Allocate memory with the border so that it can be used as a reference.
+  for (i = 0; i < num_references; i++) {
+    unsigned int border = AOM_BORDER_IN_PIXELS;
+    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
+                                   32, 8, border)) {
+      die("Failed to allocate references.");
     }
   }
 
-  int decode_frame_index = tile_v * lf_width + tile_u;
-  do {
+  // Decode anchor frames.
+  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
+
+  for (i = 0; i < num_references; ++i) {
     aom_video_reader_read_frame(reader);
-  } while (frame_cnt++ != decode_frame_index);
-  size_t frame_size = 0;
-  const unsigned char *frame = aom_video_reader_get_frame(reader, &frame_size);
-
-  int ref_bu = tile_u / lf_blocksize;
-  int ref_bv = tile_v / lf_blocksize;
-  int ref_bi = ref_bu + ref_bv * u_blocks;
-  av1_ref_frame_t ref;
-  ref.idx = 0;
-  ref.img = reference_images[ref_bi];
-  // This is too slow for real lightfield rendering.  This copies the
-  // reference image bytes.  We need a way to just set a pointer
-  // in order to make this fast enough.
-  if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref)) {
-    die_codec(&codec, "Failed to set reference image.");
+    frame = aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
+      die_codec(&codec, "Failed to decode frame.");
+
+    if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
+                          &reference_images[i]))
+      die_codec(&codec, "Failed to copy decoded reference frame");
+
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+      char name[1024];
+      snprintf(name, sizeof(name), "ref_%d.yuv", i);
+      printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
+      FILE *ref_file = fopen(name, "wb");
+      aom_img_write(img, ref_file);
+      fclose(ref_file);
+    }
+  }
+
+  FILE *infile = aom_video_reader_get_file(reader);
+  // Record the offset of the first camera image.
+  const FileOffset camera_frame_pos = ftello(infile);
+
+  // Process 1 tile.
+  for (n = 0; n < num_tile_lists; n++) {
+    for (i = 0; i <= tile_count_minus_1; i++) {
+      int image_idx = tile_list[n][i].image_idx;
+      int ref_idx = tile_list[n][i].reference_idx;
+      int tc = tile_list[n][i].tile_col;
+      int tr = tile_list[n][i].tile_row;
+      int frame_cnt = -1;
+
+      // Seek to the first camera image.
+      fseeko(infile, camera_frame_pos, SEEK_SET);
+
+      // Read out the camera image
+      while (frame_cnt != image_idx) {
+        aom_video_reader_read_frame(reader);
+        frame_cnt++;
+      }
+
+      frame = aom_video_reader_get_frame(reader, &frame_size);
+
+      aom_codec_control_(&codec, AV1_SET_TILE_MODE, 1);
+      aom_codec_control_(&codec, AV1D_EXT_TILE_DEBUG, 1);
+      aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, tr);
+      aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, tc);
+
+      av1_ref_frame_t ref;
+      ref.idx = 0;
+      ref.use_external_ref = 1;
+      ref.img = reference_images[ref_idx];
+      if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref)) {
+        die_codec(&codec, "Failed to set reference frame.");
+      }
+
+      aom_codec_err_t aom_status =
+          aom_codec_decode(&codec, frame, frame_size, NULL);
+      if (aom_status) die_codec(&codec, "Failed to decode tile.");
+
+      aom_codec_iter_t iter = NULL;
+      aom_image_t *img = aom_codec_get_frame(&codec, &iter);
+      aom_img_write(img, outfile);
+    }
   }
-  aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, tile_t);
-  aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, tile_s);
-  aom_codec_err_t aom_status =
-      aom_codec_decode(&codec, frame, frame_size, NULL, 0);
-  if (aom_status) die_codec(&codec, "Failed to decode tile.");
-  aom_codec_iter_t iter = NULL;
-  aom_image_t *img = aom_codec_get_frame(&codec, &iter);
-  aom_img_write(img, outfile);
 
+  for (i = 0; i < num_references; i++) aom_img_free(&reference_images[i]);
   if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
   aom_video_reader_close(reader);
   fclose(outfile);
diff --git a/third_party/aom/examples/lightfield_encoder.c b/third_party/aom/examples/lightfield_encoder.c
index 0a424db8c..22daf622c 100644
--- a/third_party/aom/examples/lightfield_encoder.c
+++ b/third_party/aom/examples/lightfield_encoder.c
@@ -24,7 +24,12 @@
 // image for MCP.
 // Run "make test" to download lightfield test data: vase10x10.yuv.
 // Run lightfield encoder to encode whole lightfield:
-// examples/lightfield_encoder 1024 1024 vase10x10.yuv vase10x10.webm 10 10 5
+// examples/lightfield_encoder 1024 1024 vase10x10.yuv vase10x10.ivf 10 10 5
+
+// Note: In bitstream.c and encoder.c, define EXT_TILE_DEBUG as 1 will print
+// out the uncompressed header and the frame contexts, which can be used to
+// test the bit exactness of the headers and the frame contexts for large scale
+// tile coded frames.
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -34,11 +39,13 @@
 #include "aom/aomcx.h"
 #include "av1/common/enums.h"
 
-#include "../tools_common.h"
-#include "../video_writer.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
+
+#define MAX_EXTERNAL_REFERENCES 128
+#define AOM_BORDER_IN_PIXELS 288
 
 static const char *exec_name;
-static const unsigned int deadline = AOM_DL_GOOD_QUALITY;
 
 void usage_exit(void) {
   fprintf(stderr,
@@ -48,52 +55,26 @@ void usage_exit(void) {
   exit(EXIT_FAILURE);
 }
 
-static aom_image_t *aom_img_copy(aom_image_t *src, aom_image_t *dst) {
-  dst = aom_img_alloc(dst, src->fmt, src->d_w, src->d_h, 16);
-
-  int plane;
-
-  for (plane = 0; plane < 3; ++plane) {
-    unsigned char *src_buf = src->planes[plane];
-    const int src_stride = src->stride[plane];
-    const int src_w = plane == 0 ? src->d_w : src->d_w >> 1;
-    const int src_h = plane == 0 ? src->d_h : src->d_h >> 1;
-
-    unsigned char *dst_buf = dst->planes[plane];
-    const int dst_stride = dst->stride[plane];
-    int y;
-
-    for (y = 0; y < src_h; ++y) {
-      memcpy(dst_buf, src_buf, src_w);
-      src_buf += src_stride;
-      dst_buf += dst_stride;
-    }
-  }
-  return dst;
-}
-
 static int aom_img_size_bytes(aom_image_t *img) {
   int image_size_bytes = 0;
   int plane;
   for (plane = 0; plane < 3; ++plane) {
-    const int stride = img->stride[plane];
     const int w = aom_img_plane_width(img, plane) *
                   ((img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
     const int h = aom_img_plane_height(img, plane);
-    image_size_bytes += (w + stride) * h;
+    image_size_bytes += w * h;
   }
   return image_size_bytes;
 }
 
 static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
                            aom_codec_pts_t pts, unsigned int duration,
-                           aom_enc_frame_flags_t flags, unsigned int dl,
+                           aom_enc_frame_flags_t flags,
                            aom_fixed_buf_t *stats) {
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
-  const aom_codec_err_t res =
-      aom_codec_encode(ctx, img, pts, duration, flags, dl);
+  const aom_codec_err_t res = aom_codec_encode(ctx, img, pts, duration, flags);
   if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
 
   while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
@@ -113,13 +94,11 @@ static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
 
 static int encode_frame(aom_codec_ctx_t *ctx, const aom_image_t *img,
                         aom_codec_pts_t pts, unsigned int duration,
-                        aom_enc_frame_flags_t flags, unsigned int dl,
-                        AvxVideoWriter *writer) {
+                        aom_enc_frame_flags_t flags, AvxVideoWriter *writer) {
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
-  const aom_codec_err_t res =
-      aom_codec_encode(ctx, img, pts, duration, flags, dl);
+  const aom_codec_err_t res = aom_codec_encode(ctx, img, pts, duration, flags);
   if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
 
   while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
@@ -139,33 +118,44 @@ static int encode_frame(aom_codec_ctx_t *ctx, const aom_image_t *img,
   return got_pkts;
 }
 
+static void get_raw_image(aom_image_t **frame_to_encode, aom_image_t *raw,
+                          aom_image_t *raw_shift) {
+  if (!CONFIG_LOWBITDEPTH) {
+    // Need to allocate larger buffer to use hbd internal.
+    int input_shift = 0;
+    aom_img_upshift(raw_shift, raw, input_shift);
+    *frame_to_encode = raw_shift;
+  } else {
+    *frame_to_encode = raw;
+  }
+}
+
 static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
                              const AvxInterface *encoder,
                              const aom_codec_enc_cfg_t *cfg, int lf_width,
-                             int lf_height, int lf_blocksize) {
+                             int lf_height, int lf_blocksize, int flags,
+                             aom_image_t *raw_shift) {
   aom_codec_ctx_t codec;
   int frame_count = 0;
-  int image_size_bytes = 0;
+  int image_size_bytes = aom_img_size_bytes(raw);
   int u_blocks, v_blocks;
   int bu, bv;
   aom_fixed_buf_t stats = { NULL, 0 };
+  aom_image_t *frame_to_encode;
 
-  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, flags))
     die_codec(&codec, "Failed to initialize encoder");
-  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
-    die_codec(&codec, "Failed to set frame parallel decoding");
   if (aom_codec_control(&codec, AOME_SET_ENABLEAUTOALTREF, 0))
     die_codec(&codec, "Failed to turn off auto altref");
-  if (aom_codec_control(&codec, AV1E_SET_SINGLE_TILE_DECODING, 1))
-    die_codec(&codec, "Failed to turn on single tile decoding");
-
-  image_size_bytes = aom_img_size_bytes(raw);
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 0))
+    die_codec(&codec, "Failed to set frame parallel decoding");
 
   // How many reference images we need to encode.
   u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
   v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-  aom_image_t *reference_images =
-      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
+
+  printf("\n First pass: ");
+
   for (bv = 0; bv < v_blocks; ++bv) {
     for (bu = 0; bu < u_blocks; ++bu) {
       const int block_u_min = bu * lf_blocksize;
@@ -174,7 +164,6 @@ static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
       int block_v_end = (bv + 1) * lf_blocksize;
       int u_block_size, v_block_size;
       int block_ref_u, block_ref_v;
-      struct av1_ref_frame ref_frame;
 
       block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
       block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
@@ -182,22 +171,28 @@ static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
       v_block_size = block_v_end - block_v_min;
       block_ref_u = block_u_min + u_block_size / 2;
       block_ref_v = block_v_min + v_block_size / 2;
+
+      printf("A%d, ", (block_ref_u + block_ref_v * lf_width));
       fseek(infile, (block_ref_u + block_ref_v * lf_width) * image_size_bytes,
             SEEK_SET);
       aom_img_read(raw, infile);
-      if (aom_codec_control(&codec, AOME_USE_REFERENCE,
-                            AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
-        die_codec(&codec, "Failed to set reference flags");
+      get_raw_image(&frame_to_encode, raw, raw_shift);
+
       // Reference frames can be encoded encoded without tiles.
       ++frame_count;
-      get_frame_stats(&codec, raw, frame_count, 1,
-                      AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
+      get_frame_stats(&codec, frame_to_encode, frame_count, 1,
+                      AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+                          AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
+                          AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
+                          AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                          AOM_EFLAG_NO_UPD_ARF,
                       &stats);
-      ref_frame.idx = 0;
-      aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
-      aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
     }
   }
+
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
+    die_codec(&codec, "Failed to set frame parallel decoding");
+
   for (bv = 0; bv < v_blocks; ++bv) {
     for (bu = 0; bu < u_blocks; ++bu) {
       const int block_u_min = bu * lf_blocksize;
@@ -209,58 +204,39 @@ static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
       block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
       for (v = block_v_min; v < block_v_end; ++v) {
         for (u = block_u_min; u < block_u_end; ++u) {
-          // This was a work around for a bug in libvpx.  I'm not sure if this
-          // same bug exists in current version of av1.  Need to call this,
-          // otherwise the default is to not use any reference frames.  Then
-          // if you don't have at least one AOM_EFLAG_NO_REF_* flag, all frames
-          // will be intra encoded.  I'm not sure why the default is not to use
-          // any reference frames.  It looks like there is something about the
-          // way I encode the reference frames above that sets that as
-          // default...
-          if (aom_codec_control(&codec, AOME_USE_REFERENCE,
-                                AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
-            die_codec(&codec, "Failed to set reference flags");
-
-          // Set tile size to 64 pixels. The tile_columns and
-          // tile_rows in the tile coding are overloaded to represent
-          // tile_width and tile_height, that range from 1 to 64, in the unit
-          // of 64 pixels.
-          if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 1))
-            die_codec(&codec, "Failed to set tile width");
-          if (aom_codec_control(&codec, AV1E_SET_TILE_ROWS, 1))
-            die_codec(&codec, "Failed to set tile height");
-
-          av1_ref_frame_t ref;
-          ref.idx = 0;
-          ref.img = reference_images[bv * u_blocks + bu];
-          if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref))
-            die_codec(&codec, "Failed to set reference frame");
-
+          printf("C%d, ", (u + v * lf_width));
           fseek(infile, (u + v * lf_width) * image_size_bytes, SEEK_SET);
           aom_img_read(raw, infile);
+          get_raw_image(&frame_to_encode, raw, raw_shift);
+
           ++frame_count;
-          get_frame_stats(&codec, raw, frame_count, 1,
-                          AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
-                              AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY |
-                              AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF,
-                          deadline, &stats);
+          get_frame_stats(&codec, frame_to_encode, frame_count, 1,
+                          AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+                              AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
+                              AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
+                              AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                              AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY,
+                          &stats);
         }
       }
     }
   }
   // Flush encoder.
-  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, deadline, &stats)) {
+  // No ARF, this should not be needed.
+  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, &stats)) {
   }
 
-  printf("Pass 0 complete. Processed %d frames.\n", frame_count);
   if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
 
+  printf("\nFirst pass complete. Processed %d frames.\n", frame_count);
+
   return stats;
 }
 
 static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
-                  const AvxInterface *encoder, const aom_codec_enc_cfg_t *cfg,
-                  int lf_width, int lf_height, int lf_blocksize) {
+                  const AvxInterface *encoder, aom_codec_enc_cfg_t *cfg,
+                  int lf_width, int lf_height, int lf_blocksize, int flags,
+                  aom_image_t *raw_shift) {
   AvxVideoInfo info = { encoder->fourcc,
                         cfg->g_w,
                         cfg->g_h,
@@ -268,27 +244,48 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
   AvxVideoWriter *writer = NULL;
   aom_codec_ctx_t codec;
   int frame_count = 0;
-  int image_size_bytes;
+  int image_size_bytes = aom_img_size_bytes(raw);
   int bu, bv;
   int u_blocks, v_blocks;
+  aom_image_t *frame_to_encode;
+  aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
+  int reference_image_num = 0;
+  int i;
 
   writer = aom_video_writer_open(outfile_name, kContainerIVF, &info);
   if (!writer) die("Failed to open %s for writing", outfile_name);
 
-  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), cfg, flags))
     die_codec(&codec, "Failed to initialize encoder");
-  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
-    die_codec(&codec, "Failed to set frame parallel decoding");
   if (aom_codec_control(&codec, AOME_SET_ENABLEAUTOALTREF, 0))
     die_codec(&codec, "Failed to turn off auto altref");
-  if (aom_codec_control(&codec, AV1E_SET_SINGLE_TILE_DECODING, 1))
-    die_codec(&codec, "Failed to turn on single tile decoding");
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 0))
+    die_codec(&codec, "Failed to set frame parallel decoding");
+  // Note: The superblock is a sequence parameter and has to be the same for 1
+  // sequence. In lightfield application, must choose the superblock size(either
+  // 64x64 or 128x128) before the encoding starts. Otherwise, the default is
+  // AOM_SUPERBLOCK_SIZE_DYNAMIC, and the superblock size will be set to 64x64
+  // internally.
+  if (aom_codec_control(&codec, AV1E_SET_SUPERBLOCK_SIZE,
+                        AOM_SUPERBLOCK_SIZE_64X64))
+    die_codec(&codec, "Failed to set SB size");
 
-  image_size_bytes = aom_img_size_bytes(raw);
   u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
   v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-  aom_image_t *reference_images =
-      (aom_image_t *)malloc(u_blocks * v_blocks * sizeof(aom_image_t));
+
+  reference_image_num = u_blocks * v_blocks;
+  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
+  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  // Allocate memory with the border so that it can be used as a reference.
+  for (i = 0; i < reference_image_num; i++) {
+    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, cfg->g_w,
+                                   cfg->g_h, 32, 8, AOM_BORDER_IN_PIXELS)) {
+      die("Failed to allocate image.");
+    }
+  }
+
+  printf("\n Second pass: ");
+
   // Encode reference images first.
   printf("Encoding Reference Images\n");
   for (bv = 0; bv < v_blocks; ++bv) {
@@ -299,7 +296,6 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
       int block_v_end = (bv + 1) * lf_blocksize;
       int u_block_size, v_block_size;
       int block_ref_u, block_ref_v;
-      struct av1_ref_frame ref_frame;
 
       block_u_end = block_u_end < lf_width ? block_u_end : lf_width;
       block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
@@ -307,25 +303,52 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
       v_block_size = block_v_end - block_v_min;
       block_ref_u = block_u_min + u_block_size / 2;
       block_ref_v = block_v_min + v_block_size / 2;
+
+      printf("A%d, ", (block_ref_u + block_ref_v * lf_width));
       fseek(infile, (block_ref_u + block_ref_v * lf_width) * image_size_bytes,
             SEEK_SET);
       aom_img_read(raw, infile);
-      if (aom_codec_control(&codec, AOME_USE_REFERENCE,
-                            AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
-        die_codec(&codec, "Failed to set reference flags");
+
+      get_raw_image(&frame_to_encode, raw, raw_shift);
+
       // Reference frames may be encoded without tiles.
       ++frame_count;
       printf("Encoding reference image %d of %d\n", bv * u_blocks + bu,
              u_blocks * v_blocks);
-      encode_frame(&codec, raw, frame_count, 1,
-                   AOM_EFLAG_FORCE_GF | AOM_EFLAG_NO_UPD_ENTROPY, deadline,
+      encode_frame(&codec, frame_to_encode, frame_count, 1,
+                   AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+                       AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
+                       AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
+                       AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                       AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY,
                    writer);
-      ref_frame.idx = 0;
-      aom_codec_control(&codec, AV1_GET_REFERENCE, &ref_frame);
-      aom_img_copy(&ref_frame.img, &reference_images[frame_count - 1]);
+
+      if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
+                            &reference_images[frame_count - 1]))
+        die_codec(&codec, "Failed to copy decoder reference frame");
     }
   }
 
+  cfg->large_scale_tile = 1;
+  // Fixed q encoding for camera frames.
+  cfg->rc_end_usage = AOM_Q;
+  if (aom_codec_enc_config_set(&codec, cfg))
+    die_codec(&codec, "Failed to configure encoder");
+
+  // The fixed q value used in encoding.
+  if (aom_codec_control(&codec, AOME_SET_CQ_LEVEL, 36))
+    die_codec(&codec, "Failed to set cq level");
+  if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 1))
+    die_codec(&codec, "Failed to set frame parallel decoding");
+  if (aom_codec_control(&codec, AV1E_SET_SINGLE_TILE_DECODING, 1))
+    die_codec(&codec, "Failed to turn on single tile decoding");
+  // Set tile_columns and tile_rows to MAX values, which guarantees the tile
+  // size of 64 x 64 pixels(i.e. 1 SB) for <= 4k resolution.
+  if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 6))
+    die_codec(&codec, "Failed to set tile width");
+  if (aom_codec_control(&codec, AV1E_SET_TILE_ROWS, 6))
+    die_codec(&codec, "Failed to set tile height");
+
   for (bv = 0; bv < v_blocks; ++bv) {
     for (bu = 0; bu < u_blocks; ++bu) {
       const int block_u_min = bu * lf_blocksize;
@@ -337,56 +360,44 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
       block_v_end = block_v_end < lf_height ? block_v_end : lf_height;
       for (v = block_v_min; v < block_v_end; ++v) {
         for (u = block_u_min; u < block_u_end; ++u) {
-          // This was a work around for a bug in libvpx.  I'm not sure if this
-          // same bug exists in current version of av1.  Need to call this,
-          // otherwise the default is to not use any reference frames.  Then
-          // if you don't have at least one AOM_EFLAG_NO_REF_* flag, all frames
-          // will be intra encoded.  I'm not sure why the default is not to use
-          // any reference frames.  It looks like there is something about the
-          // way I encode the reference frames above that sets that as
-          // default...
-          if (aom_codec_control(&codec, AOME_USE_REFERENCE,
-                                AOM_LAST_FLAG | AOM_GOLD_FLAG | AOM_ALT_FLAG))
-            die_codec(&codec, "Failed to set reference flags");
-
-          // Set tile size to 64 pixels. The tile_columns and
-          // tile_rows in the tile coding are overloaded to represent tile_width
-          // and tile_height, that range from 1 to 64, in the unit of 64 pixels.
-          if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 1))
-            die_codec(&codec, "Failed to set tile width");
-          if (aom_codec_control(&codec, AV1E_SET_TILE_ROWS, 1))
-            die_codec(&codec, "Failed to set tile height");
-
           av1_ref_frame_t ref;
           ref.idx = 0;
+          ref.use_external_ref = 1;
           ref.img = reference_images[bv * u_blocks + bu];
           if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref))
             die_codec(&codec, "Failed to set reference frame");
+
+          printf("C%d, ", (u + v * lf_width));
           fseek(infile, (u + v * lf_width) * image_size_bytes, SEEK_SET);
           aom_img_read(raw, infile);
-          ++frame_count;
+          get_raw_image(&frame_to_encode, raw, raw_shift);
 
+          ++frame_count;
           printf("Encoding image %d of %d\n",
                  frame_count - (u_blocks * v_blocks), lf_width * lf_height);
-          encode_frame(&codec, raw, frame_count, 1,
-                       AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
-                           AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY |
-                           AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF,
-                       deadline, writer);
+          encode_frame(&codec, frame_to_encode, frame_count, 1,
+                       AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+                           AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
+                           AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
+                           AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
+                           AOM_EFLAG_NO_UPD_ARF | AOM_EFLAG_NO_UPD_ENTROPY,
+                       writer);
         }
       }
     }
   }
 
   // Flush encoder.
-  while (encode_frame(&codec, NULL, -1, 1, 0, deadline, writer)) {
+  // No ARF, this should not be needed.
+  while (encode_frame(&codec, NULL, -1, 1, 0, writer)) {
   }
 
-  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+  for (i = 0; i < reference_image_num; i++) aom_img_free(&reference_images[i]);
 
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
   aom_video_writer_close(writer);
 
-  printf("Pass 1 complete. Processed %d frames.\n", frame_count);
+  printf("\nSecond pass complete. Processed %d frames.\n", frame_count);
 }
 
 int main(int argc, char **argv) {
@@ -401,8 +412,10 @@ int main(int argc, char **argv) {
   aom_codec_ctx_t codec;
   aom_codec_enc_cfg_t cfg;
   aom_image_t raw;
+  aom_image_t raw_shift;
   aom_codec_err_t res;
   aom_fixed_buf_t stats;
+  int flags = 0;
 
   const AvxInterface *encoder = NULL;
   const int fps = 30;
@@ -435,14 +448,19 @@ int main(int argc, char **argv) {
     die("Invalid lf_width and/or lf_height: %dx%d", lf_width, lf_height);
   if (lf_blocksize <= 0) die("Invalid lf_blocksize: %d", lf_blocksize);
 
-  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, w, h, 1))
-    die("Failed to allocate image", w, h);
+  if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, w, h, 32)) {
+    die("Failed to allocate image.");
+  }
+  if (!CONFIG_LOWBITDEPTH) {
+    // Need to allocate larger buffer to use hbd internal.
+    aom_img_alloc(&raw_shift, AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH, w, h,
+                  32);
+  }
 
   printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
 
   // Configuration
   res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
-
   if (res) die_codec(&codec, "Failed to get default codec config.");
 
   cfg.g_w = w;
@@ -450,29 +468,32 @@ int main(int argc, char **argv) {
   cfg.g_timebase.num = 1;
   cfg.g_timebase.den = fps;
   cfg.rc_target_bitrate = bitrate;
-  cfg.g_error_resilient = AOM_ERROR_RESILIENT_DEFAULT;
-  // Need to set lag_in_frames to 1 or 0.  Otherwise the frame flags get
-  // overridden after the first frame in encode_frame_to_data_rate() (see where
-  // get_frame_flags() is called).
-  cfg.g_lag_in_frames = 0;
+  cfg.g_error_resilient = 0;  // This is required.
+  cfg.g_lag_in_frames = 0;    // need to set this since default is 19.
   cfg.kf_mode = AOM_KF_DISABLED;
-  cfg.large_scale_tile = 1;
+  cfg.large_scale_tile = 0;  // Only set it to 1 for camera frame encoding.
+  cfg.g_bit_depth = AOM_BITS_8;
+  flags |= (cfg.g_bit_depth > AOM_BITS_8 || !CONFIG_LOWBITDEPTH)
+               ? AOM_CODEC_USE_HIGHBITDEPTH
+               : 0;
 
   if (!(infile = fopen(infile_arg, "rb")))
     die("Failed to open %s for reading", infile_arg);
 
   // Pass 0
   cfg.g_pass = AOM_RC_FIRST_PASS;
-  stats = pass0(&raw, infile, encoder, &cfg, lf_width, lf_height, lf_blocksize);
+  stats = pass0(&raw, infile, encoder, &cfg, lf_width, lf_height, lf_blocksize,
+                flags, &raw_shift);
 
   // Pass 1
   rewind(infile);
   cfg.g_pass = AOM_RC_LAST_PASS;
   cfg.rc_twopass_stats_in = stats;
   pass1(&raw, infile, outfile_arg, encoder, &cfg, lf_width, lf_height,
-        lf_blocksize);
+        lf_blocksize, flags, &raw_shift);
   free(stats.buf);
 
+  if (!CONFIG_LOWBITDEPTH) aom_img_free(&raw_shift);
   aom_img_free(&raw);
   fclose(infile);
 
diff --git a/third_party/aom/examples/lightfield_tile_list_decoder.c b/third_party/aom/examples/lightfield_tile_list_decoder.c
new file mode 100644
index 000000000..cec6baa2c
--- /dev/null
+++ b/third_party/aom/examples/lightfield_tile_list_decoder.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Lightfield Tile List Decoder
+// ============================
+//
+// This is a lightfield tile list decoder example. It takes an input file that
+// contains the anchor frames that are references of the coded tiles, the camera
+// frame header, and tile list OBUs that include the tile information and the
+// compressed tile data. This input file is reconstructed from the encoded
+// lightfield ivf file, and is decodable by AV1 decoder. The lf_width and
+// lf_height arguments are the number of lightfield images in each dimension.
+// The lf_blocksize determines the number of reference images used.
+// Run lightfield tile list decoder to decode an AV1 tile list file:
+// examples/lightfield_tile_list_decoder vase_tile_list.ivf vase_tile_list.yuv
+// 10 10 5 2
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
+
+#define MAX_EXTERNAL_REFERENCES 128
+#define AOM_BORDER_IN_PIXELS 288
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize> "
+          "<num_tile_lists>\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  FILE *outfile = NULL;
+  aom_codec_ctx_t codec;
+  AvxVideoReader *reader = NULL;
+  const AvxInterface *decoder = NULL;
+  const AvxVideoInfo *info = NULL;
+  const char *lf_width_arg;
+  const char *lf_height_arg;
+  const char *lf_blocksize_arg;
+  int width, height;
+  int lf_width, lf_height, lf_blocksize;
+  int u_blocks, v_blocks;
+  int num_tile_lists;
+  aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
+  size_t frame_size = 0;
+  const unsigned char *frame = NULL;
+  int i, n;
+
+  exec_name = argv[0];
+
+  if (argc != 7) die("Invalid number of arguments.");
+
+  reader = aom_video_reader_open(argv[1]);
+  if (!reader) die("Failed to open %s for reading.", argv[1]);
+
+  if (!(outfile = fopen(argv[2], "wb")))
+    die("Failed to open %s for writing.", argv[2]);
+
+  lf_width_arg = argv[3];
+  lf_height_arg = argv[4];
+  lf_blocksize_arg = argv[5];
+  lf_width = (int)strtol(lf_width_arg, NULL, 0);
+  lf_height = (int)strtol(lf_height_arg, NULL, 0);
+  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
+  num_tile_lists = (int)strtol(argv[6], NULL, 0);
+
+  info = aom_video_reader_get_info(reader);
+  width = info->frame_width;
+  height = info->frame_height;
+
+  decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
+  if (!decoder) die("Unknown input codec.");
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  // How many anchor frames we have.
+  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
+  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
+
+  int num_references = v_blocks * u_blocks;
+
+  // Allocate memory to store decoded references.
+  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
+  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  // Allocate memory with the border so that it can be used as a reference.
+  for (i = 0; i < num_references; i++) {
+    unsigned int border = AOM_BORDER_IN_PIXELS;
+    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
+                                   32, 8, border)) {
+      die("Failed to allocate references.");
+    }
+  }
+
+  // Decode anchor frames.
+  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
+
+  for (i = 0; i < num_references; ++i) {
+    aom_video_reader_read_frame(reader);
+    frame = aom_video_reader_get_frame(reader, &frame_size);
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
+      die_codec(&codec, "Failed to decode frame.");
+
+    if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
+                          &reference_images[i]))
+      die_codec(&codec, "Failed to copy decoded reference frame");
+
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+      char name[1024];
+      snprintf(name, sizeof(name), "ref_%d.yuv", i);
+      printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
+      FILE *ref_file = fopen(name, "wb");
+      aom_img_write(img, ref_file);
+      fclose(ref_file);
+    }
+  }
+
+  // Decode the lightfield.
+  aom_codec_control_(&codec, AV1_SET_TILE_MODE, 1);
+
+  // Set external references.
+  av1_ext_ref_frame_t set_ext_ref = { &reference_images[0], num_references };
+  aom_codec_control_(&codec, AV1D_SET_EXT_REF_PTR, &set_ext_ref);
+
+  // Must decode the camera frame header first.
+  aom_video_reader_read_frame(reader);
+  frame = aom_video_reader_get_frame(reader, &frame_size);
+  if (aom_codec_decode(&codec, frame, frame_size, NULL))
+    die_codec(&codec, "Failed to decode the frame.");
+
+  // Decode tile lists one by one.
+  for (n = 0; n < num_tile_lists; n++) {
+    aom_video_reader_read_frame(reader);
+    frame = aom_video_reader_get_frame(reader, &frame_size);
+
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
+      die_codec(&codec, "Failed to decode the tile list.");
+
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img;
+    while ((img = aom_codec_get_frame(&codec, &iter)))
+      fwrite(img->img_data, 1, img->sz, outfile);
+  }
+
+  for (i = 0; i < num_references; i++) aom_img_free(&reference_images[i]);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+  aom_video_reader_close(reader);
+  fclose(outfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/lossless_encoder.c b/third_party/aom/examples/lossless_encoder.c
index 32ab18a16..438ff21c6 100644
--- a/third_party/aom/examples/lossless_encoder.c
+++ b/third_party/aom/examples/lossless_encoder.c
@@ -15,9 +15,8 @@
 
 #include "aom/aom_encoder.h"
 #include "aom/aomcx.h"
-
-#include "../tools_common.h"
-#include "../video_writer.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
 
 static const char *exec_name;
 
@@ -35,7 +34,7 @@ static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
   const aom_codec_err_t res =
-      aom_codec_encode(codec, img, frame_index, 1, flags, AOM_DL_GOOD_QUALITY);
+      aom_codec_encode(codec, img, frame_index, 1, flags);
   if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
 
   while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
diff --git a/third_party/aom/examples/noise_model.c b/third_party/aom/examples/noise_model.c
new file mode 100644
index 000000000..5a5b4d40d
--- /dev/null
+++ b/third_party/aom/examples/noise_model.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+/*!\file
+ * \brief This is an sample binary to create noise params from input video.
+ *
+ * To allow for external denoising applications, this sample binary illustrates
+ * how to create a film grain table (film grain params as a function of time)
+ * from an input video and its corresponding denoised source.
+ *
+ * The --output-grain-table file can be passed as input to the encoder (in
+ * aomenc this is done through the "--film-grain-table" parameter).
+ *
+ * As an example, where the input source is an 854x480 yuv420p 8-bit video
+ * named "input.854_480.yuv" you would use steps similar to the following:
+ *
+ * # Run your denoiser (e.g, using hqdn3d filter):
+ * ffmpeg -vcodec rawvideo -video_size 854x480 -i input.854_480.yuv \
+ *    -vf hqdn3d=5:5:5:5 -vcodec rawvideo -an -f rawvideo \
+ *    denoised.854_480.yuv
+ *
+ * # Model the noise between the denoised version and original source:
+ * ./examples/noise_model --fps=25/1 --width=854 --height=480 --i420 \
+ *    --input-denoised=denoised.854_480.yuv --input=original.854_480.yuv \
+ *    --output-grain-table=film_grain.tbl
+ *
+ * # Encode with your favorite settings (including the grain table):
+ * aomenc --limit=100  --cpu-used=4 --input-bit-depth=8                  \
+ *    --i420 -w 854 -h 480 --end-usage=q --cq-level=25 --lag-in-frames=25 \
+ *    --auto-alt-ref=2 --bit-depth=8 --film-grain-table=film_grain.tbl \
+ *    -o denoised_with_grain_params.ivf denoised.854_480.yuv
+ */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+#include "aom_dsp/aom_dsp_common.h"
+
+#if CONFIG_AV1_DECODER
+#include "aom_dsp/grain_synthesis.h"
+#endif
+
+#include "aom_dsp/grain_table.h"
+#include "aom_dsp/noise_model.h"
+#include "aom_dsp/noise_util.h"
+#include "aom_mem/aom_mem.h"
+#include "common/args.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s --input=<input> --input-denoised=<denoised> "
+          "--output-grain-table=<outfile> "
+          "See comments in noise_model.c for more information.\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static const arg_def_t help =
+    ARG_DEF(NULL, "help", 0, "Show usage options and exit");
+static const arg_def_t width_arg =
+    ARG_DEF("w", "width", 1, "Input width (if rawvideo)");
+static const arg_def_t height_arg =
+    ARG_DEF("h", "height", 1, "Input height (if rawvideo)");
+static const arg_def_t skip_frames_arg =
+    ARG_DEF("s", "skip-frames", 1, "Number of frames to skip (default = 1)");
+static const arg_def_t fps_arg = ARG_DEF(NULL, "fps", 1, "Frame rate");
+static const arg_def_t input_arg = ARG_DEF("-i", "input", 1, "Input filename");
+static const arg_def_t output_grain_table_arg =
+    ARG_DEF("n", "output-grain-table", 1, "Output noise file");
+static const arg_def_t input_denoised_arg =
+    ARG_DEF("d", "input-denoised", 1, "Input denoised filename (YUV) only");
+static const arg_def_t flat_block_finder_arg =
+    ARG_DEF("b", "flat-block-finder", 1, "Run the flat block finder");
+static const arg_def_t block_size_arg =
+    ARG_DEF("b", "block-size", 1, "Block size");
+static const arg_def_t bit_depth_arg =
+    ARG_DEF(NULL, "bit-depth", 1, "Bit depth of input");
+static const arg_def_t use_i420 =
+    ARG_DEF(NULL, "i420", 0, "Input file (and denoised) is I420 (default)");
+static const arg_def_t use_i422 =
+    ARG_DEF(NULL, "i422", 0, "Input file (and denoised) is I422");
+static const arg_def_t use_i444 =
+    ARG_DEF(NULL, "i444", 0, "Input file (and denoised) is I444");
+static const arg_def_t debug_file_arg =
+    ARG_DEF(NULL, "debug-file", 1, "File to output debug info");
+
+typedef struct {
+  int width;
+  int height;
+  struct aom_rational fps;
+  const char *input;
+  const char *input_denoised;
+  const char *output_grain_table;
+  int img_fmt;
+  int block_size;
+  int bit_depth;
+  int run_flat_block_finder;
+  int force_flat_psd;
+  int skip_frames;
+  const char *debug_file;
+} noise_model_args_t;
+
+void parse_args(noise_model_args_t *noise_args, int *argc, char **argv) {
+  struct arg arg;
+  static const arg_def_t *main_args[] = { &help,
+                                          &input_arg,
+                                          &fps_arg,
+                                          &width_arg,
+                                          &height_arg,
+                                          &block_size_arg,
+                                          &output_grain_table_arg,
+                                          &input_denoised_arg,
+                                          &use_i420,
+                                          &use_i422,
+                                          &use_i444,
+                                          &debug_file_arg,
+                                          NULL };
+  for (int argi = *argc + 1; *argv; argi++, argv++) {
+    if (arg_match(&arg, &help, argv)) {
+      fprintf(stdout, "\nOptions:\n");
+      arg_show_usage(stdout, main_args);
+      exit(0);
+    } else if (arg_match(&arg, &width_arg, argv)) {
+      noise_args->width = atoi(arg.val);
+    } else if (arg_match(&arg, &height_arg, argv)) {
+      noise_args->height = atoi(arg.val);
+    } else if (arg_match(&arg, &input_arg, argv)) {
+      noise_args->input = arg.val;
+    } else if (arg_match(&arg, &input_denoised_arg, argv)) {
+      noise_args->input_denoised = arg.val;
+    } else if (arg_match(&arg, &output_grain_table_arg, argv)) {
+      noise_args->output_grain_table = arg.val;
+    } else if (arg_match(&arg, &block_size_arg, argv)) {
+      noise_args->block_size = atoi(arg.val);
+    } else if (arg_match(&arg, &bit_depth_arg, argv)) {
+      noise_args->bit_depth = atoi(arg.val);
+    } else if (arg_match(&arg, &flat_block_finder_arg, argv)) {
+      noise_args->run_flat_block_finder = atoi(arg.val);
+    } else if (arg_match(&arg, &fps_arg, argv)) {
+      noise_args->fps = arg_parse_rational(&arg);
+    } else if (arg_match(&arg, &use_i420, argv)) {
+      noise_args->img_fmt = AOM_IMG_FMT_I420;
+    } else if (arg_match(&arg, &use_i422, argv)) {
+      noise_args->img_fmt = AOM_IMG_FMT_I422;
+    } else if (arg_match(&arg, &use_i444, argv)) {
+      noise_args->img_fmt = AOM_IMG_FMT_I444;
+    } else if (arg_match(&arg, &skip_frames_arg, argv)) {
+      noise_args->skip_frames = atoi(arg.val);
+    } else if (arg_match(&arg, &debug_file_arg, argv)) {
+      noise_args->debug_file = arg.val;
+    } else {
+      fprintf(stdout, "Unknown arg: %s\n\nUsage:\n", *argv);
+      arg_show_usage(stdout, main_args);
+      exit(0);
+    }
+  }
+  if (noise_args->bit_depth > 8) {
+    noise_args->img_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
+  }
+}
+
+#if CONFIG_AV1_DECODER
+static void print_variance_y(FILE *debug_file, aom_image_t *raw,
+                             aom_image_t *denoised, const uint8_t *flat_blocks,
+                             int block_size, aom_film_grain_t *grain) {
+  aom_image_t renoised;
+  grain->apply_grain = 1;
+  grain->random_seed = 1071;
+  aom_img_alloc(&renoised, raw->fmt, raw->w, raw->h, 1);
+  av1_add_film_grain(grain, denoised, &renoised);
+
+  const int num_blocks_w = (raw->w + block_size - 1) / block_size;
+  const int num_blocks_h = (raw->h + block_size - 1) / block_size;
+  fprintf(debug_file, "x = [");
+  for (int by = 0; by < num_blocks_h; by++) {
+    for (int bx = 0; bx < num_blocks_w; bx++) {
+      double block_mean = 0;
+      double noise_std = 0, noise_mean = 0;
+      double renoise_std = 0, renoise_mean = 0;
+      for (int yi = 0; yi < block_size; ++yi) {
+        const int y = by * block_size + yi;
+        for (int xi = 0; xi < block_size; ++xi) {
+          const int x = bx * block_size + xi;
+          const double noise_v = (raw->planes[0][y * raw->stride[0] + x] -
+                                  denoised->planes[0][y * raw->stride[0] + x]);
+          noise_mean += noise_v;
+          noise_std += noise_v * noise_v;
+
+          block_mean += raw->planes[0][y * raw->stride[0] + x];
+
+          const double renoise_v =
+              (renoised.planes[0][y * raw->stride[0] + x] -
+               denoised->planes[0][y * raw->stride[0] + x]);
+          renoise_mean += renoise_v;
+          renoise_std += renoise_v * renoise_v;
+        }
+      }
+      int n = (block_size * block_size);
+      block_mean /= n;
+      noise_mean /= n;
+      renoise_mean /= n;
+      noise_std = sqrt(noise_std / n - noise_mean * noise_mean);
+      renoise_std = sqrt(renoise_std / n - renoise_mean * renoise_mean);
+      fprintf(debug_file, "%d %3.2lf %3.2lf %3.2lf  ",
+              flat_blocks[by * num_blocks_w + bx], block_mean, noise_std,
+              renoise_std);
+    }
+    fprintf(debug_file, "\n");
+  }
+  fprintf(debug_file, "];\n");
+
+  if (raw->fmt & AOM_IMG_FMT_HIGHBITDEPTH) {
+    fprintf(stderr,
+            "Detailed debug info not supported for high bit"
+            "depth formats\n");
+  } else {
+    fprintf(debug_file, "figure(2); clf;\n");
+    fprintf(debug_file,
+            "scatter(x(:, 2:4:end), x(:, 3:4:end), 'r'); hold on;\n");
+    fprintf(debug_file, "scatter(x(:, 2:4:end), x(:, 4:4:end), 'b');\n");
+    fprintf(debug_file,
+            "plot(linspace(0, 255, length(noise_strength_0)), "
+            "noise_strength_0, 'b');\n");
+    fprintf(debug_file,
+            "title('Scatter plot of intensity vs noise strength');\n");
+    fprintf(debug_file,
+            "legend('Actual', 'Estimated', 'Estimated strength');\n");
+    fprintf(debug_file, "figure(3); clf;\n");
+    fprintf(debug_file, "scatter(x(:, 3:4:end), x(:, 4:4:end), 'k');\n");
+    fprintf(debug_file, "title('Actual vs Estimated');\n");
+    fprintf(debug_file, "pause(3);\n");
+  }
+  aom_img_free(&renoised);
+}
+#endif
+
+static void print_debug_info(FILE *debug_file, aom_image_t *raw,
+                             aom_image_t *denoised, uint8_t *flat_blocks,
+                             int block_size, aom_noise_model_t *noise_model) {
+  (void)raw;
+  (void)denoised;
+  (void)flat_blocks;
+  (void)block_size;
+  fprintf(debug_file, "figure(3); clf;\n");
+  fprintf(debug_file, "figure(2); clf;\n");
+  fprintf(debug_file, "figure(1); clf;\n");
+  for (int c = 0; c < 3; ++c) {
+    fprintf(debug_file, "noise_strength_%d = [\n", c);
+    const aom_equation_system_t *eqns =
+        &noise_model->combined_state[c].strength_solver.eqns;
+    for (int k = 0; k < eqns->n; ++k) {
+      fprintf(debug_file, "%lf ", eqns->x[k]);
+    }
+    fprintf(debug_file, "];\n");
+    fprintf(debug_file, "plot(noise_strength_%d); hold on;\n", c);
+  }
+  fprintf(debug_file, "legend('Y', 'cb', 'cr');\n");
+  fprintf(debug_file, "title('Noise strength function');\n");
+
+#if CONFIG_AV1_DECODER
+  aom_film_grain_t grain;
+  aom_noise_model_get_grain_parameters(noise_model, &grain);
+  print_variance_y(debug_file, raw, denoised, flat_blocks, block_size, &grain);
+#endif
+  fflush(debug_file);
+}
+
+int main(int argc, char *argv[]) {
+  noise_model_args_t args = { 0,  0, { 25, 1 }, 0, 0, 0,   AOM_IMG_FMT_I420,
+                              32, 8, 1,         0, 1, NULL };
+  aom_image_t raw, denoised;
+  FILE *infile = NULL;
+  AvxVideoInfo info;
+
+  memset(&info, 0, sizeof(info));
+
+  exec_name = argv[0];
+  parse_args(&args, &argc, argv + 1);
+
+  info.frame_width = args.width;
+  info.frame_height = args.height;
+  info.time_base.numerator = args.fps.den;
+  info.time_base.denominator = args.fps.num;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+  if (!aom_img_alloc(&raw, args.img_fmt, info.frame_width, info.frame_height,
+                     1)) {
+    die("Failed to allocate image.");
+  }
+  if (!aom_img_alloc(&denoised, args.img_fmt, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image.");
+  }
+  infile = fopen(args.input, "r");
+  if (!infile) {
+    die("Failed to open input file:", args.input);
+  }
+  fprintf(stderr, "Bit depth: %d  stride:%d\n", args.bit_depth, raw.stride[0]);
+
+  const int high_bd = args.bit_depth > 8;
+  const int block_size = args.block_size;
+  aom_flat_block_finder_t block_finder;
+  aom_flat_block_finder_init(&block_finder, block_size, args.bit_depth,
+                             high_bd);
+
+  const int num_blocks_w = (info.frame_width + block_size - 1) / block_size;
+  const int num_blocks_h = (info.frame_height + block_size - 1) / block_size;
+  uint8_t *flat_blocks = (uint8_t *)aom_malloc(num_blocks_w * num_blocks_h);
+  // Sets the random seed on the first entry in the output table
+  int16_t random_seed = 1071;
+  aom_noise_model_t noise_model;
+  aom_noise_model_params_t params = { AOM_NOISE_SHAPE_SQUARE, 3, args.bit_depth,
+                                      high_bd };
+  aom_noise_model_init(&noise_model, params);
+
+  FILE *denoised_file = 0;
+  if (args.input_denoised) {
+    denoised_file = fopen(args.input_denoised, "rb");
+    if (!denoised_file)
+      die("Unable to open input_denoised: %s", args.input_denoised);
+  } else {
+    die("--input-denoised file must be specified");
+  }
+  FILE *debug_file = 0;
+  if (args.debug_file) {
+    debug_file = fopen(args.debug_file, "w");
+  }
+  aom_film_grain_table_t grain_table = { 0, 0 };
+
+  int64_t prev_timestamp = 0;
+  int frame_count = 0;
+  while (aom_img_read(&raw, infile)) {
+    if (args.input_denoised) {
+      if (!aom_img_read(&denoised, denoised_file)) {
+        die("Unable to read input denoised file");
+      }
+    }
+    if (frame_count % args.skip_frames == 0) {
+      int num_flat_blocks = num_blocks_w * num_blocks_h;
+      memset(flat_blocks, 1, num_flat_blocks);
+      if (args.run_flat_block_finder) {
+        memset(flat_blocks, 0, num_flat_blocks);
+        num_flat_blocks = aom_flat_block_finder_run(
+            &block_finder, raw.planes[0], info.frame_width, info.frame_height,
+            info.frame_width, flat_blocks);
+        fprintf(stdout, "Num flat blocks %d\n", num_flat_blocks);
+      }
+
+      const uint8_t *planes[3] = { raw.planes[0], raw.planes[1],
+                                   raw.planes[2] };
+      uint8_t *denoised_planes[3] = { denoised.planes[0], denoised.planes[1],
+                                      denoised.planes[2] };
+      int strides[3] = { raw.stride[0] >> high_bd, raw.stride[1] >> high_bd,
+                         raw.stride[2] >> high_bd };
+      int chroma_sub[3] = { raw.x_chroma_shift, raw.y_chroma_shift, 0 };
+
+      fprintf(stdout, "Updating noise model...\n");
+      aom_noise_status_t status = aom_noise_model_update(
+          &noise_model, (const uint8_t *const *)planes,
+          (const uint8_t *const *)denoised_planes, info.frame_width,
+          info.frame_height, strides, chroma_sub, flat_blocks, block_size);
+
+      int64_t cur_timestamp =
+          frame_count * 10000000ULL * args.fps.den / args.fps.num;
+      if (status == AOM_NOISE_STATUS_DIFFERENT_NOISE_TYPE) {
+        fprintf(stdout,
+                "Noise type is different, updating parameters for time "
+                "[ %" PRId64 ", %" PRId64 ")\n",
+                prev_timestamp, cur_timestamp);
+        aom_film_grain_t grain;
+        aom_noise_model_get_grain_parameters(&noise_model, &grain);
+        grain.random_seed = random_seed;
+        random_seed = 0;
+        aom_film_grain_table_append(&grain_table, prev_timestamp, cur_timestamp,
+                                    &grain);
+        aom_noise_model_save_latest(&noise_model);
+        prev_timestamp = cur_timestamp;
+      }
+      if (debug_file) {
+        print_debug_info(debug_file, &raw, &denoised, flat_blocks, block_size,
+                         &noise_model);
+      }
+      fprintf(stdout, "Done noise model update, status = %d\n", status);
+    }
+    frame_count++;
+  }
+
+  aom_film_grain_t grain;
+  aom_noise_model_get_grain_parameters(&noise_model, &grain);
+  grain.random_seed = random_seed;
+  aom_film_grain_table_append(&grain_table, prev_timestamp, INT64_MAX, &grain);
+  if (args.output_grain_table) {
+    struct aom_internal_error_info error_info;
+    if (AOM_CODEC_OK != aom_film_grain_table_write(&grain_table,
+                                                   args.output_grain_table,
+                                                   &error_info)) {
+      die("Unable to write output film grain table");
+    }
+  }
+  aom_film_grain_table_free(&grain_table);
+
+  if (infile) fclose(infile);
+  if (denoised_file) fclose(denoised_file);
+  if (debug_file) fclose(debug_file);
+  aom_img_free(&raw);
+  aom_img_free(&denoised);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/resize_util.c b/third_party/aom/examples/resize_util.c
index 5485691a8..6a84d5740 100644
--- a/third_party/aom/examples/resize_util.c
+++ b/third_party/aom/examples/resize_util.c
@@ -16,8 +16,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "../tools_common.h"
-#include "../av1/encoder/av1_resize.h"
+#include "av1/common/resize.h"
+#include "common/tools_common.h"
 
 static const char *exec_name = NULL;
 
diff --git a/third_party/aom/examples/scalable_decoder.c b/third_party/aom/examples/scalable_decoder.c
new file mode 100644
index 000000000..c22924223
--- /dev/null
+++ b/third_party/aom/examples/scalable_decoder.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Scalable Decoder
+// ==============
+//
+// This is an example of a scalable decoder loop. It takes a 2-spatial-layer
+// input file
+// containing the compressed data (in OBU format), passes it through the
+// decoder, and writes the decompressed frames to disk. The base layer and
+// enhancement layers are stored as separate files, out_lyr0.yuv and
+// out_lyr1.yuv, respectively.
+//
+// Standard Includes
+// -----------------
+// For decoders, you only have to include `aom_decoder.h` and then any
+// header files for the specific codecs you use. In this case, we're using
+// av1.
+//
+// Initializing The Codec
+// ----------------------
+// The libaom decoder is initialized by the call to aom_codec_dec_init().
+// Determining the codec interface to use is handled by AvxVideoReader and the
+// functions prefixed with aom_video_reader_. Discussion of those functions is
+// beyond the scope of this example, but the main gist is to open the input file
+// and parse just enough of it to determine if it's a AVx file and which AVx
+// codec is contained within the file.
+// Note the NULL pointer passed to aom_codec_dec_init(). We do that in this
+// example because we want the algorithm to determine the stream configuration
+// (width/height) and allocate memory automatically.
+//
+// Decoding A Frame
+// ----------------
+// Once the frame has been read into memory, it is decoded using the
+// `aom_codec_decode` function. The call takes a pointer to the data
+// (`frame`) and the length of the data (`frame_size`). No application data
+// is associated with the frame in this example, so the `user_priv`
+// parameter is NULL. The `deadline` parameter is left at zero for this
+// example. This parameter is generally only used when doing adaptive post
+// processing.
+//
+// Codecs may produce a variable number of output frames for every call to
+// `aom_codec_decode`. These frames are retrieved by the
+// `aom_codec_get_frame` iterator function. The iterator variable `iter` is
+// initialized to NULL each time `aom_codec_decode` is called.
+// `aom_codec_get_frame` is called in a loop, returning a pointer to a
+// decoded image or NULL to indicate the end of list.
+//
+// Processing The Decoded Data
+// ---------------------------
+// In this example, we simply write the encoded data to disk. It is
+// important to honor the image's `stride` values.
+//
+// Cleanup
+// -------
+// The `aom_codec_destroy` call frees any memory allocated by the codec.
+//
+// Error Handling
+// --------------
+// This example does not special case any error return codes. If there was
+// an error, a descriptive message is printed and the program exits. With
+// few exceptions, aom_codec functions return an enumerated error status,
+// with the value `0` indicating success.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_decoder.h"
+#include "aom/aomdx.h"
+#include "common/obudec.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
+
+static const char *exec_name;
+
+#define MAX_LAYERS 5
+
+void usage_exit(void) {
+  fprintf(stderr, "Usage: %s <infile>\n", exec_name);
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  int frame_cnt = 0;
+  FILE *outfile[MAX_LAYERS];
+  char filename[80];
+  aom_codec_ctx_t codec;
+  const AvxInterface *decoder = NULL;
+  FILE *inputfile = NULL;
+  uint8_t *buf = NULL;
+  size_t bytes_in_buffer = 0;
+  size_t buffer_size = 0;
+  struct AvxInputContext aom_input_ctx;
+  struct ObuDecInputContext obu_ctx = { &aom_input_ctx, NULL, 0, 0, 0 };
+  aom_codec_stream_info_t si;
+  uint8_t tmpbuf[32];
+  unsigned int i;
+
+  exec_name = argv[0];
+
+  if (argc != 2) die("Invalid number of arguments.");
+
+  if (!(inputfile = fopen(argv[1], "rb")))
+    die("Failed to open %s for read.", argv[1]);
+  obu_ctx.avx_ctx->file = inputfile;
+  obu_ctx.avx_ctx->filename = argv[1];
+
+  decoder = get_aom_decoder_by_index(0);
+  printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
+
+  if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
+    die_codec(&codec, "Failed to initialize decoder.");
+
+  if (aom_codec_control(&codec, AV1D_SET_OUTPUT_ALL_LAYERS, 1)) {
+    die_codec(&codec, "Failed to set output_all_layers control.");
+  }
+
+  // peak sequence header OBU to get number of spatial layers
+  const size_t ret = fread(tmpbuf, 1, 32, inputfile);
+  if (ret != 32) die_codec(&codec, "Input is not a valid obu file");
+  si.is_annexb = 0;
+  if (aom_codec_peek_stream_info(decoder->codec_interface(), tmpbuf, 32, &si)) {
+    die_codec(&codec, "Input is not a valid obu file");
+  }
+  fseek(inputfile, -32, SEEK_CUR);
+
+  if (!file_is_obu(&obu_ctx))
+    die_codec(&codec, "Input is not a valid obu file");
+
+  // open base layer output yuv file
+  snprintf(filename, sizeof(filename), "out_lyr%d.yuv", 0);
+  if (!(outfile[0] = fopen(filename, "wb")))
+    die("Failed top open output for writing.");
+
+  // open any enhancement layer output yuv files
+  for (i = 1; i < si.number_spatial_layers; i++) {
+    snprintf(filename, sizeof(filename), "out_lyr%d.yuv", i);
+    if (!(outfile[i] = fopen(filename, "wb")))
+      die("Failed to open output for writing.");
+  }
+
+  while (!obudec_read_temporal_unit(&obu_ctx, &buf, &bytes_in_buffer,
+                                    &buffer_size)) {
+    aom_codec_iter_t iter = NULL;
+    aom_image_t *img = NULL;
+    if (aom_codec_decode(&codec, buf, bytes_in_buffer, NULL))
+      die_codec(&codec, "Failed to decode frame.");
+
+    while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
+      aom_image_t *img_shifted =
+          aom_img_alloc(NULL, AOM_IMG_FMT_I420, img->d_w, img->d_h, 16);
+      img_shifted->bit_depth = 8;
+      aom_img_downshift(img_shifted, img,
+                        img->bit_depth - img_shifted->bit_depth);
+      if (img->spatial_id == 0) {
+        printf("Writing        base layer 0 %d\n", frame_cnt);
+        aom_img_write(img_shifted, outfile[0]);
+      } else if (img->spatial_id <= (int)(si.number_spatial_layers - 1)) {
+        printf("Writing enhancement layer %d %d\n", img->spatial_id, frame_cnt);
+        aom_img_write(img_shifted, outfile[img->spatial_id]);
+      } else {
+        die_codec(&codec, "Invalid bitstream. Layer id exceeds layer count");
+      }
+      if (img->spatial_id == (int)(si.number_spatial_layers - 1)) ++frame_cnt;
+    }
+  }
+
+  printf("Processed %d frames.\n", frame_cnt);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
+
+  for (i = 0; i < si.number_spatial_layers; i++) fclose(outfile[i]);
+
+  fclose(inputfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/scalable_encoder.c b/third_party/aom/examples/scalable_encoder.c
new file mode 100644
index 000000000..7af03e29f
--- /dev/null
+++ b/third_party/aom/examples/scalable_encoder.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2018, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+// Scalable Encoder
+// ==============
+//
+// This is an example of a scalable encoder loop. It takes two input files in
+// YV12 format, passes it through the encoder, and writes the compressed
+// frames to disk in OBU format.
+//
+// Getting The Default Configuration
+// ---------------------------------
+// Encoders have the notion of "usage profiles." For example, an encoder
+// may want to publish default configurations for both a video
+// conferencing application and a best quality offline encoder. These
+// obviously have very different default settings. Consult the
+// documentation for your codec to see if it provides any default
+// configurations. All codecs provide a default configuration, number 0,
+// which is valid for material in the vacinity of QCIF/QVGA.
+//
+// Updating The Configuration
+// ---------------------------------
+// Almost all applications will want to update the default configuration
+// with settings specific to their usage. Here we set the width and height
+// of the video file to that specified on the command line. We also scale
+// the default bitrate based on the ratio between the default resolution
+// and the resolution specified on the command line.
+//
+// Encoding A Frame
+// ----------------
+// The frame is read as a continuous block (size = width * height * 3 / 2)
+// from the input file. If a frame was read (the input file has not hit
+// EOF) then the frame is passed to the encoder. Otherwise, a NULL
+// is passed, indicating the End-Of-Stream condition to the encoder. The
+// `frame_cnt` is reused as the presentation time stamp (PTS) and each
+// frame is shown for one frame-time in duration. The flags parameter is
+// unused in this example.
+
+// Forced Keyframes
+// ----------------
+// Keyframes can be forced by setting the AOM_EFLAG_FORCE_KF bit of the
+// flags passed to `aom_codec_control()`. In this example, we force a
+// keyframe every <keyframe-interval> frames. Note, the output stream can
+// contain additional keyframes beyond those that have been forced using the
+// AOM_EFLAG_FORCE_KF flag because of automatic keyframe placement by the
+// encoder.
+//
+// Processing The Encoded Data
+// ---------------------------
+// Each packet of type `AOM_CODEC_CX_FRAME_PKT` contains the encoded data
+// for this frame. We write a IVF frame header, followed by the raw data.
+//
+// Cleanup
+// -------
+// The `aom_codec_destroy` call frees any memory allocated by the codec.
+//
+// Error Handling
+// --------------
+// This example does not special case any error return codes. If there was
+// an error, a descriptive message is printed and the program exits. With
+// few exeptions, aom_codec functions return an enumerated error status,
+// with the value `0` indicating success.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aom/aom_encoder.h"
+#include "aom/aomcx.h"
+#include "av1/common/enums.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
+
+static const char *exec_name;
+
+void usage_exit(void) {
+  fprintf(stderr,
+          "Usage: %s <codec> <width> <height> <infile0> <infile1> "
+          "<outfile> <frames to encode>\n"
+          "See comments in scalable_encoder.c for more information.\n",
+          exec_name);
+  exit(EXIT_FAILURE);
+}
+
+static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
+                        int frame_index, int flags, FILE *outfile) {
+  int got_pkts = 0;
+  aom_codec_iter_t iter = NULL;
+  const aom_codec_cx_pkt_t *pkt = NULL;
+  const aom_codec_err_t res =
+      aom_codec_encode(codec, img, frame_index, 1, flags);
+  if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
+
+  while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
+    got_pkts = 1;
+
+    if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
+      const int keyframe = (pkt->data.frame.flags & AOM_FRAME_IS_KEY) != 0;
+      if (fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile) !=
+          pkt->data.frame.sz) {
+        die_codec(codec, "Failed to write compressed frame");
+      }
+      printf(keyframe ? "K" : ".");
+      printf(" %6d\n", (int)pkt->data.frame.sz);
+      fflush(stdout);
+    }
+  }
+
+  return got_pkts;
+}
+
+int main(int argc, char **argv) {
+  FILE *infile0 = NULL;
+  FILE *infile1 = NULL;
+  aom_codec_ctx_t codec;
+  aom_codec_enc_cfg_t cfg;
+  int frame_count = 0;
+  aom_image_t raw0, raw1;
+  aom_codec_err_t res;
+  AvxVideoInfo info;
+  const AvxInterface *encoder = NULL;
+  const int fps = 30;
+  const int bitrate = 200;
+  int keyframe_interval = 0;
+  int max_frames = 0;
+  int frames_encoded = 0;
+  const char *codec_arg = NULL;
+  const char *width_arg = NULL;
+  const char *height_arg = NULL;
+  const char *infile0_arg = NULL;
+  const char *infile1_arg = NULL;
+  const char *outfile_arg = NULL;
+  //  const char *keyframe_interval_arg = NULL;
+  FILE *outfile = NULL;
+
+  exec_name = argv[0];
+
+  // Clear explicitly, as simply assigning "{ 0 }" generates
+  // "missing-field-initializers" warning in some compilers.
+  memset(&info, 0, sizeof(info));
+
+  if (argc != 8) die("Invalid number of arguments");
+
+  codec_arg = argv[1];
+  width_arg = argv[2];
+  height_arg = argv[3];
+  infile0_arg = argv[4];
+  infile1_arg = argv[5];
+  outfile_arg = argv[6];
+  max_frames = (int)strtol(argv[7], NULL, 0);
+
+  encoder = get_aom_encoder_by_name(codec_arg);
+  if (!encoder) die("Unsupported codec.");
+
+  info.codec_fourcc = encoder->fourcc;
+  info.frame_width = (int)strtol(width_arg, NULL, 0);
+  info.frame_height = (int)strtol(height_arg, NULL, 0);
+  info.time_base.numerator = 1;
+  info.time_base.denominator = fps;
+
+  if (info.frame_width <= 0 || info.frame_height <= 0 ||
+      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
+    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
+  }
+
+  if (!aom_img_alloc(&raw0, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image for layer 0.");
+  }
+  if (!aom_img_alloc(&raw1, AOM_IMG_FMT_I420, info.frame_width,
+                     info.frame_height, 1)) {
+    die("Failed to allocate image for layer 1.");
+  }
+
+  //  keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0);
+  keyframe_interval = 100;
+  if (keyframe_interval < 0) die("Invalid keyframe interval value.");
+
+  printf("Using %s\n", aom_codec_iface_name(encoder->codec_interface()));
+
+  res = aom_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
+  if (res) die_codec(&codec, "Failed to get default codec config.");
+
+  cfg.g_w = info.frame_width;
+  cfg.g_h = info.frame_height;
+  cfg.g_timebase.num = info.time_base.numerator;
+  cfg.g_timebase.den = info.time_base.denominator;
+  cfg.rc_target_bitrate = bitrate;
+  cfg.g_error_resilient = 0;
+  cfg.g_lag_in_frames = 0;
+  cfg.rc_end_usage = AOM_Q;
+  cfg.save_as_annexb = 0;
+
+  outfile = fopen(outfile_arg, "wb");
+  if (!outfile) die("Failed to open %s for writing.", outfile_arg);
+
+  if (!(infile0 = fopen(infile0_arg, "rb")))
+    die("Failed to open %s for reading.", infile0_arg);
+  if (!(infile1 = fopen(infile1_arg, "rb")))
+    die("Failed to open %s for reading.", infile0_arg);
+
+  if (aom_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+  if (aom_codec_control(&codec, AOME_SET_CPUUSED, 8))
+    die_codec(&codec, "Failed to set cpu to 8");
+
+  if (aom_codec_control(&codec, AV1E_SET_TILE_COLUMNS, 2))
+    die_codec(&codec, "Failed to set tile columns to 2");
+  if (aom_codec_control(&codec, AV1E_SET_NUM_TG, 3))
+    die_codec(&codec, "Failed to set num of tile groups to 3");
+
+  if (aom_codec_control(&codec, AOME_SET_NUMBER_SPATIAL_LAYERS, 2))
+    die_codec(&codec, "Failed to set number of spatial layers to 2");
+
+  // Encode frames.
+  while (aom_img_read(&raw0, infile0)) {
+    int flags = 0;
+
+    // configure and encode base layer
+
+    if (keyframe_interval > 0 && frames_encoded % keyframe_interval == 0)
+      flags |= AOM_EFLAG_FORCE_KF;
+    else
+      // use previous base layer (LAST) as sole reference
+      // save this frame as LAST to be used as reference by enhanmcent layer
+      // and next base layer
+      flags |= AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+               AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF |
+               AOM_EFLAG_NO_REF_BWD | AOM_EFLAG_NO_REF_ARF2 |
+               AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
+               AOM_EFLAG_NO_UPD_ENTROPY;
+    cfg.g_w = info.frame_width;
+    cfg.g_h = info.frame_height;
+    if (aom_codec_enc_config_set(&codec, &cfg))
+      die_codec(&codec, "Failed to set enc cfg for layer 0");
+    if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 0))
+      die_codec(&codec, "Failed to set layer id to 0");
+    if (aom_codec_control(&codec, AOME_SET_CQ_LEVEL, 62))
+      die_codec(&codec, "Failed to set cq level");
+    encode_frame(&codec, &raw0, frame_count++, flags, outfile);
+
+    // configure and encode enhancement layer
+
+    //  use LAST (base layer) as sole reference
+    flags = AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
+            AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
+            AOM_EFLAG_NO_REF_ARF2 | AOM_EFLAG_NO_UPD_LAST |
+            AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
+            AOM_EFLAG_NO_UPD_ENTROPY;
+    cfg.g_w = info.frame_width;
+    cfg.g_h = info.frame_height;
+    aom_img_read(&raw1, infile1);
+    if (aom_codec_enc_config_set(&codec, &cfg))
+      die_codec(&codec, "Failed to set enc cfg for layer 1");
+    if (aom_codec_control(&codec, AOME_SET_SPATIAL_LAYER_ID, 1))
+      die_codec(&codec, "Failed to set layer id to 1");
+    if (aom_codec_control(&codec, AOME_SET_CQ_LEVEL, 10))
+      die_codec(&codec, "Failed to set cq level");
+    encode_frame(&codec, &raw1, frame_count++, flags, outfile);
+
+    frames_encoded++;
+
+    if (max_frames > 0 && frames_encoded >= max_frames) break;
+  }
+
+  // Flush encoder.
+  while (encode_frame(&codec, NULL, -1, 0, outfile)) continue;
+
+  printf("\n");
+  fclose(infile0);
+  fclose(infile1);
+  printf("Processed %d frames.\n", frame_count / 2);
+
+  aom_img_free(&raw0);
+  aom_img_free(&raw1);
+  if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
+
+  fclose(outfile);
+
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/aom/examples/set_maps.c b/third_party/aom/examples/set_maps.c
index 3a54e5f96..9aeb96e43 100644
--- a/third_party/aom/examples/set_maps.c
+++ b/third_party/aom/examples/set_maps.c
@@ -47,11 +47,10 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "aom/aomcx.h"
 #include "aom/aom_encoder.h"
-
-#include "../tools_common.h"
-#include "../video_writer.h"
+#include "aom/aomcx.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
 
 static const char *exec_name;
 
@@ -95,8 +94,7 @@ static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
-  const aom_codec_err_t res =
-      aom_codec_encode(codec, img, frame_index, 1, 0, AOM_DL_GOOD_QUALITY);
+  const aom_codec_err_t res = aom_codec_encode(codec, img, frame_index, 1, 0);
   if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
 
   while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
diff --git a/third_party/aom/examples/simple_decoder.c b/third_party/aom/examples/simple_decoder.c
index 33a894539..d098d1e0b 100644
--- a/third_party/aom/examples/simple_decoder.c
+++ b/third_party/aom/examples/simple_decoder.c
@@ -49,9 +49,7 @@
 // `aom_codec_decode` function. The call takes a pointer to the data
 // (`frame`) and the length of the data (`frame_size`). No application data
 // is associated with the frame in this example, so the `user_priv`
-// parameter is NULL. The `deadline` parameter is left at zero for this
-// example. This parameter is generally only used when doing adaptive post
-// processing.
+// parameter is NULL.
 //
 // Codecs may produce a variable number of output frames for every call to
 // `aom_codec_decode`. These frames are retrieved by the
@@ -81,10 +79,8 @@
 #include <string.h>
 
 #include "aom/aom_decoder.h"
-
-#include "../tools_common.h"
-#include "../video_reader.h"
-#include "./aom_config.h"
+#include "common/tools_common.h"
+#include "common/video_reader.h"
 
 static const char *exec_name;
 
@@ -127,7 +123,7 @@ int main(int argc, char **argv) {
     size_t frame_size = 0;
     const unsigned char *frame =
         aom_video_reader_get_frame(reader, &frame_size);
-    if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
+    if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame.");
 
     while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
diff --git a/third_party/aom/examples/simple_encoder.c b/third_party/aom/examples/simple_encoder.c
index 996f6dacf..01a37cf0c 100644
--- a/third_party/aom/examples/simple_encoder.c
+++ b/third_party/aom/examples/simple_encoder.c
@@ -100,9 +100,8 @@
 #include <string.h>
 
 #include "aom/aom_encoder.h"
-
-#include "../tools_common.h"
-#include "../video_writer.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
 
 static const char *exec_name;
 
@@ -121,7 +120,7 @@ static int encode_frame(aom_codec_ctx_t *codec, aom_image_t *img,
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
   const aom_codec_err_t res =
-      aom_codec_encode(codec, img, frame_index, 1, flags, AOM_DL_GOOD_QUALITY);
+      aom_codec_encode(codec, img, frame_index, 1, flags);
   if (res != AOM_CODEC_OK) die_codec(codec, "Failed to encode frame");
 
   while ((pkt = aom_codec_get_cx_data(codec, &iter)) != NULL) {
diff --git a/third_party/aom/examples/twopass_encoder.c b/third_party/aom/examples/twopass_encoder.c
index e767bb5d7..1b134cce0 100644
--- a/third_party/aom/examples/twopass_encoder.c
+++ b/third_party/aom/examples/twopass_encoder.c
@@ -52,9 +52,8 @@
 #include <string.h>
 
 #include "aom/aom_encoder.h"
-
-#include "../tools_common.h"
-#include "../video_writer.h"
+#include "common/tools_common.h"
+#include "common/video_writer.h"
 
 static const char *exec_name;
 
@@ -68,13 +67,12 @@ void usage_exit(void) {
 
 static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
                            aom_codec_pts_t pts, unsigned int duration,
-                           aom_enc_frame_flags_t flags, unsigned int deadline,
+                           aom_enc_frame_flags_t flags,
                            aom_fixed_buf_t *stats) {
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
-  const aom_codec_err_t res =
-      aom_codec_encode(ctx, img, pts, duration, flags, deadline);
+  const aom_codec_err_t res = aom_codec_encode(ctx, img, pts, duration, flags);
   if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
 
   while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
@@ -94,13 +92,11 @@ static int get_frame_stats(aom_codec_ctx_t *ctx, const aom_image_t *img,
 
 static int encode_frame(aom_codec_ctx_t *ctx, const aom_image_t *img,
                         aom_codec_pts_t pts, unsigned int duration,
-                        aom_enc_frame_flags_t flags, unsigned int deadline,
-                        AvxVideoWriter *writer) {
+                        aom_enc_frame_flags_t flags, AvxVideoWriter *writer) {
   int got_pkts = 0;
   aom_codec_iter_t iter = NULL;
   const aom_codec_cx_pkt_t *pkt = NULL;
-  const aom_codec_err_t res =
-      aom_codec_encode(ctx, img, pts, duration, flags, deadline);
+  const aom_codec_err_t res = aom_codec_encode(ctx, img, pts, duration, flags);
   if (res != AOM_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
 
   while ((pkt = aom_codec_get_cx_data(ctx, &iter)) != NULL) {
@@ -133,13 +129,11 @@ static aom_fixed_buf_t pass0(aom_image_t *raw, FILE *infile,
   // Calculate frame statistics.
   while (aom_img_read(raw, infile) && frame_count < limit) {
     ++frame_count;
-    get_frame_stats(&codec, raw, frame_count, 1, 0, AOM_DL_GOOD_QUALITY,
-                    &stats);
+    get_frame_stats(&codec, raw, frame_count, 1, 0, &stats);
   }
 
   // Flush encoder.
-  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, AOM_DL_GOOD_QUALITY,
-                         &stats)) {
+  while (get_frame_stats(&codec, NULL, frame_count, 1, 0, &stats)) {
   }
 
   printf("Pass 0 complete. Processed %d frames.\n", frame_count);
@@ -168,11 +162,11 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
   // Encode frames.
   while (aom_img_read(raw, infile) && frame_count < limit) {
     ++frame_count;
-    encode_frame(&codec, raw, frame_count, 1, 0, AOM_DL_GOOD_QUALITY, writer);
+    encode_frame(&codec, raw, frame_count, 1, 0, writer);
   }
 
   // Flush encoder.
-  while (encode_frame(&codec, NULL, -1, 1, 0, AOM_DL_GOOD_QUALITY, writer)) {
+  while (encode_frame(&codec, NULL, -1, 1, 0, writer)) {
   }
 
   printf("\n");
-- 
cgit v1.2.3


From b8df135c97a854c2ff9b4394b016649c601177fa Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Fri, 19 Oct 2018 23:00:02 -0500
Subject: Update libaom to rev b25610052a1398032320008d69b51d2da94f5928

---
 third_party/aom/examples/aom_cx_set_ref.c          |  2 +-
 third_party/aom/examples/inspect.c                 |  4 +-
 .../aom/examples/lightfield_bitstream_parsing.c    | 78 +++++++++++-----------
 third_party/aom/examples/lightfield_decoder.c      | 78 +++++++++-------------
 third_party/aom/examples/lightfield_encoder.c      |  3 +-
 .../aom/examples/lightfield_tile_list_decoder.c    | 76 +++++++++------------
 third_party/aom/examples/twopass_encoder.c         |  3 +-
 7 files changed, 112 insertions(+), 132 deletions(-)

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/aom_cx_set_ref.c b/third_party/aom/examples/aom_cx_set_ref.c
index e02e94c07..fc037d484 100644
--- a/third_party/aom/examples/aom_cx_set_ref.c
+++ b/third_party/aom/examples/aom_cx_set_ref.c
@@ -163,7 +163,7 @@ static int encode_frame(aom_codec_ctx_t *ecodec, aom_image_t *img,
 
         // Copy out first decoded frame, and use it as reference later.
         if (*frame_out == 1 && ext_ref != NULL)
-          if (aom_codec_control(dcodec, AV1_GET_NEW_FRAME_IMAGE, ext_ref))
+          if (aom_codec_control(dcodec, AV1_COPY_NEW_FRAME_IMAGE, ext_ref))
             die_codec(dcodec, "Failed to get decoder new frame");
       }
     }
diff --git a/third_party/aom/examples/inspect.c b/third_party/aom/examples/inspect.c
index 4887fc4a3..9d5f0dcfc 100644
--- a/third_party/aom/examples/inspect.c
+++ b/third_party/aom/examples/inspect.c
@@ -630,7 +630,9 @@ int read_frame() {
     die_codec(&codec, "Failed to decode frame.");
   }
   int got_any_frames = 0;
-  while ((img = aom_codec_get_frame(&codec, &iter))) {
+  aom_image_t *frame_img;
+  while ((frame_img = aom_codec_get_frame(&codec, &iter))) {
+    img = frame_img;
     ++frame_count;
     got_any_frames = 1;
   }
diff --git a/third_party/aom/examples/lightfield_bitstream_parsing.c b/third_party/aom/examples/lightfield_bitstream_parsing.c
index d13f3f172..71d4dec77 100644
--- a/third_party/aom/examples/lightfield_bitstream_parsing.c
+++ b/third_party/aom/examples/lightfield_bitstream_parsing.c
@@ -12,15 +12,14 @@
 // Lightfield Bitstream Parsing
 // ============================
 //
-// This is an lightfield bitstream parsing example. It takes an input file
+// This is a lightfield bitstream parsing example. It takes an input file
 // containing the whole compressed lightfield bitstream(ivf file), and parses it
 // and constructs and outputs a new bitstream that can be decoded by an AV1
-// decoder. The output bitstream contains tile list OBUs. The lf_width and
-// lf_height arguments are the number of lightfield images in each dimension.
-// The lf_blocksize determines the number of reference images used.
+// decoder. The output bitstream contains reference frames(i.e. anchor frames),
+// camera frame header, and tile list OBUs. num_references is the number of
+// anchor frames coded at the beginning of the light field file.
 // After running the lightfield encoder, run lightfield bitstream parsing:
-// examples/lightfield_bitstream_parsing vase10x10.ivf vase_tile_list.ivf 10 10
-// 5
+// examples/lightfield_bitstream_parsing vase10x10.ivf vase_tile_list.ivf 4
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,13 +34,13 @@
 #include "common/video_reader.h"
 #include "common/video_writer.h"
 
+#define MAX_TILES 512
+
 static const char *exec_name;
 
 void usage_exit(void) {
-  fprintf(
-      stderr,
-      "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize> \n",
-      exec_name);
+  fprintf(stderr, "Usage: %s <infile> <outfile> <num_references> \n",
+          exec_name);
   exit(EXIT_FAILURE);
 }
 
@@ -95,39 +94,36 @@ const TILE_LIST_INFO tile_list[2][9] = {
     { 50, 2, 5, 4 } },
 };
 
+static int get_image_bps(aom_img_fmt_t fmt) {
+  switch (fmt) {
+    case AOM_IMG_FMT_I420: return 12;
+    case AOM_IMG_FMT_I422: return 16;
+    case AOM_IMG_FMT_I444: return 24;
+    case AOM_IMG_FMT_I42016: return 24;
+    case AOM_IMG_FMT_I42216: return 32;
+    case AOM_IMG_FMT_I44416: return 48;
+    default: die("Invalid image format");
+  }
+}
+
 int main(int argc, char **argv) {
   aom_codec_ctx_t codec;
   AvxVideoReader *reader = NULL;
   AvxVideoWriter *writer = NULL;
   const AvxInterface *decoder = NULL;
   const AvxVideoInfo *info = NULL;
-  const char *lf_width_arg;
-  const char *lf_height_arg;
-  const char *lf_blocksize_arg;
-  int width, height;
-  int lf_width, lf_height;
-  int lf_blocksize;
-  int u_blocks, v_blocks;
+  int num_references;
   int n, i;
   aom_codec_pts_t pts;
 
   exec_name = argv[0];
-  if (argc != 6) die("Invalid number of arguments.");
+  if (argc != 4) die("Invalid number of arguments.");
 
   reader = aom_video_reader_open(argv[1]);
   if (!reader) die("Failed to open %s for reading.", argv[1]);
 
-  lf_width_arg = argv[3];
-  lf_height_arg = argv[4];
-  lf_blocksize_arg = argv[5];
-
-  lf_width = (int)strtol(lf_width_arg, NULL, 0);
-  lf_height = (int)strtol(lf_height_arg, NULL, 0);
-  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
-
+  num_references = (int)strtol(argv[3], NULL, 0);
   info = aom_video_reader_get_info(reader);
-  width = info->frame_width;
-  height = info->frame_height;
 
   // The writer to write out ivf file in tile list OBU, which can be decoded by
   // AV1 decoder.
@@ -144,11 +140,6 @@ int main(int argc, char **argv) {
   // Decode anchor frames.
   aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
 
-  // How many anchor frames we have.
-  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
-  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-
-  int num_references = v_blocks * u_blocks;
   for (i = 0; i < num_references; ++i) {
     aom_video_reader_read_frame(reader);
 
@@ -223,10 +214,20 @@ int main(int argc, char **argv) {
       die_codec(&codec, "Failed to copy compressed camera frame header.");
   }
 
-  // Allocate a buffer to store tile list bitstream. Image format
-  // AOM_IMG_FMT_I420.
-  size_t data_sz =
-      ALIGN_POWER_OF_TWO(width, 5) * ALIGN_POWER_OF_TWO(height, 5) * 12 / 8;
+  // Read out the image format.
+  aom_img_fmt_t ref_fmt = 0;
+  if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
+    die_codec(&codec, "Failed to get the image format");
+  const int bps = get_image_bps(ref_fmt);
+  // read out the tile size.
+  unsigned int tile_size = 0;
+  if (aom_codec_control(&codec, AV1D_GET_TILE_SIZE, &tile_size))
+    die_codec(&codec, "Failed to get the tile size");
+  const unsigned int tile_width = tile_size >> 16;
+  const unsigned int tile_height = tile_size & 65535;
+  // Allocate a buffer to store tile list bitstream.
+  const size_t data_sz = MAX_TILES * ALIGN_POWER_OF_TWO(tile_width, 5) *
+                         ALIGN_POWER_OF_TWO(tile_height, 5) * bps / 8;
   unsigned char *tl_buf = (unsigned char *)malloc(data_sz);
   if (tl_buf == NULL) die_codec(&codec, "Failed to allocate tile list buffer.");
 
@@ -251,7 +252,8 @@ int main(int argc, char **argv) {
 
     // Write the OBU size using a fixed length_field_size of 4 bytes.
     saved_obu_size_loc = tl;
-    aom_wb_write_literal(&wb, 0, 32);
+    // aom_wb_write_unsigned_literal(&wb, data, bits) requires that bits <= 32.
+    aom_wb_write_unsigned_literal(&wb, 0, 32);
     tl += 4;
     tile_list_obu_header_size += 4;
 
diff --git a/third_party/aom/examples/lightfield_decoder.c b/third_party/aom/examples/lightfield_decoder.c
index 625cddcac..5da468413 100644
--- a/third_party/aom/examples/lightfield_decoder.c
+++ b/third_party/aom/examples/lightfield_decoder.c
@@ -14,14 +14,10 @@
 //
 // This is an example of a simple lightfield decoder. It builds upon the
 // simple_decoder.c example.  It takes an input file containing the compressed
-// data (in ivf format), treating it as a lightfield instead of a video and
-// will decode a single lightfield tile. The lf_width and lf_height arguments
-// are the number of lightfield images in each dimension. The tile to decode
-// is specified by the tile_u, tile_v, tile_s, tile_t arguments. The tile_u,
-// tile_v specify the image and tile_s, tile_t specify the tile in the image.
+// data (in ivf format), treating it as a lightfield instead of a video.
 // After running the lightfield encoder, run lightfield decoder to decode a
-// single tile:
-// examples/lightfield_decoder vase10x10.ivf vase_reference.yuv 10 10 5
+// batch of tiles:
+// examples/lightfield_decoder vase10x10.ivf vase_reference.yuv 4
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -38,10 +34,7 @@
 static const char *exec_name;
 
 void usage_exit(void) {
-  fprintf(
-      stderr,
-      "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize>\n",
-      exec_name);
+  fprintf(stderr, "Usage: %s <infile> <outfile> <num_references>\n", exec_name);
   exit(EXIT_FAILURE);
 }
 
@@ -85,22 +78,14 @@ int main(int argc, char **argv) {
   AvxVideoReader *reader = NULL;
   const AvxInterface *decoder = NULL;
   const AvxVideoInfo *info = NULL;
-  const char *lf_width_arg;
-  const char *lf_height_arg;
-  const char *lf_blocksize_arg;
-  int width, height;
-  int lf_width, lf_height;
-  int lf_blocksize;
-  int u_blocks;
-  int v_blocks;
+  int num_references;
   aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
   size_t frame_size = 0;
   const unsigned char *frame = NULL;
-  int n, i;
-
+  int n, i, j;
   exec_name = argv[0];
 
-  if (argc != 6) die("Invalid number of arguments.");
+  if (argc != 4) die("Invalid number of arguments.");
 
   reader = aom_video_reader_open(argv[1]);
   if (!reader) die("Failed to open %s for reading.", argv[1]);
@@ -108,16 +93,9 @@ int main(int argc, char **argv) {
   if (!(outfile = fopen(argv[2], "wb")))
     die("Failed to open %s for writing.", argv[2]);
 
-  lf_width_arg = argv[3];
-  lf_height_arg = argv[4];
-  lf_blocksize_arg = argv[5];
-  lf_width = (int)strtol(lf_width_arg, NULL, 0);
-  lf_height = (int)strtol(lf_height_arg, NULL, 0);
-  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
+  num_references = (int)strtol(argv[3], NULL, 0);
 
   info = aom_video_reader_get_info(reader);
-  width = info->frame_width;
-  height = info->frame_height;
 
   decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
   if (!decoder) die("Unknown input codec.");
@@ -126,33 +104,39 @@ int main(int argc, char **argv) {
   if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
     die_codec(&codec, "Failed to initialize decoder.");
 
-  // How many anchor frames we have.
-  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
-  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-
-  int num_references = v_blocks * u_blocks;
-
-  // Allocate memory to store decoded references.
-  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
-  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
-  // Allocate memory with the border so that it can be used as a reference.
-  for (i = 0; i < num_references; i++) {
-    unsigned int border = AOM_BORDER_IN_PIXELS;
-    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
-                                   32, 8, border)) {
-      die("Failed to allocate references.");
-    }
+  if (aom_codec_control(&codec, AV1D_SET_IS_ANNEXB, info->is_annexb)) {
+    die("Failed to set annex b status");
   }
 
   // Decode anchor frames.
   aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
-
   for (i = 0; i < num_references; ++i) {
     aom_video_reader_read_frame(reader);
     frame = aom_video_reader_get_frame(reader, &frame_size);
     if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame.");
 
+    if (i == 0) {
+      aom_img_fmt_t ref_fmt = 0;
+      if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
+        die_codec(&codec, "Failed to get the image format");
+
+      int frame_res[2];
+      if (aom_codec_control(&codec, AV1D_GET_FRAME_SIZE, frame_res))
+        die_codec(&codec, "Failed to get the image frame size");
+
+      // Allocate memory to store decoded references. Allocate memory with the
+      // border so that it can be used as a reference.
+      for (j = 0; j < num_references; j++) {
+        unsigned int border = AOM_BORDER_IN_PIXELS;
+        if (!aom_img_alloc_with_border(&reference_images[j], ref_fmt,
+                                       frame_res[0], frame_res[1], 32, 8,
+                                       border)) {
+          die("Failed to allocate references.");
+        }
+      }
+    }
+
     if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
                           &reference_images[i]))
       die_codec(&codec, "Failed to copy decoded reference frame");
diff --git a/third_party/aom/examples/lightfield_encoder.c b/third_party/aom/examples/lightfield_encoder.c
index 22daf622c..f8c37fbb0 100644
--- a/third_party/aom/examples/lightfield_encoder.c
+++ b/third_party/aom/examples/lightfield_encoder.c
@@ -240,7 +240,8 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
   AvxVideoInfo info = { encoder->fourcc,
                         cfg->g_w,
                         cfg->g_h,
-                        { cfg->g_timebase.num, cfg->g_timebase.den } };
+                        { cfg->g_timebase.num, cfg->g_timebase.den },
+                        0 };
   AvxVideoWriter *writer = NULL;
   aom_codec_ctx_t codec;
   int frame_count = 0;
diff --git a/third_party/aom/examples/lightfield_tile_list_decoder.c b/third_party/aom/examples/lightfield_tile_list_decoder.c
index cec6baa2c..2e4f3898d 100644
--- a/third_party/aom/examples/lightfield_tile_list_decoder.c
+++ b/third_party/aom/examples/lightfield_tile_list_decoder.c
@@ -16,12 +16,12 @@
 // contains the anchor frames that are references of the coded tiles, the camera
 // frame header, and tile list OBUs that include the tile information and the
 // compressed tile data. This input file is reconstructed from the encoded
-// lightfield ivf file, and is decodable by AV1 decoder. The lf_width and
-// lf_height arguments are the number of lightfield images in each dimension.
-// The lf_blocksize determines the number of reference images used.
+// lightfield ivf file, and is decodable by AV1 decoder. num_references is
+// the number of anchor frames coded at the beginning of the light field file.
+// num_tile_lists is the number of tile lists need to be decoded.
 // Run lightfield tile list decoder to decode an AV1 tile list file:
 // examples/lightfield_tile_list_decoder vase_tile_list.ivf vase_tile_list.yuv
-// 10 10 5 2
+// 4 2
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -40,8 +40,7 @@ static const char *exec_name;
 
 void usage_exit(void) {
   fprintf(stderr,
-          "Usage: %s <infile> <outfile> <lf_width> <lf_height> <lf_blocksize> "
-          "<num_tile_lists>\n",
+          "Usage: %s <infile> <outfile> <num_references> <num_tile_lists>\n",
           exec_name);
   exit(EXIT_FAILURE);
 }
@@ -52,21 +51,16 @@ int main(int argc, char **argv) {
   AvxVideoReader *reader = NULL;
   const AvxInterface *decoder = NULL;
   const AvxVideoInfo *info = NULL;
-  const char *lf_width_arg;
-  const char *lf_height_arg;
-  const char *lf_blocksize_arg;
-  int width, height;
-  int lf_width, lf_height, lf_blocksize;
-  int u_blocks, v_blocks;
+  int num_references;
   int num_tile_lists;
   aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
   size_t frame_size = 0;
   const unsigned char *frame = NULL;
-  int i, n;
+  int i, j, n;
 
   exec_name = argv[0];
 
-  if (argc != 7) die("Invalid number of arguments.");
+  if (argc != 5) die("Invalid number of arguments.");
 
   reader = aom_video_reader_open(argv[1]);
   if (!reader) die("Failed to open %s for reading.", argv[1]);
@@ -74,17 +68,10 @@ int main(int argc, char **argv) {
   if (!(outfile = fopen(argv[2], "wb")))
     die("Failed to open %s for writing.", argv[2]);
 
-  lf_width_arg = argv[3];
-  lf_height_arg = argv[4];
-  lf_blocksize_arg = argv[5];
-  lf_width = (int)strtol(lf_width_arg, NULL, 0);
-  lf_height = (int)strtol(lf_height_arg, NULL, 0);
-  lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
-  num_tile_lists = (int)strtol(argv[6], NULL, 0);
+  num_references = (int)strtol(argv[3], NULL, 0);
+  num_tile_lists = (int)strtol(argv[4], NULL, 0);
 
   info = aom_video_reader_get_info(reader);
-  width = info->frame_width;
-  height = info->frame_height;
 
   decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
   if (!decoder) die("Unknown input codec.");
@@ -93,33 +80,39 @@ int main(int argc, char **argv) {
   if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
     die_codec(&codec, "Failed to initialize decoder.");
 
-  // How many anchor frames we have.
-  u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
-  v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
-
-  int num_references = v_blocks * u_blocks;
-
-  // Allocate memory to store decoded references.
-  aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
-  if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
-  // Allocate memory with the border so that it can be used as a reference.
-  for (i = 0; i < num_references; i++) {
-    unsigned int border = AOM_BORDER_IN_PIXELS;
-    if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
-                                   32, 8, border)) {
-      die("Failed to allocate references.");
-    }
+  if (aom_codec_control(&codec, AV1D_SET_IS_ANNEXB, info->is_annexb)) {
+    die("Failed to set annex b status");
   }
 
   // Decode anchor frames.
   aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
-
   for (i = 0; i < num_references; ++i) {
     aom_video_reader_read_frame(reader);
     frame = aom_video_reader_get_frame(reader, &frame_size);
     if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode frame.");
 
+    if (i == 0) {
+      aom_img_fmt_t ref_fmt = 0;
+      if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
+        die_codec(&codec, "Failed to get the image format");
+
+      int frame_res[2];
+      if (aom_codec_control(&codec, AV1D_GET_FRAME_SIZE, frame_res))
+        die_codec(&codec, "Failed to get the image frame size");
+
+      // Allocate memory to store decoded references. Allocate memory with the
+      // border so that it can be used as a reference.
+      for (j = 0; j < num_references; j++) {
+        unsigned int border = AOM_BORDER_IN_PIXELS;
+        if (!aom_img_alloc_with_border(&reference_images[j], ref_fmt,
+                                       frame_res[0], frame_res[1], 32, 8,
+                                       border)) {
+          die("Failed to allocate references.");
+        }
+      }
+    }
+
     if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
                           &reference_images[i]))
       die_codec(&codec, "Failed to copy decoded reference frame");
@@ -142,13 +135,11 @@ int main(int argc, char **argv) {
   // Set external references.
   av1_ext_ref_frame_t set_ext_ref = { &reference_images[0], num_references };
   aom_codec_control_(&codec, AV1D_SET_EXT_REF_PTR, &set_ext_ref);
-
   // Must decode the camera frame header first.
   aom_video_reader_read_frame(reader);
   frame = aom_video_reader_get_frame(reader, &frame_size);
   if (aom_codec_decode(&codec, frame, frame_size, NULL))
     die_codec(&codec, "Failed to decode the frame.");
-
   // Decode tile lists one by one.
   for (n = 0; n < num_tile_lists; n++) {
     aom_video_reader_read_frame(reader);
@@ -156,7 +147,6 @@ int main(int argc, char **argv) {
 
     if (aom_codec_decode(&codec, frame, frame_size, NULL))
       die_codec(&codec, "Failed to decode the tile list.");
-
     aom_codec_iter_t iter = NULL;
     aom_image_t *img;
     while ((img = aom_codec_get_frame(&codec, &iter)))
diff --git a/third_party/aom/examples/twopass_encoder.c b/third_party/aom/examples/twopass_encoder.c
index 1b134cce0..a03bc6cc2 100644
--- a/third_party/aom/examples/twopass_encoder.c
+++ b/third_party/aom/examples/twopass_encoder.c
@@ -148,7 +148,8 @@ static void pass1(aom_image_t *raw, FILE *infile, const char *outfile_name,
   AvxVideoInfo info = { encoder->fourcc,
                         cfg->g_w,
                         cfg->g_h,
-                        { cfg->g_timebase.num, cfg->g_timebase.den } };
+                        { cfg->g_timebase.num, cfg->g_timebase.den },
+                        0 };
   AvxVideoWriter *writer = NULL;
   aom_codec_ctx_t codec;
   int frame_count = 0;
-- 
cgit v1.2.3


From d2499ead93dc4298c0882fe98902acb1b5209f99 Mon Sep 17 00:00:00 2001
From: trav90 <travawine@palemoon.org>
Date: Fri, 19 Oct 2018 23:05:00 -0500
Subject: Update libaom to commit ID 1e227d41f0616de9548a673a83a21ef990b62591

---
 third_party/aom/examples/aom_cx_set_ref.c               |  3 +--
 third_party/aom/examples/encoder_util.h                 |  6 +++---
 third_party/aom/examples/lightfield_bitstream_parsing.c |  3 +++
 third_party/aom/examples/lightfield_decoder.c           |  5 ++---
 third_party/aom/examples/lightfield_encoder.c           |  5 +----
 third_party/aom/examples/lightfield_tile_list_decoder.c |  5 ++---
 third_party/aom/examples/noise_model.c                  | 11 ++++++++---
 7 files changed, 20 insertions(+), 18 deletions(-)

(limited to 'third_party/aom/examples')

diff --git a/third_party/aom/examples/aom_cx_set_ref.c b/third_party/aom/examples/aom_cx_set_ref.c
index fc037d484..8e3d216fe 100644
--- a/third_party/aom/examples/aom_cx_set_ref.c
+++ b/third_party/aom/examples/aom_cx_set_ref.c
@@ -54,12 +54,11 @@
 #include "aom/aom_decoder.h"
 #include "aom/aom_encoder.h"
 #include "aom/aomcx.h"
+#include "aom_scale/yv12config.h"
 #include "common/tools_common.h"
 #include "common/video_writer.h"
 #include "examples/encoder_util.h"
 
-#define AOM_BORDER_IN_PIXELS 288
-
 static const char *exec_name;
 
 void usage_exit() {
diff --git a/third_party/aom/examples/encoder_util.h b/third_party/aom/examples/encoder_util.h
index 966f5e004..a6bb3fb48 100644
--- a/third_party/aom/examples/encoder_util.h
+++ b/third_party/aom/examples/encoder_util.h
@@ -11,8 +11,8 @@
 
 // Utility functions used by encoder binaries.
 
-#ifndef EXAMPLES_ENCODER_UTIL_H_
-#define EXAMPLES_ENCODER_UTIL_H_
+#ifndef AOM_EXAMPLES_ENCODER_UTIL_H_
+#define AOM_EXAMPLES_ENCODER_UTIL_H_
 
 #include "aom/aom_image.h"
 
@@ -30,4 +30,4 @@ void aom_find_mismatch(const aom_image_t *const img1,
 int aom_compare_img(const aom_image_t *const img1,
                     const aom_image_t *const img2);
 
-#endif  // EXAMPLES_ENCODER_UTIL_H_
+#endif  // AOM_EXAMPLES_ENCODER_UTIL_H_
diff --git a/third_party/aom/examples/lightfield_bitstream_parsing.c b/third_party/aom/examples/lightfield_bitstream_parsing.c
index 71d4dec77..159f1617a 100644
--- a/third_party/aom/examples/lightfield_bitstream_parsing.c
+++ b/third_party/aom/examples/lightfield_bitstream_parsing.c
@@ -104,6 +104,7 @@ static int get_image_bps(aom_img_fmt_t fmt) {
     case AOM_IMG_FMT_I44416: return 48;
     default: die("Invalid image format");
   }
+  return 0;
 }
 
 int main(int argc, char **argv) {
@@ -212,6 +213,7 @@ int main(int argc, char **argv) {
     if (!aom_video_writer_write_frame(writer, frame_hdr_buf, bytes_to_copy,
                                       pts))
       die_codec(&codec, "Failed to copy compressed camera frame header.");
+    free(frame_hdr_buf);
   }
 
   // Read out the image format.
@@ -219,6 +221,7 @@ int main(int argc, char **argv) {
   if (aom_codec_control(&codec, AV1D_GET_IMG_FORMAT, &ref_fmt))
     die_codec(&codec, "Failed to get the image format");
   const int bps = get_image_bps(ref_fmt);
+  if (!bps) die_codec(&codec, "Invalid image format.");
   // read out the tile size.
   unsigned int tile_size = 0;
   if (aom_codec_control(&codec, AV1D_GET_TILE_SIZE, &tile_size))
diff --git a/third_party/aom/examples/lightfield_decoder.c b/third_party/aom/examples/lightfield_decoder.c
index 5da468413..f5e54db7f 100644
--- a/third_party/aom/examples/lightfield_decoder.c
+++ b/third_party/aom/examples/lightfield_decoder.c
@@ -25,12 +25,11 @@
 
 #include "aom/aom_decoder.h"
 #include "aom/aomdx.h"
+#include "aom_scale/yv12config.h"
+#include "av1/common/enums.h"
 #include "common/tools_common.h"
 #include "common/video_reader.h"
 
-#define MAX_EXTERNAL_REFERENCES 128
-#define AOM_BORDER_IN_PIXELS 288
-
 static const char *exec_name;
 
 void usage_exit(void) {
diff --git a/third_party/aom/examples/lightfield_encoder.c b/third_party/aom/examples/lightfield_encoder.c
index f8c37fbb0..e55cd5ce3 100644
--- a/third_party/aom/examples/lightfield_encoder.c
+++ b/third_party/aom/examples/lightfield_encoder.c
@@ -37,14 +37,11 @@
 
 #include "aom/aom_encoder.h"
 #include "aom/aomcx.h"
+#include "aom_scale/yv12config.h"
 #include "av1/common/enums.h"
-
 #include "common/tools_common.h"
 #include "common/video_writer.h"
 
-#define MAX_EXTERNAL_REFERENCES 128
-#define AOM_BORDER_IN_PIXELS 288
-
 static const char *exec_name;
 
 void usage_exit(void) {
diff --git a/third_party/aom/examples/lightfield_tile_list_decoder.c b/third_party/aom/examples/lightfield_tile_list_decoder.c
index 2e4f3898d..5556bf0e7 100644
--- a/third_party/aom/examples/lightfield_tile_list_decoder.c
+++ b/third_party/aom/examples/lightfield_tile_list_decoder.c
@@ -30,12 +30,11 @@
 
 #include "aom/aom_decoder.h"
 #include "aom/aomdx.h"
+#include "aom_scale/yv12config.h"
+#include "av1/common/enums.h"
 #include "common/tools_common.h"
 #include "common/video_reader.h"
 
-#define MAX_EXTERNAL_REFERENCES 128
-#define AOM_BORDER_IN_PIXELS 288
-
 static const char *exec_name;
 
 void usage_exit(void) {
diff --git a/third_party/aom/examples/noise_model.c b/third_party/aom/examples/noise_model.c
index 5a5b4d40d..5cc6003b6 100644
--- a/third_party/aom/examples/noise_model.c
+++ b/third_party/aom/examples/noise_model.c
@@ -179,9 +179,14 @@ static void print_variance_y(FILE *debug_file, aom_image_t *raw,
                              int block_size, aom_film_grain_t *grain) {
   aom_image_t renoised;
   grain->apply_grain = 1;
-  grain->random_seed = 1071;
+  grain->random_seed = 7391;
   aom_img_alloc(&renoised, raw->fmt, raw->w, raw->h, 1);
-  av1_add_film_grain(grain, denoised, &renoised);
+
+  if (av1_add_film_grain(grain, denoised, &renoised)) {
+    fprintf(stderr, "Internal failure in av1_add_film_grain().\n");
+    aom_img_free(&renoised);
+    return;
+  }
 
   const int num_blocks_w = (raw->w + block_size - 1) / block_size;
   const int num_blocks_h = (raw->h + block_size - 1) / block_size;
@@ -324,7 +329,7 @@ int main(int argc, char *argv[]) {
   const int num_blocks_h = (info.frame_height + block_size - 1) / block_size;
   uint8_t *flat_blocks = (uint8_t *)aom_malloc(num_blocks_w * num_blocks_h);
   // Sets the random seed on the first entry in the output table
-  int16_t random_seed = 1071;
+  int16_t random_seed = 7391;
   aom_noise_model_t noise_model;
   aom_noise_model_params_t params = { AOM_NOISE_SHAPE_SQUARE, 3, args.bit_depth,
                                       high_bd };
-- 
cgit v1.2.3