From f57c5ad7ab045490fa9fa1a00fdfd89d9dad5f08 Mon Sep 17 00:00:00 2001 From: Jon Bauman Date: Thu, 12 Dec 2019 23:41:13 +0000 Subject: [PATCH] Bug 1443511 - Apply HTMLMediaElement volume to currently playing audio segments. r=pehrsons Rather than applying the volume change to the DecodedStream, which won't be played until the buffer catches up, instead apply the volume to the segments as they are consumed by the MediaTrackGraph. Differential Revision: https://phabricator.services.mozilla.com/D56276 --HG-- extra : moz-landing-system : lando --- dom/media/MediaTrackGraph.cpp | 15 ++++++++++++++- dom/media/MediaTrackGraph.h | 6 ++++++ dom/media/mediasink/DecodedStream.cpp | 8 ++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dom/media/MediaTrackGraph.cpp b/dom/media/MediaTrackGraph.cpp index 9917dd6779ae..188675abedfe 100644 --- a/dom/media/MediaTrackGraph.cpp +++ b/dom/media/MediaTrackGraph.cpp @@ -2417,11 +2417,14 @@ static void MoveToSegment(SourceMediaTrack* aTrack, MediaSegment* aIn, MOZ_ASSERT(aDesiredUpToTime >= aCurrentTime); if (aIn->GetType() == MediaSegment::AUDIO) { AudioSegment* in = static_cast(aIn); + AudioSegment* out = static_cast(aOut); TrackTime desiredDurationToMove = aDesiredUpToTime - aCurrentTime; TrackTime end = std::min(in->GetDuration(), desiredDurationToMove); - aOut->AppendSlice(*in, 0, end); + out->AppendSlice(*in, 0, end); in->RemoveLeading(end); + + out->ApplyVolume(aTrack->GetVolumeLocked()); } else { VideoSegment* in = static_cast(aIn); VideoSegment* out = static_cast(aOut); @@ -2709,6 +2712,16 @@ void SourceMediaTrack::RemoveAllDirectListenersImpl() { mDirectTrackListeners.Clear(); } +void SourceMediaTrack::SetVolume(float aVolume) { + MutexAutoLock lock(mMutex); + mVolume = aVolume; +} + +float SourceMediaTrack::GetVolumeLocked() { + mMutex.AssertCurrentThreadOwns(); + return mVolume; +} + SourceMediaTrack::~SourceMediaTrack() {} void MediaInputPort::Init() { diff --git a/dom/media/MediaTrackGraph.h b/dom/media/MediaTrackGraph.h index 56bcdc69cfa9..116c6467d95c 100644 --- a/dom/media/MediaTrackGraph.h +++ b/dom/media/MediaTrackGraph.h @@ -682,6 +682,11 @@ class SourceMediaTrack : public MediaTrack { void RemoveAllDirectListenersImpl() override; + // The value set here is applied in MoveToSegment so we can avoid the + // buffering delay in applying the change. See Bug 1443511. + void SetVolume(float aVolume); + float GetVolumeLocked(); + friend class MediaTrackGraphImpl; protected: @@ -737,6 +742,7 @@ class SourceMediaTrack : public MediaTrack { // held together. Mutex mMutex; // protected by mMutex + float mVolume = 1.0; UniquePtr mUpdateTrack; nsTArray> mDirectTrackListeners; }; diff --git a/dom/media/mediasink/DecodedStream.cpp b/dom/media/mediasink/DecodedStream.cpp index fa92652e9b2d..95ec26ca70f9 100644 --- a/dom/media/mediasink/DecodedStream.cpp +++ b/dom/media/mediasink/DecodedStream.cpp @@ -492,6 +492,9 @@ nsresult DecodedStream::Start(const TimeUnit& aStartTime, mVideoEndedPromise = mData->mVideoEndedPromise; mOutputListener = mData->OnOutput().Connect(mOwnerThread, this, &DecodedStream::NotifyOutput); + if (mData->mAudioTrack) { + mData->mAudioTrack->SetVolume(static_cast(mVolume)); + } SendData(); } return NS_OK; @@ -560,6 +563,9 @@ void DecodedStream::SetPlaying(bool aPlaying) { void DecodedStream::SetVolume(double aVolume) { AssertOwnerThread(); mVolume = aVolume; + if (mData && mData->mAudioTrack) { + mData->mAudioTrack->SetVolume(static_cast(aVolume)); + } } void DecodedStream::SetPlaybackRate(double aPlaybackRate) { @@ -651,8 +657,6 @@ void DecodedStream::SendAudio(double aVolume, aPrincipalHandle); } - output.ApplyVolume(aVolume); - // |mNextAudioTime| is updated as we process each audio sample in // SendStreamAudio(). if (output.GetDuration() > 0) {