// 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 if (nalu[kAnnexBHeaderSizeInBytes] == kIdrStartCode) {
      break;
    }
  }
  SB_LOG_IF(ERROR, first_sps_index_ == -1 || first_pps_index_ == -1)
      << "AVC parameter set NALUs not found.";
}

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
