114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org/*
214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *
414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  Use of this source code is governed by a BSD-style license
514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  that can be found in the LICENSE file in the root of the source
614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  tree. An additional intellectual property rights grant can be found
714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  in the file PATENTS.  All contributing project authors may
814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org */
1014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
1114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/packet_sender.h"
1214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
1314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org#include <algorithm>
1414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org#include <list>
1514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org#include <sstream>
1614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
17379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer#include "webrtc/base/checks.h"
18ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/include/module_common_types.h"
1914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
202386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes#include "webrtc/modules/remote_bitrate_estimator/test/metric_recorder.h"
2114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
2214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgnamespace webrtc {
2314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgnamespace testing {
2414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgnamespace bwe {
2514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
262386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid PacketSender::Pause() {
272386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  running_ = false;
282386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  if (metric_recorder_ != nullptr) {
292386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    metric_recorder_->PauseFlow();
302386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  }
312386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
322386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
332386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid PacketSender::Resume(int64_t paused_time_ms) {
342386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  running_ = true;
352386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  if (metric_recorder_ != nullptr) {
362386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    metric_recorder_->ResumeFlow(paused_time_ms);
372386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  }
382386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
392386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
402386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid PacketSender::set_metric_recorder(MetricRecorder* metric_recorder) {
412386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  metric_recorder_ = metric_recorder;
422386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
432386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
442386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid PacketSender::RecordBitrate() {
452386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  if (metric_recorder_ != nullptr) {
462386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    BWE_TEST_LOGGING_CONTEXT("Sender");
472386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin());
482386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    metric_recorder_->UpdateTimeMs(clock_.TimeInMilliseconds());
492386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    metric_recorder_->UpdateSendingEstimateKbps(TargetBitrateKbps());
502386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  }
512386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
522386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
53379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmerstd::list<FeedbackPacket*> GetFeedbackPackets(Packets* in_out,
54379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                                              int64_t end_time_ms,
55379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                                              int flow_id) {
56379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  std::list<FeedbackPacket*> fb_packets;
57379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  for (auto it = in_out->begin(); it != in_out->end();) {
58379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    if ((*it)->send_time_us() > 1000 * end_time_ms)
59379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      break;
60379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    if ((*it)->GetPacketType() == Packet::kFeedback &&
61379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer        flow_id == (*it)->flow_id()) {
62379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      fb_packets.push_back(static_cast<FeedbackPacket*>(*it));
63379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      it = in_out->erase(it);
64379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    } else {
65379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      ++it;
66379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    }
67379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  }
68379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  return fb_packets;
69379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer}
70379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
71379593792082a86f389df9b1b790cc0fe9eb9975Stefan HolmerVideoSender::VideoSender(PacketProcessorListener* listener,
72379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                         VideoSource* source,
73379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                         BandwidthEstimatorType estimator_type)
74379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    : PacketSender(listener, source->flow_id()),
7514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      source_(source),
764346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org      bwe_(CreateBweSender(estimator_type,
7714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                           source_->bits_per_second() / 1000,
7814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                           this,
799c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           &clock_)),
809c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      previous_sending_bitrate_(0) {
8114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  modules_.push_back(bwe_.get());
8214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
8314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
84379593792082a86f389df9b1b790cc0fe9eb9975Stefan HolmerVideoSender::~VideoSender() {
8514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
8614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
872386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid VideoSender::Pause() {
882386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  previous_sending_bitrate_ = TargetBitrateKbps();
892386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  PacketSender::Pause();
902386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
912386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
922386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaesvoid VideoSender::Resume(int64_t paused_time_ms) {
932386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  source_->SetBitrateBps(previous_sending_bitrate_);
942386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  PacketSender::Resume(paused_time_ms);
952386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes}
962386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
97379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
98c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets(
99c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes      in_out, clock_.TimeInMilliseconds() + time_ms, source_->flow_id());
10014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out);
10114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
10214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
103379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid VideoSender::ProcessFeedbackAndGeneratePackets(
10414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t time_ms,
10514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    std::list<FeedbackPacket*>* feedbacks,
1064346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    Packets* packets) {
10714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  do {
10814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    // Make sure to at least run Process() below every 100 ms.
10914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t time_to_run_ms = std::min<int64_t>(time_ms, 100);
11014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (!feedbacks->empty()) {
11114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      int64_t time_until_feedback_ms =
1129c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes          feedbacks->front()->send_time_ms() - clock_.TimeInMilliseconds();
11314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      time_to_run_ms =
11414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org          std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0);
11514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
1169c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1179c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    if (!running_) {
1189c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      source_->SetBitrateBps(0);
1199c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    }
1209c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1214346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    Packets generated;
1224346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    source_->RunFor(time_to_run_ms, &generated);
1234346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    bwe_->OnPacketsSent(generated);
1244346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org    packets->merge(generated, DereferencingComparator<Packet>);
1259c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
12614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    clock_.AdvanceTimeMilliseconds(time_to_run_ms);
1279c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
12814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (!feedbacks->empty()) {
12914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      bwe_->GiveFeedback(*feedbacks->front());
13014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      delete feedbacks->front();
13114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      feedbacks->pop_front();
13214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
1339c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
13414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    bwe_->Process();
1359c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
13614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    time_ms -= time_to_run_ms;
13714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  } while (time_ms > 0);
13814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  assert(feedbacks->empty());
13914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
14014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
141379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmerint VideoSender::GetFeedbackIntervalMs() const {
14214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  return bwe_->GetFeedbackIntervalMs();
14314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
14414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
145379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
146379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                                   uint8_t fraction_lost,
147379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer                                   int64_t rtt) {
14814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  source_->SetBitrateBps(target_bitrate_bps);
1492386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  RecordBitrate();
1509c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1519c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1529c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesuint32_t VideoSender::TargetBitrateKbps() {
1539c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  return (source_->bits_per_second() + 500) / 1000;
1549c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1559c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
15614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgPacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
15714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                   VideoSource* source,
15814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                   BandwidthEstimatorType estimator)
159379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    : VideoSender(listener, source, estimator),
16014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      pacer_(&clock_,
16114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org             this,
16214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org             source->bits_per_second() / 1000,
16314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org             PacedSender::kDefaultPaceMultiplier * source->bits_per_second() /
16414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                 1000,
16514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org             0) {
16614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  modules_.push_back(&pacer_);
16714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
16814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
16914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgPacedVideoSender::~PacedVideoSender() {
17014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (Packet* packet : pacer_queue_)
17114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    delete packet;
17214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (Packet* packet : queue_)
17314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    delete packet;
17414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
17514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
17614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgvoid PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
17714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms;
17814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  // Run process periodically to allow the packets to be paced out.
17914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  std::list<FeedbackPacket*> feedbacks =
180379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      GetFeedbackPackets(in_out, end_time_ms, source_->flow_id());
18114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  int64_t last_run_time_ms = -1;
182dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer  BWE_TEST_LOGGING_CONTEXT("Sender");
183dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer  BWE_TEST_LOGGING_CONTEXT(source_->flow_id());
18414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  do {
18514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t time_until_process_ms = TimeUntilNextProcess(modules_);
18614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t time_until_feedback_ms = time_ms;
18714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (!feedbacks.empty())
1889c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      time_until_feedback_ms = std::max<int64_t>(
1899c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes          feedbacks.front()->send_time_ms() - clock_.TimeInMilliseconds(), 0);
19014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
19114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t time_until_next_event_ms =
19214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        std::min(time_until_feedback_ms, time_until_process_ms);
19314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
19414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    time_until_next_event_ms =
19514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        std::min(source_->GetTimeUntilNextFrameMs(), time_until_next_event_ms);
19614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
19714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    // Never run for longer than we have been asked for.
19814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms)
19914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      time_until_next_event_ms = end_time_ms - clock_.TimeInMilliseconds();
20014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
20114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    // Make sure we don't get stuck if an event doesn't trigger. This typically
20214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    // happens if the prober wants to probe, but there's no packet to send.
20314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (time_until_next_event_ms == 0 && last_run_time_ms == 0)
20414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      time_until_next_event_ms = 1;
20514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    last_run_time_ms = time_until_next_event_ms;
20614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
20714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    Packets generated_packets;
20814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    source_->RunFor(time_until_next_event_ms, &generated_packets);
20914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (!generated_packets.empty()) {
21014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      for (Packet* packet : generated_packets) {
21114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        MediaPacket* media_packet = static_cast<MediaPacket*>(packet);
212e23e737177cf5d131a6d4a4d229aa513c5270a59Peter Boström        pacer_.InsertPacket(
2139c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes            PacedSender::kNormalPriority, media_packet->header().ssrc,
2149c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes            media_packet->header().sequenceNumber, media_packet->send_time_ms(),
2159c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes            media_packet->payload_size(), false);
21614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        pacer_queue_.push_back(packet);
21714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        assert(pacer_queue_.size() < 10000);
21814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      }
21914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
22014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
22114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    clock_.AdvanceTimeMilliseconds(time_until_next_event_ms);
22214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
22314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (time_until_next_event_ms == time_until_feedback_ms) {
22414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      if (!feedbacks.empty()) {
22514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        bwe_->GiveFeedback(*feedbacks.front());
22614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        delete feedbacks.front();
22714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org        feedbacks.pop_front();
22814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      }
22914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      bwe_->Process();
23014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
23114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
23214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (time_until_next_event_ms == time_until_process_ms) {
23314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      CallProcess(modules_);
23414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
23514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  } while (clock_.TimeInMilliseconds() < end_time_ms);
23614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  QueuePackets(in_out, end_time_ms * 1000);
23714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
23814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
23914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgint64_t PacedVideoSender::TimeUntilNextProcess(
24014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    const std::list<Module*>& modules) {
24114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  int64_t time_until_next_process_ms = 10;
24214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (Module* module : modules) {
24314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    int64_t next_process_ms = module->TimeUntilNextProcess();
24414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (next_process_ms < time_until_next_process_ms)
24514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      time_until_next_process_ms = next_process_ms;
24614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  }
24714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  if (time_until_next_process_ms < 0)
24814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    time_until_next_process_ms = 0;
24914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  return time_until_next_process_ms;
25014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
25114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
25214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgvoid PacedVideoSender::CallProcess(const std::list<Module*>& modules) {
25314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (Module* module : modules) {
25414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (module->TimeUntilNextProcess() <= 0) {
25514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      module->Process();
25614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
25714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  }
25814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
25914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
26014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgvoid PacedVideoSender::QueuePackets(Packets* batch,
26114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                    int64_t end_of_batch_time_us) {
26214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  queue_.merge(*batch, DereferencingComparator<Packet>);
26314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  if (queue_.empty()) {
26414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    return;
26514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  }
26614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  Packets::iterator it = queue_.begin();
26714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (; it != queue_.end(); ++it) {
26814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if ((*it)->send_time_us() > end_of_batch_time_us) {
26914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      break;
27014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
27114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  }
27214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  Packets to_transfer;
27314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it);
274318673cf5a1b230d445a50fdc4869f4b8f99c85dsprang  for (Packet* packet : to_transfer)
275318673cf5a1b230d445a50fdc4869f4b8f99c85dsprang    packet->set_paced(true);
2764346d92578e5acbf3c40c89967c548e8f72e7543stefan@webrtc.org  bwe_->OnPacketsSent(to_transfer);
27714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  batch->merge(to_transfer, DereferencingComparator<Packet>);
27814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
27914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
28014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgbool PacedVideoSender::TimeToSendPacket(uint32_t ssrc,
28114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                        uint16_t sequence_number,
28214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                        int64_t capture_time_ms,
28314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                        bool retransmission) {
28414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end();
28514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org       ++it) {
28614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    MediaPacket* media_packet = static_cast<MediaPacket*>(*it);
28714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    if (media_packet->header().sequenceNumber == sequence_number) {
28814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      int64_t pace_out_time_ms = clock_.TimeInMilliseconds();
2899c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
29014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      // Make sure a packet is never paced out earlier than when it was put into
29114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      // the pacer.
2929c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      assert(pace_out_time_ms >= media_packet->send_time_ms());
2939c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
29414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      media_packet->SetAbsSendTimeMs(pace_out_time_ms);
29514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      media_packet->set_send_time_us(1000 * pace_out_time_ms);
2960908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer      media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms);
29714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      queue_.push_back(media_packet);
29814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      pacer_queue_.erase(it);
29914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      return true;
30014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org    }
30114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  }
30214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  return false;
30314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
30414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
30514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgsize_t PacedVideoSender::TimeToSendPadding(size_t bytes) {
30614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  return 0;
30714b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
30814b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org
30914b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.orgvoid PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
31014b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                        uint8_t fraction_lost,
31114b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org                                        int64_t rtt) {
312379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt);
31314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org  pacer_.UpdateBitrate(
31414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      target_bitrate_bps / 1000,
31514b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org      PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0);
31614b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}
317379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
3189c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesconst int kNoLimit = std::numeric_limits<int>::max();
3199c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesconst int kPacketSizeBytes = 1200;
3209c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
3219c261f2d13793fbb5a0d07b26bec4154bc38342bCesar MagalhaesTcpSender::TcpSender(PacketProcessorListener* listener,
3229c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                     int flow_id,
3239c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                     int64_t offset_ms)
3249c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    : TcpSender(listener, flow_id, offset_ms, kNoLimit) {
3259c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
3269c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
3279c261f2d13793fbb5a0d07b26bec4154bc38342bCesar MagalhaesTcpSender::TcpSender(PacketProcessorListener* listener,
3289c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                     int flow_id,
3299c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                     int64_t offset_ms,
3309c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                     int send_limit_bytes)
3319c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    : PacketSender(listener, flow_id),
3329c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      cwnd_(10),
3339c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      ssthresh_(kNoLimit),
3349c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      ack_received_(false),
3359c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      last_acked_seq_num_(0),
3369c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      next_sequence_number_(0),
3379c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      offset_ms_(offset_ms),
3389c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      last_reduction_time_ms_(-1),
3399c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      last_rtt_ms_(0),
3409c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      total_sent_bytes_(0),
3419c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      send_limit_bytes_(send_limit_bytes),
3429c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      last_generated_packets_ms_(0),
3439c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      num_recent_sent_packets_(0),
3449c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      bitrate_kbps_(0) {
3459c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
3469c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
347379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid TcpSender::RunFor(int64_t time_ms, Packets* in_out) {
348c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) {
349c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    clock_.AdvanceTimeMilliseconds(time_ms);
3509c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    if (running_) {
3512386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes      Pause();
3529c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    }
353bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    return;
354bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  }
3559c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
3562386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  if (!running_ && total_sent_bytes_ == 0) {
3572386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes    Resume(offset_ms_);
3589c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
3599c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
36053d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  int64_t start_time_ms = clock_.TimeInMilliseconds();
361c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes
362c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets(
363c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes      in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin());
364379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  // The number of packets which are sent in during time_ms depends on the
365379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  // number of packets in_flight_ and the max number of packets in flight
366379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms.
367379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  for (FeedbackPacket* fb : feedbacks) {
3689c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    clock_.AdvanceTimeMilliseconds(fb->send_time_ms() -
36953d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer                                   clock_.TimeInMilliseconds());
3709c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    last_rtt_ms_ = fb->send_time_ms() - fb->latest_send_time_ms();
371379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    UpdateCongestionControl(fb);
372379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    SendPackets(in_out);
373379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  }
374ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer
375c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  for (auto it = in_flight_.begin(); it != in_flight_.end();) {
376c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    if (it->time_ms < clock_.TimeInMilliseconds() - 1000)
377c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes      in_flight_.erase(it++);
378c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    else
379c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes      ++it;
380c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes  }
381c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes
38253d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  clock_.AdvanceTimeMilliseconds(time_ms -
38353d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer                                 (clock_.TimeInMilliseconds() - start_time_ms));
384379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  SendPackets(in_out);
385379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer}
386379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
387379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid TcpSender::SendPackets(Packets* in_out) {
388379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  int cwnd = ceil(cwnd_);
389ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer  int packets_to_send = std::max(cwnd - static_cast<int>(in_flight_.size()), 0);
390bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  int timed_out = TriggerTimeouts();
391bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  if (timed_out > 0) {
392bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    HandleLoss();
393bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  }
394379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  if (packets_to_send > 0) {
395379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    Packets generated = GeneratePackets(packets_to_send);
396ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer    for (Packet* packet : generated)
397ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer      in_flight_.insert(InFlight(*static_cast<MediaPacket*>(packet)));
398c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes
399379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    in_out->merge(generated, DereferencingComparator<Packet>);
400379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  }
401379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer}
402379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
403379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmervoid TcpSender::UpdateCongestionControl(const FeedbackPacket* fb) {
404379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  const TcpFeedback* tcp_fb = static_cast<const TcpFeedback*>(fb);
40591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(!tcp_fb->acked_packets().empty());
406379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  ack_received_ = true;
407379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
4085f92051f063d5d827a16102d72cf1c23d423d3ecStefan Holmer  uint16_t expected = tcp_fb->acked_packets().back() - last_acked_seq_num_;
4095f92051f063d5d827a16102d72cf1c23d423d3ecStefan Holmer  uint16_t missing =
4105f92051f063d5d827a16102d72cf1c23d423d3ecStefan Holmer      expected - static_cast<uint16_t>(tcp_fb->acked_packets().size());
411379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
412ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer  for (uint16_t ack_seq_num : tcp_fb->acked_packets())
413c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    in_flight_.erase(InFlight(ack_seq_num, clock_.TimeInMilliseconds()));
414ac69016b0f5f5e4b9521cd1761ad728afd703d86Stefan Holmer
4155f92051f063d5d827a16102d72cf1c23d423d3ecStefan Holmer  if (missing > 0) {
416bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    HandleLoss();
417bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  } else if (cwnd_ <= ssthresh_) {
418379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    cwnd_ += tcp_fb->acked_packets().size();
419379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  } else {
420379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer    cwnd_ += 1.0f / cwnd_;
421379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  }
422379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
423379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  last_acked_seq_num_ =
424379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer      LatestSequenceNumber(tcp_fb->acked_packets().back(), last_acked_seq_num_);
425379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer}
426379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer
427bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmerint TcpSender::TriggerTimeouts() {
428bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  int timed_out = 0;
429bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  for (auto it = in_flight_.begin(); it != in_flight_.end();) {
430c81591d63f5e441bd26025a5e986bb2ebfd9fdfdCesar Magalhaes    if (it->time_ms < clock_.TimeInMilliseconds() - 1000) {
431bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      in_flight_.erase(it++);
432bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      ++timed_out;
433bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    } else {
434bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer      ++it;
435bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer    }
436bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  }
437bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  return timed_out;
438bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer}
439bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer
440bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmervoid TcpSender::HandleLoss() {
44153d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_)
44253d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer    return;
44353d0dc3f067d6440c37157db6060d2f2c9fa8446Stefan Holmer  last_reduction_time_ms_ = clock_.TimeInMilliseconds();
444bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  ssthresh_ = std::max(static_cast<int>(in_flight_.size() / 2), 2);
445bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer  cwnd_ = ssthresh_;
446bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer}
447bcbcd84888819ca913d809e162cc7c7615bc98c7Stefan Holmer
448379593792082a86f389df9b1b790cc0fe9eb9975Stefan HolmerPackets TcpSender::GeneratePackets(size_t num_packets) {
449379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  Packets generated;
4509c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
4519c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  UpdateSendBitrateEstimate(num_packets);
4529c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
453379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  for (size_t i = 0; i < num_packets; ++i) {
4549c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    if ((total_sent_bytes_ + kPacketSizeBytes) > send_limit_bytes_) {
4559c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      if (running_) {
4562386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes        Pause();
4579c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      }
4589c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      break;
4599c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    }
4609c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    generated.push_back(
4619c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes        new MediaPacket(*flow_ids().begin(), 1000 * clock_.TimeInMilliseconds(),
4629c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                        kPacketSizeBytes, next_sequence_number_++));
4630908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer    generated.back()->set_sender_timestamp_us(
4640908d0dcf227b78c55ba4d59d7f5eadcc95af75bStefan Holmer        1000 * clock_.TimeInMilliseconds());
4659c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
4669c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    total_sent_bytes_ += kPacketSizeBytes;
467379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  }
4689c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
469379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer  return generated;
470379593792082a86f389df9b1b790cc0fe9eb9975Stefan Holmer}
4719c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
4729c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid TcpSender::UpdateSendBitrateEstimate(size_t num_packets) {
4739c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const int kTimeWindowMs = 500;
4749c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  num_recent_sent_packets_ += num_packets;
4759c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
4769c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  int64_t delta_ms = clock_.TimeInMilliseconds() - last_generated_packets_ms_;
4779c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (delta_ms >= kTimeWindowMs) {
4789c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    bitrate_kbps_ =
4799c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes        static_cast<uint32_t>(8 * num_recent_sent_packets_ * kPacketSizeBytes) /
4809c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes        delta_ms;
4819c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    last_generated_packets_ms_ = clock_.TimeInMilliseconds();
4829c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    num_recent_sent_packets_ = 0;
4839c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
4842386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes
4852386a45dc710f74174ae8b3ba18b744839b969d9Cesar Magalhaes  RecordBitrate();
4869c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
4879c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
4889c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesuint32_t TcpSender::TargetBitrateKbps() {
4899c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  return bitrate_kbps_;
4909c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
4919c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
49214b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}  // namespace bwe
49314b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}  // namespace testing
49414b0279416c4916534c1e76939b0b8927a208a04stefan@webrtc.org}  // namespace webrtc
495