diff --git a/dom/media/ReaderProxy.cpp b/dom/media/ReaderProxy.cpp index 463485d309e0..6d64cb552c83 100644 --- a/dom/media/ReaderProxy.cpp +++ b/dom/media/ReaderProxy.cpp @@ -62,8 +62,9 @@ ReaderProxy::OnAudioDataRequestCompleted(RefPtr aAudio) int64_t offset = StartTime().ToMicroseconds() - mLoopingOffset.ToMicroseconds(); aAudio->AdjustForStartTime(offset); - if (aAudio->mTime.IsValid() && aAudio->GetEndTime().IsValid()) { - mLastAudioEndTime = aAudio->GetEndTime(); + if (aAudio->mTime.IsValid() && aAudio->GetEndTime().IsValid() && + CorrectTimeOfAudioDataIfNeeded(aAudio)) { + UpdateLastAudioEndTime(aAudio); return AudioDataPromise::CreateAndResolve(aAudio.forget(), __func__); } return AudioDataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, @@ -114,6 +115,28 @@ ReaderProxy::OnAudioDataRequestFailed(const MediaResult& aError) }); } +bool +ReaderProxy::CorrectTimeOfAudioDataIfNeeded(const RefPtr& aAudio) +{ + MOZ_ASSERT(aAudio->mTime.IsValid() && mLastAudioEndTime.IsValid()); + // The start time of the current audio data should be greater than the end + // time of the previous audio data. + if (aAudio->mTime < mLastAudioEndTime) { + aAudio->mTime = mLastAudioEndTime; + } + return aAudio->GetEndTime().IsValid(); +} + +void +ReaderProxy::UpdateLastAudioEndTime(const AudioData* aAudio) +{ + MOZ_ASSERT(aAudio); + MOZ_ASSERT(aAudio->GetEndTime().IsValid() && mLastAudioEndTime.IsValid()); + // Make sure the end time of the audio data are non-decreasing. + MOZ_ASSERT(aAudio->GetEndTime() >= mLastAudioEndTime); + mLastAudioEndTime = aAudio->GetEndTime(); +} + RefPtr ReaderProxy::RequestAudioData() { diff --git a/dom/media/ReaderProxy.h b/dom/media/ReaderProxy.h index 921897fdca1c..4e00c03a1cae 100644 --- a/dom/media/ReaderProxy.h +++ b/dom/media/ReaderProxy.h @@ -100,6 +100,12 @@ private: RefPtr OnAudioDataRequestFailed( const MediaResult& aError); + // Make sure the timestamp of the audio data increase monotonically by + // adjusting it according to mLastAudioEndTime. Returns true if the + // endtime is valid after correction and false otherwise. + bool CorrectTimeOfAudioDataIfNeeded(const RefPtr& aAudio); + void UpdateLastAudioEndTime(const AudioData* aAudio); + const RefPtr mOwnerThread; const RefPtr mReader;