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) 34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionMessages.h" 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h" 367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/ExceptionCode.h" 371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h" 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/events/Event.h" 3906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/GenericEventQueue.h" 4006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/fileapi/FileReaderLoader.h" 41521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "core/html/TimeRanges.h" 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/streams/Stream.h" 43521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "modules/mediasource/MediaSource.h" 441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/Logging.h" 451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/TraceEvent.h" 4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebSourceBuffer.h" 47521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/ArrayBuffer.h" 48521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "wtf/ArrayBufferView.h" 493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "wtf/MathExtras.h" 503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include <limits> 52521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebSourceBuffer; 5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 56521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace { 58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static bool throwExceptionIfRemovedOrUpdating(bool isRemoved, bool isUpdating, ExceptionState& exceptionState) 60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isRemoved) { 62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "This SourceBuffer has been removed from the parent media source."); 63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return true; 64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isUpdating) { 66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "This SourceBuffer is still processing an 'appendBuffer', 'appendStream', or 'remove' operation."); 67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return true; 68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} // namespace 7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 75197021e6b966cfb06891637935ef33fff06433d1Ben MurdochSourceBuffer* SourceBuffer::create(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue) 76521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch SourceBuffer* sourceBuffer(adoptRefCountedGarbageCollectedWillBeNoop(new SourceBuffer(webSourceBuffer, source, asyncEventQueue))); 78521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) sourceBuffer->suspendIfNeeded(); 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return sourceBuffer; 80521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 81521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 8251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)SourceBuffer::SourceBuffer(PassOwnPtr<WebSourceBuffer> webSourceBuffer, MediaSource* source, GenericEventQueue* asyncEventQueue) 831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) : ActiveDOMObject(source->executionContext()) 8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) , m_webSourceBuffer(webSourceBuffer) 85521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_source(source) 86521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_asyncEventQueue(asyncEventQueue) 8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_mode(segmentsKeyword()) 88521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_updating(false) 89521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_timestampOffset(0) 903c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch , m_appendWindowStart(0) 913c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch , m_appendWindowEnd(std::numeric_limits<double>::infinity()) 927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_firstInitializationSegmentReceived(false) 93323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) , m_pendingAppendDataOffset(0) 94f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) , m_appendBufferAsyncPartRunner(this, &SourceBuffer::appendBufferAsyncPart) 9523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch , m_pendingRemoveStart(-1) 9623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch , m_pendingRemoveEnd(-1) 97f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) , m_removeAsyncPartRunner(this, &SourceBuffer::removeAsyncPart) 9806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) , m_streamMaxSizeValid(false) 9906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) , m_streamMaxSize(0) 100f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) , m_appendStreamAsyncPartRunner(this, &SourceBuffer::appendStreamAsyncPart) 101521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 10251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ASSERT(m_webSourceBuffer); 103521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ASSERT(m_source); 1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_webSourceBuffer->setClient(this); 105521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 106521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)SourceBuffer::~SourceBuffer() 108521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Oilpan: a SourceBuffer might be finalized without having been 110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // explicitly removed first, hence the asserts below will not 111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // hold. 112197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if !ENABLE(OILPAN) 113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ASSERT(isRemoved()); 11406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(!m_loader); 11506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(!m_stream); 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!m_webSourceBuffer); 117197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif 118521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 119521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const AtomicString& SourceBuffer::segmentsKeyword() 12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, segments, ("segments", AtomicString::ConstructFromLiteral)); 12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return segments; 12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const AtomicString& SourceBuffer::sequenceKeyword() 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) DEFINE_STATIC_LOCAL(const AtomicString, sequence, ("sequence", AtomicString::ConstructFromLiteral)); 12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return sequence; 13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SourceBuffer::setMode(const AtomicString& newMode, ExceptionState& exceptionState) 13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Section 3.1 On setting mode attribute steps. 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // 1. Let new mode equal the new value being assigned to this attribute. 136323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 2. If this object has been removed from the sourceBuffers attribute of the parent media source, then throw 13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // an INVALID_STATE_ERR exception and abort these steps. 138323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 3. If the updating attribute equals true, then throw an INVALID_STATE_ERR exception and abort these steps. 139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 142323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: 143323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4.1 Set the readyState attribute of the parent media source to "open" 144323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4.2 Queue a task to fire a simple event named sourceopen at the parent media source. 14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_source->openIfInEndedState(); 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 147323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an INVALID_STATE_ERR and abort these steps. 148323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 6. If the new mode equals "sequence", then set the group start timestamp to the highest presentation end timestamp. 14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebSourceBuffer::AppendMode appendMode = WebSourceBuffer::AppendModeSegments; 15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (newMode == sequenceKeyword()) 15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) appendMode = WebSourceBuffer::AppendModeSequence; 15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!m_webSourceBuffer->setMode(appendMode)) { 153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "The mode may not be set while the SourceBuffer's append state is 'PARSING_MEDIA_SEGMENT'."); 15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 157323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 7. Update the attribute to new mode. 15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_mode = newMode; 15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 161197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPassRefPtrWillBeRawPtr<TimeRanges> SourceBuffer::buffered(ExceptionState& exceptionState) const 162521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 163521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.1 buffered attribute steps. 164521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an 165e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // InvalidStateError exception and abort these steps. 166521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isRemoved()) { 167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "This SourceBuffer has been removed from the parent media source."); 168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 169521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 170521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 171521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 2. Return a new static normalized TimeRanges object for the media segments buffered. 17251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return TimeRanges::create(m_webSourceBuffer->buffered()); 173521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 174521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 175521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)double SourceBuffer::timestampOffset() const 176521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 177521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return m_timestampOffset; 178521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 179521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 18051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setTimestampOffset(double offset, ExceptionState& exceptionState) 181521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 182521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.1 timestampOffset attribute setter steps. 183323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-timestampOffset 18423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 1. Let new timestamp offset equal the new value being assigned to this attribute. 18523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 2. If this object has been removed from the sourceBuffers attribute of the parent media source, then throw an 186e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // InvalidStateError exception and abort these steps. 18723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 3. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 1891fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch return; 1901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch 191521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 4. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: 192521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 4.1 Set the readyState attribute of the parent media source to "open" 193521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 4.2 Queue a task to fire a simple event named sourceopen at the parent media source. 194521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_source->openIfInEndedState(); 195521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // 5. If the append state equals PARSING_MEDIA_SEGMENT, then throw an INVALID_STATE_ERR and abort these steps. 19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // 6. If the mode attribute equals "sequence", then set the group start timestamp to new timestamp offset. 19851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!m_webSourceBuffer->setTimestampOffset(offset)) { 199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "The timestamp offset may not be set while the SourceBuffer's append state is 'PARSING_MEDIA_SEGMENT'."); 200521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 201521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 202521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 20323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 7. Update the attribute to new timestamp offset. 204521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_timestampOffset = offset; 205521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 206521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 2073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochdouble SourceBuffer::appendWindowStart() const 2083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 2093c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return m_appendWindowStart; 2103c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 2113c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exceptionState) 2133c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 2143c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // Section 3.1 appendWindowStart attribute setter steps. 215323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-appendWindowStart 2163c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an 2173c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // InvalidStateError exception and abort these steps. 2183c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 2203c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return; 2213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 2223c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 3. If the new value is less than 0 or greater than or equal to appendWindowEnd then throw an InvalidAccessError 2233c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // exception and abort these steps. 2243c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (start < 0 || start >= m_appendWindowEnd) { 225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexOutsideRange("value", start, 0.0, ExceptionMessages::ExclusiveBound, m_appendWindowEnd, ExceptionMessages::InclusiveBound)); 2263c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return; 2273c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } 2283c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 22951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer->setAppendWindowStart(start); 2303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 2313c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 4. Update the attribute to the new value. 2323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_appendWindowStart = start; 2333c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 2343c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 2353c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochdouble SourceBuffer::appendWindowEnd() const 2363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 2373c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return m_appendWindowEnd; 2383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 2393c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 24051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::setAppendWindowEnd(double end, ExceptionState& exceptionState) 2413c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{ 2423c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // Section 3.1 appendWindowEnd attribute setter steps. 243323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-appendWindowEnd 2443c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an 2453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // InvalidStateError exception and abort these steps. 2463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 2483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return; 2493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 2503c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 3. If the new value equals NaN, then throw an InvalidAccessError and abort these steps. 251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (std::isnan(end)) { 252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::notAFiniteNumber(end)); 253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 255323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4. If the new value is less than or equal to appendWindowStart then throw an InvalidAccessError 256323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // exception and abort these steps. 257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (end <= m_appendWindowStart) { 258f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("value", end, m_appendWindowStart)); 2593c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch return; 2603c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch } 2613c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 26251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer->setAppendWindowEnd(end); 2633c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 2643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 5. Update the attribute to the new value. 2653c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch m_appendWindowEnd = end; 2663c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch} 2673c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBuffer(PassRefPtr<ArrayBuffer> data, ExceptionState& exceptionState) 269521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 270521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.2 appendBuffer() 271521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data 27251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) appendBufferInternal(static_cast<const unsigned char*>(data->data()), data->byteLength(), exceptionState); 273521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 274521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 27551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBuffer(PassRefPtr<ArrayBufferView> data, ExceptionState& exceptionState) 276521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 277521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.2 appendBuffer() 278521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data 27951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) appendBufferInternal(static_cast<const unsigned char*>(data->baseAddress()), data->byteLength(), exceptionState); 28006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 28106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SourceBuffer::appendStream(PassRefPtrWillBeRawPtr<Stream> stream, ExceptionState& exceptionState) 28306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 28406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_streamMaxSizeValid = false; 28551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) appendStreamInternal(stream, exceptionState); 28606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 28706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SourceBuffer::appendStream(PassRefPtrWillBeRawPtr<Stream> stream, unsigned long long maxSize, ExceptionState& exceptionState) 28906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 29006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_streamMaxSizeValid = maxSize > 0; 29106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (m_streamMaxSizeValid) 29206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_streamMaxSize = maxSize; 29351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) appendStreamInternal(stream, exceptionState); 294521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 295521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 29651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::abort(ExceptionState& exceptionState) 297521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 298521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.2 abort() method steps. 299521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-abort-void 300521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 1. If this object has been removed from the sourceBuffers attribute of the parent media source 301e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // then throw an InvalidStateError exception and abort these steps. 302521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 2. If the readyState attribute of the parent media source is not in the "open" state 303e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // then throw an InvalidStateError exception and abort these steps. 304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isRemoved()) { 305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "This SourceBuffer has been removed from the parent media source."); 306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!m_source->isOpen()) { 309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "The parent media source's readyState is not 'open'."); 310521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 311521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 312521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 313521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3. If the sourceBuffer.updating attribute equals true, then run the following steps: ... 314521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) abortIfUpdating(); 315521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 316521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 4. Run the reset parser state algorithm. 31751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer->abort(); 318521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 3193c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 5. Set appendWindowStart to 0. 32051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) setAppendWindowStart(0, exceptionState); 3213c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 3223c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // 6. Set appendWindowEnd to positive Infinity. 32351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) setAppendWindowEnd(std::numeric_limits<double>::infinity(), exceptionState); 324521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 325521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 32651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::remove(double start, double end, ExceptionState& exceptionState) 32723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch{ 32823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // Section 3.2 remove() method steps. 329e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 1. If duration equals NaN, then throw an InvalidAccessError exception and abort these steps. 330e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 2. If start is negative or greater than duration, then throw an InvalidAccessError exception and abort these steps. 331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 332d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (start < 0 || (m_source && (std::isnan(m_source->duration()) || start > m_source->duration()))) { 333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexOutsideRange("start", start, 0.0, ExceptionMessages::ExclusiveBound, !m_source || std::isnan(m_source->duration()) ? 0 : m_source->duration(), ExceptionMessages::ExclusiveBound)); 334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 336e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 337e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 3. If end is less than or equal to start or end equals NaN, then throw an InvalidAccessError exception and abort these steps. 338e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) if (end <= start || std::isnan(end)) { 339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, "The end value provided (" + String::number(end) + ") must be greater than the start value provided (" + String::number(start) + ")."); 34023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch return; 34123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch } 34223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 343e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 4. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an 34423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // InvalidStateError exception and abort these steps. 345e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 5. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 34723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch return; 34823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 3491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::remove", this); 3501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 351e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 6. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: 352e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 6.1. Set the readyState attribute of the parent media source to "open" 353e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 6.2. Queue a task to fire a simple event named sourceopen at the parent media source . 35423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_source->openIfInEndedState(); 35523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 356e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 7. Run the range removal algorithm with start and end as the start and end of the removal range. 357e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 7.3. Set the updating attribute to true. 35823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_updating = true; 35923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 360e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 7.4. Queue a task to fire a simple event named updatestart at this SourceBuffer object. 3611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updatestart); 36223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 363e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) // 7.5. Return control to the caller and run the rest of the steps asynchronously. 36423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveStart = start; 36523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveEnd = end; 366f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_removeAsyncPartRunner.runAsync(); 36723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch} 368521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 369521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::abortIfUpdating() 370521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 371521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.2 abort() method step 3 substeps. 372521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-abort-void 373521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 374521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!m_updating) 375521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 376521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 3771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const char* traceEventName = 0; 3781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!m_pendingAppendData.isEmpty()) { 3791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) traceEventName = "SourceBuffer::appendBuffer"; 3801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } else if (m_stream) { 3811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) traceEventName = "SourceBuffer::appendStream"; 3821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } else if (m_pendingRemoveStart != -1) { 3831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) traceEventName = "SourceBuffer::remove"; 3841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } else { 3851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT_NOT_REACHED(); 3861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 3871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 388521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3.1. Abort the buffer append and stream append loop algorithms if they are running. 389f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendBufferAsyncPartRunner.stop(); 390521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_pendingAppendData.clear(); 391323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_pendingAppendDataOffset = 0; 392521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 393f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_removeAsyncPartRunner.stop(); 39423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveStart = -1; 39523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveEnd = -1; 39623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 397f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendStreamAsyncPartRunner.stop(); 39806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) clearAppendStreamState(); 39906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 400521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3.2. Set the updating attribute to false. 401521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_updating = false; 402521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 403521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3.3. Queue a task to fire a simple event named abort at this SourceBuffer object. 4041e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::abort); 405521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 406521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3.4. Queue a task to fire a simple event named updateend at this SourceBuffer object. 4071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updateend); 4081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 4091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("media", traceEventName, this); 410521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 411521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 412521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::removedFromMediaSource() 413521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 414521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isRemoved()) 415521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 416521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 41723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch abortIfUpdating(); 41823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 41951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer->removedFromMediaSource(); 42051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer.clear(); 421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_source = nullptr; 422521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_asyncEventQueue = 0; 423521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 424521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 4257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid SourceBuffer::initializationSegmentReceived() 4267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 4277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_source); 4287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_updating); 4297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 4307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer-init-segment-received 4317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Make steps 1-7 synchronous with this call. 4327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Augment the interface to this method to implement compliant steps 4-7 here. 4337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Step 3 (if the first initialization segment received flag is true) is 4347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // implemented by caller. 4357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 4367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_firstInitializationSegmentReceived) { 4377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 5. If active track flag equals true, then run the following steps: 4387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 5.1. Add this SourceBuffer to activeSourceBuffers. 4397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 5.2. Queue a task to fire a simple event named addsourcebuffer at 4407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // activesourcebuffers. 4417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_source->setSourceBufferActive(this); 4427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 4437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 6. Set first initialization segment received flag to true. 4447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_firstInitializationSegmentReceived = true; 4457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 4467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 4477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 448521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool SourceBuffer::hasPendingActivity() const 449521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 450521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return m_source; 451521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 452521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 453f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::suspend() 454f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 455f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendBufferAsyncPartRunner.suspend(); 456f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_removeAsyncPartRunner.suspend(); 457f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendStreamAsyncPartRunner.suspend(); 458f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 459f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 460f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::resume() 461f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 462f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendBufferAsyncPartRunner.resume(); 463f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_removeAsyncPartRunner.resume(); 464f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendStreamAsyncPartRunner.resume(); 465f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 466f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 467521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::stop() 468521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 469f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendBufferAsyncPartRunner.stop(); 470f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_removeAsyncPartRunner.stop(); 471f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendStreamAsyncPartRunner.stop(); 472521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 473521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 4741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)ExecutionContext* SourceBuffer::executionContext() const 475521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 4761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return ActiveDOMObject::executionContext(); 477521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 478521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 479521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)const AtomicString& SourceBuffer::interfaceName() const 480521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 4811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return EventTargetNames::SourceBuffer; 482521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 483521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 484521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool SourceBuffer::isRemoved() const 485521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 486521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return !m_source; 487521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 488521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 489521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void SourceBuffer::scheduleEvent(const AtomicString& eventName) 490521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 491521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ASSERT(m_asyncEventQueue); 492521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 493a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtrWillBeRawPtr<Event> event = Event::create(eventName); 494521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) event->setTarget(this); 495521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 496521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_asyncEventQueue->enqueueEvent(event.release()); 497521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 498521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 49951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void SourceBuffer::appendBufferInternal(const unsigned char* data, unsigned size, ExceptionState& exceptionState) 500521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 501521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.2 appendBuffer() 502521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data 503521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 504323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 1. Run the prepare append algorithm. 505323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-prepare-append 506323480423219ecd77329f8326dc5e0e3b50926d4Torne (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. 507323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 508d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 509521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 510521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 511323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size", size); 5121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 513323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 3. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: ... 514521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_source->openIfInEndedState(); 515521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 516323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Steps 4-5 - end "prepare append" algorithm. 517521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 518323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 2. Add data to the end of the input buffer. 519323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(data || size == 0); 520323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (data) 521323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_pendingAppendData.append(data, size); 522323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_pendingAppendDataOffset = 0; 523521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 524323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 3. Set the updating attribute to true. 525521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_updating = true; 526521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 527323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4. Queue a task to fire a simple event named updatestart at this SourceBuffer object. 5281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updatestart); 529521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 530323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 5. Asynchronously run the buffer append algorithm. 531f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendBufferAsyncPartRunner.runAsync(); 5321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 533323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "initialDelay"); 534521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 535521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 536f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::appendBufferAsyncPart() 537521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 538521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) ASSERT(m_updating); 539521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 540521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Section 3.5.4 Buffer Append Algorithm 541521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-buffer-append 542521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 543521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 1. Run the segment parser loop algorithm. 544521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Step 2 doesn't apply since we run Step 1 synchronously here. 545323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(m_pendingAppendData.size() >= m_pendingAppendDataOffset); 546323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) size_t appendSize = m_pendingAppendData.size() - m_pendingAppendDataOffset; 547323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 548323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Impose an arbitrary max size for a single append() call so that an append 549323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // doesn't block the renderer event loop very long. This value was selected 550323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // by looking at YouTube SourceBuffer usage across a variety of bitrates. 551323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // This value allows relatively large appends while keeping append() call 552323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // duration in the ~5-15ms range. 553323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) const size_t MaxAppendSize = 128 * 1024; 554323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (appendSize > MaxAppendSize) 555323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) appendSize = MaxAppendSize; 556323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 557323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this, "appending", "appendSize", static_cast<unsigned>(appendSize)); 558323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 559323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // |zero| is used for 0 byte appends so we always have a valid pointer. 560323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // We need to convey all appends, even 0 byte ones to |m_webSourceBuffer| 561323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // so that it can clear its end of stream state if necessary. 562323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) unsigned char zero = 0; 563323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) unsigned char* appendData = &zero; 564323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (appendSize) 565323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) appendData = m_pendingAppendData.data() + m_pendingAppendDataOffset; 566323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 567323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_webSourceBuffer->append(appendData, appendSize, &m_timestampOffset); 568323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 569323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_pendingAppendDataOffset += appendSize; 570323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 571323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (m_pendingAppendDataOffset < m_pendingAppendData.size()) { 572323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_appendBufferAsyncPartRunner.runAsync(); 573323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "nextPieceDelay"); 574323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return; 575591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 576521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 577521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3. Set the updating attribute to false. 578521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_updating = false; 579521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_pendingAppendData.clear(); 580323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_pendingAppendDataOffset = 0; 581521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 582521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 4. Queue a task to fire a simple event named update at this SourceBuffer object. 5831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::update); 584521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 585521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 5. Queue a task to fire a simple event named updateend at this SourceBuffer object. 5861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updateend); 5871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this); 588521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 589521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 590f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::removeAsyncPart() 59123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch{ 59223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch ASSERT(m_updating); 59323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch ASSERT(m_pendingRemoveStart >= 0); 59423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch ASSERT(m_pendingRemoveStart < m_pendingRemoveEnd); 59523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 59623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // Section 3.2 remove() method steps 59723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-remove-void-double-start-double-end 59823e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 59923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 9. Run the coded frame removal algorithm with start and end as the start and end of the removal range. 60051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) m_webSourceBuffer->remove(m_pendingRemoveStart, m_pendingRemoveEnd); 60123e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 60223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 10. Set the updating attribute to false. 60323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_updating = false; 60423e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveStart = -1; 60523e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch m_pendingRemoveEnd = -1; 60623e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 60723e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 11. Queue a task to fire a simple event named update at this SourceBuffer object. 6081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::update); 60923e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 61023e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch // 12. Queue a task to fire a simple event named updateend at this SourceBuffer object. 6111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updateend); 61223e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch} 61323e46e0f045bc1935a09565578b448d36cfc5b8cBen Murdoch 614d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void SourceBuffer::appendStreamInternal(PassRefPtrWillBeRawPtr<Stream> stream, ExceptionState& exceptionState) 61506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 61606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Section 3.2 appendStream() 61706f816c7c76bc45a15e452ade8a34e8af077693eTorne (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 618323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // (0. If the stream has been neutered, then throw an InvalidAccessError exception and abort these steps.) 619323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (stream->isNeutered()) { 620323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) exceptionState.throwDOMException(InvalidAccessError, "The stream provided has been neutered."); 62106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return; 62206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 62306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 624323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 1. Run the prepare append algorithm. 62506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Section 3.5.4 Prepare Append Algorithm. 62606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-prepare-append 62706f816c7c76bc45a15e452ade8a34e8af077693eTorne (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. 62806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. 629d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) 63006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return; 63106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 6321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::appendStream", this); 6331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 63406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 3. If the readyState attribute of the parent media source is in the "ended" state then run the following steps: ... 63506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_source->openIfInEndedState(); 63606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 63751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Steps 4-5 of the prepare append algorithm are handled by m_webSourceBuffer. 63806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 639323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 2. Set the updating attribute to true. 64006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_updating = true; 64106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 642323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 3. Queue a task to fire a simple event named updatestart at this SourceBuffer object. 6431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updatestart); 64406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 645323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // 4. Asynchronously run the stream append loop algorithm with stream and maxSize. 64606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 64706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) stream->neuter(); 64806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_loader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadByClient, this)); 64906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_stream = stream; 650f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) m_appendStreamAsyncPartRunner.runAsync(); 65106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 65206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 653f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void SourceBuffer::appendStreamAsyncPart() 65406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 65506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_updating); 65606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_loader); 65706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_stream); 65806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 65906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Section 3.5.6 Stream Append Loop 66006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-stream-append-loop 66106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 66206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 1. If maxSize is set, then let bytesLeft equal maxSize. 66306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the loop done step below. 66406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (m_streamMaxSizeValid && !m_streamMaxSize) { 66506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) appendStreamDone(true); 66606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return; 66706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 66806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 66906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Steps 3-11 are handled by m_loader. 67006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Note: Passing 0 here signals that maxSize was not set. (i.e. Read all the data in the stream). 6711e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) m_loader->start(executionContext(), *m_stream, m_streamMaxSizeValid ? m_streamMaxSize : 0); 67206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 67306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 67406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::appendStreamDone(bool success) 67506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 67606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_updating); 67706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_loader); 67806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_stream); 67906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 68006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) clearAppendStreamState(); 68106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 68206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (!success) { 68306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Section 3.5.3 Append Error Algorithm 68406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-append-error 68506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 68606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 1. Run the reset parser state algorithm. (Handled by caller) 68706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 2. Set the updating attribute to false. 68806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_updating = false; 68906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 69006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 3. Queue a task to fire a simple event named error at this SourceBuffer object. 6911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::error); 69206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 69306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 4. Queue a task to fire a simple event named updateend at this SourceBuffer object. 6941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updateend); 6951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); 69606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return; 69706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 69806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 69906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // Section 3.5.6 Stream Append Loop 70051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Steps 1-11 are handled by appendStreamAsyncPart(), |m_loader|, and |m_webSourceBuffer|. 70106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 12. Loop Done: Set the updating attribute to false. 70206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_updating = false; 70306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 70406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 13. Queue a task to fire a simple event named update at this SourceBuffer object. 7051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::update); 70606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 70706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) // 14. Queue a task to fire a simple event named updateend at this SourceBuffer object. 7081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) scheduleEvent(EventTypeNames::updateend); 7091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this); 71006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 71106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 71206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::clearAppendStreamState() 71306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 71406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_streamMaxSizeValid = false; 71506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_streamMaxSize = 0; 71606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) m_loader.clear(); 717d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_stream = nullptr; 71806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 71906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 72006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didStartLoading() 72106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 722a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(Media, "SourceBuffer::didStartLoading() %p", this); 72306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 72406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 72506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength) 72606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 727a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(Media, "SourceBuffer::didReceiveDataForClient(%d) %p", dataLength, this); 72806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_updating); 72906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) ASSERT(m_loader); 730d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength, &m_timestampOffset); 73106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 73206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 73306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didFinishLoading() 73406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 735a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(Media, "SourceBuffer::didFinishLoading() %p", this); 73606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) appendStreamDone(true); 73706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 73806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 73906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void SourceBuffer::didFail(FileError::ErrorCode errorCode) 74006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){ 741a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) WTF_LOG(Media, "SourceBuffer::didFail(%d) %p", errorCode, this); 74206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) appendStreamDone(false); 74306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 74406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 74509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SourceBuffer::trace(Visitor* visitor) 74609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 74709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) visitor->trace(m_source); 748d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) visitor->trace(m_stream); 749d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) EventTargetWithInlineData::trace(visitor); 75009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 75109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 752c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 753