// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#include "vpxpes_parser.h"

#include <cstdint>
#include <cstdio>
#include <cstring>
#include <limits>
#include <vector>

#include "common/file_util.h"

namespace libwebm {

VpxPesParser::BcmvHeader::BcmvHeader(std::uint32_t len) : length(len) {
  id[0] = 'B';
  id[1] = 'C';
  id[2] = 'M';
  id[3] = 'V';
}

bool VpxPesParser::BcmvHeader::operator==(const BcmvHeader& other) const {
  return (other.length == length && other.id[0] == id[0] &&
          other.id[1] == id[1] && other.id[2] == id[2] && other.id[3] == id[3]);
}

bool VpxPesParser::BcmvHeader::Valid() const {
  return (length > 0 && id[0] == 'B' && id[1] == 'C' && id[2] == 'M' &&
          id[3] == 'V');
}

// TODO(tomfinegan): Break Open() into separate functions. One that opens the
// file, and one that reads one packet at a time. As things are files larger
// than the maximum availble memory for the current process cannot be loaded.
bool VpxPesParser::Open(const std::string& pes_file) {
  pes_file_size_ = static_cast<size_t>(libwebm::GetFileSize(pes_file));
  if (pes_file_size_ <= 0)
    return false;
  pes_file_data_.reserve(static_cast<size_t>(pes_file_size_));
  libwebm::FilePtr file = libwebm::FilePtr(std::fopen(pes_file.c_str(), "rb"),
                                           libwebm::FILEDeleter());
  int byte;
  while ((byte = fgetc(file.get())) != EOF) {
    pes_file_data_.push_back(static_cast<std::uint8_t>(byte));
  }

  if (!feof(file.get()) || ferror(file.get()) ||
      pes_file_size_ != pes_file_data_.size()) {
    return false;
  }

  read_pos_ = 0;
  parse_state_ = kFindStartCode;
  return true;
}

bool VpxPesParser::VerifyPacketStartCode() const {
  if (read_pos_ + 2 > pes_file_data_.size())
    return false;

  // PES packets all start with the byte sequence 0x0 0x0 0x1.
  if (pes_file_data_[read_pos_] != 0 || pes_file_data_[read_pos_ + 1] != 0 ||
      pes_file_data_[read_pos_ + 2] != 1) {
    return false;
  }

  return true;
}

bool VpxPesParser::ReadStreamId(std::uint8_t* stream_id) const {
  if (!stream_id || BytesAvailable() < 4)
    return false;

  *stream_id = pes_file_data_[read_pos_ + 3];
  return true;
}

bool VpxPesParser::ReadPacketLength(std::uint16_t* packet_length) const {
  if (!packet_length || BytesAvailable() < 6)
    return false;

  // Read and byte swap 16 bit big endian length.
  *packet_length =
      (pes_file_data_[read_pos_ + 4] << 8) | pes_file_data_[read_pos_ + 5];

  return true;
}

bool VpxPesParser::ParsePesHeader(PesHeader* header) {
  if (!header || parse_state_ != kParsePesHeader)
    return false;

  if (!VerifyPacketStartCode())
    return false;

  std::size_t pos = read_pos_;
  for (auto& a : header->start_code) {
    a = pes_file_data_[pos++];
  }

  // PES Video stream IDs start at E0.
  if (!ReadStreamId(&header->stream_id))
    return false;

  if (header->stream_id < kMinVideoStreamId ||
      header->stream_id > kMaxVideoStreamId)
    return false;

  if (!ReadPacketLength(&header->packet_length))
    return false;

  read_pos_ += kPesHeaderSize;
  parse_state_ = kParsePesOptionalHeader;
  return true;
}

// TODO(tomfinegan): Make these masks constants.
bool VpxPesParser::ParsePesOptionalHeader(PesOptionalHeader* header) {
  if (!header || parse_state_ != kParsePesOptionalHeader ||
      read_pos_ >= pes_file_size_) {
    return false;
  }

  std::size_t consumed = 0;
  PacketData poh_buffer;
  if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_],
                                               kPesOptionalHeaderSize,
                                               &poh_buffer, &consumed)) {
    return false;
  }

  std::size_t offset = 0;
  header->marker = (poh_buffer[offset] & 0x80) >> 6;
  header->scrambling = (poh_buffer[offset] & 0x30) >> 4;
  header->priority = (poh_buffer[offset] & 0x8) >> 3;
  header->data_alignment = (poh_buffer[offset] & 0xc) >> 2;
  header->copyright = (poh_buffer[offset] & 0x2) >> 1;
  header->original = poh_buffer[offset] & 0x1;
  offset++;

  header->has_pts = (poh_buffer[offset] & 0x80) >> 7;
  header->has_dts = (poh_buffer[offset] & 0x40) >> 6;
  header->unused_fields = poh_buffer[offset] & 0x3f;
  offset++;

  header->remaining_size = poh_buffer[offset];
  if (header->remaining_size !=
      static_cast<int>(kWebm2PesOptHeaderRemainingSize))
    return false;

  size_t bytes_left = header->remaining_size;
  offset++;

  if (header->has_pts) {
    // Read PTS markers. Format:
    // PTS: 5 bytes
    //   4 bits (flag: PTS present, but no DTS): 0x2 ('0010')
    //   36 bits (90khz PTS):
    //     top 3 bits
    //     marker ('1')
    //     middle 15 bits
    //     marker ('1')
    //     bottom 15 bits
    //     marker ('1')
    // TODO(tomfinegan): read/store the timestamp.
    header->pts_dts_flag = (poh_buffer[offset] & 0x20) >> 4;
    // Check the marker bits.
    if ((poh_buffer[offset + 0] & 1) != 1 ||
        (poh_buffer[offset + 2] & 1) != 1 ||
        (poh_buffer[offset + 4] & 1) != 1) {
      return false;
    }

    header->pts = (poh_buffer[offset] & 0xe) << 29 |
                  ((ReadUint16(&poh_buffer[offset + 1]) & ~1) << 14) |
                  (ReadUint16(&poh_buffer[offset + 3]) >> 1);
    offset += 5;
    bytes_left -= 5;
  }

  // Validate stuffing byte(s).
  for (size_t i = 0; i < bytes_left; ++i) {
    if (poh_buffer[offset + i] != 0xff)
      return false;
  }

  read_pos_ += consumed;
  parse_state_ = kParseBcmvHeader;

  return true;
}

// Parses and validates a BCMV header.
bool VpxPesParser::ParseBcmvHeader(BcmvHeader* header) {
  if (!header || parse_state_ != kParseBcmvHeader)
    return false;

  PacketData bcmv_buffer;
  std::size_t consumed = 0;
  if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_],
                                               kBcmvHeaderSize, &bcmv_buffer,
                                               &consumed)) {
    return false;
  }

  std::size_t offset = 0;
  header->id[0] = bcmv_buffer[offset++];
  header->id[1] = bcmv_buffer[offset++];
  header->id[2] = bcmv_buffer[offset++];
  header->id[3] = bcmv_buffer[offset++];

  header->length = 0;
  header->length |= bcmv_buffer[offset++] << 24;
  header->length |= bcmv_buffer[offset++] << 16;
  header->length |= bcmv_buffer[offset++] << 8;
  header->length |= bcmv_buffer[offset++];

  // Length stored in the BCMV header is followed by 2 bytes of 0 padding.
  if (bcmv_buffer[offset++] != 0 || bcmv_buffer[offset++] != 0)
    return false;

  if (!header->Valid())
    return false;

  parse_state_ = kFindStartCode;
  read_pos_ += consumed;

  return true;
}

bool VpxPesParser::FindStartCode(std::size_t origin,
                                 std::size_t* offset) const {
  if (read_pos_ + 2 >= pes_file_size_)
    return false;

  const std::size_t length = pes_file_size_ - origin;
  if (length < 3)
    return false;

  const uint8_t* const data = &pes_file_data_[origin];
  for (std::size_t i = 0; i < length - 3; ++i) {
    if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1) {
      *offset = origin + i;
      return true;
    }
  }

  return false;
}

bool VpxPesParser::IsPayloadFragmented(const PesHeader& header) const {
  return (header.packet_length != 0 &&
          (header.packet_length - kPesOptionalHeaderSize) !=
              header.bcmv_header.length);
}

bool VpxPesParser::AccumulateFragmentedPayload(std::size_t pes_packet_length,
                                               std::size_t payload_length) {
  PesHeader fragment_header;
  const std::size_t first_fragment_length =
      pes_packet_length - kPesOptionalHeaderSize - kBcmvHeaderSize;
  for (std::size_t i = 0; i < first_fragment_length; ++i) {
    payload_.push_back(pes_file_data_[read_pos_ + i]);
  }
  read_pos_ += first_fragment_length;
  parse_state_ = kFindStartCode;

  while (payload_.size() < payload_length) {
    PesHeader header;
    std::size_t packet_start_pos = read_pos_;
    if (!FindStartCode(read_pos_, &packet_start_pos)) {
      return false;
    }
    parse_state_ = kParsePesHeader;
    read_pos_ = packet_start_pos;

    if (!ParsePesHeader(&header)) {
      return false;
    }
    if (!ParsePesOptionalHeader(&header.opt_header)) {
      return false;
    }

    const std::size_t fragment_length =
        header.packet_length - kPesOptionalHeaderSize;
    std::size_t consumed = 0;
    if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_],
                                                 fragment_length, &payload_,
                                                 &consumed)) {
      return false;
    }
    read_pos_ += consumed;
  }
  return true;
}

bool VpxPesParser::RemoveStartCodeEmulationPreventionBytes(
    const std::uint8_t* raw_data, std::size_t bytes_required,
    PacketData* processed_data, std::size_t* bytes_consumed) const {
  if (bytes_required == 0 || !processed_data)
    return false;

  std::size_t num_zeros = 0;
  std::size_t bytes_copied = 0;
  const std::uint8_t* const end_of_input =
      &pes_file_data_[0] + pes_file_data_.size();
  std::size_t i;
  for (i = 0; bytes_copied < bytes_required; ++i) {
    if (raw_data + i > end_of_input)
      return false;

    bool skip = false;

    const std::uint8_t byte = raw_data[i];
    if (byte == 0) {
      ++num_zeros;
    } else if (byte == 0x3 && num_zeros == 2) {
      skip = true;
      num_zeros = 0;
    } else {
      num_zeros = 0;
    }

    if (skip == false) {
      processed_data->push_back(byte);
      ++bytes_copied;
    }
  }
  *bytes_consumed = i;
  return true;
}

int VpxPesParser::BytesAvailable() const {
  return static_cast<int>(pes_file_data_.size() - read_pos_);
}

bool VpxPesParser::ParseNextPacket(PesHeader* header, VideoFrame* frame) {
  if (!header || !frame || parse_state_ != kFindStartCode ||
      BytesAvailable() == 0) {
    return false;
  }

  std::size_t packet_start_pos = read_pos_;
  if (!FindStartCode(read_pos_, &packet_start_pos)) {
    return false;
  }
  parse_state_ = kParsePesHeader;
  read_pos_ = packet_start_pos;

  if (!ParsePesHeader(header)) {
    return false;
  }
  if (!ParsePesOptionalHeader(&header->opt_header)) {
    return false;
  }
  if (!ParseBcmvHeader(&header->bcmv_header)) {
    return false;
  }

  // BCMV header length includes the length of the BCMVHeader itself. Adjust:
  const std::size_t payload_length =
      header->bcmv_header.length - BcmvHeader::size();

  // Make sure there's enough input data to read the entire frame.
  if (read_pos_ + payload_length > pes_file_data_.size()) {
    // Need more data.
    printf("VpxPesParser: Not enough data. Required: %u Available: %u\n",
           static_cast<unsigned int>(payload_length),
           static_cast<unsigned int>(pes_file_data_.size() - read_pos_));
    parse_state_ = kFindStartCode;
    read_pos_ = packet_start_pos;
    return false;
  }

  if (IsPayloadFragmented(*header)) {
    if (!AccumulateFragmentedPayload(header->packet_length, payload_length)) {
      fprintf(stderr, "VpxPesParser: Failed parsing fragmented payload!\n");
      return false;
    }
  } else {
    std::size_t consumed = 0;
    if (!RemoveStartCodeEmulationPreventionBytes(
            &pes_file_data_[read_pos_], payload_length, &payload_, &consumed)) {
      return false;
    }
    read_pos_ += consumed;
  }

  if (frame->buffer().capacity < payload_.size()) {
    if (frame->Init(payload_.size()) == false) {
      fprintf(stderr, "VpxPesParser: Out of memory.\n");
      return false;
    }
  }
  frame->set_nanosecond_pts(Khz90TicksToNanoseconds(header->opt_header.pts));
  std::memcpy(frame->buffer().data.get(), &payload_[0], payload_.size());
  frame->SetBufferLength(payload_.size());

  payload_.clear();
  parse_state_ = kFindStartCode;

  return true;
}

}  // namespace libwebm
