--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -91,23 +91,16 @@ static const uint32_t LOW_AUDIO_USECS =
// If more than this many usecs of decoded audio is queued, we'll hold off
// decoding more audio. If we increase the low audio threshold (see
// LOW_AUDIO_USECS above) we'll also increase this value to ensure it's not
// less than the low audio threshold.
const int64_t AMPLE_AUDIO_USECS = 1000000;
} // namespace detail
-// When we're only playing audio and we don't have a video stream, we divide
-// AMPLE_AUDIO_USECS and LOW_AUDIO_USECS by the following value. This reduces
-// the amount of decoded audio we buffer, reducing our memory usage. We only
-// need to decode far ahead when we're decoding video using software decoding,
-// as otherwise a long video decode could cause an audio underrun.
-const int64_t NO_VIDEO_AMPLE_AUDIO_DIVISOR = 8;
-
// If we have fewer than LOW_VIDEO_FRAMES decoded frames, and
// we're not "prerolling video", we'll skip the video up to the next keyframe
// which is at or after the current playback position.
static const uint32_t LOW_VIDEO_FRAMES = 2;
// Threshold in usecs that used to check if we are low on decoded video.
// If the last video frame's end time |mDecodedVideoEndTime| is more than
// |LOW_VIDEO_THRESHOLD_USECS*mPlaybackRate| after the current clock in
@@ -218,32 +211,32 @@ MediaDecoderStateMachine::MediaDecoderSt
mDecodedAudioEndTime(-1),
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, "MediaDecoderStateMachine::mAudioCaptured"),
+ mAudioCaptured(false),
mAudioCompleted(false, "MediaDecoderStateMachine::mAudioCompleted"),
mVideoCompleted(false, "MediaDecoderStateMachine::mVideoCompleted"),
mNotifyMetadataBeforeFirstFrame(false),
mDispatchedEventToDecode(false),
mQuickBuffering(false),
mMinimizePreroll(false),
mDecodeThreadWaiting(false),
mDropAudioUntilNextDiscontinuity(false),
mDropVideoUntilNextDiscontinuity(false),
mDecodeToSeekTarget(false),
mCurrentTimeBeforeSeek(0),
mCorruptFrames(60),
mDecodingFirstFrame(true),
mSentLoadedMetadataEvent(false),
- mSentFirstFrameLoadedEvent(false, "MediaDecoderStateMachine::mSentFirstFrameLoadedEvent"),
+ mSentFirstFrameLoadedEvent(false),
mSentPlaybackEndedEvent(false),
mOutputStreamManager(new OutputStreamManager()),
mResource(aDecoder->GetResource()),
mAudioOffloading(false),
mBuffered(mTaskQueue, TimeIntervals(),
"MediaDecoderStateMachine::mBuffered (Mirror)"),
mEstimatedDuration(mTaskQueue, NullableTimeUnit(),
"MediaDecoderStateMachine::mEstimatedDuration (Mirror)"),
@@ -361,18 +354,16 @@ MediaDecoderStateMachine::Initialization
mWatchManager.Watch(mVolume, &MediaDecoderStateMachine::VolumeChanged);
mWatchManager.Watch(mLogicalPlaybackRate, &MediaDecoderStateMachine::LogicalPlaybackRateChanged);
mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged);
mWatchManager.Watch(mEstimatedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mExplicitDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
- mWatchManager.Watch(mSentFirstFrameLoadedEvent, &MediaDecoderStateMachine::AdjustAudioThresholds);
- mWatchManager.Watch(mAudioCaptured, &MediaDecoderStateMachine::AdjustAudioThresholds);
}
media::MediaSink*
MediaDecoderStateMachine::CreateAudioSink()
{
RefPtr<MediaDecoderStateMachine> self = this;
auto audioSinkCreator = [self] () {
MOZ_ASSERT(self->OnTaskQueue());
@@ -2013,42 +2004,16 @@ MediaDecoderStateMachine::EnqueueFirstFr
bool
MediaDecoderStateMachine::IsDecodingFirstFrame()
{
return mState == DECODER_STATE_DECODING && mDecodingFirstFrame;
}
void
-MediaDecoderStateMachine::AdjustAudioThresholds()
-{
- MOZ_ASSERT(OnTaskQueue());
-
- // Experiments show that we need to buffer more if audio is captured to avoid
- // audio glitch. See bug 1188643 comment 16 for the details.
- int64_t divisor = mAudioCaptured ? NO_VIDEO_AMPLE_AUDIO_DIVISOR / 2
- : NO_VIDEO_AMPLE_AUDIO_DIVISOR;
-
- // We're playing audio only. We don't need to worry about slow video
- // decodes causing audio underruns, so don't buffer so much audio in
- // order to reduce memory usage.
- if (HasAudio() && !HasVideo() && mSentFirstFrameLoadedEvent) {
- mAmpleAudioThresholdUsecs = detail::AMPLE_AUDIO_USECS / divisor;
- mLowAudioThresholdUsecs = detail::LOW_AUDIO_USECS / divisor;
- mQuickBufferingLowDataThresholdUsecs =
- detail::QUICK_BUFFERING_LOW_DATA_USECS / divisor;
-
- // Check if we need to stop audio prerolling for thresholds changed.
- if (mIsAudioPrerolling && DonePrerollingAudio()) {
- StopPrerollingAudio();
- }
- }
-}
-
-void
MediaDecoderStateMachine::FinishDecodeFirstFrame()
{
MOZ_ASSERT(OnTaskQueue());
DECODER_LOG("FinishDecodeFirstFrame");
if (!IsRealTime() && !mSentFirstFrameLoadedEvent) {
mMediaSink->Redraw();
}
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -643,18 +643,16 @@ private:
// Rejected by the MediaSink to signal errors for audio/video.
void OnMediaSinkAudioError();
void OnMediaSinkVideoError();
// Return true if the video decoder's decode speed can not catch up the
// play time.
bool NeedToSkipToNextKeyframe();
- void AdjustAudioThresholds();
-
void* const mDecoderID;
const RefPtr<FrameStatistics> mFrameStats;
const RefPtr<VideoFrameContainer> mVideoFrameContainer;
const dom::AudioChannel mAudioChannel;
// Task queue for running the state machine.
RefPtr<TaskQueue> mTaskQueue;
@@ -965,23 +963,17 @@ private:
// got a few frames decoded before we consider whether decode is falling
// behind. Otherwise our "we're falling behind" logic will trigger
// unneccessarily if we start playing as soon as the first sample is
// decoded. These two fields store how many video frames and audio
// samples we must consume before are considered to be finished prerolling.
uint32_t AudioPrerollUsecs() const
{
MOZ_ASSERT(OnTaskQueue());
- if (IsRealTime()) {
- return 0;
- }
-
- uint32_t result = mLowAudioThresholdUsecs * 2;
- MOZ_ASSERT(result <= mAmpleAudioThresholdUsecs, "Prerolling will never finish");
- return result;
+ return IsRealTime() ? 0 : mAmpleAudioThresholdUsecs;
}
uint32_t VideoPrerollFrames() const
{
MOZ_ASSERT(OnTaskQueue());
return IsRealTime() ? 0 : GetAmpleVideoFrames() / 2;
}
@@ -1070,17 +1062,17 @@ private:
{
MOZ_ASSERT(OnTaskQueue());
return aType == MediaData::AUDIO_DATA ? mAudioWaitRequest : mVideoWaitRequest;
}
// True if we shouldn't play our audio (but still write it to any capturing
// streams). When this is true, the audio thread will never start again after
// it has stopped.
- Watchable<bool> mAudioCaptured;
+ bool mAudioCaptured;
// True if the audio playback thread has finished. It is finished
// when either all the audio frames have completed playing, or we've moved
// into shutdown state, and the threads are to be
// destroyed. Written by the audio playback thread and read and written by
// the state machine thread. Synchronised via decoder monitor.
// When data is being sent to a MediaStream, this is true when all data has
// been written to the MediaStream.
@@ -1168,17 +1160,17 @@ private:
// True if we are back from DECODER_STATE_DORMANT state and
// LoadedMetadataEvent was already sent.
bool mSentLoadedMetadataEvent;
// True if we are back from DECODER_STATE_DORMANT state and
// FirstFrameLoadedEvent was already sent, then we can skip
// SetStartTime because the mStartTime already set before. Also we don't need
// to decode any audio/video since the MediaDecoder will trigger a seek
// operation soon.
- Watchable<bool> mSentFirstFrameLoadedEvent;
+ bool mSentFirstFrameLoadedEvent;
bool mSentPlaybackEndedEvent;
// Data about MediaStreams that are being fed by the decoder.
const RefPtr<OutputStreamManager> mOutputStreamManager;
// Media data resource from the decoder.
RefPtr<MediaResource> mResource;