зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1208373 - Introduce a new blocking mode to MediaInputPort. r=jesup
This lets us notify about a created TrackUnionStream track (and since it was created, we can notify when it ends), even though it has been blocked from main thread. MozReview-Commit-ID: HyopzISBfbb --HG-- extra : rebase_source : a18be6b0fcb194c016ae06c62eb5cebbf86eb8d5 extra : intermediate-source : 38e3e48c8dd011a0503f1241c7b21a630738c6c0 extra : source : 690904309e169aa74f95163f0d796493ef882972
This commit is contained in:
Родитель
f3d88ad749
Коммит
141eefc951
|
@ -98,10 +98,10 @@ DOMMediaStream::TrackPort::GetSourceTrackId() const
|
|||
}
|
||||
|
||||
already_AddRefed<Pledge<bool>>
|
||||
DOMMediaStream::TrackPort::BlockSourceTrackId(TrackID aTrackId)
|
||||
DOMMediaStream::TrackPort::BlockSourceTrackId(TrackID aTrackId, BlockingMode aBlockingMode)
|
||||
{
|
||||
if (mInputPort) {
|
||||
return mInputPort->BlockSourceTrackId(aTrackId);
|
||||
return mInputPort->BlockSourceTrackId(aTrackId, aBlockingMode);
|
||||
}
|
||||
RefPtr<Pledge<bool>> rejected = new Pledge<bool>();
|
||||
rejected->Reject(NS_ERROR_FAILURE);
|
||||
|
@ -1040,8 +1040,10 @@ DOMMediaStream::CloneDOMTrack(MediaStreamTrack& aTrack,
|
|||
if (aTrack.Ended()) {
|
||||
// For extra suspenders, make sure that we don't forward data by mistake
|
||||
// to the clone when the original has already ended.
|
||||
// We only block END_EXISTING to allow any pending clones to end.
|
||||
RefPtr<Pledge<bool, nsresult>> blockingPledge =
|
||||
inputPort->BlockSourceTrackId(inputTrackID);
|
||||
inputPort->BlockSourceTrackId(inputTrackID,
|
||||
BlockingMode::END_EXISTING);
|
||||
Unused << blockingPledge;
|
||||
}
|
||||
|
||||
|
@ -1249,7 +1251,9 @@ DOMMediaStream::BlockPlaybackTrack(TrackPort* aTrack)
|
|||
{
|
||||
MOZ_ASSERT(aTrack);
|
||||
++mTracksPendingRemoval;
|
||||
RefPtr<Pledge<bool>> p = aTrack->BlockSourceTrackId(aTrack->GetTrack()->mTrackID);
|
||||
RefPtr<Pledge<bool>> p =
|
||||
aTrack->BlockSourceTrackId(aTrack->GetTrack()->mTrackID,
|
||||
BlockingMode::CREATION);
|
||||
RefPtr<DOMMediaStream> self = this;
|
||||
p->Then([self] (const bool& aIgnore) { self->NotifyPlaybackTrackBlocked(); },
|
||||
[] (const nsresult& aIgnore) { NS_ERROR("Could not remove track from MSG"); }
|
||||
|
|
|
@ -34,6 +34,8 @@ class MediaStreamDirectListener;
|
|||
class MediaStreamGraph;
|
||||
class ProcessedMediaStream;
|
||||
|
||||
enum class BlockingMode;
|
||||
|
||||
namespace dom {
|
||||
class AudioNode;
|
||||
class HTMLCanvasElement;
|
||||
|
@ -304,7 +306,8 @@ public:
|
|||
* destroyed. Returns a pledge that gets resolved when the MediaStreamGraph
|
||||
* has applied the block in the playback stream.
|
||||
*/
|
||||
already_AddRefed<media::Pledge<bool, nsresult>> BlockSourceTrackId(TrackID aTrackId);
|
||||
already_AddRefed<media::Pledge<bool, nsresult>>
|
||||
BlockSourceTrackId(TrackID aTrackId, BlockingMode aBlockingMode);
|
||||
|
||||
private:
|
||||
RefPtr<MediaInputPort> mInputPort;
|
||||
|
|
|
@ -3147,24 +3147,26 @@ MediaInputPort::SetGraphImpl(MediaStreamGraphImpl* aGraph)
|
|||
}
|
||||
|
||||
void
|
||||
MediaInputPort::BlockSourceTrackIdImpl(TrackID aTrackId)
|
||||
MediaInputPort::BlockSourceTrackIdImpl(TrackID aTrackId, BlockingMode aBlockingMode)
|
||||
{
|
||||
mBlockedTracks.AppendElement(aTrackId);
|
||||
mBlockedTracks.AppendElement(Pair<TrackID, BlockingMode>(aTrackId, aBlockingMode));
|
||||
}
|
||||
|
||||
already_AddRefed<Pledge<bool>>
|
||||
MediaInputPort::BlockSourceTrackId(TrackID aTrackId)
|
||||
MediaInputPort::BlockSourceTrackId(TrackID aTrackId, BlockingMode aBlockingMode)
|
||||
{
|
||||
class Message : public ControlMessage {
|
||||
public:
|
||||
explicit Message(MediaInputPort* aPort,
|
||||
TrackID aTrackId,
|
||||
BlockingMode aBlockingMode,
|
||||
already_AddRefed<nsIRunnable> aRunnable)
|
||||
: ControlMessage(aPort->GetDestination()),
|
||||
mPort(aPort), mTrackId(aTrackId), mRunnable(aRunnable) {}
|
||||
mPort(aPort), mTrackId(aTrackId), mBlockingMode(aBlockingMode),
|
||||
mRunnable(aRunnable) {}
|
||||
void Run() override
|
||||
{
|
||||
mPort->BlockSourceTrackIdImpl(mTrackId);
|
||||
mPort->BlockSourceTrackIdImpl(mTrackId, mBlockingMode);
|
||||
if (mRunnable) {
|
||||
mStream->Graph()->DispatchToMainThreadAfterStreamStateUpdate(mRunnable.forget());
|
||||
}
|
||||
|
@ -3175,6 +3177,7 @@ MediaInputPort::BlockSourceTrackId(TrackID aTrackId)
|
|||
}
|
||||
RefPtr<MediaInputPort> mPort;
|
||||
TrackID mTrackId;
|
||||
BlockingMode mBlockingMode;
|
||||
nsCOMPtr<nsIRunnable> mRunnable;
|
||||
};
|
||||
|
||||
|
@ -3187,7 +3190,7 @@ MediaInputPort::BlockSourceTrackId(TrackID aTrackId)
|
|||
pledge->Resolve(true);
|
||||
return NS_OK;
|
||||
});
|
||||
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aTrackId, runnable.forget()));
|
||||
GraphImpl()->AppendMessage(MakeUnique<Message>(this, aTrackId, aBlockingMode, runnable.forget()));
|
||||
return pledge.forget();
|
||||
}
|
||||
|
||||
|
@ -3230,7 +3233,7 @@ ProcessedMediaStream::AllocateInputPort(MediaStream* aStream, TrackID aTrackID,
|
|||
aInputNumber, aOutputNumber);
|
||||
if (aBlockedTracks) {
|
||||
for (TrackID trackID : *aBlockedTracks) {
|
||||
port->BlockSourceTrackIdImpl(trackID);
|
||||
port->BlockSourceTrackIdImpl(trackID, BlockingMode::CREATION);
|
||||
}
|
||||
}
|
||||
port->SetGraphImpl(GraphImpl());
|
||||
|
|
|
@ -1184,6 +1184,23 @@ protected:
|
|||
bool mNeedsMixing;
|
||||
};
|
||||
|
||||
/**
|
||||
* The blocking mode decides how a track should be blocked in a MediaInputPort.
|
||||
*/
|
||||
enum class BlockingMode
|
||||
{
|
||||
/**
|
||||
* BlockingMode CREATION blocks the source track from being created
|
||||
* in the destination. It'll end if it already exists.
|
||||
*/
|
||||
CREATION,
|
||||
/**
|
||||
* BlockingMode END_EXISTING allows a track to be created in the destination
|
||||
* but will end it before any data has been passed through.
|
||||
*/
|
||||
END_EXISTING,
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a connection between a ProcessedMediaStream and one of its
|
||||
* input streams.
|
||||
|
@ -1265,16 +1282,39 @@ public:
|
|||
* Returns a pledge that resolves on the main thread after the track block has
|
||||
* been applied by the MSG.
|
||||
*/
|
||||
already_AddRefed<media::Pledge<bool, nsresult>> BlockSourceTrackId(TrackID aTrackId);
|
||||
already_AddRefed<media::Pledge<bool, nsresult>> BlockSourceTrackId(TrackID aTrackId,
|
||||
BlockingMode aBlockingMode);
|
||||
private:
|
||||
void BlockSourceTrackIdImpl(TrackID aTrackId);
|
||||
void BlockSourceTrackIdImpl(TrackID aTrackId, BlockingMode aBlockingMode);
|
||||
|
||||
public:
|
||||
// Returns true if aTrackId has not been blocked and this port has not
|
||||
// been locked to another track.
|
||||
// Returns true if aTrackId has not been blocked for any reason and this port
|
||||
// has not been locked to another track.
|
||||
bool PassTrackThrough(TrackID aTrackId) {
|
||||
return !mBlockedTracks.Contains(aTrackId) &&
|
||||
(mSourceTrack == TRACK_ANY || mSourceTrack == aTrackId);
|
||||
bool blocked = false;
|
||||
for (auto pair : mBlockedTracks) {
|
||||
if (pair.first() == aTrackId &&
|
||||
(pair.second() == BlockingMode::CREATION ||
|
||||
pair.second() == BlockingMode::END_EXISTING)) {
|
||||
blocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return !blocked && (mSourceTrack == TRACK_ANY || mSourceTrack == aTrackId);
|
||||
}
|
||||
|
||||
// Returns true if aTrackId has not been blocked for track creation and this
|
||||
// port has not been locked to another track.
|
||||
bool AllowCreationOf(TrackID aTrackId) {
|
||||
bool blocked = false;
|
||||
for (auto pair : mBlockedTracks) {
|
||||
if (pair.first() == aTrackId &&
|
||||
pair.second() == BlockingMode::CREATION) {
|
||||
blocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return !blocked && (mSourceTrack == TRACK_ANY || mSourceTrack == aTrackId);
|
||||
}
|
||||
|
||||
uint16_t InputNumber() const { return mInputNumber; }
|
||||
|
@ -1329,7 +1369,9 @@ private:
|
|||
// Web Audio.
|
||||
const uint16_t mInputNumber;
|
||||
const uint16_t mOutputNumber;
|
||||
nsTArray<TrackID> mBlockedTracks;
|
||||
|
||||
typedef Pair<TrackID, BlockingMode> BlockedTrack;
|
||||
nsTArray<BlockedTrack> mBlockedTracks;
|
||||
|
||||
// Our media stream graph
|
||||
MediaStreamGraphImpl* mGraph;
|
||||
|
|
|
@ -237,7 +237,7 @@ MediaStreamTrack::Stop()
|
|||
MOZ_ASSERT(mOwningStream, "Every MediaStreamTrack needs an owning DOMMediaStream");
|
||||
DOMMediaStream::TrackPort* port = mOwningStream->FindOwnedTrackPort(*this);
|
||||
MOZ_ASSERT(port, "A MediaStreamTrack must exist in its owning DOMMediaStream");
|
||||
RefPtr<Pledge<bool>> p = port->BlockSourceTrackId(mInputTrackID);
|
||||
RefPtr<Pledge<bool>> p = port->BlockSourceTrackId(mInputTrackID, BlockingMode::CREATION);
|
||||
Unused << p;
|
||||
|
||||
mReadyState = MediaStreamTrackState::Ended;
|
||||
|
|
|
@ -107,7 +107,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!found && mInputs[i]->PassTrackThrough(tracks->GetID())) {
|
||||
if (!found && mInputs[i]->AllowCreationOf(tracks->GetID())) {
|
||||
bool trackFinished = false;
|
||||
trackAdded = true;
|
||||
uint32_t mapIndex = AddTrack(mInputs[i], tracks.get(), aFrom);
|
||||
|
|
Загрузка…
Ссылка в новой задаче