зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1188643. Buffer more audio in audio capture mode to avoid glitches. r=cpearce.
This commit is contained in:
Родитель
20b7d96d1c
Коммит
bd37364bb2
|
@ -205,7 +205,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
|
||||
mIsAudioPrerolling(false),
|
||||
mIsVideoPrerolling(false),
|
||||
mAudioCaptured(false),
|
||||
mAudioCaptured(false, "MediaDecoderStateMachine::mAudioCaptured"),
|
||||
mAudioCompleted(false, "MediaDecoderStateMachine::mAudioCompleted"),
|
||||
mNotifyMetadataBeforeFirstFrame(false),
|
||||
mDispatchedEventToDecode(false),
|
||||
|
@ -219,7 +219,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mCorruptFrames(60),
|
||||
mDecodingFirstFrame(true),
|
||||
mSentLoadedMetadataEvent(false),
|
||||
mSentFirstFrameLoadedEvent(false),
|
||||
mSentFirstFrameLoadedEvent(false, "MediaDecoderStateMachine::mSentFirstFrameLoadedEvent"),
|
||||
mSentPlaybackEndedEvent(false),
|
||||
mStreamSink(new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue)),
|
||||
mResource(aDecoder->GetResource()),
|
||||
|
@ -350,6 +350,8 @@ MediaDecoderStateMachine::InitializationTask()
|
|||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
|
||||
mWatchManager.Watch(mSameOriginMedia, &MediaDecoderStateMachine::SameOriginMediaChanged);
|
||||
mWatchManager.Watch(mSentFirstFrameLoadedEvent, &MediaDecoderStateMachine::AdjustAudioThresholds);
|
||||
mWatchManager.Watch(mAudioCaptured, &MediaDecoderStateMachine::AdjustAudioThresholds);
|
||||
|
||||
// Propagate mSameOriginMedia to mDecodedStream.
|
||||
SameOriginMediaChanged();
|
||||
|
@ -2068,6 +2070,28 @@ MediaDecoderStateMachine::IsDecodingFirstFrame()
|
|||
return mState == DECODER_STATE_DECODING && mDecodingFirstFrame;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::AdjustAudioThresholds()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
// Experiments show that we need to buffer more if audio is captured to avoid
|
||||
// audio glitch. See bug 1188643 comment 16 for the details.
|
||||
auto 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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
||||
{
|
||||
|
@ -2088,15 +2112,6 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
|||
"transportSeekable=%d, mediaSeekable=%d",
|
||||
Duration().ToMicroseconds(), mResource->IsTransportSeekable(), mMediaSeekable.Ref());
|
||||
|
||||
if (HasAudio() && !HasVideo() && !mSentFirstFrameLoadedEvent) {
|
||||
// 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.
|
||||
mAmpleAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
|
||||
mLowAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
|
||||
mQuickBufferingLowDataThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
|
||||
}
|
||||
|
||||
// Get potentially updated metadata
|
||||
{
|
||||
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
|
||||
|
|
|
@ -654,6 +654,8 @@ private:
|
|||
// play time.
|
||||
bool NeedToSkipToNextKeyframe();
|
||||
|
||||
void AdjustAudioThresholds();
|
||||
|
||||
// The decoder object that created this state machine. The state machine
|
||||
// holds a strong reference to the decoder to ensure that the decoder stays
|
||||
// alive once media element has started the decoder shutdown process, and has
|
||||
|
@ -1136,7 +1138,7 @@ private:
|
|||
// 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.
|
||||
bool mAudioCaptured;
|
||||
Watchable<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
|
||||
|
@ -1228,7 +1230,7 @@ private:
|
|||
// 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.
|
||||
bool mSentFirstFrameLoadedEvent;
|
||||
Watchable<bool> mSentFirstFrameLoadedEvent;
|
||||
|
||||
bool mSentPlaybackEndedEvent;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче