// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/media/drivers/amlogic_encoder/device_ctx.h"

#include <fuchsia/mediacodec/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <zircon/assert.h>
#include <zircon/types.h>

#include <limits>
#include <memory>
#include <optional>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/mmio-buffer.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/composite.h>
#include <ddk/protocol/platform/device.h>
#include <ddktl/protocol/composite.h>
#include <fbl/algorithm.h>

#include "ddktl/protocol/amlogiccanvas.h"
#include "ddktl/protocol/sysmem.h"
#include "lib/mmio/mmio.h"
#include "lib/zx/interrupt.h"
#include "src/media/drivers/amlogic_encoder/local_codec_factory.h"
#include "src/media/drivers/amlogic_encoder/macros.h"
#include "src/media/drivers/amlogic_encoder/memory_barriers.h"
#include "src/media/drivers/amlogic_encoder/registers.h"
#include "src/media/drivers/amlogic_encoder/scoped_canvas.h"

enum MmioRegion {
  kCbus,
  kDosbus,
  kAobus,
  kHiubus,
};

enum Interrupt {
  kDosMbox2Irq,
};

enum {
  kFragmentPdev = 0,
  kFragmentSysmem = 1,
  kFragmentCanvas = 2,
  kFragmentCount = 3,
};

// clock_level = 5 or 6 will cause encoder reset, reference bug 120995073
constexpr uint32_t kClockLevel = 4;

static uint32_t kV3MvSad[] = {
    // step 0
    0x00000010, 0x00010020, 0x00020030, 0x00030040, 0x00040050, 0x00050060, 0x00060070, 0x00070080,
    0x00080090, 0x000900a0, 0x000a00b0, 0x000b00c0, 0x000c00d0, 0x000d00e0, 0x000e00f0, 0x000f0100,
    // step1
    0x00100008, 0x00110010, 0x00120018, 0x00130020, 0x00140028, 0x00150030, 0x00160038, 0x00170040,
    0x00180048, 0x00190050, 0x001a0058, 0x001b0060, 0x001c0068, 0x001d0070, 0x001e0078, 0x001f0080,
    // step2
    0x00200008, 0x00210018, 0x00220018, 0x00230030, 0x00240030, 0x00250030, 0x00260030, 0x00270048,
    0x00280048, 0x00290048, 0x002a0048, 0x002b0048, 0x002c0048, 0x002d0048, 0x002e0048, 0x002f0060,
    // for step2 4x4-8x8
    0x00300001, 0x00310002, 0x00320003, 0x00330004, 0x00340005, 0x00350006, 0x00360007, 0x00370008,
    0x00380009, 0x0039000a, 0x003a000b, 0x003b000c, 0x003c000d, 0x003d000e, 0x003e000f, 0x003f0010};

constexpr uint32_t kPPicQpCDefault = 39;
constexpr uint32_t kIPicQpCDefault = 39;
static uint8_t kPicQpC[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
                            17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33,
                            34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39};

const fuchsia_hardware_mediacodec_Device_ops_t kFidlOps = {
    .GetCodecFactory =
        [](void* ctx, zx_handle_t handle) {
          zx::channel request(handle);
          reinterpret_cast<DeviceCtx*>(ctx)->GetCodecFactory(std::move(request));
          return ZX_OK;
        },
};

std::unique_ptr<DeviceCtx> DeviceCtx::Create(zx_device_t* parent) {
  ddk::CompositeProtocolClient composite(parent);
  if (!composite.is_valid()) {
    ENCODE_ERROR("Could not get composite protocol");
    return nullptr;
  }

  zx_device_t* fragments[kFragmentCount];
  size_t fragment_count = 0;
  composite.GetFragments(fragments, fbl::count_of(fragments), &fragment_count);

  if (fragment_count != kFragmentCount) {
    ENCODE_ERROR("Could not get fragments");
    return nullptr;
  }

  ddk::PDev pdev(fragments[kFragmentPdev]);
  if (!pdev.is_valid()) {
    ENCODE_ERROR("Failed to get pdev protocol");
    return nullptr;
  }

  ddk::SysmemProtocolClient sysmem(fragments[kFragmentSysmem]);
  if (!sysmem.is_valid()) {
    ENCODE_ERROR("Could not get sysmem protocol");
    return nullptr;
  }

  ddk::AmlogicCanvasProtocolClient canvas(fragments[kFragmentCanvas]);
  if (!canvas.is_valid()) {
    ENCODE_ERROR("Could not get canvas protocol");
    return nullptr;
  }

  std::optional<ddk::MmioBuffer> mmio;
  auto status = pdev.MapMmio(kCbus, &mmio);
  if (status != ZX_OK || !mmio) {
    ENCODE_ERROR("Failed map cbus %d", status);
    return nullptr;
  }
  CbusRegisterIo cbus(std::move(*mmio));

  mmio = std::nullopt;
  status = pdev.MapMmio(kDosbus, &mmio);
  if (status != ZX_OK || !mmio) {
    ENCODE_ERROR("Failed map dosbus %d", status);
    return nullptr;
  }
  DosRegisterIo dosbus(std::move(*mmio));

  mmio = std::nullopt;
  status = pdev.MapMmio(kAobus, &mmio);
  if (status != ZX_OK || !mmio) {
    ENCODE_ERROR("Failed map aobus %d", status);
    return nullptr;
  }
  AoRegisterIo aobus(std::move(*mmio));

  mmio = std::nullopt;
  status = pdev.MapMmio(kHiubus, &mmio);
  if (status != ZX_OK) {
    ENCODE_ERROR("Failed map hiubus %d", status);
    return nullptr;
  }
  HiuRegisterIo hiubus(std::move(*mmio));

  zx::interrupt interrupt;
  status = pdev.GetInterrupt(kDosMbox2Irq, 0, &interrupt);
  if (status != ZX_OK) {
    ENCODE_ERROR("Failed get enc interrupt");
    return nullptr;
  }

  zx::bti bti;
  status = pdev.GetBti(0, &bti);
  if (status != ZX_OK) {
    ENCODE_ERROR("Failed get bti");
    return nullptr;
  }

  return std::make_unique<DeviceCtx>(parent, pdev, canvas, sysmem, std::move(cbus),
                                     std::move(dosbus), std::move(aobus), std::move(hiubus),
                                     std::move(interrupt), std::move(bti));
}

void DeviceCtx::DdkUnbindNew(ddk::UnbindTxn txn) {
  ShutDown();
  txn.Reply();
}

void DeviceCtx::DdkRelease() { delete this; }

zx_status_t DeviceCtx::DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
  return fuchsia_hardware_mediacodec_Device_dispatch(this, txn, msg, &kFidlOps);
}

void DeviceCtx::ShutDown() {
  if (interrupt_handle_) {
    zx_interrupt_destroy(interrupt_handle_.get());
    if (interrupt_thread_.joinable()) {
      interrupt_thread_.join();
    }
  }
  loop_.Shutdown();
}

zx_status_t DeviceCtx::Bind() {
  pdev_device_info_t info;
  auto status = pdev_.GetDeviceInfo(&info);
  if (status != ZX_OK) {
    ENCODE_ERROR("pdev_get_device_info failed");
    return status;
  }

  switch (info.pid) {
    case PDEV_PID_AMLOGIC_S905D2:
      soc_type_ = SocType::kG12A;
      break;
    case PDEV_PID_AMLOGIC_T931:
      soc_type_ = SocType::kG12B;
      break;
    default:
      ENCODE_ERROR("Unknown soc pid: %d", info.pid);
      return ZX_ERR_INVALID_ARGS;
  }

  status = load_firmware(parent(), "h264_enc.bin", firmware_package_vmo_.reset_and_get_address(),
                         &firmware_package_size_);
  if (status != ZX_OK) {
    ENCODE_ERROR("Couldn't load firmware");
    return status;
  }

  zx::vmar::root_self()->map(0, firmware_package_vmo_, 0, firmware_package_size_, ZX_VM_PERM_READ,
                             &firmware_package_ptr_);

  sysmem_sync_ptr_.Bind(ConnectToSysmem());
  if (!sysmem_sync_ptr_) {
    ENCODE_ERROR("ConnectToSysmem() failed");
    status = ZX_ERR_INTERNAL;
    return status;
  }

  InterruptInit();

  status = loop_.StartThread("device-loop", &loop_thread_);
  if (status != ZX_OK) {
    ENCODE_ERROR("could not start loop thread");
    return status;
  }

  status = DdkAdd("amlogic_video_enc");

  return status;
}

zx_status_t DeviceCtx::ParseFirmwarePackage() {
  constexpr std::string_view kEncFirmwareName = "ga_h264_enc_cabac.bin";
  constexpr uint32_t kMaxFirmwareSize = 8 * 4096;

  if (!firmware_package_ptr_) {
    return ZX_ERR_INVALID_ARGS;
  }

  // TODO(50890) unify this code with similar parsing code over in decoder

  constexpr uint32_t kFirmwareHeaderSize = 512;
  struct FirmwareHeader {
    uint32_t magic;
    uint32_t checksum;
    char name[32];
    char cpu[16];
    char format[32];
    char version[32];
    char author[32];
    char date[32];
    char commit[16];
    uint32_t data_size;
    uint32_t time;
  };

  constexpr uint32_t kPackageMagic = ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K');
  constexpr uint32_t kPackageHeaderSize = 256;
  struct PackageHeader {
    uint32_t magic;
    uint32_t size;
    uint32_t checksum;
  };

  constexpr uint32_t kPackageEntryHeaderSize = 256;
  struct PackageEntryHeader {
    char name[32];
    char format[32];
    char cpu[32];
    uint32_t length;
  };

  if (firmware_package_size_ < kPackageHeaderSize) {
    return ZX_ERR_NO_MEMORY;
  }

  uint32_t offset = 0;
  auto header = reinterpret_cast<PackageHeader*>(firmware_package_ptr_ + offset);

  if (header->magic != kPackageMagic) {
    return ZX_ERR_INVALID_ARGS;
  }

  offset += kPackageHeaderSize;

  while (offset < firmware_package_size_) {
    if (offset + kPackageEntryHeaderSize > firmware_package_size_) {
      return ZX_ERR_NO_MEMORY;
    }

    auto entry = reinterpret_cast<PackageEntryHeader*>(firmware_package_ptr_ + offset);

    offset += kPackageEntryHeaderSize;

    if (offset + entry->length > firmware_package_size_) {
      return ZX_ERR_NO_MEMORY;
    }

    if (kFirmwareHeaderSize > entry->length) {
      return ZX_ERR_NO_MEMORY;
    }

    auto firmware_header = reinterpret_cast<FirmwareHeader*>(firmware_package_ptr_ + offset);
    if (firmware_header->data_size + kFirmwareHeaderSize > entry->length) {
      return ZX_ERR_NO_MEMORY;
    }

    if (firmware_header->data_size > kMaxFirmwareSize) {
      return ZX_ERR_NO_MEMORY;
    }

    // TODO(afoxley) check crc

    if (kEncFirmwareName.compare(0, kEncFirmwareName.size(), firmware_header->name,
                                 strnlen(firmware_header->name, sizeof(firmware_header->name))) ==
        0) {
      firmware_ptr_ = firmware_package_ptr_ + offset + kFirmwareHeaderSize;
      firmware_size_ = firmware_header->data_size;
      return ZX_OK;
    }

    offset += entry->length;
  }

  return ZX_ERR_NOT_FOUND;
}

zx_status_t DeviceCtx::LoadFirmware() {
  io_buffer_t firmware_buffer;
  const uint32_t kDmaCount = 0x1000;
  // Request page alignment.
  const uint32_t kBufferAlignShift = 0;
  const char* kBufferName = "EncFirmware";

  HcodecAssistMmcCtrl1::Get().FromValue(HcodecAssistMmcCtrl1::kCtrl).WriteTo(&dosbus_);

  if (!firmware_ptr_) {
    zx_status_t status = ParseFirmwarePackage();
    if (status != ZX_OK) {
      ENCODE_ERROR("Couldn't parse firmware package: %d", status);
      return status;
    }
  }

  ZX_DEBUG_ASSERT(firmware_ptr_ && firmware_size_);

  zx_status_t status = io_buffer_init_aligned(&firmware_buffer, bti_.get(), firmware_size_,
                                              kBufferAlignShift, IO_BUFFER_RW | IO_BUFFER_CONTIG);
  if (status != ZX_OK) {
    ENCODE_ERROR("Failed to make firmware buffer");
    return status;
  }

  zx_object_set_property(firmware_buffer.vmo_handle, ZX_PROP_NAME, kBufferName,
                         strlen(kBufferName));

  memcpy(io_buffer_virt(&firmware_buffer), reinterpret_cast<void*>(firmware_ptr_), firmware_size_);
  io_buffer_cache_flush(&firmware_buffer, 0, firmware_size_);

  BarrierAfterFlush();

  HcodecMpsr::Get().FromValue(0).WriteTo(&dosbus_);
  HcodecCpsr::Get().FromValue(0).WriteTo(&dosbus_);

  // delay
  for (int i = 0; i < 3; i++) {
    HcodecMpsr::Get().ReadFrom(&dosbus_);
  }

  HcodecImemDmaAdr::Get()
      .FromValue(truncate_to_32(io_buffer_phys(&firmware_buffer)))
      .WriteTo(&dosbus_);
  HcodecImemDmaCount::Get().FromValue(kDmaCount).WriteTo(&dosbus_);
  HcodecImemDmaCtrl::Get()
      .FromValue(0)
      .set_ready(1)
      .set_ctrl(HcodecImemDmaCtrl::kCtrl)
      .WriteTo(&dosbus_);

  if (!WaitForRegister(std::chrono::seconds(1), [this] {
        return HcodecImemDmaCtrl::Get().ReadFrom(&dosbus_).ready() == 0;
      })) {
    ENCODE_ERROR("Failed to load microcode.");

    BarrierBeforeRelease();
    io_buffer_release(&firmware_buffer);
    return ZX_ERR_TIMED_OUT;
  }

  BarrierBeforeRelease();
  io_buffer_release(&firmware_buffer);
  return ZX_OK;
}

void DeviceCtx::InterruptInit() {
  interrupt_thread_ = std::thread([this]() {
    while (true) {
      zx_time_t time;
      zx_status_t status = zx_interrupt_wait(interrupt_handle_.get(), &time);
      if (status != ZX_OK) {
        ENCODE_ERROR("zx_interrupt_wait() failed - status: %d", status);
        return;
      }

      HcodecIrqMboxClear::Get().FromValue(1).WriteTo(&dosbus_);
      hw_status_ =
          static_cast<EncoderStatus>(HcodecEncoderStatus::Get().ReadFrom(&dosbus_).reg_value());
      sync_completion_signal(&interrupt_sync_);
    }
  });
}

zx_status_t DeviceCtx::BufferAlloc() {
  constexpr uint32_t kDec0Size = 0x300000;
  constexpr uint32_t kDec1Size = 0x300000;
  constexpr uint32_t kAssitSize = 0xc0000;
  constexpr uint32_t kScaleBufSize = 0x300000;
  constexpr uint32_t kDumpInfoSize = 0xa0000;
  constexpr uint32_t kCbrInfoSize = 0x2000;
  constexpr uint32_t kSPSPPSSize = 0x1000;

  auto result = InternalBuffer::Create("H264EncoderDec0", &sysmem_sync_ptr_, bti(), kDec0Size,
                                       /*is_writable=*/true,
                                       /*is_mapping_needed*/
                                       false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  dec0_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderDec1", &sysmem_sync_ptr_, bti(), kDec1Size,

                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  dec1_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderAssit", &sysmem_sync_ptr_, bti(), kAssitSize,

                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  assit_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderScaleBuf", &sysmem_sync_ptr_, bti(), kScaleBufSize,
                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  scale_buff_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderDumpInfo", &sysmem_sync_ptr_, bti(), kDumpInfoSize,
                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  dump_info_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderCbrInfo", &sysmem_sync_ptr_, bti(), kCbrInfoSize,
                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  false);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  cbr_info_.emplace(result.take_value());

  result = InternalBuffer::Create("H264EncoderSPSPPS", &sysmem_sync_ptr_, bti(), kSPSPPSSize,
                                  /*is_writable=*/true,
                                  /*is_mapping_needed*/
                                  true);
  if (!result.is_ok()) {
    ENCODE_ERROR("Failed to make buffer - status: %d", result.error());
    return result.error();
  }
  sps_pps_data_.emplace(result.take_value());

  return ZX_OK;
}

zx_status_t DeviceCtx::SetInputBuffer(const CodecBuffer* buffer) {
  input_y_canvas_.Reset();
  input_uv_canvas_.Reset();

  uint32_t canvas_h = fbl::round_up(encoder_height_, kCanvasMinHeightAlignment);
  uint32_t canvas_w = fbl::round_up(encoder_width_, kCanvasMinWidthAlignment);

  zx::vmo dup_vmo;
  auto status = buffer->vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
  if (status != ZX_OK) {
    return status;
  }

  // TODO(afoxley) We could pre-setup these canvas handles in BufferCollection setup. Need to decide
  // on a reasonable limit for encoder canvas usage.
  status = CanvasConfig(dup_vmo.get(), canvas_w, canvas_h, /*offset=*/0, &input_y_canvas_,
                        CANVAS_FLAGS_READ);
  if (status != ZX_OK) {
    return status;
  }

  status = buffer->vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &dup_vmo);
  if (status != ZX_OK) {
    return status;
  }

  status = CanvasConfig(dup_vmo.get(), canvas_w, canvas_h / 2, /*offset=*/canvas_w * canvas_h,
                        &input_uv_canvas_, CANVAS_FLAGS_READ);
  if (status != ZX_OK) {
    return status;
  }

  input_buffer_ = buffer;
  input_canvas_ids_ = ((input_uv_canvas_.id()) << 8) | input_y_canvas_.id();
  input_format_ = InputFormat::kNv12;
  noise_reduction_ = NoiseReductionMode::kSNROnly;

  return ZX_OK;
}

void DeviceCtx::SetOutputBuffer(const CodecBuffer* buffer) {
  output_buffer_ = buffer;
  zx_status_t status = zx_cache_flush(buffer->base(), buffer->size(),
                                      ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
  if (status != ZX_OK) {
    ENCODE_ERROR("failed to flush output buffer");
  }
}

zx_status_t DeviceCtx::PowerOn() {
  // ungate dos clk
  // TODO(45193) shared with vdec
  HhiGclkMpeg0::Get().ReadFrom(&hiubus_).set_dos(true).WriteTo(&hiubus_);

  // power up HCODEC
  AoRtiGenPwrSleep0::Get()
      .ReadFrom(&aobus_)
      .set_dos_hcodec_d1_pwr_off(0)
      .set_dos_hcodec_pwr_off(0)
      .WriteTo(&aobus_);
  zx_nanosleep(zx_deadline_after(ZX_USEC(10)));

  // reset all of HCODEC
  DosSwReset1::Get().FromValue(DosSwReset1::kAll).WriteTo(&dosbus_);
  DosSwReset1::Get().FromValue(DosSwReset1::kNone).WriteTo(&dosbus_);

  // ungate clock
  switch (kClockLevel) {
    case 4:  // 400mhz
    {
      // TODO(45193) shared with vdec, should be synchronized
      HhiVdecClkCntl::Get()
          .ReadFrom(&hiubus_)
          .set_hcodec_clk_sel(/*fclk_div4*/ 2)
          .set_hcodec_clk_en(1)
          .set_hcodec_clk_div(/*fclk_div2p5*/ 0)
          .WriteTo(&hiubus_);
      break;
    }
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }

  // TODO(45193) shared with vdec
  DosGclkEn0::Get().ReadFrom(&dosbus_).set_hcodec_en(0x7fff).WriteTo(&dosbus_);

  // powerup hcodec memories
  DosMemPdHcodec::Get().FromValue(0).WriteTo(&dosbus_);

  // remove hcodec iso
  AoRtiGenPwrIso0::Get()
      .ReadFrom(&aobus_)
      .set_dos_hcodec_iso_in_en(0)
      .set_dos_hcodec_iso_out_en(0)
      .WriteTo(&aobus_);
  zx_nanosleep(zx_deadline_after(ZX_USEC(10)));

  // TODO(45193) shared with vdec
  // disable auto clock gate
  DosGenCtrl0::Get().ReadFrom(&dosbus_).set_hcodec_auto_clock_gate(1).WriteTo(&dosbus_);
  DosGenCtrl0::Get().ReadFrom(&dosbus_).set_hcodec_auto_clock_gate(0).WriteTo(&dosbus_);

  zx_nanosleep(zx_deadline_after(ZX_USEC(10)));

  return ZX_OK;
}

zx_status_t DeviceCtx::CanvasConfig(zx_handle_t vmo, uint32_t bytes_per_row, uint32_t height,
                                    uint32_t offset, ScopedCanvasId* canvas_id_out,
                                    uint32_t alloc_flag) {
  canvas_info_t info = {};
  info.height = height;
  info.stride_bytes = bytes_per_row;
  info.flags = alloc_flag;
  uint8_t id;
  zx_handle_t vmo_dup;
  zx_status_t status = zx_handle_duplicate(vmo, ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
  if (status != ZX_OK) {
    return status;
  }
  status = canvas_.Config(zx::vmo(vmo_dup), offset, &info, &id);
  if (status != ZX_OK) {
    return status;
  }
  *canvas_id_out = ScopedCanvasId(&canvas_, id);
  return ZX_OK;
}

zx_status_t DeviceCtx::CanvasInitReference(InternalBuffer* buf, ScopedCanvasId* y_canvas,
                                           ScopedCanvasId* uv_canvas, uint32_t* packed_canvas_ids) {
  uint32_t canvas_width = fbl::round_up(encoder_width_, kCanvasMinWidthAlignment);
  uint32_t canvas_height = fbl::round_up(encoder_height_, kCanvasMinHeightAlignment);

  zx::vmo dup_vmo;
  auto status = buf->vmo_duplicate(&dup_vmo);
  if (status != ZX_OK) {
    return status;
  }
  status = CanvasConfig(dup_vmo.get(), canvas_width, canvas_height, /*offset=*/0, y_canvas,
                        CANVAS_FLAGS_READ);
  if (status != ZX_OK) {
    return status;
  }

  status = buf->vmo_duplicate(&dup_vmo);
  if (status != ZX_OK) {
    return status;
  }
  status = CanvasConfig(dup_vmo.get(), canvas_width, canvas_height / 2,
                        /*offset=*/canvas_width * canvas_height, uv_canvas, CANVAS_FLAGS_READ);
  if (status != ZX_OK) {
    return status;
  }

  // use same canvas for both u and v as they share memory
  *packed_canvas_ids = (uv_canvas->id() << 16) | (uv_canvas->id() << 8) | (y_canvas->id());
  return ZX_OK;
}

zx_status_t DeviceCtx::CanvasInit() {
  auto status = CanvasInitReference(&*dec0_, &dec0_y_canvas_, &dec0_uv_canvas_, &dblk_buf_canvas_);
  if (status != ZX_OK) {
    return status;
  }

  status = CanvasInitReference(&*dec1_, &dec1_y_canvas_, &dec1_uv_canvas_, &ref_buf_canvas_);
  if (status != ZX_OK) {
    return status;
  }

  return ZX_OK;
}

void DeviceCtx::SetInputFormat() {
  uint32_t picsize_x = fbl::round_up(encoder_width_, kPictureMinAlignment);
  uint32_t picsize_y = fbl::round_up(encoder_height_, kPictureMinAlignment);
  uint8_t r2y_en = 0;
  uint32_t ifmt_extra = 0;
  uint8_t downsample_enable = 0;
  uint8_t interpolation_enable = 0;
  uint8_t y_size = 0;
  uint8_t rgb2yuv_en = 0;
  uint8_t r2y_mode = (rgb2yuv_en == 1) ? 1 : 0;
  uint8_t canv_idx0_bppx = 1;
  uint8_t canv_idx1_bppx = 1;
  uint8_t canv_idx0_bppy = 1;
  uint8_t canv_idx1_bppy = 0;
  uint8_t linear_bytes4p = 0;
  uint8_t linear_bytesperline = picsize_x * linear_bytes4p;
  bool linear_enable = false;
  uint32_t oformat = 0;

  uint8_t nr_enable = (noise_reduction_ != NoiseReductionMode::kDisabled) ? 1 : 0;
  uint8_t cfg_y_snr_en = ((noise_reduction_ == NoiseReductionMode::kSNROnly) ||
                          (noise_reduction_ == NoiseReductionMode::k3DNR))
                             ? 1
                             : 0;
  uint8_t cfg_y_tnr_en = ((noise_reduction_ == NoiseReductionMode::kTNROnly) ||
                          (noise_reduction_ == NoiseReductionMode::k3DNR))
                             ? 1
                             : 0;
  uint8_t cfg_c_snr_en = cfg_y_snr_en;
  uint8_t cfg_c_tnr_en = 0;

  // Noise Reduction For Y
  HcodecMfdInReg0D::Get()
      .FromValue(0)
      .set_cfg_y_snr_en(cfg_y_snr_en)
      .set_y_snr_err_norm(1)
      .set_y_snr_gau_bld_core(4)
      .set_y_snr_gau_bld_ofst(-4 & 0x3c)
      .set_y_snr_gau_bld_rate(30)
      .set_y_snr_gau_alp0_min(0)
      .set_y_snr_gau_alp0_max(63)
      .WriteTo(&dosbus_);

  HcodecMfdInReg0E::Get()
      .FromValue(0)
      .set_cfg_y_tnr_en(cfg_y_tnr_en)
      .set_y_tnr_mc_en(1)
      .set_y_tnr_txt_mode(0)
      .set_y_tnr_mot_sad_margin(1)
      .set_y_tnr_alpha_min(8)
      .set_y_tnr_alpha_max(63)
      .set_y_tnr_deghost_os(3)
      .WriteTo(&dosbus_);

  HcodecMfdInReg0F::Get()
      .FromValue(0)
      .set_y_tnr_mot_cortxt_rate(4)
      .set_y_tnr_mot_distxt_ofst(5)
      .set_y_tnr_mot_distxt_rate(4)
      .set_y_tnr_mot_dismot_ofst(4)
      .set_y_tnr_mot_frcsad_lock(8)
      .WriteTo(&dosbus_);

  HcodecMfdInReg10::Get()
      .FromValue(0)
      .set_y_tnr_mot2alp_frc_gain(10)
      .set_y_tnr_mot2alp_nrm_gain(216)
      .set_y_tnr_mot2alp_dis_gain(144)
      .set_y_tnr_mot2alp_dis_ofst(32)
      .WriteTo(&dosbus_);

  HcodecMfdInReg11::Get()
      .FromValue(0)
      .set_y_bld_beta2alp_rate(24)
      .set_y_bld_beta_min(0)
      .set_y_bld_beta_max(63)
      .WriteTo(&dosbus_);

  // Noise Reduction For C
  HcodecMfdInReg12::Get()
      .FromValue(0)
      .set_cfg_c_snr_en(cfg_c_snr_en)
      .set_c_snr_err_norm(0)
      .set_c_snr_gau_bld_core(4)
      .set_c_snr_gau_bld_ofst(-4 & 0x3c)
      .set_c_snr_gau_bld_rate(30)
      .set_c_snr_gau_alp0_min(0)
      .set_c_snr_gau_alp0_max(63)
      .WriteTo(&dosbus_);

  HcodecMfdInReg13::Get()
      .FromValue(0)
      .set_cfg_c_tnr_en(cfg_c_tnr_en)
      .set_c_tnr_mc_en(1)
      .set_c_tnr_txt_mode(0)
      .set_c_tnr_mot_sad_margin(1)
      .set_c_tnr_alpha_min(8)
      .set_c_tnr_alpha_max(63)
      .set_c_tnr_deghost_os(3)
      .WriteTo(&dosbus_);

  HcodecMfdInReg14::Get()
      .FromValue(0)
      .set_c_tnr_mot_cortxt_rate(4)
      .set_c_tnr_mot_distxt_ofst(5)
      .set_c_tnr_mot_distxt_rate(4)
      .set_c_tnr_mot_dismot_ofst(4)
      .set_c_tnr_mot_frcsad_lock(8)
      .WriteTo(&dosbus_);

  HcodecMfdInReg15::Get()
      .FromValue(0)
      .set_c_tnr_mot2alp_frc_gain(10)
      .set_c_tnr_mot2alp_nrm_gain(216)
      .set_c_tnr_mot2alp_dis_gain(144)
      .set_c_tnr_mot2alp_dis_ofst(32)
      .WriteTo(&dosbus_);

  HcodecMfdInReg16::Get()
      .FromValue(0)
      .set_c_bld_beta2alp_rate(24)
      .set_c_bld_beta_min(0)
      .set_c_bld_beta_max(63)
      .WriteTo(&dosbus_);

  HcodecMfdInReg1Ctrl::Get()
      .FromValue(0)
      .set_iformat(input_format_)
      .set_oformat(oformat)
      .set_dsample_en(downsample_enable)
      .set_y_size(y_size)
      .set_interp_en(interpolation_enable)
      .set_r2y_en(r2y_en)
      .set_r2y_mode(r2y_mode)
      .set_ifmt_extra(ifmt_extra)
      .set_nr_enable(nr_enable)
      .WriteTo(&dosbus_);

  HcodecMfdInReg8Dmbl::Get().FromValue(0).set_picsize_x(picsize_x).set_picsize_y(picsize_y).WriteTo(
      &dosbus_);

  if (!linear_enable) {
    HcodecMfdInReg3Canv::Get()
        .FromValue(0)
        .set_input(input_canvas_ids_)
        .set_canv_idx1_bppy(canv_idx1_bppy)
        .set_canv_idx0_bppy(canv_idx0_bppy)
        .set_canv_idx1_bppx(canv_idx1_bppx)
        .set_canv_idx0_bppx(canv_idx0_bppx)
        .WriteTo(&dosbus_);
    HcodecMfdInReg4Lnr0::Get()
        .FromValue(0)
        .set_linear_bytes4p(0)
        .set_linear_bytesperline(0)
        .WriteTo(&dosbus_);
    HcodecMfdInReg5Lnr1::Get().FromValue(0).WriteTo(&dosbus_);
  } else {
    HcodecMfdInReg3Canv::Get()
        .FromValue(0)
        .set_canv_idx1_bppy(canv_idx1_bppy)
        .set_canv_idx0_bppy(canv_idx0_bppy)
        .set_canv_idx1_bppx(canv_idx1_bppx)
        .set_canv_idx0_bppx(canv_idx0_bppx)
        .WriteTo(&dosbus_);
    HcodecMfdInReg4Lnr0::Get()
        .FromValue(0)
        .set_linear_bytes4p(linear_bytes4p)
        .set_linear_bytesperline(linear_bytesperline)
        .WriteTo(&dosbus_);
    HcodecMfdInReg5Lnr1::Get().FromValue(input_canvas_ids_).WriteTo(&dosbus_);
  }

  HcodecMfdInReg9Endn::Get()
      .FromValue(0)
      .set_field0(7)
      .set_field3(6)
      .set_field6(5)
      .set_field9(4)
      .set_field12(3)
      .set_field15(2)
      .set_field18(1)
      .set_field21(0)
      .WriteTo(&dosbus_);
}

void DeviceCtx::InputBufferConfig(zx_paddr_t phys, size_t size) {
  HcodecQdctMbStartPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecQdctMbEndPtr::Get().FromValue(phys + size - 1).WriteTo(&dosbus_);
  HcodecQdctMbWrPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecQdctMbRdPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecQdctMbBuff::Get().FromValue(0).WriteTo(&dosbus_);
}

void DeviceCtx::OutputBufferConfig(zx_paddr_t phys, size_t size) {
  HcodecVlcVbMemCtl::Get()
      .FromValue(0)
      .set_bit_31(1)
      .set_bits_30_24(0x3f)
      .set_bits_23_16(0x20)
      .set_bits_1_0(0x2)
      .WriteTo(&dosbus_);

  HcodecVlcVbStartPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecVlcVbWrPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecVlcVbSwRdPtr::Get().FromValue(phys).WriteTo(&dosbus_);
  HcodecVlcVbEndPtr::Get().FromValue(phys + size - 1).WriteTo(&dosbus_);

  // TODO(afoxley) Ask amlogic what these bits do.
  HcodecVlcVbControl::Get().FromValue(0).set_bit_0(1).WriteTo(&dosbus_);
  HcodecVlcVbControl::Get()
      .FromValue(0)
      .set_bit_14(0)
      .set_bits_5_3(0x7)
      .set_bit_1(1)
      .set_bit_0(0)
      .WriteTo(&dosbus_);
}

void DeviceCtx::ReferenceBuffersConfig() {
  HcodecRecCanvasAddr::Get().FromValue(dblk_buf_canvas_).WriteTo(&dosbus_);
  HcodecDbkRCanvasAddr::Get().FromValue(dblk_buf_canvas_).WriteTo(&dosbus_);
  HcodecDbkWCanvasAddr::Get().FromValue(dblk_buf_canvas_).WriteTo(&dosbus_);

  HcodecAnc0BufferId::Get().FromValue(ref_buf_canvas_).WriteTo(&dosbus_);
  HcodecVlcHcmdConfig::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecMemOffsetReg::Get().FromValue(assit_->phys_base()).WriteTo(&dosbus_);
}

void DeviceCtx::IeMeParameterInit(HcodecIeMeMbType::MbType mb_type) {
  // currently disable half and sub pixel
  HcodecIeMeMode::Get().FromValue(0).set_ie_pippeline_block(12).WriteTo(&dosbus_);
  HcodecIeRefSel::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecIeMeMbType::Get().FromValue(mb_type).WriteTo(&dosbus_);

  if (rows_per_slice_ != picture_to_mb(encoder_height_)) {
    uint32_t mb_per_slice = picture_to_mb(encoder_height_) * rows_per_slice_;
    HcodecFixedSliceCfg::Get().FromValue(mb_per_slice).WriteTo(&dosbus_);
  } else {
    HcodecFixedSliceCfg::Get().FromValue(0).WriteTo(&dosbus_);
  }
}

void DeviceCtx::QuantTableInit() {
  HcodecQQuantControl::Get()
      .FromValue(0)
      .set_quant_table_addr(0)
      .set_quant_table_addr_update(1)
      .WriteTo(&dosbus_);

  for (unsigned int q : quant_table_i4_) {
    HcodecQuantTableData::Get().FromValue(q).WriteTo(&dosbus_);
  }

  HcodecQQuantControl::Get()
      .FromValue(0)
      .set_quant_table_addr(0x8)
      .set_quant_table_addr_update(1)
      .WriteTo(&dosbus_);

  for (unsigned int q : quant_table_i16_) {
    HcodecQuantTableData::Get().FromValue(q).WriteTo(&dosbus_);
  }

  HcodecQQuantControl::Get()
      .FromValue(0)
      .set_quant_table_addr(0x10)
      .set_quant_table_addr_update(1)
      .WriteTo(&dosbus_);

  for (unsigned int q : quant_table_me_) {
    HcodecQuantTableData::Get().FromValue(q).WriteTo(&dosbus_);
  }
}

void DeviceCtx::Reset() {
  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }

  DosSwReset1::Get()
      .FromValue(0)
      .set_hcodec_assist(1)
      .set_hcodec_iqidct(1)
      .set_hcodec_mc(1)
      .set_hcodec_dblk(1)
      .set_hcodec_afifo(1)
      .set_hcodec_vlc(1)
      .set_hcodec_qdct(1)
      .WriteTo(&dosbus_);

  DosSwReset1::Get().FromValue(DosSwReset1::kNone).WriteTo(&dosbus_);

  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }
}

void DeviceCtx::Config(bool idr) {
  constexpr uint32_t kLog2MaxFrameNum = 4;
  constexpr uint32_t kLog2MaxPicOrderCntLsb = 4;
  constexpr uint32_t kAnc0BufferId = 0;
  constexpr uint32_t kCbrTableSize = 0x800;

  uint32_t pic_width_in_mb = picture_to_mb(encoder_width_);

  HcodecVlcTotalBytes::Get().FromValue(0).WriteTo(&dosbus_);
  HcodecVlcConfig::Get().FromValue(0x7).WriteTo(&dosbus_);
  HcodecVlcIntControl::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecAssistAmr1Int0::Get().FromValue(0x15).WriteTo(&dosbus_);
  HcodecAssistAmr1Int1::Get().FromValue(0x8).WriteTo(&dosbus_);
  HcodecAssistAmr1Int3::Get().FromValue(0x14).WriteTo(&dosbus_);

  HcodecIdrPicId::Get().FromValue(idr_pic_id_).WriteTo(&dosbus_);
  HcodecFrameNumber::Get().FromValue(frame_number_).WriteTo(&dosbus_);
  HcodecPicOrderCntLsb::Get().FromValue(pic_order_cnt_lsb_).WriteTo(&dosbus_);

  HcodecLog2MaxPicOrderCntLsb::Get().FromValue(kLog2MaxPicOrderCntLsb).WriteTo(&dosbus_);
  HcodecLog2MaxFrameNum::Get().FromValue(kLog2MaxFrameNum).WriteTo(&dosbus_);
  HcodecAnc0BufferId::Get().FromValue(kAnc0BufferId).WriteTo(&dosbus_);
  HcodecQpPicture::Get().FromValue(kInitialQuant).WriteTo(&dosbus_);

  HcodecHdecMcOmemAuto::Get()
      .FromValue(0)
      .set_use_omem_mb_xy(1)
      .set_omem_max_mb_x(pic_width_in_mb)
      .WriteTo(&dosbus_);

  HcodecVlcAdvConfig::Get()
      .FromValue(0)
      .set_early_mix_mc_hcmd(0)
      .set_update_top_left_mix(1)
      .set_p_top_left_mix(1)
      .set_mv_cal_mixed_type(0)
      .set_mc_hcmd_mixed_type(0)
      .set_use_separate_int_control(1)
      .set_hcmd_intra_use_q_info(1)
      .set_hcmd_left_use_prev_info(1)
      .set_hcmd_use_q_info(1)
      .set_use_q_delta_quant(1)
      .set_detect_I16_from_I4(0)
      .WriteTo(&dosbus_);

  HcodecQdctAdvConfig::Get()
      .FromValue(0)
      .set_mb_info_latch_no_I16_pred_mode(1)
      .set_ie_dma_mbxy_use_i_pred(1)
      .set_ie_dma_read_write_use_ip_idx(1)
      .set_ie_start_use_top_dma_count(1)
      .set_i_pred_top_dma_rd_mbbot(1)
      .set_i_pred_top_dma_wr_disable(1)
      .set_i_pred_mix(0)  // will enable in P Picture
      .set_me_ab_rd_when_intra_in_p(1)
      .set_force_mb_skip_run_when_intra(1)
      .set_mc_out_mixed_type(0)  // will enable in P Picture
      .set_ie_start_when_quant_not_full(1)
      .set_mb_info_state_mix(1)
      .set_mb_type_use_mix_result(0)  // will enable in P Picture
      .set_me_cb_ie_read_enable(0)    // will enable in P Picture
      .set_ie_cur_data_from_me(0)     // will enable in P Picture
      .set_rem_per_use_table(1)
      .set_q_latch_int_enable(0)
      .set_q_use_table(1)
      .set_q_start_wait(0)
      .set_LUMA_16_LEFT_use_cur(1)
      .set_DC_16_LEFT_SUM_use_cur(1)
      .set_c_ref_ie_sel_cur(1)
      .set_c_ipred_perfect_mode(0)
      .set_ref_ie_ul_sel(1)
      .set_mb_type_use_ie_result(1)
      .set_detect_I16_from_I4(1)
      .set_ie_not_wait_ref_busy(1)
      .set_ie_I16_enable(1)
      .set_ie_done_sel(0x3)
      .WriteTo(&dosbus_);

  HcodecIeWeight::Get()
      .FromValue(0)
      .set_i4_weight(i4_weight_)
      .set_i16_weight(i16_weight_)
      .WriteTo(&dosbus_);
  HcodecMeWeight::Get().FromValue(me_weight_).WriteTo(&dosbus_);
  HcodecSadControl0::Get()
      .FromValue(0)
      .set_ie_sad_offset_I16(i16_weight_)
      .set_ie_sad_offset_I4(i4_weight_)
      .WriteTo(&dosbus_);

  HcodecSadControl1::Get()
      .FromValue(0)
      .set_ie_sad_shift_I16(3)
      .set_ie_sad_shift_I4(3)
      .set_me_sad_shift_INTER(2)
      .set_me_sad_offset_INTER(me_weight_)
      .WriteTo(&dosbus_);

  HcodecAdvMvCtl0::Get()
      .FromValue(0)
      .set_adv_mv_large_16x8(1)
      .set_adv_mv_large_8x16(1)
      .set_adv_mv_8x8_weight(0x300)
      .set_adv_mv_4x4x4_weight(0x400)
      .WriteTo(&dosbus_);

  HcodecAdvMvCtl1::Get()
      .FromValue(0)
      .set_adv_mv_16x16_weight(0x080)
      .set_adv_mv_large_16x16(1)
      .set_adv_mv_16x8_weight(0x100)
      .WriteTo(&dosbus_);

  QuantTableInit();

  uint32_t i_pic_qp = (quant_table_i4_[0] & 0xff) + (quant_table_i16_[0] & 0xff);
  uint32_t p_pic_qp = 0;

  if (idr) {
    i_pic_qp /= 2;
  } else {
    i_pic_qp += quant_table_me_[0] & 0xff;
    i_pic_qp /= 3;
  }
  p_pic_qp = i_pic_qp;

  HcodecEncCbrTableAddr::Get().FromValue(cbr_info_->phys_base());
  HcodecEncCbrMbSizeAddr::Get().FromValue(cbr_info_->phys_base() + kCbrTableSize);

  HcodecEncCbrCtl::Get()
      .FromValue(0)
      .set_init_qp_table_idx(HcodecEncCbrCtl::kStartTableId)
      .set_short_term_adjust_shift(HcodecEncCbrCtl::kShortShift)
      .set_long_term_mb_number(HcodecEncCbrCtl::kLongMbNum)
      .set_long_term_adjust_threshold(HcodecEncCbrCtl::kLongThreshold)
      .WriteTo(&dosbus_);

  HcodecEncCbrRegionSize::Get()
      .FromValue(0)
      .set_block_w(HcodecEncCbrRegionSize::kBlockWidth)
      .set_block_h(HcodecEncCbrRegionSize::kBlockHeight)
      .WriteTo(&dosbus_);

  HcodecQdctVlcQuantCtl0::Get()
      .FromValue(0)
      .set_vlc_delta_quant_1(0)
      .set_vlc_quant_1(i_pic_qp)
      .set_vlc_delta_quant_0(0)
      .set_vlc_quant_0(i_pic_qp)
      .WriteTo(&dosbus_);

  HcodecQdctVlcQuantCtl1::Get()
      .FromValue(0)
      .set_vlc_max_delta_q_neg(14)
      .set_vlc_max_delta_q_pos(13)
      .WriteTo(&dosbus_);

  HcodecVlcPicSize::Get()
      .FromValue(0)
      .set_pic_height(encoder_height_)
      .set_pic_width(encoder_width_)
      .WriteTo(&dosbus_);

  HcodecVlcPicPosition::Get().FromValue(0).set_pic_mb_nr(0).set_pic_mby(0).set_pic_mbx(0).WriteTo(
      &dosbus_);

  uint32_t i_pic_qp_c = kIPicQpCDefault;
  uint32_t p_pic_qp_c = kPPicQpCDefault;

  if (i_pic_qp < sizeof(kPicQpC)) {
    i_pic_qp_c = kPicQpC[i_pic_qp];
  }

  if (p_pic_qp < sizeof(kPicQpC)) {
    p_pic_qp_c = kPicQpC[p_pic_qp];
  }

  HcodecQdctQQuantI::Get()
      .FromValue(0)
      .set_i_pic_qp_c(i_pic_qp_c)
      .set_i_pic_qp_c_mod6(i_pic_qp_c % 6)
      .set_i_pic_qp_c_div6(i_pic_qp_c / 6)
      .set_i_pic_qp(i_pic_qp)
      .set_i_pic_qp_mod6(i_pic_qp % 6)
      .set_i_pic_qp_div6(i_pic_qp / 6)
      .WriteTo(&dosbus_);

  HcodecQdctQQuantP::Get()
      .FromValue(0)
      .set_p_pic_qp_c(p_pic_qp_c)
      .set_p_pic_qp_c_mod6(p_pic_qp_c % 6)
      .set_p_pic_qp_c_div6(p_pic_qp_c / 6)
      .set_p_pic_qp(p_pic_qp)
      .set_p_pic_qp_mod6(p_pic_qp % 6)
      .set_p_pic_qp_div6(p_pic_qp / 6)
      .WriteTo(&dosbus_);

  HcodecIgnoreConfig::Get()
      .FromValue(0)
      .set_ignore_lac_coeff_en(1)
      .set_ignore_lac_coeff_2(1)
      .set_ignore_lac_coeff_1(2)
      .set_ignore_cac_coeff_en(1)
      .set_ignore_cac_coeff_else(1)
      .set_ignore_cac_coeff_2(1)
      .set_ignore_cac_coeff_1(2)
      .WriteTo(&dosbus_);

  HcodecIgnoreConfig2::Get()
      .FromValue(0)
      .set_ignore_t_lac_coeff_en(1)
      .set_ignore_t_lac_coeff_else(1)
      .set_ignore_t_lac_coeff_2(2)
      .set_ignore_t_lac_coeff_1(6)
      .set_ignore_cdc_coeff_en(1)
      .set_ignore_t_lac_coeff_else_le_3(0)
      .set_ignore_t_lac_coeff_else_le_4(1)
      .set_ignore_cdc_only_when_empty_cac_inter(1)
      .set_ignore_cdc_only_when_one_empty_inter(1)
      .set_ignore_cdc_range_max_inter(2)
      .set_ignore_cdc_abs_max_inter(0)
      .set_ignore_cdc_only_when_empty_cac_intra(1)
      .set_ignore_cdc_only_when_one_empty_intra(1)
      .set_ignore_cdc_range_max_intra(1)
      .set_ignore_cdc_abs_max_intra(0)
      .WriteTo(&dosbus_);

  HcodecQdctMbControl::Get().FromValue(0).set_mb_info_soft_reset(1).set_soft_reset(1).WriteTo(
      &dosbus_);

  HcodecQdctMbControl::Get()
      .FromValue(0)
      .set_ignore_t_p8x8(0)
      .set_zero_mc_out_null_non_skipped_mb(0)
      .set_no_mc_out_null_non_skipped_mb(0)
      .set_mc_out_even_skipped_mb(0)
      .set_mc_out_wait_cbp_ready(0)
      .set_mc_out_wait_mb_type_ready(0)
      .set_ie_start_int_enable(1)
      .set_i_pred_enable(1)
      .set_ie_sub_enable(1)
      .set_iq_enable(1)
      .set_idct_enable(1)
      .set_mb_pause_enable(1)
      .set_q_enable(1)
      .set_dct_enable(1)
      .set_mb_info_en(1)
      .set_endian(0)
      .set_mb_read_en(0)
      .set_soft_reset(0)
      .WriteTo(&dosbus_);

  HcodecSadControl::Get()
      .FromValue(0)
      .set_ie_result_buff_enable(0)
      .set_ie_result_buff_soft_reset(1)
      .set_sad_enable(0)
      .set_sad_soft_reset(1)
      .WriteTo(&dosbus_);

  HcodecIeResultBuffer::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecSadControl::Get()
      .FromValue(0)
      .set_ie_result_buff_enable(1)
      .set_ie_result_buff_soft_reset(0)
      .set_sad_enable(1)
      .set_sad_soft_reset(0)
      .WriteTo(&dosbus_);

  HcodecIeControl::Get()
      .FromValue(0)
      .set_active_ul_block(1)
      .set_ie_enable(0)
      .set_ie_soft_reset(1)
      .WriteTo(&dosbus_);

  HcodecIeControl::Get()
      .FromValue(0)
      .set_active_ul_block(1)
      .set_ie_enable(0)
      .set_ie_soft_reset(0)
      .WriteTo(&dosbus_);

  HcodecMeSkipLine::Get()
      .FromValue(0)
      .set_step_3_skip_line(8)
      .set_step_2_skip_line(8)
      .set_step_1_skip_line(2)
      .set_step_0_skip_line(0)
      .WriteTo(&dosbus_);

  HcodecMeStep0CloseMv::Get()
      .FromValue(0)
      .set_me_step0_big_sad(0x100)
      .set_me_step0_close_mv_y(2)
      .set_me_step0_close_mv_x(2)
      .WriteTo(&dosbus_);

  HcodecMeStep0CloseMv::Get()
      .FromValue(0)
      .set_me_step0_big_sad(0x100)
      .set_me_step0_close_mv_y(2)
      .set_me_step0_close_mv_x(2)
      .WriteTo(&dosbus_);

  HcodecMeSadEnough01::Get().FromValue(0).set_me_sad_enough_1(0x8).set_me_sad_enough_0(0x8).WriteTo(
      &dosbus_);

  HcodecMeSadEnough23::Get()
      .FromValue(0)
      .set_adv_mv_8x8_enough(0x81)
      .set_me_sad_enough_2(0x11)
      .WriteTo(&dosbus_);

  HcodecMeFSkipSad::Get()
      .FromValue(0)
      .set_force_skip_sad_3(0)
      .set_force_skip_sad_2(0)
      .set_force_skip_sad_1(0)
      .set_force_skip_sad_0(0)
      .WriteTo(&dosbus_);

  HcodecMeFSkipWeight::Get()
      .FromValue(0)
      .set_force_skip_weight_3(0)
      .set_force_skip_weight_2(0)
      .set_force_skip_weight_1(0)
      .set_force_skip_weight_0(0)
      .WriteTo(&dosbus_);

  HcodecMeMvWeight01::Get()
      .FromValue(0)
      .set_me_mv_step_weight_1(0)
      .set_me_mv_pre_weight_1(0)
      .set_me_mv_step_weight_0(0)
      .set_me_mv_pre_weight_0(0)
      .WriteTo(&dosbus_);

  HcodecMeMvWeight23::Get()
      .FromValue(0)
      .set_me_mv_step_weight_3(0)
      .set_me_mv_pre_weight_3(0)
      .set_me_mv_step_weight_2(0)
      .set_me_mv_pre_weight_2(0)
      .WriteTo(&dosbus_);

  HcodecMeSadRangeInc::Get()
      .FromValue(0)
      .set_me_sad_range_3(0)
      .set_me_sad_range_2(0)
      .set_me_sad_range_1(0)
      .set_me_sad_range_0(0)
      .WriteTo(&dosbus_);

  HcodecV4ForceSkipCfg::Get()
      .FromValue(0)
      .set_v4_force_q_r_intra(40)
      .set_v4_force_q_r_inter(40)
      .set_v4_force_q_y_enable(0)
      .set_v4_force_qr_y(5)
      .set_v4_force_qp_y(6)
      .set_v4_force_skip_sad(0)
      .WriteTo(&dosbus_);

  HcodecV3SkipControl::Get()
      .FromValue(0)
      .set_v3_skip_enable(1)
      .set_v3_step_1_weight_enable(1)
      .set_v3_mv_sad_weight_enable(1)
      .set_v3_ipred_type_enable(1)
      .set_v3_force_skip_sad_1(0x60)
      .set_v3_force_skip_sad_0(0x10)
      .WriteTo(&dosbus_);

  HcodecV3SkipWeight::Get()
      .FromValue(0)
      .set_v3_skip_weight_1(0x100)
      .set_v3_skip_weight_0(0x20)
      .WriteTo(&dosbus_);

  HcodecV3L1SkipMaxSad::Get()
      .FromValue(0)
      .set_v3_level_1_f_skip_max_sad(0x20)
      .set_v3_level_1_skip_max_sad(0x60)
      .WriteTo(&dosbus_);

  HcodecV3L2SkipWeight::Get()
      .FromValue(0)
      .set_v3_force_skip_sad_2(0)
      .set_v3_skip_weight_2(0x40)
      .WriteTo(&dosbus_);

  HcodecV3FZeroCtl0::Get()
      .FromValue(0)
      .set_v3_ie_f_zero_sad_I16(0x3c0)
      .set_v3_ie_f_zero_sad_I4(0x7d5)
      .WriteTo(&dosbus_);

  HcodecV3FZeroCtl1::Get()
      .FromValue(0)
      .set_v3_no_ver_when_top_zero_en(0)
      .set_v3_no_hor_when_left_zero_en(1)
      .set_type_hor_break(3)
      .set_v3_me_f_zero_sad(0x360)
      .WriteTo(&dosbus_);

  // MV SAD Table
  for (unsigned int i : kV3MvSad) {
    HcodecV3MvSadTable::Get().FromValue(i).WriteTo(&dosbus_);
  }

  // IE PRED SAD Table
  HcodecV3IpredTypeWeight0::Get()
      .FromValue(0)
      .set_C_ipred_weight_H(0x8)
      .set_C_ipred_weight_V(0x4)
      .set_I4_ipred_weight_else(0x28)
      .set_I4_ipred_weight_most(0x18)
      .WriteTo(&dosbus_);
  HcodecV3IpredTypeWeight1::Get()
      .FromValue(0)
      .set_I16_ipred_weight_DC(0xc)
      .set_I16_ipred_weight_H(0x8)
      .set_I16_ipred_weight_V(0x4)
      .set_C_ipred_weight_DC(0xc)
      .WriteTo(&dosbus_);

  HcodecV3LeftSmallMaxSad::Get()
      .FromValue(0)
      .set_v3_left_small_max_me_sad(0x40)
      .set_v3_left_small_max_ie_sad(0x00)
      .WriteTo(&dosbus_);

  HcodecIeDataFeedBuffInfo::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecCurrCanvasCtrl::Get().FromValue(0).WriteTo(&dosbus_);

  HcodecVlcConfig::Get().ReadFrom(&dosbus_).set_pop_coeff_even_all_zero(1).WriteTo(&dosbus_);

  HcodecInfoDumpStartAddr::Get().FromValue(dump_info_->phys_base()).WriteTo(&dosbus_);

  HcodecIrqMboxClear::Get().FromValue(1).WriteTo(&dosbus_);
  HcodecIrqMboxMask::Get().FromValue(1).WriteTo(&dosbus_);
}

// encoder control
zx_status_t DeviceCtx::EncoderInit(const fuchsia::media::FormatDetails& format_details) {
  memset(quant_table_i4_, kInitialQuant, sizeof(quant_table_i4_));
  memset(quant_table_i16_, kInitialQuant, sizeof(quant_table_i16_));
  memset(quant_table_me_, kInitialQuant, sizeof(quant_table_me_));

  auto status = UpdateEncoderSettings(format_details);
  if (status != ZX_OK) {
    return status;
  }

  status = BufferAlloc();
  if (status != ZX_OK) {
    return status;
  }

  status = PowerOn();
  if (status != ZX_OK) {
    return status;
  }

  status = CanvasInit();
  if (status != ZX_OK) {
    return status;
  }

  firmware_loaded_ = false;
  return ZX_OK;
}

zx_status_t DeviceCtx::UpdateEncoderSettings(const fuchsia::media::FormatDetails& format_details) {
  if (format_details.has_domain() && format_details.domain().is_video() &&
      format_details.domain().video().is_uncompressed()) {
    uint32_t width = format_details.domain().video().uncompressed().image_format.display_width;
    uint32_t height = format_details.domain().video().uncompressed().image_format.display_height;

    if ((encoder_width_ && width != encoder_width_) ||
        (encoder_height_ && height != encoder_height_)) {
      ENCODE_ERROR("frame size change not allowed");
      return ZX_ERR_INVALID_ARGS;
    }

    encoder_width_ = width;
    encoder_height_ = height;
    rows_per_slice_ = picture_to_mb(encoder_height_);
  }

  if (encoder_width_ == 0 || encoder_height_ == 0) {
    ENCODE_ERROR("frame size must be specified");
    return ZX_ERR_INVALID_ARGS;
  }

  if (encoder_width_ % 16 != 0 || encoder_height_ % 2 != 0) {
    ENCODE_ERROR("frame size must be multiple of 16");
    return ZX_ERR_INVALID_ARGS;
  }

  if (format_details.has_encoder_settings() && format_details.encoder_settings().is_h264()) {
    auto& settings = format_details.encoder_settings().h264();
    // TODO(afoxley) reset any stream level state when these settings change
    if (settings.has_bit_rate()) {
      bit_rate_ = settings.bit_rate();
      sps_pps_size_ = 0;
    }
    if (settings.has_frame_rate()) {
      frame_rate_ = settings.frame_rate();
      sps_pps_size_ = 0;
    }
    if (settings.has_gop_size()) {
      gop_size_ = settings.gop_size();
      if (gop_size_ > std::numeric_limits<uint16_t>::max()) {
        gop_size_ = std::numeric_limits<uint16_t>::max();
      }

      // reset any in progress group
      frame_number_ = 0;
      pic_order_cnt_lsb_ = 0;
      sps_pps_size_ = 0;
    }
  }

  return ZX_OK;
}

void DeviceCtx::Start() {
  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }

  DosSwReset1::Get().FromValue(0).set_hcodec_ccpu(1).set_hcodec_mcpu(1).WriteTo(&dosbus_);
  DosSwReset1::Get().FromValue(0).WriteTo(&dosbus_);

  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }

  HcodecMpsr::Get().FromValue(0x0001).WriteTo(&dosbus_);
}

zx_status_t DeviceCtx::EnsureFwLoaded() {
  if (firmware_loaded_) {
    return ZX_OK;
  }

  auto status = LoadFirmware();
  if (status != ZX_OK) {
    return status;
  }

  firmware_loaded_ = true;

  Reset();
  HcodecEncoderStatus::Get().FromValue(EncoderStatus::kIdle).WriteTo(&dosbus_);
  Start();

  return ZX_OK;
}

void DeviceCtx::FrameReset(bool idr) {
  ZX_DEBUG_ASSERT(input_buffer_);
  ZX_DEBUG_ASSERT(output_buffer_);
  HcodecIeMeMbType::MbType mb_type = HcodecIeMeMbType::MbType::kAuto;

  Reset();
  Config(idr);
  ReferenceBuffersConfig();
  InputBufferConfig(input_buffer_->physical_base(), input_buffer_->size());
  OutputBufferConfig(output_buffer_->physical_base(), output_buffer_->size());

  if (idr) {
    mb_type = HcodecIeMeMbType::MbType::kI4MB;
  }
  IeMeParameterInit(mb_type);
  SetInputFormat();
}

zx_status_t DeviceCtx::StopEncoder() {
  HcodecMpsr::Get().FromValue(0).WriteTo(&dosbus_);
  HcodecCpsr::Get().FromValue(0).WriteTo(&dosbus_);

  if (!WaitForRegister(std::chrono::seconds(1), [this] {
        return HcodecImemDmaCtrl::Get().ReadFrom(&dosbus_).ready() == 0;
      })) {
    ENCODE_ERROR("Failed to stop dma.");
    return ZX_ERR_TIMED_OUT;
  }

  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }

  DosSwReset1::Get()
      .FromValue(0)
      .set_hcodec_ccpu(1)
      .set_hcodec_mcpu(1)
      .set_hcodec_assist(1)
      .set_hcodec_iqidct(1)
      .set_hcodec_mc(1)
      .set_hcodec_dblk(1)
      .set_hcodec_afifo(1)
      .set_hcodec_vlc(1)
      .set_hcodec_qdct(1)
      .WriteTo(&dosbus_);

  DosSwReset1::Get().FromValue(DosSwReset1::kNone).WriteTo(&dosbus_);

  for (int i = 0; i < 3; i++) {
    // delay
    DosSwReset1::Get().ReadFrom(&dosbus_);
  }

  return ZX_OK;
}

zx_status_t DeviceCtx::EncodeCmd(EncoderStatus cmd, uint32_t* output_len) {
  constexpr zx::duration kCmdTimeout = zx::msec(1000);

  ZX_DEBUG_ASSERT(output_len);

  sync_completion_reset(&interrupt_sync_);

  hw_status_ = cmd;
  HcodecEncoderStatus::Get().FromValue(hw_status_).WriteTo(&dosbus_);

  zx_status_t status = sync_completion_wait(&interrupt_sync_, kCmdTimeout.get());

  hw_status_ =
      static_cast<EncoderStatus>(HcodecEncoderStatus::Get().ReadFrom(&dosbus_).reg_value());
  if (status == ZX_ERR_TIMED_OUT) {
    ENCODE_ERROR("no interrupt, status %d", hw_status_);
    ENCODE_INFO("mb info: 0x%x, encode status: 0x%x, dct status: 0x%x",
                HcodecVlcMbInfo::Get().ReadFrom(&dosbus_).reg_value(),
                HcodecEncoderStatus::Get().ReadFrom(&dosbus_).reg_value(),
                HcodecQdctStatusCtrl::Get().ReadFrom(&dosbus_).reg_value());
    ENCODE_INFO("vlc status: 0x%x, me status: 0x%x, risc pc:0x%x, debug:0x%x",
                HcodecVlcStatusCtrl::Get().ReadFrom(&dosbus_).reg_value(),
                HcodecMeStatus::Get().ReadFrom(&dosbus_).reg_value(),
                HcodecMpcE::Get().ReadFrom(&dosbus_).reg_value(),
                HcodecDebugReg::Get().ReadFrom(&dosbus_).reg_value());
    return status;
  }

  if (hw_status_ == EncoderStatus::kIdrDone || hw_status_ == EncoderStatus::kNonIdrDone ||
      hw_status_ == EncoderStatus::kPictureDone || hw_status_ == EncoderStatus::kSequenceDone) {
    *output_len = HcodecVlcTotalBytes::Get().ReadFrom(&dosbus_).reg_value();
  } else {
    ENCODE_ERROR("status %d", hw_status_);
    return ZX_ERR_TIMED_OUT;
  }

  return ZX_OK;
}

zx_status_t DeviceCtx::EncodeFrame(uint32_t* output_len) {
  ZX_DEBUG_ASSERT(output_len);
  ZX_DEBUG_ASSERT(output_buffer_);
  ZX_DEBUG_ASSERT(input_buffer_);

  auto status = EnsureFwLoaded();
  if (status != ZX_OK) {
    return status;
  }

  EncoderStatus cmd = EncoderStatus::kIdr;
  if (frame_number_ > 0) {
    cmd = EncoderStatus::kNonIdr;
  }
  bool idr = cmd == EncoderStatus::kIdr;

  if (idr && !sps_pps_size_) {
    status = EncodeSPSPPS();
    if (status != ZX_OK) {
      return status;
    }
  }

  FrameReset(idr);

  status = EncodeCmd(cmd, output_len);
  if (status != ZX_OK) {
    return status;
  }

  // setup for next frame
  if (idr) {
    idr_pic_id_++;
  }

  pic_order_cnt_lsb_ += 2;
  frame_number_ += 1;

  if (frame_number_ >= gop_size_) {
    frame_number_ = 0;
    pic_order_cnt_lsb_ = 0;
  }

  // commit and swap to next canvas buffer
  std::swap(ref_buf_canvas_, dblk_buf_canvas_);

  // TODO(afoxley) If output is in RAM domain the invalidate would not be required
  status = zx_cache_flush(output_buffer_->base(), *output_len,
                          ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);

  if (idr) {
    // The encoder hardware aparently requires the output pointer to be 16 byte aligned, so always
    // encode to the start and then shuffle the SPS/PPS data in when we insert it.
    // TODO(afoxley), if frequent SPS/PPS NAL's are required then make a separate API for them.
    memmove(output_buffer_->base() + sps_pps_size_, output_buffer_->base(), *output_len);
    memcpy(output_buffer_->base(), sps_pps_data_->virt_base(), sps_pps_size_);
    *output_len += sps_pps_size_;
  }

  if (status != ZX_OK) {
    return status;
  }

  return ZX_OK;
}

zx_status_t DeviceCtx::EncodeSPSPPS() {
  sps_pps_size_ = 0;
  FrameReset(/*idr*/ false);
  OutputBufferConfig(sps_pps_data_->phys_base(), sps_pps_data_->size());

  IeMeParameterInit(HcodecIeMeMbType::kDefault);
  auto status = EncodeCmd(EncoderStatus::kSequence, &sps_pps_size_);
  if (status != ZX_OK) {
    return status;
  }

  IeMeParameterInit(HcodecIeMeMbType::kDefault);
  status = EncodeCmd(EncoderStatus::kPicture, &sps_pps_size_);
  if (status != ZX_OK) {
    return status;
  }

  sps_pps_data_->CacheFlushInvalidate(0, sps_pps_size_);
  return ZX_OK;
}

fidl::InterfaceHandle<fuchsia::sysmem::Allocator> DeviceCtx::ConnectToSysmem() {
  fidl::InterfaceHandle<fuchsia::sysmem::Allocator> client_end;
  fidl::InterfaceRequest<fuchsia::sysmem::Allocator> server_end = client_end.NewRequest();
  zx_status_t connect_status = sysmem_.Connect(server_end.TakeChannel());
  if (connect_status != ZX_OK) {
    // failure
    return fidl::InterfaceHandle<fuchsia::sysmem::Allocator>();
  }
  return client_end;
}

void DeviceCtx::GetCodecFactory(zx::channel request) {
  // post to fidl thread to avoid racing on creation/error
  async::PostTask(loop_.dispatcher(), [this, request = std::move(request)]() mutable {
    fidl::InterfaceRequest<fuchsia::mediacodec::CodecFactory> factory_request(std::move(request));

    std::unique_ptr<LocalCodecFactory> codec_factory = std::make_unique<LocalCodecFactory>(
        loop_.dispatcher(), this, std::move(factory_request),
        /*factory_done_callback=*/
        [this](LocalCodecFactory* codec_factory,
               std::unique_ptr<CodecImpl> created_codec_instance) {
          // own codec impl and bind it
          codec_instance_ = std::move(created_codec_instance);
          codec_instance_->BindAsync(/*error_handler=*/[this] {
            // Drop codec impl and close channel on error
            codec_instance_ = nullptr;
          });
          // drop factory and close factory channel
          codec_factories_.erase(codec_factory);
        },
        codec_admission_control_.get(),
        /* error_handler */
        [this](LocalCodecFactory* codec_factory, zx_status_t error) {
          // Drop and close factory channel on error.
          codec_factories_.erase(codec_factory);
        });

    codec_factories_.emplace(codec_factory.get(), std::move(codec_factory));
  });
}
