// Copyright 2016 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 "cobalt/media/filters/source_buffer_state.h"

#include <algorithm>
#include <memory>
#include <set>

#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "cobalt/media/base/media_track.h"
#include "cobalt/media/base/media_tracks.h"
#include "cobalt/media/base/mime_util.h"
#include "cobalt/media/filters/chunk_demuxer.h"
#include "cobalt/media/filters/frame_processor.h"
#include "cobalt/media/filters/source_buffer_stream.h"

namespace cobalt {
namespace media {

enum {
  // Limits the number of MEDIA_LOG() calls warning the user that a muxed stream
  // media segment is missing a block from at least one of the audio or video
  // tracks.
  kMaxMissingTrackInSegmentLogs = 10,
};

namespace {

TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) {
  return queue.back()->timestamp() + queue.back()->duration();
}

// Check the input |text_configs| and |bytestream_ids| and return false if
// duplicate track ids are detected.
bool CheckBytestreamTrackIds(
    const MediaTracks& tracks,
    const StreamParser::TextTrackConfigMap& text_configs) {
  std::set<StreamParser::TrackId> bytestream_ids;
  for (size_t i = 0; i < tracks.tracks().size(); ++i) {
    const StreamParser::TrackId& track_id =
        tracks.tracks()[i]->bytestream_track_id();
    if (bytestream_ids.find(track_id) != bytestream_ids.end()) {
      return false;
    }
    bytestream_ids.insert(track_id);
  }
  for (StreamParser::TextTrackConfigMap::const_iterator iter =
           text_configs.begin();
       iter != text_configs.end(); ++iter) {
    const StreamParser::TrackId& track_id = iter->first;
    if (bytestream_ids.find(track_id) != bytestream_ids.end()) {
      return false;
    }
    bytestream_ids.insert(track_id);
  }
  return true;
}

}  // namespace

// List of time ranges for each SourceBuffer.
// static
Ranges<TimeDelta> SourceBufferState::ComputeRangesIntersection(
    const RangesList& active_ranges, bool ended) {
  // TODO(servolk): Perhaps this can be removed in favor of blink implementation
  // (MediaSource::buffered)? Currently this is only used on Android and for
  // updating DemuxerHost's buffered ranges during AppendData() as well as
  // SourceBuffer.buffered property implementation.
  // Implementation of HTMLMediaElement.buffered algorithm in MSE spec.
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#dom-htmlmediaelement.buffered

  // Step 1: If activeSourceBuffers.length equals 0 then return an empty
  //  TimeRanges object and abort these steps.
  if (active_ranges.empty()) return Ranges<TimeDelta>();

  // Step 2: Let active ranges be the ranges returned by buffered for each
  //  SourceBuffer object in activeSourceBuffers.
  // Step 3: Let highest end time be the largest range end time in the active
  //  ranges.
  TimeDelta highest_end_time;
  for (size_t i = 0; i < active_ranges.size(); ++i) {
    if (!active_ranges[i].size()) continue;

    highest_end_time = std::max(
        highest_end_time, active_ranges[i].end(active_ranges[i].size() - 1));
  }

  // Step 4: Let intersection ranges equal a TimeRange object containing a
  //  single range from 0 to highest end time.
  Ranges<TimeDelta> intersection_ranges;
  intersection_ranges.Add(TimeDelta(), highest_end_time);

  // Step 5: For each SourceBuffer object in activeSourceBuffers run the
  //  following steps:
  for (size_t i = 0; i < active_ranges.size(); ++i) {
    // Step 5.1: Let source ranges equal the ranges returned by the buffered
    //  attribute on the current SourceBuffer.
    Ranges<TimeDelta> source_ranges = active_ranges[i];

    // Step 5.2: If readyState is "ended", then set the end time on the last
    //  range in source ranges to highest end time.
    if (ended && source_ranges.size()) {
      source_ranges.Add(source_ranges.start(source_ranges.size() - 1),
                        highest_end_time);
    }

    // Step 5.3: Let new intersection ranges equal the intersection between
    // the intersection ranges and the source ranges.
    // Step 5.4: Replace the ranges in intersection ranges with the new
    // intersection ranges.
    intersection_ranges = intersection_ranges.IntersectionWith(source_ranges);
  }

  return intersection_ranges;
}

SourceBufferState::SourceBufferState(
    std::unique_ptr<StreamParser> stream_parser,
    std::unique_ptr<FrameProcessor> frame_processor,
    const CreateDemuxerStreamCB& create_demuxer_stream_cb,
    const scoped_refptr<MediaLog>& media_log,
    DecoderBuffer::Allocator* buffer_allocator)
    : num_missing_track_logs_(0),
      create_demuxer_stream_cb_(create_demuxer_stream_cb),
      timestamp_offset_during_append_(NULL),
      parsing_media_segment_(false),
      stream_parser_(stream_parser.release()),
      frame_processor_(frame_processor.release()),
      media_log_(media_log),
      state_(UNINITIALIZED),
      append_in_progress_(false),
      first_init_segment_received_(false),
      auto_update_timestamp_offset_(false),
      buffer_allocator_(buffer_allocator) {
  DCHECK(!create_demuxer_stream_cb_.is_null());
  DCHECK(frame_processor_);
}

SourceBufferState::~SourceBufferState() { Shutdown(); }

void SourceBufferState::Init(
    const StreamParser::InitCB& init_cb, const std::string& expected_codecs,
    const StreamParser::EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
    const NewTextTrackCB& new_text_track_cb) {
  DCHECK_EQ(state_, UNINITIALIZED);
  new_text_track_cb_ = new_text_track_cb;
  init_cb_ = init_cb;

  std::vector<std::string> expected_codecs_parsed;
  ParseCodecString(expected_codecs, &expected_codecs_parsed, false);

  std::vector<AudioCodec> expected_acodecs;
  std::vector<VideoCodec> expected_vcodecs;
  for (size_t i = 0; i < expected_codecs_parsed.size(); ++i) {
    AudioCodec acodec = StringToAudioCodec(expected_codecs_parsed[i]);
    if (acodec != kUnknownAudioCodec) {
      expected_audio_codecs_.push_back(acodec);
      continue;
    }
    VideoCodec vcodec = StringToVideoCodec(expected_codecs_parsed[i]);
    if (vcodec != kUnknownVideoCodec) {
      expected_video_codecs_.push_back(vcodec);
      continue;
    }
    MEDIA_LOG(INFO, media_log_)
        << "Unrecognized media codec: " << expected_codecs_parsed[i];
  }

  state_ = PENDING_PARSER_CONFIG;
  stream_parser_->Init(
      base::Bind(&SourceBufferState::OnSourceInitDone, base::Unretained(this)),
      base::Bind(&SourceBufferState::OnNewConfigs, base::Unretained(this),
                 expected_codecs),
      base::Bind(&SourceBufferState::OnNewBuffers, base::Unretained(this)),
      new_text_track_cb_.is_null(), encrypted_media_init_data_cb,
      base::Bind(&SourceBufferState::OnNewMediaSegment, base::Unretained(this)),
      base::Bind(&SourceBufferState::OnEndOfMediaSegment,
                 base::Unretained(this)),
      media_log_);
}

void SourceBufferState::SetSequenceMode(bool sequence_mode) {
  DCHECK(!parsing_media_segment_);

  frame_processor_->SetSequenceMode(sequence_mode);
}

void SourceBufferState::SetGroupStartTimestampIfInSequenceMode(
    base::TimeDelta timestamp_offset) {
  DCHECK(!parsing_media_segment_);

  frame_processor_->SetGroupStartTimestampIfInSequenceMode(timestamp_offset);
}

void SourceBufferState::SetTracksWatcher(
    const Demuxer::MediaTracksUpdatedCB& tracks_updated_cb) {
  DCHECK(init_segment_received_cb_.is_null());
  DCHECK(!tracks_updated_cb.is_null());
  init_segment_received_cb_ = tracks_updated_cb;
}

bool SourceBufferState::Append(const uint8_t* data, size_t length,
                               TimeDelta append_window_start,
                               TimeDelta append_window_end,
                               TimeDelta* timestamp_offset) {
  append_in_progress_ = true;
  DCHECK(timestamp_offset);
  DCHECK(!timestamp_offset_during_append_);
  append_window_start_during_append_ = append_window_start;
  append_window_end_during_append_ = append_window_end;
  timestamp_offset_during_append_ = timestamp_offset;

  // TODO(wolenetz/acolwell): Curry and pass a NewBuffersCB here bound with
  // append window and timestamp offset pointer. See http://crbug.com/351454.
  bool result = stream_parser_->Parse(data, length);
  if (!result) {
    MEDIA_LOG(ERROR, media_log_)
        << __func__ << ": stream parsing failed. Data size=" << length
        << " append_window_start=" << append_window_start.InSecondsF()
        << " append_window_end=" << append_window_end.InSecondsF();
  }
  timestamp_offset_during_append_ = NULL;
  append_in_progress_ = false;
  return result;
}

void SourceBufferState::ResetParserState(TimeDelta append_window_start,
                                         TimeDelta append_window_end,
                                         base::TimeDelta* timestamp_offset) {
  DCHECK(timestamp_offset);
  DCHECK(!timestamp_offset_during_append_);
  timestamp_offset_during_append_ = timestamp_offset;
  append_window_start_during_append_ = append_window_start;
  append_window_end_during_append_ = append_window_end;

  stream_parser_->Flush();
  timestamp_offset_during_append_ = NULL;

  frame_processor_->Reset();
  parsing_media_segment_ = false;
  media_segment_has_data_for_track_.clear();
}

void SourceBufferState::Remove(TimeDelta start, TimeDelta end,
                               TimeDelta duration) {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->Remove(start, end, duration);
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->Remove(start, end, duration);
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->Remove(start, end, duration);
  }
}

bool SourceBufferState::EvictCodedFrames(DecodeTimestamp media_time,
                                         size_t newDataSize) {
  size_t total_buffered_size = 0;
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    total_buffered_size += it->second->GetBufferedSize();
  }
  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    total_buffered_size += it->second->GetBufferedSize();
  }
  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    total_buffered_size += it->second->GetBufferedSize();
  }

  DVLOG(3) << __func__ << " media_time=" << media_time.InSecondsF()
           << " newDataSize=" << newDataSize
           << " total_buffered_size=" << total_buffered_size;

  if (total_buffered_size == 0) return true;

  bool success = true;
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    uint64_t curr_size = it->second->GetBufferedSize();
    if (curr_size == 0) continue;
    uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size;
    DCHECK_LE(estimated_new_size, SIZE_MAX);
    success &= it->second->EvictCodedFrames(
        media_time, static_cast<size_t>(estimated_new_size));
  }
  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    uint64_t curr_size = it->second->GetBufferedSize();
    if (curr_size == 0) continue;
    uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size;
    DCHECK_LE(estimated_new_size, SIZE_MAX);
    success &= it->second->EvictCodedFrames(
        media_time, static_cast<size_t>(estimated_new_size));
  }
  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    uint64_t curr_size = it->second->GetBufferedSize();
    if (curr_size == 0) continue;
    uint64_t estimated_new_size = newDataSize * curr_size / total_buffered_size;
    DCHECK_LE(estimated_new_size, SIZE_MAX);
    success &= it->second->EvictCodedFrames(
        media_time, static_cast<size_t>(estimated_new_size));
  }

  DVLOG(3) << __func__ << " success=" << success;
  return success;
}

Ranges<TimeDelta> SourceBufferState::GetBufferedRanges(TimeDelta duration,
                                                       bool ended) const {
  RangesList ranges_list;
  for (DemuxerStreamMap::const_iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    ranges_list.push_back(it->second->GetBufferedRanges(duration));
  }

  for (DemuxerStreamMap::const_iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    ranges_list.push_back(it->second->GetBufferedRanges(duration));
  }

  for (DemuxerStreamMap::const_iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    ranges_list.push_back(it->second->GetBufferedRanges(duration));
  }

  return ComputeRangesIntersection(ranges_list, ended);
}

Ranges<TimeDelta> SourceBufferState::GetAudioBufferedRanges(TimeDelta duration,
                                                            bool ended) const {
  RangesList ranges_list;
  for (DemuxerStreamMap::const_iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    ranges_list.push_back(it->second->GetBufferedRanges(duration));
  }

  return ComputeRangesIntersection(ranges_list, ended);
}

TimeDelta SourceBufferState::GetVideoSeekKeyframeTimestamp() const {
  if (video_streams_.empty()) {
    return kNoTimestamp;
  }
  DCHECK_EQ(video_streams_.size(), 1);
  return video_streams_.begin()->second->GetSeekKeyframeTimestamp();
}

TimeDelta SourceBufferState::GetHighestPresentationTimestamp() const {
  TimeDelta max_pts;

  for (DemuxerStreamMap::const_iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    max_pts = std::max(max_pts, it->second->GetHighestPresentationTimestamp());
  }

  for (DemuxerStreamMap::const_iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    max_pts = std::max(max_pts, it->second->GetHighestPresentationTimestamp());
  }

  for (DemuxerStreamMap::const_iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    max_pts = std::max(max_pts, it->second->GetHighestPresentationTimestamp());
  }

  return max_pts;
}

TimeDelta SourceBufferState::GetMaxBufferedDuration() const {
  TimeDelta max_duration;

  for (DemuxerStreamMap::const_iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    max_duration = std::max(max_duration, it->second->GetBufferedDuration());
  }

  for (DemuxerStreamMap::const_iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    max_duration = std::max(max_duration, it->second->GetBufferedDuration());
  }

  for (DemuxerStreamMap::const_iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    max_duration = std::max(max_duration, it->second->GetBufferedDuration());
  }

  return max_duration;
}

void SourceBufferState::StartReturningData() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->StartReturningData();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->StartReturningData();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->StartReturningData();
  }
}

void SourceBufferState::AbortReads() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->AbortReads();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->AbortReads();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->AbortReads();
  }
}

void SourceBufferState::Seek(TimeDelta seek_time) {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->Seek(seek_time);
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->Seek(seek_time);
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->Seek(seek_time);
  }
}

void SourceBufferState::CompletePendingReadIfPossible() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->CompletePendingReadIfPossible();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->CompletePendingReadIfPossible();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->CompletePendingReadIfPossible();
  }
}

void SourceBufferState::OnSetDuration(TimeDelta duration) {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->OnSetDuration(duration);
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->OnSetDuration(duration);
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->OnSetDuration(duration);
  }
}

void SourceBufferState::MarkEndOfStream() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->MarkEndOfStream();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->MarkEndOfStream();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->MarkEndOfStream();
  }
}

void SourceBufferState::UnmarkEndOfStream() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->UnmarkEndOfStream();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->UnmarkEndOfStream();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->UnmarkEndOfStream();
  }
}

void SourceBufferState::Shutdown() {
  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    it->second->Shutdown();
  }

  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    it->second->Shutdown();
  }

  for (DemuxerStreamMap::iterator it = text_streams_.begin();
       it != text_streams_.end(); ++it) {
    it->second->Shutdown();
  }
}

void SourceBufferState::SetMemoryLimits(DemuxerStream::Type type,
                                        size_t memory_limit) {
  switch (type) {
    case DemuxerStream::AUDIO:
      for (DemuxerStreamMap::iterator it = audio_streams_.begin();
           it != audio_streams_.end(); ++it) {
        it->second->SetStreamMemoryLimit(memory_limit);
      }
      break;
    case DemuxerStream::VIDEO:
      for (DemuxerStreamMap::iterator it = video_streams_.begin();
           it != video_streams_.end(); ++it) {
        it->second->SetStreamMemoryLimit(memory_limit);
      }
      break;
    case DemuxerStream::TEXT:
      for (DemuxerStreamMap::iterator it = text_streams_.begin();
           it != text_streams_.end(); ++it) {
        it->second->SetStreamMemoryLimit(memory_limit);
      }
      break;
    case DemuxerStream::UNKNOWN:
    case DemuxerStream::NUM_TYPES:
      NOTREACHED();
      break;
  }
}

bool SourceBufferState::IsSeekWaitingForData() const {
  for (DemuxerStreamMap::const_iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    if (it->second->IsSeekWaitingForData()) return true;
  }

  for (DemuxerStreamMap::const_iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    if (it->second->IsSeekWaitingForData()) return true;
  }

  // NOTE: We are intentionally not checking the text tracks
  // because text tracks are discontinuous and may not have data
  // for the seek position. This is ok and playback should not be
  // stalled because we don't have cues. If cues, with timestamps after
  // the seek time, eventually arrive they will be delivered properly
  // in response to ChunkDemuxerStream::Read() calls.

  return false;
}

bool SourceBufferState::OnNewConfigs(
    std::string expected_codecs, std::unique_ptr<MediaTracks> tracks,
    const StreamParser::TextTrackConfigMap& text_configs) {
  DCHECK(tracks.get());
  DVLOG(1) << __func__ << " expected_codecs=" << expected_codecs
           << " tracks=" << tracks->tracks().size();
  DCHECK_GE(state_, PENDING_PARSER_CONFIG);

  // Check that there is no clashing bytestream track ids.
  if (!CheckBytestreamTrackIds(*tracks, text_configs)) {
    MEDIA_LOG(ERROR, media_log_) << "Duplicate bytestream track ids detected";
    for (size_t i = 0; i < tracks->tracks().size(); ++i) {
      const StreamParser::TrackId& track_id =
          tracks->tracks()[i]->bytestream_track_id();
      MEDIA_LOG(DEBUG, media_log_)
          << TrackTypeToStr(tracks->tracks()[i]->type()) << " track "
          << " bytestream track id=" << track_id;
    }
    return false;
  }

  // MSE spec allows new configs to be emitted only during Append, but not
  // during Flush or parser reset operations.
  CHECK(append_in_progress_);

  bool success = true;

  // TODO(wolenetz): Update codec string strictness, if necessary, once spec
  // issue https://github.com/w3c/media-source/issues/161 is resolved.
  std::vector<AudioCodec> expected_acodecs = expected_audio_codecs_;
  std::vector<VideoCodec> expected_vcodecs = expected_video_codecs_;

  FrameProcessor::TrackIdChanges track_id_changes;
  for (size_t i = 0; i < tracks->tracks().size(); ++i) {
    StreamParser::TrackId track_id = tracks->tracks()[i]->bytestream_track_id();

    if (tracks->tracks()[i]->type() == MediaTrack::Audio) {
      AudioDecoderConfig audio_config = tracks->getAudioConfig(track_id);
      DVLOG(1) << "Audio track_id=" << track_id
               << " config: " << audio_config.AsHumanReadableString();
      DCHECK(audio_config.IsValidConfig());

      std::vector<AudioCodec>::iterator it =
          std::find(expected_acodecs.begin(), expected_acodecs.end(),
                    audio_config.codec());
      if (it == expected_acodecs.end()) {
        MEDIA_LOG(ERROR, media_log_)
            << "Audio stream codec " << GetCodecName(audio_config.codec())
            << " doesn't match SourceBuffer codecs.";
        return false;
      }
      expected_acodecs.erase(it);

      ChunkDemuxerStream* stream = NULL;
      if (!first_init_segment_received_) {
        DCHECK(audio_streams_.find(track_id) == audio_streams_.end());
        stream = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO);
        if (!stream || !frame_processor_->AddTrack(track_id, stream)) {
          MEDIA_LOG(ERROR, media_log_) << "Failed to create audio stream.";
          return false;
        }
        audio_streams_[track_id] = stream;
        media_log_->SetBooleanProperty("found_audio_stream", true);
        media_log_->SetStringProperty("audio_codec_name",
                                      GetCodecName(audio_config.codec()));
      } else {
        if (audio_streams_.size() > 1) {
          DemuxerStreamMap::iterator it = audio_streams_.find(track_id);
          if (it != audio_streams_.end()) stream = it->second;
        } else {
          // If there is only one audio track then bytestream id might change in
          // a new init segment. So update our state and notify frame processor.
          DemuxerStreamMap::iterator it = audio_streams_.begin();
          if (it != audio_streams_.end()) {
            stream = it->second;
            if (it->first != track_id) {
              track_id_changes[it->first] = track_id;
              audio_streams_[track_id] = stream;
              audio_streams_.erase(it->first);
            }
          }
        }
        if (!stream) {
          MEDIA_LOG(ERROR, media_log_) << "Got unexpected audio track"
                                       << " track_id=" << track_id;
          return false;
        }
      }

      tracks->tracks()[i]->set_id(stream->media_track_id());
      frame_processor_->OnPossibleAudioConfigUpdate(audio_config);
      success &= stream->UpdateAudioConfig(audio_config, media_log_);
    } else if (tracks->tracks()[i]->type() == MediaTrack::Video) {
      VideoDecoderConfig video_config = tracks->getVideoConfig(track_id);
      DVLOG(1) << "Video track_id=" << track_id
               << " config: " << video_config.AsHumanReadableString();
      DCHECK(video_config.IsValidConfig());

      std::vector<VideoCodec>::iterator it =
          std::find(expected_vcodecs.begin(), expected_vcodecs.end(),
                    video_config.codec());
      if (it == expected_vcodecs.end()) {
        MEDIA_LOG(ERROR, media_log_)
            << "Video stream codec " << GetCodecName(video_config.codec())
            << " doesn't match SourceBuffer codecs.";
        return false;
      }
      expected_vcodecs.erase(it);

      ChunkDemuxerStream* stream = NULL;
      if (!first_init_segment_received_) {
        DCHECK(video_streams_.find(track_id) == video_streams_.end());
        stream = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO);
        if (!stream || !frame_processor_->AddTrack(track_id, stream)) {
          MEDIA_LOG(ERROR, media_log_) << "Failed to create video stream.";
          return false;
        }
        video_streams_[track_id] = stream;
        media_log_->SetBooleanProperty("found_video_stream", true);
        media_log_->SetStringProperty("video_codec_name",
                                      GetCodecName(video_config.codec()));
      } else {
        if (video_streams_.size() > 1) {
          DemuxerStreamMap::iterator it = video_streams_.find(track_id);
          if (it != video_streams_.end()) stream = it->second;
        } else {
          // If there is only one video track then bytestream id might change in
          // a new init segment. So update our state and notify frame processor.
          DemuxerStreamMap::iterator it = video_streams_.begin();
          if (it != video_streams_.end()) {
            stream = it->second;
            if (it->first != track_id) {
              track_id_changes[it->first] = track_id;
              video_streams_[track_id] = stream;
              video_streams_.erase(it->first);
            }
          }
        }
        if (!stream) {
          MEDIA_LOG(ERROR, media_log_) << "Got unexpected video track"
                                       << " track_id=" << track_id;
          return false;
        }
      }

      tracks->tracks()[i]->set_id(stream->media_track_id());
      buffer_allocator_->UpdateVideoConfig(video_config);
      success &= stream->UpdateVideoConfig(video_config, media_log_);
    } else {
      MEDIA_LOG(ERROR, media_log_) << "Error: unsupported media track type "
                                   << tracks->tracks()[i]->type();
      return false;
    }
  }

  if (!expected_acodecs.empty() || !expected_vcodecs.empty()) {
    for (size_t i = 0; i < expected_acodecs.size(); ++i) {
      MEDIA_LOG(ERROR, media_log_)
          << "Initialization segment misses expected "
          << GetCodecName(expected_acodecs[i]) << " track.";
    }
    for (size_t i = 0; i < expected_vcodecs.size(); ++i) {
      MEDIA_LOG(ERROR, media_log_)
          << "Initialization segment misses expected "
          << GetCodecName(expected_vcodecs[i]) << " track.";
    }
    return false;
  }

  if (text_streams_.empty()) {
    for (StreamParser::TextTrackConfigMap::const_iterator itr =
             text_configs.begin();
         itr != text_configs.end(); ++itr) {
      ChunkDemuxerStream* const text_stream =
          create_demuxer_stream_cb_.Run(DemuxerStream::TEXT);
      if (!frame_processor_->AddTrack(itr->first, text_stream)) {
        success &= false;
        MEDIA_LOG(ERROR, media_log_) << "Failed to add text track ID "
                                     << itr->first << " to frame processor.";
        break;
      }
      text_stream->UpdateTextConfig(itr->second, media_log_);
      text_streams_[itr->first] = text_stream;
      new_text_track_cb_.Run(text_stream, itr->second);
    }
  } else {
    const size_t text_count = text_streams_.size();
    if (text_configs.size() != text_count) {
      success &= false;
      MEDIA_LOG(ERROR, media_log_)
          << "The number of text track configs changed.";
    } else if (text_count == 1) {
      StreamParser::TextTrackConfigMap::const_iterator config_itr =
          text_configs.begin();
      DemuxerStreamMap::iterator stream_itr = text_streams_.begin();
      ChunkDemuxerStream* text_stream = stream_itr->second;
      TextTrackConfig old_config = text_stream->text_track_config();
      TextTrackConfig new_config(
          config_itr->second.kind(), config_itr->second.label(),
          config_itr->second.language(), old_config.id());
      if (!new_config.Matches(old_config)) {
        success &= false;
        MEDIA_LOG(ERROR, media_log_)
            << "New text track config does not match old one.";
      } else {
        StreamParser::TrackId old_id = stream_itr->first;
        StreamParser::TrackId new_id = config_itr->first;
        if (new_id != old_id) {
          track_id_changes[old_id] = new_id;
          text_streams_.erase(old_id);
          text_streams_[new_id] = text_stream;
        }
      }
    } else {
      for (StreamParser::TextTrackConfigMap::const_iterator config_itr =
               text_configs.begin();
           config_itr != text_configs.end(); ++config_itr) {
        DemuxerStreamMap::iterator stream_itr =
            text_streams_.find(config_itr->first);
        if (stream_itr == text_streams_.end()) {
          success &= false;
          MEDIA_LOG(ERROR, media_log_)
              << "Unexpected text track configuration for track ID "
              << config_itr->first;
          break;
        }

        const TextTrackConfig& new_config = config_itr->second;
        ChunkDemuxerStream* stream = stream_itr->second;
        TextTrackConfig old_config = stream->text_track_config();
        if (!new_config.Matches(old_config)) {
          success &= false;
          MEDIA_LOG(ERROR, media_log_)
              << "New text track config for track ID " << config_itr->first
              << " does not match old one.";
          break;
        }
      }
    }
  }

  if (audio_streams_.empty() && video_streams_.empty()) {
    DVLOG(1) << __func__ << ": couldn't find a valid audio or video stream";
    return false;
  }

  if (!frame_processor_->UpdateTrackIds(track_id_changes)) {
    DVLOG(1) << __func__ << ": failed to remap track ids in frame processor";
    return false;
  }

  frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint();

  if (!first_init_segment_received_) {
    first_init_segment_received_ = true;
    SetStreamMemoryLimits();
  }

  DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed");
  if (success) {
    if (state_ == PENDING_PARSER_CONFIG) state_ = PENDING_PARSER_INIT;
    DCHECK(!init_segment_received_cb_.is_null());
    init_segment_received_cb_.Run(std::move(tracks));
  }

  return success;
}

void SourceBufferState::SetStreamMemoryLimits() {}

void SourceBufferState::OnNewMediaSegment() {
  DVLOG(2) << "OnNewMediaSegment()";
  DCHECK_EQ(state_, PARSER_INITIALIZED);
  parsing_media_segment_ = true;
  media_segment_has_data_for_track_.clear();
}

void SourceBufferState::OnEndOfMediaSegment() {
  DVLOG(2) << "OnEndOfMediaSegment()";
  DCHECK_EQ(state_, PARSER_INITIALIZED);
  parsing_media_segment_ = false;

  for (DemuxerStreamMap::iterator it = audio_streams_.begin();
       it != audio_streams_.end(); ++it) {
    if (!media_segment_has_data_for_track_[it->first]) {
      LIMITED_MEDIA_LOG(DEBUG, media_log_, num_missing_track_logs_,
                        kMaxMissingTrackInSegmentLogs)
          << "Media segment did not contain any coded frames for track "
          << it->first
          << ", mismatching initialization segment. Therefore, MSE"
             " coded frame processing may not interoperably detect"
             " discontinuities in appended media.";
    }
  }
  for (DemuxerStreamMap::iterator it = video_streams_.begin();
       it != video_streams_.end(); ++it) {
    if (!media_segment_has_data_for_track_[it->first]) {
      LIMITED_MEDIA_LOG(DEBUG, media_log_, num_missing_track_logs_,
                        kMaxMissingTrackInSegmentLogs)
          << "Media segment did not contain any coded frames for track "
          << it->first
          << ", mismatching initialization segment. Therefore, MSE"
             " coded frame processing may not interoperably detect"
             " discontinuities in appended media.";
    }
  }
}

bool SourceBufferState::OnNewBuffers(
    const StreamParser::BufferQueueMap& buffer_queue_map) {
  DVLOG(2) << __func__ << " buffer_queues=" << buffer_queue_map.size();
  DCHECK_EQ(state_, PARSER_INITIALIZED);
  DCHECK(timestamp_offset_during_append_);
  DCHECK(parsing_media_segment_);

  for (StreamParser::BufferQueueMap::const_iterator it =
           buffer_queue_map.begin();
       it != buffer_queue_map.end(); ++it) {
    const StreamParser::BufferQueue& bufq = it->second;
    DCHECK(!bufq.empty());
    media_segment_has_data_for_track_[it->first] = true;
  }

  const TimeDelta timestamp_offset_before_processing =
      *timestamp_offset_during_append_;

  // Calculate the new timestamp offset for audio/video tracks if the stream
  // parser has requested automatic updates.
  TimeDelta new_timestamp_offset = timestamp_offset_before_processing;
  if (auto_update_timestamp_offset_) {
    TimeDelta min_end_timestamp = kNoTimestamp;
    for (StreamParser::BufferQueueMap::const_iterator it =
             buffer_queue_map.begin();
         it != buffer_queue_map.end(); ++it) {
      const StreamParser::BufferQueue& bufq = it->second;
      DCHECK(!bufq.empty());
      if (min_end_timestamp == kNoTimestamp ||
          EndTimestamp(bufq) < min_end_timestamp) {
        min_end_timestamp = EndTimestamp(bufq);
        DCHECK_NE(kNoTimestamp, min_end_timestamp);
      }
    }
    if (min_end_timestamp != kNoTimestamp)
      new_timestamp_offset += min_end_timestamp;
  }

  if (!frame_processor_->ProcessFrames(
          buffer_queue_map, append_window_start_during_append_,
          append_window_end_during_append_, timestamp_offset_during_append_)) {
    return false;
  }

  // Only update the timestamp offset if the frame processor hasn't already.
  if (auto_update_timestamp_offset_ &&
      timestamp_offset_before_processing == *timestamp_offset_during_append_) {
    *timestamp_offset_during_append_ = new_timestamp_offset;
  }

  return true;
}
void SourceBufferState::OnSourceInitDone(
    const StreamParser::InitParameters& params) {
  DCHECK_EQ(state_, PENDING_PARSER_INIT);
  state_ = PARSER_INITIALIZED;
  auto_update_timestamp_offset_ = params.auto_update_timestamp_offset;
  base::ResetAndReturn(&init_cb_).Run(params);
}

}  // namespace media
}  // namespace cobalt
