summaryrefslogtreecommitdiffstats
path: root/dom/media/MediaStreamTrack.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/media/MediaStreamTrack.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/media/MediaStreamTrack.h')
-rw-r--r--dom/media/MediaStreamTrack.h481
1 files changed, 481 insertions, 0 deletions
diff --git a/dom/media/MediaStreamTrack.h b/dom/media/MediaStreamTrack.h
new file mode 100644
index 000000000..bf092e4b2
--- /dev/null
+++ b/dom/media/MediaStreamTrack.h
@@ -0,0 +1,481 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MEDIASTREAMTRACK_H_
+#define MEDIASTREAMTRACK_H_
+
+#include "mozilla/DOMEventTargetHelper.h"
+#include "nsError.h"
+#include "nsID.h"
+#include "nsIPrincipal.h"
+#include "StreamTracks.h"
+#include "MediaTrackConstraints.h"
+#include "mozilla/CORSMode.h"
+#include "PrincipalChangeObserver.h"
+#include "mozilla/dom/MediaStreamTrackBinding.h"
+#include "mozilla/dom/MediaTrackSettingsBinding.h"
+#include "mozilla/media/MediaUtils.h"
+
+namespace mozilla {
+
+class DOMMediaStream;
+class MediaEnginePhotoCallback;
+class MediaInputPort;
+class MediaStream;
+class MediaStreamGraph;
+class MediaStreamGraphImpl;
+class MediaStreamTrackListener;
+class DirectMediaStreamTrackListener;
+class PeerConnectionImpl;
+class PeerConnectionMedia;
+class PeerIdentity;
+class ProcessedMediaStream;
+class RemoteSourceStreamInfo;
+class SourceStreamInfo;
+
+namespace dom {
+
+class AudioStreamTrack;
+class VideoStreamTrack;
+class MediaStreamError;
+
+/**
+ * Common interface through which a MediaStreamTrack can communicate with its
+ * producer on the main thread.
+ *
+ * Kept alive by a strong ref in all MediaStreamTracks (original and clones)
+ * sharing this source.
+ */
+class MediaStreamTrackSource : public nsISupports
+{
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackSource)
+
+public:
+ class Sink
+ {
+ public:
+ virtual void PrincipalChanged() = 0;
+ };
+
+ MediaStreamTrackSource(nsIPrincipal* aPrincipal,
+ const nsString& aLabel)
+ : mPrincipal(aPrincipal),
+ mLabel(aLabel),
+ mStopped(false)
+ {
+ MOZ_COUNT_CTOR(MediaStreamTrackSource);
+ }
+
+ /**
+ * Use to clean up any resources that have to be cleaned before the
+ * destructor is called. It is often too late in the destructor because
+ * of garbage collection having removed the members already.
+ */
+ virtual void Destroy() {}
+
+ /**
+ * Gets the source's MediaSourceEnum for usage by PeerConnections.
+ */
+ virtual MediaSourceEnum GetMediaSource() const = 0;
+
+ /**
+ * Get this TrackSource's principal.
+ */
+ nsIPrincipal* GetPrincipal() const { return mPrincipal; }
+
+ /**
+ * Get the source's current CORSMode. If not applicable CORS_NONE is returned.
+ * The sink will be notified of changes to our CORSMode through
+ * PrincipalChanged().
+ */
+ virtual CORSMode GetCORSMode() const { return CORS_NONE; }
+
+ /**
+ * This is used in WebRTC. A peerIdentity constrained MediaStreamTrack cannot
+ * be sent across the network to anything other than a peer with the provided
+ * identity. If this is set, then GetPrincipal() should return an instance of
+ * nsNullPrincipal.
+ *
+ * A track's PeerIdentity is immutable and will not change during the track's
+ * lifetime.
+ */
+ virtual const PeerIdentity* GetPeerIdentity() const { return nullptr; }
+
+ /**
+ * MediaStreamTrack::GetLabel (see spec) calls through to here.
+ */
+ void GetLabel(nsAString& aLabel) { aLabel.Assign(mLabel); }
+
+ /**
+ * Forwards a photo request to backends that support it. Other backends return
+ * NS_ERROR_NOT_IMPLEMENTED to indicate that a MediaStreamGraph-based fallback
+ * should be used.
+ */
+ virtual nsresult TakePhoto(MediaEnginePhotoCallback*) const { return NS_ERROR_NOT_IMPLEMENTED; }
+
+ typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
+
+ /**
+ * We provide a fallback solution to ApplyConstraints() here.
+ * Sources that support ApplyConstraints() will have to override it.
+ */
+ virtual already_AddRefed<PledgeVoid>
+ ApplyConstraints(nsPIDOMWindowInner* aWindow,
+ const dom::MediaTrackConstraints& aConstraints);
+
+ /**
+ * Same for GetSettings (no-op).
+ */
+ virtual void
+ GetSettings(dom::MediaTrackSettings& aResult) {};
+
+ /**
+ * Called by the source interface when all registered sinks have unregistered.
+ */
+ virtual void Stop() = 0;
+
+ /**
+ * Called by each MediaStreamTrack clone on initialization.
+ */
+ void RegisterSink(Sink* aSink)
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ if (mStopped) {
+ return;
+ }
+ mSinks.AppendElement(aSink);
+ }
+
+ /**
+ * Called by each MediaStreamTrack clone on Stop() if supported by the
+ * source (us) or destruction.
+ */
+ void UnregisterSink(Sink* aSink)
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ if (mSinks.RemoveElement(aSink) && mSinks.IsEmpty()) {
+ MOZ_ASSERT(!mStopped);
+ Stop();
+ mStopped = true;
+ }
+ }
+
+protected:
+ virtual ~MediaStreamTrackSource()
+ {
+ MOZ_COUNT_DTOR(MediaStreamTrackSource);
+ }
+
+ /**
+ * Called by a sub class when the principal has changed.
+ * Notifies all sinks.
+ */
+ void PrincipalChanged()
+ {
+ for (Sink* sink : mSinks) {
+ sink->PrincipalChanged();
+ }
+ }
+
+ // Principal identifying who may access the contents of this source.
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+
+ // Currently registered sinks.
+ nsTArray<Sink*> mSinks;
+
+ // The label of the track we are the source of per the MediaStreamTrack spec.
+ const nsString mLabel;
+
+ // True if all MediaStreamTrack users have unregistered from this source and
+ // Stop() has been called.
+ bool mStopped;
+};
+
+/**
+ * Basic implementation of MediaStreamTrackSource that doesn't forward Stop().
+ */
+class BasicTrackSource : public MediaStreamTrackSource
+{
+public:
+ explicit BasicTrackSource(nsIPrincipal* aPrincipal,
+ const MediaSourceEnum aMediaSource =
+ MediaSourceEnum::Other)
+ : MediaStreamTrackSource(aPrincipal, nsString())
+ , mMediaSource(aMediaSource)
+ {}
+
+ MediaSourceEnum GetMediaSource() const override { return mMediaSource; }
+
+ void Stop() override {}
+
+protected:
+ ~BasicTrackSource() {}
+
+ const MediaSourceEnum mMediaSource;
+};
+
+/**
+ * Base class that consumers of a MediaStreamTrack can use to get notifications
+ * about state changes in the track.
+ */
+class MediaStreamTrackConsumer : public nsISupports
+{
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackConsumer)
+
+ /**
+ * Called when the track's readyState transitions to "ended".
+ * Unlike the "ended" event exposed to script this is called for any reason,
+ * including MediaStreamTrack::Stop().
+ */
+ virtual void NotifyEnded(MediaStreamTrack* aTrack) {};
+
+protected:
+ virtual ~MediaStreamTrackConsumer() {}
+};
+
+/**
+ * Class representing a track in a DOMMediaStream.
+ */
+class MediaStreamTrack : public DOMEventTargetHelper,
+ public MediaStreamTrackSource::Sink
+{
+ // DOMMediaStream owns MediaStreamTrack instances, and requires access to
+ // some internal state, e.g., GetInputStream(), GetOwnedStream().
+ friend class mozilla::DOMMediaStream;
+
+ // PeerConnection and friends need to know our owning DOMStream and track id.
+ friend class mozilla::PeerConnectionImpl;
+ friend class mozilla::PeerConnectionMedia;
+ friend class mozilla::SourceStreamInfo;
+ friend class mozilla::RemoteSourceStreamInfo;
+
+ class PrincipalHandleListener;
+
+public:
+ /**
+ * aTrackID is the MediaStreamGraph track ID for the track in the
+ * MediaStream owned by aStream.
+ */
+ MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
+ TrackID aInputTrackID,
+ MediaStreamTrackSource* aSource,
+ const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
+ DOMEventTargetHelper)
+
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
+
+ virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
+ virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
+
+ 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;
+ void GetLabel(nsAString& aLabel) { GetSource().GetLabel(aLabel); }
+ bool Enabled() { return mEnabled; }
+ void SetEnabled(bool aEnabled);
+ void Stop();
+ void GetConstraints(dom::MediaTrackConstraints& aResult);
+ void GetSettings(dom::MediaTrackSettings& aResult);
+
+ already_AddRefed<Promise>
+ ApplyConstraints(const dom::MediaTrackConstraints& aConstraints, ErrorResult &aRv);
+ already_AddRefed<MediaStreamTrack> Clone();
+ MediaStreamTrackState ReadyState() { return mReadyState; }
+
+ IMPL_EVENT_HANDLER(ended)
+
+ /**
+ * Convenience (and legacy) method for when ready state is "ended".
+ */
+ bool Ended() const { return mReadyState == MediaStreamTrackState::Ended; }
+
+ /**
+ * Forces the ready state to a particular value, for instance when we're
+ * cloning an already ended track.
+ */
+ void SetReadyState(MediaStreamTrackState aState);
+
+ /**
+ * Notified by the MediaStreamGraph, through our owning MediaStream on the
+ * main thread.
+ *
+ * Note that this sets the track to ended and raises the "ended" event
+ * synchronously.
+ */
+ void OverrideEnded();
+
+ /**
+ * Get this track's principal.
+ */
+ nsIPrincipal* GetPrincipal() const { return mPrincipal; }
+
+ /**
+ * Called by the PrincipalHandleListener when this track's PrincipalHandle changes on
+ * the MediaStreamGraph thread. When the PrincipalHandle matches the pending
+ * principal we know that the principal change has propagated to consumers.
+ */
+ void NotifyPrincipalHandleChanged(const PrincipalHandle& aPrincipalHandle);
+
+ /**
+ * Called when this track's readyState transitions to "ended".
+ * Notifies all MediaStreamTrackConsumers that this track ended.
+ */
+ void NotifyEnded();
+
+ /**
+ * Get this track's CORS mode.
+ */
+ CORSMode GetCORSMode() const { return GetSource().GetCORSMode(); }
+
+ /**
+ * Get this track's PeerIdentity.
+ */
+ const PeerIdentity* GetPeerIdentity() const { return GetSource().GetPeerIdentity(); }
+
+ MediaStreamGraph* Graph();
+ MediaStreamGraphImpl* GraphImpl();
+
+ MediaStreamTrackSource& GetSource() const
+ {
+ MOZ_RELEASE_ASSERT(mSource, "The track source is only removed on destruction");
+ return *mSource;
+ }
+
+ // Webrtc allows the remote side to name tracks whatever it wants, and we
+ // need to surface this to content.
+ void AssignId(const nsAString& aID) { mID = aID; }
+
+ // Implementation of MediaStreamTrackSource::Sink
+ void PrincipalChanged() override;
+
+ /**
+ * Add a PrincipalChangeObserver to this track.
+ *
+ * Returns true if it was successfully added.
+ *
+ * Ownership of the PrincipalChangeObserver remains with the caller, and it's
+ * the caller's responsibility to remove the observer before it dies.
+ */
+ bool AddPrincipalChangeObserver(PrincipalChangeObserver<MediaStreamTrack>* aObserver);
+
+ /**
+ * Remove an added PrincipalChangeObserver from this track.
+ *
+ * Returns true if it was successfully removed.
+ */
+ bool RemovePrincipalChangeObserver(PrincipalChangeObserver<MediaStreamTrack>* aObserver);
+
+ /**
+ * Add a MediaStreamTrackConsumer to this track.
+ *
+ * Adding the same consumer multiple times is prohibited.
+ */
+ void AddConsumer(MediaStreamTrackConsumer* aConsumer);
+
+ /**
+ * Remove an added MediaStreamTrackConsumer from this track.
+ */
+ void RemoveConsumer(MediaStreamTrackConsumer* aConsumer);
+
+ /**
+ * Adds a MediaStreamTrackListener to the MediaStreamGraph representation of
+ * this track.
+ */
+ void AddListener(MediaStreamTrackListener* aListener);
+
+ /**
+ * Removes a MediaStreamTrackListener from the MediaStreamGraph representation
+ * of this track.
+ */
+ void RemoveListener(MediaStreamTrackListener* aListener);
+
+ /**
+ * Attempts to add a direct track listener to this track.
+ * Callers must listen to the NotifyInstalled event to know if installing
+ * the listener succeeded (tracks originating from SourceMediaStreams) or
+ * failed (e.g., WebAudio originated tracks).
+ */
+ void AddDirectListener(DirectMediaStreamTrackListener *aListener);
+ void RemoveDirectListener(DirectMediaStreamTrackListener *aListener);
+
+ /**
+ * Sets up a MediaInputPort from the underlying track that this
+ * MediaStreamTrack represents, to aStream, and returns it.
+ */
+ already_AddRefed<MediaInputPort> ForwardTrackContentsTo(ProcessedMediaStream* aStream,
+ TrackID aDestinationTrackID = TRACK_ANY);
+
+ /**
+ * Returns true if this track is connected to aPort and forwarded to aPort's
+ * output stream.
+ */
+ bool IsForwardedThrough(MediaInputPort* aPort);
+
+ void SetMediaStreamSizeListener(DirectMediaStreamTrackListener* aListener);
+
+protected:
+ virtual ~MediaStreamTrack();
+
+ void Destroy();
+
+ // Returns the original DOMMediaStream's underlying input stream.
+ MediaStream* GetInputStream();
+
+ // Returns the owning DOMMediaStream's underlying owned stream.
+ ProcessedMediaStream* GetOwnedStream();
+
+ // Returns the original DOMMediaStream. If this track is a clone,
+ // the original track's owning DOMMediaStream is returned.
+ DOMMediaStream* GetInputDOMStream();
+
+ /**
+ * Sets the principal and notifies PrincipalChangeObservers if it changes.
+ */
+ void SetPrincipal(nsIPrincipal* aPrincipal);
+
+ /**
+ * Creates a new MediaStreamTrack with the same type, input track ID and
+ * source as this MediaStreamTrack.
+ * aTrackID is the TrackID the new track will have in its owned stream.
+ */
+ virtual already_AddRefed<MediaStreamTrack> CloneInternal(DOMMediaStream* aOwningStream,
+ TrackID aTrackID) = 0;
+
+ nsTArray<PrincipalChangeObserver<MediaStreamTrack>*> mPrincipalChangeObservers;
+
+ nsTArray<RefPtr<MediaStreamTrackConsumer>> mConsumers;
+
+ RefPtr<DOMMediaStream> mOwningStream;
+ TrackID mTrackID;
+ TrackID mInputTrackID;
+ RefPtr<MediaStreamTrackSource> mSource;
+ RefPtr<MediaStreamTrack> mOriginalTrack;
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ nsCOMPtr<nsIPrincipal> mPendingPrincipal;
+ RefPtr<PrincipalHandleListener> mPrincipalHandleListener;
+ // Keep tracking MediaStreamTrackListener and DirectMediaStreamTrackListener,
+ // so we can remove them in |Destory|.
+ nsTArray<RefPtr<MediaStreamTrackListener>> mTrackListeners;
+ nsTArray<RefPtr<DirectMediaStreamTrackListener>> mDirectTrackListeners;
+ nsString mID;
+ MediaStreamTrackState mReadyState;
+ bool mEnabled;
+ dom::MediaTrackConstraints mConstraints;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* MEDIASTREAMTRACK_H_ */