// Copyright 2020 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/starboard/media/avc_util.h"

#include <type_traits>

#include "starboard/memory.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace media {

namespace {

const uint8_t kAnnexBHeader[] = {0, 0, 0, 1};
const auto kAnnexBHeaderSizeInBytes =
    AvcParameterSets::kAnnexBHeaderSizeInBytes;

bool StartsWithAnnexBHeader(const uint8_t* annex_b_data,
                            size_t annex_b_data_size) {
  static_assert(
      sizeof(kAnnexBHeader) == AvcParameterSets::kAnnexBHeaderSizeInBytes,
      "sizeof(kAnnexBHeader) doesn't match kAnnexBHeaderSizeInBytes");

  if (annex_b_data_size < sizeof(kAnnexBHeader)) {
    return false;
  }
  return SbMemoryCompare(annex_b_data, kAnnexBHeader, sizeof(kAnnexBHeader)) ==
         0;
}

// UInt8Type can be "uint8_t", or "const uint8_t".
template <typename UInt8Type>
bool AdvanceToNextAnnexBHeader(UInt8Type** annex_b_data,
                               size_t* annex_b_data_size) {
  SB_DCHECK(annex_b_data);
  SB_DCHECK(annex_b_data_size);

  if (!StartsWithAnnexBHeader(*annex_b_data, *annex_b_data_size)) {
    return false;
  }

  *annex_b_data += kAnnexBHeaderSizeInBytes;
  *annex_b_data_size -= kAnnexBHeaderSizeInBytes;

  while (*annex_b_data_size > 0) {
    if (StartsWithAnnexBHeader(*annex_b_data, *annex_b_data_size)) {
      return true;
    }
    ++*annex_b_data;
    --*annex_b_data_size;
  }
  return true;
}

bool ExtractAnnexBNalu(const uint8_t** annex_b_data,
                       size_t* annex_b_data_size,
                       std::vector<uint8_t>* annex_b_nalu) {
  SB_DCHECK(annex_b_data);
  SB_DCHECK(annex_b_data_size);
  SB_DCHECK(annex_b_nalu);

  const uint8_t* saved_data = *annex_b_data;

  if (!AdvanceToNextAnnexBHeader(annex_b_data, annex_b_data_size)) {
    return false;
  }

  annex_b_nalu->assign(saved_data, *annex_b_data);
  return true;
}

}  // namespace

AvcParameterSets::AvcParameterSets(Format format,
                                   const uint8_t* data,
                                   size_t size)
    : format_(format) {
  SB_DCHECK(format == kAnnexB);

  is_valid_ =
      format == kAnnexB && (size == 0 || StartsWithAnnexBHeader(data, size));

  if (!is_valid_) {
    return;
  }

  if (size == 0) {
    return;
  }

  std::vector<uint8_t> nalu;
  while (size > kAnnexBHeaderSizeInBytes &&
         ExtractAnnexBNalu(&data, &size, &nalu)) {
    if (nalu[kAnnexBHeaderSizeInBytes] == kSpsStartCode) {
      if (first_sps_index_ == -1) {
        first_sps_index_ = static_cast<int>(parameter_sets_.size());
      }
      parameter_sets_.push_back(nalu);
      combined_size_in_bytes_ += nalu.size();
    } else if (nalu[kAnnexBHeaderSizeInBytes] == kPpsStartCode) {
      if (first_pps_index_ == -1) {
        first_pps_index_ = static_cast<int>(parameter_sets_.size());
      }
      parameter_sets_.push_back(nalu);
      combined_size_in_bytes_ += nalu.size();
    } else {
      break;
    }
  }
}

AvcParameterSets AvcParameterSets::ConvertTo(Format new_format) const {
  if (format_ == new_format) {
    return *this;
  }

  SB_DCHECK(format_ == kAnnexB);
  SB_DCHECK(new_format == kHeadless);

  AvcParameterSets new_parameter_sets(*this);
  new_parameter_sets.format_ = new_format;
  if (!new_parameter_sets.is_valid()) {
    return new_parameter_sets;
  }
  for (auto& parameter_set : new_parameter_sets.parameter_sets_) {
    SB_DCHECK(parameter_set.size() >= kAnnexBHeaderSizeInBytes);
    parameter_set.erase(parameter_set.begin(),
                        parameter_set.begin() + kAnnexBHeaderSizeInBytes);
    new_parameter_sets.combined_size_in_bytes_ -= kAnnexBHeaderSizeInBytes;
  }

  return new_parameter_sets;
}

bool AvcParameterSets::operator==(const AvcParameterSets& that) const {
  if (is_valid() != that.is_valid()) {
    return false;
  }
  if (!is_valid()) {
    return true;
  }

  SB_DCHECK(format() == that.format());

  if (parameter_sets_ == that.parameter_sets_) {
    SB_DCHECK(first_sps_index_ == that.first_sps_index_);
    SB_DCHECK(first_pps_index_ == that.first_pps_index_);
    return true;
  }
  return false;
}

bool AvcParameterSets::operator!=(const AvcParameterSets& that) const {
  return !(*this == that);
}

bool ConvertAnnexBToAvcc(const uint8_t* annex_b_source,
                         size_t size,
                         uint8_t* avcc_destination) {
  if (size == 0) {
    return true;
  }

  SB_DCHECK(annex_b_source);
  SB_DCHECK(avcc_destination);

  if (!StartsWithAnnexBHeader(annex_b_source, size)) {
    return false;
  }

  auto annex_b_source_size = size;
  // |avcc_destination_end| exists only for the purpose of validation.
  const auto avcc_destination_end = avcc_destination + size;

  const uint8_t* last_source = annex_b_source;

  const auto kAvccLengthInBytes = kAnnexBHeaderSizeInBytes;

  while (AdvanceToNextAnnexBHeader(&annex_b_source, &annex_b_source_size)) {
    SB_DCHECK(annex_b_source - last_source >= kAnnexBHeaderSizeInBytes);
    SB_DCHECK(avcc_destination < avcc_destination_end);

    size_t payload_size =
        annex_b_source - last_source - kAnnexBHeaderSizeInBytes;
    avcc_destination[0] =
        static_cast<uint8_t>((payload_size & 0xff000000) >> 24);
    avcc_destination[1] = static_cast<uint8_t>((payload_size & 0xff0000) >> 16);
    avcc_destination[2] = static_cast<uint8_t>((payload_size & 0xff00) >> 8);
    avcc_destination[3] = static_cast<uint8_t>(payload_size & 0xff);
    SbMemoryCopy(avcc_destination + kAvccLengthInBytes,
                 last_source + kAnnexBHeaderSizeInBytes, payload_size);
    avcc_destination += annex_b_source - last_source;
    last_source = annex_b_source;
  }

  SB_DCHECK(annex_b_source_size == 0);
  SB_DCHECK(avcc_destination == avcc_destination_end);

  return true;
}

}  // namespace media
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
