Bug 1661668 - Clarify MediaInputPort threading model. r=padenot

Depends on D88821

Differential Revision: https://phabricator.services.mozilla.com/D88822
This commit is contained in:
Andreas Pehrson 2020-08-31 15:34:42 +00:00
Родитель 222394b14b
Коммит cf3a11ca42
2 изменённых файлов: 51 добавлений и 34 удалений

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

@ -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;