mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1208371 - Implement DOMMediaStream::Clone() r=smaug,jib,roc
MozReview-Commit-ID: FZQIWYZcEDr --HG-- extra : rebase_source : 33336f84b8ab4f4fe9cc5bf734a7e3b587ff8729
This commit is contained in:
parent
660d9407e0
commit
d81423155b
@ -390,15 +390,15 @@ DOMMediaStream::Destroy()
|
||||
mOwnedPort = nullptr;
|
||||
}
|
||||
if (mPlaybackStream) {
|
||||
mPlaybackStream->Destroy();
|
||||
mPlaybackStream->UnregisterUser();
|
||||
mPlaybackStream = nullptr;
|
||||
}
|
||||
if (mOwnedStream) {
|
||||
mOwnedStream->Destroy();
|
||||
mOwnedStream->UnregisterUser();
|
||||
mOwnedStream = nullptr;
|
||||
}
|
||||
if (mInputStream) {
|
||||
mInputStream->Destroy();
|
||||
mInputStream->UnregisterUser();
|
||||
mInputStream = nullptr;
|
||||
}
|
||||
}
|
||||
@ -596,6 +596,108 @@ DOMMediaStream::RemoveTrack(MediaStreamTrack& aTrack)
|
||||
LOG(LogLevel::Debug, ("DOMMediaStream %p Removed track %p", this, &aTrack));
|
||||
}
|
||||
|
||||
class ClonedStreamSourceGetter :
|
||||
public MediaStreamTrackSourceGetter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ClonedStreamSourceGetter,
|
||||
MediaStreamTrackSourceGetter)
|
||||
|
||||
explicit ClonedStreamSourceGetter(DOMMediaStream* aStream)
|
||||
: mStream(aStream) {}
|
||||
|
||||
already_AddRefed<MediaStreamTrackSource>
|
||||
GetMediaStreamTrackSource(TrackID aInputTrackID) override
|
||||
{
|
||||
MediaStreamTrack* sourceTrack =
|
||||
mStream->FindOwnedDOMTrack(mStream->GetOwnedStream(), aInputTrackID);
|
||||
MOZ_RELEASE_ASSERT(sourceTrack);
|
||||
|
||||
return do_AddRef(&sourceTrack->GetSource());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ClonedStreamSourceGetter() {}
|
||||
|
||||
RefPtr<DOMMediaStream> mStream;
|
||||
};
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ClonedStreamSourceGetter,
|
||||
MediaStreamTrackSourceGetter)
|
||||
NS_IMPL_RELEASE_INHERITED(ClonedStreamSourceGetter,
|
||||
MediaStreamTrackSourceGetter)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ClonedStreamSourceGetter)
|
||||
NS_INTERFACE_MAP_END_INHERITING(MediaStreamTrackSourceGetter)
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ClonedStreamSourceGetter,
|
||||
MediaStreamTrackSourceGetter,
|
||||
mStream)
|
||||
|
||||
already_AddRefed<DOMMediaStream>
|
||||
DOMMediaStream::Clone()
|
||||
{
|
||||
return CloneInternal(TrackForwardingOption::CURRENT);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMMediaStream>
|
||||
DOMMediaStream::CloneInternal(TrackForwardingOption aForwarding)
|
||||
{
|
||||
RefPtr<DOMMediaStream> newStream =
|
||||
new DOMMediaStream(GetParentObject(), new ClonedStreamSourceGetter(this));
|
||||
|
||||
LOG(LogLevel::Info, ("DOMMediaStream %p created clone %p, forwarding %s tracks",
|
||||
this, newStream.get(),
|
||||
aForwarding == TrackForwardingOption::ALL
|
||||
? "all" : "current"));
|
||||
|
||||
MOZ_RELEASE_ASSERT(mPlaybackStream);
|
||||
MOZ_RELEASE_ASSERT(mPlaybackStream->Graph());
|
||||
MediaStreamGraph* graph = mPlaybackStream->Graph();
|
||||
|
||||
// We initiate the owned and playback streams first, since we need to create
|
||||
// all existing DOM tracks before we add the generic input port from
|
||||
// mInputStream to mOwnedStream (see AllocateInputPort wrt. destination
|
||||
// TrackID as to why).
|
||||
newStream->InitOwnedStreamCommon(graph);
|
||||
newStream->InitPlaybackStreamCommon(graph);
|
||||
|
||||
// Set up existing DOM tracks.
|
||||
TrackID allocatedTrackID = 1;
|
||||
for (const RefPtr<TrackPort>& info : mTracks) {
|
||||
MediaStreamTrack& track = *info->GetTrack();
|
||||
|
||||
LOG(LogLevel::Debug, ("DOMMediaStream %p forwarding external track %p to clone %p",
|
||||
this, &track, newStream.get()));
|
||||
RefPtr<MediaStreamTrack> trackClone =
|
||||
newStream->CreateClonedDOMTrack(track, allocatedTrackID++);
|
||||
}
|
||||
|
||||
if (aForwarding == TrackForwardingOption::ALL) {
|
||||
// Set up an input port from our input stream to the new DOM stream's owned
|
||||
// stream, to allow for dynamically added tracks at the source to appear in
|
||||
// the clone. The clone may treat mInputStream as its own mInputStream but
|
||||
// ownership remains with us.
|
||||
newStream->mInputStream = mInputStream;
|
||||
if (mInputStream) {
|
||||
// We have already set up track-locked input ports for all existing DOM
|
||||
// tracks, so now we need to block those in the generic input port to
|
||||
// avoid ending up with double instances of them.
|
||||
nsTArray<TrackID> tracksToBlock;
|
||||
for (const RefPtr<TrackPort>& info : mOwnedTracks) {
|
||||
tracksToBlock.AppendElement(info->GetTrack()->mTrackID);
|
||||
}
|
||||
|
||||
newStream->mInputStream->RegisterUser();
|
||||
newStream->mOwnedPort =
|
||||
newStream->mOwnedStream->AllocateInputPort(mInputStream,
|
||||
TRACK_ANY, TRACK_ANY, 0, 0,
|
||||
&tracksToBlock);
|
||||
}
|
||||
}
|
||||
|
||||
return newStream.forget();
|
||||
}
|
||||
|
||||
MediaStreamTrack*
|
||||
DOMMediaStream::GetTrackById(const nsString& aId)
|
||||
{
|
||||
@ -698,6 +800,7 @@ DOMMediaStream::InitInputStreamCommon(MediaStream* aStream,
|
||||
MOZ_ASSERT(!mOwnedStream, "Input stream must be initialized before owned stream");
|
||||
|
||||
mInputStream = aStream;
|
||||
mInputStream->RegisterUser();
|
||||
}
|
||||
|
||||
void
|
||||
@ -709,6 +812,7 @@ DOMMediaStream::InitOwnedStreamCommon(MediaStreamGraph* aGraph)
|
||||
// streams. This is only needed for the playback stream.
|
||||
mOwnedStream = aGraph->CreateTrackUnionStream(nullptr);
|
||||
mOwnedStream->SetAutofinish(true);
|
||||
mOwnedStream->RegisterUser();
|
||||
if (mInputStream) {
|
||||
mOwnedPort = mOwnedStream->AllocateInputPort(mInputStream);
|
||||
}
|
||||
@ -723,6 +827,7 @@ DOMMediaStream::InitPlaybackStreamCommon(MediaStreamGraph* aGraph)
|
||||
{
|
||||
mPlaybackStream = aGraph->CreateTrackUnionStream(this);
|
||||
mPlaybackStream->SetAutofinish(true);
|
||||
mPlaybackStream->RegisterUser();
|
||||
if (mOwnedStream) {
|
||||
mPlaybackPort = mPlaybackStream->AllocateInputPort(mOwnedStream);
|
||||
}
|
||||
|
@ -362,8 +362,25 @@ public:
|
||||
void AddTrack(MediaStreamTrack& aTrack);
|
||||
void RemoveTrack(MediaStreamTrack& aTrack);
|
||||
|
||||
/** Identical to CloneInternal(TrackForwardingOption::EXPLICIT) */
|
||||
already_AddRefed<DOMMediaStream> Clone();
|
||||
|
||||
// NON-WebIDL
|
||||
|
||||
/**
|
||||
* Option to provide to CloneInternal() of which tracks should be forwarded
|
||||
* from the source stream (`this`) to the returned stream clone.
|
||||
*
|
||||
* CURRENT forwards the tracks currently in the source stream's track set.
|
||||
* ALL forwards like EXPLICIT plus any and all future tracks originating
|
||||
* from the same input stream as the source DOMMediaStream (`this`).
|
||||
*/
|
||||
enum class TrackForwardingOption {
|
||||
CURRENT,
|
||||
ALL
|
||||
};
|
||||
already_AddRefed<DOMMediaStream> CloneInternal(TrackForwardingOption aForwarding);
|
||||
|
||||
MediaStreamTrack* GetTrackById(const nsString& aId);
|
||||
|
||||
MediaStreamTrack* GetOwnedTrackById(const nsString& aId);
|
||||
|
@ -39,7 +39,7 @@ interface MediaStream : EventTarget {
|
||||
// MediaStreamTrack? getTrackById (DOMString trackId);
|
||||
void addTrack (MediaStreamTrack track);
|
||||
void removeTrack (MediaStreamTrack track);
|
||||
// MediaStream clone ();
|
||||
MediaStream clone ();
|
||||
// readonly attribute boolean active;
|
||||
// attribute EventHandler onactive;
|
||||
// attribute EventHandler oninactive;
|
||||
|
Loading…
Reference in New Issue
Block a user