Add support for bi-directional simulations by having both an uplink and a downlink.

Partially make PacketReceiver a source which should be possible to hook up to the network.

Require that flow ids are set in all constructors.

BUG=4173
R=pbos@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/36059004

Cr-Commit-Position: refs/heads/master@{#8367}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8367 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
index 4550c91..7ba9437 100644
--- a/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
+++ b/webrtc/modules/remote_bitrate_estimator/bwe_simulations.cc
@@ -42,11 +42,11 @@
 TEST_P(BweSimulation, SprintUplinkTest) {
   VerboseLogging(true);
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacketSender sender(&uplink_, &source, GetParam());
+  RateCounterFilter counter1(&uplink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
+  RateCounterFilter counter2(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   ASSERT_TRUE(filter.Init(test::ResourcePath("sprint-uplink", "rx")));
   RunFor(60 * 1000);
 }
@@ -54,38 +54,53 @@
 TEST_P(BweSimulation, Verizon4gDownlinkTest) {
   VerboseLogging(true);
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacketSender sender(&downlink_, &source, GetParam());
+  RateCounterFilter counter1(&downlink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&downlink_, 0, "link_capacity");
+  RateCounterFilter counter2(&downlink_, 0, "receiver_input");
+  PacketReceiver receiver(&downlink_, 0, GetParam(), true, true);
   ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
   RunFor(22 * 60 * 1000);
 }
 
 TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
   VerboseLogging(true);
-  AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
-  filter.SetCapacity(1000);
-  filter.SetMaxDelay(500);
+
+  const int kFlowIds[] = {0, 1};
+  const size_t kNumFlows = sizeof(kFlowIds) / sizeof(kFlowIds[0]);
+
+  AdaptiveVideoSource source(kFlowIds[0], 30, 300, 0, 0);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter choke(&uplink_, kFlowIds[0]);
+  RateCounterFilter counter(&uplink_, kFlowIds[0], "receiver_input_0");
+  PacketReceiver receiver(&uplink_, kFlowIds[0], GetParam(), true, false);
+
+  AdaptiveVideoSource source2(kFlowIds[1], 30, 300, 0, 0);
+  PacketSender sender2(&downlink_, &source2, GetParam());
+  ChokeFilter choke2(&downlink_, kFlowIds[1]);
+  DelayFilter delay(&downlink_, CreateFlowIds(kFlowIds, kNumFlows));
+  RateCounterFilter counter2(&downlink_, kFlowIds[1], "receiver_input_1");
+  PacketReceiver receiver2(&downlink_, kFlowIds[1], GetParam(), true, false);
+
+  choke2.SetCapacity(500);
+  delay.SetDelay(0);
+
+  choke.SetCapacity(1000);
+  choke.SetMaxDelay(500);
   RunFor(60 * 1000);
-  filter.SetCapacity(500);
+  choke.SetCapacity(500);
   RunFor(60 * 1000);
-  filter.SetCapacity(1000);
+  choke.SetCapacity(1000);
   RunFor(60 * 1000);
 }
 
 TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
   VerboseLogging(true);
   PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
-  PacedVideoSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacedVideoSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   filter.SetCapacity(1000);
   filter.SetMaxDelay(500);
   RunFor(60 * 1000);
@@ -98,10 +113,10 @@
 TEST_P(BweSimulation, PacerChoke10000kbps) {
   VerboseLogging(true);
   PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
-  PacedVideoSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacedVideoSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   filter.SetCapacity(10000);
   filter.SetMaxDelay(500);
   RunFor(60 * 1000);
@@ -110,10 +125,10 @@
 TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
   VerboseLogging(true);
   PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
-  PacedVideoSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacedVideoSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   filter.SetCapacity(200);
   filter.SetMaxDelay(500);
   RunFor(60 * 1000);
@@ -126,10 +141,10 @@
 TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
   VerboseLogging(true);
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   filter.SetCapacity(200);
   filter.SetMaxDelay(500);
   RunFor(60 * 1000);
@@ -142,12 +157,12 @@
 TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
   VerboseLogging(true);
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, kRembEstimator);
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
+  PacketSender sender(&uplink_, &source, kRembEstimator);
+  RateCounterFilter counter1(&uplink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
   filter.SetMaxDelay(500);
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  RateCounterFilter counter2(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
   RunFor(300 * 1000);
 }
@@ -155,12 +170,12 @@
 TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) {
   VerboseLogging(true);
   PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
-  PacedVideoSender sender(this, &source, kRembEstimator);
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
+  PacedVideoSender sender(&uplink_, &source, kRembEstimator);
+  RateCounterFilter counter1(&uplink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
   filter.SetMaxDelay(500);
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), true, true);
+  RateCounterFilter counter2(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), true, true);
   ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
   RunFor(300 * 1000);
 }
@@ -176,25 +191,25 @@
     // competing for the bandwidth.
     sources[i].reset(
         new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
-    senders[i].reset(new PacketSender(this, sources[i].get(), GetParam()));
+    senders[i].reset(new PacketSender(&uplink_, sources[i].get(), GetParam()));
   }
 
-  ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
+  ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
   choke.SetCapacity(1000);
 
   scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
   for (size_t i = 0; i < kNumFlows; ++i) {
     rate_counters[i].reset(new RateCounterFilter(
-        this, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
+        &uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
   }
 
   RateCounterFilter total_utilization(
-      this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
+      &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
 
   scoped_ptr<PacketReceiver> receivers[kNumFlows];
   for (size_t i = 0; i < kNumFlows; ++i) {
-    receivers[i].reset(
-        new PacketReceiver(this, kAllFlowIds[i], GetParam(), i == 0, false));
+    receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], GetParam(),
+                                          i == 0, false));
   }
 
   RunFor(30 * 60 * 1000);
@@ -212,25 +227,26 @@
     // competing for the bandwidth.
     sources[i].reset(new PeriodicKeyFrameSource(kAllFlowIds[i], 30, 300, 0,
                                                 i * 20000, 1000));
-    senders[i].reset(new PacedVideoSender(this, sources[i].get(), GetParam()));
+    senders[i].reset(
+        new PacedVideoSender(&uplink_, sources[i].get(), GetParam()));
   }
 
-  ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
+  ChokeFilter choke(&uplink_, CreateFlowIds(kAllFlowIds, kNumFlows));
   choke.SetCapacity(1000);
 
   scoped_ptr<RateCounterFilter> rate_counters[kNumFlows];
   for (size_t i = 0; i < kNumFlows; ++i) {
     rate_counters[i].reset(new RateCounterFilter(
-        this, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
+        &uplink_, CreateFlowIds(&kAllFlowIds[i], 1), "receiver_input"));
   }
 
   RateCounterFilter total_utilization(
-      this, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
+      &uplink_, CreateFlowIds(kAllFlowIds, kNumFlows), "total_utilization");
 
   scoped_ptr<PacketReceiver> receivers[kNumFlows];
   for (size_t i = 0; i < kNumFlows; ++i) {
-    receivers[i].reset(
-        new PacketReceiver(this, kAllFlowIds[i], GetParam(), i == 0, false));
+    receivers[i].reset(new PacketReceiver(&uplink_, kAllFlowIds[i], GetParam(),
+                                          i == 0, false));
   }
 
   RunFor(30 * 60 * 1000);
diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
index 75046e7..b21d139 100644
--- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
+++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimators_test.cc
@@ -34,25 +34,25 @@
 
 TEST_P(DefaultBweTest, UnlimitedSpeed) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(10 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, SteadyLoss) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  LossFilter loss(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  LossFilter loss(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   loss.SetLoss(20.0);
   RunFor(10 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, IncreasingLoss1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  LossFilter loss(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  LossFilter loss(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   for (int i = 0; i < 76; ++i) {
     loss.SetLoss(i);
     RunFor(5000);
@@ -61,18 +61,18 @@
 
 TEST_P(DefaultBweTest, SteadyDelay) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  DelayFilter delay(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  DelayFilter delay(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   delay.SetDelay(1000);
   RunFor(10 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, IncreasingDelay1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  DelayFilter delay(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  DelayFilter delay(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(10 * 60 * 1000);
   for (int i = 0; i < 30 * 2; ++i) {
     delay.SetDelay(i);
@@ -83,10 +83,10 @@
 
 TEST_P(DefaultBweTest, IncreasingDelay2) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  DelayFilter delay(this);
-  RateCounterFilter counter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  DelayFilter delay(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(1 * 60 * 1000);
   for (int i = 1; i < 51; ++i) {
     delay.SetDelay(10.0f * i);
@@ -98,9 +98,9 @@
 
 TEST_P(DefaultBweTest, JumpyDelay1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  DelayFilter delay(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  DelayFilter delay(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(10 * 60 * 1000);
   for (int i = 1; i < 200; ++i) {
     delay.SetDelay((10 * i) % 500);
@@ -114,19 +114,19 @@
 
 TEST_P(DefaultBweTest, SteadyJitter) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  JitterFilter jitter(this);
-  RateCounterFilter counter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  JitterFilter jitter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   jitter.SetJitter(20);
   RunFor(2 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, IncreasingJitter1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  JitterFilter jitter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  JitterFilter jitter(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   for (int i = 0; i < 2 * 60 * 2; ++i) {
     jitter.SetJitter(i);
     RunFor(10 * 1000);
@@ -136,9 +136,9 @@
 
 TEST_P(DefaultBweTest, IncreasingJitter2) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  JitterFilter jitter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  JitterFilter jitter(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(30 * 1000);
   for (int i = 1; i < 51; ++i) {
     jitter.SetJitter(10.0f * i);
@@ -150,18 +150,18 @@
 
 TEST_P(DefaultBweTest, SteadyReorder) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ReorderFilter reorder(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ReorderFilter reorder(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   reorder.SetReorder(20.0);
   RunFor(10 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, IncreasingReorder1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ReorderFilter reorder(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ReorderFilter reorder(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   for (int i = 0; i < 76; ++i) {
     reorder.SetReorder(i);
     RunFor(5000);
@@ -170,18 +170,18 @@
 
 TEST_P(DefaultBweTest, SteadyChoke) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter choke(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter choke(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   choke.SetCapacity(140);
   RunFor(10 * 60 * 1000);
 }
 
 TEST_P(DefaultBweTest, IncreasingChoke1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter choke(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter choke(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   for (int i = 1200; i >= 100; i -= 100) {
     choke.SetCapacity(i);
     RunFor(5000);
@@ -190,9 +190,9 @@
 
 TEST_P(DefaultBweTest, IncreasingChoke2) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter choke(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter choke(&uplink_, 0);
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   RunFor(60 * 1000);
   for (int i = 1200; i >= 100; i -= 20) {
     choke.SetCapacity(i);
@@ -202,11 +202,11 @@
 
 TEST_P(DefaultBweTest, Multi1) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  DelayFilter delay(this);
-  ChokeFilter choke(this);
-  RateCounterFilter counter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  DelayFilter delay(&uplink_, 0);
+  ChokeFilter choke(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   choke.SetCapacity(1000);
   RunFor(1 * 60 * 1000);
   for (int i = 1; i < 51; ++i) {
@@ -220,11 +220,11 @@
 
 TEST_P(DefaultBweTest, Multi2) {
   VideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter choke(this);
-  JitterFilter jitter(this);
-  RateCounterFilter counter(this);
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter choke(&uplink_, 0);
+  JitterFilter jitter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   choke.SetCapacity(2000);
   jitter.SetJitter(120);
   RunFor(5 * 60 * 1000);
@@ -278,10 +278,10 @@
 
 TEST_P(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   const int kHighCapacityKbps = 1000;
   const int kLowCapacityKbps = 500;
   filter.SetCapacity(kHighCapacityKbps);
@@ -297,10 +297,10 @@
 
 TEST_P(BweFeedbackTest, Choke200kbps30kbps200kbps) {
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  ChokeFilter filter(this);
-  RateCounterFilter counter(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  ChokeFilter filter(&uplink_, 0);
+  RateCounterFilter counter(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   const int kHighCapacityKbps = 200;
   const int kLowCapacityKbps = 30;
   filter.SetCapacity(kHighCapacityKbps);
@@ -317,11 +317,11 @@
 
 TEST_P(BweFeedbackTest, Verizon4gDownlinkTest) {
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  PacketSender sender(&uplink_, &source, GetParam());
+  RateCounterFilter counter1(&uplink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
+  RateCounterFilter counter2(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   ASSERT_TRUE(filter.Init(test::ResourcePath("verizon4g-downlink", "rx")));
   RunFor(22 * 60 * 1000);
   PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
@@ -331,12 +331,12 @@
 // webrtc:3277
 TEST_P(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
   AdaptiveVideoSource source(0, 30, 300, 0, 0);
-  PacketSender sender(this, &source, GetParam());
-  RateCounterFilter counter1(this, "sender_output");
-  TraceBasedDeliveryFilter filter(this, "link_capacity");
+  PacketSender sender(&uplink_, &source, GetParam());
+  RateCounterFilter counter1(&uplink_, 0, "sender_output");
+  TraceBasedDeliveryFilter filter(&uplink_, 0, "link_capacity");
   filter.SetMaxDelay(500);
-  RateCounterFilter counter2(this, "receiver_input");
-  PacketReceiver receiver(this, 0, GetParam(), false, false);
+  RateCounterFilter counter2(&uplink_, 0, "receiver_input");
+  PacketReceiver receiver(&uplink_, 0, GetParam(), false, false);
   ASSERT_TRUE(filter.Init(test::ResourcePath("google-wifi-3mbps", "rx")));
   RunFor(300 * 1000);
   PrintResults(filter.GetBitrateStats().GetMean(), counter2.GetBitrateStats(),
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
index 951550a..8be2856 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc
@@ -33,7 +33,7 @@
   virtual void ReceivePacket(int64_t arrival_time_ms,
                              size_t payload_size,
                              const RTPHeader& header) {}
-  virtual FeedbackPacket* GetFeedback() { return NULL; }
+  virtual FeedbackPacket* GetFeedback(int64_t now_ms) { return NULL; }
 
  protected:
   int flow_id_;
@@ -50,7 +50,8 @@
 
 class SendSideBweReceiver : public BweReceiver {
  public:
-  explicit SendSideBweReceiver(int flow_id) : BweReceiver(flow_id) {}
+  explicit SendSideBweReceiver(int flow_id)
+      : BweReceiver(flow_id), last_feedback_ms_(0) {}
   virtual void ReceivePacket(int64_t arrival_time_ms,
                              size_t payload_size,
                              const RTPHeader& header) OVERRIDE {
@@ -59,14 +60,18 @@
         header.sequenceNumber, payload_size));
   }
 
-  virtual FeedbackPacket* GetFeedback() OVERRIDE {
-    FeedbackPacket* fb =
-        new SendSideBweFeedback(flow_id_, 0, packet_feedback_vector_);
+  virtual FeedbackPacket* GetFeedback(int64_t now_ms) OVERRIDE {
+    if (now_ms - last_feedback_ms_ < 100)
+      return NULL;
+    last_feedback_ms_ = now_ms;
+    FeedbackPacket* fb = new SendSideBweFeedback(flow_id_, now_ms * 1000,
+                                                 packet_feedback_vector_);
     packet_feedback_vector_.clear();
     return fb;
   }
 
  private:
+  int64_t last_feedback_ms_;
   std::vector<PacketInfo> packet_feedback_vector_;
 };
 
@@ -112,7 +117,7 @@
     ASSERT_TRUE(arrival_time_ms == clock_.TimeInMilliseconds());
   }
 
-  virtual FeedbackPacket* GetFeedback() {
+  virtual FeedbackPacket* GetFeedback(int64_t now_ms) OVERRIDE {
     BWE_TEST_LOGGING_CONTEXT("Remb");
     uint32_t estimated_bps = 0;
     RembFeedback* feedback = NULL;
@@ -122,8 +127,8 @@
       if (!statisticians.empty()) {
         report_block = BuildReportBlock(statisticians.begin()->second);
       }
-      feedback = new RembFeedback(flow_id_, clock_.TimeInMilliseconds(),
-                                  estimated_bps, report_block);
+      feedback = new RembFeedback(flow_id_, now_ms * 1000, estimated_bps,
+                                  report_block);
 
       double estimated_kbps = static_cast<double>(estimated_bps) / 1000.0;
       RTC_UNUSED(estimated_kbps);
@@ -135,9 +140,9 @@
     return feedback;
   }
 
+  // Implements RemoteBitrateObserver.
   virtual void OnReceiveBitrateChanged(const vector<unsigned int>& ssrcs,
-                                       unsigned int bitrate) {
-  }
+                                       unsigned int bitrate) OVERRIDE {}
 
  private:
   static RTCPReportBlock BuildReportBlock(StreamStatistician* statistician) {
@@ -210,29 +215,37 @@
 }
 
 void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
-  for (const auto* packet : *in_out) {
+  Packets feedback;
+  for (auto it = in_out->begin(); it != in_out->end();) {
     // PacketReceivers are only associated with a single stream, and therefore
     // should only process a single flow id.
     // TODO(holmer): Break this out into a Demuxer which implements both
     // PacketProcessorListener and PacketProcessor.
-    if (packet->flow_id() != *flow_ids().begin())
-      continue;
-    BWE_TEST_LOGGING_CONTEXT("Receiver");
-    assert(packet->GetPacketType() == Packet::kMedia);
-    const MediaPacket& media_packet = static_cast<const MediaPacket&>(*packet);
-    // We're treating the send time (from previous filter) as the arrival
-    // time once packet reaches the estimator.
-    int64_t arrival_time_ms = (media_packet.send_time_us() + 500) / 1000;
-    BWE_TEST_LOGGING_TIME(arrival_time_ms);
-    PlotDelay(arrival_time_ms, (media_packet.creation_time_us() + 500) / 1000);
+    if ((*it)->GetPacketType() == Packet::kMedia &&
+        (*it)->flow_id() == *flow_ids().begin()) {
+      BWE_TEST_LOGGING_CONTEXT("Receiver");
+      const MediaPacket* media_packet = static_cast<const MediaPacket*>(*it);
+      // We're treating the send time (from previous filter) as the arrival
+      // time once packet reaches the estimator.
+      int64_t arrival_time_ms = (media_packet->send_time_us() + 500) / 1000;
+      BWE_TEST_LOGGING_TIME(arrival_time_ms);
+      PlotDelay(arrival_time_ms,
+                (media_packet->creation_time_us() + 500) / 1000);
 
-    bwe_receiver_->ReceivePacket(arrival_time_ms, media_packet.payload_size(),
-                                 media_packet.header());
+      bwe_receiver_->ReceivePacket(arrival_time_ms,
+                                   media_packet->payload_size(),
+                                   media_packet->header());
+      FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms);
+      if (fb)
+        feedback.push_back(fb);
+      delete media_packet;
+      it = in_out->erase(it);
+    } else {
+      ++it;
+    }
   }
-}
-
-FeedbackPacket* PacketReceiver::GetFeedback() {
-  return bwe_receiver_->GetFeedback();
+  // Insert feedback packets to be sent back to the sender.
+  in_out->merge(feedback, DereferencingComparator<Packet>);
 }
 
 void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
@@ -256,7 +269,7 @@
       delete packet;
   }
 
-  bool HasProcessor(const PacketProcessor* processor) const {
+  bool RunsProcessor(const PacketProcessor* processor) const {
     return processor == processor_;
   }
 
@@ -312,9 +325,13 @@
 
 BweTest::BweTest()
     : run_time_ms_(0), time_now_ms_(-1), simulation_interval_ms_(-1) {
+  links_.push_back(&uplink_);
+  links_.push_back(&downlink_);
 }
 
 BweTest::~BweTest() {
+  for (Packet* packet : packets_)
+    delete packet;
 }
 
 void BweTest::SetUp() {
@@ -326,8 +343,8 @@
   BWE_TEST_LOGGING_GLOBAL_ENABLE(false);
 }
 
-void BweTest::AddPacketProcessor(PacketProcessor* processor,
-                                 ProcessorType processor_type) {
+void Link::AddPacketProcessor(PacketProcessor* processor,
+                              ProcessorType processor_type) {
   assert(processor);
   switch (processor_type) {
     case kSender:
@@ -342,10 +359,10 @@
   processors_.push_back(PacketProcessorRunner(processor));
 }
 
-void BweTest::RemovePacketProcessor(PacketProcessor* processor) {
+void Link::RemovePacketProcessor(PacketProcessor* processor) {
   for (vector<PacketProcessorRunner>::iterator it = processors_.begin();
        it != processors_.end(); ++it) {
-    if (it->HasProcessor(processor)) {
+    if (it->RunsProcessor(processor)) {
       processors_.erase(it);
       return;
     }
@@ -353,29 +370,24 @@
   assert(false);
 }
 
-void BweTest::VerboseLogging(bool enable) {
-  BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
+// Ownership of the created packets is handed over to the caller.
+void Link::Run(int64_t run_for_ms, int64_t now_ms, Packets* packets) {
+  for (auto& processor : processors_) {
+    processor.RunFor(run_for_ms, now_ms, packets);
+  }
 }
 
-void BweTest::GiveFeedbackToAffectedSenders(PacketReceiver* receiver) {
-  FeedbackPacket* feedback = receiver->GetFeedback();
-  if (feedback) {
-    for (PacketSender* sender : senders_) {
-      if (sender->flow_ids().find(feedback->flow_id()) !=
-          sender->flow_ids().end()) {
-        sender->GiveFeedback(*feedback);
-        break;
-      }
-    }
-  }
-  delete feedback;
+void BweTest::VerboseLogging(bool enable) {
+  BWE_TEST_LOGGING_GLOBAL_ENABLE(enable);
 }
 
 void BweTest::RunFor(int64_t time_ms) {
   // Set simulation interval from first packet sender.
   // TODO(holmer): Support different feedback intervals for different flows.
-  if (!senders_.empty()) {
-    simulation_interval_ms_ = senders_[0]->GetFeedbackIntervalMs();
+  if (!uplink_.senders().empty()) {
+    simulation_interval_ms_ = uplink_.senders()[0]->GetFeedbackIntervalMs();
+  } else if (!downlink_.senders().empty()) {
+    simulation_interval_ms_ = downlink_.senders()[0]->GetFeedbackIntervalMs();
   }
   assert(simulation_interval_ms_ > 0);
   if (time_now_ms_ == -1) {
@@ -384,32 +396,12 @@
   for (run_time_ms_ += time_ms;
        time_now_ms_ <= run_time_ms_ - simulation_interval_ms_;
        time_now_ms_ += simulation_interval_ms_) {
-    Packets packets;
-    for (PacketProcessorRunner& processor : processors_) {
-      processor.RunFor(simulation_interval_ms_, time_now_ms_, &packets);
-    }
-
-    // Verify packets are in order between batches.
-    if (!packets.empty()) {
-      if (!previous_packets_.empty()) {
-        packets.splice(packets.begin(), previous_packets_,
-                       --previous_packets_.end());
-        ASSERT_TRUE(IsTimeSorted(packets));
-        delete packets.front();
-        packets.erase(packets.begin());
-      }
-      ASSERT_LE(packets.front()->send_time_us(), time_now_ms_ * 1000);
-      ASSERT_LE(packets.back()->send_time_us(), time_now_ms_ * 1000);
-    } else {
-      ASSERT_TRUE(IsTimeSorted(packets));
-    }
-
-    for (const auto* packet : packets)
-      delete packet;
-
-    for (const auto& receiver : receivers_) {
-      GiveFeedbackToAffectedSenders(receiver);
-    }
+    // Packets are first generated on the first link, passed through all the
+    // PacketProcessors and PacketReceivers. The PacketReceivers produces
+    // FeedbackPackets which are then processed by the next link, where they
+    // at some point will be consumed by a PacketSender.
+    for (Link* link : links_)
+      link->Run(simulation_interval_ms_, time_now_ms_, &packets_);
   }
 }
 
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h
index 0ff4e5e..5cc5b30 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h
@@ -22,7 +22,6 @@
 namespace bwe {
 
 class BweReceiver;
-class PacketReceiver;
 class PacketProcessorRunner;
 
 class PacketReceiver : public PacketProcessor {
@@ -37,13 +36,12 @@
   // Implements PacketProcessor.
   virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
 
-  FeedbackPacket* GetFeedback();
-
   void LogStats();
 
  protected:
   void PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms);
 
+  int64_t now_ms_;
   std::string delay_log_prefix_;
   int64_t last_delay_plot_ms_;
   bool plot_delay_;
@@ -53,22 +51,38 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(PacketReceiver);
 };
 
-class BweTest : public PacketProcessorListener {
+class Link : public PacketProcessorListener {
  public:
-  BweTest();
-  virtual ~BweTest();
-
   virtual void AddPacketProcessor(PacketProcessor* processor,
                                   ProcessorType type);
   virtual void RemovePacketProcessor(PacketProcessor* processor);
 
+  void Run(int64_t run_for_ms, int64_t now_ms, Packets* packets);
+
+  const std::vector<PacketSender*>& senders() { return senders_; }
+  const std::vector<PacketProcessorRunner>& processors() { return processors_; }
+
+ private:
+  std::vector<PacketSender*> senders_;
+  std::vector<PacketReceiver*> receivers_;
+  std::vector<PacketProcessorRunner> processors_;
+};
+
+class BweTest {
+ public:
+  BweTest();
+  ~BweTest();
+
  protected:
-  virtual void SetUp();
+  void SetUp();
 
   void VerboseLogging(bool enable);
   void RunFor(int64_t time_ms);
   std::string GetTestName() const;
 
+  Link downlink_;
+  Link uplink_;
+
  private:
   void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in,
                             Packets* out);
@@ -77,10 +91,8 @@
   int64_t run_time_ms_;
   int64_t time_now_ms_;
   int64_t simulation_interval_ms_;
-  Packets previous_packets_;
-  std::vector<PacketSender*> senders_;
-  std::vector<PacketReceiver*> receivers_;
-  std::vector<PacketProcessorRunner> processors_;
+  std::vector<Link*> links_;
+  Packets packets_;
 
   DISALLOW_COPY_AND_ASSIGN(BweTest);
 };
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
index 1186aac..768ff93 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc
@@ -84,6 +84,7 @@
   uint32_t bits_per_second() const {
     return bytes_per_second_ * 8;
   }
+
   uint32_t packets_per_second() const { return packets_per_second_; }
 
  private:
@@ -198,15 +199,6 @@
 }
 
 PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
-                                 ProcessorType type)
-    : listener_(listener) {
-  flow_ids_.insert(0);
-  if (listener_) {
-    listener_->AddPacketProcessor(this, type);
-  }
-}
-
-PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
                                  int flow_id,
                                  ProcessorType type)
     : listener_(listener) {
@@ -231,17 +223,10 @@
   }
 }
 
-RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
-      rate_counter_(new RateCounter()),
-      packets_per_second_stats_(),
-      kbps_stats_(),
-      name_("") {
-}
-
 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
-                                     const std::string& name)
-    : PacketProcessor(listener, kRegular),
+                                     int flow_id,
+                                     const char* name)
+    : PacketProcessor(listener, flow_id, kRegular),
       rate_counter_(new RateCounter()),
       packets_per_second_stats_(),
       kbps_stats_(),
@@ -250,7 +235,7 @@
 
 RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
                                      const FlowIds& flow_ids,
-                                     const std::string& name)
+                                     const char* name)
     : PacketProcessor(listener, flow_ids, kRegular),
       rate_counter_(new RateCounter()),
       packets_per_second_stats_(),
@@ -301,8 +286,15 @@
   kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
 }
 
-LossFilter::LossFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
+LossFilter::LossFilter(PacketProcessorListener* listener, int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
+      random_(0x12345678),
+      loss_fraction_(0.0f) {
+}
+
+LossFilter::LossFilter(PacketProcessorListener* listener,
+                       const FlowIds& flow_ids)
+    : PacketProcessor(listener, flow_ids, kRegular),
       random_(0x12345678),
       loss_fraction_(0.0f) {
 }
@@ -327,8 +319,17 @@
   }
 }
 
-DelayFilter::DelayFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular), delay_us_(0), last_send_time_us_(0) {
+DelayFilter::DelayFilter(PacketProcessorListener* listener, int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
+      delay_us_(0),
+      last_send_time_us_(0) {
+}
+
+DelayFilter::DelayFilter(PacketProcessorListener* listener,
+                         const FlowIds& flow_ids)
+    : PacketProcessor(listener, flow_ids, kRegular),
+      delay_us_(0),
+      last_send_time_us_(0) {
 }
 
 void DelayFilter::SetDelay(int64_t delay_ms) {
@@ -347,8 +348,16 @@
   }
 }
 
-JitterFilter::JitterFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
+JitterFilter::JitterFilter(PacketProcessorListener* listener, int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
+      random_(0x89674523),
+      stddev_jitter_us_(0),
+      last_send_time_us_(0) {
+}
+
+JitterFilter::JitterFilter(PacketProcessorListener* listener,
+                           const FlowIds& flow_ids)
+    : PacketProcessor(listener, flow_ids, kRegular),
       random_(0x89674523),
       stddev_jitter_us_(0),
       last_send_time_us_(0) {
@@ -372,8 +381,15 @@
   }
 }
 
-ReorderFilter::ReorderFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
+ReorderFilter::ReorderFilter(PacketProcessorListener* listener, int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
+      random_(0x27452389),
+      reorder_fraction_(0.0f) {
+}
+
+ReorderFilter::ReorderFilter(PacketProcessorListener* listener,
+                             const FlowIds& flow_ids)
+    : PacketProcessor(listener, flow_ids, kRegular),
       random_(0x27452389),
       reorder_fraction_(0.0f) {
 }
@@ -404,8 +420,8 @@
   }
 }
 
-ChokeFilter::ChokeFilter(PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
+ChokeFilter::ChokeFilter(PacketProcessorListener* listener, int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
       kbps_(1200),
       last_send_time_us_(0),
       delay_cap_helper_(new DelayCapHelper()) {
@@ -456,8 +472,9 @@
 }
 
 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
-    PacketProcessorListener* listener)
-    : PacketProcessor(listener, kRegular),
+    PacketProcessorListener* listener,
+    int flow_id)
+    : PacketProcessor(listener, flow_id, kRegular),
       current_offset_us_(0),
       delivery_times_us_(),
       next_delivery_it_(),
@@ -471,8 +488,24 @@
 
 TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
     PacketProcessorListener* listener,
-    const std::string& name)
-    : PacketProcessor(listener, kRegular),
+    const FlowIds& flow_ids)
+    : PacketProcessor(listener, flow_ids, kRegular),
+      current_offset_us_(0),
+      delivery_times_us_(),
+      next_delivery_it_(),
+      local_time_us_(-1),
+      rate_counter_(new RateCounter),
+      name_(""),
+      delay_cap_helper_(new DelayCapHelper()),
+      packets_per_second_stats_(),
+      kbps_stats_() {
+}
+
+TraceBasedDeliveryFilter::TraceBasedDeliveryFilter(
+    PacketProcessorListener* listener,
+    int flow_id,
+    const char* name)
+    : PacketProcessor(listener, flow_id, kRegular),
       current_offset_us_(0),
       delivery_times_us_(),
       next_delivery_it_(),
@@ -584,12 +617,12 @@
                          int64_t first_frame_offset_ms)
     : kMaxPayloadSizeBytes(1200),
       kTimestampBase(0xff80ff00ul),
-      flow_id_(flow_id),
       frame_period_ms_(1000.0 / fps),
-      bytes_per_second_((1000 * kbps) / 8),
-      frame_size_bytes_(bytes_per_second_ / fps),
+      bits_per_second_(1000 * kbps),
+      frame_size_bytes_(bits_per_second_ / 8 / fps),
+      flow_id_(flow_id),
       next_frame_ms_(first_frame_offset_ms),
-      now_ms_(0.0),
+      now_ms_(0),
       prototype_header_() {
   memset(&prototype_header_, 0, sizeof(prototype_header_));
   prototype_header_.ssrc = ssrc;
@@ -646,8 +679,8 @@
 }
 
 void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) {
-  bytes_per_second_ = std::min(bitrate_bps / 8, 2500000 / 8);
-  frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
+  bits_per_second_ = std::min(bitrate_bps, 2500000);
+  frame_size_bytes_ = (bits_per_second_ / 8 * frame_period_ms_ + 500) / 1000;
 }
 
 PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id,
@@ -757,8 +790,6 @@
   if (fb.packet_feedback_vector().empty())
     return;
   rbe_->IncomingPacketFeedbackVector(fb.packet_feedback_vector());
-  if (rbe_->TimeUntilNextProcess() <= 0)
-    rbe_->Process();
   // TODO(holmer): Handle losses in between feedback packets.
   int expected_packets = fb.packet_feedback_vector().back().sequence_number -
                          fb.packet_feedback_vector().front().sequence_number +
@@ -817,7 +848,7 @@
       clock_(0),
       source_(source),
       bwe_(CreateEstimator(estimator,
-                           8 * source_->bytes_per_second() / 1000,
+                           source_->bits_per_second() / 1000,
                            this,
                            &clock_)) {
   modules_.push_back(bwe_.get());
@@ -827,22 +858,59 @@
 }
 
 void PacketSender::RunFor(int64_t time_ms, Packets* in_out) {
-  start_of_run_ms_ = clock_.TimeInMilliseconds();
-  while (time_ms > 0) {
-    int64_t time_to_run_ms = std::min(time_ms, static_cast<int64_t>(100));
-    source_->RunFor(time_to_run_ms, in_out);
+  int64_t now_ms = clock_.TimeInMilliseconds();
+  std::list<FeedbackPacket*> feedbacks =
+      GetFeedbackPackets(in_out, now_ms + time_ms);
+  ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out);
+}
+
+void PacketSender::ProcessFeedbackAndGeneratePackets(
+    int64_t time_ms,
+    std::list<FeedbackPacket*>* feedbacks,
+    Packets* generated) {
+  do {
+    // Make sure to at least run Process() below every 100 ms.
+    int64_t time_to_run_ms = std::min<int64_t>(time_ms, 100);
+    if (!feedbacks->empty()) {
+      int64_t time_until_feedback_ms =
+          feedbacks->front()->send_time_us() / 1000 -
+          clock_.TimeInMilliseconds();
+      time_to_run_ms =
+          std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0);
+    }
+    source_->RunFor(time_to_run_ms, generated);
     clock_.AdvanceTimeMilliseconds(time_to_run_ms);
+    if (!feedbacks->empty()) {
+      bwe_->GiveFeedback(*feedbacks->front());
+      delete feedbacks->front();
+      feedbacks->pop_front();
+    }
     bwe_->Process();
     time_ms -= time_to_run_ms;
-  }
+  } while (time_ms > 0);
+  assert(feedbacks->empty());
 }
 
 int PacketSender::GetFeedbackIntervalMs() const {
   return bwe_->GetFeedbackIntervalMs();
 }
 
-void PacketSender::GiveFeedback(const FeedbackPacket& feedback) {
-  bwe_->GiveFeedback(feedback);
+std::list<FeedbackPacket*> PacketSender::GetFeedbackPackets(
+    Packets* in_out,
+    int64_t end_time_ms) {
+  std::list<FeedbackPacket*> fb_packets;
+  for (auto it = in_out->begin(); it != in_out->end();) {
+    if ((*it)->send_time_us() > 1000 * end_time_ms)
+      break;
+    if ((*it)->GetPacketType() == Packet::kFeedback &&
+        source()->flow_id() == (*it)->flow_id()) {
+      fb_packets.push_back(static_cast<FeedbackPacket*>(*it));
+      it = in_out->erase(it);
+    } else {
+      ++it;
+    }
+  }
+  return fb_packets;
 }
 
 void PacketSender::OnNetworkChanged(uint32_t target_bitrate_bps,
@@ -861,9 +929,8 @@
     : PacketSender(listener, source, estimator),
       pacer_(&clock_,
              this,
-             8 * source->bytes_per_second() / 1000,
-             PacedSender::kDefaultPaceMultiplier * 8 *
-                 source->bytes_per_second() /
+             source->bits_per_second() / 1000,
+             PacedSender::kDefaultPaceMultiplier * source->bits_per_second() /
                  1000,
              0) {
   modules_.push_back(&pacer_);
@@ -877,47 +944,64 @@
 }
 
 void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
-  start_of_run_ms_ = clock_.TimeInMilliseconds();
-  Packets generated_packets;
-  source_->RunFor(time_ms, &generated_packets);
-  // Run process periodically to allow the packets to be paced out.
   int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms;
-  Packets::iterator it = generated_packets.begin();
-  while (clock_.TimeInMilliseconds() <= end_time_ms) {
+  // Run process periodically to allow the packets to be paced out.
+  std::list<FeedbackPacket*> feedbacks =
+      GetFeedbackPackets(in_out, end_time_ms);
+  int64_t last_run_time_ms = -1;
+  do {
     int64_t time_until_process_ms = TimeUntilNextProcess(modules_);
+    int64_t time_until_feedback_ms = time_ms;
+    if (!feedbacks.empty())
+      time_until_feedback_ms = feedbacks.front()->send_time_us() / 1000 -
+                               clock_.TimeInMilliseconds();
 
-    int time_until_packet_ms = time_ms;
-    if (it != generated_packets.end())
-      time_until_packet_ms =
-          ((*it)->send_time_us() + 500) / 1000 - clock_.TimeInMilliseconds();
-    assert(time_until_packet_ms >= 0);
+    int64_t time_until_next_event_ms =
+        std::min(time_until_feedback_ms, time_until_process_ms);
 
-    int time_until_next_event_ms = time_until_packet_ms;
-    if (time_until_process_ms < time_until_packet_ms) {
-      time_until_next_event_ms = time_until_process_ms;
+    time_until_next_event_ms =
+        std::min(source_->GetTimeUntilNextFrameMs(), time_until_next_event_ms);
+
+    // Never run for longer than we have been asked for.
+    if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms)
+      time_until_next_event_ms = end_time_ms - clock_.TimeInMilliseconds();
+
+    // Make sure we don't get stuck if an event doesn't trigger. This typically
+    // happens if the prober wants to probe, but there's no packet to send.
+    if (time_until_next_event_ms == 0 && last_run_time_ms == 0)
+      time_until_next_event_ms = 1;
+    last_run_time_ms = time_until_next_event_ms;
+
+    Packets generated_packets;
+    source_->RunFor(time_until_next_event_ms, &generated_packets);
+    if (!generated_packets.empty()) {
+      for (Packet* packet : generated_packets) {
+        MediaPacket* media_packet = static_cast<MediaPacket*>(packet);
+        pacer_.SendPacket(PacedSender::kNormalPriority,
+                          media_packet->header().ssrc,
+                          media_packet->header().sequenceNumber,
+                          (media_packet->send_time_us() + 500) / 1000,
+                          media_packet->payload_size(), false);
+        pacer_queue_.push_back(packet);
+        assert(pacer_queue_.size() < 10000);
+      }
     }
 
-    if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) {
-      clock_.AdvanceTimeMilliseconds(end_time_ms - clock_.TimeInMilliseconds());
-      break;
-    }
     clock_.AdvanceTimeMilliseconds(time_until_next_event_ms);
-    if (time_until_process_ms < time_until_packet_ms) {
-      // Time to process.
-      CallProcess(modules_);
-    } else {
-      // Time to send next packet to pacer.
-      MediaPacket* media_packet = static_cast<MediaPacket*>(*it);
-      pacer_.SendPacket(PacedSender::kNormalPriority,
-                        media_packet->header().ssrc,
-                        media_packet->header().sequenceNumber,
-                        (media_packet->send_time_us() + 500) / 1000,
-                        media_packet->payload_size(), false);
-      pacer_queue_.push_back(media_packet);
-      assert(pacer_queue_.size() < 10000);
-      ++it;
+
+    if (time_until_next_event_ms == time_until_feedback_ms) {
+      if (!feedbacks.empty()) {
+        bwe_->GiveFeedback(*feedbacks.front());
+        delete feedbacks.front();
+        feedbacks.pop_front();
+      }
+      bwe_->Process();
     }
-  }
+
+    if (time_until_next_event_ms == time_until_process_ms) {
+      CallProcess(modules_);
+    }
+  } while (clock_.TimeInMilliseconds() < end_time_ms);
   QueuePackets(in_out, end_time_ms * 1000);
 }
 
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
index 58ec06c..2543d6f 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h
@@ -46,6 +46,8 @@
 
 template <typename T>
 bool DereferencingComparator(const T* const& a, const T* const& b) {
+  assert(a != NULL);
+  assert(b != NULL);
   return *a < *b;
 }
 
@@ -265,7 +267,6 @@
 
 class PacketProcessor {
  public:
-  PacketProcessor(PacketProcessorListener* listener, ProcessorType type);
   PacketProcessor(PacketProcessorListener* listener,
                   int flow_id,
                   ProcessorType type);
@@ -294,12 +295,12 @@
 
 class RateCounterFilter : public PacketProcessor {
  public:
-  explicit RateCounterFilter(PacketProcessorListener* listener);
   RateCounterFilter(PacketProcessorListener* listener,
-                    const std::string& name);
+                    int flow_id,
+                    const char* name);
   RateCounterFilter(PacketProcessorListener* listener,
                     const FlowIds& flow_ids,
-                    const std::string& name);
+                    const char* name);
   virtual ~RateCounterFilter();
 
   uint32_t packets_per_second() const;
@@ -321,7 +322,8 @@
 
 class LossFilter : public PacketProcessor {
  public:
-  explicit LossFilter(PacketProcessorListener* listener);
+  LossFilter(PacketProcessorListener* listener, int flow_id);
+  LossFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
   virtual ~LossFilter() {}
 
   void SetLoss(float loss_percent);
@@ -336,7 +338,8 @@
 
 class DelayFilter : public PacketProcessor {
  public:
-  explicit DelayFilter(PacketProcessorListener* listener);
+  DelayFilter(PacketProcessorListener* listener, int flow_id);
+  DelayFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
   virtual ~DelayFilter() {}
 
   void SetDelay(int64_t delay_ms);
@@ -351,7 +354,8 @@
 
 class JitterFilter : public PacketProcessor {
  public:
-  explicit JitterFilter(PacketProcessorListener* listener);
+  JitterFilter(PacketProcessorListener* listener, int flow_id);
+  JitterFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
   virtual ~JitterFilter() {}
 
   void SetJitter(int64_t stddev_jitter_ms);
@@ -368,7 +372,8 @@
 // Reorders two consecutive packets with a probability of reorder_percent.
 class ReorderFilter : public PacketProcessor {
  public:
-  explicit ReorderFilter(PacketProcessorListener* listener);
+  ReorderFilter(PacketProcessorListener* listener, int flow_id);
+  ReorderFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
   virtual ~ReorderFilter() {}
 
   void SetReorder(float reorder_percent);
@@ -384,7 +389,7 @@
 // Apply a bitrate choke with an infinite queue on the packet stream.
 class ChokeFilter : public PacketProcessor {
  public:
-  explicit ChokeFilter(PacketProcessorListener* listener);
+  ChokeFilter(PacketProcessorListener* listener, int flow_id);
   ChokeFilter(PacketProcessorListener* listener, const FlowIds& flow_ids);
   virtual ~ChokeFilter();
 
@@ -404,9 +409,12 @@
 
 class TraceBasedDeliveryFilter : public PacketProcessor {
  public:
-  explicit TraceBasedDeliveryFilter(PacketProcessorListener* listener);
+  TraceBasedDeliveryFilter(PacketProcessorListener* listener, int flow_id);
   TraceBasedDeliveryFilter(PacketProcessorListener* listener,
-                           const std::string& name);
+                           const FlowIds& flow_ids);
+  TraceBasedDeliveryFilter(PacketProcessorListener* listener,
+                           int flow_id,
+                           const char* name);
   virtual ~TraceBasedDeliveryFilter();
 
   // The file should contain nanosecond timestamps corresponding to the time
@@ -446,12 +454,13 @@
               int64_t first_frame_offset_ms);
   virtual ~VideoSource() {}
 
-  uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
-  uint32_t bytes_per_second() const { return bytes_per_second_; }
-
   virtual void RunFor(int64_t time_ms, Packets* in_out);
-  virtual void SetBitrateBps(int bitrate_bps) {}
+
   virtual int flow_id() const { return flow_id_; }
+  virtual void SetBitrateBps(int bitrate_bps) {}
+  uint32_t bits_per_second() const { return bits_per_second_; }
+  uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
+  int64_t GetTimeUntilNextFrameMs() const { return next_frame_ms_ - now_ms_; }
 
  protected:
   virtual uint32_t NextFrameSize();
@@ -460,14 +469,14 @@
 
   const uint32_t kMaxPayloadSizeBytes;
   const uint32_t kTimestampBase;
-  const int flow_id_;
   const double frame_period_ms_;
-  uint32_t bytes_per_second_;
+  uint32_t bits_per_second_;
   uint32_t frame_size_bytes_;
 
  private:
-  double next_frame_ms_;
-  double now_ms_;
+  const int flow_id_;
+  int64_t next_frame_ms_;
+  int64_t now_ms_;
   RTPHeader prototype_header_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSource);
@@ -602,7 +611,6 @@
   // output of the estimators is sampled and therefore the baseline files may
   // have to be regenerated.
   virtual int GetFeedbackIntervalMs() const;
-  virtual void GiveFeedback(const FeedbackPacket& feedback);
   virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
 
   virtual VideoSource* source() const { return source_; }
@@ -613,6 +621,12 @@
                                 int64_t rtt) OVERRIDE;
 
  protected:
+  void ProcessFeedbackAndGeneratePackets(int64_t time_ms,
+                                         std::list<FeedbackPacket*>* feedbacks,
+                                         Packets* generated);
+  std::list<FeedbackPacket*> GetFeedbackPackets(Packets* in_out,
+                                                int64_t end_time_ms);
+
   SimulatedClock clock_;
   VideoSource* source_;
   scoped_ptr<SendSideBwe> bwe_;
diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc
index ac57054..ace2f5b 100644
--- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc
+++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework_unittest.cc
@@ -181,10 +181,7 @@
 
 class BweTestFramework_RateCounterFilterTest : public ::testing::Test {
  public:
-  BweTestFramework_RateCounterFilterTest()
-    : filter_(NULL),
-      now_ms_(0) {
-  }
+  BweTestFramework_RateCounterFilterTest() : filter_(NULL, 0, ""), now_ms_(0) {}
   virtual ~BweTestFramework_RateCounterFilterTest() {}
 
  protected:
@@ -244,7 +241,7 @@
 }
 
 static void TestLossFilter(float loss_percent, bool zero_tolerance) {
-  LossFilter filter(NULL);
+  LossFilter filter(NULL, 0);
   filter.SetLoss(loss_percent);
   Packets::size_type sent_packets = 0;
   Packets::size_type remaining_packets = 0;
@@ -308,10 +305,7 @@
 class BweTestFramework_DelayFilterTest : public ::testing::Test {
  public:
   BweTestFramework_DelayFilterTest()
-    : filter_(NULL),
-      now_ms_(0),
-      sequence_number_(0) {
-  }
+      : filter_(NULL, 0), now_ms_(0), sequence_number_(0) {}
   virtual ~BweTestFramework_DelayFilterTest() {
     for (auto* packet : accumulated_packets_)
       delete packet;
@@ -416,7 +410,7 @@
 }
 
 TEST_F(BweTestFramework_DelayFilterTest, JumpToZeroDelay) {
-  DelayFilter delay(NULL);
+  DelayFilter delay(NULL, 0);
   Packets acc;
   Packets packets;
 
@@ -464,7 +458,7 @@
 }
 
 static void TestJitterFilter(int64_t stddev_jitter_ms) {
-  JitterFilter filter(NULL);
+  JitterFilter filter(NULL, 0);
   filter.SetJitter(stddev_jitter_ms);
 
   int64_t now_ms = 0;
@@ -547,7 +541,7 @@
   ASSERT_TRUE(IsSequenceNumberSorted(packets));
 
   // Reorder packets, verify that send times are still in order.
-  ReorderFilter filter(NULL);
+  ReorderFilter filter(NULL, 0);
   filter.SetReorder(reorder_percent);
   filter.RunFor(now_ms, &packets);
   ASSERT_TRUE(IsTimeSorted(packets));
@@ -674,14 +668,14 @@
   // 100ms, 100 packets, 10 kbps choke -> 1 kbit of data should have propagated.
   // That is actually just a single packet, since each packet has 1000 bits of
   // payload.
-  ChokeFilter filter(NULL);
+  ChokeFilter filter(NULL, 0);
   filter.SetCapacity(10);
   TestChoke(&filter, 100, 100, 1);
 }
 
 TEST_F(BweTestFramework_ChokeFilterTest, Medium) {
   // 100ms, 10 packets, 10 kbps choke -> 1 packet through, or 1 kbit.
-  ChokeFilter filter(NULL);
+  ChokeFilter filter(NULL, 0);
   filter.SetCapacity(10);
   TestChoke(&filter, 100, 10, 1);
   // 200ms, no new packets -> another packet through.
@@ -694,7 +688,7 @@
 
 TEST_F(BweTestFramework_ChokeFilterTest, Long) {
   // 100ms, 100 packets in queue, 10 kbps choke -> 1 packet through, or 1 kbit.
-  ChokeFilter filter(NULL);
+  ChokeFilter filter(NULL, 0);
   filter.SetCapacity(10);
   TestChoke(&filter, 100, 100, 1);
   // 200ms, no input, another packet through.
@@ -716,7 +710,7 @@
 
 TEST_F(BweTestFramework_ChokeFilterTest, MaxDelay) {
   // 10 kbps choke, 500 ms delay cap
-  ChokeFilter filter(NULL);
+  ChokeFilter filter(NULL, 0);
   filter.SetCapacity(10);
   filter.SetMaxDelay(500);
   // 100ms, 100 packets in queue, 10 kbps choke -> 1 packet through, or 1 kbit.
@@ -745,7 +739,7 @@
 TEST_F(BweTestFramework_ChokeFilterTest, ShortTrace) {
   // According to the input file 6 packets should be transmitted within
   // 100 milliseconds.
-  TraceBasedDeliveryFilter filter(NULL);
+  TraceBasedDeliveryFilter filter(NULL, 0);
   ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx")));
   TestChoke(&filter, 100, 100, 6);
 }
@@ -753,13 +747,13 @@
 TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceTwoWraps) {
   // According to the input file 19 packets should be transmitted within
   // 280 milliseconds (at the wrapping point two packets are sent back to back).
-  TraceBasedDeliveryFilter filter(NULL);
+  TraceBasedDeliveryFilter filter(NULL, 0);
   ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx")));
   TestChoke(&filter, 280, 100, 19);
 }
 
 TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceMaxDelay) {
-  TraceBasedDeliveryFilter filter(NULL);
+  TraceBasedDeliveryFilter filter(NULL, 0);
   filter.SetMaxDelay(25);
   ASSERT_TRUE(filter.Init(test::ResourcePath("synthetic-trace", "rx")));
   // Uses all slots up to 110 ms. Several packets are being dropped.
@@ -818,7 +812,7 @@
   // 1 fps, 80 kbps
   VideoSource source(0, 1.0f, 80, 0x1234, 0);
   PacketSender sender(NULL, &source, kNullEstimator);
-  EXPECT_EQ(10000u, source.bytes_per_second());
+  EXPECT_EQ(80000u, source.bits_per_second());
   // We're at 1 fps, so all packets should be generated on first call, giving 10
   // packets of each 1000 bytes, total 10000 bytes.
   TestVideoSender(&sender, 1, 9, 400, 10000);
@@ -836,7 +830,7 @@
   // 1 fps, 80 kbps, offset 0.5 of a frame period, ==0.5s in this case.
   VideoSource source(0, 1.0f, 80, 0x1234, 500);
   PacketSender sender(NULL, &source, kNullEstimator);
-  EXPECT_EQ(10000u, source.bytes_per_second());
+  EXPECT_EQ(80000u, source.bits_per_second());
   // 499ms, no output.
   TestVideoSender(&sender, 499, 0, 0, 0);
   // 500ms, first frame (this is the offset we set), 10 packets of 1000 bytes.
@@ -857,7 +851,7 @@
   // 50 fps, 80 kbps.
   VideoSource source(0, 50.0f, 80, 0x1234, 0);
   PacketSender sender(NULL, &source, kNullEstimator);
-  EXPECT_EQ(10000u, source.bytes_per_second());
+  EXPECT_EQ(80000u, source.bits_per_second());
   // 9998ms, should see 500 frames, 200 byte payloads, total 100000 bytes.
   TestVideoSender(&sender, 9998, 500, 200, 100000);
   // 9999ms, nothing.
@@ -874,7 +868,7 @@
   // 20 fps, 120 kbps.
   VideoSource source(0, 20.0f, 120, 0x1234, 0);
   PacketSender sender(NULL, &source, kNullEstimator);
-  EXPECT_EQ(15000u, source.bytes_per_second());
+  EXPECT_EQ(120000u, source.bits_per_second());
   // 498ms, 10 frames with 750 byte payloads, total 7500 bytes.
   TestVideoSender(&sender, 498, 10, 750, 7500);
   // 499ms, nothing.
@@ -891,7 +885,7 @@
   // 20 fps, 820 kbps.
   VideoSource source(0, 25.0f, 820, 0x1234, 0);
   PacketSender sender(NULL, &source, kNullEstimator);
-  EXPECT_EQ(102500u, source.bytes_per_second());
+  EXPECT_EQ(820000u, source.bits_per_second());
   // 9998ms, 250 frames. 820 kbps = 102500 bytes/s, so total should be 1025000.
   // Each frame is 102500/25=4100 bytes, or 5 packets (4 @1000 bytes, 1 @100),
   // so packet count should be 5*250=1250 and last packet of each frame has
@@ -913,7 +907,7 @@
   // 1 fps, 80 kbps, 250ms offset.
   VideoSource source1(0, 1.0f, 80, 0x1234, 250);
   PacketSender sender1(NULL, &source1, kNullEstimator);
-  EXPECT_EQ(10000u, source1.bytes_per_second());
+  EXPECT_EQ(80000u, source1.bits_per_second());
   Packets packets;
   // Generate some packets, verify they are sorted.
   sender1.RunFor(999, &packets);
@@ -929,7 +923,7 @@
   // Another sender, 2 fps, 160 kbps, 150ms offset
   VideoSource source2(0, 2.0f, 160, 0x2234, 150);
   PacketSender sender2(NULL, &source2, kNullEstimator);
-  EXPECT_EQ(20000u, source2.bytes_per_second());
+  EXPECT_EQ(160000u, source2.bits_per_second());
   // Generate some packets, verify that they are merged with the packets already
   // on the list.
   sender2.RunFor(999, &packets);
@@ -948,35 +942,63 @@
   VideoSource source(0, 25.0f, 820, 0x1234, 0);
   PacketSender sender(NULL, &source, kNullEstimator);
 
-  EXPECT_EQ(102500u, source.bytes_per_second());
+  EXPECT_EQ(820000u, source.bits_per_second());
   TestVideoSender(&sender, 9998, 1000, 500, 1025000);
 
   // Make sure feedback has no effect on a regular video sender.
-  RembFeedback feedback(0, 0, 512000, RTCPReportBlock());
-  sender.GiveFeedback(feedback);
-  EXPECT_EQ(102500u, source.bytes_per_second());
+  RembFeedback* feedback = new RembFeedback(0, 0, 512000, RTCPReportBlock());
+  Packets packets;
+  packets.push_back(feedback);
+  sender.RunFor(0, &packets);
+  EXPECT_EQ(820000u, source.bits_per_second());
   TestVideoSender(&sender, 9998, 1000, 500, 1025000);
 }
 
 TEST(BweTestFramework_AdaptiveVideoSenderTest, FeedbackChangesBitrate) {
   AdaptiveVideoSource source(0, 25.0f, 820, 0x1234, 0);
   PacketSender sender(NULL, &source, kRembEstimator);
-  EXPECT_EQ(102500u, source.bytes_per_second());
+  EXPECT_EQ(820000u, source.bits_per_second());
   TestVideoSender(&sender, 9998, 1000, 500, 1025000);
 
   // Make sure we can reduce the bitrate.
-  RembFeedback feedback(0, 0, 512000, RTCPReportBlock());
-  sender.GiveFeedback(feedback);
-  EXPECT_EQ(64000u, source.bytes_per_second());
+  RembFeedback* feedback = new RembFeedback(0, 0, 512000, RTCPReportBlock());
+  Packets packets;
+  packets.push_back(feedback);
+  sender.RunFor(0, &packets);
+  EXPECT_EQ(512000u, source.bits_per_second());
   TestVideoSender(&sender, 9998, 750, 160, 640000);
 
   // Increase the bitrate to the initial bitrate and verify that the output is
   // the same.
-  RembFeedback feedback2(0, 0, 820000, RTCPReportBlock());
-  sender.GiveFeedback(feedback2);
-  Packets packets;
+  feedback = new RembFeedback(0, 0, 820000, RTCPReportBlock());
+  packets.push_back(feedback);
   sender.RunFor(10000, &packets);
-  EXPECT_EQ(102500u, source.bytes_per_second());
+  EXPECT_EQ(820000u, source.bits_per_second());
+
+  for (auto* packet : packets)
+    delete packet;
+}
+
+TEST(BweTestFramework_AdaptiveVideoSenderTest, Paced_FeedbackChangesBitrate) {
+  AdaptiveVideoSource source(0, 25.0f, 820, 0x1234, 0);
+  PacedVideoSender sender(NULL, &source, kRembEstimator);
+  EXPECT_EQ(820000u, source.bits_per_second());
+  TestVideoSender(&sender, 9998, 1000, 500, 1025000);
+
+  // Make sure we can reduce the bitrate.
+  RembFeedback* feedback = new RembFeedback(0, 1, 512000, RTCPReportBlock());
+  Packets packets;
+  packets.push_back(feedback);
+  sender.RunFor(10000, &packets);
+  ASSERT_EQ(512000u, source.bits_per_second());
+  TestVideoSender(&sender, 9998, 750, 160, 640000);
+
+  // Increase the bitrate to the initial bitrate and verify that the output is
+  // the same.
+  feedback = new RembFeedback(0, 0, 820000, RTCPReportBlock());
+  packets.push_back(feedback);
+  sender.RunFor(10000, &packets);
+  EXPECT_EQ(820000u, source.bits_per_second());
 
   for (auto* packet : packets)
     delete packet;