LCOV - code coverage report
Current view: top level - dom/media/webaudio - AudioNode.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 55 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef AudioNode_h_
       8             : #define AudioNode_h_
       9             : 
      10             : #include "mozilla/DOMEventTargetHelper.h"
      11             : #include "mozilla/dom/AudioNodeBinding.h"
      12             : #include "nsCycleCollectionParticipant.h"
      13             : #include "nsTArray.h"
      14             : #include "AudioContext.h"
      15             : #include "MediaStreamGraph.h"
      16             : #include "WebAudioUtils.h"
      17             : #include "mozilla/MemoryReporting.h"
      18             : #include "nsWeakReference.h"
      19             : #include "SelfRef.h"
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : class AbstractThread;
      24             : 
      25             : namespace dom {
      26             : 
      27             : class AudioContext;
      28             : class AudioBufferSourceNode;
      29             : class AudioParam;
      30             : class AudioParamTimeline;
      31             : struct ThreeDPoint;
      32             : 
      33             : /**
      34             :  * The DOM object representing a Web Audio AudioNode.
      35             :  *
      36             :  * Each AudioNode has a MediaStream representing the actual
      37             :  * real-time processing and output of this AudioNode.
      38             :  *
      39             :  * We track the incoming and outgoing connections to other AudioNodes.
      40             :  * Outgoing connections have strong ownership.  Also, AudioNodes that will
      41             :  * produce sound on their output even when they have silent or no input ask
      42             :  * the AudioContext to keep playing or tail-time references to keep them alive
      43             :  * until the context is finished.
      44             :  *
      45             :  * Explicit disconnections will only remove references from output nodes after
      46             :  * the graph is notified and the main thread receives a reply.  Similarly,
      47             :  * nodes with playing or tail-time references release these references only
      48             :  * after receiving notification from their engine on the graph thread that
      49             :  * playing has stopped.  Engines notifying the main thread that they have
      50             :  * finished do so strictly *after* producing and returning their last block.
      51             :  * In this way, an engine that receives non-null input knows that the input
      52             :  * comes from nodes that are still alive and will keep their output nodes
      53             :  * alive for at least as long as it takes to process messages from the graph
      54             :  * thread.  i.e. the engine receiving non-null input knows that its node is
      55             :  * still alive, and will still be alive when it receives a message from the
      56             :  * engine.
      57             :  */
      58             : class AudioNode : public DOMEventTargetHelper,
      59             :                   public nsSupportsWeakReference
      60             : {
      61             : protected:
      62             :   // You can only use refcounting to delete this object
      63             :   virtual ~AudioNode();
      64             : 
      65             : public:
      66             :   AudioNode(AudioContext* aContext,
      67             :             uint32_t aChannelCount,
      68             :             ChannelCountMode aChannelCountMode,
      69             :             ChannelInterpretation aChannelInterpretation);
      70             : 
      71             :   // This should be idempotent (safe to call multiple times).
      72             :   virtual void DestroyMediaStream();
      73             : 
      74             :   NS_DECL_ISUPPORTS_INHERITED
      75           0 :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioNode,
      76             :                                            DOMEventTargetHelper)
      77             : 
      78           0 :   virtual AudioBufferSourceNode* AsAudioBufferSourceNode()
      79             :   {
      80           0 :     return nullptr;
      81             :   }
      82             : 
      83           0 :   AudioContext* GetParentObject() const
      84             :   {
      85           0 :     return mContext;
      86             :   }
      87             : 
      88           0 :   AudioContext* Context() const
      89             :   {
      90           0 :     return mContext;
      91             :   }
      92             : 
      93             :   virtual AudioNode* Connect(AudioNode& aDestination, uint32_t aOutput,
      94             :                              uint32_t aInput, ErrorResult& aRv);
      95             : 
      96             :   virtual void Connect(AudioParam& aDestination, uint32_t aOutput,
      97             :                        ErrorResult& aRv);
      98             : 
      99             :   virtual void Disconnect(ErrorResult& aRv);
     100             :   virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv);
     101             :   virtual void Disconnect(AudioNode& aDestination, ErrorResult& aRv);
     102             :   virtual void Disconnect(AudioNode& aDestination, uint32_t aOutput,
     103             :                           ErrorResult& aRv);
     104             :   virtual void Disconnect(AudioNode& aDestination,
     105             :                           uint32_t aOutput, uint32_t aInput,
     106             :                           ErrorResult& aRv);
     107             :   virtual void Disconnect(AudioParam& aDestination, ErrorResult& aRv);
     108             :   virtual void Disconnect(AudioParam& aDestination, uint32_t aOutput,
     109             :                           ErrorResult& aRv);
     110             : 
     111             :   // Called after input nodes have been explicitly added or removed through
     112             :   // the Connect() or Disconnect() methods.
     113           0 :   virtual void NotifyInputsChanged() {}
     114             :   // Indicate that the node should continue indefinitely to behave as if an
     115             :   // input is connected, even though there is no longer a corresponding entry
     116             :   // in mInputNodes.  Called after an input node has been removed because it
     117             :   // is being garbage collected.
     118           0 :   virtual void NotifyHasPhantomInput() {}
     119             : 
     120             :   // The following two virtual methods must be implemented by each node type
     121             :   // to provide their number of input and output ports. These numbers are
     122             :   // constant for the lifetime of the node. Both default to 1.
     123           0 :   virtual uint16_t NumberOfInputs() const { return 1; }
     124           0 :   virtual uint16_t NumberOfOutputs() const { return 1; }
     125             : 
     126           0 :   uint32_t Id() const { return mId; }
     127             : 
     128             :   bool PassThrough() const;
     129             :   void SetPassThrough(bool aPassThrough);
     130             : 
     131           0 :   uint32_t ChannelCount() const { return mChannelCount; }
     132           0 :   virtual void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv)
     133             :   {
     134           0 :     if (aChannelCount == 0 ||
     135             :         aChannelCount > WebAudioUtils::MaxChannelCount) {
     136           0 :       aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     137           0 :       return;
     138             :     }
     139           0 :     mChannelCount = aChannelCount;
     140           0 :     SendChannelMixingParametersToStream();
     141             :   }
     142           0 :   ChannelCountMode ChannelCountModeValue() const
     143             :   {
     144           0 :     return mChannelCountMode;
     145             :   }
     146           0 :   virtual void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv)
     147             :   {
     148           0 :     mChannelCountMode = aMode;
     149           0 :     SendChannelMixingParametersToStream();
     150           0 :   }
     151           0 :   ChannelInterpretation ChannelInterpretationValue() const
     152             :   {
     153           0 :     return mChannelInterpretation;
     154             :   }
     155           0 :   void SetChannelInterpretationValue(ChannelInterpretation aMode)
     156             :   {
     157           0 :     mChannelInterpretation = aMode;
     158           0 :     SendChannelMixingParametersToStream();
     159           0 :   }
     160             : 
     161           0 :   struct InputNode final
     162             :   {
     163           0 :     ~InputNode()
     164           0 :     {
     165           0 :       if (mStreamPort) {
     166           0 :         mStreamPort->Destroy();
     167             :       }
     168           0 :     }
     169             : 
     170           0 :     size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
     171             :     {
     172           0 :       size_t amount = 0;
     173           0 :       if (mStreamPort) {
     174           0 :         amount += mStreamPort->SizeOfIncludingThis(aMallocSizeOf);
     175             :       }
     176             : 
     177           0 :       return amount;
     178             :     }
     179             : 
     180             :     // Weak reference.
     181             :     AudioNode* mInputNode;
     182             :     RefPtr<MediaInputPort> mStreamPort;
     183             :     // The index of the input port this node feeds into.
     184             :     // This is not used for connections to AudioParams.
     185             :     uint32_t mInputPort;
     186             :     // The index of the output port this node comes out of.
     187             :     uint32_t mOutputPort;
     188             :   };
     189             : 
     190             :   // Returns the stream, if any.
     191           0 :   AudioNodeStream* GetStream() const { return mStream; }
     192             : 
     193           0 :   const nsTArray<InputNode>& InputNodes() const
     194             :   {
     195           0 :     return mInputNodes;
     196             :   }
     197           0 :   const nsTArray<RefPtr<AudioNode> >& OutputNodes() const
     198             :   {
     199           0 :     return mOutputNodes;
     200             :   }
     201           0 :   const nsTArray<RefPtr<AudioParam> >& OutputParams() const
     202             :   {
     203           0 :     return mOutputParams;
     204             :   }
     205             : 
     206             :   template<typename T>
     207             :   const nsTArray<InputNode>&
     208             :   InputsForDestination(uint32_t aOutputIndex) const;
     209             : 
     210             :   void RemoveOutputParam(AudioParam* aParam);
     211             : 
     212             :   // MarkActive() asks the context to keep the AudioNode alive until the
     213             :   // context is finished.  This takes care of "playing" references and
     214             :   // "tail-time" references.
     215           0 :   void MarkActive() { Context()->RegisterActiveNode(this); }
     216             :   // Active nodes call MarkInactive() when they have finished producing sound
     217             :   // for the foreseeable future.
     218             :   // Do not call MarkInactive from a node destructor.  If the destructor is
     219             :   // called, then the node is already inactive.
     220             :   // MarkInactive() may delete |this|.
     221           0 :   void MarkInactive() { Context()->UnregisterActiveNode(this); }
     222             : 
     223             :   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
     224             :   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
     225             : 
     226             :   // Returns a string from constant static storage identifying the dom node
     227             :   // type.
     228             :   virtual const char* NodeType() const = 0;
     229             : 
     230           0 :   AbstractThread* AbstractMainThread() const { return mAbstractMainThread; }
     231             : 
     232             : private:
     233             :   // Given:
     234             :   //
     235             :   // - a DestinationType, that can be an AudioNode or an AudioParam ;
     236             :   // - a Predicate, a function that takes an InputNode& and returns a bool ;
     237             :   //
     238             :   // This method iterates on the InputNodes() of the node at the index
     239             :   // aDestinationIndex, and calls `DisconnectFromOutputIfConnected` with this
     240             :   // input node, if aPredicate returns true.
     241             :   template<typename DestinationType, typename Predicate>
     242             :   bool DisconnectMatchingDestinationInputs(uint32_t aDestinationIndex,
     243             :                                            Predicate aPredicate);
     244             : 
     245           0 :   virtual void LastRelease() override
     246             :   {
     247             :     // We are about to be deleted, disconnect the object from the graph before
     248             :     // the derived type is destroyed.
     249           0 :     DisconnectFromGraph();
     250           0 :   }
     251             :   // Callers must hold a reference to 'this'.
     252             :   void DisconnectFromGraph();
     253             : 
     254             :   template<typename DestinationType>
     255             :   bool DisconnectFromOutputIfConnected(uint32_t aOutputIndex, uint32_t aInputIndex);
     256             : 
     257             : protected:
     258             :   // Helper for the Constructors for nodes.
     259             :   void Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv);
     260             : 
     261             :   // Helpers for sending different value types to streams
     262             :   void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
     263             :   void SendInt32ParameterToStream(uint32_t aIndex, int32_t aValue);
     264             :   void SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue);
     265             :   void SendChannelMixingParametersToStream();
     266             : 
     267             : private:
     268             :   RefPtr<AudioContext> mContext;
     269             : 
     270             : protected:
     271             :   // Must be set in the constructor. Must not be null unless finished.
     272             :   RefPtr<AudioNodeStream> mStream;
     273             : 
     274             : private:
     275             :   // For every InputNode, there is a corresponding entry in mOutputNodes of the
     276             :   // InputNode's mInputNode.
     277             :   nsTArray<InputNode> mInputNodes;
     278             :   // For every mOutputNode entry, there is a corresponding entry in mInputNodes
     279             :   // of the mOutputNode entry. We won't necessarily be able to identify the
     280             :   // exact matching entry, since mOutputNodes doesn't include the port
     281             :   // identifiers and the same node could be connected on multiple ports.
     282             :   nsTArray<RefPtr<AudioNode> > mOutputNodes;
     283             :   // For every mOutputParams entry, there is a corresponding entry in
     284             :   // AudioParam::mInputNodes of the mOutputParams entry. We won't necessarily be
     285             :   // able to identify the exact matching entry, since mOutputParams doesn't
     286             :   // include the port identifiers and the same node could be connected on
     287             :   // multiple ports.
     288             :   nsTArray<RefPtr<AudioParam> > mOutputParams;
     289             :   uint32_t mChannelCount;
     290             :   ChannelCountMode mChannelCountMode;
     291             :   ChannelInterpretation mChannelInterpretation;
     292             :   const uint32_t mId;
     293             :   // Whether the node just passes through its input.  This is a devtools API that
     294             :   // only works for some node types.
     295             :   bool mPassThrough;
     296             :   // DocGroup-specifc AbstractThread::MainThread() for MediaStreamGraph operations.
     297             :   const RefPtr<AbstractThread> mAbstractMainThread;
     298             : };
     299             : 
     300             : } // namespace dom
     301             : } // namespace mozilla
     302             : 
     303             : #endif

Generated by: LCOV version 1.13