Switch to use range based loops in the BWE simulation framework.
R=tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/40519004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8135 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h"
|
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.h"
|
||||||
|
|
||||||
|
#include "webrtc/base/common.h"
|
||||||
#include "webrtc/modules/interface/module_common_types.h"
|
#include "webrtc/modules/interface/module_common_types.h"
|
||||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h"
|
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_baselinefile.h"
|
||||||
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
|
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
|
||||||
@ -206,7 +207,7 @@ class PacketProcessorRunner {
|
|||||||
// TODO(holmer): Further optimize this by looking for consecutive flow ids
|
// TODO(holmer): Further optimize this by looking for consecutive flow ids
|
||||||
// in the packet list and only doing the binary search + splice once for a
|
// in the packet list and only doing the binary search + splice once for a
|
||||||
// sequence.
|
// sequence.
|
||||||
if (std::binary_search(flow_ids.begin(), flow_ids.end(), it->flow_id())) {
|
if (flow_ids.find(it->flow_id()) != flow_ids.end()) {
|
||||||
Packets::iterator next = it;
|
Packets::iterator next = it;
|
||||||
++next;
|
++next;
|
||||||
out->splice(out->end(), *in, it);
|
out->splice(out->end(), *in, it);
|
||||||
@ -281,9 +282,9 @@ void BweTest::AddPacketProcessor(PacketProcessor* processor, bool is_sender) {
|
|||||||
if (is_sender) {
|
if (is_sender) {
|
||||||
senders_.push_back(static_cast<PacketSender*>(processor));
|
senders_.push_back(static_cast<PacketSender*>(processor));
|
||||||
}
|
}
|
||||||
const FlowIds& flow_ids = processor->flow_ids();
|
for (const auto& flow_id : processor->flow_ids()) {
|
||||||
for (size_t i = 0; i < flow_ids.size(); ++i) {
|
RTC_UNUSED(flow_id);
|
||||||
assert(estimators_.count(flow_ids[i]) == 1);
|
assert(estimators_.count(flow_id) == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,20 +307,17 @@ void BweTest::VerboseLogging(bool enable) {
|
|||||||
void BweTest::GiveFeedbackToAffectedSenders(int flow_id,
|
void BweTest::GiveFeedbackToAffectedSenders(int flow_id,
|
||||||
PacketReceiver* estimator) {
|
PacketReceiver* estimator) {
|
||||||
std::list<PacketSender*> affected_senders;
|
std::list<PacketSender*> affected_senders;
|
||||||
for (std::vector<PacketSender*>::iterator psit =
|
for (auto* sender : senders_) {
|
||||||
senders_.begin(); psit != senders_.end(); ++psit) {
|
if (sender->flow_ids().find(flow_id) != sender->flow_ids().end()) {
|
||||||
const FlowIds& flow_ids = (*psit)->flow_ids();
|
affected_senders.push_back(sender);
|
||||||
if (std::binary_search(flow_ids.begin(), flow_ids.end(), flow_id)) {
|
|
||||||
affected_senders.push_back(*psit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PacketSender::Feedback feedback = {0};
|
PacketSender::Feedback feedback = {0};
|
||||||
if (estimator->GetFeedback(&feedback) && !affected_senders.empty()) {
|
if (estimator->GetFeedback(&feedback) && !affected_senders.empty()) {
|
||||||
// Allocate the bitrate evenly between the senders.
|
// Allocate the bitrate evenly between the senders.
|
||||||
feedback.estimated_bps /= affected_senders.size();
|
feedback.estimated_bps /= affected_senders.size();
|
||||||
for (std::list<PacketSender*>::iterator psit = affected_senders.begin();
|
for (auto* sender : affected_senders) {
|
||||||
psit != affected_senders.end(); ++psit) {
|
sender->GiveFeedback(feedback);
|
||||||
(*psit)->GiveFeedback(feedback);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,9 +336,8 @@ void BweTest::RunFor(int64_t time_ms) {
|
|||||||
time_now_ms_ <= run_time_ms_ - simulation_interval_ms_;
|
time_now_ms_ <= run_time_ms_ - simulation_interval_ms_;
|
||||||
time_now_ms_ += simulation_interval_ms_) {
|
time_now_ms_ += simulation_interval_ms_) {
|
||||||
Packets packets;
|
Packets packets;
|
||||||
for (vector<PacketProcessorRunner>::iterator it =
|
for (auto& processor : processors_) {
|
||||||
processors_.begin(); it != processors_.end(); ++it) {
|
processor.RunFor(simulation_interval_ms_, time_now_ms_, &packets);
|
||||||
it->RunFor(simulation_interval_ms_, time_now_ms_, &packets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify packets are in order between batches.
|
// Verify packets are in order between batches.
|
||||||
@ -357,15 +354,14 @@ void BweTest::RunFor(int64_t time_ms) {
|
|||||||
ASSERT_TRUE(IsTimeSorted(packets));
|
ASSERT_TRUE(IsTimeSorted(packets));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PacketsConstIt it = packets.begin(); it != packets.end(); ++it) {
|
for (const auto& packet : packets) {
|
||||||
EstimatorMap::iterator est_it = estimators_.find(it->flow_id());
|
EstimatorMap::iterator est_it = estimators_.find(packet.flow_id());
|
||||||
ASSERT_TRUE(est_it != estimators_.end());
|
ASSERT_TRUE(est_it != estimators_.end());
|
||||||
est_it->second->EatPacket(*it);
|
est_it->second->EatPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (EstimatorMap::iterator est_it = estimators_.begin();
|
for (const auto& estimator : estimators_) {
|
||||||
est_it != estimators_.end(); ++est_it) {
|
GiveFeedbackToAffectedSenders(estimator.first, estimator.second);
|
||||||
GiveFeedbackToAffectedSenders(est_it->first, est_it->second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,18 @@ bool IsTimeSorted(const Packets& packets) {
|
|||||||
|
|
||||||
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
||||||
bool is_sender)
|
bool is_sender)
|
||||||
: listener_(listener), flow_ids_(1, 0) {
|
: listener_(listener) {
|
||||||
|
flow_ids_.insert(0);
|
||||||
|
if (listener_) {
|
||||||
|
listener_->AddPacketProcessor(this, is_sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketProcessor::PacketProcessor(PacketProcessorListener* listener,
|
||||||
|
int flow_id,
|
||||||
|
bool is_sender)
|
||||||
|
: listener_(listener) {
|
||||||
|
flow_ids_.insert(flow_id);
|
||||||
if (listener_) {
|
if (listener_) {
|
||||||
listener_->AddPacketProcessor(this, is_sender);
|
listener_->AddPacketProcessor(this, is_sender);
|
||||||
}
|
}
|
||||||
@ -219,8 +230,8 @@ RateCounterFilter::RateCounterFilter(PacketProcessorListener* listener,
|
|||||||
name_(name) {
|
name_(name) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << name_ << "_";
|
ss << name_ << "_";
|
||||||
for (size_t i = 0; i < flow_ids.size(); ++i) {
|
for (auto flow_id : flow_ids) {
|
||||||
ss << flow_ids[i] << ",";
|
ss << flow_id << ",";
|
||||||
}
|
}
|
||||||
name_ = ss.str();
|
name_ = ss.str();
|
||||||
}
|
}
|
||||||
@ -255,8 +266,8 @@ void RateCounterFilter::Plot(int64_t timestamp_ms) {
|
|||||||
|
|
||||||
void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
void RateCounterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
||||||
assert(in_out);
|
assert(in_out);
|
||||||
for (PacketsConstIt it = in_out->begin(); it != in_out->end(); ++it) {
|
for (const auto& packet : *in_out) {
|
||||||
rate_counter_->UpdateRates(it->send_time_us(), it->payload_size());
|
rate_counter_->UpdateRates(packet.send_time_us(), packet.payload_size());
|
||||||
}
|
}
|
||||||
packets_per_second_stats_.Push(rate_counter_->packets_per_second());
|
packets_per_second_stats_.Push(rate_counter_->packets_per_second());
|
||||||
kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
|
kbps_stats_.Push(rate_counter_->bits_per_second() / 1000.0);
|
||||||
@ -302,10 +313,10 @@ void DelayFilter::SetDelay(int64_t delay_ms) {
|
|||||||
|
|
||||||
void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
void DelayFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
||||||
assert(in_out);
|
assert(in_out);
|
||||||
for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
|
for (auto& packet : *in_out) {
|
||||||
int64_t new_send_time_us = it->send_time_us() + delay_us_;
|
int64_t new_send_time_us = packet.send_time_us() + delay_us_;
|
||||||
last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
|
last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
|
||||||
it->set_send_time_us(last_send_time_us_);
|
packet.set_send_time_us(last_send_time_us_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,11 +337,11 @@ void JitterFilter::SetJitter(int64_t stddev_jitter_ms) {
|
|||||||
|
|
||||||
void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
void JitterFilter::RunFor(int64_t /*time_ms*/, Packets* in_out) {
|
||||||
assert(in_out);
|
assert(in_out);
|
||||||
for (PacketsIt it = in_out->begin(); it != in_out->end(); ++it) {
|
for (auto& packet : *in_out) {
|
||||||
int64_t new_send_time_us = it->send_time_us();
|
int64_t new_send_time_us = packet.send_time_us();
|
||||||
new_send_time_us += random_.Gaussian(0, stddev_jitter_us_);
|
new_send_time_us += random_.Gaussian(0, stddev_jitter_us_);
|
||||||
last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
|
last_send_time_us_ = std::max(last_send_time_us_, new_send_time_us);
|
||||||
it->set_send_time_us(last_send_time_us_);
|
packet.set_send_time_us(last_send_time_us_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,9 +533,8 @@ void TraceBasedDeliveryFilter::ProceedToNextSlot() {
|
|||||||
++next_delivery_it_;
|
++next_delivery_it_;
|
||||||
if (next_delivery_it_ == delivery_times_us_.end()) {
|
if (next_delivery_it_ == delivery_times_us_.end()) {
|
||||||
// When the trace wraps we allow two packets to be sent back-to-back.
|
// When the trace wraps we allow two packets to be sent back-to-back.
|
||||||
for (TimeList::iterator it = delivery_times_us_.begin();
|
for (auto& delivery_time_us : delivery_times_us_) {
|
||||||
it != delivery_times_us_.end(); ++it) {
|
delivery_time_us += local_time_us_ - current_offset_us_;
|
||||||
*it += local_time_us_ - current_offset_us_;
|
|
||||||
}
|
}
|
||||||
current_offset_us_ += local_time_us_ - current_offset_us_;
|
current_offset_us_ += local_time_us_ - current_offset_us_;
|
||||||
next_delivery_it_ = delivery_times_us_.begin();
|
next_delivery_it_ = delivery_times_us_.begin();
|
||||||
@ -539,7 +549,7 @@ PacketSender::PacketSender(PacketProcessorListener* listener)
|
|||||||
: PacketProcessor(listener, true) {}
|
: PacketProcessor(listener, true) {}
|
||||||
|
|
||||||
PacketSender::PacketSender(PacketProcessorListener* listener, int flow_id)
|
PacketSender::PacketSender(PacketProcessorListener* listener, int flow_id)
|
||||||
: PacketProcessor(listener, FlowIds(1, flow_id), true) {
|
: PacketProcessor(listener, flow_id, true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoSender::VideoSender(int flow_id,
|
VideoSender::VideoSender(int flow_id,
|
||||||
@ -595,8 +605,8 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
|||||||
while (payload_size > 0) {
|
while (payload_size > 0) {
|
||||||
++prototype_header_.sequenceNumber;
|
++prototype_header_.sequenceNumber;
|
||||||
uint32_t size = NextPacketSize(frame_size, payload_size);
|
uint32_t size = NextPacketSize(frame_size, payload_size);
|
||||||
new_packets.push_back(Packet(flow_ids()[0], send_time_us, size,
|
new_packets.push_back(
|
||||||
prototype_header_));
|
Packet(*flow_ids().begin(), send_time_us, size, prototype_header_));
|
||||||
new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
|
new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
|
||||||
payload_size -= size;
|
payload_size -= size;
|
||||||
}
|
}
|
||||||
@ -681,7 +691,7 @@ RegularVideoSender::RegularVideoSender(PacketProcessorListener* listener,
|
|||||||
// It is important that the first_frame_offset and the initial time of
|
// It is important that the first_frame_offset and the initial time of
|
||||||
// clock_ are both zero, otherwise we can't have absolute time in this
|
// clock_ are both zero, otherwise we can't have absolute time in this
|
||||||
// class.
|
// class.
|
||||||
: PacketSender(listener, source->flow_ids()[0]),
|
: PacketSender(listener, *source->flow_ids().begin()),
|
||||||
clock_(0),
|
clock_(0),
|
||||||
start_of_run_ms_(0),
|
start_of_run_ms_(0),
|
||||||
bitrate_controller_(BitrateController::CreateBitrateController(&clock_,
|
bitrate_controller_(BitrateController::CreateBitrateController(&clock_,
|
||||||
@ -721,7 +731,7 @@ void RegularVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
|||||||
feedback.estimated_bps = target_bitrate_bps;
|
feedback.estimated_bps = target_bitrate_bps;
|
||||||
source_->GiveFeedback(feedback);
|
source_->GiveFeedback(feedback);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "SendEstimate_" << flow_ids()[0] << "#1";
|
ss << "SendEstimate_" << *flow_ids().begin() << "#1";
|
||||||
BWE_TEST_LOGGING_PLOT(ss.str(), clock_.TimeInMilliseconds(),
|
BWE_TEST_LOGGING_PLOT(ss.str(), clock_.TimeInMilliseconds(),
|
||||||
target_bitrate_bps / 1000);
|
target_bitrate_bps / 1000);
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,7 @@ namespace bwe {
|
|||||||
class DelayCapHelper;
|
class DelayCapHelper;
|
||||||
class RateCounter;
|
class RateCounter;
|
||||||
|
|
||||||
|
typedef std::set<int> FlowIds;
|
||||||
typedef std::vector<int> FlowIds;
|
|
||||||
const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids);
|
const FlowIds CreateFlowIds(const int *flow_ids_array, size_t num_flow_ids);
|
||||||
|
|
||||||
template<typename T> class Stats {
|
template<typename T> class Stats {
|
||||||
@ -74,9 +73,8 @@ template<typename T> class Stats {
|
|||||||
last_variance_count_ = data_.size();
|
last_variance_count_ = data_.size();
|
||||||
T mean = GetMean();
|
T mean = GetMean();
|
||||||
variance_ = 0;
|
variance_ = 0;
|
||||||
for (typename std::vector<T>::const_iterator it = data_.begin();
|
for (const auto& sample : data_) {
|
||||||
it != data_.end(); ++it) {
|
T diff = (sample - mean);
|
||||||
T diff = (*it - mean);
|
|
||||||
variance_ += diff * diff;
|
variance_ += diff * diff;
|
||||||
}
|
}
|
||||||
assert(last_variance_count_ != 0);
|
assert(last_variance_count_ != 0);
|
||||||
@ -200,6 +198,9 @@ class PacketProcessorListener {
|
|||||||
class PacketProcessor {
|
class PacketProcessor {
|
||||||
public:
|
public:
|
||||||
PacketProcessor(PacketProcessorListener* listener, bool is_sender);
|
PacketProcessor(PacketProcessorListener* listener, bool is_sender);
|
||||||
|
PacketProcessor(PacketProcessorListener* listener,
|
||||||
|
int flow_id,
|
||||||
|
bool is_sender);
|
||||||
PacketProcessor(PacketProcessorListener* listener, const FlowIds& flow_ids,
|
PacketProcessor(PacketProcessorListener* listener, const FlowIds& flow_ids,
|
||||||
bool is_sender);
|
bool is_sender);
|
||||||
virtual ~PacketProcessor();
|
virtual ~PacketProcessor();
|
||||||
|
Reference in New Issue
Block a user