Bug 1208371 - Add MediaStreamTrackSourceGetter interface. r=roc

This allows DOMMediaStream to assign MediaStreamTrackSources to
dynamically created MediaStreamTracks.

MozReview-Commit-ID: 3v91zLiqfl7

--HG--
extra : rebase_source : 4fe67e92b9c833fe5ba964fc5f3b11ba21447f36
This commit is contained in:
Andreas Pehrson 2016-01-05 10:16:21 +08:00
Родитель 9899305f28
Коммит 5401608e6c
6 изменённых файлов: 120 добавлений и 38 удалений

Просмотреть файл

@ -250,7 +250,7 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
Promise* aPromise,
nsPIDOMWindowInner* aWindow)
: DOMMediaStream(aWindow)
: DOMMediaStream(aWindow, nullptr)
, mCameraControl(nullptr)
, mAudioChannelAgent(nullptr)
, mGetCameraPromise(aPromise)

Просмотреть файл

@ -1868,6 +1868,19 @@ already_AddRefed<DOMMediaStream>
HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
MediaStreamGraph* aGraph)
{
class CaptureStreamTrackSourceGetter : public MediaStreamTrackSourceGetter
{
public:
already_AddRefed<dom::MediaStreamTrackSource>
GetMediaStreamTrackSource(TrackID aInputTrackID) override
{
return do_AddRef(new BasicUnstoppableTrackSource());
}
protected:
virtual ~CaptureStreamTrackSourceGetter() {}
};
nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow();
if (!window) {
return nullptr;
@ -1891,7 +1904,8 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
}
OutputMediaStream* out = mOutputStreams.AppendElement();
out->mStream = DOMMediaStream::CreateTrackUnionStream(window, aGraph);
MediaStreamTrackSourceGetter* getter = new CaptureStreamTrackSourceGetter();
out->mStream = DOMMediaStream::CreateTrackUnionStream(window, aGraph, getter);
RefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
out->mStream->CombineWithPrincipal(principal);
out->mStream->SetCORSMode(mCORSMode);

Просмотреть файл

@ -209,7 +209,7 @@ NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
CanvasCaptureMediaStream::CanvasCaptureMediaStream(nsPIDOMWindowInner* aWindow,
HTMLCanvasElement* aCanvas)
: DOMMediaStream(aWindow)
: DOMMediaStream(aWindow, nullptr)
, mCanvas(aCanvas)
, mOutputStreamDriver(nullptr)
{

Просмотреть файл

@ -104,6 +104,12 @@ NS_IMPL_CYCLE_COLLECTION(DOMMediaStream::TrackPort, mTrack)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMediaStream::TrackPort, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMediaStream::TrackPort, Release)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaStreamTrackSourceGetter)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaStreamTrackSourceGetter)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaStreamTrackSourceGetter)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_0(MediaStreamTrackSourceGetter)
/**
* Listener registered on the Owned stream to detect added and ended owned
@ -135,8 +141,15 @@ public:
"a corresponding MediaStreamTrack. Initial tracks "
"should be added manually to immediately and "
"synchronously be available to JS.");
track = mStream->CreateOwnDOMTrack(aTrackId, aType, nsString(),
new BasicUnstoppableTrackSource());
RefPtr<MediaStreamTrackSource> source;
if (mStream->mTrackSourceGetter) {
source = mStream->mTrackSourceGetter->GetMediaStreamTrackSource(aTrackId);
}
if (!source) {
NS_ASSERTION(false, "Dynamic track created without an explicit TrackSource");
source = new BasicUnstoppableTrackSource();
}
track = mStream->CreateOwnDOMTrack(aTrackId, aType, nsString(), source);
}
}
@ -285,6 +298,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMMediaStream,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwnedTracks)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTracks)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsumersToKeepAlive)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTrackSourceGetter)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMMediaStream,
@ -293,6 +307,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMMediaStream,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwnedTracks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTracks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsumersToKeepAlive)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTrackSourceGetter)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(DOMMediaStream, DOMEventTargetHelper)
@ -318,12 +333,13 @@ NS_IMPL_RELEASE_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream)
NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
DOMMediaStream::DOMMediaStream(nsPIDOMWindowInner* aWindow)
DOMMediaStream::DOMMediaStream(nsPIDOMWindowInner* aWindow,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
: mLogicalStreamStartTime(0), mWindow(aWindow),
mInputStream(nullptr), mOwnedStream(nullptr), mPlaybackStream(nullptr),
mOwnedPort(nullptr), mPlaybackPort(nullptr),
mTracksCreated(false), mNotifiedOfMediaStreamGraphShutdown(false),
mCORSMode(CORS_NONE)
mTrackSourceGetter(aTrackSourceGetter), mTracksCreated(false),
mNotifiedOfMediaStreamGraphShutdown(false), mCORSMode(CORS_NONE)
{
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
@ -427,7 +443,9 @@ DOMMediaStream::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
RefPtr<DOMMediaStream> newStream = new DOMMediaStream(ownerWindow);
// Streams created from JS cannot have dynamically created tracks.
MediaStreamTrackSourceGetter* getter = nullptr;
RefPtr<DOMMediaStream> newStream = new DOMMediaStream(ownerWindow, getter);
for (MediaStreamTrack& track : aTracks) {
if (!newStream->GetPlaybackStream()) {
@ -675,18 +693,20 @@ DOMMediaStream::InitPlaybackStreamCommon(MediaStreamGraph* aGraph)
already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateSourceStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow);
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow, aTrackSourceGetter);
stream->InitSourceStream(aGraph);
return stream.forget();
}
already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateTrackUnionStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow);
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow, aTrackSourceGetter);
stream->InitTrackUnionStream(aGraph);
return stream.forget();
}
@ -695,7 +715,8 @@ already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateAudioCaptureStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
{
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow);
MediaStreamTrackSourceGetter* getter = nullptr;
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow, getter);
stream->InitAudioCaptureStream(aGraph);
return stream.forget();
}
@ -1008,18 +1029,22 @@ DOMLocalMediaStream::StopImpl()
already_AddRefed<DOMLocalMediaStream>
DOMLocalMediaStream::CreateSourceStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream(aWindow);
RefPtr<DOMLocalMediaStream> stream =
new DOMLocalMediaStream(aWindow, aTrackSourceGetter);
stream->InitSourceStream(aGraph);
return stream.forget();
}
already_AddRefed<DOMLocalMediaStream>
DOMLocalMediaStream::CreateTrackUnionStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream(aWindow);
RefPtr<DOMLocalMediaStream> stream =
new DOMLocalMediaStream(aWindow, aTrackSourceGetter);
stream->InitTrackUnionStream(aGraph);
return stream.forget();
}
@ -1028,13 +1053,15 @@ already_AddRefed<DOMLocalMediaStream>
DOMLocalMediaStream::CreateAudioCaptureStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph)
{
RefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream(aWindow);
// AudioCapture doesn't create tracks dynamically
MediaStreamTrackSourceGetter* getter = nullptr;
RefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream(aWindow, getter);
stream->InitAudioCaptureStream(aGraph);
return stream.forget();
}
DOMAudioNodeMediaStream::DOMAudioNodeMediaStream(nsPIDOMWindowInner* aWindow, AudioNode* aNode)
: DOMMediaStream(aWindow),
: DOMMediaStream(aWindow, nullptr),
mStreamNode(aNode)
{
}
@ -1054,7 +1081,7 @@ DOMAudioNodeMediaStream::CreateTrackUnionStream(nsPIDOMWindowInner* aWindow,
}
DOMHwMediaStream::DOMHwMediaStream(nsPIDOMWindowInner* aWindow)
: DOMLocalMediaStream(aWindow)
: DOMLocalMediaStream(aWindow, nullptr)
{
}

Просмотреть файл

@ -43,6 +43,7 @@ namespace dom {
class AudioNode;
class HTMLCanvasElement;
class MediaStreamTrack;
class MediaStreamTrackSource;
class AudioStreamTrack;
class VideoStreamTrack;
class MediaStreamTrackSource;
@ -71,6 +72,33 @@ public:
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0;
};
/**
* Interface through which a DOMMediaStream can query its producer for a
* MediaStreamTrackSource. This will be used whenever a track occurs in the
* DOMMediaStream's owned stream that has not yet been created on the main
* thread (see DOMMediaStream::CreateOwnDOMTrack).
*/
class MediaStreamTrackSourceGetter : public nsISupports
{
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackSourceGetter)
public:
MediaStreamTrackSourceGetter()
{
MOZ_COUNT_CTOR(MediaStreamTrackSourceGetter);
}
virtual already_AddRefed<dom::MediaStreamTrackSource>
GetMediaStreamTrackSource(TrackID aInputTrackID) = 0;
protected:
virtual ~MediaStreamTrackSourceGetter()
{
MOZ_COUNT_DTOR(MediaStreamTrackSourceGetter);
}
};
/**
* DOM wrapper for MediaStreams.
*
@ -291,7 +319,8 @@ public:
const InputPortOwnership mOwnership;
};
explicit DOMMediaStream(nsPIDOMWindowInner* aWindow);
DOMMediaStream(nsPIDOMWindowInner* aWindow,
MediaStreamTrackSourceGetter* aTrackSourceGetter);
NS_DECL_ISUPPORTS_INHERITED
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
@ -455,14 +484,16 @@ public:
/**
* Create a DOMMediaStream whose underlying input stream is a SourceMediaStream.
*/
static already_AddRefed<DOMMediaStream>
CreateSourceStream(nsPIDOMWindowInner* aWindow, MediaStreamGraph* aGraph);
static already_AddRefed<DOMMediaStream> CreateSourceStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create a DOMMediaStream whose underlying input stream is a TrackUnionStream.
*/
static already_AddRefed<DOMMediaStream>
CreateTrackUnionStream(nsPIDOMWindowInner* aWindow, MediaStreamGraph* aGraph);
static already_AddRefed<DOMMediaStream> CreateTrackUnionStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create an DOMMediaStream whose underlying input stream is an
@ -591,6 +622,10 @@ protected:
// MediaStreamTracks corresponding to tracks in our mPlaybackStream.
AutoTArray<RefPtr<TrackPort>, 2> mTracks;
// The interface through which we can query the stream producer for
// track sources.
RefPtr<MediaStreamTrackSourceGetter> mTrackSourceGetter;
RefPtr<OwnedStreamListener> mOwnedListener;
RefPtr<PlaybackStreamListener> mPlaybackListener;
@ -632,8 +667,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DOMMediaStream,
class DOMLocalMediaStream : public DOMMediaStream
{
public:
explicit DOMLocalMediaStream(nsPIDOMWindowInner* aWindow)
: DOMMediaStream(aWindow) {}
explicit DOMLocalMediaStream(nsPIDOMWindowInner* aWindow,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
: DOMMediaStream(aWindow, aTrackSourceGetter) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMLOCALMEDIASTREAM_IID)
@ -647,14 +683,16 @@ public:
*/
static already_AddRefed<DOMLocalMediaStream>
CreateSourceStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph);
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
*/
static already_AddRefed<DOMLocalMediaStream>
CreateTrackUnionStream(nsPIDOMWindowInner* aWindow,
MediaStreamGraph* aGraph);
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create an nsDOMLocalMediaStream whose underlying stream is an

Просмотреть файл

@ -667,17 +667,19 @@ public:
static already_AddRefed<nsDOMUserMediaStream>
CreateSourceStream(nsPIDOMWindowInner* aWindow,
GetUserMediaCallbackMediaStreamListener* aListener,
MediaStreamGraph* aMSG)
MediaStreamGraph* aMSG,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<nsDOMUserMediaStream> stream = new nsDOMUserMediaStream(aWindow,
aListener);
RefPtr<nsDOMUserMediaStream> stream =
new nsDOMUserMediaStream(aWindow, aListener, aTrackSourceGetter);
stream->InitSourceStream(aMSG);
return stream.forget();
}
nsDOMUserMediaStream(nsPIDOMWindowInner* aWindow,
GetUserMediaCallbackMediaStreamListener* aListener) :
DOMLocalMediaStream(aWindow),
GetUserMediaCallbackMediaStreamListener* aListener,
MediaStreamTrackSourceGetter* aTrackSourceGetter) :
DOMLocalMediaStream(aWindow, aTrackSourceGetter),
mListener(aListener)
{}
@ -937,9 +939,10 @@ public:
};
// Normal case, connect the source stream to the track union stream to
// avoid us blocking
domStream = nsDOMUserMediaStream::CreateSourceStream(window, mListener,
msg);
// avoid us blocking. Pass a null TrackSourceGetter since gUM should never
// add tracks dynamically.
domStream =
nsDOMUserMediaStream::CreateSourceStream(window, mListener, msg, nullptr);
if (mAudioDevice) {
nsString audioDeviceName;