diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp index a02697569184..a3c48e394df0 100644 --- a/dom/media/MediaData.cpp +++ b/dom/media/MediaData.cpp @@ -35,14 +35,6 @@ using media::TimeUnit; const char* AudioData::sTypeName = "audio"; const char* VideoData::sTypeName = "video"; -bool IsDataLoudnessHearable(const AudioDataValue aData) { - // We can transfer the digital value to dBFS via following formula. According - // to American SMPTE standard, 0 dBu equals -20 dBFS. In theory 0 dBu is still - // hearable, so we choose a smaller value as our threshold. If the loudness - // is under this threshold, it might not be hearable. - return 20.0f * std::log10(AudioSampleToFloat(aData)) > -100; -} - AudioData::AudioData(int64_t aOffset, const media::TimeUnit& aTime, AlignedAudioBuffer&& aData, uint32_t aChannels, uint32_t aRate, uint32_t aChannelMap) @@ -143,23 +135,6 @@ size_t AudioData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { return size; } -bool AudioData::IsAudible() const { - if (!mAudioData) { - return false; - } - - const AudioDataValue* data = GetAdjustedData(); - - for (uint32_t frame = 0; frame < mFrames; ++frame) { - for (uint32_t channel = 0; channel < mChannels; ++channel) { - if (IsDataLoudnessHearable(data[frame * mChannels + channel])) { - return true; - } - } - } - return false; -} - AlignedAudioBuffer AudioData::MoveableData() { // Trim buffer according to trimming mask. mAudioData.PopFront(mDataOffset); diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index a523cb1b47c9..152f8f7a9dbd 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -375,10 +375,6 @@ class AudioData : public MediaData { // 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; - // Return true if the adjusted time is valid. Caller should handle error when // the result is invalid. bool AdjustForStartTime(const media::TimeUnit& aStartTime) override; diff --git a/dom/media/mediasink/AudioSink.cpp b/dom/media/mediasink/AudioSink.cpp index 2cec6a1faf31..1e2ade85fc33 100644 --- a/dom/media/mediasink/AudioSink.cpp +++ b/dom/media/mediasink/AudioSink.cpp @@ -68,6 +68,7 @@ AudioSink::AudioSink(AbstractThread* aThread, mFramesParsed(0), mOutputRate(DecideAudioPlaybackSampleRate(aInfo)), mOutputChannels(DecideAudioPlaybackChannels(aInfo)), + mAudibilityMonitor(mOutputRate, 2.0), mAudioQueue(aAudioQueue) { } @@ -316,7 +317,9 @@ void AudioSink::Errored() { void AudioSink::CheckIsAudible(const AudioData* aData) { MOZ_ASSERT(aData); - bool isAudible = aData->IsAudible(); + mAudibilityMonitor.ProcessAudioData(aData); + bool isAudible = mAudibilityMonitor.RecentlyAudible(); + if (isAudible != mIsAudioDataAudible) { mIsAudioDataAudible = isAudible; mAudibleEvent.Notify(mIsAudioDataAudible); diff --git a/dom/media/mediasink/AudioSink.h b/dom/media/mediasink/AudioSink.h index 77604d11e958..8e9fa9deab21 100644 --- a/dom/media/mediasink/AudioSink.h +++ b/dom/media/mediasink/AudioSink.h @@ -7,6 +7,7 @@ #define AudioSink_h__ #include "AudioStream.h" +#include "AudibilityMonitor.h" #include "MediaEventSource.h" #include "MediaInfo.h" #include "MediaQueue.h" @@ -161,10 +162,8 @@ class AudioSink : private AudioStream::DataSource { // Never modifed after construction. uint32_t mOutputRate; uint32_t mOutputChannels; - - // True when audio is producing audible sound, false when audio is silent. + AudibilityMonitor mAudibilityMonitor; bool mIsAudioDataAudible; - MediaEventProducer mAudibleEvent; MediaQueue& mAudioQueue; diff --git a/dom/media/mediasink/DecodedStream.cpp b/dom/media/mediasink/DecodedStream.cpp index 26757653464a..15df1700d5dc 100644 --- a/dom/media/mediasink/DecodedStream.cpp +++ b/dom/media/mediasink/DecodedStream.cpp @@ -420,6 +420,7 @@ nsresult DecodedStream::Start(const TimeUnit& aStartTime, mPlaying = true; mPrincipalHandle.Connect(mCanonicalOutputPrincipal); mWatchManager.Watch(mPlaying, &DecodedStream::PlayingChanged); + mAudibilityMonitor.emplace(AudibilityMonitor(mInfo.mAudio.mRate, 2.0f)); ConnectListener(); class R : public Runnable { @@ -517,6 +518,7 @@ void DecodedStream::Stop() { mPrincipalHandle.DisconnectIfConnected(); mWatchManager.Unwatch(mPlaying, &DecodedStream::PlayingChanged); + mAudibilityMonitor.reset(); } bool DecodedStream::IsStarted() const { @@ -674,7 +676,9 @@ void DecodedStream::SendAudio(double aVolume, void DecodedStream::CheckIsDataAudible(const AudioData* aData) { MOZ_ASSERT(aData); - bool isAudible = aData->IsAudible(); + mAudibilityMonitor->ProcessAudioData(aData); + bool isAudible = mAudibilityMonitor->RecentlyAudible(); + if (isAudible != mIsAudioDataAudible) { mIsAudioDataAudible = isAudible; mAudibleEvent.Notify(mIsAudioDataAudible); diff --git a/dom/media/mediasink/DecodedStream.h b/dom/media/mediasink/DecodedStream.h index d29ca2eab228..a7160d61bb5b 100644 --- a/dom/media/mediasink/DecodedStream.h +++ b/dom/media/mediasink/DecodedStream.h @@ -111,6 +111,7 @@ class DecodedStream : public MediaSink { MediaInfo mInfo; // True when stream is producing audible sound, false when stream is silent. bool mIsAudioDataAudible = false; + Maybe mAudibilityMonitor; MediaEventProducer mAudibleEvent; MediaQueue& mAudioQueue;