/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/mediasource/SourceBuffer.h"

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/DOMArrayBuffer.h"
#include "core/dom/DOMArrayBufferView.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/Event.h"
#include "core/events/GenericEventQueue.h"
#include "core/frame/Deprecation.h"
#include "core/frame/UseCounter.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/MediaError.h"
#include "core/html/TimeRanges.h"
#include "core/html/track/AudioTrack.h"
#include "core/html/track/AudioTrackList.h"
#include "core/html/track/VideoTrack.h"
#include "core/html/track/VideoTrackList.h"
#include "modules/mediasource/MediaSource.h"
#include "modules/mediasource/SourceBufferTrackBaseSupplement.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/instrumentation/tracing/TraceEvent.h"
#include "public/platform/WebSourceBuffer.h"
#include "wtf/MathExtras.h"
#include <limits>
#include <memory>
#include <sstream>

#ifndef BLINK_SBLOG
#define BLINK_SBLOG DVLOG(3)
#endif

using blink::WebSourceBuffer;

namespace blink {

namespace {

static bool throwExceptionIfRemovedOrUpdating(bool isRemoved,
                                              bool isUpdating,
                                              ExceptionState& exceptionState) {
  if (isRemoved) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "This SourceBuffer has been removed from the parent media source.");
    return true;
  }
  if (isUpdating) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "This SourceBuffer is still processing an 'appendBuffer' or "
        "'remove' operation.");
    return true;
  }

  return false;
}

WTF::String webTimeRangesToString(const WebTimeRanges& ranges) {
  StringBuilder stringBuilder;
  stringBuilder.append('{');
  for (auto& r : ranges) {
    stringBuilder.append(" [");
    stringBuilder.appendNumber(r.start);
    stringBuilder.append(';');
    stringBuilder.appendNumber(r.end);
    stringBuilder.append(']');
  }
  stringBuilder.append(" }");
  return stringBuilder.toString();
}

}  // namespace

SourceBuffer* SourceBuffer::create(
    std::unique_ptr<WebSourceBuffer> webSourceBuffer,
    MediaSource* source,
    GenericEventQueue* asyncEventQueue) {
  SourceBuffer* sourceBuffer =
      new SourceBuffer(std::move(webSourceBuffer), source, asyncEventQueue);
  sourceBuffer->suspendIfNeeded();
  return sourceBuffer;
}

SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> webSourceBuffer,
                           MediaSource* source,
                           GenericEventQueue* asyncEventQueue)
    : SuspendableObject(source->getExecutionContext()),
      m_webSourceBuffer(std::move(webSourceBuffer)),
      m_source(source),
      m_trackDefaults(TrackDefaultList::create()),
      m_asyncEventQueue(asyncEventQueue),
      m_mode(segmentsKeyword()),
      m_updating(false),
      m_timestampOffset(0),
      m_appendWindowStart(0),
      m_appendWindowEnd(std::numeric_limits<double>::infinity()),
      m_firstInitializationSegmentReceived(false),
      m_pendingAppendDataOffset(0),
      m_appendBufferAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(
          this,
          &SourceBuffer::appendBufferAsyncPart)),
      m_pendingRemoveStart(-1),
      m_pendingRemoveEnd(-1),
      m_removeAsyncPartRunner(AsyncMethodRunner<SourceBuffer>::create(
          this,
          &SourceBuffer::removeAsyncPart)) {
  BLINK_SBLOG << __func__ << " this=" << this;

  DCHECK(m_webSourceBuffer);
  DCHECK(m_source);
  DCHECK(m_source->mediaElement());
  m_audioTracks = AudioTrackList::create(*m_source->mediaElement());
  m_videoTracks = VideoTrackList::create(*m_source->mediaElement());
  m_webSourceBuffer->setClient(this);
}

SourceBuffer::~SourceBuffer() {
  BLINK_SBLOG << __func__ << " this=" << this;
}

void SourceBuffer::dispose() {
  // Promptly clears a raw reference from content/ to an on-heap object
  // so that content/ doesn't access it in a lazy sweeping phase.
  m_webSourceBuffer.reset();
}

const AtomicString& SourceBuffer::segmentsKeyword() {
  DEFINE_STATIC_LOCAL(const AtomicString, segments, ("segments"));
  return segments;
}

const AtomicString& SourceBuffer::sequenceKeyword() {
  DEFINE_STATIC_LOCAL(const AtomicString, sequence, ("sequence"));
  return sequence;
}

void SourceBuffer::setMode(const AtomicString& newMode,
                           ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " newMode=" << newMode;
  // Section 3.1 On setting mode attribute steps.
  // 1. Let new mode equal the new value being assigned to this attribute.
  // 2. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source, then throw an INVALID_STATE_ERR exception and abort
  //    these steps.
  // 3. If the updating attribute equals true, then throw an INVALID_STATE_ERR
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 4. If the readyState attribute of the parent media source is in the "ended"
  //    state then run the following steps:
  // 4.1 Set the readyState attribute of the parent media source to "open"
  // 4.2 Queue a task to fire a simple event named sourceopen at the parent
  //     media source.
  m_source->openIfInEndedState();

  // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an
  //    INVALID_STATE_ERR and abort these steps.
  // 6. If the new mode equals "sequence", then set the group start timestamp to
  //    the highest presentation end timestamp.
  WebSourceBuffer::AppendMode appendMode = WebSourceBuffer::AppendModeSegments;
  if (newMode == sequenceKeyword())
    appendMode = WebSourceBuffer::AppendModeSequence;
  if (!m_webSourceBuffer->setMode(appendMode)) {
    MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError,
                                         "The mode may not be set while the "
                                         "SourceBuffer's append state is "
                                         "'PARSING_MEDIA_SEGMENT'.");
    return;
  }

  // 7. Update the attribute to new mode.
  m_mode = newMode;
}

TimeRanges* SourceBuffer::buffered(ExceptionState& exceptionState) const {
  // Section 3.1 buffered attribute steps.
  // 1. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source then throw an InvalidStateError exception and abort
  //    these steps.
  if (isRemoved()) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "This SourceBuffer has been removed from the parent media source.");
    return nullptr;
  }

  // 2. Return a new static normalized TimeRanges object for the media segments
  //    buffered.
  return TimeRanges::create(m_webSourceBuffer->buffered());
}

double SourceBuffer::timestampOffset() const {
  return m_timestampOffset;
}

void SourceBuffer::setTimestampOffset(double offset,
                                      ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " offset=" << offset;
  // Section 3.1 timestampOffset attribute setter steps.
  // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-timestampOffset
  // 1. Let new timestamp offset equal the new value being assigned to this
  //    attribute.
  // 2. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source, then throw an InvalidStateError exception and abort
  //    these steps.
  // 3. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 4. If the readyState attribute of the parent media source is in the "ended"
  //    state then run the following steps:
  // 4.1 Set the readyState attribute of the parent media source to "open"
  // 4.2 Queue a task to fire a simple event named sourceopen at the parent
  //     media source.
  m_source->openIfInEndedState();

  // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an
  //    INVALID_STATE_ERR and abort these steps.
  // 6. If the mode attribute equals "sequence", then set the group start
  //    timestamp to new timestamp offset.
  if (!m_webSourceBuffer->setTimestampOffset(offset)) {
    MediaSource::logAndThrowDOMException(exceptionState, InvalidStateError,
                                         "The timestamp offset may not be set "
                                         "while the SourceBuffer's append "
                                         "state is 'PARSING_MEDIA_SEGMENT'.");
    return;
  }

  // 7. Update the attribute to new timestamp offset.
  m_timestampOffset = offset;
}

AudioTrackList& SourceBuffer::audioTracks() {
  DCHECK(HTMLMediaElement::mediaTracksEnabledInternally());
  return *m_audioTracks;
}

VideoTrackList& SourceBuffer::videoTracks() {
  DCHECK(HTMLMediaElement::mediaTracksEnabledInternally());
  return *m_videoTracks;
}

double SourceBuffer::appendWindowStart() const {
  return m_appendWindowStart;
}

void SourceBuffer::setAppendWindowStart(double start,
                                        ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " start=" << start;
  // Section 3.1 appendWindowStart attribute setter steps.
  // https://www.w3.org/TR/media-source/#widl-SourceBuffer-appendWindowStart
  // 1. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source then throw an InvalidStateError exception and abort
  //    these steps.
  // 2. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 3. If the new value is less than 0 or greater than or equal to
  //    appendWindowEnd then throw a TypeError exception and abort these steps.
  if (start < 0 || start >= m_appendWindowEnd) {
    MediaSource::logAndThrowTypeError(
        exceptionState,
        ExceptionMessages::indexOutsideRange(
            "value", start, 0.0, ExceptionMessages::ExclusiveBound,
            m_appendWindowEnd, ExceptionMessages::InclusiveBound));
    return;
  }

  m_webSourceBuffer->setAppendWindowStart(start);

  // 4. Update the attribute to the new value.
  m_appendWindowStart = start;
}

double SourceBuffer::appendWindowEnd() const {
  return m_appendWindowEnd;
}

void SourceBuffer::setAppendWindowEnd(double end,
                                      ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " end=" << end;
  // Section 3.1 appendWindowEnd attribute setter steps.
  // https://www.w3.org/TR/media-source/#widl-SourceBuffer-appendWindowEnd
  // 1. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source then throw an InvalidStateError exception and abort
  //    these steps.
  // 2. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 3. If the new value equals NaN, then throw a TypeError and abort these
  //    steps.
  if (std::isnan(end)) {
    MediaSource::logAndThrowTypeError(exceptionState,
                                      ExceptionMessages::notAFiniteNumber(end));
    return;
  }
  // 4. If the new value is less than or equal to appendWindowStart then throw a
  //    TypeError exception and abort these steps.
  if (end <= m_appendWindowStart) {
    MediaSource::logAndThrowTypeError(
        exceptionState, ExceptionMessages::indexExceedsMinimumBound(
                            "value", end, m_appendWindowStart));
    return;
  }

  m_webSourceBuffer->setAppendWindowEnd(end);

  // 5. Update the attribute to the new value.
  m_appendWindowEnd = end;
}

void SourceBuffer::appendBuffer(DOMArrayBuffer* data,
                                ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " size=" << data->byteLength();
  // Section 3.2 appendBuffer()
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
  appendBufferInternal(static_cast<const unsigned char*>(data->data()),
                       data->byteLength(), exceptionState);
}

void SourceBuffer::appendBuffer(DOMArrayBufferView* data,
                                ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " size=" << data->byteLength();
  // Section 3.2 appendBuffer()
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
  appendBufferInternal(static_cast<const unsigned char*>(data->baseAddress()),
                       data->byteLength(), exceptionState);
}

void SourceBuffer::abort(ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this;
  // http://w3c.github.io/media-source/#widl-SourceBuffer-abort-void
  // 1. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source then throw an InvalidStateError exception and abort
  //    these steps.
  // 2. If the readyState attribute of the parent media source is not in the
  //    "open" state then throw an InvalidStateError exception and abort these
  //    steps.
  if (isRemoved()) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "This SourceBuffer has been removed from the parent media source.");
    return;
  }
  if (!m_source->isOpen()) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "The parent media source's readyState is not 'open'.");
    return;
  }

  // 3. If the range removal algorithm is running, then throw an
  //    InvalidStateError exception and abort these steps.
  if (m_pendingRemoveStart != -1) {
    DCHECK(m_updating);
    // Throwing the exception and aborting these steps is new behavior that
    // is implemented behind the MediaSourceNewAbortAndDuration
    // RuntimeEnabledFeature.
    if (RuntimeEnabledFeatures::mediaSourceNewAbortAndDurationEnabled()) {
      MediaSource::logAndThrowDOMException(
          exceptionState, InvalidStateError,
          "Aborting asynchronous remove() operation is disallowed.");
      return;
    }

    Deprecation::countDeprecation(m_source->mediaElement()->document(),
                                  UseCounter::MediaSourceAbortRemove);
    cancelRemove();
  }

  // 4. If the sourceBuffer.updating attribute equals true, then run the
  //    following steps: ...
  abortIfUpdating();

  // 5. Run the reset parser state algorithm.
  m_webSourceBuffer->resetParserState();

  // 6. Set appendWindowStart to 0.
  setAppendWindowStart(0, exceptionState);

  // 7. Set appendWindowEnd to positive Infinity.
  setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState);
}

void SourceBuffer::remove(double start,
                          double end,
                          ExceptionState& exceptionState) {
  BLINK_SBLOG << __func__ << " this=" << this << " start=" << start
              << " end=" << end;

  // Section 3.2 remove() method steps.
  // https://www.w3.org/TR/media-source/#widl-SourceBuffer-remove-void-double-start-unrestricted-double-end
  // 1. If this object has been removed from the sourceBuffers attribute of the
  //    parent media source then throw an InvalidStateError exception and abort
  //    these steps.
  // 2. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 3. If duration equals NaN, then throw a TypeError exception and abort these
  //    steps.
  // 4. If start is negative or greater than duration, then throw a TypeError
  //    exception and abort these steps.
  if (start < 0 || std::isnan(m_source->duration()) ||
      start > m_source->duration()) {
    MediaSource::logAndThrowTypeError(
        exceptionState,
        ExceptionMessages::indexOutsideRange(
            "start", start, 0.0, ExceptionMessages::ExclusiveBound,
            std::isnan(m_source->duration()) ? 0 : m_source->duration(),
            ExceptionMessages::ExclusiveBound));
    return;
  }

  // 5. If end is less than or equal to start or end equals NaN, then throw a
  //    TypeError exception and abort these steps.
  if (end <= start || std::isnan(end)) {
    MediaSource::logAndThrowTypeError(
        exceptionState,
        "The end value provided (" + String::number(end) +
            ") must be greater than the start value provided (" +
            String::number(start) + ").");
    return;
  }

  TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::remove", this);

  // 6. If the readyState attribute of the parent media source is in the "ended"
  //    state then run the following steps:
  // 6.1. Set the readyState attribute of the parent media source to "open"
  // 6.2. Queue a task to fire a simple event named sourceopen at the parent
  //      media source .
  m_source->openIfInEndedState();

  // 7. Run the range removal algorithm with start and end as the start and end
  //    of the removal range.
  // 7.3. Set the updating attribute to true.
  m_updating = true;

  // 7.4. Queue a task to fire a simple event named updatestart at this
  //      SourceBuffer object.
  scheduleEvent(EventTypeNames::updatestart);

  // 7.5. Return control to the caller and run the rest of the steps
  //      asynchronously.
  m_pendingRemoveStart = start;
  m_pendingRemoveEnd = end;
  m_removeAsyncPartRunner->runAsync();
}

void SourceBuffer::setTrackDefaults(TrackDefaultList* trackDefaults,
                                    ExceptionState& exceptionState) {
  // Per 02 Dec 2014 Editor's Draft
  // http://w3c.github.io/media-source/#widl-SourceBuffer-trackDefaults
  // 1. If this object has been removed from the sourceBuffers attribute of
  //    the parent media source, then throw an InvalidStateError exception
  //    and abort these steps.
  // 2. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState))
    return;

  // 3. Update the attribute to the new value.
  m_trackDefaults = trackDefaults;
}

void SourceBuffer::cancelRemove() {
  DCHECK(m_updating);
  DCHECK_NE(m_pendingRemoveStart, -1);
  m_removeAsyncPartRunner->stop();
  m_pendingRemoveStart = -1;
  m_pendingRemoveEnd = -1;
  m_updating = false;

  if (!RuntimeEnabledFeatures::mediaSourceNewAbortAndDurationEnabled()) {
    scheduleEvent(EventTypeNames::abort);
    scheduleEvent(EventTypeNames::updateend);
  }

  TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::remove", this);
}

void SourceBuffer::abortIfUpdating() {
  // Section 3.2 abort() method step 4 substeps.
  // http://w3c.github.io/media-source/#widl-SourceBuffer-abort-void

  if (!m_updating)
    return;

  DCHECK_EQ(m_pendingRemoveStart, -1);

  const char* traceEventName = "SourceBuffer::appendBuffer";

  // 4.1. Abort the buffer append and stream append loop algorithms if they are
  //      running.
  m_appendBufferAsyncPartRunner->stop();
  m_pendingAppendData.clear();
  m_pendingAppendDataOffset = 0;

  // 4.2. Set the updating attribute to false.
  m_updating = false;

  // 4.3. Queue a task to fire a simple event named abort at this SourceBuffer
  //      object.
  scheduleEvent(EventTypeNames::abort);

  // 4.4. Queue a task to fire a simple event named updateend at this
  //      SourceBuffer object.
  scheduleEvent(EventTypeNames::updateend);

  TRACE_EVENT_ASYNC_END0("media", traceEventName, this);
}

void SourceBuffer::removedFromMediaSource() {
  if (isRemoved())
    return;

  BLINK_SBLOG << __func__ << " this=" << this;
  if (m_pendingRemoveStart != -1) {
    cancelRemove();
  } else {
    abortIfUpdating();
  }

  if (HTMLMediaElement::mediaTracksEnabledInternally()) {
    DCHECK(m_source);
    if (m_source->mediaElement()->audioTracks().length() > 0 ||
        m_source->mediaElement()->videoTracks().length() > 0) {
      removeMediaTracks();
    }
  }

  m_webSourceBuffer->removedFromMediaSource();
  m_webSourceBuffer.reset();
  m_source = nullptr;
  m_asyncEventQueue = nullptr;
}

double SourceBuffer::highestPresentationTimestamp() {
  DCHECK(!isRemoved());

  double pts = m_webSourceBuffer->highestPresentationTimestamp();
  BLINK_SBLOG << __func__ << " this=" << this << ", pts=" << pts;
  return pts;
}

void SourceBuffer::removeMediaTracks() {
  DCHECK(HTMLMediaElement::mediaTracksEnabledInternally());
  // Spec:
  // http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuffer-void-SourceBuffer-sourceBuffer
  DCHECK(m_source);

  HTMLMediaElement* mediaElement = m_source->mediaElement();
  DCHECK(mediaElement);
  // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object
  //    returned by sourceBuffer.audioTracks.
  // 4. If the SourceBuffer audioTracks list is not empty, then run the
  //    following steps:
  // 4.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object
  //     returned by the audioTracks attribute on the HTMLMediaElement.
  // 4.2 Let the removed enabled audio track flag equal false.
  bool removedEnabledAudioTrack = false;
  // 4.3 For each AudioTrack object in the SourceBuffer audioTracks list, run
  //     the following steps:
  while (audioTracks().length() > 0) {
    AudioTrack* audioTrack = audioTracks().anonymousIndexedGetter(0);
    // 4.3.1 Set the sourceBuffer attribute on the AudioTrack object to null.
    SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, nullptr);
    // 4.3.2 If the enabled attribute on the AudioTrack object is true, then set
    //       the removed enabled audio track flag to true.
    if (audioTrack->enabled())
      removedEnabledAudioTrack = true;
    // 4.3.3 Remove the AudioTrack object from the HTMLMediaElement audioTracks
    //       list.
    // 4.3.4 Queue a task to fire a trusted event named removetrack, that does
    //       not bubble and is not cancelable, and that uses the TrackEvent
    //       interface, at the HTMLMediaElement audioTracks list.
    mediaElement->audioTracks().remove(audioTrack->id());
    // 4.3.5 Remove the AudioTrack object from the SourceBuffer audioTracks
    //       list.
    // 4.3.6 Queue a task to fire a trusted event named removetrack, that does
    //       not bubble and is not cancelable, and that uses the TrackEvent
    //       interface, at the SourceBuffer audioTracks list.
    audioTracks().remove(audioTrack->id());
  }
  // 4.4 If the removed enabled audio track flag equals true, then queue a task
  //     to fire a simple event named change at the HTMLMediaElement audioTracks
  //     list.
  if (removedEnabledAudioTrack) {
    Event* event = Event::create(EventTypeNames::change);
    event->setTarget(&mediaElement->audioTracks());
    mediaElement->scheduleEvent(event);
  }

  // 5. Let SourceBuffer videoTracks list equal the VideoTrackList object
  //    returned by sourceBuffer.videoTracks.
  // 6. If the SourceBuffer videoTracks list is not empty, then run the
  //    following steps:
  // 6.1 Let HTMLMediaElement videoTracks list equal the VideoTrackList object
  //     returned by the videoTracks attribute on the HTMLMediaElement.
  // 6.2 Let the removed selected video track flag equal false.
  bool removedSelectedVideoTrack = false;
  // 6.3 For each VideoTrack object in the SourceBuffer videoTracks list, run
  //     the following steps:
  while (videoTracks().length() > 0) {
    VideoTrack* videoTrack = videoTracks().anonymousIndexedGetter(0);
    // 6.3.1 Set the sourceBuffer attribute on the VideoTrack object to null.
    SourceBufferTrackBaseSupplement::setSourceBuffer(*videoTrack, nullptr);
    // 6.3.2 If the selected attribute on the VideoTrack object is true, then
    //       set the removed selected video track flag to true.
    if (videoTrack->selected())
      removedSelectedVideoTrack = true;
    // 6.3.3 Remove the VideoTrack object from the HTMLMediaElement videoTracks
    //       list.
    // 6.3.4 Queue a task to fire a trusted event named removetrack, that does
    //       not bubble and is not cancelable, and that uses the TrackEvent
    //       interface, at the HTMLMediaElement videoTracks list.
    mediaElement->videoTracks().remove(videoTrack->id());
    // 6.3.5 Remove the VideoTrack object from the SourceBuffer videoTracks
    //       list.
    // 6.3.6 Queue a task to fire a trusted event named removetrack, that does
    //       not bubble and is not cancelable, and that uses the TrackEvent
    //       interface, at the SourceBuffer videoTracks list.
    videoTracks().remove(videoTrack->id());
  }
  // 6.4 If the removed selected video track flag equals true, then queue a task
  //     to fire a simple event named change at the HTMLMediaElement videoTracks
  //     list.
  if (removedSelectedVideoTrack) {
    Event* event = Event::create(EventTypeNames::change);
    event->setTarget(&mediaElement->videoTracks());
    mediaElement->scheduleEvent(event);
  }

  // 7-8. TODO(servolk): Remove text tracks once SourceBuffer has text tracks.
}

template <class T>
T* findExistingTrackById(const TrackListBase<T>& trackList, const String& id) {
  // According to MSE specification
  // (https://w3c.github.io/media-source/#sourcebuffer-init-segment-received)
  // step 3.1:
  // > If more than one track for a single type are present (ie 2 audio tracks),
  // then the Track IDs match the ones in the first initialization segment.
  // I.e. we only need to search by TrackID if there is more than one track,
  // otherwise we can assume that the only track of the given type is the same
  // one that we had in previous init segments.
  if (trackList.length() == 1)
    return trackList.anonymousIndexedGetter(0);
  return trackList.getTrackById(id);
}

const TrackDefault* SourceBuffer::getTrackDefault(
    const AtomicString& trackType,
    const AtomicString& byteStreamTrackID) const {
  // This is a helper for implementation of default track label and default
  // track language algorithms.
  // defaultTrackLabel spec:
  // https://w3c.github.io/media-source/#sourcebuffer-default-track-label
  // defaultTrackLanguage spec:
  // https://w3c.github.io/media-source/#sourcebuffer-default-track-language

  // 1. If trackDefaults contains a TrackDefault object with a type attribute
  //    equal to type and a byteStreamTrackID attribute equal to
  //    byteStreamTrackID, then return the value of the label/language attribute
  //    on this matching object and abort these steps.
  // 2. If trackDefaults contains a TrackDefault object with a type attribute
  //    equal to type and a byteStreamTrackID attribute equal to an empty
  //    string, then return the value of the label/language attribute on this
  //    matching object and abort these steps.
  // 3. Return an empty string to the caller
  const TrackDefault* trackDefaultWithEmptyBytestreamId = nullptr;
  for (unsigned i = 0; i < m_trackDefaults->length(); ++i) {
    const TrackDefault* trackDefault = m_trackDefaults->item(i);
    if (trackDefault->type() != trackType)
      continue;
    if (trackDefault->byteStreamTrackID() == byteStreamTrackID)
      return trackDefault;
    if (!trackDefaultWithEmptyBytestreamId &&
        trackDefault->byteStreamTrackID() == "")
      trackDefaultWithEmptyBytestreamId = trackDefault;
  }
  return trackDefaultWithEmptyBytestreamId;
}

AtomicString SourceBuffer::defaultTrackLabel(
    const AtomicString& trackType,
    const AtomicString& byteStreamTrackID) const {
  // Spec: https://w3c.github.io/media-source/#sourcebuffer-default-track-label
  const TrackDefault* trackDefault =
      getTrackDefault(trackType, byteStreamTrackID);
  return trackDefault ? AtomicString(trackDefault->label()) : "";
}

AtomicString SourceBuffer::defaultTrackLanguage(
    const AtomicString& trackType,
    const AtomicString& byteStreamTrackID) const {
  // Spec:
  // https://w3c.github.io/media-source/#sourcebuffer-default-track-language
  const TrackDefault* trackDefault =
      getTrackDefault(trackType, byteStreamTrackID);
  return trackDefault ? AtomicString(trackDefault->language()) : "";
}

bool SourceBuffer::initializationSegmentReceived(
    const WebVector<MediaTrackInfo>& newTracks) {
  BLINK_SBLOG << __func__ << " this=" << this << " tracks=" << newTracks.size();
  DCHECK(m_source);
  DCHECK(m_source->mediaElement());
  DCHECK(m_updating);

  if (!HTMLMediaElement::mediaTracksEnabledInternally()) {
    if (!m_firstInitializationSegmentReceived) {
      m_source->setSourceBufferActive(this, true);
      m_firstInitializationSegmentReceived = true;
    }
    return true;
  }

  // Implementation of Initialization Segment Received, see
  // https://w3c.github.io/media-source/#sourcebuffer-init-segment-received

  // Sort newTracks into audio and video tracks to facilitate implementation
  // of subsequent steps of this algorithm.
  Vector<MediaTrackInfo> newAudioTracks;
  Vector<MediaTrackInfo> newVideoTracks;
  for (const MediaTrackInfo& trackInfo : newTracks) {
    const TrackBase* track = nullptr;
    if (trackInfo.trackType == WebMediaPlayer::AudioTrack) {
      newAudioTracks.push_back(trackInfo);
      if (m_firstInitializationSegmentReceived)
        track = findExistingTrackById(audioTracks(), trackInfo.id);
    } else if (trackInfo.trackType == WebMediaPlayer::VideoTrack) {
      newVideoTracks.push_back(trackInfo);
      if (m_firstInitializationSegmentReceived)
        track = findExistingTrackById(videoTracks(), trackInfo.id);
    } else {
      BLINK_SBLOG << __func__ << " this=" << this
                  << " failed: unsupported track type " << trackInfo.trackType;
      // TODO(servolk): Add handling of text tracks.
      NOTREACHED();
    }
    if (m_firstInitializationSegmentReceived && !track) {
      BLINK_SBLOG << __func__ << " this=" << this
                  << " failed: tracks mismatch the first init segment.";
      return false;
    }
#if !LOG_DISABLED
    const char* logTrackTypeStr =
        (trackInfo.trackType == WebMediaPlayer::AudioTrack) ? "audio" : "video";
    BLINK_SBLOG << __func__ << " this=" << this << " : " << logTrackTypeStr
                << " track "
                << " id=" << String(trackInfo.id)
                << " byteStreamTrackID=" << String(trackInfo.byteStreamTrackID)
                << " kind=" << String(trackInfo.kind)
                << " label=" << String(trackInfo.label)
                << " language=" << String(trackInfo.language);
#endif
  }

  // 1. Update the duration attribute if it currently equals NaN:
  // TODO(servolk): Pass also stream duration into initSegmentReceived.

  // 2. If the initialization segment has no audio, video, or text tracks, then
  //    run the append error algorithm with the decode error parameter set to
  //    true and abort these steps.
  if (newTracks.size() == 0) {
    BLINK_SBLOG << __func__ << " this=" << this
                << " failed: no tracks found in the init segment.";
    // The append error algorithm will be called at the top level after we
    // return false here to indicate failure.
    return false;
  }

  // 3. If the first initialization segment received flag is true, then run the
  //    following steps:
  if (m_firstInitializationSegmentReceived) {
    // 3.1 Verify the following properties. If any of the checks fail then run
    //     the append error algorithm with the decode error parameter set to
    //     true and abort these steps.
    bool tracksMatchFirstInitSegment = true;
    // - The number of audio, video, and text tracks match what was in the first
    //   initialization segment.
    if (newAudioTracks.size() != audioTracks().length() ||
        newVideoTracks.size() != videoTracks().length()) {
      tracksMatchFirstInitSegment = false;
    }
    // - The codecs for each track, match what was specified in the first
    //   initialization segment.
    // This is currently done in MediaSourceState::OnNewConfigs.
    // - If more than one track for a single type are present (ie 2 audio
    //   tracks), then the Track IDs match the ones in the first initialization
    //   segment.
    if (tracksMatchFirstInitSegment && newAudioTracks.size() > 1) {
      for (size_t i = 0; i < newAudioTracks.size(); ++i) {
        const String& newTrackId = newVideoTracks[i].id;
        if (newTrackId !=
            String(audioTracks().anonymousIndexedGetter(i)->id())) {
          tracksMatchFirstInitSegment = false;
          break;
        }
      }
    }

    if (tracksMatchFirstInitSegment && newVideoTracks.size() > 1) {
      for (size_t i = 0; i < newVideoTracks.size(); ++i) {
        const String& newTrackId = newVideoTracks[i].id;
        if (newTrackId !=
            String(videoTracks().anonymousIndexedGetter(i)->id())) {
          tracksMatchFirstInitSegment = false;
          break;
        }
      }
    }

    if (!tracksMatchFirstInitSegment) {
      BLINK_SBLOG << __func__ << " this=" << this
                  << " failed: tracks mismatch the first init segment.";
      // The append error algorithm will be called at the top level after we
      // return false here to indicate failure.
      return false;
    }

    // 3.2 Add the appropriate track descriptions from this initialization
    //     segment to each of the track buffers.  This is done in Chromium code
    //     in stream parsers and demuxer implementations.

    // 3.3 Set the need random access point flag on all track buffers to true.
    // This is done in Chromium code, see MediaSourceState::OnNewConfigs.
  }

  // 4. Let active track flag equal false.
  bool activeTrack = false;

  // 5. If the first initialization segment received flag is false, then run the
  //    following steps:
  if (!m_firstInitializationSegmentReceived) {
    // 5.1 If the initialization segment contains tracks with codecs the user
    //     agent does not support, then run the append error algorithm with the
    //     decode error parameter set to true and abort these steps.
    // This is done in Chromium code, see MediaSourceState::OnNewConfigs.

    // 5.2 For each audio track in the initialization segment, run following
    //     steps:
    for (const MediaTrackInfo& trackInfo : newAudioTracks) {
      // 5.2.1 Let audio byte stream track ID be the Track ID for the current
      //       track being processed.
      const auto& byteStreamTrackID = trackInfo.byteStreamTrackID;
      // 5.2.2 Let audio language be a BCP 47 language tag for the language
      //       specified in the initialization segment for this track or an
      //       empty string if no language info is present.
      WebString language = trackInfo.language;
      // 5.2.3 If audio language equals an empty string or the 'und' BCP 47
      //       value, then run the default track language algorithm with
      //       byteStreamTrackID set to audio byte stream track ID and type set
      //       to "audio" and assign the value returned by the algorithm to
      //       audio language.
      if (language.isEmpty() || language == "und")
        language = defaultTrackLanguage(TrackDefault::audioKeyword(),
                                        byteStreamTrackID);
      // 5.2.4 Let audio label be a label specified in the initialization
      //       segment for this track or an empty string if no label info is
      //       present.
      WebString label = trackInfo.label;
      // 5.3.5 If audio label equals an empty string, then run the default track
      //       label algorithm with byteStreamTrackID set to audio byte stream
      //       track ID and type set to "audio" and assign the value returned by
      //       the algorithm to audio label.
      if (label.isEmpty())
        label =
            defaultTrackLabel(TrackDefault::audioKeyword(), byteStreamTrackID);
      // 5.2.6 Let audio kinds be an array of kind strings specified in the
      //       initialization segment for this track or an empty array if no
      //       kind information is provided.
      const auto& kind = trackInfo.kind;
      // 5.2.7 TODO(servolk): Implement track kind processing.
      // 5.2.8.2 Let new audio track be a new AudioTrack object.
      AudioTrack* audioTrack =
          AudioTrack::create(trackInfo.id, kind, label, language, false);
      SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, this);
      // 5.2.8.7 If audioTracks.length equals 0, then run the following steps:
      if (audioTracks().length() == 0) {
        // 5.2.8.7.1 Set the enabled property on new audio track to true.
        audioTrack->setEnabled(true);
        // 5.2.8.7.2 Set active track flag to true.
        activeTrack = true;
      }
      // 5.2.8.8 Add new audio track to the audioTracks attribute on this
      //         SourceBuffer object.
      // 5.2.8.9 Queue a task to fire a trusted event named addtrack, that does
      //         not bubble and is not cancelable, and that uses the TrackEvent
      //         interface, at the AudioTrackList object referenced by the
      //         audioTracks attribute on this SourceBuffer object.
      audioTracks().add(audioTrack);
      // 5.2.8.10 Add new audio track to the audioTracks attribute on the
      //          HTMLMediaElement.
      // 5.2.8.11 Queue a task to fire a trusted event named addtrack, that does
      //          not bubble and is not cancelable, and that uses the TrackEvent
      //          interface, at the AudioTrackList object referenced by the
      //          audioTracks attribute on the HTMLMediaElement.
      m_source->mediaElement()->audioTracks().add(audioTrack);
    }

    // 5.3. For each video track in the initialization segment, run following
    //      steps:
    for (const MediaTrackInfo& trackInfo : newVideoTracks) {
      // 5.3.1 Let video byte stream track ID be the Track ID for the current
      //       track being processed.
      const auto& byteStreamTrackID = trackInfo.byteStreamTrackID;
      // 5.3.2 Let video language be a BCP 47 language tag for the language
      //       specified in the initialization segment for this track or an
      //       empty string if no language info is present.
      WebString language = trackInfo.language;
      // 5.3.3 If video language equals an empty string or the 'und' BCP 47
      //       value, then run the default track language algorithm with
      //       byteStreamTrackID set to video byte stream track ID and type set
      //       to "video" and assign the value returned by the algorithm to
      //       video language.
      if (language.isEmpty() || language == "und")
        language = defaultTrackLanguage(TrackDefault::videoKeyword(),
                                        byteStreamTrackID);
      // 5.3.4 Let video label be a label specified in the initialization
      //       segment for this track or an empty string if no label info is
      //       present.
      WebString label = trackInfo.label;
      // 5.3.5 If video label equals an empty string, then run the default track
      //       label algorithm with byteStreamTrackID set to video byte stream
      //       track ID and type set to "video" and assign the value returned by
      //       the algorithm to video label.
      if (label.isEmpty())
        label =
            defaultTrackLabel(TrackDefault::videoKeyword(), byteStreamTrackID);
      // 5.3.6 Let video kinds be an array of kind strings specified in the
      //       initialization segment for this track or an empty array if no
      //       kind information is provided.
      const auto& kind = trackInfo.kind;
      // 5.3.7 TODO(servolk): Implement track kind processing.
      // 5.3.8.2 Let new video track be a new VideoTrack object.
      VideoTrack* videoTrack =
          VideoTrack::create(trackInfo.id, kind, label, language, false);
      SourceBufferTrackBaseSupplement::setSourceBuffer(*videoTrack, this);
      // 5.3.8.7 If videoTracks.length equals 0, then run the following steps:
      if (videoTracks().length() == 0) {
        // 5.3.8.7.1 Set the selected property on new audio track to true.
        videoTrack->setSelected(true);
        // 5.3.8.7.2 Set active track flag to true.
        activeTrack = true;
      }
      // 5.3.8.8 Add new video track to the videoTracks attribute on this
      //         SourceBuffer object.
      // 5.3.8.9 Queue a task to fire a trusted event named addtrack, that does
      //         not bubble and is not cancelable, and that uses the TrackEvent
      //         interface, at the VideoTrackList object referenced by the
      //         videoTracks attribute on this SourceBuffer object.
      videoTracks().add(videoTrack);
      // 5.3.8.10 Add new video track to the videoTracks attribute on the
      //          HTMLMediaElement.
      // 5.3.8.11 Queue a task to fire a trusted event named addtrack, that does
      //          not bubble and is not cancelable, and that uses the TrackEvent
      //          interface, at the VideoTrackList object referenced by the
      //          videoTracks attribute on the HTMLMediaElement.
      m_source->mediaElement()->videoTracks().add(videoTrack);
    }

    // 5.4 TODO(servolk): Add text track processing here.

    // 5.5 If active track flag equals true, then run the following steps:
    // activesourcebuffers.
    if (activeTrack) {
      // 5.5.1 Add this SourceBuffer to activeSourceBuffers.
      // 5.5.2 Queue a task to fire a simple event named addsourcebuffer at
      //       activeSourceBuffers
      m_source->setSourceBufferActive(this, true);
    }

    // 5.6. Set first initialization segment received flag to true.
    m_firstInitializationSegmentReceived = true;
  }

  return true;
}

bool SourceBuffer::hasPendingActivity() const {
  return m_source;
}

void SourceBuffer::suspend() {
  m_appendBufferAsyncPartRunner->suspend();
  m_removeAsyncPartRunner->suspend();
}

void SourceBuffer::resume() {
  m_appendBufferAsyncPartRunner->resume();
  m_removeAsyncPartRunner->resume();
}

void SourceBuffer::contextDestroyed(ExecutionContext*) {
  m_appendBufferAsyncPartRunner->stop();
  m_removeAsyncPartRunner->stop();
}

ExecutionContext* SourceBuffer::getExecutionContext() const {
  return SuspendableObject::getExecutionContext();
}

const AtomicString& SourceBuffer::interfaceName() const {
  return EventTargetNames::SourceBuffer;
}

bool SourceBuffer::isRemoved() const {
  return !m_source;
}

void SourceBuffer::scheduleEvent(const AtomicString& eventName) {
  DCHECK(m_asyncEventQueue);

  Event* event = Event::create(eventName);
  event->setTarget(this);

  m_asyncEventQueue->enqueueEvent(event);
}

bool SourceBuffer::prepareAppend(size_t newDataSize,
                                 ExceptionState& exceptionState) {
  TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::prepareAppend", this);
  // http://w3c.github.io/media-source/#sourcebuffer-prepare-append
  // 3.5.4 Prepare Append Algorithm
  // 1. If the SourceBuffer has been removed from the sourceBuffers attribute of
  //    the parent media source then throw an InvalidStateError exception and
  //    abort these steps.
  // 2. If the updating attribute equals true, then throw an InvalidStateError
  //    exception and abort these steps.
  if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating,
                                        exceptionState)) {
    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
    return false;
  }

  // 3. If the HTMLMediaElement.error attribute is not null, then throw an
  //    InvalidStateError exception and abort these steps.
  DCHECK(m_source);
  DCHECK(m_source->mediaElement());
  if (m_source->mediaElement()->error()) {
    MediaSource::logAndThrowDOMException(
        exceptionState, InvalidStateError,
        "The HTMLMediaElement.error attribute is not null.");
    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
    return false;
  }

  // 4. If the readyState attribute of the parent media source is in the "ended"
  //    state then run the following steps:
  //    1. Set the readyState attribute of the parent media source to "open"
  //    2. Queue a task to fire a simple event named sourceopen at the parent
  //       media source.
  m_source->openIfInEndedState();

  // 5. Run the coded frame eviction algorithm.
  if (!evictCodedFrames(newDataSize)) {
    // 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_ERR
    //    exception and abort these steps.
    BLINK_SBLOG << __func__ << " this=" << this
                << " -> throw QuotaExceededError";
    MediaSource::logAndThrowDOMException(exceptionState, QuotaExceededError,
                                         "The SourceBuffer is full, and cannot "
                                         "free space to append additional "
                                         "buffers.");
    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
    return false;
  }

  TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
  return true;
}

bool SourceBuffer::evictCodedFrames(size_t newDataSize) {
  DCHECK(m_source);
  DCHECK(m_source->mediaElement());

  // Nothing to do if the mediaElement does not yet have frames to evict.
  if (m_source->mediaElement()->getReadyState() <
      HTMLMediaElement::kHaveMetadata) {
    return true;
  }

  double currentTime = m_source->mediaElement()->currentTime();
  bool result = m_webSourceBuffer->evictCodedFrames(currentTime, newDataSize);
  if (!result) {
    BLINK_SBLOG << __func__ << " this=" << this
                << " failed. newDataSize=" << newDataSize
                << " currentTime=" << currentTime << " buffered="
                << webTimeRangesToString(m_webSourceBuffer->buffered());
  }
  return result;
}

void SourceBuffer::appendBufferInternal(const unsigned char* data,
                                        unsigned size,
                                        ExceptionState& exceptionState) {
  TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size",
                           size);
  // Section 3.2 appendBuffer()
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data

  // 1. Run the prepare append algorithm.
  if (!prepareAppend(size, exceptionState)) {
    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
    return;
  }
  TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
                               "prepareAppend");

  // 2. Add data to the end of the input buffer.
  DCHECK(data || size == 0);
  if (data)
    m_pendingAppendData.append(data, size);
  m_pendingAppendDataOffset = 0;

  // 3. Set the updating attribute to true.
  m_updating = true;

  // 4. Queue a task to fire a simple event named updatestart at this
  //    SourceBuffer object.
  scheduleEvent(EventTypeNames::updatestart);

  // 5. Asynchronously run the buffer append algorithm.
  m_appendBufferAsyncPartRunner->runAsync();

  TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
                               "initialDelay");
}

void SourceBuffer::appendBufferAsyncPart() {
  DCHECK(m_updating);

  // Section 3.5.4 Buffer Append Algorithm
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-buffer-append

  // 1. Run the segment parser loop algorithm.
  // Step 2 doesn't apply since we run Step 1 synchronously here.
  DCHECK_GE(m_pendingAppendData.size(), m_pendingAppendDataOffset);
  size_t appendSize = m_pendingAppendData.size() - m_pendingAppendDataOffset;

  // Impose an arbitrary max size for a single append() call so that an append
  // doesn't block the renderer event loop very long. This value was selected
  // by looking at YouTube SourceBuffer usage across a variety of bitrates.
  // This value allows relatively large appends while keeping append() call
  // duration in the  ~5-15ms range.
  const size_t MaxAppendSize = 128 * 1024;
  if (appendSize > MaxAppendSize)
    appendSize = MaxAppendSize;

  TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this,
                               "appending", "appendSize",
                               static_cast<unsigned>(appendSize));

  // |zero| is used for 0 byte appends so we always have a valid pointer.
  // We need to convey all appends, even 0 byte ones to |m_webSourceBuffer|
  // so that it can clear its end of stream state if necessary.
  unsigned char zero = 0;
  unsigned char* appendData = &zero;
  if (appendSize)
    appendData = m_pendingAppendData.data() + m_pendingAppendDataOffset;

  bool appendSuccess =
      m_webSourceBuffer->append(appendData, appendSize, &m_timestampOffset);

  if (!appendSuccess) {
    m_pendingAppendData.clear();
    m_pendingAppendDataOffset = 0;
    appendError();
  } else {
    m_pendingAppendDataOffset += appendSize;

    if (m_pendingAppendDataOffset < m_pendingAppendData.size()) {
      m_appendBufferAsyncPartRunner->runAsync();
      TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
                                   "nextPieceDelay");
      return;
    }

    // 3. Set the updating attribute to false.
    m_updating = false;
    m_pendingAppendData.clear();
    m_pendingAppendDataOffset = 0;

    // 4. Queue a task to fire a simple event named update at this SourceBuffer
    //    object.
    scheduleEvent(EventTypeNames::update);

    // 5. Queue a task to fire a simple event named updateend at this
    //    SourceBuffer object.
    scheduleEvent(EventTypeNames::updateend);
  }

  TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
  BLINK_SBLOG << __func__ << " done. this=" << this << " buffered="
              << webTimeRangesToString(m_webSourceBuffer->buffered());
}

void SourceBuffer::removeAsyncPart() {
  DCHECK(m_updating);
  DCHECK_GE(m_pendingRemoveStart, 0);
  DCHECK_LT(m_pendingRemoveStart, m_pendingRemoveEnd);

  // Section 3.2 remove() method steps
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-remove-void-double-start-double-end

  // 9. Run the coded frame removal algorithm with start and end as the start
  //    and end of the removal range.
  m_webSourceBuffer->remove(m_pendingRemoveStart, m_pendingRemoveEnd);

  // 10. Set the updating attribute to false.
  m_updating = false;
  m_pendingRemoveStart = -1;
  m_pendingRemoveEnd = -1;

  // 11. Queue a task to fire a simple event named update at this SourceBuffer
  //     object.
  scheduleEvent(EventTypeNames::update);

  // 12. Queue a task to fire a simple event named updateend at this
  //     SourceBuffer object.
  scheduleEvent(EventTypeNames::updateend);
}

void SourceBuffer::appendError() {
  BLINK_SBLOG << __func__ << " this=" << this;
  // Section 3.5.3 Append Error Algorithm
  // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-append-error

  // 1. Run the reset parser state algorithm.
  m_webSourceBuffer->resetParserState();

  // 2. Set the updating attribute to false.
  m_updating = false;

  // 3. Queue a task to fire a simple event named error at this SourceBuffer
  //    object.
  scheduleEvent(EventTypeNames::error);

  // 4. Queue a task to fire a simple event named updateend at this SourceBuffer
  //    object.
  scheduleEvent(EventTypeNames::updateend);

  // 5. If decode error is true, then run the end of stream algorithm with the
  // error parameter set to "decode".
  m_source->endOfStream("decode", ASSERT_NO_EXCEPTION);
}

DEFINE_TRACE(SourceBuffer) {
  visitor->trace(m_source);
  visitor->trace(m_trackDefaults);
  visitor->trace(m_asyncEventQueue);
  visitor->trace(m_appendBufferAsyncPartRunner);
  visitor->trace(m_removeAsyncPartRunner);
  visitor->trace(m_audioTracks);
  visitor->trace(m_videoTracks);
  EventTargetWithInlineData::trace(visitor);
  SuspendableObject::trace(visitor);
}

}  // namespace blink
