| Index: third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
|
| diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
|
| index 67c78a8aed7ce736b973dbfe9fed580971a26836..7eb17a9ac1aec9c2930bb0143851ffb9058ff42d 100644
|
| --- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
|
| +++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
|
| @@ -816,26 +816,33 @@ void SourceBuffer::appendBufferAsyncPart()
|
| if (appendSize)
|
| appendData = m_pendingAppendData.data() + m_pendingAppendDataOffset;
|
|
|
| - m_webSourceBuffer->append(appendData, appendSize, &m_timestampOffset);
|
| + bool appendSuccess = m_webSourceBuffer->append(appendData, appendSize, &m_timestampOffset);
|
|
|
| - m_pendingAppendDataOffset += appendSize;
|
| + if (!appendSuccess) {
|
| + m_pendingAppendData.clear();
|
| + m_pendingAppendDataOffset = 0;
|
| + appendError(DecodeError);
|
| + } else {
|
| + m_pendingAppendDataOffset += appendSize;
|
|
|
| - if (m_pendingAppendDataOffset < m_pendingAppendData.size()) {
|
| - m_appendBufferAsyncPartRunner->runAsync();
|
| - TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "nextPieceDelay");
|
| - return;
|
| - }
|
| + if (m_pendingAppendDataOffset < m_pendingAppendData.size()) {
|
| + m_appendBufferAsyncPartRunner->runAsync();
|
| + TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this, "nextPieceDelay");
|
| + return;
|
| + }
|
|
|
| - // 3. Set the updating attribute to false.
|
| - m_updating = false;
|
| - m_pendingAppendData.clear();
|
| - m_pendingAppendDataOffset = 0;
|
| + // 3. Set the updating attribute to false.
|
| + m_updating = false;
|
| + m_pendingAppendData.clear();
|
| + m_pendingAppendDataOffset = 0;
|
|
|
| - // 4. Queue a task to fire a simple event named update at this SourceBuffer object.
|
| - scheduleEvent(EventTypeNames::update);
|
| + // 4. Queue a task to fire a simple event named update at this SourceBuffer object.
|
| + scheduleEvent(EventTypeNames::update);
|
| +
|
| + // 5. Queue a task to fire a simple event named updateend at this SourceBuffer object.
|
| + scheduleEvent(EventTypeNames::updateend);
|
| + }
|
|
|
| - // 5. Queue a task to fire a simple event named updateend at this SourceBuffer object.
|
| - scheduleEvent(EventTypeNames::updateend);
|
| TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
|
| SBLOG << __FUNCTION__ << " done. this=" << this << " buffered=" << webTimeRangesToString(m_webSourceBuffer->buffered());
|
| }
|
| @@ -910,7 +917,7 @@ void SourceBuffer::appendStreamAsyncPart()
|
| // 1. If maxSize is set, then let bytesLeft equal maxSize.
|
| // 2. Loop Top: If maxSize is set and bytesLeft equals 0, then jump to the loop done step below.
|
| if (m_streamMaxSizeValid && !m_streamMaxSize) {
|
| - appendStreamDone(true);
|
| + appendStreamDone(NoError);
|
| return;
|
| }
|
|
|
| @@ -919,7 +926,7 @@ void SourceBuffer::appendStreamAsyncPart()
|
| m_loader->start(getExecutionContext(), *m_stream, m_streamMaxSizeValid ? m_streamMaxSize : 0);
|
| }
|
|
|
| -void SourceBuffer::appendStreamDone(bool success)
|
| +void SourceBuffer::appendStreamDone(AppendStreamDoneAction action)
|
| {
|
| DCHECK(m_updating);
|
| DCHECK(m_loader);
|
| @@ -927,8 +934,14 @@ void SourceBuffer::appendStreamDone(bool success)
|
|
|
| clearAppendStreamState();
|
|
|
| - if (!success) {
|
| - appendError(false);
|
| + if (action != NoError) {
|
| + if (action == RunAppendErrorWithNoDecodeError) {
|
| + appendError(NoDecodeError);
|
| + } else {
|
| + DCHECK_EQ(action, RunAppendErrorWithDecodeError);
|
| + appendError(DecodeError);
|
| + }
|
| +
|
| TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendStream", this);
|
| return;
|
| }
|
| @@ -956,9 +969,9 @@ void SourceBuffer::clearAppendStreamState()
|
| m_stream = nullptr;
|
| }
|
|
|
| -void SourceBuffer::appendError(bool decodeError)
|
| +void SourceBuffer::appendError(AppendError err)
|
| {
|
| - SBLOG << __FUNCTION__ << " this=" << this << " decodeError=" << decodeError;
|
| + SBLOG << __FUNCTION__ << " this=" << this << " AppendError=" << err;
|
| // Section 3.5.3 Append Error Algorithm
|
| // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-append-error
|
|
|
| @@ -976,8 +989,12 @@ void SourceBuffer::appendError(bool decodeError)
|
|
|
| // 5. If decode error is true, then run the end of stream algorithm with the
|
| // error parameter set to "decode".
|
| - if (decodeError)
|
| + if (err == DecodeError) {
|
| m_source->endOfStream("decode", ASSERT_NO_EXCEPTION);
|
| + } else {
|
| + DCHECK_EQ(err, NoDecodeError);
|
| + // Nothing else to do in this case.
|
| + }
|
| }
|
|
|
| void SourceBuffer::didStartLoading()
|
| @@ -997,28 +1014,30 @@ void SourceBuffer::didReceiveDataForClient(const char* data, unsigned dataLength
|
| // 10. Run the coded frame eviction algorithm.
|
| if (!evictCodedFrames(dataLength)) {
|
| // 11. (in appendStreamDone) If the buffer full flag equals true, then run the append error algorithm with the decode error parameter set to false and abort this algorithm.
|
| - appendStreamDone(false);
|
| + appendStreamDone(RunAppendErrorWithNoDecodeError);
|
| return;
|
| }
|
|
|
| - m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength, &m_timestampOffset);
|
| + if (!m_webSourceBuffer->append(reinterpret_cast<const unsigned char*>(data), dataLength, &m_timestampOffset))
|
| + appendStreamDone(RunAppendErrorWithDecodeError);
|
| }
|
|
|
| void SourceBuffer::didFinishLoading()
|
| {
|
| SBLOG << __FUNCTION__ << " this=" << this;
|
| DCHECK(m_loader);
|
| - appendStreamDone(true);
|
| + appendStreamDone(NoError);
|
| }
|
|
|
| void SourceBuffer::didFail(FileError::ErrorCode errorCode)
|
| {
|
| SBLOG << __FUNCTION__ << " this=" << this << " errorCode=" << errorCode;
|
| // m_loader might be already released, in case appendStream has failed due
|
| - // to evictCodedFrames failing in didReceiveDataForClient. In that case
|
| - // appendStreamDone will be invoked from there, no need to repeat it here.
|
| + // to evictCodedFrames or WebSourceBuffer append failing in
|
| + // didReceiveDataForClient. In that case appendStreamDone will be invoked
|
| + // from there, no need to repeat it here.
|
| if (m_loader)
|
| - appendStreamDone(false);
|
| + appendStreamDone(RunAppendErrorWithNoDecodeError);
|
| }
|
|
|
| DEFINE_TRACE(SourceBuffer)
|
|
|