// 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/mp4/box_definitions.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "media/base/media_switches.h"
#include "media/base/media_util.h"
#include "media/base/video_types.h"
#include "media/base/video_util.h"
#include "media/formats/common/opus_constants.h"
#include "media/formats/mp4/es_descriptor.h"
#include "media/formats/mp4/rcheck.h"
#include "media/media_buildflags.h"

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#include "media/formats/mp4/avc.h"
#include "media/video/h264_parser.h"  // nogncheck

#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
#include "media/formats/mp4/dolby_vision.h"
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)

#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
#include "media/formats/mp4/hevc.h"
#endif  // BUILDFLAG(ENABLE_HEVC_DEMUXING)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)

namespace media {
namespace mp4 {

namespace {

const size_t kKeyIdSize = 16;
const size_t kFlacMetadataBlockStreaminfoSize = 34;

}  // namespace

FileType::FileType() = default;
FileType::FileType(const FileType& other) = default;
FileType::~FileType() = default;
FourCC FileType::BoxType() const { return FOURCC_FTYP; }

bool FileType::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version));
  size_t num_brands = (reader->box_size() - reader->pos()) / sizeof(FourCC);
  return reader->SkipBytes(sizeof(FourCC) * num_brands);  // compatible_brands
}

ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() = default;
ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader(
    const ProtectionSystemSpecificHeader& other) = default;
ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() = default;
FourCC ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH; }

bool ProtectionSystemSpecificHeader::Parse(BoxReader* reader) {
  // Don't bother validating the box's contents.
  // Copy the entire box, including the header, for passing to EME as initData.
  DCHECK(raw_box.empty());
  raw_box.assign(reader->buffer(), reader->buffer() + reader->box_size());
  return true;
}

FullProtectionSystemSpecificHeader::FullProtectionSystemSpecificHeader() =
    default;
FullProtectionSystemSpecificHeader::FullProtectionSystemSpecificHeader(
    const FullProtectionSystemSpecificHeader& other) = default;
FullProtectionSystemSpecificHeader::~FullProtectionSystemSpecificHeader() =
    default;
FourCC FullProtectionSystemSpecificHeader::BoxType() const {
  return FOURCC_PSSH;
}

// The format of a 'pssh' box is as follows:
//   unsigned int(32) size;
//   unsigned int(32) type = "pssh";
//   if (size==1) {
//     unsigned int(64) largesize;
//   } else if (size==0) {
//     -- box extends to end of file
//   }
//   unsigned int(8) version;
//   bit(24) flags;
//   unsigned int(8)[16] SystemID;
//   if (version > 0)
//   {
//     unsigned int(32) KID_count;
//     {
//       unsigned int(8)[16] KID;
//     } [KID_count]
//   }
//   unsigned int(32) DataSize;
//   unsigned int(8)[DataSize] Data;

bool FullProtectionSystemSpecificHeader::Parse(mp4::BoxReader* reader) {
  RCHECK(reader->type() == BoxType() && reader->ReadFullBoxHeader());

  // Only versions 0 and 1 of the 'pssh' boxes are supported. Any other
  // versions are ignored.
  RCHECK(reader->version() == 0 || reader->version() == 1);
  RCHECK(reader->flags() == 0);
  RCHECK(reader->ReadVec(&system_id, 16));

  if (reader->version() > 0) {
    uint32_t kid_count;
    RCHECK(reader->Read4(&kid_count));
    for (uint32_t i = 0; i < kid_count; ++i) {
      std::vector<uint8_t> kid;
      RCHECK(reader->ReadVec(&kid, 16));
      key_ids.push_back(kid);
    }
  }

  uint32_t data_size;
  RCHECK(reader->Read4(&data_size));
  RCHECK(reader->ReadVec(&data, data_size));
  return true;
}

SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() = default;
SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset(
    const SampleAuxiliaryInformationOffset& other) = default;
SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() = default;
FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; }

bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  if (reader->flags() & 1)
    RCHECK(reader->SkipBytes(8));

  uint32_t count;
  RCHECK(reader->Read4(&count));
  int bytes_per_offset = reader->version() == 1 ? 8 : 4;

  // Cast |count| to size_t before multiplying to support maximum platform size.
  base::CheckedNumeric<size_t> bytes_needed =
      base::CheckMul(bytes_per_offset, static_cast<size_t>(count));
  RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
                      "Extreme SAIO count exceeds implementation limit.");
  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));

  RCHECK(count <= offsets.max_size());
  offsets.resize(count);

  for (uint32_t i = 0; i < count; i++) {
    if (reader->version() == 1) {
      RCHECK(reader->Read8(&offsets[i]));
    } else {
      RCHECK(reader->Read4Into8(&offsets[i]));
    }
  }
  return true;
}

SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize()
  : default_sample_info_size(0), sample_count(0) {
}
SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize(
    const SampleAuxiliaryInformationSize& other) = default;
SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() = default;
FourCC SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ; }

bool SampleAuxiliaryInformationSize::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  if (reader->flags() & 1)
    RCHECK(reader->SkipBytes(8));

  RCHECK(reader->Read1(&default_sample_info_size) &&
         reader->Read4(&sample_count));
  if (default_sample_info_size == 0)
    return reader->ReadVec(&sample_info_sizes, sample_count);
  return true;
}

SampleEncryptionEntry::SampleEncryptionEntry() = default;
SampleEncryptionEntry::SampleEncryptionEntry(
    const SampleEncryptionEntry& other) = default;
SampleEncryptionEntry::~SampleEncryptionEntry() = default;

bool SampleEncryptionEntry::Parse(BufferReader* reader,
                                  uint8_t iv_size,
                                  bool has_subsamples) {
  // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
  // 64-bit (8-byte) or 128-bit (16-byte). The 3rd Edition allows |iv_size|
  // to be 0, for the case of a "constant IV". In this case, the existence of
  // the constant IV must be ensured by the caller.
  RCHECK(iv_size == 0 || iv_size == 8 || iv_size == 16);

  memset(initialization_vector, 0, sizeof(initialization_vector));
  for (uint8_t i = 0; i < iv_size; i++)
    RCHECK(reader->Read1(initialization_vector + i));

  if (!has_subsamples) {
    subsamples.clear();
    return true;
  }

  uint16_t subsample_count;
  RCHECK(reader->Read2(&subsample_count));
  RCHECK(subsample_count > 0);
  RCHECK(subsample_count <= subsamples.max_size());
  subsamples.resize(subsample_count);
  for (SubsampleEntry& subsample : subsamples) {
    uint16_t clear_bytes;
    uint32_t cypher_bytes;
    RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes));
    subsample.clear_bytes = clear_bytes;
    subsample.cypher_bytes = cypher_bytes;
  }
  return true;
}

bool SampleEncryptionEntry::GetTotalSizeOfSubsamples(size_t* total_size) const {
  size_t size = 0;
  for (const SubsampleEntry& subsample : subsamples) {
    size += subsample.clear_bytes;
    RCHECK(size >= subsample.clear_bytes);  // overflow
    size += subsample.cypher_bytes;
    RCHECK(size >= subsample.cypher_bytes);  // overflow
  }
  *total_size = size;
  return true;
}

SampleEncryption::SampleEncryption() : use_subsample_encryption(false) {}
SampleEncryption::SampleEncryption(const SampleEncryption& other) = default;
SampleEncryption::~SampleEncryption() = default;
FourCC SampleEncryption::BoxType() const {
  return FOURCC_SENC;
}

bool SampleEncryption::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  use_subsample_encryption = (reader->flags() & kUseSubsampleEncryption) != 0;
  sample_encryption_data.assign(reader->buffer() + reader->pos(),
                                reader->buffer() + reader->box_size());
  return true;
}

OriginalFormat::OriginalFormat() : format(FOURCC_NULL) {}
OriginalFormat::OriginalFormat(const OriginalFormat& other) = default;
OriginalFormat::~OriginalFormat() = default;
FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; }

bool OriginalFormat::Parse(BoxReader* reader) {
  return reader->ReadFourCC(&format);
}

SchemeType::SchemeType() : type(FOURCC_NULL), version(0) {}
SchemeType::SchemeType(const SchemeType& other) = default;
SchemeType::~SchemeType() = default;
FourCC SchemeType::BoxType() const { return FOURCC_SCHM; }

bool SchemeType::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->ReadFourCC(&type) &&
         reader->Read4(&version));
  return true;
}

TrackEncryption::TrackEncryption()
    : is_encrypted(false),
      default_iv_size(0)
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
      ,
      default_crypt_byte_block(0),
      default_skip_byte_block(0),
      default_constant_iv_size(0)
#endif
{
}
TrackEncryption::TrackEncryption(const TrackEncryption& other) = default;
TrackEncryption::~TrackEncryption() = default;
FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }

bool TrackEncryption::Parse(BoxReader* reader) {
  uint8_t flag;
  uint8_t possible_pattern_info;
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->SkipBytes(1) &&  // skip reserved byte
         reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
         reader->Read1(&default_iv_size) &&
         reader->ReadVec(&default_kid, kKeyIdSize));
  is_encrypted = (flag != 0);
  if (is_encrypted) {
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
    if (reader->version() > 0) {
      default_crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
      default_skip_byte_block = possible_pattern_info & 0x0f;
    }
    if (default_iv_size == 0) {
      RCHECK(reader->Read1(&default_constant_iv_size));
      RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
      memset(default_constant_iv, 0, sizeof(default_constant_iv));
      for (uint8_t i = 0; i < default_constant_iv_size; i++)
        RCHECK(reader->Read1(default_constant_iv + i));
    } else {
      RCHECK(default_iv_size == 8 || default_iv_size == 16);
    }
#else
    RCHECK(default_iv_size == 8 || default_iv_size == 16);
#endif
  } else {
    RCHECK(default_iv_size == 0);
  }
  return true;
}

SchemeInfo::SchemeInfo() = default;
SchemeInfo::SchemeInfo(const SchemeInfo& other) = default;
SchemeInfo::~SchemeInfo() = default;
FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; }

bool SchemeInfo::Parse(BoxReader* reader) {
  return reader->ScanChildren() && reader->ReadChild(&track_encryption);
}

ProtectionSchemeInfo::ProtectionSchemeInfo() = default;
ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) =
    default;
ProtectionSchemeInfo::~ProtectionSchemeInfo() = default;
FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; }

bool ProtectionSchemeInfo::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() &&
         reader->ReadChild(&format) &&
         reader->ReadChild(&type));
  if (HasSupportedScheme())
    RCHECK(reader->ReadChild(&info));
  // Other protection schemes are silently ignored. Since the protection scheme
  // type can't be determined until this box is opened, we return 'true' for
  // unsupported protection schemes. It is the parent box's responsibility to
  // ensure that this scheme type is a supported one.
  return true;
}

bool ProtectionSchemeInfo::HasSupportedScheme() const {
  FourCC four_cc = type.type;
  if (four_cc == FOURCC_CENC)
    return true;
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
  if (four_cc == FOURCC_CBCS)
    return true;
#endif
  return false;
}

bool ProtectionSchemeInfo::IsCbcsEncryptionScheme() const {
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
  FourCC four_cc = type.type;
  return (four_cc == FOURCC_CBCS);
#else
  return false;
#endif
}

MovieHeader::MovieHeader()
    : version(0),
      creation_time(0),
      modification_time(0),
      timescale(0),
      duration(0),
      rate(-1),
      volume(-1),
      next_track_id(0) {}
MovieHeader::MovieHeader(const MovieHeader& other) = default;
MovieHeader::~MovieHeader() = default;
FourCC MovieHeader::BoxType() const { return FOURCC_MVHD; }

bool MovieHeader::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  version = reader->version();

  if (version == 1) {
    RCHECK(reader->Read8(&creation_time) &&
           reader->Read8(&modification_time) &&
           reader->Read4(&timescale) &&
           reader->Read8(&duration));
  } else {
    RCHECK(reader->Read4Into8(&creation_time) &&
           reader->Read4Into8(&modification_time) &&
           reader->Read4(&timescale) &&
           reader->Read4Into8(&duration));
  }

  RCHECK_MEDIA_LOGGED(timescale > 0, reader->media_log(),
                      "Movie header's timescale must not be 0");

  RCHECK(reader->Read4s(&rate) &&
         reader->Read2s(&volume) &&
         reader->SkipBytes(10) &&  // reserved
         reader->ReadDisplayMatrix(display_matrix) &&
         reader->SkipBytes(24) &&  // predefined zero
         reader->Read4(&next_track_id));
  return true;
}

TrackHeader::TrackHeader()
    : creation_time(0),
      modification_time(0),
      track_id(0),
      duration(0),
      layer(-1),
      alternate_group(-1),
      volume(-1),
      width(0),
      height(0) {}
TrackHeader::TrackHeader(const TrackHeader& other) = default;
TrackHeader::~TrackHeader() = default;
FourCC TrackHeader::BoxType() const { return FOURCC_TKHD; }

bool TrackHeader::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  if (reader->version() == 1) {
    RCHECK(reader->Read8(&creation_time) &&
           reader->Read8(&modification_time) &&
           reader->Read4(&track_id) &&
           reader->SkipBytes(4) &&    // reserved
           reader->Read8(&duration));
  } else {
    RCHECK(reader->Read4Into8(&creation_time) &&
           reader->Read4Into8(&modification_time) &&
           reader->Read4(&track_id) &&
           reader->SkipBytes(4) &&   // reserved
           reader->Read4Into8(&duration));
  }

  RCHECK(reader->SkipBytes(8) &&  // reserved
         reader->Read2s(&layer) &&
         reader->Read2s(&alternate_group) &&
         reader->Read2s(&volume) &&
         reader->SkipBytes(2) &&  // reserved
         reader->ReadDisplayMatrix(display_matrix) &&
         reader->Read4(&width) &&
         reader->Read4(&height));

  // Round width and height to the nearest number.
  // Note: width and height are fixed-point 16.16 values. The following code
  // rounds a.1x to a + 1, and a.0x to a.
  width >>= 15;
  width += 1;
  width >>= 1;
  height >>= 15;
  height += 1;
  height >>= 1;

  return true;
}

SampleDescription::SampleDescription() : type(kInvalid) {}
SampleDescription::SampleDescription(const SampleDescription& other) = default;
SampleDescription::~SampleDescription() = default;
FourCC SampleDescription::BoxType() const { return FOURCC_STSD; }

bool SampleDescription::Parse(BoxReader* reader) {
  uint32_t count;
  RCHECK(reader->SkipBytes(4) &&
         reader->Read4(&count));
  video_entries.clear();
  audio_entries.clear();

  // Note: this value is preset before scanning begins. See comments in the
  // Parse(Media*) function.
  if (type == kVideo) {
    RCHECK(reader->ReadAllChildren(&video_entries));
  } else if (type == kAudio) {
    RCHECK(reader->ReadAllChildren(&audio_entries));
  }
  return true;
}

SampleTable::SampleTable() = default;
SampleTable::SampleTable(const SampleTable& other) = default;

SampleTable::~SampleTable() = default;
FourCC SampleTable::BoxType() const { return FOURCC_STBL; }

bool SampleTable::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() &&
         reader->ReadChild(&description));
  // There could be multiple SampleGroupDescription boxes with different
  // grouping types. For common encryption, the relevant grouping type is
  // 'seig'. Continue reading until 'seig' is found, or until running out of
  // child boxes.
  while (reader->HasChild(&sample_group_description)) {
    RCHECK(reader->ReadChild(&sample_group_description));
    if (sample_group_description.grouping_type == FOURCC_SEIG)
      break;
    sample_group_description.entries.clear();
  }
  return true;
}

EditList::EditList() = default;
EditList::EditList(const EditList& other) = default;
EditList::~EditList() = default;
FourCC EditList::BoxType() const { return FOURCC_ELST; }

bool EditList::Parse(BoxReader* reader) {
  uint32_t count;
  RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count));

  const size_t bytes_per_edit = reader->version() == 1 ? 20 : 12;

  // Cast |count| to size_t before multiplying to support maximum platform size.
  base::CheckedNumeric<size_t> bytes_needed =
      base::CheckMul(bytes_per_edit, static_cast<size_t>(count));
  RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
                      "Extreme ELST count exceeds implementation limit.");
  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));

  RCHECK(count <= edits.max_size());
  edits.resize(count);

  for (auto edit = edits.begin(); edit != edits.end(); ++edit) {
    if (reader->version() == 1) {
      RCHECK(reader->Read8(&edit->segment_duration) &&
             reader->Read8s(&edit->media_time));
    } else {
      RCHECK(reader->Read4Into8(&edit->segment_duration) &&
             reader->Read4sInto8s(&edit->media_time));
    }
    RCHECK(reader->Read2s(&edit->media_rate_integer) &&
           reader->Read2s(&edit->media_rate_fraction));
  }
  return true;
}

Edit::Edit() = default;
Edit::Edit(const Edit& other) = default;
Edit::~Edit() = default;
FourCC Edit::BoxType() const { return FOURCC_EDTS; }

bool Edit::Parse(BoxReader* reader) {
  return reader->ScanChildren() && reader->ReadChild(&list);
}

HandlerReference::HandlerReference() : type(kInvalid) {}
HandlerReference::HandlerReference(const HandlerReference& other) = default;
HandlerReference::~HandlerReference() = default;
FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; }

bool HandlerReference::Parse(BoxReader* reader) {
  FourCC hdlr_type;
  RCHECK(reader->ReadFullBoxHeader() && reader->SkipBytes(4) &&
         reader->ReadFourCC(&hdlr_type) && reader->SkipBytes(12));

  // Now we should be at the beginning of the |name| field of HDLR box. The
  // |name| is a zero-terminated ASCII string in ISO BMFF, but it was a
  // Pascal-style counted string in older QT/Mov formats. So we'll read the
  // remaining box bytes first, then if the last one is zero, we strip the last
  // zero byte, otherwise we'll string the first byte (containing the length of
  // the Pascal-style string).
  std::vector<uint8_t> name_bytes;
  RCHECK(reader->ReadVec(&name_bytes, reader->box_size() - reader->pos()));
  if (name_bytes.size() == 0) {
    name = "";
  } else if (name_bytes.back() == 0) {
    // This is a zero-terminated C-style string, exclude the last byte.
    name = std::string(name_bytes.begin(), name_bytes.end() - 1);
  } else {
    // Check that the length of the Pascal-style string is correct.
    RCHECK(name_bytes[0] == (name_bytes.size() - 1));
    // Skip the first byte, containing the length of the Pascal-string.
    name = std::string(name_bytes.begin() + 1, name_bytes.end());
  }

  if (hdlr_type == FOURCC_VIDE) {
    type = kVideo;
  } else if (hdlr_type == FOURCC_SOUN) {
    type = kAudio;
  } else if (hdlr_type == FOURCC_META || hdlr_type == FOURCC_SUBT ||
             hdlr_type == FOURCC_TEXT || hdlr_type == FOURCC_SBTL) {
    // For purposes of detection, we include 'sbtl' handler here. Note, though
    // that ISO-14496-12 and its 2012 Amendment 2, and the spec for sourcing
    // inband tracks all reference only 'text' or 'subt', and 14496-30
    // references only 'subt'. Yet ffmpeg can encode subtitles as 'sbtl'.
    type = kText;
  } else {
    type = kInvalid;
  }
  return true;
}

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
    : version(0),
      profile_indication(0),
      profile_compatibility(0),
      avc_level(0),
      length_size(0) {}
AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord(
    const AVCDecoderConfigurationRecord& other) = default;
AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() = default;
FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; }

bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
  return ParseInternal(reader, reader->media_log());
}

bool AVCDecoderConfigurationRecord::Parse(const uint8_t* data, int data_size) {
  BufferReader reader(data, data_size);
  // TODO(wolenetz): Questionable MediaLog usage, http://crbug.com/712310
  NullMediaLog media_log;
  return ParseInternal(&reader, &media_log);
}

bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
                                                  MediaLog* media_log) {
  RCHECK(reader->Read1(&version) && version == 1 &&
         reader->Read1(&profile_indication) &&
         reader->Read1(&profile_compatibility) &&
         reader->Read1(&avc_level));

  uint8_t length_size_minus_one;
  RCHECK(reader->Read1(&length_size_minus_one));
  length_size = (length_size_minus_one & 0x3) + 1;

  RCHECK(length_size != 3); // Only values of 1, 2, and 4 are valid.

  uint8_t num_sps;
  RCHECK(reader->Read1(&num_sps));
  num_sps &= 0x1f;

  sps_list.resize(num_sps);
  for (int i = 0; i < num_sps; i++) {
    uint16_t sps_length;
    RCHECK(reader->Read2(&sps_length) &&
           reader->ReadVec(&sps_list[i], sps_length));
    RCHECK(sps_list[i].size() > 4);
  }

  uint8_t num_pps;
  RCHECK(reader->Read1(&num_pps));

  pps_list.resize(num_pps);
  for (int i = 0; i < num_pps; i++) {
    uint16_t pps_length;
    RCHECK(reader->Read2(&pps_length) &&
           reader->ReadVec(&pps_list[i], pps_length));
  }

  return true;
}
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)

VPCodecConfigurationRecord::VPCodecConfigurationRecord()
    : profile(VIDEO_CODEC_PROFILE_UNKNOWN) {}

VPCodecConfigurationRecord::VPCodecConfigurationRecord(
    const VPCodecConfigurationRecord& other) = default;

VPCodecConfigurationRecord::~VPCodecConfigurationRecord() = default;

FourCC VPCodecConfigurationRecord::BoxType() const {
  return FOURCC_VPCC;
}

bool VPCodecConfigurationRecord::Parse(BoxReader* reader) {
  uint8_t profile_indication = 0;
  RCHECK(reader->ReadFullBoxHeader() && reader->Read1(&profile_indication));
  // The remaining fields are not parsed as we don't care about them for now.

  switch (profile_indication) {
    case 0:
      profile = VP9PROFILE_PROFILE0;
      break;
    case 1:
      profile = VP9PROFILE_PROFILE1;
      break;
    case 2:
      profile = VP9PROFILE_PROFILE2;
      break;
    case 3:
      profile = VP9PROFILE_PROFILE3;
      break;
    default:
      MEDIA_LOG(ERROR, reader->media_log())
          << "Unsupported VP9 profile: 0x" << std::hex
          << static_cast<uint32_t>(profile_indication);
      return false;
  }
  return true;
}

#if BUILDFLAG(ENABLE_AV1_DECODER)
AV1CodecConfigurationRecord::AV1CodecConfigurationRecord()
    : profile(VIDEO_CODEC_PROFILE_UNKNOWN) {}

AV1CodecConfigurationRecord::AV1CodecConfigurationRecord(
    const AV1CodecConfigurationRecord& other) = default;

AV1CodecConfigurationRecord::~AV1CodecConfigurationRecord() = default;

FourCC AV1CodecConfigurationRecord::BoxType() const {
  return FOURCC_AV1C;
}

// Parse the AV1CodecConfigurationRecord, which has the following format:
// unsigned int (1) marker = 1;
// unsigned int (7) version = 1;
// unsigned int (3) seq_profile;
// unsigned int (5) seq_level_idx_0;
// unsigned int (1) seq_tier_0;
// unsigned int (1) high_bitdepth;
// unsigned int (1) twelve_bit;
// unsigned int (1) monochrome;
// unsigned int (1) chroma_subsampling_x;
// unsigned int (1) chroma_subsampling_y;
// unsigned int (2) chroma_sample_position;
// unsigned int (3) reserved = 0;
//
// unsigned int (1) initial_presentation_delay_present;
// if (initial_presentation_delay_present) {
//   unsigned int (4) initial_presentation_delay_minus_one;
// } else {
//   unsigned int (4) reserved = 0;
// }
//
// unsigned int (8)[] configOBUs;
bool AV1CodecConfigurationRecord::Parse(BoxReader* reader) {
  uint8_t av1c_byte = 0;
  RCHECK(reader->Read1(&av1c_byte));
  const uint8_t av1c_marker =  av1c_byte >> 7;
  if (!av1c_marker) {
    MEDIA_LOG(ERROR, reader->media_log()) << "Unsupported av1C: marker unset.";
    return false;
  }

  const uint8_t av1c_version = av1c_byte & 0b01111111;
  if (av1c_version != 1) {
    MEDIA_LOG(ERROR, reader->media_log())
        << "Unsupported av1C: unexpected version number: " << av1c_version;
    return false;
  }

  RCHECK(reader->Read1(&av1c_byte));
  const uint8_t seq_profile = av1c_byte >> 5;
  switch (seq_profile) {
    case 0:
      profile = AV1PROFILE_PROFILE_MAIN;
      break;
    case 1:
      profile = AV1PROFILE_PROFILE_HIGH;
      break;
    case 2:
      profile = AV1PROFILE_PROFILE_PRO;
      break;
    default:
      MEDIA_LOG(ERROR, reader->media_log())
          << "Unsupported av1C: unknown profile 0x" << std::hex << seq_profile;
      return false;
  }

  // The remaining fields are ignored since we don't care about them yet.

  return true;
}
#endif  // BUILDFLAG(ENABLE_AV1_DECODER)

PixelAspectRatioBox::PixelAspectRatioBox() : h_spacing(1), v_spacing(1) {}
PixelAspectRatioBox::PixelAspectRatioBox(const PixelAspectRatioBox& other) =
    default;
PixelAspectRatioBox::~PixelAspectRatioBox() = default;
FourCC PixelAspectRatioBox::BoxType() const { return FOURCC_PASP; }

bool PixelAspectRatioBox::Parse(BoxReader* reader) {
  RCHECK(reader->Read4(&h_spacing) &&
         reader->Read4(&v_spacing));
  return true;
}

VideoSampleEntry::VideoSampleEntry()
    : format(FOURCC_NULL),
      data_reference_index(0),
      width(0),
      height(0),
      video_codec(kUnknownVideoCodec),
      video_codec_profile(VIDEO_CODEC_PROFILE_UNKNOWN) {}

VideoSampleEntry::VideoSampleEntry(const VideoSampleEntry& other) = default;

VideoSampleEntry::~VideoSampleEntry() = default;
FourCC VideoSampleEntry::BoxType() const {
  DCHECK(false) << "VideoSampleEntry should be parsed according to the "
                << "handler type recovered in its Media ancestor.";
  return FOURCC_NULL;
}

bool VideoSampleEntry::Parse(BoxReader* reader) {
  format = reader->type();
  RCHECK(reader->SkipBytes(6) &&
         reader->Read2(&data_reference_index) &&
         reader->SkipBytes(16) &&
         reader->Read2(&width) &&
         reader->Read2(&height) &&
         reader->SkipBytes(50));

  RCHECK(reader->ScanChildren());
  if (reader->HasChild(&pixel_aspect)) {
    RCHECK(reader->MaybeReadChild(&pixel_aspect));
  }

  if (format == FOURCC_ENCV) {
    // Continue scanning until a recognized protection scheme is found, or until
    // we run out of protection schemes.
    while (!sinf.HasSupportedScheme()) {
      if (!reader->ReadChild(&sinf))
        return false;
    }
  }

  const FourCC actual_format =
      format == FOURCC_ENCV ? sinf.format.format : format;
  switch (actual_format) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
    case FOURCC_AVC1:
    case FOURCC_AVC3: {
      DVLOG(2) << __func__ << " reading AVCDecoderConfigurationRecord (avcC)";
      std::unique_ptr<AVCDecoderConfigurationRecord> avcConfig(
          new AVCDecoderConfigurationRecord());
      RCHECK(reader->ReadChild(avcConfig.get()));
      video_codec = kCodecH264;
      video_codec_profile = H264Parser::ProfileIDCToVideoCodecProfile(
          avcConfig->profile_indication);

      frame_bitstream_converter =
          base::MakeRefCounted<AVCBitstreamConverter>(std::move(avcConfig));
#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
      // It can be Dolby Vision stream if there is DVCC box.
      DolbyVisionConfiguration dvccConfig;
      if (reader->HasChild(&dvccConfig) && reader->ReadChild(&dvccConfig)) {
        DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvcC)";
        static_cast<AVCBitstreamConverter*>(frame_bitstream_converter.get())
            ->disable_validation();
        video_codec = kCodecDolbyVision;
        video_codec_profile = dvccConfig.codec_profile;
      }
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
      break;
    }
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
    case FOURCC_HEV1:
    case FOURCC_HVC1: {
      DVLOG(2) << __func__ << " parsing HEVCDecoderConfigurationRecord (hvcC)";
      std::unique_ptr<HEVCDecoderConfigurationRecord> hevcConfig(
          new HEVCDecoderConfigurationRecord());
      RCHECK(reader->ReadChild(hevcConfig.get()));
      video_codec = kCodecHEVC;
      video_codec_profile = hevcConfig->GetVideoProfile();
      frame_bitstream_converter =
          base::MakeRefCounted<HEVCBitstreamConverter>(std::move(hevcConfig));
#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
      // It can be Dolby Vision stream if there is DVCC box.
      DolbyVisionConfiguration dvccConfig;
      if (reader->HasChild(&dvccConfig) && reader->ReadChild(&dvccConfig)) {
        DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvcC)";
        video_codec = kCodecDolbyVision;
        video_codec_profile = dvccConfig.codec_profile;
      }
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
      break;
    }
#endif  // BUILDFLAG(ENABLE_HEVC_DEMUXING)
#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
    case FOURCC_DVA1:
    case FOURCC_DVAV: {
      DVLOG(2) << __func__ << " reading AVCDecoderConfigurationRecord (avcC)";
      std::unique_ptr<AVCDecoderConfigurationRecord> avcConfig(
          new AVCDecoderConfigurationRecord());
      RCHECK(reader->ReadChild(avcConfig.get()));
      frame_bitstream_converter =
          base::MakeRefCounted<AVCBitstreamConverter>(std::move(avcConfig));
      DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvcC)";
      DolbyVisionConfiguration dvccConfig;
      RCHECK(reader->ReadChild(&dvccConfig));
      video_codec = kCodecDolbyVision;
      video_codec_profile = dvccConfig.codec_profile;
      break;
    }
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
    case FOURCC_DVH1:
    case FOURCC_DVHE: {
      DVLOG(2) << __func__ << " reading HEVCDecoderConfigurationRecord (hvcC)";
      std::unique_ptr<HEVCDecoderConfigurationRecord> hevcConfig(
          new HEVCDecoderConfigurationRecord());
      RCHECK(reader->ReadChild(hevcConfig.get()));
      frame_bitstream_converter =
          base::MakeRefCounted<HEVCBitstreamConverter>(std::move(hevcConfig));
      DVLOG(2) << __func__ << " reading DolbyVisionConfiguration (dvcC)";
      DolbyVisionConfiguration dvccConfig;
      RCHECK(reader->ReadChild(&dvccConfig));
      video_codec = kCodecDolbyVision;
      video_codec_profile = dvccConfig.codec_profile;
      break;
    }
#endif  // BUILDFLAG(ENABLE_HEVC_DEMUXING)
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
    case FOURCC_VP09: {
      DVLOG(2) << __func__ << " parsing VPCodecConfigurationRecord (vpcC)";
      std::unique_ptr<VPCodecConfigurationRecord> vp_config(
          new VPCodecConfigurationRecord());
      RCHECK(reader->ReadChild(vp_config.get()));
      frame_bitstream_converter = nullptr;
      video_codec = kCodecVP9;
      video_codec_profile = vp_config->profile;
      break;
    }
#if BUILDFLAG(ENABLE_AV1_DECODER)
    case FOURCC_AV01: {
      DVLOG(2) << __func__ << " reading AV1 configuration.";
      AV1CodecConfigurationRecord av1_config;
      RCHECK(reader->ReadChild(&av1_config));
      frame_bitstream_converter = nullptr;
      video_codec = kCodecAV1;
      video_codec_profile = av1_config.profile;
      break;
    }
#endif
    default:
      // Unknown/unsupported format
      MEDIA_LOG(ERROR, reader->media_log())
          << "Unsupported VisualSampleEntry type "
          << FourCCToString(actual_format);
      return false;
  }

  if (video_codec_profile == VIDEO_CODEC_PROFILE_UNKNOWN) {
    MEDIA_LOG(ERROR, reader->media_log()) << "Unrecognized video codec profile";
    return false;
  }

  return true;
}

bool VideoSampleEntry::IsFormatValid() const {
  const FourCC actual_format =
      format == FOURCC_ENCV ? sinf.format.format : format;
  switch (actual_format) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
    case FOURCC_AVC1:
    case FOURCC_AVC3:
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
    case FOURCC_HEV1:
    case FOURCC_HVC1:
#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
    case FOURCC_DVH1:
    case FOURCC_DVHE:
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
#endif  // BUILDFLAG(ENABLE_HEVC_DEMUXING)
#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
    case FOURCC_DVA1:
    case FOURCC_DVAV:
#endif  // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
    case FOURCC_VP09:
      return true;
#if BUILDFLAG(ENABLE_AV1_DECODER)
    case FOURCC_AV01:
      return true;
#endif
    default:
      return false;
  }
}

ElementaryStreamDescriptor::ElementaryStreamDescriptor()
    : object_type(kForbidden) {}

ElementaryStreamDescriptor::ElementaryStreamDescriptor(
    const ElementaryStreamDescriptor& other) = default;

ElementaryStreamDescriptor::~ElementaryStreamDescriptor() = default;

FourCC ElementaryStreamDescriptor::BoxType() const {
  return FOURCC_ESDS;
}

bool ElementaryStreamDescriptor::Parse(BoxReader* reader) {
  std::vector<uint8_t> data;
  ESDescriptor es_desc;

  RCHECK(reader->ReadFullBoxHeader());
  RCHECK(reader->ReadVec(&data, reader->box_size() - reader->pos()));
  RCHECK(es_desc.Parse(data));

  object_type = es_desc.object_type();

  if (es_desc.IsAAC(object_type)) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
    RCHECK(aac.Parse(es_desc.decoder_specific_info(), reader->media_log()));
#else
    return false;
#endif
  }

  return true;
}

FlacSpecificBox::FlacSpecificBox()
    : sample_rate(0), channel_count(0), bits_per_sample(0) {}

FlacSpecificBox::FlacSpecificBox(const FlacSpecificBox& other) = default;

FlacSpecificBox::~FlacSpecificBox() = default;

FourCC FlacSpecificBox::BoxType() const {
  return FOURCC_DFLA;
}

bool FlacSpecificBox::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  RCHECK_MEDIA_LOGGED(reader->version() == 0, reader->media_log(),
                      "Only version 0 FLACSpecificBox (dfLa) is supported.");
  RCHECK_MEDIA_LOGGED(reader->flags() == 0, reader->media_log(),
                      "Only 0 flags in FLACSpecificBox (dfLa) is supported.");

  // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt, a
  // FLACMetadataBlock is formatted as:
  //   unsigned int(1) LastMetadataBlockFlag;
  //   unsigned int(7) BlockType;
  //   unsigned int(24) Length;
  //   unsigned int(8)  BlockData[Length];
  // We only care about the first block, which must exist, and must be
  // STREAMINFO.
  uint32_t metadata_framing;
  RCHECK_MEDIA_LOGGED(reader->Read4(&metadata_framing), reader->media_log(),
                      "Missing STREAMINFO block in FLACSpecificBox (dfLa).");
  uint8_t block_type = (metadata_framing >> 24) & 0x7f;
  RCHECK_MEDIA_LOGGED(block_type == 0, reader->media_log(),
                      "FLACSpecificBox metadata must begin with STREAMINFO.");
  uint32_t block_length = metadata_framing & 0x00ffffff;
  RCHECK_MEDIA_LOGGED(
      block_length == kFlacMetadataBlockStreaminfoSize, reader->media_log(),
      "STREAMINFO block in FLACSpecificBox (dfLa) has incorrect size.");

  // See https://xiph.org/flac/format.html#metadata_block_streaminfo for
  // STREAMINFO structure format and semantics. We only care about
  // |sample_rate|, |channel_count|,  and |bits_per_sample|,
  // though we also copy the STREAMINFO block for use later in audio decoder
  // configuration. See also the FLAC AudioSampleEntry logic: the |sample_rate|
  // here is used instead of that in the AudioSampleEntry per
  // https://github.com/xiph/flac/blob/master/doc/isoflac.txt.
  RCHECK(reader->ReadVec(&stream_info, kFlacMetadataBlockStreaminfoSize));
  // Bytes 0-9 (min/max block and frame sizes) are ignored here.
  sample_rate = stream_info[10] << 12;
  sample_rate += stream_info[11] << 4;
  sample_rate += (stream_info[12] >> 4) & 0xf;
  RCHECK_MEDIA_LOGGED(sample_rate > 0, reader->media_log(),
                      "STREAMINFO block in FLACSpecificBox (dfLa) must have "
                      "nonzero sample rate.");

  channel_count = (stream_info[12] >> 1) & 0x7;
  channel_count++;

  bits_per_sample = (stream_info[12] & 1) << 4;
  bits_per_sample += (stream_info[13] >> 4) & 0xf;
  bits_per_sample++;

  // The lower 4 bits of byte 13 and all of bytes 14-17 (number of samples in
  // stream) are ignored here.
  // Bytes 18-33 (hash of the unencoded audio data) are ignored here.

  return true;
}

OpusSpecificBox::OpusSpecificBox()
    : seek_preroll(base::TimeDelta::FromMilliseconds(80)),
      codec_delay_in_frames(0) {}

OpusSpecificBox::OpusSpecificBox(const OpusSpecificBox& other) = default;

OpusSpecificBox::~OpusSpecificBox() = default;

FourCC OpusSpecificBox::BoxType() const {
  return FOURCC_DOPS;
}

bool OpusSpecificBox::Parse(BoxReader* reader) {
  // Extradata must start with "OpusHead" magic.
  extradata.insert(extradata.end(),
                   {0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64});

  // The opus specific box must be present and at least OPUS_EXTRADATA_SIZE - 8
  // bytes in length. The -8 is for the missing "OpusHead" magic signature that
  // is required at the start of the extradata we give to the codec.
  const size_t headerless_extradata_size = reader->box_size() - reader->pos();
  RCHECK(headerless_extradata_size >= OPUS_EXTRADATA_SIZE - extradata.size());
  extradata.resize(extradata.size() + headerless_extradata_size);

  int16_t gain_db;

  RCHECK(reader->Read1(&extradata[OPUS_EXTRADATA_VERSION_OFFSET]));
  RCHECK(reader->Read1(&extradata[OPUS_EXTRADATA_CHANNELS_OFFSET]));
  RCHECK(reader->Read2(&codec_delay_in_frames /* PreSkip */));
  RCHECK(reader->Read4(&sample_rate));
  RCHECK(reader->Read2s(&gain_db));

#if !defined(ARCH_CPU_LITTLE_ENDIAN)
#error The code below assumes little-endianness.
#endif

  memcpy(&extradata[OPUS_EXTRADATA_SKIP_SAMPLES_OFFSET], &codec_delay_in_frames,
         sizeof(codec_delay_in_frames));
  memcpy(&extradata[OPUS_EXTRADATA_SAMPLE_RATE_OFFSET], &sample_rate,
         sizeof(sample_rate));
  memcpy(&extradata[OPUS_EXTRADATA_GAIN_OFFSET], &gain_db, sizeof(gain_db));

  channel_count = extradata[OPUS_EXTRADATA_CHANNELS_OFFSET];

  // Any remaining data is 1-byte data, so copy it over as is, there should
  // only be a handful of these entries, so reading byte by byte is okay.
  for (size_t i = OPUS_EXTRADATA_CHANNEL_MAPPING_OFFSET; i < extradata.size();
       ++i) {
    RCHECK(reader->Read1(&extradata[i]));
  }

  return true;
}

AudioSampleEntry::AudioSampleEntry()
    : format(FOURCC_NULL),
      data_reference_index(0),
      channelcount(0),
      samplesize(0),
      samplerate(0) {}

AudioSampleEntry::AudioSampleEntry(const AudioSampleEntry& other) = default;

AudioSampleEntry::~AudioSampleEntry() = default;

FourCC AudioSampleEntry::BoxType() const {
  DCHECK(false) << "AudioSampleEntry should be parsed according to the "
                << "handler type recovered in its Media ancestor.";
  return FOURCC_NULL;
}

bool AudioSampleEntry::Parse(BoxReader* reader) {
  format = reader->type();
  RCHECK(reader->SkipBytes(6) &&
         reader->Read2(&data_reference_index) &&
         reader->SkipBytes(8) &&
         reader->Read2(&channelcount) &&
         reader->Read2(&samplesize) &&
         reader->SkipBytes(4) &&
         reader->Read4(&samplerate));
  // Convert from 16.16 fixed point to integer
  samplerate >>= 16;

  RCHECK(reader->ScanChildren());
  if (format == FOURCC_ENCA) {
    // Continue scanning until a recognized protection scheme is found, or until
    // we run out of protection schemes.
    while (!sinf.HasSupportedScheme()) {
      if (!reader->ReadChild(&sinf))
        return false;
    }
  }

  if (format == FOURCC_OPUS ||
      (format == FOURCC_ENCA && sinf.format.format == FOURCC_OPUS)) {
    RCHECK_MEDIA_LOGGED(reader->ReadChild(&dops), reader->media_log(),
                        "Failure parsing OpusSpecificBox (dOps)");
    RCHECK_MEDIA_LOGGED(channelcount == dops.channel_count, reader->media_log(),
                        "Opus AudioSampleEntry channel count mismatches "
                        "OpusSpecificBox STREAMINFO channel count");
    RCHECK_MEDIA_LOGGED(samplerate == dops.sample_rate, reader->media_log(),
                        "Opus AudioSampleEntry sample rate mismatches "
                        "OpusSpecificBox STREAMINFO channel count");
  }

  // Read the FLACSpecificBox, even if CENC is signalled.
  if (format == FOURCC_FLAC ||
      (format == FOURCC_ENCA && sinf.format.format == FOURCC_FLAC)) {
    RCHECK_MEDIA_LOGGED(reader->ReadChild(&dfla), reader->media_log(),
                        "Failure parsing FLACSpecificBox (dfLa)");

    // AudioSampleEntry is constrained to max 65535Hz. Instead, use the sample
    // rate from the FlacSpecificBox per
    // https://github.com/xiph/flac/blob/master/doc/isoflac.txt
    if (samplerate != dfla.sample_rate) {
      MEDIA_LOG(INFO, reader->media_log())
          << "FLAC AudioSampleEntry sample rate " << samplerate
          << " overridden by rate " << dfla.sample_rate
          << " from FLACSpecificBox's STREAMINFO metadata";
      samplerate = dfla.sample_rate;
    }

    RCHECK_MEDIA_LOGGED(channelcount == dfla.channel_count, reader->media_log(),
                        "FLAC AudioSampleEntry channel count mismatches "
                        "FLACSpecificBox STREAMINFO channel count");

    RCHECK_MEDIA_LOGGED(samplesize == dfla.bits_per_sample, reader->media_log(),
                        "FLAC AudioSampleEntry sample size mismatches "
                        "FLACSpecificBox STREAMINFO sample size");
  } else {
    RCHECK_MEDIA_LOGGED(!reader->HasChild(&dfla), reader->media_log(),
                        "FLACSpecificBox (dfLa) must only be used with FLAC "
                        "AudioSampleEntry or CENC AudioSampleEntry wrapping "
                        "FLAC");
  }

  // ESDS is not valid in case of EAC3.
  RCHECK(reader->MaybeReadChild(&esds));
  return true;
}

MediaHeader::MediaHeader()
    : creation_time(0),
      modification_time(0),
      timescale(0),
      duration(0),
      language_code(0) {}
MediaHeader::MediaHeader(const MediaHeader& other) = default;
MediaHeader::~MediaHeader() = default;
FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; }

bool MediaHeader::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());

  if (reader->version() == 1) {
    RCHECK(reader->Read8(&creation_time) && reader->Read8(&modification_time) &&
           reader->Read4(&timescale) && reader->Read8(&duration) &&
           reader->Read2(&language_code));
  } else {
    RCHECK(reader->Read4Into8(&creation_time) &&
           reader->Read4Into8(&modification_time) &&
           reader->Read4(&timescale) && reader->Read4Into8(&duration) &&
           reader->Read2(&language_code));
  }

  RCHECK_MEDIA_LOGGED(timescale > 0, reader->media_log(),
                      "Track media header's timescale must not be 0");

  // ISO 639-2/T language code only uses 15 lower bits, so reset the 16th bit.
  language_code &= 0x7fff;
  // Skip playback quality information
  return reader->SkipBytes(2);
}

std::string MediaHeader::language() const {
  if (language_code == 0x7fff || language_code < 0x400) {
    return "und";
  }
  char lang_chars[4];
  lang_chars[3] = 0;
  lang_chars[2] = 0x60 + (language_code & 0x1f);
  lang_chars[1] = 0x60 + ((language_code >> 5) & 0x1f);
  lang_chars[0] = 0x60 + ((language_code >> 10) & 0x1f);

  if (lang_chars[0] < 'a' || lang_chars[0] > 'z' || lang_chars[1] < 'a' ||
      lang_chars[1] > 'z' || lang_chars[2] < 'a' || lang_chars[2] > 'z') {
    // Got unexpected characteds in ISO 639-2/T language code. Something must be
    // wrong with the input file, report 'und' language to be safe.
    DVLOG(2) << "Ignoring MDHD language_code (non ISO 639-2 compliant): "
             << lang_chars;
    lang_chars[0] = 'u';
    lang_chars[1] = 'n';
    lang_chars[2] = 'd';
  }

  return lang_chars;
}

MediaInformation::MediaInformation() = default;
MediaInformation::MediaInformation(const MediaInformation& other) = default;
MediaInformation::~MediaInformation() = default;
FourCC MediaInformation::BoxType() const { return FOURCC_MINF; }

bool MediaInformation::Parse(BoxReader* reader) {
  return reader->ScanChildren() &&
         reader->ReadChild(&sample_table);
}

Media::Media() = default;
Media::Media(const Media& other) = default;
Media::~Media() = default;
FourCC Media::BoxType() const { return FOURCC_MDIA; }

bool Media::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() &&
         reader->ReadChild(&header) &&
         reader->ReadChild(&handler));

  // Maddeningly, the HandlerReference box specifies how to parse the
  // SampleDescription box, making the latter the only box (of those that we
  // support) which cannot be parsed correctly on its own (or even with
  // information from its strict ancestor tree). We thus copy the handler type
  // to the sample description box *before* parsing it to provide this
  // information while parsing.
  information.sample_table.description.type = handler.type;
  RCHECK(reader->ReadChild(&information));
  return true;
}

Track::Track() = default;
Track::Track(const Track& other) = default;
Track::~Track() = default;
FourCC Track::BoxType() const { return FOURCC_TRAK; }

bool Track::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() &&
         reader->ReadChild(&header) &&
         reader->ReadChild(&media) &&
         reader->MaybeReadChild(&edit));
  return true;
}

MovieExtendsHeader::MovieExtendsHeader() : fragment_duration(0) {}
MovieExtendsHeader::MovieExtendsHeader(const MovieExtendsHeader& other) =
    default;
MovieExtendsHeader::~MovieExtendsHeader() = default;
FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; }

bool MovieExtendsHeader::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  if (reader->version() == 1) {
    RCHECK(reader->Read8(&fragment_duration));
  } else {
    RCHECK(reader->Read4Into8(&fragment_duration));
  }
  return true;
}

TrackExtends::TrackExtends()
    : track_id(0),
      default_sample_description_index(0),
      default_sample_duration(0),
      default_sample_size(0),
      default_sample_flags(0) {}
TrackExtends::TrackExtends(const TrackExtends& other) = default;
TrackExtends::~TrackExtends() = default;
FourCC TrackExtends::BoxType() const { return FOURCC_TREX; }

bool TrackExtends::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->Read4(&track_id) &&
         reader->Read4(&default_sample_description_index) &&
         reader->Read4(&default_sample_duration) &&
         reader->Read4(&default_sample_size) &&
         reader->Read4(&default_sample_flags));
  return true;
}

MovieExtends::MovieExtends() = default;
MovieExtends::MovieExtends(const MovieExtends& other) = default;
MovieExtends::~MovieExtends() = default;
FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; }

bool MovieExtends::Parse(BoxReader* reader) {
  header.fragment_duration = 0;
  return reader->ScanChildren() &&
         reader->MaybeReadChild(&header) &&
         reader->ReadChildren(&tracks);
}

Movie::Movie() : fragmented(false) {}
Movie::Movie(const Movie& other) = default;
Movie::~Movie() = default;
FourCC Movie::BoxType() const { return FOURCC_MOOV; }

bool Movie::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() && reader->ReadChild(&header) &&
         reader->ReadChildren(&tracks));

  RCHECK_MEDIA_LOGGED(reader->ReadChild(&extends), reader->media_log(),
                      "Detected unfragmented MP4. Media Source Extensions "
                      "require ISO BMFF moov to contain mvex to indicate that "
                      "Movie Fragments are to be expected.");

  MetadataBox meta;
  RCHECK(reader->MaybeReadChild(&meta));
  base::UmaHistogramBoolean("Media.MSE.DetectedShakaPackagerInMp4",
                            meta.used_shaka_packager);

  return reader->MaybeReadChildren(&pssh);
}

TrackFragmentDecodeTime::TrackFragmentDecodeTime() : decode_time(0) {}
TrackFragmentDecodeTime::TrackFragmentDecodeTime(
    const TrackFragmentDecodeTime& other) = default;
TrackFragmentDecodeTime::~TrackFragmentDecodeTime() = default;
FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; }

bool TrackFragmentDecodeTime::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  if (reader->version() == 1)
    return reader->Read8(&decode_time);
  else
    return reader->Read4Into8(&decode_time);
}

MovieFragmentHeader::MovieFragmentHeader() : sequence_number(0) {}
MovieFragmentHeader::MovieFragmentHeader(const MovieFragmentHeader& other) =
    default;
MovieFragmentHeader::~MovieFragmentHeader() = default;
FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; }

bool MovieFragmentHeader::Parse(BoxReader* reader) {
  return reader->SkipBytes(4) && reader->Read4(&sequence_number);
}

TrackFragmentHeader::TrackFragmentHeader()
    : track_id(0),
      sample_description_index(0),
      default_sample_duration(0),
      default_sample_size(0),
      default_sample_flags(0),
      has_default_sample_flags(false) {}

TrackFragmentHeader::TrackFragmentHeader(const TrackFragmentHeader& other) =
    default;
TrackFragmentHeader::~TrackFragmentHeader() = default;
FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; }

bool TrackFragmentHeader::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&track_id));

  // Media Source specific: reject tracks that set 'base-data-offset-present'.
  // Although the Media Source requires that 'default-base-is-moof' (14496-12
  // Amendment 2) be set, we omit this check as many otherwise-valid files in
  // the wild don't set it.
  //
  //  RCHECK((flags & 0x020000) && !(flags & 0x1));
  RCHECK_MEDIA_LOGGED(!(reader->flags() & 0x1), reader->media_log(),
                      "TFHD base-data-offset not allowed by MSE. See "
                      "https://www.w3.org/TR/mse-byte-stream-format-isobmff/"
                      "#movie-fragment-relative-addressing");

  if (reader->flags() & 0x2) {
    RCHECK(reader->Read4(&sample_description_index));
  } else {
    sample_description_index = 0;
  }

  if (reader->flags() & 0x8) {
    RCHECK(reader->Read4(&default_sample_duration));
  } else {
    default_sample_duration = 0;
  }

  if (reader->flags() & 0x10) {
    RCHECK(reader->Read4(&default_sample_size));
  } else {
    default_sample_size = 0;
  }

  if (reader->flags() & 0x20) {
    RCHECK(reader->Read4(&default_sample_flags));
    has_default_sample_flags = true;
  } else {
    has_default_sample_flags = false;
  }

  return true;
}

TrackFragmentRun::TrackFragmentRun()
    : sample_count(0), data_offset(0) {}
TrackFragmentRun::TrackFragmentRun(const TrackFragmentRun& other) = default;
TrackFragmentRun::~TrackFragmentRun() = default;
FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; }

bool TrackFragmentRun::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->Read4(&sample_count));
  const uint32_t flags = reader->flags();

  bool data_offset_present = (flags & 0x1) != 0;
  bool first_sample_flags_present = (flags & 0x4) != 0;
  bool sample_duration_present = (flags & 0x100) != 0;
  bool sample_size_present = (flags & 0x200) != 0;
  bool sample_flags_present = (flags & 0x400) != 0;
  bool sample_composition_time_offsets_present = (flags & 0x800) != 0;

  if (data_offset_present) {
    RCHECK(reader->Read4(&data_offset));
  } else {
    data_offset = 0;
  }

  uint32_t first_sample_flags = 0;
  if (first_sample_flags_present)
    RCHECK(reader->Read4(&first_sample_flags));

  int fields = sample_duration_present + sample_size_present +
      sample_flags_present + sample_composition_time_offsets_present;
  const size_t bytes_per_field = 4;

  // Cast |sample_count| to size_t before multiplying to support maximum
  // platform size.
  base::CheckedNumeric<size_t> bytes_needed = base::CheckMul(
      fields, bytes_per_field, static_cast<size_t>(sample_count));
  RCHECK_MEDIA_LOGGED(
      bytes_needed.IsValid(), reader->media_log(),
      "Extreme TRUN sample count exceeds implementation limit.");
  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));

  if (sample_duration_present) {
    RCHECK(sample_count <= sample_durations.max_size());
    sample_durations.resize(sample_count);
  }
  if (sample_size_present) {
    RCHECK(sample_count <= sample_sizes.max_size());
    sample_sizes.resize(sample_count);
  }
  if (sample_flags_present) {
    RCHECK(sample_count <= sample_flags.max_size());
    sample_flags.resize(sample_count);
  }
  if (sample_composition_time_offsets_present) {
    RCHECK(sample_count <= sample_composition_time_offsets.max_size());
    sample_composition_time_offsets.resize(sample_count);
  }

  if (sample_duration_present || sample_size_present || sample_flags_present ||
      sample_composition_time_offsets_present) {
    for (uint32_t i = 0; i < sample_count; ++i) {
      if (sample_duration_present)
        RCHECK(reader->Read4(&sample_durations[i]));
      if (sample_size_present)
        RCHECK(reader->Read4(&sample_sizes[i]));
      if (sample_flags_present)
        RCHECK(reader->Read4(&sample_flags[i]));
      if (sample_composition_time_offsets_present)
        RCHECK(reader->Read4s(&sample_composition_time_offsets[i]));
    }
  }

  if (first_sample_flags_present) {
    if (sample_flags.size() == 0) {
      sample_flags.push_back(first_sample_flags);
    } else {
      sample_flags[0] = first_sample_flags;
    }
  }
  return true;
}

SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
SampleToGroup::SampleToGroup(const SampleToGroup& other) = default;
SampleToGroup::~SampleToGroup() = default;
FourCC SampleToGroup::BoxType() const { return FOURCC_SBGP; }

bool SampleToGroup::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->Read4(&grouping_type));

  if (reader->version() == 1)
    RCHECK(reader->Read4(&grouping_type_parameter));

  if (grouping_type != FOURCC_SEIG) {
    DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type
                  << "' is not supported.";
    return true;
  }

  uint32_t count;
  RCHECK(reader->Read4(&count));

  const size_t bytes_per_entry = 8;
  // Cast |count| to size_t before multiplying to support maximum platform size.
  base::CheckedNumeric<size_t> bytes_needed =
      base::CheckMul(bytes_per_entry, static_cast<size_t>(count));
  RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
                      "Extreme SBGP count exceeds implementation limit.");
  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));

  RCHECK(count <= entries.max_size());
  entries.resize(count);
  for (uint32_t i = 0; i < count; ++i) {
    RCHECK(reader->Read4(&entries[i].sample_count) &&
           reader->Read4(&entries[i].group_description_index));
  }
  return true;
}

CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
    : is_encrypted(false),
      iv_size(0)
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
      ,
      crypt_byte_block(0),
      skip_byte_block(0),
      constant_iv_size(0)
#endif
{
}
CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry(
    const CencSampleEncryptionInfoEntry& other) = default;
CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() = default;

bool CencSampleEncryptionInfoEntry::Parse(BoxReader* reader) {
  uint8_t flag;
  uint8_t possible_pattern_info;
  RCHECK(reader->SkipBytes(1) &&  // reserved.
         reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
         reader->Read1(&iv_size) && reader->ReadVec(&key_id, kKeyIdSize));

  is_encrypted = (flag != 0);
  if (is_encrypted) {
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
    crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
    skip_byte_block = possible_pattern_info & 0x0f;
    if (iv_size == 0) {
      RCHECK(reader->Read1(&constant_iv_size));
      RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
      memset(constant_iv, 0, sizeof(constant_iv));
      for (uint8_t i = 0; i < constant_iv_size; i++)
        RCHECK(reader->Read1(constant_iv + i));
    } else {
      RCHECK(iv_size == 8 || iv_size == 16);
    }
#else
    RCHECK(iv_size == 8 || iv_size == 16);
#endif
  } else {
    RCHECK(iv_size == 0);
  }
  return true;
}

SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
SampleGroupDescription::SampleGroupDescription(
    const SampleGroupDescription& other) = default;
SampleGroupDescription::~SampleGroupDescription() = default;
FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }

bool SampleGroupDescription::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader() &&
         reader->Read4(&grouping_type));

  if (grouping_type != FOURCC_SEIG) {
    DLOG(WARNING) << "SampleGroupDescription box with grouping_type '"
                  << grouping_type << "' is not supported.";
    return true;
  }

  const uint8_t version = reader->version();

  const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize;
  uint32_t default_length = 0;
  if (version == 1) {
      RCHECK(reader->Read4(&default_length));
      RCHECK(default_length == 0 || default_length >= kEntrySize);
  }

  uint32_t count;
  RCHECK(reader->Read4(&count));

  // Check that we have at least two bytes for each entry before allocating a
  // potentially huge entries vector. In reality each entry will require a
  // variable number of bytes in excess of 2.
  const int bytes_per_entry = 2;
  // Cast |count| to size_t before multiplying to support maximum platform size.
  base::CheckedNumeric<size_t> bytes_needed =
      base::CheckMul(bytes_per_entry, static_cast<size_t>(count));
  RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
                      "Extreme SGPD count exceeds implementation limit.");
  RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));

  RCHECK(count <= entries.max_size());
  entries.resize(count);
  for (uint32_t i = 0; i < count; ++i) {
    if (version == 1) {
      if (default_length == 0) {
        uint32_t description_length = 0;
        RCHECK(reader->Read4(&description_length));
        RCHECK(description_length >= kEntrySize);
      }
    }
    RCHECK(entries[i].Parse(reader));
  }
  return true;
}

TrackFragment::TrackFragment() = default;
TrackFragment::TrackFragment(const TrackFragment& other) = default;
TrackFragment::~TrackFragment() = default;
FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }

bool TrackFragment::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() && reader->ReadChild(&header) &&
         // Media Source specific: 'tfdt' required
         reader->ReadChild(&decode_time) && reader->MaybeReadChildren(&runs) &&
         reader->MaybeReadChild(&auxiliary_offset) &&
         reader->MaybeReadChild(&auxiliary_size) &&
         reader->MaybeReadChild(&sdtp) &&
         reader->MaybeReadChild(&sample_encryption));

  // There could be multiple SampleGroupDescription and SampleToGroup boxes with
  // different grouping types. For common encryption, the relevant grouping type
  // is 'seig'. Continue reading until 'seig' is found, or until running out of
  // child boxes.
  while (reader->HasChild(&sample_group_description)) {
    RCHECK(reader->ReadChild(&sample_group_description));
    if (sample_group_description.grouping_type == FOURCC_SEIG)
      break;
    sample_group_description.entries.clear();
  }
  while (reader->HasChild(&sample_to_group)) {
    RCHECK(reader->ReadChild(&sample_to_group));
    if (sample_to_group.grouping_type == FOURCC_SEIG)
      break;
    sample_to_group.entries.clear();
  }
  return true;
}

MovieFragment::MovieFragment() = default;
MovieFragment::MovieFragment(const MovieFragment& other) = default;
MovieFragment::~MovieFragment() = default;
FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; }

bool MovieFragment::Parse(BoxReader* reader) {
  RCHECK(reader->ScanChildren() &&
         reader->ReadChild(&header) &&
         reader->ReadChildren(&tracks) &&
         reader->MaybeReadChildren(&pssh));
  return true;
}

IndependentAndDisposableSamples::IndependentAndDisposableSamples() = default;
IndependentAndDisposableSamples::IndependentAndDisposableSamples(
    const IndependentAndDisposableSamples& other) = default;
IndependentAndDisposableSamples::~IndependentAndDisposableSamples() = default;
FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; }

bool IndependentAndDisposableSamples::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());
  RCHECK(reader->version() == 0);
  RCHECK(reader->flags() == 0);

  size_t sample_count = reader->box_size() - reader->pos();
  RCHECK(sample_count <= sample_depends_on_.max_size());
  sample_depends_on_.resize(sample_count);
  for (size_t i = 0; i < sample_count; ++i) {
    uint8_t sample_info;
    RCHECK(reader->Read1(&sample_info));

    sample_depends_on_[i] =
        static_cast<SampleDependsOn>((sample_info >> 4) & 0x3);

    RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved);
  }

  return true;
}

SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
    size_t i) const {
  if (i >= sample_depends_on_.size())
    return kSampleDependsOnUnknown;

  return sample_depends_on_[i];
}

ID3v2Box::ID3v2Box() = default;
ID3v2Box::ID3v2Box(const ID3v2Box& other) = default;
ID3v2Box::~ID3v2Box() = default;
FourCC ID3v2Box::BoxType() const {
  return FOURCC_ID32;
}

bool ID3v2Box::Parse(BoxReader* reader) {
  // This is reading the ID32 box without regard for what's in it -- there will
  // likely be binary data in this vector. We don't care though since we're just
  // going to scan the memory without caring about sentinel values like \0.
  RCHECK(reader->ReadVec(&id3v2_data,
                         std::min(static_cast<size_t>(128),
                                  reader->buffer_size() - reader->pos())));
  return true;
}

MetadataBox::MetadataBox() : used_shaka_packager(false) {}
MetadataBox::MetadataBox(const MetadataBox& other) = default;
MetadataBox::~MetadataBox() = default;
FourCC MetadataBox::BoxType() const {
  return FOURCC_META;
}

bool MetadataBox::Parse(BoxReader* reader) {
  RCHECK(reader->ReadFullBoxHeader());

  // This is an optional box, so generate no errors.
  if (!reader->ScanChildren())
    return true;

  ID3v2Box id3v2;
  if (!reader->ReadChild(&id3v2))
    return true;

  constexpr char kShakaPackager[] = "shaka-packager";
  used_shaka_packager =
      base::StringPiece(reinterpret_cast<char*>(id3v2.id3v2_data.data()),
                        id3v2.id3v2_data.size())
          .find(kShakaPackager) != base::StringPiece::npos;
  return true;
}

}  // namespace mp4
}  // namespace media
