зеркало из https://github.com/mozilla/gecko-dev.git
675 строки
25 KiB
C++
675 строки
25 KiB
C++
/* -*- 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 NSDOMMEDIASTREAM_H_
|
|
#define NSDOMMEDIASTREAM_H_
|
|
|
|
#include "ImageContainer.h"
|
|
|
|
#include "nsAutoPtr.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsWrapperCache.h"
|
|
#include "StreamTracks.h"
|
|
#include "nsIDOMWindow.h"
|
|
#include "nsIPrincipal.h"
|
|
#include "MediaTrackConstraints.h"
|
|
#include "mozilla/DOMEventTargetHelper.h"
|
|
#include "mozilla/RelativeTimeline.h"
|
|
#include "PrincipalChangeObserver.h"
|
|
|
|
namespace mozilla {
|
|
|
|
class AbstractThread;
|
|
class DOMMediaStream;
|
|
class MediaStream;
|
|
class MediaInputPort;
|
|
class MediaStreamGraph;
|
|
class ProcessedMediaStream;
|
|
|
|
enum class BlockingMode;
|
|
|
|
namespace dom {
|
|
class AudioNode;
|
|
class HTMLCanvasElement;
|
|
class MediaStreamTrack;
|
|
class MediaStreamTrackSource;
|
|
class AudioStreamTrack;
|
|
class VideoStreamTrack;
|
|
class AudioTrack;
|
|
class VideoTrack;
|
|
class AudioTrackList;
|
|
class VideoTrackList;
|
|
class MediaTrackListListener;
|
|
} // namespace dom
|
|
|
|
namespace layers {
|
|
class ImageContainer;
|
|
class OverlayImage;
|
|
} // namespace layers
|
|
|
|
#define NS_DOMMEDIASTREAM_IID \
|
|
{ \
|
|
0x8cb65468, 0x66c0, 0x444e, { \
|
|
0x89, 0x9f, 0x89, 0x1d, 0x9e, 0xd2, 0xbe, 0x7c \
|
|
} \
|
|
}
|
|
|
|
/**
|
|
|
|
// clang-format off
|
|
* DOM wrapper for MediaStreams.
|
|
*
|
|
* To account for track operations such as clone(), addTrack() and
|
|
* removeTrack(), a DOMMediaStream wraps three internal (and chained)
|
|
* MediaStreams:
|
|
* 1. mInputStream
|
|
* - Controlled by the owner/source of the DOMMediaStream.
|
|
* It's a stream of the type indicated by
|
|
* - DOMMediaStream::CreateSourceStream/CreateTrackUnionStream. A source
|
|
* typically creates its DOMMediaStream, creates the MediaStreamTracks
|
|
* owned by said stream, then gets the internal input stream to which it
|
|
* feeds data for the previously created tracks.
|
|
* - When necessary it can create tracks on the internal stream only and
|
|
* their corresponding MediaStreamTracks will be asynchronously created.
|
|
* 2. mOwnedStream
|
|
* - A TrackUnionStream containing tracks owned by this stream.
|
|
* - The internal model of a MediaStreamTrack consists of its owning
|
|
* DOMMediaStream and the TrackID of the corresponding internal track in
|
|
* the owning DOMMediaStream's mOwnedStream.
|
|
* - The owned stream is different from the input stream since a cloned
|
|
* DOMMediaStream is also the owner of its (cloned) MediaStreamTracks.
|
|
* - Stopping an original track shall not stop its clone. This is
|
|
* solved by stopping it at the owned stream, while the clone's owned
|
|
* stream gets data directly from the original input stream.
|
|
* - A DOMMediaStream (original or clone) gets all tracks dynamically
|
|
* added by the source automatically forwarded by having a TRACK_ANY
|
|
* MediaInputPort set up from the owning DOMMediaStream's input stream
|
|
* to this DOMMediaStream's owned stream.
|
|
* 3. mPlaybackStream
|
|
* - A TrackUnionStream containing the tracks corresponding to the
|
|
* MediaStreamTracks currently in this DOMMediaStream (per getTracks()).
|
|
* - Similarly as for mOwnedStream, there's a TRACK_ANY MediaInputPort set
|
|
* up from the owned stream to the playback stream to allow tracks
|
|
* dynamically added by the source to be automatically forwarded to any
|
|
* audio or video sinks.
|
|
* - MediaStreamTracks added by addTrack() are set up with a MediaInputPort
|
|
* locked to their internal TrackID, from their owning DOMMediaStream's
|
|
* owned stream to this playback stream.
|
|
*
|
|
*
|
|
* A graphical representation of how tracks are connected in various cases as
|
|
* follows:
|
|
*
|
|
* addTrack()ed case:
|
|
* DOMStream A
|
|
* Input Owned Playback
|
|
* t1 ---------> t1 ------------> t1 <- MediaStreamTrack X
|
|
* (pointing to t1 in A)
|
|
* --------> t2 <- MediaStreamTrack Y
|
|
* / (pointing to t1 in B)
|
|
* DOMStream B /
|
|
* Input Owned / Playback
|
|
* t1 ---------> t1 ------------> t1 <- MediaStreamTrack Y
|
|
* (pointing to t1 in B)
|
|
*
|
|
* removeTrack()ed case:
|
|
* DOMStream A
|
|
* Input Owned Playback
|
|
* t1 ---------> t1 <- No tracks
|
|
*
|
|
*
|
|
* clone()d case:
|
|
* DOMStream A
|
|
* Input Owned Playback
|
|
* t1 ---------> t1 ------------> t1 <- MediaStreamTrack X
|
|
* \ (pointing to t1 in A)
|
|
* -----
|
|
* DOMStream B \
|
|
* Input \ Owned Playback
|
|
* -> t1 ------------> t1 <- MediaStreamTrack Y
|
|
* (pointing to t1 in B)
|
|
*
|
|
*
|
|
* addTrack()ed, removeTrack()ed and clone()d case:
|
|
*
|
|
* Here we have done the following:
|
|
* var A = someStreamWithTwoTracks;
|
|
* var B = someStreamWithOneTrack;
|
|
* var X = A.getTracks()[0];
|
|
* var Y = A.getTracks()[1];
|
|
* var Z = B.getTracks()[0];
|
|
* A.addTrack(Z);
|
|
* A.removeTrack(X);
|
|
* B.removeTrack(Z);
|
|
* var A' = A.clone();
|
|
*
|
|
* DOMStream A
|
|
* Input Owned Playback
|
|
* t1 ---------> t1 <- MediaStreamTrack X
|
|
* (removed)
|
|
* (pointing to t1 in A)
|
|
* t2 ---------> t2 ------------> t2 <- MediaStreamTrack Y
|
|
* \ (pointing to t2 in A)
|
|
* \ ------> t3 <- MediaStreamTrack Z
|
|
* \ / (pointing to t1 in B)
|
|
* DOMStream B \ /
|
|
* Input \ Owned / Playback
|
|
* t1 ---^-----> t1 --- <- MediaStreamTrack Z
|
|
* (removed)
|
|
* \ \ (pointing to t1 in B)
|
|
* \ \
|
|
* DOMStream A' \ \
|
|
* Input \ \ Owned Playback
|
|
* \ -> t1 ------------> t1 <- MediaStreamTrack Y'
|
|
* \ (pointing to t1 in A')
|
|
* ----> t2 ------------> t2 <- MediaStreamTrack Z'
|
|
* (pointing to t2 in A')
|
|
*/
|
|
// clang-format on
|
|
class DOMMediaStream
|
|
: public DOMEventTargetHelper,
|
|
public dom::PrincipalChangeObserver<dom::MediaStreamTrack>,
|
|
public RelativeTimeline {
|
|
friend class dom::MediaStreamTrack;
|
|
typedef dom::MediaStreamTrack MediaStreamTrack;
|
|
typedef dom::AudioStreamTrack AudioStreamTrack;
|
|
typedef dom::VideoStreamTrack VideoStreamTrack;
|
|
typedef dom::MediaStreamTrackSource MediaStreamTrackSource;
|
|
typedef dom::AudioTrack AudioTrack;
|
|
typedef dom::VideoTrack VideoTrack;
|
|
typedef dom::AudioTrackList AudioTrackList;
|
|
typedef dom::VideoTrackList VideoTrackList;
|
|
|
|
public:
|
|
typedef dom::MediaTrackConstraints MediaTrackConstraints;
|
|
|
|
class TrackListener {
|
|
public:
|
|
virtual ~TrackListener() {}
|
|
|
|
/**
|
|
* Called when the DOMMediaStream has a live track added, either by
|
|
* script (addTrack()) or the source creating one.
|
|
*/
|
|
virtual void NotifyTrackAdded(const RefPtr<MediaStreamTrack>& aTrack){};
|
|
|
|
/**
|
|
* Called when the DOMMediaStream removes a live track from playback, either
|
|
* by script (removeTrack(), track.stop()) or the source ending it.
|
|
*/
|
|
virtual void NotifyTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack){};
|
|
|
|
/**
|
|
* Called when the DOMMediaStream has become active.
|
|
*/
|
|
virtual void NotifyActive(){};
|
|
|
|
/**
|
|
* Called when the DOMMediaStream has become inactive.
|
|
*/
|
|
virtual void NotifyInactive(){};
|
|
};
|
|
|
|
/**
|
|
* TrackPort is a representation of a MediaStreamTrack-MediaInputPort pair
|
|
* that make up a link between the Owned stream and the Playback stream.
|
|
*
|
|
* Semantically, the track is the identifier/key and the port the value of
|
|
* this connection.
|
|
*
|
|
* The input port can be shared between several TrackPorts. This is the case
|
|
* for DOMMediaStream's mPlaybackPort which forwards all tracks in its
|
|
* mOwnedStream automatically.
|
|
*
|
|
* If the MediaStreamTrack is owned by another DOMMediaStream (called A) than
|
|
* the one owning the TrackPort (called B), the input port (locked to the
|
|
* MediaStreamTrack's TrackID) connects A's mOwnedStream to B's
|
|
* mPlaybackStream.
|
|
*
|
|
* A TrackPort may never leave the DOMMediaStream it was created in. Internal
|
|
* use only.
|
|
*/
|
|
class TrackPort {
|
|
public:
|
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrackPort)
|
|
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TrackPort)
|
|
|
|
/**
|
|
* Indicates MediaInputPort ownership to the TrackPort.
|
|
*
|
|
* OWNED - Owned by the TrackPort itself. TrackPort must destroy the
|
|
* input port when it's destructed.
|
|
* EXTERNAL - Owned by another entity. It's the caller's responsibility to
|
|
* ensure the the MediaInputPort outlives the TrackPort.
|
|
*/
|
|
enum class InputPortOwnership { OWNED = 1, EXTERNAL };
|
|
|
|
TrackPort(MediaInputPort* aInputPort, MediaStreamTrack* aTrack,
|
|
const InputPortOwnership aOwnership);
|
|
|
|
protected:
|
|
virtual ~TrackPort();
|
|
|
|
public:
|
|
void DestroyInputPort();
|
|
|
|
/**
|
|
* Returns the source stream of the input port.
|
|
*/
|
|
MediaStream* GetSource() const;
|
|
|
|
/**
|
|
* Returns the track ID this track is locked to in the source stream of the
|
|
* input port.
|
|
*/
|
|
TrackID GetSourceTrackId() const;
|
|
|
|
MediaInputPort* GetInputPort() const { return mInputPort; }
|
|
MediaStreamTrack* GetTrack() const { return mTrack; }
|
|
|
|
/**
|
|
* Blocks aTrackId from going into mInputPort unless the port has been
|
|
* destroyed. Returns a promise that gets resolved when the MediaStreamGraph
|
|
* has applied the block in the playback stream.
|
|
*/
|
|
RefPtr<GenericPromise> BlockSourceTrackId(TrackID aTrackId,
|
|
BlockingMode aBlockingMode);
|
|
|
|
private:
|
|
RefPtr<MediaInputPort> mInputPort;
|
|
RefPtr<MediaStreamTrack> mTrack;
|
|
|
|
// Defines if we've been given ownership of the input port or if it's owned
|
|
// externally. The owner is responsible for destroying the port.
|
|
const InputPortOwnership mOwnership;
|
|
};
|
|
|
|
explicit DOMMediaStream(nsPIDOMWindowInner* aWindow);
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMMediaStream, DOMEventTargetHelper)
|
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMMEDIASTREAM_IID)
|
|
|
|
nsPIDOMWindowInner* GetParentObject() const { return mWindow; }
|
|
virtual JSObject* WrapObject(JSContext* aCx,
|
|
JS::Handle<JSObject*> aGivenProto) override;
|
|
|
|
// WebIDL
|
|
|
|
static already_AddRefed<DOMMediaStream> Constructor(
|
|
const dom::GlobalObject& aGlobal, ErrorResult& aRv);
|
|
|
|
static already_AddRefed<DOMMediaStream> Constructor(
|
|
const dom::GlobalObject& aGlobal, const DOMMediaStream& aStream,
|
|
ErrorResult& aRv);
|
|
|
|
static already_AddRefed<DOMMediaStream> Constructor(
|
|
const dom::GlobalObject& aGlobal,
|
|
const dom::Sequence<OwningNonNull<MediaStreamTrack>>& aTracks,
|
|
ErrorResult& aRv);
|
|
|
|
static already_AddRefed<dom::Promise> CountUnderlyingStreams(
|
|
const dom::GlobalObject& aGlobal, ErrorResult& aRv);
|
|
|
|
void GetId(nsAString& aID) const;
|
|
|
|
void GetAudioTracks(nsTArray<RefPtr<AudioStreamTrack>>& aTracks) const;
|
|
void GetAudioTracks(nsTArray<RefPtr<MediaStreamTrack>>& aTracks) const;
|
|
void GetVideoTracks(nsTArray<RefPtr<VideoStreamTrack>>& aTracks) const;
|
|
void GetVideoTracks(nsTArray<RefPtr<MediaStreamTrack>>& aTracks) const;
|
|
void GetTracks(nsTArray<RefPtr<MediaStreamTrack>>& aTracks) const;
|
|
MediaStreamTrack* GetTrackById(const nsAString& aId) const;
|
|
void AddTrack(MediaStreamTrack& aTrack);
|
|
void RemoveTrack(MediaStreamTrack& aTrack);
|
|
already_AddRefed<DOMMediaStream> Clone();
|
|
|
|
bool Active() const;
|
|
|
|
IMPL_EVENT_HANDLER(addtrack)
|
|
IMPL_EVENT_HANDLER(removetrack)
|
|
|
|
// NON-WebIDL
|
|
|
|
MediaStreamTrack* GetOwnedTrackById(const nsAString& aId);
|
|
|
|
/**
|
|
* Returns true if this DOMMediaStream has aTrack in its mPlaybackStream.
|
|
*/
|
|
bool HasTrack(const MediaStreamTrack& aTrack) const;
|
|
|
|
/**
|
|
* Returns true if this DOMMediaStream owns aTrack.
|
|
*/
|
|
bool OwnsTrack(const MediaStreamTrack& aTrack) const;
|
|
|
|
/**
|
|
* Returns the corresponding MediaStreamTrack if it's in our mOwnedStream.
|
|
* aInputTrackID should match the track's TrackID in its input stream,
|
|
* and aTrackID the TrackID in mOwnedStream.
|
|
*
|
|
* When aTrackID is not supplied or set to TRACK_ANY, we return the first
|
|
* MediaStreamTrack that matches the given input track. Note that there may
|
|
* be multiple MediaStreamTracks matching the same input track, but that they
|
|
* in that case all share the same MediaStreamTrackSource.
|
|
*/
|
|
MediaStreamTrack* FindOwnedDOMTrack(MediaStream* aInputStream,
|
|
TrackID aInputTrackID,
|
|
TrackID aTrackID = TRACK_ANY) const;
|
|
|
|
/**
|
|
* Returns the TrackPort connecting aTrack's input stream to mOwnedStream,
|
|
* or nullptr if aTrack is not owned by this DOMMediaStream.
|
|
*/
|
|
TrackPort* FindOwnedTrackPort(const MediaStreamTrack& aTrack) const;
|
|
|
|
/**
|
|
* Returns the corresponding MediaStreamTrack if it's in our mPlaybackStream.
|
|
* aInputTrackID should match the track's TrackID in its owned stream.
|
|
*/
|
|
MediaStreamTrack* FindPlaybackDOMTrack(MediaStream* aInputStream,
|
|
TrackID aInputTrackID) const;
|
|
|
|
/**
|
|
* Returns the TrackPort connecting mOwnedStream to mPlaybackStream for
|
|
* aTrack.
|
|
*/
|
|
TrackPort* FindPlaybackTrackPort(const MediaStreamTrack& aTrack) const;
|
|
|
|
MediaStream* GetInputStream() const { return mInputStream; }
|
|
ProcessedMediaStream* GetOwnedStream() const { return mOwnedStream; }
|
|
ProcessedMediaStream* GetPlaybackStream() const { return mPlaybackStream; }
|
|
|
|
/**
|
|
* Allows a video element to identify this stream as a camera stream, which
|
|
* needs special treatment.
|
|
*/
|
|
virtual MediaStream* GetCameraStream() const { return nullptr; }
|
|
|
|
/**
|
|
* Legacy method that returns true when the playback stream has finished.
|
|
*/
|
|
bool IsFinished() const;
|
|
|
|
TrackRate GraphRate();
|
|
|
|
/**
|
|
* Returns a principal indicating who may access this stream. The stream
|
|
* contents can only be accessed by principals subsuming this principal.
|
|
*/
|
|
nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
|
|
|
/**
|
|
* Returns a principal indicating who may access video data of this stream.
|
|
* The video principal will be a combination of all live video tracks.
|
|
*/
|
|
nsIPrincipal* GetVideoPrincipal() { return mVideoPrincipal; }
|
|
|
|
// From PrincipalChangeObserver<MediaStreamTrack>.
|
|
void PrincipalChanged(MediaStreamTrack* aTrack) override;
|
|
|
|
/**
|
|
* Add a PrincipalChangeObserver to this stream.
|
|
*
|
|
* 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(
|
|
dom::PrincipalChangeObserver<DOMMediaStream>* aObserver);
|
|
|
|
/**
|
|
* Remove an added PrincipalChangeObserver from this stream.
|
|
*
|
|
* Returns true if it was successfully removed.
|
|
*/
|
|
bool RemovePrincipalChangeObserver(
|
|
dom::PrincipalChangeObserver<DOMMediaStream>* aObserver);
|
|
|
|
// Webrtc allows the remote side to name a stream whatever it wants, and we
|
|
// need to surface this to content.
|
|
void AssignId(const nsAString& aID) { mID = aID; }
|
|
|
|
/**
|
|
* Create a DOMMediaStream whose underlying input stream is a
|
|
* SourceMediaStream.
|
|
*/
|
|
static already_AddRefed<DOMMediaStream> CreateSourceStreamAsInput(
|
|
nsPIDOMWindowInner* aWindow, MediaStreamGraph* aGraph);
|
|
|
|
/**
|
|
* Create a DOMMediaStream whose underlying input stream is a
|
|
* TrackUnionStream.
|
|
*/
|
|
static already_AddRefed<DOMMediaStream> CreateTrackUnionStreamAsInput(
|
|
nsPIDOMWindowInner* aWindow, MediaStreamGraph* aGraph);
|
|
|
|
/**
|
|
* Create an DOMMediaStream whose underlying input stream is an
|
|
* AudioCaptureStream.
|
|
*/
|
|
static already_AddRefed<DOMMediaStream> CreateAudioCaptureStreamAsInput(
|
|
nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
|
|
MediaStreamGraph* aGraph);
|
|
|
|
/**
|
|
* Adds a MediaStreamTrack to mTracks and raises "addtrack".
|
|
*
|
|
* Note that "addtrack" is raised synchronously and only has an effect if
|
|
* this MediaStream is already exposed to script. For spec compliance this is
|
|
* to be called from an async task.
|
|
*/
|
|
void AddTrackInternal(MediaStreamTrack* aTrack);
|
|
|
|
/**
|
|
* Called for each track in our owned stream to indicate to JS that we
|
|
* are carrying that track.
|
|
*
|
|
* Pre-creates a MediaStreamTrack and returns it.
|
|
* It is up to the caller to make sure it is added through AddTrackInternal.
|
|
*/
|
|
already_AddRefed<MediaStreamTrack> CreateDOMTrack(
|
|
TrackID aTrackID, MediaSegment::Type aType,
|
|
MediaStreamTrackSource* aSource,
|
|
const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
|
|
|
|
/**
|
|
* Creates a MediaStreamTrack cloned from aTrack, adds it to mTracks and
|
|
* returns it.
|
|
* aCloneTrackID is the TrackID the new track will get in mOwnedStream.
|
|
*/
|
|
already_AddRefed<MediaStreamTrack> CloneDOMTrack(MediaStreamTrack& aTrack,
|
|
TrackID aCloneTrackID);
|
|
|
|
/**
|
|
* Add an nsISupports object that this stream will keep alive as long as
|
|
* the stream itself is alive.
|
|
*/
|
|
void AddConsumerToKeepAlive(nsISupports* aConsumer) {
|
|
mConsumersToKeepAlive.AppendElement(aConsumer);
|
|
}
|
|
|
|
// Registers a track listener to this MediaStream, for listening to changes
|
|
// to our track set. The caller must call UnregisterTrackListener before
|
|
// being destroyed, so we don't hold on to a dead pointer. Main thread only.
|
|
void RegisterTrackListener(TrackListener* aListener);
|
|
|
|
// Unregisters a track listener from this MediaStream. The caller must call
|
|
// UnregisterTrackListener before being destroyed, so we don't hold on to
|
|
// a dead pointer. Main thread only.
|
|
void UnregisterTrackListener(TrackListener* aListener);
|
|
|
|
// Tells this MediaStream whether it can go inactive as soon as no tracks
|
|
// are live anymore.
|
|
void SetFinishedOnInactive(bool aFinishedOnInactive);
|
|
|
|
protected:
|
|
virtual ~DOMMediaStream();
|
|
|
|
void Destroy();
|
|
void InitSourceStream(MediaStreamGraph* aGraph);
|
|
void InitTrackUnionStream(MediaStreamGraph* aGraph);
|
|
void InitAudioCaptureStream(nsIPrincipal* aPrincipal,
|
|
MediaStreamGraph* aGraph);
|
|
|
|
// Sets up aStream as mInputStream. A producer may append data to a
|
|
// SourceMediaStream input stream, or connect another stream to a
|
|
// TrackUnionStream input stream.
|
|
void InitInputStreamCommon(MediaStream* aStream, MediaStreamGraph* aGraph);
|
|
|
|
// Sets up a new TrackUnionStream as mOwnedStream and connects it to
|
|
// mInputStream with a TRACK_ANY MediaInputPort if available.
|
|
// If this DOMMediaStream should have an input stream (producing data),
|
|
// it has to be initiated before the owned stream.
|
|
void InitOwnedStreamCommon(MediaStreamGraph* aGraph);
|
|
|
|
// Sets up a new TrackUnionStream as mPlaybackStream and connects it to
|
|
// mOwnedStream with a TRACK_ANY MediaInputPort if available.
|
|
// If this DOMMediaStream should have an owned stream (producer or clone),
|
|
// it has to be initiated before the playback stream.
|
|
void InitPlaybackStreamCommon(MediaStreamGraph* aGraph);
|
|
|
|
// Dispatches NotifyActive() to all registered track listeners.
|
|
void NotifyActive();
|
|
|
|
// Dispatches NotifyInactive() to all registered track listeners.
|
|
void NotifyInactive();
|
|
|
|
// Dispatches NotifyTrackAdded() to all registered track listeners.
|
|
void NotifyTrackAdded(const RefPtr<MediaStreamTrack>& aTrack);
|
|
|
|
// Dispatches NotifyTrackRemoved() to all registered track listeners.
|
|
void NotifyTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack);
|
|
|
|
// Dispatches "addtrack" or "removetrack".
|
|
nsresult DispatchTrackEvent(const nsAString& aName,
|
|
const RefPtr<MediaStreamTrack>& aTrack);
|
|
|
|
class PlaybackTrackListener;
|
|
friend class PlaybackTrackListener;
|
|
|
|
/**
|
|
* Block a track in our playback stream. Calls NotifyPlaybackTrackBlocked()
|
|
* after the MediaStreamGraph has applied the block and the track is no longer
|
|
* live.
|
|
*/
|
|
void BlockPlaybackTrack(TrackPort* aTrack);
|
|
|
|
/**
|
|
* Called on main thread after MediaStreamGraph has applied a track block in
|
|
* our playback stream.
|
|
*/
|
|
void NotifyPlaybackTrackBlocked();
|
|
|
|
// Recomputes the current principal of this stream based on the set of tracks
|
|
// it currently contains. PrincipalChangeObservers will be notified only if
|
|
// the principal changes.
|
|
void RecomputePrincipal();
|
|
|
|
// We need this to track our parent object.
|
|
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
|
|
|
// MediaStreams are owned by the graph, but we tell them when to die,
|
|
// and they won't die until we let them.
|
|
|
|
// This stream contains tracks used as input by us. Cloning happens from this
|
|
// stream. Tracks may exist in these stream but not in |mOwnedStream| if they
|
|
// have been stopped.
|
|
MediaStream* mInputStream;
|
|
|
|
// This stream contains tracks owned by us (if we were created directly from
|
|
// source, or cloned from some other stream). Tracks map to |mOwnedTracks|.
|
|
ProcessedMediaStream* mOwnedStream;
|
|
|
|
// This stream contains tracks currently played by us, despite of owner.
|
|
// Tracks map to |mTracks|.
|
|
ProcessedMediaStream* mPlaybackStream;
|
|
|
|
// This port connects mInputStream to mOwnedStream. All tracks forwarded.
|
|
RefPtr<MediaInputPort> mOwnedPort;
|
|
|
|
// This port connects mOwnedStream to mPlaybackStream. All tracks not
|
|
// explicitly blocked due to removal are forwarded.
|
|
RefPtr<MediaInputPort> mPlaybackPort;
|
|
|
|
// MediaStreamTracks corresponding to tracks in our mOwnedStream.
|
|
AutoTArray<RefPtr<TrackPort>, 2> mOwnedTracks;
|
|
|
|
// MediaStreamTracks corresponding to tracks in our mPlaybackStream.
|
|
AutoTArray<RefPtr<TrackPort>, 2> mTracks;
|
|
|
|
// Number of MediaStreamTracks that have been removed on main thread but are
|
|
// waiting to be removed on MediaStreamGraph thread.
|
|
size_t mTracksPendingRemoval;
|
|
|
|
// Listener tracking when live MediaStreamTracks in mTracks end.
|
|
RefPtr<PlaybackTrackListener> mPlaybackTrackListener;
|
|
|
|
// Set to true after MediaStreamGraph has created tracks for mPlaybackStream.
|
|
bool mTracksCreated;
|
|
|
|
nsString mID;
|
|
|
|
// Keep these alive while the stream is alive.
|
|
nsTArray<nsCOMPtr<nsISupports>> mConsumersToKeepAlive;
|
|
|
|
bool mNotifiedOfMediaStreamGraphShutdown;
|
|
|
|
// The track listeners subscribe to changes in this stream's track set.
|
|
nsTArray<TrackListener*> mTrackListeners;
|
|
|
|
// True if this stream has live tracks.
|
|
bool mActive;
|
|
|
|
// For compatibility with mozCaptureStream, we in some cases do not go
|
|
// inactive until the MediaDecoder lets us. (Remove this in Bug 1302379)
|
|
bool mFinishedOnInactive;
|
|
|
|
private:
|
|
void NotifyPrincipalChanged();
|
|
// Principal identifying who may access the collected contents of this stream.
|
|
// If null, this stream can be used by anyone because it has no content yet.
|
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
// Video principal is used by video element as access is requested to its
|
|
// image data.
|
|
nsCOMPtr<nsIPrincipal> mVideoPrincipal;
|
|
nsTArray<dom::PrincipalChangeObserver<DOMMediaStream>*>
|
|
mPrincipalChangeObservers;
|
|
CORSMode mCORSMode;
|
|
};
|
|
|
|
NS_DEFINE_STATIC_IID_ACCESSOR(DOMMediaStream, NS_DOMMEDIASTREAM_IID)
|
|
|
|
class DOMAudioNodeMediaStream : public DOMMediaStream {
|
|
typedef dom::AudioNode AudioNode;
|
|
|
|
public:
|
|
DOMAudioNodeMediaStream(nsPIDOMWindowInner* aWindow, AudioNode* aNode);
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMAudioNodeMediaStream,
|
|
DOMMediaStream)
|
|
|
|
/**
|
|
* Create a DOMAudioNodeMediaStream whose underlying stream is a
|
|
* TrackUnionStream.
|
|
*/
|
|
static already_AddRefed<DOMAudioNodeMediaStream>
|
|
CreateTrackUnionStreamAsInput(nsPIDOMWindowInner* aWindow, AudioNode* aNode,
|
|
MediaStreamGraph* aGraph);
|
|
|
|
protected:
|
|
~DOMAudioNodeMediaStream();
|
|
|
|
private:
|
|
// If this object wraps a stream owned by an AudioNode, we need to ensure that
|
|
// the node isn't cycle-collected too early.
|
|
RefPtr<AudioNode> mStreamNode;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif /* NSDOMMEDIASTREAM_H_ */
|