author | Andreas Pehrson <pehrsons@mozilla.com> |
Fri, 10 Nov 2017 15:55:42 +0100 | |
changeset 454191 | 87a5b07fa4c9c258e11b1c77058afe135b9a6533 |
parent 454190 | c7bd57a9d7ef2010fe408ffab503077bc15f3e01 |
child 454192 | 871480d5c37d3ff8e2d011ca4700f550148d490d |
push id | 8799 |
push user | mtabara@mozilla.com |
push date | Thu, 01 Mar 2018 16:46:23 +0000 |
treeherder | mozilla-beta@15334014dc67 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jib |
bugs | 1299515 |
milestone | 60.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/HTMLCanvasElement.cpp +++ b/dom/html/HTMLCanvasElement.cpp @@ -715,16 +715,24 @@ public: if (!mCaptureStream) { NS_ERROR("No stream"); return; } mCaptureStream->StopCapture(); } + void Disable() override + { + } + + void Enable() override + { + } + private: virtual ~CanvasCaptureTrackSource() {} RefPtr<CanvasCaptureMediaStream> mCaptureStream; }; NS_IMPL_ADDREF_INHERITED(CanvasCaptureTrackSource, MediaStreamTrackSource)
--- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -3243,16 +3243,32 @@ public: * Do not keep the track source alive. The source lifetime is controlled by * its associated tracks. */ bool KeepsSourceAlive() const override { return false; } + /** + * Do not keep the track source on. It is controlled by its associated tracks. + */ + bool Enabled() const override + { + return false; + } + + void Disable() override + { + } + + void Enable() override + { + } + void PrincipalChanged() override { if (!mCapturedTrackSource) { // This could happen during shutdown. return; } mPrincipal = mCapturedTrackSource->GetPrincipal(); @@ -3336,16 +3352,24 @@ public: void Stop() override { // We don't notify the source that a track was stopped since it will keep // producing tracks until the element ends. The decoder also needs the // tracks it created to be live at the source since the decoder's clock is // based on MediaStreams during capture. } + void Disable() override + { + } + + void Enable() override + { + } + void NotifyDecoderPrincipalChanged() override { nsCOMPtr<nsIPrincipal> newPrincipal = mElement->GetCurrentPrincipal(); if (nsContentUtils::CombineResourcePrincipals(&mPrincipal, newPrincipal)) { PrincipalChanged(); } }
--- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -183,16 +183,29 @@ public: /** * Posts a task to stop the device associated with aTrackID and notifies the * associated window listener that a track was stopped. * Should this track be the last live one to be stopped, we'll also clean up. */ void StopTrack(TrackID aTrackID); /** + * Posts a task to disable the device associated with aTrackID and notifies + * the associated window listener that a track has been disabled. + */ + void DisableTrack(TrackID aTrackID); + + + /** + * Posts a task to enable the device associated with aTrackID and notifies + * the associated window listener that a track has been enabled. + */ + void EnableTrack(TrackID aTrackID); + + /** * Stops all screen/app/window/audioCapture sharing, but not camera or * microphone. */ void StopSharing(); MediaStream* Stream() const { return mStream; @@ -1114,16 +1127,30 @@ public: void Stop() override { if (mListener) { mListener->StopTrack(mTrackID); mListener = nullptr; } } + void Disable() override + { + if (mListener) { + mListener->DisableTrack(mTrackID); + } + } + + void Enable() override + { + if (mListener) { + mListener->EnableTrack(mTrackID); + } + } + protected: ~LocalTrackSource() {} RefPtr<SourceListener> mListener; const MediaSourceEnum mSource; const TrackID mTrackID; const RefPtr<const PeerIdentity> mPeerIdentity; }; @@ -3806,16 +3833,112 @@ SourceListener::StopTrack(TrackID aTrack if (!mWindowListener) { MOZ_ASSERT(false, "Should still have window listener"); return; } mWindowListener->NotifySourceTrackStopped(); } void +SourceListener::DisableTrack(TrackID aTrackID) +{ + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread"); + + if (!Activated()) { + MOZ_ASSERT(false, "No device to disable"); + return; + } + + RefPtr<MediaDevice> device; + + switch (aTrackID) { + case kAudioTrack: { + LOG(("SourceListener %p disabling audio track %d", this, aTrackID)); + if (!mAudioDevice) { + NS_ASSERTION(false, "Can't disable audio. No device."); + return; + } + if (mAudioStopped) { + // Audio stopped. Disabling is pointless. + return; + } + device = mAudioDevice; + break; + } + case kVideoTrack: { + LOG(("SourceListener %p disabling video track %d", this, aTrackID)); + if (!mVideoDevice) { + NS_ASSERTION(false, "Can't disable video. No device."); + return; + } + if (mVideoStopped) { + // Video stopped. Disabling is pointless. + return; + } + device = mVideoDevice; + break; + } + default: { + MOZ_ASSERT(false, "Unknown track id"); + return; + } + } + + // XXX Later patch +} + +void +SourceListener::EnableTrack(TrackID aTrackID) +{ + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread"); + + if (!Activated()) { + MOZ_ASSERT(false, "No device to enable"); + return; + } + + RefPtr<MediaDevice> device; + + switch (aTrackID) { + case kAudioTrack: { + LOG(("SourceListener %p enabling audio track %d", this, aTrackID)); + if (!mAudioDevice) { + NS_ASSERTION(false, "Can't enable audio. No device."); + return; + } + if (mAudioStopped) { + // Audio stopped. Enabling is pointless. + return; + } + device = mAudioDevice; + break; + } + case kVideoTrack: { + LOG(("SourceListener %p enabling video track %d", this, aTrackID)); + if (!mVideoDevice) { + NS_ASSERTION(false, "Can't enable video. No device."); + return; + } + if (mVideoStopped) { + // Video stopped. Enabling is pointless. + return; + } + device = mVideoDevice; + break; + } + default: { + MOZ_ASSERT(false, "Unknown track id"); + return; + } + } + + // XXX Later patch +} + +void SourceListener::StopSharing() { MOZ_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(mWindowListener); if (mStopped) { return; }
--- a/dom/media/MediaStreamTrack.cpp +++ b/dom/media/MediaStreamTrack.cpp @@ -217,16 +217,17 @@ void MediaStreamTrack::SetEnabled(bool aEnabled) { LOG(LogLevel::Info, ("MediaStreamTrack %p %s", this, aEnabled ? "Enabled" : "Disabled")); mEnabled = aEnabled; GetOwnedStream()->SetTrackEnabled(mTrackID, mEnabled ? DisabledTrackMode::ENABLED : DisabledTrackMode::SILENCE_BLACK); + GetSource().SinkEnabledStateChanged(); } void MediaStreamTrack::Stop() { LOG(LogLevel::Info, ("MediaStreamTrack %p Stop()", this)); if (Ended()) {
--- a/dom/media/MediaStreamTrack.h +++ b/dom/media/MediaStreamTrack.h @@ -69,16 +69,31 @@ public: * registered alive. * Return false to allow the source to stop. * * Typically MediaStreamTrack::Sink returns true and other Sinks * (like HTMLMediaElement::StreamCaptureTrackSource) return false. */ virtual bool KeepsSourceAlive() const = 0; + /** + * Return true to ensure that the MediaStreamTrackSource where this Sink is + * registered is kept turned on and active. + * Return false to allow the source to pause, and any underlying devices to + * temporarily stop. + * + * When the underlying enabled state of the sink changes, + * call MediaStreamTrackSource::SinkEnabledStateChanged(). + * + * Typically MediaStreamTrack returns the track's enabled state and other + * Sinks (like HTMLMediaElement::StreamCaptureTrackSource) return false so + * control over device state remains with tracks and their enabled state. + */ + virtual bool Enabled() const = 0; + virtual void PrincipalChanged() = 0; virtual void MutedChanged(bool aNewState) = 0; }; MediaStreamTrackSource(nsIPrincipal* aPrincipal, const nsString& aLabel) : mPrincipal(aPrincipal), mLabel(aLabel), @@ -152,16 +167,43 @@ public: /** * Called by the source interface when all registered sinks with * KeepsSourceAlive() == true have unregistered. */ virtual void Stop() = 0; /** + * Called by the source interface when all registered sinks with + * KeepsSourceAlive() == true become disabled. + */ + virtual void Disable() = 0; + + /** + * Called by the source interface when at least one registered sink with + * KeepsSourceAlive() == true become enabled. + */ + virtual void Enable() = 0; + + /** + * Called when a Sink's Enabled() state changed. Will iterate through all + * sinks and notify the source of the aggregated enabled state. + * + * Note that a Sink with KeepsSourceAlive() == false counts as disabled. + */ + void SinkEnabledStateChanged() + { + if (IsEnabled()) { + Enable(); + } else { + Disable(); + } + } + + /** * Called by each MediaStreamTrack clone on initialization. */ void RegisterSink(Sink* aSink) { MOZ_ASSERT(NS_IsMainThread()); if (mStopped) { return; } @@ -200,16 +242,26 @@ protected: for (const WeakPtr<Sink>& sink : mSinks) { if (sink && sink->KeepsSourceAlive()) { return true; } } return false; } + bool IsEnabled() + { + for (const WeakPtr<Sink>& sink : mSinks) { + if (sink && sink->KeepsSourceAlive() && sink->Enabled()) { + return true; + } + } + return false; + } + /** * Called by a sub class when the principal has changed. * Notifies all sinks. */ void PrincipalChanged() { MOZ_ASSERT(NS_IsMainThread()); nsTArray<WeakPtr<Sink>> sinks(mSinks); @@ -267,16 +319,18 @@ public: MediaSourceEnum::Other) : MediaStreamTrackSource(aPrincipal, nsString()) , mMediaSource(aMediaSource) {} MediaSourceEnum GetMediaSource() const override { return mMediaSource; } void Stop() override {} + void Disable() override {} + void Enable() override {} protected: ~BasicTrackSource() {} const MediaSourceEnum mMediaSource; }; /** @@ -337,17 +391,17 @@ public: virtual const AudioStreamTrack* AsAudioStreamTrack() const { return nullptr; } virtual const VideoStreamTrack* AsVideoStreamTrack() const { return nullptr; } // WebIDL virtual void GetKind(nsAString& aKind) = 0; void GetId(nsAString& aID) const; virtual void GetLabel(nsAString& aLabel, CallerType /* aCallerType */) { GetSource().GetLabel(aLabel); } - bool Enabled() { return mEnabled; } + bool Enabled() const override { return mEnabled; } void SetEnabled(bool aEnabled); bool Muted() { return mMuted; } void Stop(); void GetConstraints(dom::MediaTrackConstraints& aResult); void GetSettings(dom::MediaTrackSettings& aResult, CallerType aCallerType); already_AddRefed<Promise> ApplyConstraints(const dom::MediaTrackConstraints& aConstraints,
--- a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp +++ b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp @@ -44,16 +44,24 @@ public: return MediaSourceEnum::AudioCapture; } void Stop() override { Destroy(); } + void Disable() override + { + } + + void Enable() override + { + } + private: ~AudioDestinationTrackSource() = default; RefPtr<MediaStreamAudioDestinationNode> mNode; }; NS_IMPL_ADDREF_INHERITED(AudioDestinationTrackSource, MediaStreamTrackSource)
--- a/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp +++ b/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp @@ -67,16 +67,25 @@ public: { } virtual mozilla::dom::MediaSourceEnum GetMediaSource() const override { return mozilla::dom::MediaSourceEnum::Microphone; } + + virtual void Disable() override + { + } + + virtual void Enable() override + { + } + virtual void Stop() override { } }; class FakeAudioStreamTrack : public mozilla::dom::AudioStreamTrack {
--- a/media/webrtc/signaling/src/peerconnection/RemoteTrackSource.h +++ b/media/webrtc/signaling/src/peerconnection/RemoteTrackSource.h @@ -35,16 +35,24 @@ public: } void Stop() override { // XXX (Bug 1314270): Implement rejection logic if necessary when we have // clarity in the spec. } + void Disable() override + { + } + + void Enable() override + { + } + void SetPrincipal(nsIPrincipal* aPrincipal) { mPrincipal = aPrincipal; PrincipalChanged(); } protected: virtual ~RemoteTrackSource() {}