1521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)/*
2521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
3521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *
4521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * modification, are permitted provided that the following conditions are
6521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * met:
7521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *
8521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
9521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
10521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
11521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
12521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * in the documentation and/or other materials provided with the
13521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * distribution.
14521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
15521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
16521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * this software without specific prior written permission.
17521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) *
18521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) */
30521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
31521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "config.h"
32521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "modules/mediasource/SourceBuffer.h"
33521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "bindings/v8/ExceptionState.h"
357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/ExceptionCode.h"
361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h"
371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/events/Event.h"
3806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/GenericEventQueue.h"
3906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/fileapi/FileReaderLoader.h"
4006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/fileapi/Stream.h"
41521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "core/html/TimeRanges.h"
42521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "modules/mediasource/MediaSource.h"
431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Logging.h"
441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/TraceEvent.h"
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebSourceBuffer.h"
46521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/ArrayBuffer.h"
47521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/ArrayBufferView.h"
483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "wtf/MathExtras.h"
493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include <limits>
51521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebSourceBuffer;
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
54521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)namespace WebCore {
55521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<SourceBuffer> SourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue)
57521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    RefPtr<SourceBuffer> sourceBuffer(adoptRef(new SourceBuffer(webSourceBuffer, source, asyncEventQueue)));
59521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    sourceBuffer->suspendIfNeeded();
60521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return sourceBuffer.release();
61521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
62521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)SourceBuffer::SourceBuffer(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue)
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    : ActiveDOMObject(source->executionContext())
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    , m_webSourceBuffer(webSourceBuffer)
66521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_source(source)
67521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_asyncEventQueue(asyncEventQueue)
68521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_updating(false)
69521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_timestampOffset(0)
703c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    , m_appendWindowStart(0)
713c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    , m_appendWindowEnd(std::numeric_limits<double>::infinity())
72f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_appendBufferAsyncPartRunner(this, &SourceBuffer::appendBufferAsyncPart)
7323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    , m_pendingRemoveStart(-1)
7423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    , m_pendingRemoveEnd(-1)
75f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_removeAsyncPartRunner(this, &SourceBuffer::removeAsyncPart)
7606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    , m_streamMaxSizeValid(false)
7706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    , m_streamMaxSize(0)
78f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_appendStreamAsyncPartRunner(this, &SourceBuffer::appendStreamAsyncPart)
79521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
8051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(m_webSourceBuffer);
81521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ASSERT(m_source);
82521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ScriptWrappable::init(this);
83521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
84521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
85521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)SourceBuffer::~SourceBuffer()
86521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
87521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ASSERT(isRemoved());
8806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(!m_loader);
8906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(!m_stream);
90521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
91521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<TimeRanges> SourceBuffer::buffered(ExceptionState& exceptionState) const
93521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
94521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.1 buffered attribute steps.
95521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
96e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    //    InvalidStateError exception and abort these steps.
97521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (isRemoved()) {
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
99521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return 0;
100521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
101521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
102521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 2. Return a new static normalized TimeRanges object for the media segments buffered.
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return TimeRanges::create(m_webSourceBuffer->buffered());
104521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
105521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
106521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)double SourceBuffer::timestampOffset() const
107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
108521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return m_timestampOffset;
109521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
110521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setTimestampOffset(double offset, ExceptionState& exceptionState)
112521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.1 timestampOffset attribute setter steps.
11423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 1. Let new timestamp offset equal the new value being assigned to this attribute.
11523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 2. If this object has been removed from the sourceBuffers attribute of the parent media source, then throw an
116e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    //    InvalidStateError exception and abort these steps.
11723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 3. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
11823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (isRemoved() || m_updating) {
11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
1201fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        return;
1211fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
1221fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch
123521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps:
124521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4.1 Set the readyState attribute of the parent media source to "open"
125521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4.2 Queue a task to fire a simple event named sourceopen at the parent media source.
126521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_source->openIfInEndedState();
127521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
128e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // 5. If this object is waiting for the end of a media segment to be appended, then throw an InvalidStateError
129521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // and abort these steps.
13023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    //
13123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // FIXME: Add step 6 text when mode attribute is implemented.
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!m_webSourceBuffer->setTimestampOffset(offset)) {
13351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
134521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
135521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
136521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
13723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 7. Update the attribute to new timestamp offset.
138521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_timestampOffset = offset;
139521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
140521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochdouble SourceBuffer::appendWindowStart() const
1423c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
1433c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return m_appendWindowStart;
1443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
1453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
14651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exceptionState)
1473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
1483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // Enforce throwing an exception on restricted double values.
1493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (std::isnan(start)
1503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        || start == std::numeric_limits<double>::infinity()
1513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        || start == -std::numeric_limits<double>::infinity()) {
15251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
1533c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return;
1543c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
1553c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1563c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // Section 3.1 appendWindowStart attribute setter steps.
1573c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
1583c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    //    InvalidStateError exception and abort these steps.
1593c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
1603c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (isRemoved() || m_updating) {
16151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
1623c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return;
1633c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
1643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1653c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 3. If the new value is less than 0 or greater than or equal to appendWindowEnd then throw an InvalidAccessError
1663c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    //    exception and abort these steps.
1673c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (start < 0 || start >= m_appendWindowEnd) {
16851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1693c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return;
1703c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
1713c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
17251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->setAppendWindowStart(start);
1733c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1743c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 4. Update the attribute to the new value.
1753c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    m_appendWindowStart = start;
1763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
1773c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1783c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochdouble SourceBuffer::appendWindowEnd() const
1793c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
1803c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return m_appendWindowEnd;
1813c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
1823c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
18351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setAppendWindowEnd(double end, ExceptionState& exceptionState)
1843c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
1853c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // Section 3.1 appendWindowEnd attribute setter steps.
1863c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
1873c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    //    InvalidStateError exception and abort these steps.
1883c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
1893c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (isRemoved() || m_updating) {
19051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
1913c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return;
1923c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
1933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 3. If the new value equals NaN, then throw an InvalidAccessError and abort these steps.
1953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 4. If the new value is less than or equal to appendWindowStart then throw an InvalidAccessError
1963c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    //    exception and abort these steps.
1973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    if (std::isnan(end) || end <= m_appendWindowStart) {
19851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1993c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return;
2003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    }
2013c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
20251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->setAppendWindowEnd(end);
2033c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
2043c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 5. Update the attribute to the new value.
2053c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    m_appendWindowEnd = end;
2063c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
2073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
20851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBuffer(PassRefPtr<ArrayBuffer> data, ExceptionState& exceptionState)
209521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
210521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.2 appendBuffer()
211521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
212e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // 1. If data is null then throw an InvalidAccessError exception and abort these steps.
213521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!data) {
21451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
215521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
216521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
217521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    appendBufferInternal(static_cast<const unsigned char*>(data->data()), data->byteLength(), exceptionState);
219521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
220521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
22151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBuffer(PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState)
222521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
223521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.2 appendBuffer()
224521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
225e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // 1. If data is null then throw an InvalidAccessError exception and abort these steps.
226521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!data) {
22751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
228521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
229521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
230521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
23151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    appendBufferInternal(static_cast<const unsigned char*>(data->baseAddress()), data->byteLength(), exceptionState);
23206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
23306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendStream(PassRefPtr<Stream> stream, ExceptionState& exceptionState)
23506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
23606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_streamMaxSizeValid = false;
23751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    appendStreamInternal(stream, exceptionState);
23806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
23906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
24051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendStream(PassRefPtr<Stream> stream, unsigned long long maxSize, ExceptionState& exceptionState)
24106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
24206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_streamMaxSizeValid = maxSize > 0;
24306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (m_streamMaxSizeValid)
24406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_streamMaxSize = maxSize;
24551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    appendStreamInternal(stream, exceptionState);
246521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
247521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
24851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::abort(ExceptionState& exceptionState)
249521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
250521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.2 abort() method steps.
251521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-abort-void
252521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 1. If this object has been removed from the sourceBuffers attribute of the parent media source
253e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    //    then throw an InvalidStateError exception and abort these steps.
254521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 2. If the readyState attribute of the parent media source is not in the "open" state
255e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    //    then throw an InvalidStateError exception and abort these steps.
256521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (isRemoved() || !m_source->isOpen()) {
25751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
258521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
259521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
260521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
261521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3. If the sourceBuffer.updating attribute equals true, then run the following steps: ...
262521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    abortIfUpdating();
263521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
264521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4. Run the reset parser state algorithm.
26551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->abort();
266521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
2673c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 5. Set appendWindowStart to 0.
26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setAppendWindowStart(0, exceptionState);
2693c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
2703c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    // 6. Set appendWindowEnd to positive Infinity.
27151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState);
272521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
273521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
27451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::remove(double start, double end, ExceptionState& exceptionState)
27523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch{
27623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // Section 3.2 remove() method steps.
27723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 1. If start is negative or greater than duration, then throw an InvalidAccessError exception and abort these steps.
27823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 2. If end is less than or equal to start, then throw an InvalidAccessError exception and abort these steps.
27923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (start < 0 || (m_source && (std::isnan(m_source->duration()) || start > m_source->duration())) || end <= start) {
28051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
28123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        return;
28223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    }
28323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
28423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 3. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an
28523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    //    InvalidStateError exception and abort these steps.
28623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 4. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
28723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    if (isRemoved() || m_updating) {
28851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
28923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch        return;
29023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    }
29123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
2921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::remove", this);
2931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
29423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 5. If the readyState attribute of the parent media source is in the "ended" state then run the following steps:
29523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 5.1. Set the readyState attribute of the parent media source to "open"
29623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 5.2. Queue a task to fire a simple event named sourceopen at the parent media source .
29723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_source->openIfInEndedState();
29823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
29923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 6. Set the updating attribute to true.
30023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_updating = true;
30123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
30223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 7. Queue a task to fire a simple event named updatestart at this SourceBuffer object.
3031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updatestart);
30423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
30523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 8. Return control to the caller and run the rest of the steps asynchronously.
30623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveStart = start;
30723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveEnd = end;
308f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_removeAsyncPartRunner.runAsync();
30923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch}
310521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
311521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::abortIfUpdating()
312521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
313521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.2 abort() method step 3 substeps.
314521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-abort-void
315521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
316521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!m_updating)
317521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
318521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
3191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    const char* traceEventName = 0;
3201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!m_pendingAppendData.isEmpty()) {
3211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        traceEventName = "SourceBuffer::appendBuffer";
3221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else if (m_stream) {
3231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        traceEventName = "SourceBuffer::appendStream";
3241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else if (m_pendingRemoveStart != -1) {
3251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        traceEventName = "SourceBuffer::remove";
3261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else {
3271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ASSERT_NOT_REACHED();
3281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
3291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
330521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3.1. Abort the buffer append and stream append loop algorithms if they are running.
331f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendBufferAsyncPartRunner.stop();
332521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_pendingAppendData.clear();
333521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
334f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_removeAsyncPartRunner.stop();
33523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveStart = -1;
33623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveEnd = -1;
33723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
338f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendStreamAsyncPartRunner.stop();
33906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    clearAppendStreamState();
34006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
341521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3.2. Set the updating attribute to false.
342521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_updating = false;
343521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
344521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3.3. Queue a task to fire a simple event named abort at this SourceBuffer object.
3451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::abort);
346521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
347521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3.4. Queue a task to fire a simple event named updateend at this SourceBuffer object.
3481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updateend);
3491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
3501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_END0("media", traceEventName, this);
351521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
352521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
353521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::removedFromMediaSource()
354521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
355521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (isRemoved())
356521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
357521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
35823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    abortIfUpdating();
35923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
36051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->removedFromMediaSource();
36151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer.clear();
362521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_source = 0;
363521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_asyncEventQueue = 0;
364521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
365521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
366521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool SourceBuffer::hasPendingActivity() const
367521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
368521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return m_source;
369521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
370521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
371f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::suspend()
372f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
373f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendBufferAsyncPartRunner.suspend();
374f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_removeAsyncPartRunner.suspend();
375f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendStreamAsyncPartRunner.suspend();
376f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
377f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
378f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::resume()
379f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
380f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendBufferAsyncPartRunner.resume();
381f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_removeAsyncPartRunner.resume();
382f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendStreamAsyncPartRunner.resume();
383f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
384f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
385521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::stop()
386521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
387f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendBufferAsyncPartRunner.stop();
388f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_removeAsyncPartRunner.stop();
389f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendStreamAsyncPartRunner.stop();
390521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
391521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
3921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)ExecutionContext* SourceBuffer::executionContext() const
393521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
3941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return ActiveDOMObject::executionContext();
395521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
396521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
397521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)const AtomicString& SourceBuffer::interfaceName() const
398521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
3991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return EventTargetNames::SourceBuffer;
400521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
401521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
402521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool SourceBuffer::isRemoved() const
403521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
404521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return !m_source;
405521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
406521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
407521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::scheduleEvent(const AtomicString& eventName)
408521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
409521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ASSERT(m_asyncEventQueue);
410521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
4118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    RefPtr<Event> event = Event::create(eventName);
412521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    event->setTarget(this);
413521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
414521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_asyncEventQueue->enqueueEvent(event.release());
415521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
416521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
41751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBufferInternal(const unsigned char* data, unsigned size, ExceptionState& exceptionState)
418521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
419521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.2 appendBuffer()
420521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
421521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
422521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Step 1 is enforced by the caller.
423e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // 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.
424e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // 3. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
425521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (isRemoved() || m_updating) {
42651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
427521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
428521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
429521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
4301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::appendBuffer", this);
4311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
432521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: ...
433521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_source->openIfInEndedState();
434521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
435521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Steps 5-6
436521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
437521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 7. Add data to the end of the input buffer.
438521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_pendingAppendData.append(data, size);
439521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
440521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 8. Set the updating attribute to true.
441521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_updating = true;
442521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
443521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 9. Queue a task to fire a simple event named updatestart at this SourceBuffer object.
4441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updatestart);
445521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
446521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 10. Asynchronously run the buffer append algorithm.
447f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendBufferAsyncPartRunner.runAsync();
4481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
44951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "waiting");
450521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
451521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
452f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::appendBufferAsyncPart()
453521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
454521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ASSERT(m_updating);
455521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
45651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "appending");
4571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
458521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Section 3.5.4 Buffer Append Algorithm
459521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-buffer-append
460521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
461521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 1. Run the segment parser loop algorithm.
462521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Step 2 doesn't apply since we run Step 1 synchronously here.
463591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    size_t appendSize = m_pendingAppendData.size();
464591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (!appendSize) {
465591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        // Resize buffer for 0 byte appends so we always have a valid pointer.
46651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // We need to convey all appends, even 0 byte ones to |m_webSourceBuffer|
46751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // so that it can clear its end of stream state if necessary.
468591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        m_pendingAppendData.resize(1);
469591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
47051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->append(m_pendingAppendData.data(), appendSize);
471521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
472521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3. Set the updating attribute to false.
473521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_updating = false;
474521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_pendingAppendData.clear();
475521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
476521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 4. Queue a task to fire a simple event named update at this SourceBuffer object.
4771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::update);
478521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
479521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 5. Queue a task to fire a simple event named updateend at this SourceBuffer object.
4801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updateend);
4811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
482521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
483521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
484f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::removeAsyncPart()
48523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch{
48623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    ASSERT(m_updating);
48723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    ASSERT(m_pendingRemoveStart >= 0);
48823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    ASSERT(m_pendingRemoveStart < m_pendingRemoveEnd);
48923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
49023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // Section 3.2 remove() method steps
49123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-remove-void-double-start-double-end
49223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
49323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 9. Run the coded frame removal algorithm with start and end as the start and end of the removal range.
49451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->remove(m_pendingRemoveStart, m_pendingRemoveEnd);
49523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
49623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 10. Set the updating attribute to false.
49723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_updating = false;
49823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveStart = -1;
49923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    m_pendingRemoveEnd = -1;
50023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
50123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 11. Queue a task to fire a simple event named update at this SourceBuffer object.
5021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::update);
50323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
50423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch    // 12. Queue a task to fire a simple event named updateend at this SourceBuffer object.
5051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updateend);
50623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch}
50723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch
50851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendStreamInternal(PassRefPtr<Stream> stream, ExceptionState& exceptionState)
50906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
51006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Section 3.2 appendStream()
51106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendStream-void-Stream-stream-unsigned-long-long-maxSize
51206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 1. If stream is null then throw an InvalidAccessError exception and abort these steps.
51306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!stream || stream->isNeutered()) {
51451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
51506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
51606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
51706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
51806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 2. Run the prepare append algorithm.
51906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //  Section 3.5.4 Prepare Append Algorithm.
52006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //  https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-prepare-append
52106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //  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.
52206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //  2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps.
52306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (isRemoved() || m_updating) {
52451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
52506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
52606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
52706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
5281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::appendStream", this);
5291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
53006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    //  3. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: ...
53106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_source->openIfInEndedState();
53206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
53351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Steps 4-5 of the prepare append algorithm are handled by m_webSourceBuffer.
53406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
53506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 3. Set the updating attribute to true.
53606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_updating = true;
53706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
53806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 4. Queue a task to fire a simple event named updatestart at this SourceBuffer object.
5391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updatestart);
54006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
54106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 5. Asynchronously run the stream append loop algorithm with stream and maxSize.
54206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
54306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    stream->neuter();
54406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_loader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadByClient, this));
54506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_stream = stream;
546f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    m_appendStreamAsyncPartRunner.runAsync();
54706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
54806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
549f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::appendStreamAsyncPart()
55006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
55106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_updating);
55206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_loader);
55306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_stream);
55406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
55506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Section 3.5.6 Stream Append Loop
55606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-stream-append-loop
55706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
55806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 1. If maxSize is set, then let bytesLeft equal maxSize.
55906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the loop done step below.
56006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (m_streamMaxSizeValid && !m_streamMaxSize) {
56106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        appendStreamDone(true);
56206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
56306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
56406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
56506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Steps 3-11 are handled by m_loader.
56606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the data in the stream).
5671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_loader->start(executionContext(), *m_stream, m_streamMaxSizeValid ? m_streamMaxSize : 0);
56806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
56906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
57006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::appendStreamDone(bool success)
57106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
57206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_updating);
57306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_loader);
57406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_stream);
57506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
57606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    clearAppendStreamState();
57706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
57806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!success) {
57906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // Section 3.5.3 Append Error Algorithm
58006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-append-error
58106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        //
58206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // 1. Run the reset parser state algorithm. (Handled by caller)
58306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // 2. Set the updating attribute to false.
58406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_updating = false;
58506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
58606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // 3. Queue a task to fire a simple event named error at this SourceBuffer object.
5871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleEvent(EventTypeNames::error);
58806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
58906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        // 4. Queue a task to fire a simple event named updateend at this SourceBuffer object.
5901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scheduleEvent(EventTypeNames::updateend);
5911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this);
59206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
59306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
59406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
59506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Section 3.5.6 Stream Append Loop
59651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_webSourceBuffer|.
59706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 12. Loop Done: Set the updating attribute to false.
59806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_updating = false;
59906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
60006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 13. Queue a task to fire a simple event named update at this SourceBuffer object.
6011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::update);
60206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
60306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // 14. Queue a task to fire a simple event named updateend at this SourceBuffer object.
6041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    scheduleEvent(EventTypeNames::updateend);
6051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this);
60606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
60706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
60806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::clearAppendStreamState()
60906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
61006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_streamMaxSizeValid = false;
61106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_streamMaxSize = 0;
61206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_loader.clear();
61306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    m_stream = 0;
61406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
61506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
61606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didStartLoading()
61706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
618a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    WTF_LOG(Media, "SourceBuffer::didStartLoading() %p", this);
61906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
62006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
62106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength)
62206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
623a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    WTF_LOG(Media, "SourceBuffer::didReceiveDataForClient(%d) %p", dataLength, this);
62406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_updating);
62506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT(m_loader);
62606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
62751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength);
62806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
62906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
63006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didFinishLoading()
63106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
632a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    WTF_LOG(Media, "SourceBuffer::didFinishLoading() %p", this);
63306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    appendStreamDone(true);
63406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
63506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
63606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didFail(FileError::ErrorCode errorCode)
63706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
638a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    WTF_LOG(Media, "SourceBuffer::didFail(%d) %p", errorCode, this);
63906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    appendStreamDone(false);
64006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
64106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
642521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} // namespace WebCore
643