Bug 884365: Add method to return the amount of buffered data on a SourceMediaStream r=roc
authorRandell Jesup <rjesup@jesup.org>
Sat, 24 Aug 2013 09:53:01 -0400
changeset 144236 b962e46a293b43fb2b0b95e6ffacac94608cc7bf
parent 144235 6f47042e62d8503e2bc36252e9faac9da67179e3
child 144237 c55a56be94f24d5216c462b1a20c5b42f9ca7962
push id25153
push userphilringnalda@gmail.com
push dateSun, 25 Aug 2013 15:20:47 +0000
treeherdermozilla-central@133348d717a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs884365
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 884365: Add method to return the amount of buffered data on a SourceMediaStream r=roc
content/media/MediaStreamGraph.cpp
content/media/MediaStreamGraph.h
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -1979,16 +1979,22 @@ bool
 SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment)
 {
   MutexAutoLock lock(mMutex);
   // ::EndAllTrackAndFinished() can end these before the sources notice
   bool appended = false;
   if (!mFinished) {
     TrackData *track = FindDataForTrack(aID);
     if (track) {
+      // Data goes into mData, and on the next iteration of the MSG moves
+      // into the track's segment after NotifyQueuedTrackChanges().  This adds
+      // 0-10ms of delay before data gets to direct listeners.
+      // Indirect listeners (via subsequent TrackUnion nodes) are synced to
+      // playout time, and so can be delayed by buffering.
+
       track->mData->AppendFrom(aSegment);
       appended = true;
     } else {
       aSegment->Clear();
     }
   }
   if (!mDestroyed) {
     GraphImpl()->EnsureNextIteration();
@@ -2068,16 +2074,31 @@ SourceMediaStream::EndAllTrackAndFinish(
   for (uint32_t i = 0; i < mUpdateTracks.Length(); ++i) {
     SourceMediaStream::TrackData* data = &mUpdateTracks[i];
     data->mCommands |= TRACK_END;
   }
   FinishWithLockHeld();
   // we will call NotifyFinished() to let GetUserMedia know
 }
 
+TrackTicks
+SourceMediaStream::GetBufferedTicks(TrackID aID)
+{
+  StreamBuffer::Track* track  = mBuffer.FindTrack(aID);
+  if (track) {
+    MediaSegment* segment = track->GetSegment();
+    if (segment) {
+      return segment->GetDuration() -
+        track->TimeToTicksRoundDown(
+          GraphTimeToStreamTime(GraphImpl()->mStateComputedTime));
+    }
+  }
+  return 0;
+}
+
 void
 MediaInputPort::Init()
 {
   LOG(PR_LOG_DEBUG, ("Adding MediaInputPort %p (from %p to %p) to the graph",
       this, mSource, mDest));
   mSource->AddConsumer(this);
   mDest->AddInput(this);
   // mPortCount decremented via MediaInputPort::Destroy's message
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -653,16 +653,27 @@ public:
 
 
   /**
    * End all tracks and Finish() this stream.  Used to voluntarily revoke access
    * to a LocalMediaStream.
    */
   void EndAllTrackAndFinish();
 
+  /**
+   * Note: Only call from Media Graph thread (eg NotifyPull)
+   *
+   * Returns amount of time (data) that is currently buffered in the track,
+   * assuming playout via PlayAudio or via a TrackUnion - note that
+   * NotifyQueuedTrackChanges() on a SourceMediaStream will occur without
+   * any "extra" buffering, but NotifyQueued TrackChanges() on a TrackUnion
+   * will be buffered.
+   */
+  TrackTicks GetBufferedTicks(TrackID aID);
+
   // XXX need a Reset API
 
   friend class MediaStreamGraphImpl;
 
   struct ThreadAndRunnable {
     void Init(nsIThread* aThread, nsIRunnable* aRunnable)
     {
       mThread = aThread;