// Copyright 2018 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 "use_video_decoder.h"

#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fit/defer.h>
#include <lib/media/codec_impl/fourcc.h>
#include <lib/media/test/codec_client.h>
#include <lib/media/test/frame_sink.h>
#include <lib/media/test/one_shot_event.h>
#include <lib/syslog/cpp/macros.h>
#include <stdint.h>
#include <string.h>
#include <zircon/time.h>

#include <optional>
#include <thread>
#include <vector>

#include <fbl/algorithm.h>
#include <src/media/lib/raw_video_writer/raw_video_writer.h>
#include <tee-client-api/tee-client-types.h>

#include "in_stream_peeker.h"
#include "input_copier.h"
#include "lib/zx/time.h"
#include "util.h"

namespace {

// Most cases secure output can't be read to be verified, but under some testing
// circumstances it can be possible.
constexpr bool kVerifySecureOutput = false;

// Queue SPS and PPS separately from the subsequent picture slice.
constexpr bool kH264SeparateSpsPps = true;

// Force some splitting of frames across packet boundaries.  The remainder of the frame data will go
// in subsequent packets.
constexpr size_t kMaxFrameBytesPerPacket = 4ul * 1024;

constexpr zx::duration kInStreamDeadlineDuration = zx::sec(30);

// This example only has one stream_lifetime_ordinal which is 1.
//
// TODO(dustingreen): actually re-use the Codec instance for at least one more
// stream, even if it's just to decode the same data again.
constexpr uint64_t kStreamLifetimeOrdinal = 1;

// Scenic ImagePipe doesn't allow image_id 0, so start here.
constexpr uint32_t kFirstValidImageId = 1;

constexpr uint8_t kLongStartCodeArray[] = {0x00, 0x00, 0x00, 0x01};
constexpr uint8_t kShortStartCodeArray[] = {0x00, 0x00, 0x01};

// For now, we need to ensure we can process frames up to this large for h264.  This doesn't add in
// the 128 * 1024 that we reserve for SEI/SPS/PPS that can be in the same buffer as a frame.
constexpr uint32_t kInputLargeFrameSizeH264 = 1920 * 1080 * 3 / 2 / 2;
constexpr uint32_t kInputReservedForBigHeadersSizeH264 = 128 * 1024;
constexpr uint32_t kInputMinBufferSizeH264 =
    kInputLargeFrameSizeH264 + kInputReservedForBigHeadersSizeH264;

// We need to ensure we can process frames/superframes up to this large for VP9.  This is the size
// Chromium currently sets for input buffers (for both h264 and vp9).
constexpr uint32_t kInputLargeFrameSizeVp9 = 1920 * 1080 * 3 / 2 / 2 + 128 * 1024;
constexpr uint32_t kInputMinBufferSizeVp9 = kInputLargeFrameSizeVp9;

constexpr uint32_t kInputMinBufferSize = std::max(kInputMinBufferSizeH264, kInputMinBufferSizeVp9);

// If readable_bytes is 0, that's considered a "start code", to allow the caller
// to terminate a NAL the same way regardless of whether another start code is
// found or the end of the buffer is found.
//
// ptr has readable_bytes of data - the function only evaluates whether there is
// a start code at the beginning of the data at ptr.
//
// readable_bytes - the caller indicates how many bytes are readable starting at
// ptr.
//
// *start_code_size_bytes will have length of the start code in bytes when the
// function returns true - unchanged otherwise.  Normally this would be 3 or 4,
// but a 0 is possible if readable_bytes is 0.
bool is_start_code(uint8_t* ptr, size_t readable_bytes, size_t* start_code_size_bytes_out) {
  if (readable_bytes == 0) {
    *start_code_size_bytes_out = 0;
    return true;
  }
  if (readable_bytes >= 4) {
    if (!memcmp(ptr, kLongStartCodeArray, sizeof(kLongStartCodeArray))) {
      *start_code_size_bytes_out = 4;
      return true;
    }
  }
  if (readable_bytes >= 3) {
    if (!memcmp(ptr, kShortStartCodeArray, sizeof(kShortStartCodeArray))) {
      *start_code_size_bytes_out = 3;
      return true;
    }
  }
  return false;
}

// Test-only.  Not for production use.  Caller must ensure there are at least 5
// bytes at nal_unit.
uint8_t GetNalUnitType(const uint8_t* nal_unit) {
  // Also works with 4-byte startcodes.
  static const uint8_t start_code[3] = {0, 0, 1};
  uint8_t* next_start = static_cast<uint8_t*>(memmem(nal_unit, 5, start_code, sizeof(start_code))) +
                        sizeof(start_code);
  return *next_start & 0xf;
}

struct __attribute__((__packed__)) IvfHeader {
  uint32_t signature;
  uint16_t version;
  uint16_t header_length;
  uint32_t fourcc;
  uint16_t width;
  uint16_t height;
  uint32_t frame_rate;
  uint32_t time_scale;
  uint32_t frame_count;
  uint32_t unused;
};

struct __attribute__((__packed__)) IvfFrameHeader {
  uint32_t size_bytes;
  uint64_t presentation_timestamp;
};

enum class Format {
  kH264,
  // This uses the multi-instance h.264 decoder.
  kH264Multi,
  kVp9,
};

const uint8_t kSliceNalUnitTypes[] = {1, 2, 3, 4, 5, 19, 20, 21};
bool IsSliceNalUnitType(uint8_t nal_unit_type) {
  for (uint8_t type : kSliceNalUnitTypes) {
    if (type == nal_unit_type) {
      return true;
    }
  }
  return false;
}

class VideoDecoderRunner {
 public:
  VideoDecoderRunner(Format format, UseVideoDecoderParams params);
  void Run();

 private:
  uint64_t QueueH264Frames(uint64_t stream_lifetime_ordinal, uint64_t input_pts_counter_start);
  uint64_t QueueVp9Frames(uint64_t stream_lifetime_ordinal, uint64_t input_pts_counter_start);

  Format format_;
  UseVideoDecoderParams params_;
  std::optional<CodecClient> codec_client_;

  // For testing purposes, we share some info from output to input.  Normally this sort of sharing
  // woudln't tend to happen.
  //
  // Unlike the usual situation with video decoders, in this test, input PTS values are sequential,
  // while output PTS values are impacted by frame reordering.
  //
  // For h264, the degree of reordering is supposed to be bounded by max_num_reorder_frames.  This
  // means that a given frame can be delayed by up to max_num_reorder_frames, requiring that many
  // additional frames on input before the delayed frame's PTS is seen on output.
  //
  // This value is only ever written by the output thread.  It is read by both the output thread
  // and the input thread.
  std::atomic<int64_t> max_output_pts_seen_{-1};
};

VideoDecoderRunner::VideoDecoderRunner(Format format, UseVideoDecoderParams params)
    : format_(std::move(format)), params_(std::move(params)) {}

// Payload data for bear.h264 is 00 00 00 01 start code before each NAL, with
// SPS / PPS NALs and also frame NALs.  We deliver to Codec NAL-by-NAL without
// the start code.
//
// Since the .h264 file has SPS + PPS NALs in addition to frame NALs, we don't
// use oob_bytes for this stream.
//
// TODO(dustingreen): Determine for .mp4 or similar which don't have SPS / PPS
// in band whether .mp4 provides ongoing OOB data, or just at the start, and
// document in codec.fidl how that's to be handled.
//
// Returns how many input packets queued with a PTS.
uint64_t VideoDecoderRunner::QueueH264Frames(uint64_t stream_lifetime_ordinal,
                                             uint64_t input_pts_counter_start) {
  // Raw .h264 has start code 00 00 01 or 00 00 00 01 before each NAL, and
  // the start codes don't alias in the middle of NALs, so we just scan
  // for NALs and send them in to the decoder.
  uint64_t input_pts_counter = input_pts_counter_start;
  uint64_t frame_count = 0;
  std::vector<uint8_t> accumulator;
  auto queue_access_unit = [this, stream_lifetime_ordinal, &input_pts_counter, &frame_count,
                            &accumulator](uint8_t* bytes, size_t byte_count) -> bool {
    auto tvp = params_.input_copier;

    size_t start_code_size_bytes = 0;
    ZX_ASSERT(is_start_code(bytes, byte_count, &start_code_size_bytes));
    ZX_ASSERT(start_code_size_bytes < byte_count);
    uint8_t nal_unit_type = bytes[start_code_size_bytes] & 0x1f;

    size_t insert_offset = accumulator.size();
    size_t new_size = insert_offset + byte_count;
    if (accumulator.capacity() < new_size) {
      size_t new_capacity = std::max(accumulator.capacity() * 2, new_size);
      accumulator.reserve(new_capacity);
    }
    accumulator.resize(insert_offset + byte_count);
    // Zero pad first few frames a lot to verify large frames can decode.
    if (IsSliceNalUnitType(nal_unit_type) && frame_count < 5) {
      ZX_DEBUG_ASSERT(byte_count < kInputLargeFrameSizeH264);
      uint32_t zero_padding_bytes = kInputLargeFrameSizeH264 - byte_count;
      accumulator.resize(accumulator.size() + zero_padding_bytes);
      insert_offset += zero_padding_bytes;
    }
    memcpy(accumulator.data() + insert_offset, bytes, byte_count);

    if (!kH264SeparateSpsPps && !IsSliceNalUnitType(nal_unit_type)) {
      return true;
    }

    auto orig_bytes = bytes;
    bytes = accumulator.data();
    byte_count = accumulator.size();
    auto clear_accumulator = fit::defer([&accumulator] { accumulator.clear(); });

    size_t bytes_so_far = 0;
    // printf("queuing offset: %ld byte_count: %zu\n", bytes -
    // input_bytes.get(), byte_count);
    while (bytes_so_far != byte_count) {
      VLOGF("BlockingGetFreeInputPacket()...");
      std::unique_ptr<fuchsia::media::Packet> packet = codec_client_->BlockingGetFreeInputPacket();
      if (!packet) {
        return false;
      }
      VLOGF("BlockingGetFreeInputPacket() done");

      if (!packet->has_header()) {
        Exit("broken server sent packet without header");
      }

      if (!packet->header().has_packet_index()) {
        Exit("broken server sent packet without packet index");
      }

      // For input we do buffer_index == packet_index.
      const CodecBuffer& buffer = codec_client_->BlockingGetFreeInputBufferForPacket(packet.get());
      ZX_ASSERT(packet->buffer_index() == buffer.buffer_index());
      uint32_t padding_length = tvp ? tvp->PaddingLength() : 0;
      size_t bytes_to_copy =
          std::min(byte_count - bytes_so_far, buffer.size_bytes() - padding_length);

      // Force some frames to split across packet boundary.
      //
      // TODO(fxbug.dev/13483): Also cover more than one frame in a packet, and split headers.
      //
      // TODO(fxbug.dev/13483): Enable testing frames split across packets once SW decode can do
      // that, or have this be gated on whether capability was requested of decoder and try
      // requesting this capability then fall back to not this capability.
      (void)kMaxFrameBytesPerPacket;
      // bytes_to_copy = std::min(bytes_to_copy, kMaxFrameBytesPerPacket);

      packet->set_stream_lifetime_ordinal(stream_lifetime_ordinal);
      packet->set_start_offset(0);
      packet->set_valid_length_bytes(bytes_to_copy);

      if (bytes_so_far == 0) {
        uint8_t nal_unit_type = GetNalUnitType(orig_bytes);
        if (IsSliceNalUnitType(nal_unit_type)) {
          constexpr zx::duration kComplainInterval = zx::sec(5);
          zx::time complain_time = zx::clock::get_monotonic() + kComplainInterval;
          // Wait until max_output_pts_seen_ increases to within the threshold, or time out while
          // complaining every 5 seconds.
          while (static_cast<int64_t>(input_pts_counter) >
                 max_output_pts_seen_ + 1 + params_.test_params->max_num_reorder_frames_threshold) {
            zx::time now = zx::clock::get_monotonic();
            if (now >= complain_time) {
              fprintf(stderr,
                      "max_num_reorder_frames_threshold not satisfied? - keep waiting - may time "
                      "out...\n");
              complain_time = now + kComplainInterval;
            }
            zx::nanosleep(zx::deadline_after(zx::msec(1)));
          }
          packet->set_timestamp_ish(input_pts_counter++);
        }
      }

      packet->set_start_access_unit(bytes_so_far == 0);
      packet->set_known_end_access_unit(bytes_so_far + bytes_to_copy == byte_count);
      if (tvp) {
        TEEC_Result result = tvp->DecryptVideo(bytes + bytes_so_far, bytes_to_copy, buffer.vmo());
        ZX_ASSERT(result == TEEC_SUCCESS);
      } else {
        memcpy(buffer.base(), bytes + bytes_so_far, bytes_to_copy);
      }
      codec_client_->QueueInputPacket(std::move(packet));
      bytes_so_far += bytes_to_copy;
    }
    if (IsSliceNalUnitType(nal_unit_type)) {
      frame_count++;
    }
    if (frame_count == params_.test_params->frame_count) {
      return false;
    }
    return true;
  };

  auto in_stream = params_.in_stream;
  // Let caller-provided in_stream drive how far ahead we peek.  If it's not far
  // enough to find a start code or the EOS, then we'll error out.
  uint32_t max_peek_bytes = in_stream->max_peek_bytes();
  // default -1
  int64_t input_stop_stream_after_frame_ordinal =
      params_.test_params->input_stop_stream_after_frame_ordinal;
  int64_t stream_frame_ordinal = 0;
  while (true) {
    // Until clang-tidy correctly interprets Exit(), this "= 0" satisfies it.
    size_t start_code_size_bytes = 0;
    uint32_t actual_peek_bytes;
    uint8_t* peek;
    VLOGF("PeekBytes()...");
    zx_status_t status = in_stream->PeekBytes(max_peek_bytes, &actual_peek_bytes, &peek,
                                              zx::deadline_after(kInStreamDeadlineDuration));
    ZX_ASSERT(status == ZX_OK);
    VLOGF("PeekBytes() done");
    if (actual_peek_bytes == 0) {
      // Out of input.  Not an error.  No more input AUs.
      ZX_DEBUG_ASSERT(in_stream->eos_position_known() &&
                      in_stream->cursor_position() == in_stream->eos_position());
      break;
    }
    if (!is_start_code(&peek[0], actual_peek_bytes, &start_code_size_bytes)) {
      for (uint32_t i = 0; i < 64; ++i) {
        LOGF("peek[%u] == 0x%x", i, peek[i]);
      }
      char buf[65] = {};
      memcpy(&buf[0], &peek[0], 64);
      buf[64] = 0;
      LOGF("peek[0..64]: %s", buf);
      if (in_stream->cursor_position() == 0) {
        Exit(
            "Didn't find a start code at the start of the file, and this "
            "example doesn't scan forward (for now).");
      } else {
        Exit(
            "Fell out of sync somehow - previous NAL offset + previous "
            "NAL length not a start code.");
      }
    }
    if (in_stream->eos_position_known() &&
        in_stream->cursor_position() + start_code_size_bytes == in_stream->eos_position()) {
      Exit("Start code at end of file unexpected");
    }
    size_t nal_start_offset = start_code_size_bytes;
    // Scan for end of NAL.  The end of NAL can be because we're out of peeked
    // data, or because we hit another start code.
    size_t find_end_iter = nal_start_offset;
    size_t ignore_start_code_size_bytes;
    while (find_end_iter <= actual_peek_bytes &&
           !is_start_code(&peek[find_end_iter], actual_peek_bytes - find_end_iter,
                          &ignore_start_code_size_bytes)) {
      find_end_iter++;
    }
    ZX_DEBUG_ASSERT(find_end_iter <= actual_peek_bytes);
    if (find_end_iter == nal_start_offset) {
      Exit("Two adjacent start codes unexpected.");
    }
    ZX_DEBUG_ASSERT(find_end_iter > nal_start_offset);
    size_t nal_length = find_end_iter - nal_start_offset;
    if (!queue_access_unit(&peek[0], start_code_size_bytes + nal_length)) {
      // only reached on error
      break;
    }

    // start code + NAL payload
    VLOGF("TossPeekedBytes()...");
    in_stream->TossPeekedBytes(start_code_size_bytes + nal_length);
    VLOGF("TossPeekedBytes() done");

    if (stream_frame_ordinal == input_stop_stream_after_frame_ordinal) {
      break;
    }
    stream_frame_ordinal++;
  }

  return input_pts_counter - input_pts_counter_start;
}

uint64_t VideoDecoderRunner::QueueVp9Frames(uint64_t stream_lifetime_ordinal,
                                            uint64_t input_pts_counter_start) {
  // default -1
  int64_t input_pts_counter = input_pts_counter_start;
  uint32_t frame_ordinal = 0;
  auto queue_access_unit = [this, stream_lifetime_ordinal, &input_pts_counter,
                            &frame_ordinal](size_t byte_count) {
    auto in_stream = params_.in_stream;
    auto tvp = params_.input_copier;
    const int64_t skip_frame_ordinal = params_.test_params->skip_frame_ordinal;

    std::unique_ptr<fuchsia::media::Packet> packet = codec_client_->BlockingGetFreeInputPacket();
    if (!packet) {
      fprintf(stderr, "Returning because failed to get input packet\n");
      return false;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // No more return false from here down.  Before we return true, we must have consumed the input
    // data, and incremented the input_frame_ordinal, and returned the input packet to the
    // codec_client.  The codec_client only wants the input packet back after its been filled out
    // completely.
    ////////////////////////////////////////////////////////////////////////////////////////////////
    auto do_not_return_early_interval = fit::defer([] {
      ZX_PANIC("don't return early until packet is set up and returned to codec_client\n");
    });
    auto increment_input_pts_counter = fit::defer([&input_pts_counter] { input_pts_counter++; });

    ZX_ASSERT(packet->has_header());
    ZX_ASSERT(packet->header().has_packet_index());
    const CodecBuffer& buffer = codec_client_->BlockingGetFreeInputBufferForPacket(packet.get());
    ZX_ASSERT(packet->buffer_index() == buffer.buffer_index());
    // VP9 decoder doesn't yet support splitting access units into multiple
    // packets.
    if (byte_count > buffer.size_bytes()) {
      fprintf(stderr,
              "buffer_count >= buffer.size_bytes() - byte_count: %lu buffer.size_bytes(): %lu\n",
              byte_count, buffer.size_bytes());
    }
    ZX_ASSERT(byte_count <= buffer.size_bytes());

    // Check that we don't waste contiguous space on non-secure VP9 input buffers.
    ZX_ASSERT(!buffer.is_physically_contiguous() || tvp);
    packet->set_stream_lifetime_ordinal(stream_lifetime_ordinal);
    packet->set_start_offset(0);
    packet->set_valid_length_bytes(byte_count);

    // We don't use frame_header->presentation_timestamp, because we want to
    // send through frame index in timestamp_ish field instead, for consistency
    // with .h264 files which don't have timestamps in them, and so tests can
    // assume frame index as timestamp_ish on output.
    packet->set_timestamp_ish(input_pts_counter);

    packet->set_start_access_unit(true);
    packet->set_known_end_access_unit(true);

    uint32_t actual_bytes_read;
    std::unique_ptr<uint8_t[]> bytes;
    uint8_t* read_address = nullptr;

    if (tvp) {
      bytes = std::make_unique<uint8_t[]>(byte_count);
      read_address = bytes.get();
    } else {
      read_address = buffer.base();
    }

    zx_status_t status =
        in_stream->ReadBytesComplete(byte_count, &actual_bytes_read, read_address,
                                     zx::deadline_after(kInStreamDeadlineDuration));
    ZX_ASSERT(status == ZX_OK);
    if (actual_bytes_read < byte_count) {
      Exit("Frame truncated.");
    }
    ZX_DEBUG_ASSERT(actual_bytes_read == byte_count);

    /////////////////////////////////////////////////////////////////////////////////
    // Switch from not being able to return early to being able to return true early.
    /////////////////////////////////////////////////////////////////////////////////
    do_not_return_early_interval.cancel();
    auto do_not_queue_input_packet_after_all = fit::defer(
        [this, &packet] { codec_client_->DoNotQueueInputPacketAfterAll(std::move(packet)); });

    if (input_pts_counter == skip_frame_ordinal) {
      LOGF("skipping input frame: %" PRId64, input_pts_counter);
      // ~do_not_queue_input_packet_after_all, ~increment_input_pts_counter
      return true;
    }

    if (tvp) {
      VLOGF("before DecryptVideo...");
      TEEC_Result result = tvp->DecryptVideo(bytes.get(), byte_count, buffer.vmo());
      VLOGF("after DecryptVideo");
      ZX_ASSERT(result == TEEC_SUCCESS);
    }

    do_not_queue_input_packet_after_all.cancel();

    // Ideally we'd figure out why this padding doesn't work / how to pad VP9 frames, if possible.
#if 0
    if (frame_ordinal <= 5) {
      // Assert not a superframe.  If we have some of these in input, we can skip padding them
      // instead, or find a way to pad a superframe.
      ZX_DEBUG_ASSERT((*(buffer.base() + packet->valid_length_bytes() - 1) & 0xE0) != 0xC0);
      ZX_DEBUG_ASSERT(buffer.size_bytes() >= kInputLargeFrameSizeVp9);
      if (byte_count < kInputLargeFrameSizeVp9) {
        uint32_t zero_bytes_count = kInputLargeFrameSizeVp9 - byte_count;
        memset(buffer.base() + byte_count, 0, zero_bytes_count);
        packet->set_valid_length_bytes(packet->valid_length_bytes() + zero_bytes_count);
      }
    }
#endif

    codec_client_->QueueInputPacket(std::move(packet));

    ++frame_ordinal;

    // ~increment_input_pts_counter
    return true;
  };
  auto in_stream = params_.in_stream;
  IvfHeader header;
  uint32_t actual_bytes_read;
  zx_status_t status = in_stream->ReadBytesComplete(sizeof(header), &actual_bytes_read,
                                                    reinterpret_cast<uint8_t*>(&header),
                                                    zx::deadline_after(kInStreamDeadlineDuration));
  // This could fail if a remote-source stream breaks.
  ZX_ASSERT(status == ZX_OK);
  // This could fail if the input is too short.
  ZX_ASSERT(actual_bytes_read == sizeof(header));
  size_t remaining_header_length = header.header_length - sizeof(header);
  // We're not interested in any remaining portion of the header, but we should
  // skip the rest of the header, if any.
  if (remaining_header_length) {
    uint8_t toss_buffer[1024];
    while (remaining_header_length != 0) {
      uint32_t bytes_to_read = std::min(sizeof(toss_buffer), remaining_header_length);
      uint32_t actual_bytes_read;
      status = in_stream->ReadBytesComplete(bytes_to_read, &actual_bytes_read, &toss_buffer[0],
                                            zx::deadline_after(kInStreamDeadlineDuration));
      ZX_ASSERT(status == ZX_OK);
      ZX_ASSERT(actual_bytes_read == bytes_to_read);
      remaining_header_length -= actual_bytes_read;
    }
  }
  ZX_DEBUG_ASSERT(!remaining_header_length);
  // default -1
  int64_t input_stop_stream_after_frame_ordinal =
      params_.test_params->input_stop_stream_after_frame_ordinal;
  int64_t stream_frame_ordinal = 0;
  while (true) {
    IvfFrameHeader frame_header;
    status = in_stream->ReadBytesComplete(sizeof(frame_header), &actual_bytes_read,
                                          reinterpret_cast<uint8_t*>(&frame_header),
                                          zx::deadline_after(kInStreamDeadlineDuration));
    ZX_ASSERT(status == ZX_OK);
    if (actual_bytes_read == 0) {
      // No more frames.  That's fine.
      break;
    }
    if (actual_bytes_read < sizeof(frame_header)) {
      Exit("Frame header truncated.");
    }
    ZX_DEBUG_ASSERT(actual_bytes_read == sizeof(frame_header));
    if (params_.test_params->per_frame_debug_output) {
      LOGF("input stream: %" PRIu64 " stream_frame_ordinal: %" PRId64 " input_pts_counter: %" PRIu64
           " frame_header.size_bytes: %u",
           stream_lifetime_ordinal, stream_frame_ordinal, input_pts_counter,
           frame_header.size_bytes);
    }
    if (!queue_access_unit(frame_header.size_bytes)) {
      // can be fine in case of vp9 input fuzzing test
      break;
    }

    if (stream_frame_ordinal == input_stop_stream_after_frame_ordinal) {
      break;
    }
    stream_frame_ordinal++;
  }

  return input_pts_counter - input_pts_counter_start;
}

void VideoDecoderRunner::Run() {
  const UseVideoDecoderTestParams default_test_params;
  if (!params_.test_params) {
    params_.test_params = &default_test_params;
  }
  params_.test_params->Validate();

  VLOGF("before CodecClient::CodecClient()...");
  codec_client_.emplace(params_.fidl_loop, params_.fidl_thread, std::move(params_.sysmem));
  codec_client_->SetMinInputBufferSize(kInputMinBufferSize);
  // no effect if 0
  codec_client_->SetMinOutputBufferSize(params_.min_output_buffer_size);
  // no effect if 0
  codec_client_->SetMinOutputBufferCount(params_.min_output_buffer_count);
  codec_client_->set_is_output_secure(params_.is_secure_output);
  codec_client_->set_is_input_secure(params_.is_secure_input);
  codec_client_->set_in_lax_mode(params_.lax_mode);

  std::string mime_type;
  switch (format_) {
    case Format::kH264:
      mime_type = "video/h264";
      break;

    case Format::kH264Multi:
      mime_type = "video/h264-multi";
      break;

    case Format::kVp9:
      mime_type = "video/vp9";
      break;
  }
  if (params_.test_params->mime_type) {
    mime_type = params_.test_params->mime_type.value();
  }

  async::PostTask(
      params_.fidl_loop->dispatcher(),
      [this, codec_client_request = codec_client_->GetTheRequestOnce(), mime_type]() mutable {
        VLOGF("before codec_factory->CreateDecoder() (async)");
        fuchsia::media::FormatDetails input_details;
        input_details.set_format_details_version_ordinal(0);
        input_details.set_mime_type(mime_type.c_str());
        fuchsia::mediacodec::CreateDecoder_Params decoder_params;
        decoder_params.set_input_details(std::move(input_details));
        // This is required for timestamp_ish values to transit the
        // Codec.
        //
        // TODO(fxbug.dev/57706): We shouldn't need to promise this to have PTS(s) flow through.
        decoder_params.set_promise_separate_access_units_on_input(true);
        if (params_.is_secure_output) {
          decoder_params.set_secure_output_mode(fuchsia::mediacodec::SecureMemoryMode::ON);
        }
        if (params_.is_secure_input) {
          decoder_params.set_secure_input_mode(fuchsia::mediacodec::SecureMemoryMode::ON);
        }
        // Bind the fuchsia::media::CodecFactoryHandle to a CodecFactoryPtr so we can send a
        // CreateDecoder message. This unbinds params_.codec_factory.
        auto codec_factory_ptr = params_.codec_factory.Bind();
        codec_factory_ptr->CreateDecoder(std::move(decoder_params),
                                         std::move(codec_client_request));
        // Now that the CreateDecoder message is sent, we no longer need to keep a channel open
        // to the CodecFactory so we can just let codec_factory_ptr fall out of scope.
      });

  VLOGF("before codec_client.Start()...");
  codec_client_->Start();

  VLOGF("before starting in_thread...");
  auto in_thread = std::make_unique<std::thread>([this]() {
    auto& in_stream = params_.in_stream;
    auto& test_params = params_.test_params;
    VLOGF("in_thread start");
    // default 1
    const uint32_t loop_stream_count = test_params->loop_stream_count;
    // default 2
    const uint64_t keep_stream_modulo = test_params->keep_stream_modulo;
    uint64_t stream_lifetime_ordinal = kStreamLifetimeOrdinal;
    uint64_t input_frame_pts_counter = 0;
    uint32_t frames_queued = 0;
    for (uint32_t loop_ordinal = 0; loop_ordinal < loop_stream_count;
         ++loop_ordinal, stream_lifetime_ordinal += 2) {
      switch (format_) {
        case Format::kH264:
        case Format::kH264Multi:
          frames_queued = QueueH264Frames(stream_lifetime_ordinal, input_frame_pts_counter);
          break;

        case Format::kVp9:
          frames_queued = QueueVp9Frames(stream_lifetime_ordinal, input_frame_pts_counter);
          break;
      }

      // Send through QueueInputEndOfStream().
      VLOGF("QueueInputEndOfStream() - stream_lifetime_ordinal: %" PRIu64, stream_lifetime_ordinal);
      // For debugging a flake:
      if (test_params->loop_stream_count > 1) {
        LOGF("QueueInputEndOfStream() - stream_lifetime_ordinal: %" PRIu64,
             stream_lifetime_ordinal);
      }
      codec_client_->QueueInputEndOfStream(stream_lifetime_ordinal);

      if (stream_lifetime_ordinal % keep_stream_modulo == 1) {
        // We flush and close to run the handling code server-side.  However, we don't
        // yet verify that this successfully achieves what it says.
        VLOGF("FlushEndOfStreamAndCloseStream() - stream_lifetime_ordinal: %" PRIu64,
              stream_lifetime_ordinal);
        // For debugging a flake:
        if (test_params->loop_stream_count > 1) {
          LOGF("FlushEndOfStreamAndCloseStream() - stream_lifetime_ordinal: %" PRIu64,
               stream_lifetime_ordinal);
        }
        codec_client_->FlushEndOfStreamAndCloseStream(stream_lifetime_ordinal);

        // Stitch together the PTS values of the streams which we're keeping.
        input_frame_pts_counter += frames_queued;
      }

      if (loop_ordinal + 1 != loop_stream_count) {
        zx_status_t status = in_stream->ResetToStart(zx::deadline_after(kInStreamDeadlineDuration));
        ZX_ASSERT(status == ZX_OK);
      }
    }
    VLOGF("in_thread done");
  });

  // Separate thread to process the output.
  //
  // codec_client outlives the thread (and for separate reasons below, all the
  // frame_sink activity started by out_thread).
  auto out_thread = std::make_unique<std::thread>([this]() {
    VLOGF("out_thread start");
    // We allow the server to send multiple output constraint updates if it
    // wants; see implementation of BlockingGetEmittedOutput() which will hide
    // multiple constraint updates before the first packet from this code.  In
    // contrast we assert if the server sends multiple format updates with no
    // packets in between since that's not compliant with the protocol rules.
    std::shared_ptr<const fuchsia::media::StreamOutputFormat> prev_stream_format;
    const fuchsia::media::VideoUncompressedFormat* raw = nullptr;
    std::optional<zx::time> frame_zero_time;
    uint64_t frame_index = 0;
    uint32_t image_id = kFirstValidImageId;
    std::atomic<uint32_t> async_put_frame_count = 0;
    while (true) {
      if (params_.frame_sink) {
        // Control concurrency of pending Present()s to scenic - this could be an issue for very
        // large buffer collections, or in cases where we switch buffer collections a lot - in such
        // cases Scenic can start complaining about too many queued Present()s.  This avoids the
        // frame_sink needing to block/delay the output thread anywhere other than here.
        //
        // It'd be better if this were event driven, but this works for now.
        while (async_put_frame_count + params_.frame_sink->GetPendingCount() >= 10) {
          zx::nanosleep(zx::deadline_after(zx::msec(10)));
        }
      }
      VLOGF("BlockingGetEmittedOutput()...");
      std::unique_ptr<CodecOutput> output = codec_client_->BlockingGetEmittedOutput();
      VLOGF("BlockingGetEmittedOutput() done");
      if (!output) {
        return;
      }
      if (output->stream_lifetime_ordinal() % 2 == 0) {
        Exit(
            "server emitted a stream_lifetime_ordinal that client didn't set "
            "on any input");
      }
      if (output->end_of_stream()) {
        VLOGF("output end_of_stream() - stream_lifetime_ordinal: %" PRIu64,
              output->stream_lifetime_ordinal());
        // For debugging a flake:
        if (params_.test_params->loop_stream_count > 1) {
          LOGF("output end_of_stream() - stream_lifetime_ordinal: %" PRIu64,
               output->stream_lifetime_ordinal());
        }
        // default 1
        const int64_t loop_stream_count = params_.test_params->loop_stream_count;
        const uint64_t max_stream_lifetime_ordinal = (loop_stream_count - 1) * 2 + 1;
        if (output->stream_lifetime_ordinal() != max_stream_lifetime_ordinal) {
          continue;
        }
        VLOGF("done with output - stream_lifetime_ordinal: %" PRIu64,
              output->stream_lifetime_ordinal());
        // For debugging a flake:
        if (params_.test_params->loop_stream_count > 1) {
          LOGF("done with output - stream_lifetime_ordinal: %" PRIu64,
               output->stream_lifetime_ordinal());
        }
        // Just "break;" would be more fragile under code modification.
        goto end_of_output;
      }

      const fuchsia::media::Packet& packet = output->packet();

      if (!packet.has_header()) {
        // The server should not generate any empty packets.
        Exit("broken server sent packet without header");
      }

      // cleanup can run on any thread, and codec_client.RecycleOutputPacket()
      // is ok with that.  In addition, cleanup can run after codec_client is
      // gone, since we don't block return from use_video_decoder() on Scenic
      // actually freeing up all previously-queued frames.
      auto cleanup =
          fit::defer([this, packet_header = fidl::Clone(packet.header()), &frame_index]() mutable {
            // Using an auto call for this helps avoid losing track of the
            // output_buffer.
            codec_client_->RecycleOutputPacket(std::move(packet_header));
            ++frame_index;
          });
      std::shared_ptr<const fuchsia::media::StreamOutputFormat> format = output->format();

      if (!packet.has_buffer_index()) {
        // The server should not generate any empty packets.
        Exit("broken server sent packet without buffer index");
      }

      // This will remain live long enough because this thread is the only
      // thread that re-allocates output buffers.
      const CodecBuffer& buffer = codec_client_->GetOutputBufferByIndex(packet.buffer_index());

      ZX_ASSERT(!prev_stream_format ||
                (prev_stream_format->has_format_details() &&
                 prev_stream_format->format_details().format_details_version_ordinal()));
      if (!format->has_format_details()) {
        Exit("!format->has_format_details()");
      }
      if (!format->format_details().has_format_details_version_ordinal()) {
        Exit("!format->format_details().has_format_details_version_ordinal()");
      }

      if (!packet.has_valid_length_bytes() || packet.valid_length_bytes() == 0) {
        // The server should not generate any empty packets.
        Exit("broken server sent empty packet");
      }

      if (!packet.has_start_offset()) {
        // The server should not generate any empty packets.
        Exit("broken server sent packet without start offset");
      }

      // We have a non-empty packet of the stream.

      if (packet.has_timestamp_ish()) {
        uint64_t timestamp_ish = packet.timestamp_ish();
        ZX_ASSERT(timestamp_ish < std::numeric_limits<int64_t>::max());
        if (static_cast<int64_t>(timestamp_ish) > max_output_pts_seen_) {
          max_output_pts_seen_ = timestamp_ish;
        }
      }

      if (!prev_stream_format || prev_stream_format.get() != format.get()) {
        VLOGF("handling output format");
        // Every output has a format.  This happens exactly once.
        prev_stream_format = format;

        ZX_ASSERT(format->format_details().has_domain());

        if (!format->has_format_details()) {
          Exit("!format_details");
        }

        const fuchsia::media::FormatDetails& format_details = format->format_details();
        if (!format_details.has_domain()) {
          Exit("!format.domain");
        }

        if (!format_details.domain().is_video()) {
          Exit("!format.domain.is_video()");
        }
        const fuchsia::media::VideoFormat& video_format = format_details.domain().video();
        if (!video_format.is_uncompressed()) {
          Exit("!video.is_uncompressed()");
        }

        raw = &video_format.uncompressed();
        switch (raw->fourcc) {
          case make_fourcc('N', 'V', '1', '2'): {
            size_t y_size = raw->primary_height_pixels * raw->primary_line_stride_bytes;
            if (raw->secondary_start_offset < y_size) {
              Exit("raw.secondary_start_offset < y_size");
            }
            // NV12 requires UV be same line stride as Y.
            size_t total_size = raw->secondary_start_offset +
                                raw->primary_height_pixels / 2 * raw->primary_line_stride_bytes;
            if (packet.valid_length_bytes() < total_size) {
              Exit(
                  "packet.valid_length_bytes < total_size (1) - valid_length_bytes: %u total_size: "
                  "%lu",
                  packet.valid_length_bytes(), total_size);
            }
            break;
          }
          case make_fourcc('Y', 'V', '1', '2'): {
            size_t y_size = raw->primary_height_pixels * raw->primary_line_stride_bytes;
            size_t v_size = raw->secondary_height_pixels * raw->secondary_line_stride_bytes;
            size_t u_size = v_size;
            size_t total_size = y_size + u_size + v_size;

            if (packet.valid_length_bytes() < total_size) {
              Exit("packet.valid_length_bytes < total_size (2)");
            }

            if (raw->secondary_start_offset < y_size) {
              Exit("raw.secondary_start_offset < y_size");
            }

            if (raw->tertiary_start_offset < y_size + v_size) {
              Exit("raw.tertiary_start_offset < y_size + v_size");
            }
            break;
          }
          default:
            Exit("fourcc != NV12 && fourcc != YV12");
        }
      }

      if (frame_index == 0) {
        ZX_ASSERT(!frame_zero_time);
        frame_zero_time.emplace(zx::clock::get_monotonic());
      }
      if (params_.test_params->print_fps) {
        zx::time now = zx::clock::get_monotonic();
        zx::duration duration = now - frame_zero_time.value();
        if (frame_index != 0 && frame_index % params_.test_params->print_fps_modulus == 0) {
          printf("frame_index: %" PRIu64 " fps: %g\n", frame_index,
                 static_cast<double>(frame_index) * 1000000.0 /
                     static_cast<double>(duration.to_usecs()));
          fflush(nullptr);
        }
      }

      if (params_.emit_frame) {
        // i420_bytes is in I420 format - Y plane first, then U plane, then V
        // plane.  The U and V planes are half size in both directions.  Each
        // plane is 8 bits per sample.
        uint32_t i420_stride = fbl::round_up(raw->primary_display_width_pixels, 2u);
        // When width is odd, we want a chroma sample for the right-most luma.
        uint32_t uv_width = (raw->primary_display_width_pixels + 1) / 2;
        // When height is odd, we want a chroma sample for the bottom-most luma.
        uint32_t uv_height = (raw->primary_display_height_pixels + 1) / 2;
        uint32_t uv_stride = i420_stride / 2;
        std::unique_ptr<uint8_t[]> i420_bytes;
        if (kVerifySecureOutput || !params_.is_secure_output) {
          i420_bytes = std::make_unique<uint8_t[]>(
              i420_stride * raw->primary_display_height_pixels + uv_stride * uv_height * 2);
          switch (raw->fourcc) {
            case make_fourcc('N', 'V', '1', '2'): {
              // Y
              uint8_t* y_src = buffer.base() + packet.start_offset() + raw->primary_start_offset;
              uint8_t* y_dst = i420_bytes.get();
              for (uint32_t y_iter = 0; y_iter < raw->primary_display_height_pixels; y_iter++) {
                memcpy(y_dst, y_src, raw->primary_display_width_pixels);
                y_src += raw->primary_line_stride_bytes;
                y_dst += i420_stride;
              }
              // UV
              uint8_t* uv_src = buffer.base() + packet.start_offset() + raw->secondary_start_offset;
              uint8_t* u_dst_line = y_dst;
              uint8_t* v_dst_line = u_dst_line + uv_stride * uv_height;
              for (uint32_t uv_iter = 0; uv_iter < uv_height; uv_iter++) {
                uint8_t* u_dst = u_dst_line;
                uint8_t* v_dst = v_dst_line;
                for (uint32_t uv_line_iter = 0; uv_line_iter < uv_width; ++uv_line_iter) {
                  *u_dst++ = uv_src[uv_line_iter * 2];
                  *v_dst++ = uv_src[uv_line_iter * 2 + 1];
                }
                uv_src += raw->primary_line_stride_bytes;
                u_dst_line += uv_stride;
                v_dst_line += uv_stride;
              }
              break;
            }
            case make_fourcc('Y', 'V', '1', '2'): {
              // Y
              uint8_t* y_src = buffer.base() + packet.start_offset() + raw->primary_start_offset;
              uint8_t* y_dst = i420_bytes.get();
              for (uint32_t y_iter = 0; y_iter < raw->primary_display_height_pixels; y_iter++) {
                memcpy(y_dst, y_src, raw->primary_display_width_pixels);
                y_src += raw->primary_line_stride_bytes;
                y_dst += i420_stride;
              }
              // UV
              uint8_t* v_src = buffer.base() + packet.start_offset() + raw->primary_start_offset +
                               raw->primary_line_stride_bytes * raw->primary_height_pixels;
              uint8_t* u_src =
                  v_src + (raw->primary_line_stride_bytes / 2) * (raw->primary_height_pixels / 2);
              uint8_t* u_dst = y_dst;
              uint8_t* v_dst = u_dst + uv_stride * uv_height;
              for (uint32_t uv_iter = 0; uv_iter < uv_height; uv_iter++) {
                memcpy(u_dst, u_src, uv_width);
                memcpy(v_dst, v_src, uv_width);
                u_dst += uv_stride;
                v_dst += uv_stride;
                u_src += raw->primary_line_stride_bytes / 2;
                v_src += raw->primary_line_stride_bytes / 2;
              }
              break;
            }
            default:
              Exit("Feeding EmitFrame not yet implemented for fourcc: %s",
                   fourcc_to_string(raw->fourcc).c_str());
          }
        }
        params_.emit_frame(output->stream_lifetime_ordinal(), i420_bytes.get(),
                           raw->primary_display_width_pixels, raw->primary_display_height_pixels,
                           i420_stride, packet.has_timestamp_ish(),
                           packet.has_timestamp_ish() ? packet.timestamp_ish() : 0);
      }

      if (params_.frame_sink) {
        async_put_frame_count++;
        zx::vmo image_vmo;
        ZX_ASSERT(ZX_OK == buffer.vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &image_vmo));
        async::PostTask(
            params_.fidl_loop->dispatcher(),
            [this, image_id = image_id++, vmo = std::move(image_vmo),
             vmo_offset = buffer.vmo_offset() + packet.start_offset() + raw->primary_start_offset,
             format, cleanup = std::move(cleanup), &async_put_frame_count]() mutable {
              params_.frame_sink->PutFrame(image_id, std::move(vmo), vmo_offset, format,
                                           [cleanup = std::move(cleanup)] {
                                             // The ~cleanup can run on any thread (the
                                             // current thread is main_loop's thread),
                                             // and codec_client is ok with that
                                             // (because it switches over to |loop|'s
                                             // thread before sending a Codec message).
                                             //
                                             // ~cleanup
                                           });
              async_put_frame_count--;
            });
      }
      // If we didn't std::move(cleanup) before here, then ~cleanup runs here.
    }
  end_of_output:;
    VLOGF("out_thread done");
    // output thread done
    // ~raw_video_writer
  });

  // decode for a bit...  in_thread, loop, out_thread, and the codec itself are
  // taking care of it.

  // First wait for the input thread to be done feeding input data.  Before the
  // in_thread terminates, it'll have sent in a last empty EOS input buffer.
  VLOGF("before in_thread->join()...");
  in_thread->join();
  VLOGF("after in_thread->join()");

  // The EOS queued as an input buffer should cause the codec to output an EOS
  // output buffer, at which point out_thread should terminate, after it has
  // finalized the output file.
  VLOGF("before out_thread->join()...");
  out_thread->join();
  VLOGF("after out_thread->join()");

  // We wait for frame_sink to return all the frames for these reasons:
  //   * As of this writing, some noisy-in-the-log things can happen in Scenic
  //     if we don't.
  //   * We don't want to cancel display of any frames, because we want to see
  //     the frames on the screen.
  //   * We don't want the |cleanup| to run after codec_client is gone since the
  //     |cleanup| calls codec_client.
  //   * It's easier to grok if activity started by use_h264_decoder() is done
  //     by the time use_h264_decoder() returns, given use_h264_decoder()'s role
  //     as an overall sequencer.
  if (params_.frame_sink) {
    OneShotEvent frames_done_event;
    fit::closure on_frames_returned = [&frames_done_event] { frames_done_event.Signal(); };
    async::PostTask(params_.fidl_loop->dispatcher(), [frame_sink = params_.frame_sink,
                                                      on_frames_returned =
                                                          std::move(on_frames_returned)]() mutable {
      frame_sink->PutEndOfStreamThenWaitForFramesReturnedAsync(std::move(on_frames_returned));
    });
    // The just-posted wait will set frames_done using the main_loop_'s thread,
    // which is not this thread.
    FX_LOGS(INFO) << "waiting for all frames to be returned from Scenic...";
    frames_done_event.Wait(zx::deadline_after(zx::sec(30)));
    FX_LOGS(INFO) << "all frames have been returned from Scenic";
    // Now we know that there are zero frames in frame_sink, including zero
    // frame cleanup(s) in-flight (in the sense of a pending/running cleanup
    // that's touching codec_client to post any new work.  Work already posted
    // via codec_client can still be in flight.  See below.)
  }

  // Close the channels explicitly (just so we can more easily print messages
  // before and after vs. ~codec_client).
  VLOGF("before codec_client stop...");
  codec_client_->Stop();
  VLOGF("after codec_client stop.");

  codec_client_ = std::nullopt;

  // success
  return;
}

void use_video_decoder(Format format, UseVideoDecoderParams params) {
  VLOGF("use_video_decoder()");

  auto video_decoder_runner =
      std::make_unique<VideoDecoderRunner>(std::move(format), std::move(params));
  video_decoder_runner->Run();
  // ~video_decoder_runner
}

}  // namespace

void use_h264_decoder(UseVideoDecoderParams params) {
  use_video_decoder(Format::kH264, std::move(params));
}

void use_h264_multi_decoder(UseVideoDecoderParams params) {
  use_video_decoder(Format::kH264Multi, std::move(params));
}

void use_vp9_decoder(UseVideoDecoderParams params) {
  use_video_decoder(Format::kVp9, std::move(params));
}
