зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1544023 - let AudioNode keep the reference of all AudioParams which belong to itself. r=padenot
When we suspend or resume the `AudioContext`, it should affect ALL media streams which belong to or are related to the `AudioNode` that are created by this `AudioContext`. As `AudioNode::OutputParams()` can only return the connected AudioParams, it doesn't return the AudioParams which are belong to itself. That means we would miss to apply the suspend/resume operation for those streams, and it would cause imbalancing suspended count. Therefore, we let `AudioNode` to keep the reference of all its AudioParam, and return them to `AudioContext` in order to do the operation for all streams. Differential Revision: https://phabricator.services.mozilla.com/D28008 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d547376a66
Коммит
c58212fe27
|
@ -588,13 +588,12 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
|
|||
: AudioScheduledSourceNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mLoopStart(0.0),
|
||||
mLoopEnd(0.0)
|
||||
mLoopEnd(0.0),
|
||||
// mOffset and mDuration are initialized in Start().
|
||||
,
|
||||
mPlaybackRate(new AudioParam(this, PLAYBACKRATE, "playbackRate", 1.0f)),
|
||||
mDetune(new AudioParam(this, DETUNE, "detune", 0.0f)),
|
||||
mLoop(false),
|
||||
mStartCalled(false) {
|
||||
CreateAudioParam(mPlaybackRate, PLAYBACKRATE, "playbackRate", 1.0f);
|
||||
CreateAudioParam(mDetune, DETUNE, "detune", 0.0f);
|
||||
AudioBufferSourceNodeEngine* engine =
|
||||
new AudioBufferSourceNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(aContext, engine,
|
||||
|
|
|
@ -904,8 +904,8 @@ nsTArray<MediaStream*> AudioContext::GetAllStreams() const {
|
|||
if (s) {
|
||||
streams.AppendElement(s);
|
||||
}
|
||||
// Add the streams for the AudioParam that have an AudioNode input.
|
||||
const nsTArray<RefPtr<AudioParam>>& audioParams = node->OutputParams();
|
||||
// Add the streams of AudioParam.
|
||||
const nsTArray<RefPtr<AudioParam>>& audioParams = node->GetAudioParams();
|
||||
if (!audioParams.IsEmpty()) {
|
||||
for (auto& param : audioParams) {
|
||||
s = param->GetStream();
|
||||
|
|
|
@ -26,12 +26,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AudioNode, DOMEventTargetHelper)
|
|||
tmp->mContext->UnregisterNode(tmp);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputNodes)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioNode,
|
||||
DOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputNodes)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
@ -595,5 +597,13 @@ void AudioNode::SetPassThrough(bool aPassThrough) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioNode::CreateAudioParam(RefPtr<AudioParam>& aParam, uint32_t aIndex,
|
||||
const char* aName, float aDefaultValue,
|
||||
float aMinValue, float aMaxValue) {
|
||||
aParam =
|
||||
new AudioParam(this, aIndex, aName, aDefaultValue, aMinValue, aMaxValue);
|
||||
mParams.AppendElement(aParam);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -168,10 +168,10 @@ class AudioNode : public DOMEventTargetHelper, public nsSupportsWeakReference {
|
|||
AudioNodeStream* GetStream() const { return mStream; }
|
||||
|
||||
const nsTArray<InputNode>& InputNodes() const { return mInputNodes; }
|
||||
const nsTArray<RefPtr<AudioNode> >& OutputNodes() const {
|
||||
const nsTArray<RefPtr<AudioNode>>& OutputNodes() const {
|
||||
return mOutputNodes;
|
||||
}
|
||||
const nsTArray<RefPtr<AudioParam> >& OutputParams() const {
|
||||
const nsTArray<RefPtr<AudioParam>>& OutputParams() const {
|
||||
return mOutputParams;
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,8 @@ class AudioNode : public DOMEventTargetHelper, public nsSupportsWeakReference {
|
|||
// during document shutdown.
|
||||
AbstractThread* GetAbstractMainThread() const { return mAbstractMainThread; }
|
||||
|
||||
const nsTArray<RefPtr<AudioParam>>& GetAudioParams() const { return mParams; }
|
||||
|
||||
private:
|
||||
// Given:
|
||||
//
|
||||
|
@ -246,6 +248,15 @@ class AudioNode : public DOMEventTargetHelper, public nsSupportsWeakReference {
|
|||
// Must not become null until finished.
|
||||
RefPtr<AudioNodeStream> mStream;
|
||||
|
||||
// The reference pointing out all audio params which belong to this node.
|
||||
nsTArray<RefPtr<AudioParam>> mParams;
|
||||
// Use this function to create a AudioParam, which will automatically add the
|
||||
// new AudioParam to `mParams`.
|
||||
void CreateAudioParam(RefPtr<AudioParam>& aParam, uint32_t aIndex,
|
||||
const char* aName, float aDefaultValue,
|
||||
float aMinValue = std::numeric_limits<float>::lowest(),
|
||||
float aMaxValue = std::numeric_limits<float>::max());
|
||||
|
||||
private:
|
||||
// For every InputNode, there is a corresponding entry in mOutputNodes of the
|
||||
// InputNode's mInputNode.
|
||||
|
@ -254,13 +265,13 @@ class AudioNode : public DOMEventTargetHelper, public nsSupportsWeakReference {
|
|||
// of the mOutputNode entry. We won't necessarily be able to identify the
|
||||
// exact matching entry, since mOutputNodes doesn't include the port
|
||||
// identifiers and the same node could be connected on multiple ports.
|
||||
nsTArray<RefPtr<AudioNode> > mOutputNodes;
|
||||
nsTArray<RefPtr<AudioNode>> mOutputNodes;
|
||||
// For every mOutputParams entry, there is a corresponding entry in
|
||||
// AudioParam::mInputNodes of the mOutputParams entry. We won't necessarily be
|
||||
// able to identify the exact matching entry, since mOutputParams doesn't
|
||||
// include the port identifiers and the same node could be connected on
|
||||
// multiple ports.
|
||||
nsTArray<RefPtr<AudioParam> > mOutputParams;
|
||||
nsTArray<RefPtr<AudioParam>> mOutputParams;
|
||||
uint32_t mChannelCount;
|
||||
ChannelCountMode mChannelCountMode;
|
||||
ChannelInterpretation mChannelInterpretation;
|
||||
|
|
|
@ -224,14 +224,14 @@ class BiquadFilterNodeEngine final : public AudioNodeEngine {
|
|||
BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
|
||||
: AudioNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mType(BiquadFilterType::Lowpass),
|
||||
mFrequency(new AudioParam(
|
||||
this, BiquadFilterNodeEngine::FREQUENCY, "frequency", 350.f,
|
||||
-(aContext->SampleRate() / 2), aContext->SampleRate() / 2)),
|
||||
mDetune(
|
||||
new AudioParam(this, BiquadFilterNodeEngine::DETUNE, "detune", 0.f)),
|
||||
mQ(new AudioParam(this, BiquadFilterNodeEngine::Q, "Q", 1.f)),
|
||||
mGain(new AudioParam(this, BiquadFilterNodeEngine::GAIN, "gain", 0.f)) {
|
||||
mType(BiquadFilterType::Lowpass) {
|
||||
CreateAudioParam(mFrequency, BiquadFilterNodeEngine::FREQUENCY, "frequency",
|
||||
350.f, -(aContext->SampleRate() / 2),
|
||||
aContext->SampleRate() / 2);
|
||||
CreateAudioParam(mDetune, BiquadFilterNodeEngine::DETUNE, "detune", 0.f);
|
||||
CreateAudioParam(mQ, BiquadFilterNodeEngine::Q, "Q", 1.f);
|
||||
CreateAudioParam(mGain, BiquadFilterNodeEngine::GAIN, "gain", 0.f);
|
||||
|
||||
uint64_t windowID = 0;
|
||||
if (aContext->GetParentObject()) {
|
||||
windowID = aContext->GetParentObject()->WindowID();
|
||||
|
|
|
@ -156,9 +156,8 @@ class ConstantSourceNodeEngine final : public AudioNodeEngine {
|
|||
ConstantSourceNode::ConstantSourceNode(AudioContext* aContext)
|
||||
: AudioScheduledSourceNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mOffset(new AudioParam(this, ConstantSourceNodeEngine::OFFSET, "offset",
|
||||
1.0f)),
|
||||
mStartCalled(false) {
|
||||
CreateAudioParam(mOffset, ConstantSourceNodeEngine::OFFSET, "offset", 1.0f);
|
||||
ConstantSourceNodeEngine* engine =
|
||||
new ConstantSourceNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(aContext, engine,
|
||||
|
|
|
@ -172,9 +172,9 @@ class DelayNodeEngine final : public AudioNodeEngine {
|
|||
|
||||
DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
|
||||
: AudioNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mDelay(new AudioParam(this, DelayNodeEngine::DELAY, "delayTime", 0.0f,
|
||||
0.f, aMaxDelay)) {
|
||||
ChannelInterpretation::Speakers) {
|
||||
CreateAudioParam(mDelay, DelayNodeEngine::DELAY, "delayTime", 0.0f, 0.f,
|
||||
aMaxDelay);
|
||||
DelayNodeEngine* engine = new DelayNodeEngine(
|
||||
this, aContext->Destination(), aContext->SampleRate() * aMaxDelay);
|
||||
mStream = AudioNodeStream::Create(
|
||||
|
|
|
@ -163,17 +163,17 @@ class DynamicsCompressorNodeEngine final : public AudioNodeEngine {
|
|||
DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
|
||||
: AudioNode(aContext, 2, ChannelCountMode::Clamped_max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mThreshold(new AudioParam(this, DynamicsCompressorNodeEngine::THRESHOLD,
|
||||
"threshold", -24.f, -100.f, 0.f)),
|
||||
mKnee(new AudioParam(this, DynamicsCompressorNodeEngine::KNEE, "knee",
|
||||
30.f, 0.f, 40.f)),
|
||||
mRatio(new AudioParam(this, DynamicsCompressorNodeEngine::RATIO, "ratio",
|
||||
12.f, 1.f, 20.f)),
|
||||
mReduction(0),
|
||||
mAttack(new AudioParam(this, DynamicsCompressorNodeEngine::ATTACK,
|
||||
"attack", 0.003f, 0.f, 1.f)),
|
||||
mRelease(new AudioParam(this, DynamicsCompressorNodeEngine::RELEASE,
|
||||
"release", 0.25f, 0.f, 1.f)) {
|
||||
mReduction(0) {
|
||||
CreateAudioParam(mThreshold, DynamicsCompressorNodeEngine::THRESHOLD,
|
||||
"threshold", -24.f, -100.f, 0.f);
|
||||
CreateAudioParam(mKnee, DynamicsCompressorNodeEngine::KNEE, "knee", 30.f, 0.f,
|
||||
40.f);
|
||||
CreateAudioParam(mRatio, DynamicsCompressorNodeEngine::RATIO, "ratio", 12.f,
|
||||
1.f, 20.f);
|
||||
CreateAudioParam(mAttack, DynamicsCompressorNodeEngine::ATTACK, "attack",
|
||||
0.003f, 0.f, 1.f);
|
||||
CreateAudioParam(mRelease, DynamicsCompressorNodeEngine::RELEASE, "release",
|
||||
0.25f, 0.f, 1.f);
|
||||
DynamicsCompressorNodeEngine* engine =
|
||||
new DynamicsCompressorNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(
|
||||
|
|
|
@ -108,8 +108,8 @@ class GainNodeEngine final : public AudioNodeEngine {
|
|||
|
||||
GainNode::GainNode(AudioContext* aContext)
|
||||
: AudioNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mGain(new AudioParam(this, GainNodeEngine::GAIN, "gain", 1.0f)) {
|
||||
ChannelInterpretation::Speakers) {
|
||||
CreateAudioParam(mGain, GainNodeEngine::GAIN, "gain", 1.0f);
|
||||
GainNodeEngine* engine = new GainNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(
|
||||
aContext, engine, AudioNodeStream::NO_STREAM_FLAGS, aContext->Graph());
|
||||
|
|
|
@ -371,12 +371,11 @@ OscillatorNode::OscillatorNode(AudioContext* aContext)
|
|||
: AudioScheduledSourceNode(aContext, 2, ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mType(OscillatorType::Sine),
|
||||
mFrequency(new AudioParam(
|
||||
this, OscillatorNodeEngine::FREQUENCY, "frequency", 440.0f,
|
||||
-(aContext->SampleRate() / 2), aContext->SampleRate() / 2)),
|
||||
mDetune(
|
||||
new AudioParam(this, OscillatorNodeEngine::DETUNE, "detune", 0.0f)),
|
||||
mStartCalled(false) {
|
||||
CreateAudioParam(mFrequency, OscillatorNodeEngine::FREQUENCY, "frequency",
|
||||
440.0f, -(aContext->SampleRate() / 2),
|
||||
aContext->SampleRate() / 2);
|
||||
CreateAudioParam(mDetune, OscillatorNodeEngine::DETUNE, "detune", 0.0f);
|
||||
OscillatorNodeEngine* engine =
|
||||
new OscillatorNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(aContext, engine,
|
||||
|
|
|
@ -296,24 +296,21 @@ PannerNode::PannerNode(AudioContext* aContext)
|
|||
,
|
||||
mPanningModel(PanningModelType::Equalpower),
|
||||
mDistanceModel(DistanceModelType::Inverse),
|
||||
mPositionX(
|
||||
new AudioParam(this, PannerNode::POSITIONX, this->NodeType(), 0.f)),
|
||||
mPositionY(
|
||||
new AudioParam(this, PannerNode::POSITIONY, this->NodeType(), 0.f)),
|
||||
mPositionZ(
|
||||
new AudioParam(this, PannerNode::POSITIONZ, this->NodeType(), 0.f)),
|
||||
mOrientationX(new AudioParam(this, PannerNode::ORIENTATIONX,
|
||||
this->NodeType(), 1.0f)),
|
||||
mOrientationY(new AudioParam(this, PannerNode::ORIENTATIONY,
|
||||
this->NodeType(), 0.f)),
|
||||
mOrientationZ(new AudioParam(this, PannerNode::ORIENTATIONZ,
|
||||
this->NodeType(), 0.f)),
|
||||
mRefDistance(1.),
|
||||
mMaxDistance(10000.),
|
||||
mRolloffFactor(1.),
|
||||
mConeInnerAngle(360.),
|
||||
mConeOuterAngle(360.),
|
||||
mConeOuterGain(0.) {
|
||||
CreateAudioParam(mPositionX, PannerNode::POSITIONX, this->NodeType(), 0.f);
|
||||
CreateAudioParam(mPositionY, PannerNode::POSITIONY, this->NodeType(), 0.f);
|
||||
CreateAudioParam(mPositionZ, PannerNode::POSITIONZ, this->NodeType(), 0.f);
|
||||
CreateAudioParam(mOrientationX, PannerNode::ORIENTATIONX, this->NodeType(),
|
||||
1.0f);
|
||||
CreateAudioParam(mOrientationY, PannerNode::ORIENTATIONY, this->NodeType(),
|
||||
0.f);
|
||||
CreateAudioParam(mOrientationZ, PannerNode::ORIENTATIONZ, this->NodeType(),
|
||||
0.f);
|
||||
mStream = AudioNodeStream::Create(
|
||||
aContext,
|
||||
new PannerNodeEngine(this, aContext->Destination(),
|
||||
|
|
|
@ -155,9 +155,8 @@ class StereoPannerNodeEngine final : public AudioNodeEngine {
|
|||
|
||||
StereoPannerNode::StereoPannerNode(AudioContext* aContext)
|
||||
: AudioNode(aContext, 2, ChannelCountMode::Clamped_max,
|
||||
ChannelInterpretation::Speakers),
|
||||
mPan(new AudioParam(this, StereoPannerNodeEngine::PAN, "pan", 0.f, -1.f,
|
||||
1.f)) {
|
||||
ChannelInterpretation::Speakers) {
|
||||
CreateAudioParam(mPan, StereoPannerNodeEngine::PAN, "pan", 0.f, -1.f, 1.f);
|
||||
StereoPannerNodeEngine* engine =
|
||||
new StereoPannerNodeEngine(this, aContext->Destination());
|
||||
mStream = AudioNodeStream::Create(
|
||||
|
|
Загрузка…
Ссылка в новой задаче