From f8cd6def9a3aea3f097cd273f0d5ae8c4460b437 Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 21 Jan 2016 10:19:19 +0800 Subject: [PATCH] Bug 1238906 - part1 : check whether audio data is audible. r=jwwang --HG-- extra : rebase_source : 46869a13ba565e0af5413cc2bb387e7c7e0c2df8 --- dom/media/MediaData.cpp | 17 +++++++++++++++ dom/media/MediaData.h | 4 ++++ dom/media/MediaDecoderStateMachine.cpp | 29 ++++++++++++++++++++++++++ dom/media/MediaDecoderStateMachine.h | 5 +++++ 4 files changed, 55 insertions(+) diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp index d2f9cc06e283..3ccba39e2f7e 100644 --- a/dom/media/MediaData.cpp +++ b/dom/media/MediaData.cpp @@ -54,6 +54,23 @@ AudioData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const return size; } +bool +AudioData::IsAudible() const +{ + if (!mAudioData) { + return false; + } + + for (uint32_t frame = 0; frame < mFrames; ++frame) { + for (uint32_t channel = 0; channel < mChannels; ++channel) { + if (mAudioData[frame * mChannels + channel] != 0) { + return true; + } + } + } + return false; +} + /* static */ already_AddRefed AudioData::TransferAndUpdateTimestampAndDuration(AudioData* aOther, diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index 09e9673cc085..9bf8c6793ca3 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -149,6 +149,10 @@ public: // If mAudioBuffer is null, creates it from mAudioData. void EnsureAudioBuffer(); + // To check whether mAudioData has audible signal, it's used to distinguish + // the audiable data and silent data. + bool IsAudible() const; + const uint32_t mChannels; const uint32_t mRate; // At least one of mAudioBuffer/mAudioData must be non-null. diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index f092df465e30..9ee0f7b67c47 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -116,6 +116,11 @@ static const int AUDIO_DURATION_USECS = 40000; // increase it by more. static const int THRESHOLD_FACTOR = 2; +// When the continuous silent data is over this threshold, means the a/v does +// not produce any sound. This time is decided by UX suggestion, see +// https://bugzilla.mozilla.org/show_bug.cgi?id=1235612#c18 +static const uint32_t SILENT_DATA_THRESHOLD_USECS = 10000000; + namespace detail { // If we have less than this much undecoded data available, we'll consider @@ -236,6 +241,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mOutputStreamManager(new OutputStreamManager()), mResource(aDecoder->GetResource()), mAudioOffloading(false), + mIsAudioDataAudible(false), + mSilentDataDuration(0), mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderStateMachine::mBuffered (Mirror)"), mEstimatedDuration(mTaskQueue, NullableTimeUnit(), @@ -709,14 +716,36 @@ MediaDecoderStateMachine::PushFront(MediaData* aSample, MediaData::Type aSampleT UpdateNextFrameStatus(); } +void +MediaDecoderStateMachine::CheckIsAudible(const MediaData* aSample) +{ + MOZ_ASSERT(OnTaskQueue()); + MOZ_ASSERT(aSample->mType == MediaData::AUDIO_DATA); + + const AudioData* data = aSample->As(); + bool isAudible = data->IsAudible(); + if (isAudible && !mIsAudioDataAudible) { + mIsAudioDataAudible = true; + mSilentDataDuration = 0; + } else if (isAudible && mIsAudioDataAudible) { + mSilentDataDuration += data->mDuration; + if (mSilentDataDuration > SILENT_DATA_THRESHOLD_USECS) { + mIsAudioDataAudible = false; + mSilentDataDuration = 0; + } + } +} + void MediaDecoderStateMachine::OnAudioPopped(const RefPtr& aSample) { MOZ_ASSERT(OnTaskQueue()); + mPlaybackOffset = std::max(mPlaybackOffset.Ref(), aSample->mOffset); UpdateNextFrameStatus(); DispatchAudioDecodeTaskIfNeeded(); MaybeStartBuffering(); + CheckIsAudible(aSample); } void diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 7e85ed281172..95ce63f72526 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -405,6 +405,7 @@ protected: void OnAudioPopped(const RefPtr& aSample); void OnVideoPopped(const RefPtr& aSample); + void CheckIsAudible(const MediaData* aSample); void VolumeChanged(); void LogicalPlaybackRateChanged(); void PreservesPitchChanged(); @@ -1195,6 +1196,10 @@ private: // Playback will not start when audio is offloading. bool mAudioOffloading; + // Used to distiguish continuous silent audio data. + bool mIsAudioDataAudible; + uint32_t mSilentDataDuration; + #ifdef MOZ_EME void OnCDMProxyReady(RefPtr aProxy); void OnCDMProxyNotReady();