Commit 0676daca authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

WebAudio: Fix MediaStreamAudioDestinationNode liveness

Canonical fix:
- Model liveness through MediaStreamAudioDestinationNode (AudioNode),
  i.e., keep alive listener from there.
- Change off-thread handler to use a weak root

This works as AudioNode disposes the handler in the pre-finalizer.

Bug: 928781, 843903
Change-Id: Ia8eedeb29896bc29d9eb2b81c04d44bc1a21a3c0
Reviewed-on: https://chromium-review.googlesource.com/c/1489247Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635971}
parent 97ab3c2a
......@@ -49,23 +49,10 @@ MediaStreamAudioDestinationHandler::MediaStreamAudioDestinationHandler(
node,
node.context()->sampleRate(),
number_of_channels),
source_(static_cast<MediaStreamAudioDestinationNode&>(node).source()),
mix_bus_(AudioBus::Create(number_of_channels,
audio_utilities::kRenderQuantumFrames)) {
source_ = MediaStreamSource::Create("WebAudio-" + CreateCanonicalUUIDString(),
MediaStreamSource::kTypeAudio,
"MediaStreamAudioDestinationNode", false,
MediaStreamSource::kReadyStateLive, true);
MediaStreamSourceVector audio_sources;
audio_sources.push_back(source_.Get());
MediaStreamSourceVector video_sources;
stream_ = MediaStream::Create(
node.context()->GetExecutionContext(),
MediaStreamDescriptor::Create(audio_sources, video_sources));
MediaStreamCenter::Instance().DidCreateMediaStreamAndTracks(
stream_->Descriptor());
source_->SetAudioFormat(number_of_channels, node.context()->sampleRate());
SetInternalChannelCountMode(kExplicit);
Initialize();
}
......@@ -144,7 +131,20 @@ uint32_t MediaStreamAudioDestinationHandler::MaxChannelCount() const {
MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(
AudioContext& context,
uint32_t number_of_channels)
: AudioBasicInspectorNode(context) {
: AudioBasicInspectorNode(context),
source_(
MediaStreamSource::Create("WebAudio-" + CreateCanonicalUUIDString(),
MediaStreamSource::kTypeAudio,
"MediaStreamAudioDestinationNode",
false,
MediaStreamSource::kReadyStateLive,
true)),
stream_(MediaStream::Create(context.GetExecutionContext(),
MediaStreamDescriptor::Create(
MediaStreamSourceVector({source_.Get()}),
MediaStreamSourceVector()))) {
MediaStreamCenter::Instance().DidCreateMediaStreamAndTracks(
stream_->Descriptor());
SetHandler(
MediaStreamAudioDestinationHandler::Create(*this, number_of_channels));
}
......@@ -181,8 +181,10 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
return node;
}
MediaStream* MediaStreamAudioDestinationNode::stream() const {
return static_cast<MediaStreamAudioDestinationHandler&>(Handler()).Stream();
void MediaStreamAudioDestinationNode::Trace(Visitor* visitor) {
visitor->Trace(stream_);
visitor->Trace(source_);
AudioBasicInspectorNode::Trace(visitor);
}
} // namespace blink
......@@ -43,8 +43,6 @@ class MediaStreamAudioDestinationHandler final
uint32_t number_of_channels);
~MediaStreamAudioDestinationHandler() override;
MediaStream* Stream() { return stream_.Get(); }
// AudioHandler.
void Process(uint32_t frames_to_process) override;
void SetChannelCount(unsigned, ExceptionState&) override;
......@@ -58,12 +56,11 @@ class MediaStreamAudioDestinationHandler final
// As an audio source, we will never propagate silence.
bool PropagatesSilence() const override { return false; }
// This Persistent doesn't make a reference cycle.
Persistent<MediaStream> stream_;
// MediaStreamSource is held alive by MediaStreamAudioDestinationNode.
// Accessed by main thread and during audio thread processing.
//
// TODO: try to avoid such access during audio thread processing.
CrossThreadPersistent<MediaStreamSource> source_;
CrossThreadWeakPersistent<MediaStreamSource> source_;
// This synchronizes dynamic changes to the channel count with
// process() to manage the mix bus.
......@@ -87,7 +84,14 @@ class MediaStreamAudioDestinationNode final : public AudioBasicInspectorNode {
MediaStreamAudioDestinationNode(AudioContext&, uint32_t number_of_channels);
MediaStream* stream() const;
MediaStream* stream() const { return stream_; }
MediaStreamSource* source() const { return source_; }
void Trace(Visitor*) final;
private:
const Member<MediaStreamSource> source_;
const Member<MediaStream> stream_;
};
} // namespace blink
......
......@@ -630,6 +630,9 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
template <wtf_size_t otherCapacity>
HeapVector(const HeapVector<T, otherCapacity>& other)
: Vector<T, inlineCapacity, HeapAllocator>(other) {}
HeapVector(std::initializer_list<T> elements)
: Vector<T, inlineCapacity, HeapAllocator>(elements) {}
};
template <typename T, wtf_size_t inlineCapacity = 0>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment