// Copyright 2014 The Chromium 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 "media/formats/mp2t/ts_packet.h"

#include <memory>

#include "media/base/bit_reader.h"
#include "media/formats/mp2t/mp2t_common.h"

namespace cobalt {
namespace media {
namespace mp2t {

static const uint8_t kTsHeaderSyncword = 0x47;

// static
int TsPacket::Sync(const uint8_t* buf, int size) {
  int k = 0;
  for (; k < size; k++) {
    // Verify that we have 4 syncwords in a row when possible,
    // this should improve synchronization robustness.
    // TODO: Consider the case where there is garbage between TS packets.
    bool is_header = true;
    for (int i = 0; i < 4; i++) {
      int idx = k + i * kPacketSize;
      if (idx >= size) break;
      if (buf[idx] != kTsHeaderSyncword) {
        DVLOG(LOG_LEVEL_TS) << "ByteSync" << idx << ": " << std::hex
                            << static_cast<int>(buf[idx]) << std::dec;
        is_header = false;
        break;
      }
    }
    if (is_header) break;
  }

  DVLOG_IF(1, k != 0) << "SYNC: nbytes_skipped=" << k;
  return k;
}

// static
TsPacket* TsPacket::Parse(const uint8_t* buf, int size) {
  if (size < kPacketSize) {
    DVLOG(1) << "Buffer does not hold one full TS packet:"
             << " buffer_size=" << size;
    return NULL;
  }

  DCHECK_EQ(buf[0], kTsHeaderSyncword);
  if (buf[0] != kTsHeaderSyncword) {
    DVLOG(1) << "Not on a TS syncword:"
             << " buf[0]=" << std::hex << static_cast<int>(buf[0]) << std::dec;
    return NULL;
  }

  std::unique_ptr<TsPacket> ts_packet(new TsPacket());
  bool status = ts_packet->ParseHeader(buf);
  if (!status) {
    DVLOG(1) << "Parsing header failed";
    return NULL;
  }
  return ts_packet.release();
}

TsPacket::TsPacket() {}

TsPacket::~TsPacket() {}

bool TsPacket::ParseHeader(const uint8_t* buf) {
  BitReader bit_reader(buf, kPacketSize);
  payload_ = buf;
  payload_size_ = kPacketSize;

  // Read the TS header: 4 bytes.
  int syncword;
  int transport_error_indicator;
  int payload_unit_start_indicator;
  int transport_priority;
  int transport_scrambling_control;
  int adaptation_field_control;
  RCHECK(bit_reader.ReadBits(8, &syncword));
  RCHECK(bit_reader.ReadBits(1, &transport_error_indicator));
  RCHECK(bit_reader.ReadBits(1, &payload_unit_start_indicator));
  RCHECK(bit_reader.ReadBits(1, &transport_priority));
  RCHECK(bit_reader.ReadBits(13, &pid_));
  RCHECK(bit_reader.ReadBits(2, &transport_scrambling_control));
  RCHECK(bit_reader.ReadBits(2, &adaptation_field_control));
  RCHECK(bit_reader.ReadBits(4, &continuity_counter_));
  payload_unit_start_indicator_ = (payload_unit_start_indicator != 0);
  payload_ += 4;
  payload_size_ -= 4;

  // Default values when no adaptation field.
  discontinuity_indicator_ = false;
  random_access_indicator_ = false;

  // Done since no adaptation field.
  if ((adaptation_field_control & 0x2) == 0) return true;

  // Read the adaptation field if needed.
  int adaptation_field_length;
  RCHECK(bit_reader.ReadBits(8, &adaptation_field_length));
  DVLOG(LOG_LEVEL_TS) << "adaptation_field_length=" << adaptation_field_length;
  payload_ += 1;
  payload_size_ -= 1;
  if ((adaptation_field_control & 0x1) == 0 && adaptation_field_length != 183) {
    DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    return false;
  }
  if ((adaptation_field_control & 0x1) == 1 && adaptation_field_length > 182) {
    DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    // This is not allowed by the spec.
    // However, some badly encoded streams are using
    // adaptation_field_length = 183
    return false;
  }

  // adaptation_field_length = '0' is used to insert a single stuffing byte
  // in the adaptation field of a transport stream packet.
  if (adaptation_field_length == 0) return true;

  bool status = ParseAdaptationField(&bit_reader, adaptation_field_length);
  payload_ += adaptation_field_length;
  payload_size_ -= adaptation_field_length;
  return status;
}

bool TsPacket::ParseAdaptationField(BitReader* bit_reader,
                                    int adaptation_field_length) {
  DCHECK_GT(adaptation_field_length, 0);
  int adaptation_field_start_marker = bit_reader->bits_available() / 8;

  int discontinuity_indicator;
  int random_access_indicator;
  int elementary_stream_priority_indicator;
  int pcr_flag;
  int opcr_flag;
  int splicing_point_flag;
  int transport_private_data_flag;
  int adaptation_field_extension_flag;
  RCHECK(bit_reader->ReadBits(1, &discontinuity_indicator));
  RCHECK(bit_reader->ReadBits(1, &random_access_indicator));
  RCHECK(bit_reader->ReadBits(1, &elementary_stream_priority_indicator));
  RCHECK(bit_reader->ReadBits(1, &pcr_flag));
  RCHECK(bit_reader->ReadBits(1, &opcr_flag));
  RCHECK(bit_reader->ReadBits(1, &splicing_point_flag));
  RCHECK(bit_reader->ReadBits(1, &transport_private_data_flag));
  RCHECK(bit_reader->ReadBits(1, &adaptation_field_extension_flag));
  discontinuity_indicator_ = (discontinuity_indicator != 0);
  random_access_indicator_ = (random_access_indicator != 0);

  if (pcr_flag) {
    int64_t program_clock_reference_base;
    int reserved;
    int program_clock_reference_extension;
    RCHECK(bit_reader->ReadBits(33, &program_clock_reference_base));
    RCHECK(bit_reader->ReadBits(6, &reserved));
    RCHECK(bit_reader->ReadBits(9, &program_clock_reference_extension));
  }

  if (opcr_flag) {
    int64_t original_program_clock_reference_base;
    int reserved;
    int original_program_clock_reference_extension;
    RCHECK(bit_reader->ReadBits(33, &original_program_clock_reference_base));
    RCHECK(bit_reader->ReadBits(6, &reserved));
    RCHECK(
        bit_reader->ReadBits(9, &original_program_clock_reference_extension));
  }

  if (splicing_point_flag) {
    int splice_countdown;
    RCHECK(bit_reader->ReadBits(8, &splice_countdown));
  }

  if (transport_private_data_flag) {
    int transport_private_data_length;
    RCHECK(bit_reader->ReadBits(8, &transport_private_data_length));
    RCHECK(bit_reader->SkipBits(8 * transport_private_data_length));
  }

  if (adaptation_field_extension_flag) {
    int adaptation_field_extension_length;
    RCHECK(bit_reader->ReadBits(8, &adaptation_field_extension_length));
    RCHECK(bit_reader->SkipBits(8 * adaptation_field_extension_length));
  }

  // The rest of the adaptation field should be stuffing bytes.
  int adaptation_field_remaining_size =
      adaptation_field_length -
      (adaptation_field_start_marker - bit_reader->bits_available() / 8);
  RCHECK(adaptation_field_remaining_size >= 0);
  for (int k = 0; k < adaptation_field_remaining_size; k++) {
    int stuffing_byte;
    RCHECK(bit_reader->ReadBits(8, &stuffing_byte));
    // Unfortunately, a lot of streams exist in the field that do not fill
    // the remaining of the adaptation field with the expected stuffing value:
    // do not fail if that's the case.
    DVLOG_IF(1, stuffing_byte != 0xff)
        << "Stream not compliant: invalid stuffing byte " << std::hex
        << stuffing_byte;
  }

  DVLOG(LOG_LEVEL_TS) << "random_access_indicator=" << random_access_indicator_;
  return true;
}

}  // namespace mp2t
}  // namespace media
}  // namespace cobalt
