// 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 <lib/media/codec_impl/codec_adapter.h>
#include <zircon/assert.h>

#include <limits>
#include <memory>

namespace {
constexpr uint64_t kInputBufferConstraintsVersionOrdinal = 1;
constexpr uint64_t kInputDefaultBufferConstraintsVersionOrdinal =
    kInputBufferConstraintsVersionOrdinal;

// No particular reason to demand more than 1 input packet to camp on, since by default we'll likely
// only be decoding from 1 at a time.  If a particular decoder really does camp on more than 1 at a
// time for whatever reason for any significant duration, it should override this default.
constexpr uint32_t kInputPacketCountForCodecMin = 1;
// This is fairly arbitrary, but roughly speaking, 1 to be decoding, 1 to be in
// flight back to the client.  The one in-flight from the client to the codec is the client's
// business, to avoid double-counting (or vice versa if you like - the counting doesn't care which
// is counted as long as we're not double-counting).  Particular CodecAdapter(s) may want to
// override this upward if we find it's needed to keep the HW busy when there's any backlog.
constexpr uint32_t kInputPacketCountForCodecRecommended = 2;
constexpr uint32_t kInputPacketCountForCodecRecommendedMax = 16;
constexpr uint32_t kInputPacketCountForCodecMax = 64;

constexpr uint32_t kInputDefaultPacketCountForCodec = kInputPacketCountForCodecRecommended;

constexpr uint32_t kInputPacketCountForClientMin = 1;
constexpr uint32_t kInputPacketCountForClientMax = std::numeric_limits<uint32_t>::max();

// This is fairly arbitrary, but rough speaking, 1 to be filling, 1 to be in
// flight toward the codec, and 1 to be in flight from the codec.  This doesn't
// intend to be large enough to ride out any hypothetical decoder performance
// variability vs. needed decode rate.
constexpr uint32_t kInputDefaultPacketCountForClient = 3;

// TODO(dustingreen): Implement and permit single-buffer mode.  (The default
// will probably remain buffer per packet mode though.)
constexpr bool kInputSingleBufferModeAllowed = false;
constexpr bool kInputDefaultSingleBufferMode = false;

// A client using the min shouldn't necessarily expect performance to be
// acceptable when running higher bit-rates.
constexpr uint32_t kInputPerPacketBufferBytesMin = 8 * 1024;
// This is fairly arbitrary, but roughly speaking, ~266 KiB for an average frame
// at 50 Mbps for 4k video, rounded up to 512 KiB buffer space per packet to
// allow most but not all frames to fit in one packet.  It could be equally
// reasonable to say the average-size compressed from should barely fit in one
// packet's buffer space, or the average-size compressed frame should split to
// ~1.5 packets, but we don't want an excessive number of packets required per
// frame (not even for I frames).
constexpr uint32_t kInputPerPacketBufferBytesRecommended = 512 * 1024;
// This is an arbitrary cap for now.  The only reason it's larger than
// recommended is to allow some room to profile whether larger buffer space per
// packet might be useful for performance.
constexpr uint32_t kInputPerPacketBufferBytesMax = 4 * 1024 * 1024;

constexpr uint32_t kInputDefaultPerPacketBufferBytes = kInputPerPacketBufferBytesRecommended;

}  // namespace

CodecAdapter::CodecAdapter(std::mutex& lock, CodecAdapterEvents* codec_adapter_events)
    : lock_(lock),
      events_(codec_adapter_events),
      random_device_(),
      not_for_security_prng_(random_device_()) {
  ZX_DEBUG_ASSERT(events_);
  // nothing else to do here
}

CodecAdapter::~CodecAdapter() {
  // nothing to do here
}

void CodecAdapter::CoreCodecSetSecureMemoryMode(
    CodecPort port, fuchsia::mediacodec::SecureMemoryMode secure_memory_mode) {
  if (secure_memory_mode != fuchsia::mediacodec::SecureMemoryMode::OFF) {
    events_->onCoreCodecFailCodec(
        "In CodecAdapter::CoreCodecSetSecureMemoryMode(), secure_memory_mode != OFF");
    return;
  }
  // CodecImpl will enforce that BufferCollection constraints and BufferCollectionInfo_2 are
  // consistent with OFF.
  return;
}

std::unique_ptr<const fuchsia::media::StreamBufferConstraints>
CodecAdapter::CoreCodecBuildNewInputConstraints() {
  auto constraints = std::make_unique<fuchsia::media::StreamBufferConstraints>();
  constraints->set_buffer_constraints_version_ordinal(kInputBufferConstraintsVersionOrdinal)
      .set_packet_count_for_server_recommended_max(kInputPacketCountForCodecRecommendedMax)
      .set_per_packet_buffer_bytes_min(kInputPerPacketBufferBytesMin)
      .set_per_packet_buffer_bytes_recommended(kInputPerPacketBufferBytesRecommended)
      .set_per_packet_buffer_bytes_max(kInputPerPacketBufferBytesMax)
      .set_packet_count_for_server_min(kInputPacketCountForCodecMin)
      .set_packet_count_for_server_recommended(kInputPacketCountForCodecRecommended)
      .set_packet_count_for_server_max(kInputPacketCountForCodecMax)
      .set_packet_count_for_client_min(kInputPacketCountForClientMin)
      .set_packet_count_for_client_max(kInputPacketCountForClientMax)
      .set_single_buffer_mode_allowed(kInputSingleBufferModeAllowed);

  constraints->mutable_default_settings()
      ->set_buffer_lifetime_ordinal(0)
      .set_buffer_constraints_version_ordinal(kInputDefaultBufferConstraintsVersionOrdinal)
      .set_packet_count_for_server(kInputDefaultPacketCountForCodec)
      .set_packet_count_for_client(kInputDefaultPacketCountForClient)
      .set_per_packet_buffer_bytes(kInputDefaultPerPacketBufferBytes)
      .set_single_buffer_mode(kInputDefaultSingleBufferMode);

  return constraints;
}

void CodecAdapter::CoreCodecResetStreamAfterCurrentFrame() {
  ZX_PANIC(
      "onCoreCodecResetStreamAfterCurrentFrame() triggered by a CodecAdapter that doesn't override "
      "CoreCodecResetStreamAfterCurrentFrame()\n");
}
