Bug 1172830 - Move buffering check out of MediaDecoderStateMachine::UpdateRenderedVideoFrames(). r=cpearce.

This commit is contained in:
JW Wang 2015-09-15 17:47:26 +08:00
Родитель fa740cbb49
Коммит 6064385135
2 изменённых файлов: 34 добавлений и 24 удалений

Просмотреть файл

@ -699,6 +699,7 @@ MediaDecoderStateMachine::OnAudioPopped(const nsRefPtr<MediaData>& aSample)
mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset);
UpdateNextFrameStatus();
DispatchAudioDecodeTaskIfNeeded();
MaybeStartBuffering();
}
void
@ -709,6 +710,7 @@ MediaDecoderStateMachine::OnVideoPopped(const nsRefPtr<MediaData>& aSample)
mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset);
UpdateNextFrameStatus();
DispatchVideoDecodeTaskIfNeeded();
MaybeStartBuffering();
}
void
@ -1097,6 +1099,34 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
DispatchDecodeTasksIfNeeded();
}
void
MediaDecoderStateMachine::MaybeStartBuffering()
{
MOZ_ASSERT(OnTaskQueue());
AssertCurrentThreadInMonitor();
if (mState == DECODER_STATE_DECODING &&
mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
mResource->IsExpectingMoreData()) {
bool shouldBuffer;
if (mReader->UseBufferingHeuristics()) {
shouldBuffer = HasLowDecodedData(EXHAUSTED_DATA_MARGIN_USECS) &&
(JustExitedQuickBuffering() || HasLowUndecodedData());
} else {
MOZ_ASSERT(mReader->IsWaitForDataSupported());
shouldBuffer = (OutOfDecodedAudio() && mAudioWaitRequest.Exists()) ||
(OutOfDecodedVideo() && mVideoWaitRequest.Exists());
}
if (shouldBuffer) {
StartBuffering();
// Don't go straight back to the state machine loop since that might
// cause us to start decoding again and we could flip-flop between
// decoding and quick-buffering.
ScheduleStateMachineIn(USECS_PER_S);
}
}
}
void MediaDecoderStateMachine::UpdatePlaybackPositionInternal(int64_t aTime)
{
MOZ_ASSERT(OnTaskQueue());
@ -2612,30 +2642,6 @@ void MediaDecoderStateMachine::UpdateRenderedVideoFrames()
RenderVideoFrames(sVideoQueueSendToCompositorSize, clockTime, nowTime);
// Check to see if we don't have enough data to play up to the next frame.
// If we don't, switch to buffering mode.
if (mState == DECODER_STATE_DECODING &&
mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
mResource->IsExpectingMoreData()) {
bool shouldBuffer;
if (mReader->UseBufferingHeuristics()) {
shouldBuffer = HasLowDecodedData(EXHAUSTED_DATA_MARGIN_USECS) &&
(JustExitedQuickBuffering() || HasLowUndecodedData());
} else {
MOZ_ASSERT(mReader->IsWaitForDataSupported());
shouldBuffer = (OutOfDecodedAudio() && mAudioWaitRequest.Exists()) ||
(OutOfDecodedVideo() && mVideoWaitRequest.Exists());
}
if (shouldBuffer) {
StartBuffering();
// Don't go straight back to the state machine loop since that might
// cause us to start decoding again and we could flip-flop between
// decoding and quick-buffering.
ScheduleStateMachineIn(USECS_PER_S);
return;
}
}
// Cap the current time to the larger of the audio and video end time.
// This ensures that if we're running off the system clock, we don't
// advance the clock to after the media end time.

Просмотреть файл

@ -522,6 +522,10 @@ protected:
// Must be called with the decode monitor held.
void MaybeStartPlayback();
// Check to see if we don't have enough data to play up to the next frame.
// If we don't, switch to buffering mode.
void MaybeStartBuffering();
// Moves the decoder into decoding state. Called on the state machine
// thread. The decoder monitor must be held.
void StartDecoding();