☠☠ backed out by cdc15e930dab ☠ ☠ | |
author | Alastor Wu <alwu@mozilla.com> |
Mon, 18 Jan 2016 10:50:47 +0800 | |
changeset 280354 | e729b30ba7b41f14d52ae6e9eefda909f265645d |
parent 280353 | 1857bca40ac45d31ca0320273ac19baa230af3f5 |
child 280355 | f4384563b945a517c61999ae0eb59a14f8d80bac |
push id | 70413 |
push user | cbook@mozilla.com |
push date | Mon, 18 Jan 2016 09:08:57 +0000 |
treeherder | mozilla-inbound@e729b30ba7b4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwwang |
bugs | 1238906 |
milestone | 46.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -2108,17 +2108,18 @@ HTMLMediaElement::HTMLMediaElement(alrea mAudioChannelVolume(1.0), mPlayingThroughTheAudioChannel(false), mDisableVideo(false), mPlayBlockedBecauseHidden(false), mMediaStreamTrackListener(nullptr), mElementInTreeState(ELEMENT_NOT_INTREE), mHasUserInteraction(false), mFirstFrameLoaded(false), - mDefaultPlaybackStartPosition(0.0) + mDefaultPlaybackStartPosition(0.0), + mIsAudioTrackAudible(false) { mAudioChannel = AudioChannelService::GetDefaultAudioChannel(); mPaused.SetOuter(this); RegisterActivityObserver(); NotifyOwnerDocumentActivityChangedInternal(); @@ -5164,10 +5165,19 @@ HTMLMediaElement::IsCurrentlyPlaying() c if (mDecoder && mDecoder->IsSeeking() && !mPlayingBeforeSeek) { return false; } return true; } return false; } +void +HTMLMediaElement::NotifyAudibleStateChanged(bool aAudible) +{ + if (mIsAudioTrackAudible != aAudible) { + mIsAudioTrackAudible = aAudible; + // To do ... + } +} + } // namespace dom } // namespace mozilla
--- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -392,16 +392,19 @@ public: { return mNetworkState; } // Called by the media decoder object, on the main thread, // when the connection between Rtsp server and client gets lost. virtual void ResetConnectionState() final override; + // Called by media decoder when the audible state changed. + virtual void NotifyAudibleStateChanged(bool aAudible) final override; + // XPCOM GetPreload() is OK void SetPreload(const nsAString& aValue, ErrorResult& aRv) { SetHTMLAttr(nsGkAtoms::preload, aValue, aRv); } already_AddRefed<TimeRanges> Buffered() const; @@ -1516,14 +1519,17 @@ private: // True if the first frame has been successfully loaded. bool mFirstFrameLoaded; // Media elements also have a default playback start position, which must // initially be set to zero seconds. This time is used to allow the element to // be seeked even before the media is loaded. double mDefaultPlaybackStartPosition; + + // True if the audio track is producing audible sound. + bool mIsAudioTrackAudible; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_HTMLMediaElement_h
--- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -527,16 +527,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED, "MediaDecoder::mNextFrameStatus (Mirror)") , mCurrentPosition(AbstractThread::MainThread(), 0, "MediaDecoder::mCurrentPosition (Mirror)") , mStateMachineDuration(AbstractThread::MainThread(), NullableTimeUnit(), "MediaDecoder::mStateMachineDuration (Mirror)") , mPlaybackPosition(AbstractThread::MainThread(), 0, "MediaDecoder::mPlaybackPosition (Mirror)") + , mIsAudioDataAudible(AbstractThread::MainThread(), false, + "MediaDecoder::mIsAudioDataAudible (Mirror)") , mVolume(AbstractThread::MainThread(), 0.0, "MediaDecoder::mVolume (Canonical)") , mPlaybackRate(AbstractThread::MainThread(), 1.0, "MediaDecoder::mPlaybackRate (Canonical)") , mPreservesPitch(AbstractThread::MainThread(), true, "MediaDecoder::mPreservesPitch (Canonical)") , mEstimatedDuration(AbstractThread::MainThread(), NullableTimeUnit(), "MediaDecoder::mEstimatedDuration (Canonical)") @@ -587,16 +589,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO // mLogicalPosition mWatchManager.Watch(mCurrentPosition, &MediaDecoder::UpdateLogicalPosition); mWatchManager.Watch(mPlayState, &MediaDecoder::UpdateLogicalPosition); mWatchManager.Watch(mLogicallySeeking, &MediaDecoder::UpdateLogicalPosition); // mIgnoreProgressData mWatchManager.Watch(mLogicallySeeking, &MediaDecoder::SeekingChanged); + mWatchManager.Watch(mIsAudioDataAudible, &MediaDecoder::NotifyAudibleStateChanged); + MediaShutdownManager::Instance().Register(this); } RefPtr<ShutdownPromise> MediaDecoder::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); @@ -618,16 +622,18 @@ MediaDecoder::Shutdown() if (mDecoderStateMachine) { mTimedMetadataListener.Disconnect(); mMetadataLoadedListener.Disconnect(); mFirstFrameLoadedListener.Disconnect(); mOnPlaybackEvent.Disconnect(); mOnSeekingStart.Disconnect(); mOnMediaNotSeekable.Disconnect(); + mWatchManager.Unwatch(mIsAudioDataAudible, &MediaDecoder::NotifyAudibleStateChanged); + shutdown = mDecoderStateMachine->BeginShutdown() ->Then(AbstractThread::MainThread(), __func__, this, &MediaDecoder::FinishShutdown, &MediaDecoder::FinishShutdown) ->CompletionPromise(); } // Force any outstanding seek and byterange requests to complete @@ -1468,23 +1474,25 @@ MediaDecoder::SetStateMachine(MediaDecod if (mDecoderStateMachine) { mStateMachineDuration.Connect(mDecoderStateMachine->CanonicalDuration()); mBuffered.Connect(mDecoderStateMachine->CanonicalBuffered()); mStateMachineIsShutdown.Connect(mDecoderStateMachine->CanonicalIsShutdown()); mNextFrameStatus.Connect(mDecoderStateMachine->CanonicalNextFrameStatus()); mCurrentPosition.Connect(mDecoderStateMachine->CanonicalCurrentPosition()); mPlaybackPosition.Connect(mDecoderStateMachine->CanonicalPlaybackOffset()); + mIsAudioDataAudible.Connect(mDecoderStateMachine->CanonicalIsAudioDataAudible()); } else { mStateMachineDuration.DisconnectIfConnected(); mBuffered.DisconnectIfConnected(); mStateMachineIsShutdown.DisconnectIfConnected(); mNextFrameStatus.DisconnectIfConnected(); mCurrentPosition.DisconnectIfConnected(); mPlaybackPosition.DisconnectIfConnected(); + mIsAudioDataAudible.DisconnectIfConnected(); } } ImageContainer* MediaDecoder::GetImageContainer() { return mVideoFrameContainer ? mVideoFrameContainer->GetImageContainer() : nullptr; } @@ -1826,16 +1834,23 @@ MediaDecoder::NextFrameBufferedStatus() media::TimeUnit::FromMicroseconds(CurrentPosition()); media::TimeInterval interval(currentPosition, currentPosition + media::TimeUnit::FromMicroseconds(DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED)); return GetBuffered().Contains(interval) ? MediaDecoderOwner::NEXT_FRAME_AVAILABLE : MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; } +void +MediaDecoder::NotifyAudibleStateChanged() +{ + MOZ_ASSERT(!mShuttingDown); + mOwner->NotifyAudibleStateChanged(mIsAudioDataAudible); +} + MediaMemoryTracker::MediaMemoryTracker() { } void MediaMemoryTracker::InitMemoryReporter() { RegisterWeakAsyncMemoryReporter(this);
--- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -768,16 +768,19 @@ protected: Mirror<media::NullableTimeUnit> mStateMachineDuration; // Current playback position in the stream. This is (approximately) // where we're up to playing back the stream. This is not adjusted // during decoder seek operations, but it's updated at the end when we // start playing back again. Mirror<int64_t> mPlaybackPosition; + // Used to distiguish whether the audio is producing sound. + Mirror<bool> mIsAudioDataAudible; + // Volume of playback. 0.0 = muted. 1.0 = full volume. Canonical<double> mVolume; // PlaybackRate and pitch preservation status we should start at. Canonical<double> mPlaybackRate; Canonical<bool> mPreservesPitch; @@ -863,16 +866,19 @@ public: AbstractCanonical<int64_t>* CanonicalDecoderPosition() { return &mDecoderPosition; } AbstractCanonical<bool>* CanonicalMediaSeekable() { return &mMediaSeekable; } private: + // Notify owner when the audible state changed + void NotifyAudibleStateChanged(); + /* Functions called by ResourceCallback */ // A media stream is assumed to be infinite if the metadata doesn't // contain the duration, and range requests are not supported, and // no headers give a hint of a possible duration (Content-Length, // Content-Duration, and variants), and we cannot seek in the media // stream to determine the duration. //
--- a/dom/media/MediaDecoderOwner.h +++ b/dom/media/MediaDecoderOwner.h @@ -125,16 +125,19 @@ public: // Called by the media decoder and the video frame to get the // ImageContainer containing the video data. virtual VideoFrameContainer* GetVideoFrameContainer() = 0; // Called by the media decoder object, on the main thread, // when the connection between Rtsp server and client gets lost. virtual void ResetConnectionState() = 0; + // Called by media decoder when the audible state changed + virtual void NotifyAudibleStateChanged(bool aAudible) = 0; + #ifdef MOZ_EME // Dispatches a "encrypted" event to the HTMLMediaElement, with the // provided init data. Actual dispatch may be delayed until HAVE_METADATA. // Main thread only. virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData, const nsAString& aInitDataType) = 0; #endif // MOZ_EME };
--- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -236,17 +236,16 @@ MediaDecoderStateMachine::MediaDecoderSt mCorruptFrames(60), mDecodingFirstFrame(true), mSentLoadedMetadataEvent(false), mSentFirstFrameLoadedEvent(false), mSentPlaybackEndedEvent(false), mOutputStreamManager(new OutputStreamManager()), mResource(aDecoder->GetResource()), mAudioOffloading(false), - mIsAudioDataAudible(false), mSilentDataDuration(0), mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderStateMachine::mBuffered (Mirror)"), mEstimatedDuration(mTaskQueue, NullableTimeUnit(), "MediaDecoderStateMachine::mEstimatedDuration (Mirror)"), mExplicitDuration(mTaskQueue, Maybe<double>(), "MediaDecoderStateMachine::mExplicitDuration (Mirror)"), mPlayState(mTaskQueue, MediaDecoder::PLAY_STATE_LOADING, @@ -274,17 +273,19 @@ MediaDecoderStateMachine::MediaDecoderSt "MediaDecoderStateMachine::mDuration (Canonical"), mIsShutdown(mTaskQueue, false, "MediaDecoderStateMachine::mIsShutdown (Canonical)"), mNextFrameStatus(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED, "MediaDecoderStateMachine::mNextFrameStatus (Canonical)"), mCurrentPosition(mTaskQueue, 0, "MediaDecoderStateMachine::mCurrentPosition (Canonical)"), mPlaybackOffset(mTaskQueue, 0, - "MediaDecoderStateMachine::mPlaybackOffset (Canonical)") + "MediaDecoderStateMachine::mPlaybackOffset (Canonical)"), + mIsAudioDataAudible(mTaskQueue, false, + "MediaDecoderStateMachine::mIsAudioDataAudible (Canonical)") { MOZ_COUNT_CTOR(MediaDecoderStateMachine); NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); // Dispatch initialization that needs to happen on that task queue. nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<RefPtr<MediaDecoder>>( this, &MediaDecoderStateMachine::InitializationTask, aDecoder); mTaskQueue->Dispatch(r.forget()); @@ -2192,16 +2193,17 @@ MediaDecoderStateMachine::FinishShutdown mDecoderPosition.DisconnectIfConnected(); mMediaSeekable.DisconnectIfConnected(); mDuration.DisconnectAll(); mIsShutdown.DisconnectAll(); mNextFrameStatus.DisconnectAll(); mCurrentPosition.DisconnectAll(); mPlaybackOffset.DisconnectAll(); + mIsAudioDataAudible.DisconnectAll(); // Shut down the watch manager before shutting down our task queue. mWatchManager.Shutdown(); MOZ_ASSERT(mState == DECODER_STATE_SHUTDOWN, "How did we escape from the shutdown state?"); DECODER_LOG("Shutting down state machine task queue"); return OwnerThread()->BeginShutdown();
--- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -1191,18 +1191,17 @@ private: MediaEventProducer<MediaEventType> mOnPlaybackEvent; MediaEventProducer<MediaDecoderEventVisibility> mOnSeekingStart; // True if audio is offloading. // Playback will not start when audio is offloading. bool mAudioOffloading; - // Used to distiguish continuous silent audio data. - bool mIsAudioDataAudible; + // Duration of the continuous silent data. uint32_t mSilentDataDuration; #ifdef MOZ_EME void OnCDMProxyReady(RefPtr<CDMProxy> aProxy); void OnCDMProxyNotReady(); RefPtr<CDMProxy> mCDMProxy; MozPromiseRequestHolder<MediaDecoder::CDMProxyPromise> mCDMProxyPromise; #endif @@ -1263,16 +1262,19 @@ private: // The time of the current frame in microseconds, corresponding to the "current // playback position" in HTML5. This is referenced from 0, which is the initial // playback position. Canonical<int64_t> mCurrentPosition; // Current playback position in the stream in bytes. Canonical<int64_t> mPlaybackOffset; + // Used to distiguish whether the audio is producing sound. + Canonical<bool> mIsAudioDataAudible; + public: AbstractCanonical<media::TimeIntervals>* CanonicalBuffered() { return mReader->CanonicalBuffered(); } AbstractCanonical<media::NullableTimeUnit>* CanonicalDuration() { return &mDuration; } AbstractCanonical<bool>* CanonicalIsShutdown() { @@ -1282,13 +1284,16 @@ public: return &mNextFrameStatus; } AbstractCanonical<int64_t>* CanonicalCurrentPosition() { return &mCurrentPosition; } AbstractCanonical<int64_t>* CanonicalPlaybackOffset() { return &mPlaybackOffset; } + AbstractCanonical<bool>* CanonicalIsAudioDataAudible() { + return &mIsAudioDataAudible; + } }; } // namespace mozilla #endif
--- a/dom/media/gtest/MockMediaDecoderOwner.h +++ b/dom/media/gtest/MockMediaDecoderOwner.h @@ -42,12 +42,13 @@ public: virtual void DownloadResumed(bool aForceNetworkLoading) override {} virtual void NotifySuspendedByCache(bool aIsSuspended) override {} virtual void NotifyDecoderPrincipalChanged() override {} virtual VideoFrameContainer* GetVideoFrameContainer() override { return nullptr; } virtual void ResetConnectionState() override {} + virtual void NotifyAudibleStateChanged(bool aAudible) override {}; }; } #endif