зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1661668 - Clarify MediaInputPort threading model. r=padenot
Depends on D88821 Differential Revision: https://phabricator.services.mozilla.com/D88822
This commit is contained in:
Родитель
222394b14b
Коммит
cf3a11ca42
|
@ -414,10 +414,10 @@ void MediaTrackGraphImpl::UpdateTrackOrder() {
|
|||
// Not-visited input tracks should be processed first.
|
||||
// SourceMediaTracks have already been ordered.
|
||||
for (uint32_t i = inputs.Length(); i--;) {
|
||||
if (inputs[i]->mSource->IsSuspended()) {
|
||||
if (inputs[i]->GetSource()->IsSuspended()) {
|
||||
continue;
|
||||
}
|
||||
auto input = inputs[i]->mSource->AsProcessedTrack();
|
||||
auto input = inputs[i]->GetSource()->AsProcessedTrack();
|
||||
if (input && input->mCycleMarker == NOT_VISITED) {
|
||||
// It can be that this track has an input which is from a suspended
|
||||
// AudioContext.
|
||||
|
@ -440,10 +440,10 @@ void MediaTrackGraphImpl::UpdateTrackOrder() {
|
|||
// unless it is part of the cycle.
|
||||
uint32_t cycleStackMarker = 0;
|
||||
for (uint32_t i = inputs.Length(); i--;) {
|
||||
if (inputs[i]->mSource->IsSuspended()) {
|
||||
if (inputs[i]->GetSource()->IsSuspended()) {
|
||||
continue;
|
||||
}
|
||||
auto input = inputs[i]->mSource->AsProcessedTrack();
|
||||
auto input = inputs[i]->GetSource()->AsProcessedTrack();
|
||||
if (input) {
|
||||
cycleStackMarker = std::max(cycleStackMarker, input->mCycleMarker);
|
||||
}
|
||||
|
@ -2885,6 +2885,7 @@ float SourceMediaTrack::GetVolumeLocked() {
|
|||
SourceMediaTrack::~SourceMediaTrack() = default;
|
||||
|
||||
void MediaInputPort::Init() {
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
LOG(LogLevel::Debug, ("%p: Adding MediaInputPort %p (from %p to %p)",
|
||||
mSource->GraphImpl(), this, mSource, mDest));
|
||||
// Only connect the port if it wasn't disconnected on allocation.
|
||||
|
@ -2897,17 +2898,20 @@ void MediaInputPort::Init() {
|
|||
}
|
||||
|
||||
void MediaInputPort::Disconnect() {
|
||||
GraphImpl()->AssertOnGraphThreadOrNotRunning();
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
NS_ASSERTION(!mSource == !mDest,
|
||||
"mSource must either both be null or both non-null");
|
||||
if (!mSource) return;
|
||||
"mSource and mDest must either both be null or both non-null");
|
||||
|
||||
if (!mSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSource->RemoveConsumer(this);
|
||||
mDest->RemoveInput(this);
|
||||
mSource = nullptr;
|
||||
mDest = nullptr;
|
||||
|
||||
GraphImpl()->SetTrackOrderDirty();
|
||||
mGraph->SetTrackOrderDirty();
|
||||
}
|
||||
|
||||
MediaInputPort::InputInterval MediaInputPort::GetNextInputInterval(
|
||||
|
@ -2918,6 +2922,7 @@ MediaInputPort::InputInterval MediaInputPort::GetNextInputInterval(
|
|||
result.mInputIsBlocked = true;
|
||||
return result;
|
||||
}
|
||||
aPort->mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
if (aTime >= aPort->mDest->mStartBlocking) {
|
||||
return result;
|
||||
}
|
||||
|
@ -2930,9 +2935,15 @@ MediaInputPort::InputInterval MediaInputPort::GetNextInputInterval(
|
|||
return result;
|
||||
}
|
||||
|
||||
void MediaInputPort::Suspended() { mDest->InputSuspended(this); }
|
||||
void MediaInputPort::Suspended() {
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
mDest->InputSuspended(this);
|
||||
}
|
||||
|
||||
void MediaInputPort::Resumed() { mDest->InputResumed(this); }
|
||||
void MediaInputPort::Resumed() {
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
mDest->InputResumed(this);
|
||||
}
|
||||
|
||||
void MediaInputPort::Destroy() {
|
||||
class Message : public ControlMessage {
|
||||
|
@ -2950,17 +2961,25 @@ void MediaInputPort::Destroy() {
|
|||
};
|
||||
// Keep a reference to the graph, since Message might RunDuringShutdown()
|
||||
// synchronously and make GraphImpl() invalid.
|
||||
RefPtr<MediaTrackGraphImpl> graph = GraphImpl();
|
||||
RefPtr<MediaTrackGraphImpl> graph = mGraph;
|
||||
graph->AppendMessage(MakeUnique<Message>(this));
|
||||
--graph->mMainThreadPortCount;
|
||||
}
|
||||
|
||||
MediaTrackGraphImpl* MediaInputPort::GraphImpl() { return mGraph; }
|
||||
MediaTrackGraphImpl* MediaInputPort::GraphImpl() const {
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
return mGraph;
|
||||
}
|
||||
|
||||
MediaTrackGraph* MediaInputPort::Graph() { return mGraph; }
|
||||
MediaTrackGraph* MediaInputPort::Graph() const {
|
||||
mGraph->AssertOnGraphThreadOrNotRunning();
|
||||
return mGraph;
|
||||
}
|
||||
|
||||
void MediaInputPort::SetGraphImpl(MediaTrackGraphImpl* aGraph) {
|
||||
MOZ_ASSERT(!mGraph || !aGraph, "Should only be set once");
|
||||
DebugOnly<MediaTrackGraphImpl*> graph = mGraph ? mGraph : aGraph;
|
||||
MOZ_ASSERT(graph->OnGraphThreadOrNotRunning());
|
||||
mGraph = aGraph;
|
||||
}
|
||||
|
||||
|
@ -2988,12 +3007,13 @@ already_AddRefed<MediaInputPort> ProcessedMediaTrack::AllocateInputPort(
|
|||
// Create a port that's disconnected, which is what it'd be after its source
|
||||
// track is Destroy()ed normally. Disconnect() is idempotent so destroying
|
||||
// this later is fine.
|
||||
port = new MediaInputPort(nullptr, nullptr, aInputNumber, aOutputNumber);
|
||||
port = new MediaInputPort(GraphImpl(), nullptr, nullptr, aInputNumber,
|
||||
aOutputNumber);
|
||||
} else {
|
||||
MOZ_ASSERT(aTrack->GraphImpl() == GraphImpl());
|
||||
port = new MediaInputPort(aTrack, this, aInputNumber, aOutputNumber);
|
||||
port = new MediaInputPort(GraphImpl(), aTrack, this, aInputNumber,
|
||||
aOutputNumber);
|
||||
}
|
||||
port->SetGraphImpl(GraphImpl());
|
||||
++GraphImpl()->mMainThreadPortCount;
|
||||
GraphImpl()->AppendMessage(MakeUnique<Message>(port));
|
||||
return port.forget();
|
||||
|
|
|
@ -195,7 +195,6 @@ class AudioNodeEngine;
|
|||
class AudioNodeExternalInputTrack;
|
||||
class AudioNodeTrack;
|
||||
class DirectMediaTrackListener;
|
||||
class MediaInputPort;
|
||||
class MediaTrackGraphImpl;
|
||||
class MediaTrackListener;
|
||||
class ProcessedMediaTrack;
|
||||
|
@ -798,13 +797,14 @@ class MediaInputPort final {
|
|||
private:
|
||||
// Do not call this constructor directly. Instead call
|
||||
// aDest->AllocateInputPort.
|
||||
MediaInputPort(MediaTrack* aSource, ProcessedMediaTrack* aDest,
|
||||
uint16_t aInputNumber, uint16_t aOutputNumber)
|
||||
MediaInputPort(MediaTrackGraphImpl* aGraph, MediaTrack* aSource,
|
||||
ProcessedMediaTrack* aDest, uint16_t aInputNumber,
|
||||
uint16_t aOutputNumber)
|
||||
: mSource(aSource),
|
||||
mDest(aDest),
|
||||
mInputNumber(aInputNumber),
|
||||
mOutputNumber(aOutputNumber),
|
||||
mGraph(nullptr) {
|
||||
mGraph(aGraph) {
|
||||
MOZ_COUNT_CTOR(MediaInputPort);
|
||||
}
|
||||
|
||||
|
@ -814,27 +814,26 @@ class MediaInputPort final {
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaInputPort)
|
||||
|
||||
// Called on graph manager thread
|
||||
// Do not call these from outside MediaTrackGraph.cpp!
|
||||
void Init();
|
||||
// Called during message processing to trigger removal of this track.
|
||||
void Disconnect();
|
||||
|
||||
// Control API
|
||||
/**
|
||||
* Disconnects and destroys the port. The caller must not reference this
|
||||
* object again.
|
||||
* object again. Main thread.
|
||||
*/
|
||||
void Destroy();
|
||||
|
||||
// Any thread
|
||||
// The remaining methods and members must always be called on the graph thread
|
||||
// from within MediaTrackGraph.cpp.
|
||||
|
||||
void Init();
|
||||
// Called during message processing to trigger removal of this port's source
|
||||
// and destination tracks.
|
||||
void Disconnect();
|
||||
|
||||
MediaTrack* GetSource() const { return mSource; }
|
||||
ProcessedMediaTrack* GetDestination() const { return mDest; }
|
||||
|
||||
uint16_t InputNumber() const { return mInputNumber; }
|
||||
uint16_t OutputNumber() const { return mOutputNumber; }
|
||||
|
||||
// Call on graph manager thread
|
||||
struct InputInterval {
|
||||
GraphTime mStart;
|
||||
GraphTime mEnd;
|
||||
|
@ -849,8 +848,8 @@ class MediaInputPort final {
|
|||
/**
|
||||
* Returns the graph that owns this port.
|
||||
*/
|
||||
MediaTrackGraphImpl* GraphImpl();
|
||||
MediaTrackGraph* Graph();
|
||||
MediaTrackGraphImpl* GraphImpl() const;
|
||||
MediaTrackGraph* Graph() const;
|
||||
|
||||
/**
|
||||
* Sets the graph that owns this track. Should only be called once.
|
||||
|
@ -882,8 +881,6 @@ class MediaInputPort final {
|
|||
}
|
||||
|
||||
private:
|
||||
friend class MediaTrackGraphImpl;
|
||||
friend class MediaTrack;
|
||||
friend class ProcessedMediaTrack;
|
||||
// Never modified after Init()
|
||||
MediaTrack* mSource;
|
||||
|
|
Загрузка…
Ссылка в новой задаче