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