Bug 1323079 - Send disabled frames no more often than 1 FPS over WebRTC. r?jesup draft
authorAndreas Pehrson <pehrsons@gmail.com>
Wed, 28 Dec 2016 16:40:47 +0100
changeset 458430 15dd3a3008c30f6c265a40eba428a2d7fa29ce47
parent 454520 87efd66165ddaa1b97608b92cd651b73c11aca6f
child 541649 adcc4a60e22907e32f9d1f4998db01e69b1e3ef7
push id40957
push userbmo:pehrson@telenordigital.com
push dateTue, 10 Jan 2017 09:55:27 +0000
reviewersjesup
bugs1323079
milestone53.0a1
Bug 1323079 - Send disabled frames no more often than 1 FPS over WebRTC. r?jesup MozReview-Commit-ID: EoVLutIXkXV
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -114,17 +114,16 @@ protected:
 class VideoFrameConverter
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameConverter)
 
   VideoFrameConverter()
     : mLength(0)
     , last_img_(-1) // -1 is not a guaranteed invalid serial. See bug 1262134.
-    , disabled_frame_sent_(false)
 #ifdef DEBUG
     , mThrottleCount(0)
     , mThrottleRecord(0)
 #endif
     , mMutex("VideoFrameConverter")
   {
     MOZ_COUNT_CTOR(VideoFrameConverter);
 
@@ -178,27 +177,32 @@ public:
 
     bool forceBlack = aForceBlack || aChunk.mFrame.GetForceBlack();
 
     if (forceBlack) {
       // Reset the last-img check.
       // -1 is not a guaranteed invalid serial. See bug 1262134.
       last_img_ = -1;
 
-      if (disabled_frame_sent_) {
-        // After disabling we just pass one black frame to the encoder.
-        // Allocating and setting it to black steals some performance
-        // that can be avoided. We don't handle resolution changes while
-        // disabled for now.
+      // After disabling, we still want *some* frames to flow to the other side.
+      // It could happen that we drop the packet that carried the first disabled
+      // frame, for instance. Note that this still requires the application to
+      // send a frame, or it doesn't trigger at all.
+      const double disabledMinFps = 1.0;
+      TimeStamp t = aChunk.mTimeStamp;
+      MOZ_ASSERT(!t.IsNull());
+      if (!disabled_frame_sent_.IsNull() &&
+          (t - disabled_frame_sent_).ToSeconds() < (1.0 / disabledMinFps)) {
         return;
       }
 
-      disabled_frame_sent_ = true;
+      disabled_frame_sent_ = t;
     } else {
-      disabled_frame_sent_ = false;
+      // This sets it to the Null time.
+      disabled_frame_sent_ = TimeStamp();
     }
 
     ++mLength; // Atomic
 
     nsCOMPtr<nsIRunnable> runnable =
       NewRunnableMethod<StorensRefPtrPassByPtr<Image>, bool>(
         this, &VideoFrameConverter::ProcessVideoFrame,
         aChunk.mFrame.GetImage(), forceBlack);
@@ -447,17 +451,17 @@ protected:
     VideoFrameConverted(yuv, buffer_size, size.width, size.height, mozilla::kVideoI420, 0);
   }
 
   Atomic<int32_t, Relaxed> mLength;
   RefPtr<TaskQueue> mTaskQueue;
 
   // Written and read from the queueing thread (normally MSG).
   int32_t last_img_; // serial number of last Image
-  bool disabled_frame_sent_; // If a black frame has been sent after disabling.
+  TimeStamp disabled_frame_sent_; // The time we sent the last disabled frame.
 #ifdef DEBUG
   uint32_t mThrottleCount;
   uint32_t mThrottleRecord;
 #endif
 
   // mMutex guards the below variables.
   Mutex mMutex;
   nsTArray<RefPtr<VideoConverterListener>> mListeners;