content/media/MediaStreamGraphImpl.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef MOZILLA_MEDIASTREAMGRAPHIMPL_H_
     7 #define MOZILLA_MEDIASTREAMGRAPHIMPL_H_
     9 #include "MediaStreamGraph.h"
    11 #include "mozilla/Monitor.h"
    12 #include "mozilla/TimeStamp.h"
    13 #include "nsIMemoryReporter.h"
    14 #include "nsIThread.h"
    15 #include "nsIRunnable.h"
    16 #include "Latency.h"
    17 #include "mozilla/WeakPtr.h"
    19 namespace mozilla {
    21 template <typename T>
    22 class LinkedList;
    24 class AudioMixer;
    26 /**
    27  * Assume we can run an iteration of the MediaStreamGraph loop in this much time
    28  * or less.
    29  * We try to run the control loop at this rate.
    30  */
    31 static const int MEDIA_GRAPH_TARGET_PERIOD_MS = 10;
    33 /**
    34  * Assume that we might miss our scheduled wakeup of the MediaStreamGraph by
    35  * this much.
    36  */
    37 static const int SCHEDULE_SAFETY_MARGIN_MS = 10;
    39 /**
    40  * Try have this much audio buffered in streams and queued to the hardware.
    41  * The maximum delay to the end of the next control loop
    42  * is 2*MEDIA_GRAPH_TARGET_PERIOD_MS + SCHEDULE_SAFETY_MARGIN_MS.
    43  * There is no point in buffering more audio than this in a stream at any
    44  * given time (until we add processing).
    45  * This is not optimal yet.
    46  */
    47 static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
    48     SCHEDULE_SAFETY_MARGIN_MS;
    50 /**
    51  * Try have this much video buffered. Video frames are set
    52  * near the end of the iteration of the control loop. The maximum delay
    53  * to the setting of the next video frame is 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
    54  * SCHEDULE_SAFETY_MARGIN_MS. This is not optimal yet.
    55  */
    56 static const int VIDEO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
    57     SCHEDULE_SAFETY_MARGIN_MS;
    59 /**
    60  * A per-stream update message passed from the media graph thread to the
    61  * main thread.
    62  */
    63 struct StreamUpdate {
    64   int64_t mGraphUpdateIndex;
    65   nsRefPtr<MediaStream> mStream;
    66   StreamTime mNextMainThreadCurrentTime;
    67   bool mNextMainThreadFinished;
    68 };
    70 /**
    71  * This represents a message passed from the main thread to the graph thread.
    72  * A ControlMessage always has a weak reference a particular affected stream.
    73  */
    74 class ControlMessage {
    75 public:
    76   explicit ControlMessage(MediaStream* aStream) : mStream(aStream)
    77   {
    78     MOZ_COUNT_CTOR(ControlMessage);
    79   }
    80   // All these run on the graph thread
    81   virtual ~ControlMessage()
    82   {
    83     MOZ_COUNT_DTOR(ControlMessage);
    84   }
    85   // Do the action of this message on the MediaStreamGraph thread. Any actions
    86   // affecting graph processing should take effect at mStateComputedTime.
    87   // All stream data for times < mStateComputedTime has already been
    88   // computed.
    89   virtual void Run() = 0;
    90   // When we're shutting down the application, most messages are ignored but
    91   // some cleanup messages should still be processed (on the main thread).
    92   // This must not add new control messages to the graph.
    93   virtual void RunDuringShutdown() {}
    94   MediaStream* GetStream() { return mStream; }
    96 protected:
    97   // We do not hold a reference to mStream. The graph will be holding
    98   // a reference to the stream until the Destroy message is processed. The
    99   // last message referencing a stream is the Destroy message for that stream.
   100   MediaStream* mStream;
   101 };
   103 /**
   104  * The implementation of a media stream graph. This class is private to this
   105  * file. It's not in the anonymous namespace because MediaStream needs to
   106  * be able to friend it.
   107  *
   108  * Currently we have one global instance per process, and one per each
   109  * OfflineAudioContext object.
   110  */
   111 class MediaStreamGraphImpl : public MediaStreamGraph,
   112                              public nsIMemoryReporter {
   113 public:
   114   NS_DECL_ISUPPORTS
   115   NS_DECL_NSIMEMORYREPORTER
   117   /**
   118    * Set aRealtime to true in order to create a MediaStreamGraph which provides
   119    * support for real-time audio and video.  Set it to false in order to create
   120    * a non-realtime instance which just churns through its inputs and produces
   121    * output.  Those objects currently only support audio, and are used to
   122    * implement OfflineAudioContext.  They do not support MediaStream inputs.
   123    */
   124   explicit MediaStreamGraphImpl(bool aRealtime, TrackRate aSampleRate);
   126   /**
   127    * Unregisters memory reporting and deletes this instance. This should be
   128    * called instead of calling the destructor directly.
   129    */
   130   void Destroy();
   132   // Main thread only.
   133   /**
   134    * This runs every time we need to sync state from the media graph thread
   135    * to the main thread while the main thread is not in the middle
   136    * of a script. It runs during a "stable state" (per HTML5) or during
   137    * an event posted to the main thread.
   138    */
   139   void RunInStableState();
   140   /**
   141    * Ensure a runnable to run RunInStableState is posted to the appshell to
   142    * run at the next stable state (per HTML5).
   143    * See EnsureStableStateEventPosted.
   144    */
   145   void EnsureRunInStableState();
   146   /**
   147    * Called to apply a StreamUpdate to its stream.
   148    */
   149   void ApplyStreamUpdate(StreamUpdate* aUpdate);
   150   /**
   151    * Append a ControlMessage to the message queue. This queue is drained
   152    * during RunInStableState; the messages will run on the graph thread.
   153    */
   154   void AppendMessage(ControlMessage* aMessage);
   155   /**
   156    * Make this MediaStreamGraph enter forced-shutdown state. This state
   157    * will be noticed by the media graph thread, which will shut down all streams
   158    * and other state controlled by the media graph thread.
   159    * This is called during application shutdown.
   160    */
   161   void ForceShutDown();
   162   /**
   163    * Shutdown() this MediaStreamGraph's threads and return when they've shut down.
   164    */
   165   void ShutdownThreads();
   167   /**
   168    * Called before the thread runs.
   169    */
   170   void Init();
   171   // The following methods run on the graph thread (or possibly the main thread if
   172   // mLifecycleState > LIFECYCLE_RUNNING)
   173   /**
   174    * Runs main control loop on the graph thread. Normally a single invocation
   175    * of this runs for the entire lifetime of the graph thread.
   176    */
   177   void RunThread();
   178   /**
   179    * Call this to indicate that another iteration of the control loop is
   180    * required on its regular schedule. The monitor must not be held.
   181    */
   182   void EnsureNextIteration();
   183   /**
   184    * As above, but with the monitor already held.
   185    */
   186   void EnsureNextIterationLocked(MonitorAutoLock& aLock);
   187   /**
   188    * Call this to indicate that another iteration of the control loop is
   189    * required immediately. The monitor must already be held.
   190    */
   191   void EnsureImmediateWakeUpLocked(MonitorAutoLock& aLock);
   192   /**
   193    * Ensure there is an event posted to the main thread to run RunInStableState.
   194    * mMonitor must be held.
   195    * See EnsureRunInStableState
   196    */
   197   void EnsureStableStateEventPosted();
   198   /**
   199    * Generate messages to the main thread to update it for all state changes.
   200    * mMonitor must be held.
   201    */
   202   void PrepareUpdatesToMainThreadState(bool aFinalUpdate);
   203   /**
   204    * Returns false if there is any stream that has finished but not yet finished
   205    * playing out.
   206    */
   207   bool AllFinishedStreamsNotified();
   208   /**
   209    * If we are rendering in non-realtime mode, we don't want to send messages to
   210    * the main thread at each iteration for performance reasons. We instead
   211    * notify the main thread at the same rate
   212    */
   213   bool ShouldUpdateMainThread();
   214   // The following methods are the various stages of RunThread processing.
   215   /**
   216    * Compute a new current time for the graph and advance all on-graph-thread
   217    * state to the new current time.
   218    */
   219   void UpdateCurrentTime();
   220   /**
   221    * Update the consumption state of aStream to reflect whether its data
   222    * is needed or not.
   223    */
   224   void UpdateConsumptionState(SourceMediaStream* aStream);
   225   /**
   226    * Extract any state updates pending in aStream, and apply them.
   227    */
   228   void ExtractPendingInput(SourceMediaStream* aStream,
   229                            GraphTime aDesiredUpToTime,
   230                            bool* aEnsureNextIteration);
   231   /**
   232    * Update "have enough data" flags in aStream.
   233    */
   234   void UpdateBufferSufficiencyState(SourceMediaStream* aStream);
   235   /*
   236    * If aStream hasn't already been ordered, push it onto aStack and order
   237    * its children.
   238    */
   239   void UpdateStreamOrderForStream(mozilla::LinkedList<MediaStream>* aStack,
   240                                   already_AddRefed<MediaStream> aStream);
   241   /**
   242    * Mark aStream and all its inputs (recursively) as consumed.
   243    */
   244   static void MarkConsumed(MediaStream* aStream);
   245   /**
   246    * Sort mStreams so that every stream not in a cycle is after any streams
   247    * it depends on, and every stream in a cycle is marked as being in a cycle.
   248    * Also sets mIsConsumed on every stream.
   249    */
   250   void UpdateStreamOrder();
   251   /**
   252    * Compute the blocking states of streams from mStateComputedTime
   253    * until the desired future time aEndBlockingDecisions.
   254    * Updates mStateComputedTime and sets MediaStream::mBlocked
   255    * for all streams.
   256    */
   257   void RecomputeBlocking(GraphTime aEndBlockingDecisions);
   258   // The following methods are used to help RecomputeBlocking.
   259   /**
   260    * If aStream isn't already in aStreams, add it and recursively call
   261    * AddBlockingRelatedStreamsToSet on all the streams whose blocking
   262    * status could depend on or affect the state of aStream.
   263    */
   264   void AddBlockingRelatedStreamsToSet(nsTArray<MediaStream*>* aStreams,
   265                                       MediaStream* aStream);
   266   /**
   267    * Mark a stream blocked at time aTime. If this results in decisions that need
   268    * to be revisited at some point in the future, *aEnd will be reduced to the
   269    * first time in the future to recompute those decisions.
   270    */
   271   void MarkStreamBlocking(MediaStream* aStream);
   272   /**
   273    * Recompute blocking for the streams in aStreams for the interval starting at aTime.
   274    * If this results in decisions that need to be revisited at some point
   275    * in the future, *aEnd will be reduced to the first time in the future to
   276    * recompute those decisions.
   277    */
   278   void RecomputeBlockingAt(const nsTArray<MediaStream*>& aStreams,
   279                            GraphTime aTime, GraphTime aEndBlockingDecisions,
   280                            GraphTime* aEnd);
   281   /**
   282    * Produce data for all streams >= aStreamIndex for the given time interval.
   283    * Advances block by block, each iteration producing data for all streams
   284    * for a single block.
   285    * This is called whenever we have an AudioNodeStream in the graph.
   286    */
   287   void ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
   288                                          TrackRate aSampleRate,
   289                                          GraphTime aFrom,
   290                                          GraphTime aTo);
   291   /**
   292    * Returns true if aStream will underrun at aTime for its own playback.
   293    * aEndBlockingDecisions is when we plan to stop making blocking decisions.
   294    * *aEnd will be reduced to the first time in the future to recompute these
   295    * decisions.
   296    */
   297   bool WillUnderrun(MediaStream* aStream, GraphTime aTime,
   298                     GraphTime aEndBlockingDecisions, GraphTime* aEnd);
   299   /**
   300    * Given a graph time aTime, convert it to a stream time taking into
   301    * account the time during which aStream is scheduled to be blocked.
   302    */
   303   StreamTime GraphTimeToStreamTime(MediaStream* aStream, GraphTime aTime);
   304   /**
   305    * Given a graph time aTime, convert it to a stream time taking into
   306    * account the time during which aStream is scheduled to be blocked, and
   307    * when we don't know whether it's blocked or not, we assume it's not blocked.
   308    */
   309   StreamTime GraphTimeToStreamTimeOptimistic(MediaStream* aStream, GraphTime aTime);
   310   enum {
   311     INCLUDE_TRAILING_BLOCKED_INTERVAL = 0x01
   312   };
   313   /**
   314    * Given a stream time aTime, convert it to a graph time taking into
   315    * account the time during which aStream is scheduled to be blocked.
   316    * aTime must be <= mStateComputedTime since blocking decisions
   317    * are only known up to that point.
   318    * If aTime is exactly at the start of a blocked interval, then the blocked
   319    * interval is included in the time returned if and only if
   320    * aFlags includes INCLUDE_TRAILING_BLOCKED_INTERVAL.
   321    */
   322   GraphTime StreamTimeToGraphTime(MediaStream* aStream, StreamTime aTime,
   323                                   uint32_t aFlags = 0);
   324   /**
   325    * Get the current audio position of the stream's audio output.
   326    */
   327   GraphTime GetAudioPosition(MediaStream* aStream);
   328   /**
   329    * Call NotifyHaveCurrentData on aStream's listeners.
   330    */
   331   void NotifyHasCurrentData(MediaStream* aStream);
   332   /**
   333    * If aStream needs an audio stream but doesn't have one, create it.
   334    * If aStream doesn't need an audio stream but has one, destroy it.
   335    */
   336   void CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTime,
   337                                    MediaStream* aStream);
   338   /**
   339    * Queue audio (mix of stream audio and silence for blocked intervals)
   340    * to the audio output stream. Returns the number of frames played.
   341    */
   342   TrackTicks PlayAudio(MediaStream* aStream, GraphTime aFrom, GraphTime aTo);
   343   /**
   344    * Set the correct current video frame for stream aStream.
   345    */
   346   void PlayVideo(MediaStream* aStream);
   347   /**
   348    * No more data will be forthcoming for aStream. The stream will end
   349    * at the current buffer end point. The StreamBuffer's tracks must be
   350    * explicitly set to finished by the caller.
   351    */
   352   void FinishStream(MediaStream* aStream);
   353   /**
   354    * Compute how much stream data we would like to buffer for aStream.
   355    */
   356   StreamTime GetDesiredBufferEnd(MediaStream* aStream);
   357   /**
   358    * Returns true when there are no active streams.
   359    */
   360   bool IsEmpty() { return mStreams.IsEmpty() && mPortCount == 0; }
   362   // For use by control messages, on graph thread only.
   363   /**
   364    * Identify which graph update index we are currently processing.
   365    */
   366   int64_t GetProcessingGraphUpdateIndex() { return mProcessingGraphUpdateIndex; }
   367   /**
   368    * Add aStream to the graph and initializes its graph-specific state.
   369    */
   370   void AddStream(MediaStream* aStream);
   371   /**
   372    * Remove aStream from the graph. Ensures that pending messages about the
   373    * stream back to the main thread are flushed.
   374    */
   375   void RemoveStream(MediaStream* aStream);
   376   /**
   377    * Remove aPort from the graph and release it.
   378    */
   379   void DestroyPort(MediaInputPort* aPort);
   380   /**
   381    * Mark the media stream order as dirty.
   382    */
   383   void SetStreamOrderDirty()
   384   {
   385     mStreamOrderDirty = true;
   386   }
   387   /**
   388    * Pause all AudioStreams being written to by MediaStreams
   389    */
   390   void PauseAllAudioOutputs();
   391   /**
   392    * Resume all AudioStreams being written to by MediaStreams
   393    */
   394   void ResumeAllAudioOutputs();
   396   TrackRate AudioSampleRate() { return mSampleRate; }
   398   // Data members
   400   /**
   401    * Media graph thread.
   402    * Readonly after initialization on the main thread.
   403    */
   404   nsCOMPtr<nsIThread> mThread;
   406   // The following state is managed on the graph thread only, unless
   407   // mLifecycleState > LIFECYCLE_RUNNING in which case the graph thread
   408   // is not running and this state can be used from the main thread.
   410   nsTArray<nsRefPtr<MediaStream> > mStreams;
   411   /**
   412    * mOldStreams is used as temporary storage for streams when computing the
   413    * order in which we compute them.
   414    */
   415   nsTArray<nsRefPtr<MediaStream> > mOldStreams;
   416   /**
   417    * The current graph time for the current iteration of the RunThread control
   418    * loop.
   419    */
   420   GraphTime mCurrentTime;
   421   /**
   422    * Blocking decisions and all stream contents have been computed up to this
   423    * time. The next batch of updates from the main thread will be processed
   424    * at this time. Always >= mCurrentTime.
   425    */
   426   GraphTime mStateComputedTime;
   427   /**
   428    * This is only used for logging.
   429    */
   430   TimeStamp mInitialTimeStamp;
   431   /**
   432    * The real timestamp of the latest run of UpdateCurrentTime.
   433    */
   434   TimeStamp mCurrentTimeStamp;
   435   /**
   436    * Date of the last time we updated the main thread with the graph state.
   437    */
   438   TimeStamp mLastMainThreadUpdate;
   439   /**
   440    * Which update batch we are currently processing.
   441    */
   442   int64_t mProcessingGraphUpdateIndex;
   443   /**
   444    * Number of active MediaInputPorts
   445    */
   446   int32_t mPortCount;
   448   // mMonitor guards the data below.
   449   // MediaStreamGraph normally does its work without holding mMonitor, so it is
   450   // not safe to just grab mMonitor from some thread and start monkeying with
   451   // the graph. Instead, communicate with the graph thread using provided
   452   // mechanisms such as the ControlMessage queue.
   453   Monitor mMonitor;
   455   // Data guarded by mMonitor (must always be accessed with mMonitor held,
   456   // regardless of the value of mLifecycleState.
   458   /**
   459    * State to copy to main thread
   460    */
   461   nsTArray<StreamUpdate> mStreamUpdates;
   462   /**
   463    * Runnables to run after the next update to main thread state.
   464    */
   465   nsTArray<nsCOMPtr<nsIRunnable> > mUpdateRunnables;
   466   struct MessageBlock {
   467     int64_t mGraphUpdateIndex;
   468     nsTArray<nsAutoPtr<ControlMessage> > mMessages;
   469   };
   470   /**
   471    * A list of batches of messages to process. Each batch is processed
   472    * as an atomic unit.
   473    */
   474   nsTArray<MessageBlock> mMessageQueue;
   475   /**
   476    * This enum specifies where this graph is in its lifecycle. This is used
   477    * to control shutdown.
   478    * Shutdown is tricky because it can happen in two different ways:
   479    * 1) Shutdown due to inactivity. RunThread() detects that it has no
   480    * pending messages and no streams, and exits. The next RunInStableState()
   481    * checks if there are new pending messages from the main thread (true only
   482    * if new stream creation raced with shutdown); if there are, it revives
   483    * RunThread(), otherwise it commits to shutting down the graph. New stream
   484    * creation after this point will create a new graph. An async event is
   485    * dispatched to Shutdown() the graph's threads and then delete the graph
   486    * object.
   487    * 2) Forced shutdown at application shutdown, or completion of a
   488    * non-realtime graph. A flag is set, RunThread() detects the flag and
   489    * exits, the next RunInStableState() detects the flag, and dispatches the
   490    * async event to Shutdown() the graph's threads. However the graph object
   491    * is not deleted. New messages for the graph are processed synchronously on
   492    * the main thread if necessary. When the last stream is destroyed, the
   493    * graph object is deleted.
   494    */
   495   enum LifecycleState {
   496     // The graph thread hasn't started yet.
   497     LIFECYCLE_THREAD_NOT_STARTED,
   498     // RunThread() is running normally.
   499     LIFECYCLE_RUNNING,
   500     // In the following states, the graph thread is not running so
   501     // all "graph thread only" state in this class can be used safely
   502     // on the main thread.
   503     // RunThread() has exited and we're waiting for the next
   504     // RunInStableState(), at which point we can clean up the main-thread
   505     // side of the graph.
   506     LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP,
   507     // RunInStableState() posted a ShutdownRunnable, and we're waiting for it
   508     // to shut down the graph thread(s).
   509     LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN,
   510     // Graph threads have shut down but we're waiting for remaining streams
   511     // to be destroyed. Only happens during application shutdown and on
   512     // completed non-realtime graphs, since normally we'd only shut down a
   513     // realtime graph when it has no streams.
   514     LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
   515   };
   516   LifecycleState mLifecycleState;
   517   /**
   518    * This enum specifies the wait state of the graph thread.
   519    */
   520   enum WaitState {
   521     // RunThread() is running normally
   522     WAITSTATE_RUNNING,
   523     // RunThread() is paused waiting for its next iteration, which will
   524     // happen soon
   525     WAITSTATE_WAITING_FOR_NEXT_ITERATION,
   526     // RunThread() is paused indefinitely waiting for something to change
   527     WAITSTATE_WAITING_INDEFINITELY,
   528     // Something has signaled RunThread() to wake up immediately,
   529     // but it hasn't done so yet
   530     WAITSTATE_WAKING_UP
   531   };
   532   WaitState mWaitState;
   533   /**
   534    * The graph should stop processing at or after this time.
   535    */
   536   GraphTime mEndTime;
   538   /**
   539    * Sample rate at which this graph runs. For real time graphs, this is
   540    * the rate of the audio mixer. For offline graphs, this is the rate specified
   541    * at construction.
   542    */
   543   TrackRate mSampleRate;
   544   /**
   545    * True when another iteration of the control loop is required.
   546    */
   547   bool mNeedAnotherIteration;
   548   /**
   549    * True when we need to do a forced shutdown during application shutdown.
   550    */
   551   bool mForceShutDown;
   552   /**
   553    * True when we have posted an event to the main thread to run
   554    * RunInStableState() and the event hasn't run yet.
   555    */
   556   bool mPostedRunInStableStateEvent;
   558   // Main thread only
   560   /**
   561    * Messages posted by the current event loop task. These are forwarded to
   562    * the media graph thread during RunInStableState. We can't forward them
   563    * immediately because we want all messages between stable states to be
   564    * processed as an atomic batch.
   565    */
   566   nsTArray<nsAutoPtr<ControlMessage> > mCurrentTaskMessageQueue;
   567   /**
   568    * True when RunInStableState has determined that mLifecycleState is >
   569    * LIFECYCLE_RUNNING. Since only the main thread can reset mLifecycleState to
   570    * LIFECYCLE_RUNNING, this can be relied on to not change unexpectedly.
   571    */
   572   bool mDetectedNotRunning;
   573   /**
   574    * True when a stable state runner has been posted to the appshell to run
   575    * RunInStableState at the next stable state.
   576    */
   577   bool mPostedRunInStableState;
   578   /**
   579    * True when processing real-time audio/video.  False when processing non-realtime
   580    * audio.
   581    */
   582   bool mRealtime;
   583   /**
   584    * True when a non-realtime MediaStreamGraph has started to process input.  This
   585    * value is only accessed on the main thread.
   586    */
   587   bool mNonRealtimeProcessing;
   588   /**
   589    * True when a change has happened which requires us to recompute the stream
   590    * blocking order.
   591    */
   592   bool mStreamOrderDirty;
   593   /**
   594    * Hold a ref to the Latency logger
   595    */
   596   nsRefPtr<AsyncLatencyLogger> mLatencyLog;
   597   /**
   598    * If this is not null, all the audio output for the MSG will be mixed down.
   599    */
   600   nsAutoPtr<AudioMixer> mMixer;
   602 private:
   603   virtual ~MediaStreamGraphImpl();
   605   MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
   607   /**
   608    * Used to signal that a memory report has been requested.
   609    */
   610   Monitor mMemoryReportMonitor;
   611   /**
   612    * This class uses manual memory management, and all pointers to it are raw
   613    * pointers. However, in order for it to implement nsIMemoryReporter, it needs
   614    * to implement nsISupports and so be ref-counted. So it maintains a single
   615    * nsRefPtr to itself, giving it a ref-count of 1 during its entire lifetime,
   616    * and Destroy() nulls this self-reference in order to trigger self-deletion.
   617    */
   618   nsRefPtr<MediaStreamGraphImpl> mSelfRef;
   619   /**
   620    * Used to pass memory report information across threads.
   621    */
   622   nsTArray<AudioNodeSizes> mAudioStreamSizes;
   623   /**
   624    * Indicates that the MSG thread should gather data for a memory report.
   625    */
   626   bool mNeedsMemoryReport;
   628 #ifdef DEBUG
   629   /**
   630    * Used to assert when AppendMessage() runs ControlMessages synchronously.
   631    */
   632   bool mCanRunMessagesSynchronously;
   633 #endif
   635 };
   637 }
   639 #endif /* MEDIASTREAMGRAPHIMPL_H_ */

mercurial