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

#include <stddef.h>

#include <limits>
#include <memory>
#include <utility>
#include <vector>

#include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/numerics/math_constants.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/encryption_pattern.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_switches.h"
#include "media/base/media_tracks.h"
#include "media/base/media_util.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/text_track_config.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_util.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/formats/mp4/box_reader.h"
#include "media/formats/mp4/es_descriptor.h"
#include "media/formats/mp4/rcheck.h"
#include "media/formats/mpeg/adts_constants.h"

namespace media {
namespace mp4 {

namespace {

const int kMaxEmptySampleLogs = 20;
const int kMaxInvalidConversionLogs = 20;
const int kMaxVideoKeyframeMismatchLogs = 10;

// Caller should be prepared to handle return of Unencrypted() in case of
// unsupported scheme.
EncryptionScheme GetEncryptionScheme(const ProtectionSchemeInfo& sinf) {
  if (!sinf.HasSupportedScheme())
    return Unencrypted();
  FourCC fourcc = sinf.type.type;
  EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
  EncryptionPattern pattern;
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
  bool uses_pattern_encryption = false;
#endif
  switch (fourcc) {
    case FOURCC_CENC:
      mode = EncryptionScheme::CIPHER_MODE_AES_CTR;
      break;
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
    case FOURCC_CBCS:
      mode = EncryptionScheme::CIPHER_MODE_AES_CBC;
      uses_pattern_encryption = true;
      break;
#endif
    default:
      NOTREACHED();
      break;
  }
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
  if (uses_pattern_encryption) {
    pattern = {sinf.info.track_encryption.default_crypt_byte_block,
               sinf.info.track_encryption.default_skip_byte_block};
  }
#endif
  return EncryptionScheme(mode, pattern);
}
}  // namespace

MP4StreamParser::MP4StreamParser(const std::set<int>& audio_object_types,
                                 bool has_sbr,
                                 bool has_flac)
    : state_(kWaitingForInit),
      moof_head_(0),
      mdat_tail_(0),
      highest_end_offset_(0),
      has_audio_(false),
      has_video_(false),
      audio_object_types_(audio_object_types),
      has_sbr_(has_sbr),
      has_flac_(has_flac),
      num_empty_samples_skipped_(0),
      num_invalid_conversions_(0),
      num_video_keyframe_mismatches_(0) {}

MP4StreamParser::~MP4StreamParser() = default;

void MP4StreamParser::Init(
    InitCB init_cb,
    const NewConfigCB& config_cb,
    const NewBuffersCB& new_buffers_cb,
    bool /* ignore_text_tracks */,
    const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
    const NewMediaSegmentCB& new_segment_cb,
    const EndMediaSegmentCB& end_of_segment_cb,
    MediaLog* media_log) {
  DCHECK_EQ(state_, kWaitingForInit);
  DCHECK(!init_cb_);
  DCHECK(init_cb);
  DCHECK(config_cb);
  DCHECK(new_buffers_cb);
  DCHECK(encrypted_media_init_data_cb);
  DCHECK(new_segment_cb);
  DCHECK(end_of_segment_cb);

  ChangeState(kParsingBoxes);
  init_cb_ = std::move(init_cb);
  config_cb_ = config_cb;
  new_buffers_cb_ = new_buffers_cb;
  encrypted_media_init_data_cb_ = encrypted_media_init_data_cb;
  new_segment_cb_ = new_segment_cb;
  end_of_segment_cb_ = end_of_segment_cb;
  media_log_ = media_log;
}

void MP4StreamParser::Reset() {
  queue_.Reset();
  runs_.reset();
  moof_head_ = 0;
  mdat_tail_ = 0;
}

void MP4StreamParser::Flush() {
  DCHECK_NE(state_, kWaitingForInit);
  Reset();
  ChangeState(kParsingBoxes);
}

bool MP4StreamParser::GetGenerateTimestampsFlag() const {
  return false;
}

bool MP4StreamParser::Parse(const uint8_t* buf, int size) {
  DCHECK_NE(state_, kWaitingForInit);

  if (state_ == kError)
    return false;

  queue_.Push(buf, size);

  BufferQueueMap buffers;

  // TODO(sandersd): Remove these bools. ParseResult replaced their purpose, but
  // this method needs to be refactored to complete that work.
  bool result = false;
  bool err = false;

  do {
    switch (state_) {
      case kWaitingForInit:
      case kError:
        NOTREACHED();
        return false;

      case kParsingBoxes: {
        ParseResult pr = ParseBox();
        result = pr == ParseResult::kOk;
        err = pr == ParseResult::kError;
        break;
      }

      case kWaitingForSampleData:
        result = HaveEnoughDataToEnqueueSamples();
        if (result)
          ChangeState(kEmittingSamples);
        break;

      case kEmittingSamples: {
        ParseResult pr = EnqueueSample(&buffers);
        result = pr == ParseResult::kOk;
        err = pr == ParseResult::kError;
        if (result) {
          int64_t max_clear = runs_->GetMaxClearOffset() + moof_head_;
          err = !ReadAndDiscardMDATsUntil(max_clear);
        }
        break;
      }
    }
  } while (result && !err);

  if (!err)
    err = !SendAndFlushSamples(&buffers);

  if (err) {
    DLOG(ERROR) << "Error while parsing MP4";
    moov_.reset();
    Reset();
    ChangeState(kError);
    return false;
  }

  return true;
}

ParseResult MP4StreamParser::ParseBox() {
  const uint8_t* buf;
  int size;
  queue_.Peek(&buf, &size);
  if (!size)
    return ParseResult::kNeedMoreData;

  std::unique_ptr<BoxReader> reader;
  ParseResult result =
      BoxReader::ReadTopLevelBox(buf, size, media_log_, &reader);
  if (result != ParseResult::kOk)
    return result;

  DCHECK(reader);
  if (reader->type() == FOURCC_MOOV) {
    if (!ParseMoov(reader.get()))
      return ParseResult::kError;
  } else if (reader->type() == FOURCC_MOOF) {
    moof_head_ = queue_.head();
    if (!ParseMoof(reader.get()))
      return ParseResult::kError;

    // Set up first mdat offset for ReadMDATsUntil().
    mdat_tail_ = queue_.head() + reader->box_size();

    // Return early to avoid evicting 'moof' data from queue. Auxiliary info may
    // be located anywhere in the file, including inside the 'moof' itself.
    // (Since 'default-base-is-moof' is mandated, no data references can come
    // before the head of the 'moof', so keeping this box around is sufficient.)
    return ParseResult::kOk;
  } else {
    // TODO(wolenetz,chcunningham): Enforce more strict adherence to MSE byte
    // stream spec for ftyp and styp. See http://crbug.com/504514.
    DVLOG(2) << "Skipping unrecognized top-level box: "
             << FourCCToString(reader->type());
  }

  queue_.Pop(reader->box_size());
  return ParseResult::kOk;
}

static inline double FixedToFloatingPoint(const int32_t& i) {
  return static_cast<double>(i >> 16);
}

VideoRotation MP4StreamParser::CalculateRotation(const TrackHeader& track,
                                                 const MovieHeader& movie) {
  static_assert(kDisplayMatrixDimension == 9, "Display matrix must be 3x3");
  // 3x3 matrix: [ a b c ]
  //             [ d e f ]
  //             [ x y z ]
  int32_t rotation_matrix[kDisplayMatrixDimension] = {0};

  // Shift values for fixed point multiplications.
  const int32_t shifts[kDisplayMatrixHeight] = {16, 16, 30};

  // Matrix multiplication for
  // track.display_matrix * movie.display_matrix
  // with special consideration taken that entries a-f are 16.16 fixed point
  // decimals and x-z are 2.30 fixed point decimals.
  for (int i = 0; i < kDisplayMatrixWidth; i++) {
    for (int j = 0; j < kDisplayMatrixHeight; j++) {
      for (int e = 0; e < kDisplayMatrixHeight; e++) {
        rotation_matrix[i * kDisplayMatrixHeight + j] +=
            ((int64_t)track.display_matrix[i * kDisplayMatrixHeight + e] *
             movie.display_matrix[e * kDisplayMatrixHeight + j]) >>
            shifts[e];
      }
    }
  }

  // Rotation by angle Θ is represented in the matrix as:
  // [ cos(Θ), -sin(Θ), ...]
  // [ sin(Θ),  cos(Θ), ...]
  // [ ...,     ...,     1 ]
  // But we only need cos(Θ) for the angle and sin(Θ) for the quadrant.
  double angle = acos(FixedToFloatingPoint(rotation_matrix[0]))
    * 180 / base::kPiDouble;

  if (angle < 0)
    angle += 360;

  if (angle >= 360)
    angle -= 360;

  // 16 bits of fixed point decimal is enough to give 6 decimals of precision
  // to cos(Θ). A delta of ±0.000001 causes acos(cos(Θ)) to differ by a minimum
  // of 0.0002, which is why we only need to check that the angle is only
  // accurate to within four decimal places. This is preferred to checking for
  // a more precise accuracy, as the 'double' type is architecture dependant and
  // ther may variance in floating point errors.
  if (abs(angle - 0) < 1e-4)
    return VIDEO_ROTATION_0;

  if (abs(angle - 180) < 1e-4)
    return VIDEO_ROTATION_180;

  if (abs(angle - 90) < 1e-4) {
    bool quadrant = asin(FixedToFloatingPoint(rotation_matrix[3])) < 0;
    return quadrant ? VIDEO_ROTATION_90 : VIDEO_ROTATION_270;
  }

  // TODO(tmathmeyer): Record this event and the faulty matrix somewhere.
  return VIDEO_ROTATION_0;
}

bool MP4StreamParser::ParseMoov(BoxReader* reader) {
  moov_.reset(new Movie);
  RCHECK(moov_->Parse(reader));
  runs_.reset();
  audio_track_ids_.clear();
  video_track_ids_.clear();

  has_audio_ = false;
  has_video_ = false;

  std::unique_ptr<MediaTracks> media_tracks(new MediaTracks());
  AudioDecoderConfig audio_config;
  VideoDecoderConfig video_config;
  int detected_audio_track_count = 0;
  int detected_video_track_count = 0;
  int detected_text_track_count = 0;

  for (std::vector<Track>::const_iterator track = moov_->tracks.begin();
       track != moov_->tracks.end(); ++track) {
    const SampleDescription& samp_descr =
        track->media.information.sample_table.description;

    // TODO(wolenetz): When codec reconfigurations are supported, detect and
    // send a codec reconfiguration for fragments using a sample description
    // index different from the previous one. See https://crbug.com/748250.
    size_t desc_idx = 0;
    for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
      const TrackExtends& trex = moov_->extends.tracks[t];
      if (trex.track_id == track->header.track_id) {
        desc_idx = trex.default_sample_description_index;
        break;
      }
    }
    RCHECK(desc_idx > 0);
    desc_idx -= 1;  // BMFF descriptor index is one-based

    if (track->media.handler.type == kAudio) {
      detected_audio_track_count++;

      RCHECK(!samp_descr.audio_entries.empty());

      // It is not uncommon to find otherwise-valid files with incorrect sample
      // description indices, so we fail gracefully in that case.
      if (desc_idx >= samp_descr.audio_entries.size())
        desc_idx = 0;
      const AudioSampleEntry& entry = samp_descr.audio_entries[desc_idx];

      // For encrypted audio streams entry.format is FOURCC_ENCA and actual
      // format is in entry.sinf.format.format.
      FourCC audio_format = (entry.format == FOURCC_ENCA)
                                ? entry.sinf.format.format
                                : entry.format;

      if (audio_format != FOURCC_OPUS && audio_format != FOURCC_FLAC &&
#if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
          audio_format != FOURCC_AC3 && audio_format != FOURCC_EAC3 &&
#endif
#if BUILDFLAG(ENABLE_MPEG_H_AUDIO_DEMUXING)
          audio_format != FOURCC_MHM1 &&
#endif
          audio_format != FOURCC_MP4A) {
        MEDIA_LOG(ERROR, media_log_)
            << "Unsupported audio format 0x" << std::hex << entry.format
            << " in stsd box.";
        return false;
      }

      AudioCodec codec = kUnknownAudioCodec;
      ChannelLayout channel_layout = CHANNEL_LAYOUT_NONE;
      int sample_per_second = 0;
      int codec_delay_in_frames = 0;
      base::TimeDelta seek_preroll;
      std::vector<uint8_t> extra_data;
      if (audio_format == FOURCC_OPUS) {
        codec = kCodecOpus;
        channel_layout = GuessChannelLayout(entry.dops.channel_count);
        sample_per_second = entry.dops.sample_rate;
        codec_delay_in_frames = entry.dops.codec_delay_in_frames;
        seek_preroll = entry.dops.seek_preroll;
        extra_data = entry.dops.extradata;
      } else if (audio_format == FOURCC_FLAC) {
        // FLAC-in-ISOBMFF does not use object type indication. |audio_format|
        // is sufficient for identifying FLAC codec.
        if (!has_flac_) {
          MEDIA_LOG(ERROR, media_log_) << "FLAC audio stream detected in MP4, "
                                          "mismatching what is specified in "
                                          "the mimetype.";
          return false;
        }

        codec = kCodecFLAC;
        channel_layout = GuessChannelLayout(entry.channelcount);
        sample_per_second = entry.samplerate;
        extra_data = entry.dfla.stream_info;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#if BUILDFLAG(ENABLE_MPEG_H_AUDIO_DEMUXING)
      } else if (audio_format == FOURCC_MHM1) {
        codec = kCodecMpegHAudio;
        channel_layout = CHANNEL_LAYOUT_BITSTREAM;
        sample_per_second = entry.samplerate;
        extra_data = entry.dfla.stream_info;
#endif
      } else {
        uint8_t audio_type = entry.esds.object_type;
#if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
        if (audio_type == kForbidden) {
          if (audio_format == FOURCC_AC3)
            audio_type = kAC3;
          if (audio_format == FOURCC_EAC3)
            audio_type = kEAC3;
        }
#endif
        DVLOG(1) << "audio_type 0x" << std::hex << static_cast<int>(audio_type);
        if (audio_object_types_.find(audio_type) == audio_object_types_.end()) {
          MEDIA_LOG(ERROR, media_log_)
              << "audio object type 0x" << std::hex
              << static_cast<int>(audio_type)
              << " does not match what is specified in the mimetype.";
          return false;
        }

        // Check if it is MPEG4 AAC defined in ISO 14496 Part 3 or
        // supported MPEG2 AAC varients.
        if (ESDescriptor::IsAAC(audio_type)) {
          const AAC& aac = entry.esds.aac;
          codec = kCodecAAC;
          channel_layout = aac.GetChannelLayout(has_sbr_);
          sample_per_second = aac.GetOutputSamplesPerSecond(has_sbr_);
#if defined(OS_ANDROID)
          extra_data = aac.codec_specific_data();
#endif
#if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
        } else if (audio_type == kAC3) {
          codec = kCodecAC3;
          channel_layout = GuessChannelLayout(entry.channelcount);
          sample_per_second = entry.samplerate;
        } else if (audio_type == kEAC3) {
          codec = kCodecEAC3;
          channel_layout = GuessChannelLayout(entry.channelcount);
          sample_per_second = entry.samplerate;
#endif
        } else {
          MEDIA_LOG(ERROR, media_log_)
              << "Unsupported audio object type 0x" << std::hex
              << static_cast<int>(audio_type) << " in esds.";
          return false;
        }
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
      }

      SampleFormat sample_format;
      if (entry.samplesize == 8) {
        sample_format = kSampleFormatU8;
      } else if (entry.samplesize == 16) {
        sample_format = kSampleFormatS16;
      } else if (entry.samplesize == 24) {
        sample_format = kSampleFormatS24;
      } else if (entry.samplesize == 32) {
        sample_format = kSampleFormatS32;
      } else {
        LOG(ERROR) << "Unsupported sample size.";
        return false;
      }

      uint32_t audio_track_id = track->header.track_id;
      if (audio_track_ids_.find(audio_track_id) != audio_track_ids_.end()) {
        MEDIA_LOG(ERROR, media_log_)
            << "Audio track with track_id=" << audio_track_id
            << " already present.";
        return false;
      }
      bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted;
      EncryptionScheme scheme = Unencrypted();
      if (is_track_encrypted) {
        scheme = GetEncryptionScheme(entry.sinf);
        if (!scheme.is_encrypted())
          return false;
      }
      audio_config.Initialize(codec, sample_format, channel_layout,
                              sample_per_second, extra_data, scheme,
                              seek_preroll, codec_delay_in_frames);
      if (codec == kCodecAAC)
        audio_config.disable_discard_decoder_delay();

      DVLOG(1) << "audio_track_id=" << audio_track_id
               << " config=" << audio_config.AsHumanReadableString();
      if (!audio_config.IsValidConfig()) {
        MEDIA_LOG(ERROR, media_log_) << "Invalid audio decoder config: "
                                     << audio_config.AsHumanReadableString();
        return false;
      }
      has_audio_ = true;
      audio_track_ids_.insert(audio_track_id);
      const char* track_kind = (audio_track_ids_.size() == 1 ? "main" : "");
      media_tracks->AddAudioTrack(audio_config, audio_track_id, track_kind,
                                  track->media.handler.name,
                                  track->media.header.language());
      continue;
    }

    if (track->media.handler.type == kVideo) {
      detected_video_track_count++;

      RCHECK(!samp_descr.video_entries.empty());
      if (desc_idx >= samp_descr.video_entries.size())
        desc_idx = 0;
      const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx];

      if (!entry.IsFormatValid()) {
        MEDIA_LOG(ERROR, media_log_) << "Unsupported video format 0x"
                                     << std::hex << entry.format
                                     << " in stsd box.";
        return false;
      }

      // TODO(strobe): Recover correct crop box
      gfx::Size coded_size(entry.width, entry.height);
      gfx::Rect visible_rect(coded_size);

      // If PASP is available, use the coded size and PASP to calculate the
      // natural size. Otherwise, use the size in track header for natural size.
      gfx::Size natural_size(visible_rect.size());
      if (entry.pixel_aspect.h_spacing != 1 ||
          entry.pixel_aspect.v_spacing != 1) {
        natural_size =
            GetNaturalSize(visible_rect.size(), entry.pixel_aspect.h_spacing,
                           entry.pixel_aspect.v_spacing);
      } else if (track->header.width && track->header.height) {
        natural_size =
            gfx::Size(track->header.width, track->header.height);
      }

      uint32_t video_track_id = track->header.track_id;
      if (video_track_ids_.find(video_track_id) != video_track_ids_.end()) {
        MEDIA_LOG(ERROR, media_log_)
            << "Video track with track_id=" << video_track_id
            << " already present.";
        return false;
      }
      bool is_track_encrypted = entry.sinf.info.track_encryption.is_encrypted;
      EncryptionScheme scheme = Unencrypted();
      if (is_track_encrypted) {
        scheme = GetEncryptionScheme(entry.sinf);
        if (!scheme.is_encrypted())
          return false;
      }
      video_config.Initialize(entry.video_codec, entry.video_codec_profile,
                              PIXEL_FORMAT_I420, VideoColorSpace::REC709(),
                              CalculateRotation(track->header, moov_->header),
                              coded_size, visible_rect, natural_size,
                              // No decoder-specific buffer needed for AVC;
                              // SPS/PPS are embedded in the video stream
                              EmptyExtraData(), scheme);
      DVLOG(1) << "video_track_id=" << video_track_id
               << " config=" << video_config.AsHumanReadableString();
      if (!video_config.IsValidConfig()) {
        MEDIA_LOG(ERROR, media_log_) << "Invalid video decoder config: "
                                     << video_config.AsHumanReadableString();
        return false;
      }
      has_video_ = true;
      video_track_ids_.insert(video_track_id);
      const char* track_kind = (video_track_ids_.size() == 1 ? "main" : "");
      media_tracks->AddVideoTrack(video_config, video_track_id, track_kind,
                                  track->media.handler.name,
                                  track->media.header.language());
      continue;
    }

    // TODO(wolenetz): Investigate support in MSE and Chrome MSE for CEA 608/708
    // embedded caption data in video track. At time of init segment parsing, we
    // don't have this data (unless maybe by SourceBuffer's mimetype).
    // See https://crbug.com/597073
    if (track->media.handler.type == kText)
      detected_text_track_count++;
  }

  if (!moov_->pssh.empty())
    OnEncryptedMediaInitData(moov_->pssh);

  RCHECK(config_cb_.Run(std::move(media_tracks), TextTrackConfigMap()));

  StreamParser::InitParameters params(kInfiniteDuration);
  if (moov_->extends.header.fragment_duration > 0) {
    params.duration = TimeDeltaFromRational(
        moov_->extends.header.fragment_duration, moov_->header.timescale);
    if (params.duration == kNoTimestamp) {
      MEDIA_LOG(ERROR, media_log_) << "Fragment duration exceeds representable "
                                   << "limit";
      return false;
    }
    params.liveness = DemuxerStream::LIVENESS_RECORDED;
  } else if (moov_->header.duration > 0 &&
             ((moov_->header.version == 0 &&
               moov_->header.duration !=
                   std::numeric_limits<uint32_t>::max()) ||
              (moov_->header.version == 1 &&
               moov_->header.duration !=
                   std::numeric_limits<uint64_t>::max()))) {
    // In ISO/IEC 14496-12:2012, 8.2.2.3: "If the duration cannot be determined
    // then duration is set to all 1s."
    // The duration field is either 32-bit or 64-bit depending on the version in
    // MovieHeaderBox. We interpret not 0 and not all 1's here as "known
    // duration".
    params.duration =
        TimeDeltaFromRational(moov_->header.duration, moov_->header.timescale);
    if (params.duration == kNoTimestamp) {
      MEDIA_LOG(ERROR, media_log_) << "Movie duration exceeds representable "
                                   << "limit";
      return false;
    }
    params.liveness = DemuxerStream::LIVENESS_RECORDED;
  } else {
    // In ISO/IEC 14496-12:2005(E), 8.30.2: ".. If an MP4 file is created in
    // real-time, such as used in live streaming, it is not likely that the
    // fragment_duration is known in advance and this (mehd) box may be
    // omitted."

    // We have an unknown duration (neither any mvex fragment_duration nor moov
    // duration value indicated a known duration, above.)

    // TODO(wolenetz): Investigate gating liveness detection on timeline_offset
    // when it's populated. See http://crbug.com/312699
    params.liveness = DemuxerStream::LIVENESS_LIVE;
  }

  DVLOG(1) << "liveness: " << params.liveness;

  if (init_cb_) {
    params.detected_audio_track_count = detected_audio_track_count;
    params.detected_video_track_count = detected_video_track_count;
    params.detected_text_track_count = detected_text_track_count;
    std::move(init_cb_).Run(params);
  }

  return true;
}

bool MP4StreamParser::ParseMoof(BoxReader* reader) {
  RCHECK(moov_.get());  // Must already have initialization segment
  MovieFragment moof;
  RCHECK(moof.Parse(reader));
  if (!runs_)
    runs_.reset(new TrackRunIterator(moov_.get(), media_log_));
  RCHECK(runs_->Init(moof));
  RCHECK(ComputeHighestEndOffset(moof));

  if (!moof.pssh.empty())
    OnEncryptedMediaInitData(moof.pssh);

  new_segment_cb_.Run();
  ChangeState(kWaitingForSampleData);
  return true;
}

void MP4StreamParser::OnEncryptedMediaInitData(
    const std::vector<ProtectionSystemSpecificHeader>& headers) {
  // TODO(strobe): ensure that the value of init_data (all PSSH headers
  // concatenated in arbitrary order) matches the EME spec.
  // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=17673.
  size_t total_size = 0;
  for (size_t i = 0; i < headers.size(); i++)
    total_size += headers[i].raw_box.size();

  std::vector<uint8_t> init_data(total_size);
  size_t pos = 0;
  for (size_t i = 0; i < headers.size(); i++) {
    memcpy(&init_data[pos], &headers[i].raw_box[0],
           headers[i].raw_box.size());
    pos += headers[i].raw_box.size();
  }
  encrypted_media_init_data_cb_.Run(EmeInitDataType::CENC, init_data);
}

#if BUILDFLAG(USE_PROPRIETARY_CODECS)
bool MP4StreamParser::PrepareAACBuffer(
    const AAC& aac_config,
    std::vector<uint8_t>* frame_buf,
    std::vector<SubsampleEntry>* subsamples) const {
  // Append an ADTS header to every audio sample.
  RCHECK(aac_config.ConvertEsdsToADTS(frame_buf));

  // As above, adjust subsample information to account for the headers. AAC is
  // not required to use subsample encryption, so we may need to add an entry.
  if (subsamples->empty()) {
    subsamples->push_back(SubsampleEntry(
        kADTSHeaderMinSize, frame_buf->size() - kADTSHeaderMinSize));
  } else {
    (*subsamples)[0].clear_bytes += kADTSHeaderMinSize;
  }
  return true;
}
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)

ParseResult MP4StreamParser::EnqueueSample(BufferQueueMap* buffers) {
  DCHECK_EQ(state_, kEmittingSamples);

  if (!runs_->IsRunValid()) {
    // Flush any buffers we've gotten in this chunk so that buffers don't
    // cross |new_segment_cb_| calls
    if (!SendAndFlushSamples(buffers))
      return ParseResult::kError;

    // Remain in kEmittingSamples state, discarding data, until the end of
    // the current 'mdat' box has been appended to the queue.
    // TODO(sandersd): As I understand it, this Trim() will always succeed,
    // since |mdat_tail_| is never outside of the queue. It's also plausible
    // that this Trim() is always a no-op, but perhaps if all runs are empty
    // this still does something?
    if (!queue_.Trim(mdat_tail_))
      return ParseResult::kNeedMoreData;

    ChangeState(kParsingBoxes);
    end_of_segment_cb_.Run();
    return ParseResult::kOk;
  }

  if (!runs_->IsSampleValid()) {
    if (!runs_->AdvanceRun())
      return ParseResult::kError;
    return ParseResult::kOk;
  }

  const uint8_t* buf;
  int buf_size;
  queue_.Peek(&buf, &buf_size);
  if (!buf_size)
    return ParseResult::kNeedMoreData;

  bool audio =
      audio_track_ids_.find(runs_->track_id()) != audio_track_ids_.end();
  bool video =
      video_track_ids_.find(runs_->track_id()) != video_track_ids_.end();

  // Skip this entire track if it's not one we're interested in
  if (!audio && !video) {
    if (!runs_->AdvanceRun())
      return ParseResult::kError;
    return ParseResult::kOk;
  }

  // Attempt to cache the auxiliary information first. Aux info is usually
  // placed in a contiguous block before the sample data, rather than being
  // interleaved. If we didn't cache it, this would require that we retain the
  // start of the segment buffer while reading samples. Aux info is typically
  // quite small compared to sample data, so this pattern is useful on
  // memory-constrained devices where the source buffer consumes a substantial
  // portion of the total system memory.
  if (runs_->AuxInfoNeedsToBeCached()) {
    queue_.PeekAt(runs_->aux_info_offset() + moof_head_, &buf, &buf_size);
    if (buf_size < runs_->aux_info_size())
      return ParseResult::kNeedMoreData;
    if (!runs_->CacheAuxInfo(buf, buf_size))
      return ParseResult::kError;
    return ParseResult::kOk;
  }

  queue_.PeekAt(runs_->sample_offset() + moof_head_, &buf, &buf_size);

  if (runs_->sample_size() >
      static_cast<uint32_t>(std::numeric_limits<int>::max())) {
    MEDIA_LOG(ERROR, media_log_) << "Sample size is too large";
    return ParseResult::kError;
  }

  int sample_size = base::checked_cast<int>(runs_->sample_size());

  if (buf_size < sample_size)
    return ParseResult::kNeedMoreData;

  if (sample_size == 0) {
    // Generally not expected, but spec allows it. Code below this block assumes
    // the current sample is not empty.
    LIMITED_MEDIA_LOG(DEBUG, media_log_, num_empty_samples_skipped_,
                      kMaxEmptySampleLogs)
        << "Skipping 'trun' sample with size of 0.";
    if (!runs_->AdvanceSample())
      return ParseResult::kError;
    return ParseResult::kOk;
  }

  std::unique_ptr<DecryptConfig> decrypt_config;
  std::vector<SubsampleEntry> subsamples;
  if (runs_->is_encrypted()) {
    decrypt_config = runs_->GetDecryptConfig();
    if (!decrypt_config)
      return ParseResult::kError;
    subsamples = decrypt_config->subsamples();
  }

  // This may change if analysis results indicate runs_->is_keyframe() is
  // opposite of what the coded frame contains.
  bool is_keyframe = runs_->is_keyframe();

  std::vector<uint8_t> frame_buf(buf, buf + sample_size);
  if (video) {
    if (runs_->video_description().video_codec == kCodecH264 ||
        runs_->video_description().video_codec == kCodecHEVC ||
        runs_->video_description().video_codec == kCodecDolbyVision) {
      DCHECK(runs_->video_description().frame_bitstream_converter);
      BitstreamConverter::AnalysisResult analysis;
      if (!runs_->video_description()
               .frame_bitstream_converter->ConvertAndAnalyzeFrame(
                   &frame_buf, is_keyframe, &subsamples, &analysis)) {
        MEDIA_LOG(ERROR, media_log_)
            << "Failed to prepare video sample for decode";
        return ParseResult::kError;
      }

      // If conformance analysis was not actually performed, assume the frame is
      // conformant.  If it was performed and found to be non-conformant, log
      // it.
      if (!analysis.is_conformant.value_or(true)) {
        LIMITED_MEDIA_LOG(DEBUG, media_log_, num_invalid_conversions_,
                          kMaxInvalidConversionLogs)
            << "Prepared video sample is not conformant";
      }

      // Use |analysis.is_keyframe|, if it was actually determined, for logging
      // if the analysis mismatches the container's keyframe metadata for
      // |frame_buf|.
      if (analysis.is_keyframe.has_value() &&
          is_keyframe != analysis.is_keyframe.value()) {
        LIMITED_MEDIA_LOG(DEBUG, media_log_, num_video_keyframe_mismatches_,
                          kMaxVideoKeyframeMismatchLogs)
            << "ISO-BMFF container metadata for video frame indicates that the "
               "frame is "
            << (is_keyframe ? "" : "not ")
            << "a keyframe, but the video frame contents indicate the "
               "opposite.";
        // As of September 2018, it appears that all of Edge, Firefox, Safari
        // work with content that marks non-avc-keyframes as a keyframe in the
        // container. Encoders/muxers/old streams still exist that produce
        // all-keyframe mp4 video tracks, though many of the coded frames are
        // not keyframes (likely workaround due to the impact on low-latency
        // live streams until https://crbug.com/229412 was fixed).  We'll trust
        // the AVC frame's keyframe-ness over the mp4 container's metadata if
        // they mismatch. If other out-of-order codecs in mp4 (e.g. HEVC, DV)
        // implement keyframe analysis in their frame_bitstream_converter, we'll
        // similarly trust that analysis instead of the mp4.
        // We'll only use the analysis to override the MP4 keyframeness if
        // |media::kMseBufferByPts| is enabled.
        if (base::FeatureList::IsEnabled(kMseBufferByPts)) {
          is_keyframe = analysis.is_keyframe.value();
        }
      }
    }
  }

  if (audio) {
    if (ESDescriptor::IsAAC(runs_->audio_description().esds.object_type)) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
      if (!PrepareAACBuffer(runs_->audio_description().esds.aac, &frame_buf,
                            &subsamples)) {
        MEDIA_LOG(ERROR, media_log_)
            << "Failed to prepare AAC sample for decode";
        return ParseResult::kError;
      }
#else
      return ParseResult::kError;
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
    }
  }

  if (decrypt_config) {
    if (!subsamples.empty()) {
      // Create a new config with the updated subsamples.
      decrypt_config.reset(
          new DecryptConfig(decrypt_config->encryption_mode(),
                            decrypt_config->key_id(), decrypt_config->iv(),
                            subsamples, decrypt_config->encryption_pattern()));
    }
    // else, use the existing config.
  }

  StreamParserBuffer::Type buffer_type = audio ? DemuxerStream::AUDIO :
      DemuxerStream::VIDEO;

  scoped_refptr<StreamParserBuffer> stream_buf =
      StreamParserBuffer::CopyFrom(&frame_buf[0], frame_buf.size(), is_keyframe,
                                   buffer_type, runs_->track_id());

  if (decrypt_config)
    stream_buf->set_decrypt_config(std::move(decrypt_config));

  if (runs_->duration() != kNoTimestamp) {
    stream_buf->set_duration(runs_->duration());
  } else {
    MEDIA_LOG(ERROR, media_log_) << "Frame duration exceeds representable "
                                 << "limit";
    return ParseResult::kError;
  }

  if (runs_->cts() != kNoTimestamp) {
    stream_buf->set_timestamp(runs_->cts());
  } else {
    MEDIA_LOG(ERROR, media_log_) << "Frame PTS exceeds representable limit";
    return ParseResult::kError;
  }

  if (runs_->dts() != kNoDecodeTimestamp()) {
    stream_buf->SetDecodeTimestamp(runs_->dts());
  } else {
    MEDIA_LOG(ERROR, media_log_) << "Frame DTS exceeds representable limit";
    return ParseResult::kError;
  }

  DVLOG(3) << "Emit " << (audio ? "audio" : "video") << " frame: "
           << " track_id=" << runs_->track_id() << ", key=" << is_keyframe
           << ", dur=" << runs_->duration().InMilliseconds()
           << ", dts=" << runs_->dts().InMilliseconds()
           << ", cts=" << runs_->cts().InMilliseconds()
           << ", size=" << sample_size;

  (*buffers)[runs_->track_id()].push_back(stream_buf);
  if (!runs_->AdvanceSample())
    return ParseResult::kError;
  return ParseResult::kOk;
}

bool MP4StreamParser::SendAndFlushSamples(BufferQueueMap* buffers) {
  if (buffers->empty())
    return true;
  bool success = new_buffers_cb_.Run(*buffers);
  buffers->clear();
  return success;
}

bool MP4StreamParser::ReadAndDiscardMDATsUntil(int64_t max_clear_offset) {
  ParseResult result = ParseResult::kOk;
  int64_t upper_bound = std::min(max_clear_offset, queue_.tail());
  while (mdat_tail_ < upper_bound) {
    const uint8_t* buf = NULL;
    int size = 0;
    queue_.PeekAt(mdat_tail_, &buf, &size);

    FourCC type;
    size_t box_sz;
    result = BoxReader::StartTopLevelBox(buf, size, media_log_, &type, &box_sz);
    if (result != ParseResult::kOk)
      break;

    if (type != FOURCC_MDAT) {
      MEDIA_LOG(DEBUG, media_log_)
          << "Unexpected box type while parsing MDATs: "
          << FourCCToString(type);
    }
    // TODO(chcunningham): Fix mdat_tail_ and ByteQueue classes to use size_t.
    // TODO(sandersd): The whole |mdat_tail_| mechanism appears to be pointless
    // because StartTopLevelBox() only succeeds for complete boxes. Either
    // remove |mdat_tail_| throughout this class or implement the ability to
    // discard partial mdats.
    mdat_tail_ += base::checked_cast<int64_t>(box_sz);
  }
  queue_.Trim(std::min(mdat_tail_, upper_bound));
  return result != ParseResult::kError;
}

void MP4StreamParser::ChangeState(State new_state) {
  DVLOG(2) << "Changing state: " << new_state;
  state_ = new_state;
}

bool MP4StreamParser::HaveEnoughDataToEnqueueSamples() {
  DCHECK_EQ(state_, kWaitingForSampleData);
  // For muxed content, make sure we have data up to |highest_end_offset_|
  // so we can ensure proper enqueuing behavior. Otherwise assume we have enough
  // data and allow per sample offset checks to meter sample enqueuing.
  // TODO(acolwell): Fix trun box handling so we don't have to special case
  // muxed content.
  return !(has_audio_ && has_video_ &&
           queue_.tail() < highest_end_offset_ + moof_head_);
}

bool MP4StreamParser::ComputeHighestEndOffset(const MovieFragment& moof) {
  highest_end_offset_ = 0;

  TrackRunIterator runs(moov_.get(), media_log_);
  RCHECK(runs.Init(moof));

  while (runs.IsRunValid()) {
    int64_t aux_info_end_offset = runs.aux_info_offset() + runs.aux_info_size();
    if (aux_info_end_offset > highest_end_offset_)
      highest_end_offset_ = aux_info_end_offset;

    while (runs.IsSampleValid()) {
      int64_t sample_end_offset = runs.sample_offset() + runs.sample_size();
      if (sample_end_offset > highest_end_offset_)
        highest_end_offset_ = sample_end_offset;
      if (!runs.AdvanceSample())
        return false;
    }
    if (!runs.AdvanceRun())
      return false;
  }

  return true;
}

}  // namespace mp4
}  // namespace media
