// 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 "base/memory/scoped_ptr.h"
#include "media/base/bit_reader.h"
#include "media/formats/mp2t/mp2t_common.h"

namespace media {
namespace mp2t {

static const uint8 kTsHeaderSyncword = 0x47;

// static
int TsPacket::Sync(const uint8* 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(damienv): 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* 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;
  }

  scoped_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* 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 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 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

