diff --git a/content/media/mediasource/SourceBuffer.cpp b/content/media/mediasource/SourceBuffer.cpp index 8889fdb1c561..f6575a16caf3 100644 --- a/content/media/mediasource/SourceBuffer.cpp +++ b/content/media/mediasource/SourceBuffer.cpp @@ -583,15 +583,9 @@ void SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv) { MSE_DEBUG("SourceBuffer(%p)::AppendData(aLength=%u)", this, aLength); - if (!IsAttached() || mUpdating) { - aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + if (!PrepareAppend(aRv)) { return; } - if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) { - mMediaSource->SetReadyState(MediaSourceReadyState::Open); - } - // TODO: Run coded frame eviction algorithm. - // TODO: Test buffer full flag. StartUpdating(); // TODO: Run more of the buffer append algorithm asynchronously. if (mParser->IsInitSegmentPresent(aData, aLength)) { @@ -647,6 +641,28 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR return; } + // Schedule the state machine thread to ensure playback starts + // if required when data is appended. + mMediaSource->GetDecoder()->ScheduleStateMachineThread(); + + // Run the final step of the buffer append algorithm asynchronously to + // ensure the SourceBuffer's updating flag transition behaves as required + // by the spec. + nsCOMPtr event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating); + NS_DispatchToMainThread(event); +} + +bool +SourceBuffer::PrepareAppend(ErrorResult& aRv) +{ + if (!IsAttached() || mUpdating) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return false; + } + if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) { + mMediaSource->SetReadyState(MediaSourceReadyState::Open); + } + // Eviction uses a byte threshold. If the buffer is greater than the // number of bytes then data is evicted. The time range for this // eviction is reported back to the media source. It will then @@ -665,15 +681,8 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR mMediaSource->NotifyEvicted(0.0, GetBufferedStart()); } - // Run the final step of the buffer append algorithm asynchronously to - // ensure the SourceBuffer's updating flag transition behaves as required - // by the spec. - nsCOMPtr event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating); - NS_DispatchToMainThread(event); - - // Schedule the state machine thread to ensure playback starts - // if required when data is appended. - mMediaSource->GetDecoder()->ScheduleStateMachineThread(); + // TODO: Test buffer full flag. + return true; } double diff --git a/content/media/mediasource/SourceBuffer.h b/content/media/mediasource/SourceBuffer.h index 078422fd9a77..aa4e2f068b66 100644 --- a/content/media/mediasource/SourceBuffer.h +++ b/content/media/mediasource/SourceBuffer.h @@ -135,6 +135,10 @@ private: // Shared implementation of AppendBuffer overloads. void AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv); + // Implements the "Prepare Append Algorithm". Returns true if the append + // may continue, or false (with aRv set) on error. + bool PrepareAppend(ErrorResult& aRv); + nsRefPtr mMediaSource; const nsCString mType;