Bug 816664: wallpaper patch for negative delta times for video frames r=derf
☠☠ backed out by d2552e3d3ed6 ☠ ☠
authorRandell Jesup <rjesup@jesup.org>
Fri, 28 Dec 2012 15:34:01 -0500
changeset 126286 7d6255d1c54741db5e8b6a3138f8eda77c0f2524
parent 126285 a47d98073d4ebbde9ef59e33a57acf3ae331d72e
child 126287 515acd47156b3115e63f40e353c64adaeb40a7b5
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersderf
bugs816664
milestone20.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 816664: wallpaper patch for negative delta times for video frames r=derf
content/media/MediaSegment.h
content/media/webrtc/MediaEngineWebRTCAudio.cpp
content/media/webrtc/MediaEngineWebRTCVideo.cpp
--- a/content/media/MediaSegment.h
+++ b/content/media/MediaSegment.h
@@ -210,16 +210,17 @@ protected:
   MediaSegmentBase(Type aType) : MediaSegment(aType) {}
 
   /**
    * Appends the contents of aSource to this segment, clearing aSource.
    */
   void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
   {
     static_cast<C*>(this)->CheckCompatible(*static_cast<C*>(aSource));
+    MOZ_ASSERT(aSource->mDuration >= 0);
     mDuration += aSource->mDuration;
     aSource->mDuration = 0;
     if (!mChunks.IsEmpty() && !aSource->mChunks.IsEmpty() &&
         mChunks[mChunks.Length() - 1].CanCombineWithFollowing(aSource->mChunks[0])) {
       mChunks[mChunks.Length() - 1].mDuration += aSource->mChunks[0].mDuration;
       aSource->mChunks.RemoveElementAt(0);
     }
     mChunks.MoveElementsFrom(aSource->mChunks);
@@ -243,16 +244,17 @@ protected:
         mChunks.AppendElement(c)->SliceTo(start - offset, end - offset);
       }
       offset = nextOffset;
     }
   }
 
   Chunk* AppendChunk(TrackTicks aDuration)
   {
+    MOZ_ASSERT(aDuration >= 0);
     Chunk* c = mChunks.AppendElement();
     c->mDuration = aDuration;
     mDuration += aDuration;
     return c;
   }
 
   Chunk* FindChunkContaining(TrackTicks aOffset, TrackTicks* aStart = nullptr)
   {
--- a/content/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -141,17 +141,17 @@ void
 MediaEngineWebRTCAudioSource::NotifyPull(MediaStreamGraph* aGraph,
                                          StreamTime aDesiredTime)
 {
   // Ignore - we push audio data
 #ifdef DEBUG
   static TrackTicks mLastEndTime = 0;
   TrackTicks target = TimeToTicksRoundUp(SAMPLE_FREQUENCY, aDesiredTime);
   TrackTicks delta = target - mLastEndTime;
-  LOG(("Audio:NotifyPull: target %lu, delta %lu",(uint32_t) target, (uint32_t) delta));
+  LOG(("Audio: NotifyPull: aDesiredTime %ld, target %ld, delta %ld",(int64_t) aDesiredTime, (int64_t) target, (int64_t) delta));
   mLastEndTime = target;
 #endif
 }
 
 nsresult
 MediaEngineWebRTCAudioSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
 {
    return NS_ERROR_NOT_IMPLEMENTED;
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -10,16 +10,17 @@
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaManagerLog();
 #define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 #else
 #define LOG(msg)
 #endif
+#define LOG_ALL_FRAMES 1
 
 /**
  * Webrtc video source.
  */
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
 
 // ViEExternalRenderer Callback.
 int
@@ -105,22 +106,26 @@ MediaEngineWebRTCVideoSource::NotifyPull
   if (mState != kStarted)
     return;
 
   // Note: we're not giving up mImage here
   nsRefPtr<layers::Image> image = mImage;
   TrackTicks target = TimeToTicksRoundUp(USECS_PER_S, aDesiredTime);
   TrackTicks delta = target - mLastEndTime;
 #ifdef LOG_ALL_FRAMES
-  LOG(("NotifyPull, target = %lu, delta = %lu", (uint64_t) target, (uint64_t) delta));
+  LOG(("NotifyPull, desired = %ld, target = %ld, delta = %ld", (int64_t) aDesiredTime, (int64_t) target, (int64_t) delta));
 #endif
-  // NULL images are allowed
-  segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
-  mSource->AppendToTrack(mTrackID, &(segment));
-  mLastEndTime = target;
+  // Don't append if we've already provided a frame that supposedly goes past the current aDesiredTime
+  // Doing so means a negative delta and thus messes up handling of the graph
+  if (delta > 0) {
+    // NULL images are allowed
+    segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
+    mSource->AppendToTrack(mTrackID, &(segment));
+    mLastEndTime = target;
+  }
 }
 
 void
 MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS)
 {
   int num = mViECapture->NumberOfCapabilities(mUniqueId, KMaxUniqueIdLength);
 
   NS_WARN_IF_FALSE(!mCapabilityChosen,"Shouldn't select capability of a device twice");