コード例 #1
0
ファイル: AudioNode.cpp プロジェクト: brendandahl/positron
bool
AudioNode::DisconnectFromParamIfConnected(AudioParam& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex)
{
  MOZ_ASSERT(aOutputIndex < mOutputParams.Length());
  MOZ_ASSERT(aInputIndex < aDestination.InputNodes().Length());

  const InputNode& input = aDestination.InputNodes()[aInputIndex];
  if (input.mInputNode != this) {
    return false;
  }
  aDestination.RemoveInputNode(aInputIndex);
  // Remove one instance of 'dest' from mOutputParams. There could be
  // others, and it's not correct to remove them all since some of them
  // could be for different output ports.
  mOutputParams.RemoveElementAt(aOutputIndex);
  return true;
}
コード例 #2
0
ファイル: AudioNode.cpp プロジェクト: eeejay/gecko-dev
void
AudioNode::Disconnect(uint32_t aOutput, ErrorResult& aRv)
{
  if (aOutput >= NumberOfOutputs()) {
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    return;
  }

  // An upstream node may be starting to play on the graph thread, and the
  // engine for a downstream node may be sending a PlayingRefChangeHandler
  // ADDREF message to this (main) thread.  Wait for a round trip before
  // releasing nodes, to give engines receiving sound now time to keep their
  // nodes alive.
  class RunnableRelease final : public nsRunnable
  {
  public:
    explicit RunnableRelease(already_AddRefed<AudioNode> aNode)
      : mNode(aNode) {}

    NS_IMETHODIMP Run() override
    {
      mNode = nullptr;
      return NS_OK;
    }
  private:
    nsRefPtr<AudioNode> mNode;
  };

  for (int32_t i = mOutputNodes.Length() - 1; i >= 0; --i) {
    AudioNode* dest = mOutputNodes[i];
    for (int32_t j = dest->mInputNodes.Length() - 1; j >= 0; --j) {
      InputNode& input = dest->mInputNodes[j];
      if (input.mInputNode == this && input.mOutputPort == aOutput) {
        // Destroying the InputNode here sends a message to the graph thread
        // to disconnect the streams, which should be sent before the
        // RunAfterPendingUpdates() call below.
        dest->mInputNodes.RemoveElementAt(j);
        // Remove one instance of 'dest' from mOutputNodes. There could be
        // others, and it's not correct to remove them all since some of them
        // could be for different output ports.
        nsRefPtr<AudioNode> output = mOutputNodes[i].forget();
        mOutputNodes.RemoveElementAt(i);
        output->NotifyInputsChanged();
        if (mStream) {
          nsRefPtr<nsIRunnable> runnable = new RunnableRelease(output.forget());
          mStream->RunAfterPendingUpdates(runnable.forget());
        }
        break;
      }
    }
  }

  for (int32_t i = mOutputParams.Length() - 1; i >= 0; --i) {
    AudioParam* dest = mOutputParams[i];
    for (int32_t j = dest->InputNodes().Length() - 1; j >= 0; --j) {
      const InputNode& input = dest->InputNodes()[j];
      if (input.mInputNode == this && input.mOutputPort == aOutput) {
        dest->RemoveInputNode(j);
        // Remove one instance of 'dest' from mOutputParams. There could be
        // others, and it's not correct to remove them all since some of them
        // could be for different output ports.
        mOutputParams.RemoveElementAt(i);
        break;
      }
    }
  }

  // This disconnection may have disconnected a panner and a source.
  Context()->UpdatePannerSource();
}