Bug 1242841 - Make MDSM::mDecodedAudioEndTime zero-based. r=kikuo.
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -208,17 +208,17 @@ MediaDecoderStateMachine::MediaDecoderSt
mRealTime(aRealTime),
mDispatchedStateMachine(false),
mDelayedScheduler(mTaskQueue),
mState(DECODER_STATE_DECODING_NONE, "MediaDecoderStateMachine::mState"),
mCurrentFrameID(0),
mObservedDuration(TimeUnit(), "MediaDecoderStateMachine::mObservedDuration"),
mFragmentEndTime(-1),
mReader(aReader),
- mDecodedAudioEndTime(-1),
+ mDecodedAudioEndTime(0),
mDecodedVideoEndTime(-1),
mPlaybackRate(1.0),
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
mIsAudioPrerolling(false),
mIsVideoPrerolling(false),
mAudioCaptured(false),
@@ -419,19 +419,20 @@ bool MediaDecoderStateMachine::HaveNextF
(!HasVideo() || VideoQueue().GetSize() > 1);
}
int64_t
MediaDecoderStateMachine::GetDecodedAudioDuration()
{
MOZ_ASSERT(OnTaskQueue());
if (mMediaSink->IsStarted()) {
- // |mDecodedAudioEndTime == -1| means no decoded audio at all so the
- // returned duration is 0.
- return mDecodedAudioEndTime != -1 ? mDecodedAudioEndTime - GetClock() : 0;
+ // mDecodedAudioEndTime might be smaller than GetClock() when there is
+ // overlap between 2 adjacent audio samples or when we are playing
+ // a chained ogg file.
+ return std::max<int64_t>(mDecodedAudioEndTime - GetClock(), 0);
}
// MediaSink not started. All audio samples are in the queue.
return AudioQueue().Duration();
}
void MediaDecoderStateMachine::DiscardStreamData()
{
MOZ_ASSERT(OnTaskQueue());
@@ -601,17 +602,19 @@ MediaDecoderStateMachine::IsVideoSeekCom
void
MediaDecoderStateMachine::OnAudioDecoded(MediaData* aAudioSample)
{
MOZ_ASSERT(OnTaskQueue());
RefPtr<MediaData> audio(aAudioSample);
MOZ_ASSERT(audio);
mAudioDataRequest.Complete();
aAudioSample->AdjustForStartTime(StartTime());
- mDecodedAudioEndTime = audio->GetEndTime();
+
+ // audio->GetEndTime() is not always mono-increasing in chained ogg.
+ mDecodedAudioEndTime = std::max(audio->GetEndTime(), mDecodedAudioEndTime);
SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
(audio ? audio->mTime : -1),
(audio ? audio->GetEndTime() : -1),
(audio ? audio->mDiscontinuity : 0));
switch (mState) {
case DECODER_STATE_BUFFERING: {
@@ -1873,19 +1876,16 @@ bool MediaDecoderStateMachine::HasLowUnd
}
int64_t endOfDecodedVideoData = INT64_MAX;
if (HasVideo() && !VideoQueue().AtEndOfStream()) {
endOfDecodedVideoData = VideoQueue().Peek() ? VideoQueue().Peek()->GetEndTime() : VideoEndTime();
}
int64_t endOfDecodedAudioData = INT64_MAX;
if (HasAudio() && !AudioQueue().AtEndOfStream()) {
- // mDecodedAudioEndTime could be -1 when no audio samples are decoded.
- // But that is fine since we consider ourself as low in decoded data when
- // we don't have any decoded audio samples at all.
endOfDecodedAudioData = mDecodedAudioEndTime;
}
int64_t endOfDecodedData = std::min(endOfDecodedVideoData, endOfDecodedAudioData);
if (Duration().ToMicroseconds() < endOfDecodedData) {
// Our duration is not up to date. No point buffering.
return false;
}
media::TimeInterval interval(media::TimeUnit::FromMicroseconds(endOfDecodedData),
@@ -2385,17 +2385,17 @@ MediaDecoderStateMachine::Reset()
mState == DECODER_STATE_DECODING_NONE);
// Stop the audio thread. Otherwise, MediaSink might be accessing AudioQueue
// outside of the decoder monitor while we are clearing the queue and causes
// crash for no samples to be popped.
StopMediaSink();
mDecodedVideoEndTime = -1;
- mDecodedAudioEndTime = -1;
+ mDecodedAudioEndTime = 0;
mAudioCompleted = false;
mVideoCompleted = false;
AudioQueue().Reset();
VideoQueue().Reset();
mFirstVideoFrameAfterSeek = nullptr;
mDropAudioUntilNextDiscontinuity = true;
mDropVideoUntilNextDiscontinuity = true;
mDecodeToSeekTarget = false;