Refactor senders into senders and sources in the simulation framework.
BUG=4173 R=sprang@webrtc.org Review URL: https://webrtc-codereview.appspot.com/38579005 Cr-Commit-Position: refs/heads/master@{#8218} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8218 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
a671f4b2cb
commit
f88bee6d88
@ -64,7 +64,8 @@ INSTANTIATE_TEST_CASE_P(VideoSendersTest, BweSimulation,
|
||||
|
||||
TEST_P(BweSimulation, SprintUplinkTest) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
RateCounterFilter counter2(this, "receiver_input");
|
||||
@ -74,7 +75,8 @@ TEST_P(BweSimulation, SprintUplinkTest) {
|
||||
|
||||
TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
RateCounterFilter counter2(this, "receiver_input");
|
||||
@ -84,7 +86,8 @@ TEST_P(BweSimulation, Verizon4gDownlinkTest) {
|
||||
|
||||
TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
filter.SetCapacity(1000);
|
||||
@ -98,8 +101,8 @@ TEST_P(BweSimulation, Choke1000kbps500kbps1000kbps) {
|
||||
|
||||
TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
|
||||
VerboseLogging(true);
|
||||
PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, 300, &source);
|
||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
filter.SetCapacity(1000);
|
||||
@ -113,8 +116,8 @@ TEST_P(BweSimulation, PacerChoke1000kbps500kbps1000kbps) {
|
||||
|
||||
TEST_P(BweSimulation, PacerChoke10000kbps) {
|
||||
VerboseLogging(true);
|
||||
PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 0);
|
||||
PacedVideoSender sender(this, 300, &source);
|
||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
filter.SetCapacity(10000);
|
||||
@ -124,8 +127,8 @@ TEST_P(BweSimulation, PacerChoke10000kbps) {
|
||||
|
||||
TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
||||
VerboseLogging(true);
|
||||
PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, 300, &source);
|
||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
filter.SetCapacity(200);
|
||||
@ -139,7 +142,8 @@ TEST_P(BweSimulation, PacerChoke200kbps30kbps200kbps) {
|
||||
|
||||
TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
filter.SetCapacity(200);
|
||||
@ -153,7 +157,8 @@ TEST_P(BweSimulation, Choke200kbps30kbps200kbps) {
|
||||
|
||||
TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
|
||||
VerboseLogging(true);
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
@ -164,8 +169,8 @@ TEST_P(BweSimulation, GoogleWifiTrace3Mbps) {
|
||||
|
||||
TEST_P(BweSimulation, PacerGoogleWifiTrace3Mbps) {
|
||||
VerboseLogging(true);
|
||||
PeriodicKeyFrameSender source(0, NULL, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, 300, &source);
|
||||
PeriodicKeyFrameSource source(0, 30, 300, 0, 0, 1000);
|
||||
PacedVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
@ -190,13 +195,14 @@ TEST_P(MultiFlowBweSimulation, SelfFairnessTest) {
|
||||
VerboseLogging(true);
|
||||
const int kAllFlowIds[] = {0, 1, 2};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
scoped_ptr<AdaptiveVideoSender> senders[kNumFlows];
|
||||
|
||||
scoped_ptr<AdaptiveVideoSource> sources[kNumFlows];
|
||||
scoped_ptr<RegularVideoSender> senders[kNumFlows];
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
senders[i].reset(
|
||||
new AdaptiveVideoSender(kAllFlowIds[i], this, 30, 300, 0, i * 20000));
|
||||
sources[i].reset(
|
||||
new AdaptiveVideoSource(kAllFlowIds[i], 30, 300, 0, i * 20000));
|
||||
senders[i].reset(new RegularVideoSender(this, sources[i].get(), 300));
|
||||
}
|
||||
|
||||
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
@ -218,15 +224,15 @@ TEST_P(MultiFlowBweSimulation, PacedSelfFairnessTest) {
|
||||
VerboseLogging(true);
|
||||
const int kAllFlowIds[] = {0, 1, 2};
|
||||
const size_t kNumFlows = sizeof(kAllFlowIds) / sizeof(kAllFlowIds[0]);
|
||||
scoped_ptr<PeriodicKeyFrameSender> sources[kNumFlows];
|
||||
scoped_ptr<PeriodicKeyFrameSource> sources[kNumFlows];
|
||||
scoped_ptr<PacedVideoSender> senders[kNumFlows];
|
||||
|
||||
for (size_t i = 0; i < kNumFlows; ++i) {
|
||||
// Streams started 20 seconds apart to give them different advantage when
|
||||
// competing for the bandwidth.
|
||||
sources[i].reset(new PeriodicKeyFrameSender(kAllFlowIds[i], NULL, 30, 300,
|
||||
0, i * 20000, 1000));
|
||||
senders[i].reset(new PacedVideoSender(this, 300, sources[i].get()));
|
||||
sources[i].reset(new PeriodicKeyFrameSource(kAllFlowIds[i], 30, 300, 0,
|
||||
i * 20000, 1000));
|
||||
senders[i].reset(new PacedVideoSender(this, sources[i].get(), 300));
|
||||
}
|
||||
|
||||
ChokeFilter choke(this, CreateFlowIds(kAllFlowIds, kNumFlows));
|
||||
|
@ -57,14 +57,14 @@ DefaultBweTestConfig MakeBweTestConfig(uint32_t sender_count,
|
||||
class DefaultBweTest : public BweTest,
|
||||
public ::testing::TestWithParam<DefaultBweTestConfig> {
|
||||
public:
|
||||
DefaultBweTest() : packet_senders_() {}
|
||||
virtual ~DefaultBweTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
const DefaultBweTestConfig& config = GetParam();
|
||||
SetupTestFromConfig(config.bwe_test_config);
|
||||
for (size_t i = 0; i < config.number_of_senders; ++i) {
|
||||
packet_senders_.push_back(new VideoSender(0, this, 30, 300, 0, 0));
|
||||
sources_.push_back(new VideoSource(0, 30, 300, 0, 0));
|
||||
packet_senders_.push_back(new PacketSender(this, sources_.back()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,9 +73,14 @@ class DefaultBweTest : public BweTest,
|
||||
delete packet_senders_.front();
|
||||
packet_senders_.pop_front();
|
||||
}
|
||||
while (!sources_.empty()) {
|
||||
delete sources_.front();
|
||||
sources_.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::list<VideoSource*> sources_;
|
||||
std::list<PacketSender*> packet_senders_;
|
||||
};
|
||||
|
||||
@ -277,7 +282,8 @@ class BweFeedbackTest : public BweTest,
|
||||
};
|
||||
|
||||
TEST_F(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
const int kHighCapacityKbps = 1000;
|
||||
@ -294,7 +300,8 @@ TEST_F(BweFeedbackTest, Choke1000kbps500kbps1000kbps) {
|
||||
}
|
||||
|
||||
TEST_F(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
ChokeFilter filter(this);
|
||||
RateCounterFilter counter(this, "receiver_input");
|
||||
const int kHighCapacityKbps = 200;
|
||||
@ -312,7 +319,8 @@ TEST_F(BweFeedbackTest, Choke200kbps30kbps200kbps) {
|
||||
}
|
||||
|
||||
TEST_F(BweFeedbackTest, Verizon4gDownlinkTest) {
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
RateCounterFilter counter2(this, "receiver_input");
|
||||
@ -324,7 +332,8 @@ TEST_F(BweFeedbackTest, Verizon4gDownlinkTest) {
|
||||
|
||||
// webrtc:3277
|
||||
TEST_F(BweFeedbackTest, DISABLED_GoogleWifiTrace3Mbps) {
|
||||
AdaptiveVideoSender sender(0, this, 30, 300, 0, 0);
|
||||
AdaptiveVideoSource source(0, 30, 300, 0, 0);
|
||||
RegularVideoSender sender(this, &source, 300);
|
||||
RateCounterFilter counter1(this, "sender_output");
|
||||
TraceBasedDeliveryFilter filter(this, "link_capacity");
|
||||
filter.SetMaxDelay(500);
|
||||
|
@ -288,8 +288,7 @@ void BweTest::AddPacketProcessor(PacketProcessor* processor, bool is_sender) {
|
||||
}
|
||||
}
|
||||
|
||||
void BweTest::RemovePacketProcessor(
|
||||
PacketProcessor* processor) {
|
||||
void BweTest::RemovePacketProcessor(PacketProcessor* processor) {
|
||||
for (vector<PacketProcessorRunner>::iterator it = processors_.begin();
|
||||
it != processors_.end(); ++it) {
|
||||
if (it->HasProcessor(processor)) {
|
||||
|
@ -545,22 +545,14 @@ void TraceBasedDeliveryFilter::ProceedToNextSlot() {
|
||||
rate_counter_->UpdateRates(local_time_us_, kPayloadSize);
|
||||
}
|
||||
|
||||
PacketSender::PacketSender(PacketProcessorListener* listener)
|
||||
: PacketProcessor(listener, true) {}
|
||||
|
||||
PacketSender::PacketSender(PacketProcessorListener* listener, int flow_id)
|
||||
: PacketProcessor(listener, flow_id, true) {
|
||||
}
|
||||
|
||||
VideoSender::VideoSender(int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
VideoSource::VideoSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms)
|
||||
: PacketSender(listener, flow_id),
|
||||
kMaxPayloadSizeBytes(1200),
|
||||
: kMaxPayloadSizeBytes(1200),
|
||||
kTimestampBase(0xff80ff00ul),
|
||||
flow_id_(flow_id),
|
||||
frame_period_ms_(1000.0 / fps),
|
||||
bytes_per_second_((1000 * kbps) / 8),
|
||||
frame_size_bytes_(bytes_per_second_ / fps),
|
||||
@ -572,20 +564,16 @@ VideoSender::VideoSender(int flow_id,
|
||||
prototype_header_.sequenceNumber = 0xf000u;
|
||||
}
|
||||
|
||||
uint32_t VideoSender::GetCapacityKbps() const {
|
||||
return (bytes_per_second_ * 8) / 1000;
|
||||
}
|
||||
|
||||
uint32_t VideoSender::NextFrameSize() {
|
||||
uint32_t VideoSource::NextFrameSize() {
|
||||
return frame_size_bytes_;
|
||||
}
|
||||
|
||||
uint32_t VideoSender::NextPacketSize(uint32_t frame_size,
|
||||
uint32_t VideoSource::NextPacketSize(uint32_t frame_size,
|
||||
uint32_t remaining_payload) {
|
||||
return std::min(kMaxPayloadSizeBytes, remaining_payload);
|
||||
}
|
||||
|
||||
void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
void VideoSource::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
assert(in_out);
|
||||
now_ms_ += time_ms;
|
||||
Packets new_packets;
|
||||
@ -606,7 +594,7 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
++prototype_header_.sequenceNumber;
|
||||
uint32_t size = NextPacketSize(frame_size, payload_size);
|
||||
new_packets.push_back(
|
||||
Packet(*flow_ids().begin(), send_time_us, size, prototype_header_));
|
||||
Packet(flow_id_, send_time_us, size, prototype_header_));
|
||||
new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
|
||||
payload_size -= size;
|
||||
}
|
||||
@ -616,41 +604,33 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
in_out->merge(new_packets);
|
||||
}
|
||||
|
||||
AdaptiveVideoSender::AdaptiveVideoSender(int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
AdaptiveVideoSource::AdaptiveVideoSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms)
|
||||
: VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset_ms) {
|
||||
: VideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms) {
|
||||
}
|
||||
|
||||
void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
|
||||
bytes_per_second_ = std::min(feedback.estimated_bps / 8, 2500000u / 8);
|
||||
void AdaptiveVideoSource::SetBitrateBps(int bitrate_bps) {
|
||||
bytes_per_second_ = std::min(bitrate_bps / 8, 2500000 / 8);
|
||||
frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
|
||||
}
|
||||
|
||||
PeriodicKeyFrameSender::PeriodicKeyFrameSender(
|
||||
int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms,
|
||||
int key_frame_interval)
|
||||
: AdaptiveVideoSender(flow_id,
|
||||
listener,
|
||||
fps,
|
||||
kbps,
|
||||
ssrc,
|
||||
first_frame_offset_ms),
|
||||
PeriodicKeyFrameSource::PeriodicKeyFrameSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms,
|
||||
int key_frame_interval)
|
||||
: AdaptiveVideoSource(flow_id, fps, kbps, ssrc, first_frame_offset_ms),
|
||||
key_frame_interval_(key_frame_interval),
|
||||
frame_counter_(0),
|
||||
compensation_bytes_(0),
|
||||
compensation_per_frame_(0) {
|
||||
}
|
||||
|
||||
uint32_t PeriodicKeyFrameSender::NextFrameSize() {
|
||||
uint32_t PeriodicKeyFrameSource::NextFrameSize() {
|
||||
uint32_t payload_size = frame_size_bytes_;
|
||||
if (frame_counter_ == 0) {
|
||||
payload_size = kMaxPayloadSizeBytes * 12;
|
||||
@ -677,7 +657,7 @@ uint32_t PeriodicKeyFrameSender::NextFrameSize() {
|
||||
return payload_size;
|
||||
}
|
||||
|
||||
uint32_t PeriodicKeyFrameSender::NextPacketSize(uint32_t frame_size,
|
||||
uint32_t PeriodicKeyFrameSource::NextPacketSize(uint32_t frame_size,
|
||||
uint32_t remaining_payload) {
|
||||
uint32_t fragments =
|
||||
(frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes;
|
||||
@ -685,19 +665,26 @@ uint32_t PeriodicKeyFrameSender::NextPacketSize(uint32_t frame_size,
|
||||
return std::min(avg_size, remaining_payload);
|
||||
}
|
||||
|
||||
PacketSender::PacketSender(PacketProcessorListener* listener,
|
||||
VideoSource* source)
|
||||
: PacketProcessor(listener, source->flow_id(), true), source_(source) {
|
||||
}
|
||||
|
||||
void PacketSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
source_->RunFor(time_ms, in_out);
|
||||
}
|
||||
|
||||
RegularVideoSender::RegularVideoSender(PacketProcessorListener* listener,
|
||||
uint32_t kbps,
|
||||
AdaptiveVideoSender* source)
|
||||
VideoSource* source,
|
||||
uint32_t kbps)
|
||||
// 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
|
||||
// class.
|
||||
: PacketSender(listener, *source->flow_ids().begin()),
|
||||
clock_(0),
|
||||
start_of_run_ms_(0),
|
||||
: PacketSender(listener, source),
|
||||
clock_(kInitialTimeMs),
|
||||
bitrate_controller_(BitrateController::CreateBitrateController(&clock_,
|
||||
false)),
|
||||
feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()),
|
||||
source_(source),
|
||||
modules_() {
|
||||
const int kMinBitrateBps = 10000;
|
||||
const int kMaxBitrateBps = 20000000;
|
||||
@ -720,16 +707,21 @@ void RegularVideoSender::GiveFeedback(const Feedback& feedback) {
|
||||
|
||||
void RegularVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
|
||||
start_of_run_ms_ = clock_.TimeInMilliseconds();
|
||||
source_->RunFor(time_ms, in_out);
|
||||
clock_.AdvanceTimeMilliseconds(time_ms);
|
||||
int64_t time_left_ms = time_ms;
|
||||
while (time_left_ms > 0) {
|
||||
const int64_t kMaxRunTimeMs = 100;
|
||||
int64_t time_to_run_ms = std::min(time_left_ms, kMaxRunTimeMs);
|
||||
PacketSender::RunFor(time_to_run_ms, in_out);
|
||||
clock_.AdvanceTimeMilliseconds(time_to_run_ms);
|
||||
bitrate_controller_->Process();
|
||||
time_left_ms -= time_to_run_ms;
|
||||
}
|
||||
}
|
||||
|
||||
void RegularVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
uint8_t fraction_lost,
|
||||
int64_t rtt) {
|
||||
PacketSender::Feedback feedback;
|
||||
feedback.estimated_bps = target_bitrate_bps;
|
||||
source_->GiveFeedback(feedback);
|
||||
source_->SetBitrateBps(target_bitrate_bps);
|
||||
std::stringstream ss;
|
||||
ss << "SendEstimate_" << *flow_ids().begin() << "#1";
|
||||
BWE_TEST_LOGGING_PLOT(ss.str(), clock_.TimeInMilliseconds(),
|
||||
@ -737,12 +729,12 @@ void RegularVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
}
|
||||
|
||||
PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
|
||||
uint32_t kbps,
|
||||
AdaptiveVideoSender* source)
|
||||
VideoSource* source,
|
||||
uint32_t kbps)
|
||||
// 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
|
||||
// class.
|
||||
: RegularVideoSender(listener, kbps, source),
|
||||
: RegularVideoSender(listener, source, kbps),
|
||||
pacer_(&clock_,
|
||||
this,
|
||||
kbps,
|
||||
|
@ -367,47 +367,21 @@ class TraceBasedDeliveryFilter : public PacketProcessor {
|
||||
DISALLOW_COPY_AND_ASSIGN(TraceBasedDeliveryFilter);
|
||||
};
|
||||
|
||||
class PacketSender : public PacketProcessor {
|
||||
class VideoSource {
|
||||
public:
|
||||
struct Feedback {
|
||||
uint32_t estimated_bps;
|
||||
RTCPReportBlock report_block;
|
||||
};
|
||||
|
||||
explicit PacketSender(PacketProcessorListener* listener);
|
||||
PacketSender(PacketProcessorListener* listener, int flow_id);
|
||||
virtual ~PacketSender() {}
|
||||
|
||||
virtual uint32_t GetCapacityKbps() const { return 0; }
|
||||
|
||||
// Call GiveFeedback() with the returned interval in milliseconds, provided
|
||||
// there is a new estimate available.
|
||||
// Note that changing the feedback interval affects the timing of when the
|
||||
// output of the estimators is sampled and therefore the baseline files may
|
||||
// have to be regenerated.
|
||||
virtual int GetFeedbackIntervalMs() const { return 1000; }
|
||||
virtual void GiveFeedback(const Feedback& feedback) {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PacketSender);
|
||||
};
|
||||
|
||||
class VideoSender : public PacketSender {
|
||||
public:
|
||||
VideoSender(int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
VideoSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms);
|
||||
virtual ~VideoSender() {}
|
||||
virtual ~VideoSource() {}
|
||||
|
||||
uint32_t max_payload_size_bytes() const { return kMaxPayloadSizeBytes; }
|
||||
uint32_t bytes_per_second() const { return bytes_per_second_; }
|
||||
|
||||
virtual uint32_t GetCapacityKbps() const OVERRIDE;
|
||||
|
||||
virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
|
||||
virtual void RunFor(int64_t time_ms, Packets* in_out);
|
||||
virtual void SetBitrateBps(int bitrate_bps) {}
|
||||
virtual int flow_id() const { return flow_id_; }
|
||||
|
||||
protected:
|
||||
virtual uint32_t NextFrameSize();
|
||||
@ -416,6 +390,7 @@ class VideoSender : public PacketSender {
|
||||
|
||||
const uint32_t kMaxPayloadSizeBytes;
|
||||
const uint32_t kTimestampBase;
|
||||
const int flow_id_;
|
||||
const double frame_period_ms_;
|
||||
uint32_t bytes_per_second_;
|
||||
uint32_t frame_size_bytes_;
|
||||
@ -425,36 +400,33 @@ class VideoSender : public PacketSender {
|
||||
double now_ms_;
|
||||
RTPHeader prototype_header_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSender);
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoSource);
|
||||
};
|
||||
|
||||
class AdaptiveVideoSender : public VideoSender {
|
||||
class AdaptiveVideoSource : public VideoSource {
|
||||
public:
|
||||
AdaptiveVideoSender(int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
AdaptiveVideoSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms);
|
||||
virtual ~AdaptiveVideoSender() {}
|
||||
virtual ~AdaptiveVideoSource() {}
|
||||
|
||||
virtual int GetFeedbackIntervalMs() const OVERRIDE { return 100; }
|
||||
virtual void GiveFeedback(const Feedback& feedback) OVERRIDE;
|
||||
virtual void SetBitrateBps(int bitrate_bps) OVERRIDE;
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSender);
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveVideoSource);
|
||||
};
|
||||
|
||||
class PeriodicKeyFrameSender : public AdaptiveVideoSender {
|
||||
class PeriodicKeyFrameSource : public AdaptiveVideoSource {
|
||||
public:
|
||||
PeriodicKeyFrameSender(int flow_id,
|
||||
PacketProcessorListener* listener,
|
||||
PeriodicKeyFrameSource(int flow_id,
|
||||
float fps,
|
||||
uint32_t kbps,
|
||||
uint32_t ssrc,
|
||||
int64_t first_frame_offset_ms,
|
||||
int key_frame_interval);
|
||||
virtual ~PeriodicKeyFrameSender() {}
|
||||
virtual ~PeriodicKeyFrameSource() {}
|
||||
|
||||
protected:
|
||||
virtual uint32_t NextFrameSize() OVERRIDE;
|
||||
@ -466,14 +438,44 @@ class PeriodicKeyFrameSender : public AdaptiveVideoSender {
|
||||
uint32_t frame_counter_;
|
||||
int compensation_bytes_;
|
||||
int compensation_per_frame_;
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSender);
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSource);
|
||||
};
|
||||
|
||||
class PacketSender : public PacketProcessor {
|
||||
public:
|
||||
struct Feedback {
|
||||
uint32_t estimated_bps;
|
||||
RTCPReportBlock report_block;
|
||||
};
|
||||
|
||||
PacketSender(PacketProcessorListener* listener, VideoSource* source);
|
||||
virtual ~PacketSender() {}
|
||||
|
||||
virtual uint32_t GetCapacityKbps() const { return 0; }
|
||||
|
||||
// Call GiveFeedback() with the returned interval in milliseconds, provided
|
||||
// there is a new estimate available.
|
||||
// Note that changing the feedback interval affects the timing of when the
|
||||
// output of the estimators is sampled and therefore the baseline files may
|
||||
// have to be regenerated.
|
||||
virtual int GetFeedbackIntervalMs() const { return 1000; }
|
||||
virtual void GiveFeedback(const Feedback& feedback) {}
|
||||
virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
|
||||
|
||||
virtual VideoSource* source() const { return source_; }
|
||||
|
||||
protected:
|
||||
VideoSource* source_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PacketSender);
|
||||
};
|
||||
|
||||
class RegularVideoSender : public PacketSender, public BitrateObserver {
|
||||
public:
|
||||
RegularVideoSender(PacketProcessorListener* listener,
|
||||
uint32_t kbps,
|
||||
AdaptiveVideoSender* source);
|
||||
VideoSource* source,
|
||||
uint32_t kbps);
|
||||
virtual ~RegularVideoSender();
|
||||
|
||||
virtual int GetFeedbackIntervalMs() const OVERRIDE { return 100; }
|
||||
@ -491,7 +493,6 @@ class RegularVideoSender : public PacketSender, public BitrateObserver {
|
||||
int64_t start_of_run_ms_;
|
||||
scoped_ptr<BitrateController> bitrate_controller_;
|
||||
scoped_ptr<RtcpBandwidthObserver> feedback_observer_;
|
||||
AdaptiveVideoSender* source_;
|
||||
std::list<Module*> modules_;
|
||||
|
||||
private:
|
||||
@ -502,8 +503,8 @@ class PacedVideoSender : public RegularVideoSender,
|
||||
public PacedSender::Callback {
|
||||
public:
|
||||
PacedVideoSender(PacketProcessorListener* listener,
|
||||
uint32_t kbps,
|
||||
AdaptiveVideoSender* source);
|
||||
VideoSource* source,
|
||||
uint32_t kbps);
|
||||
virtual ~PacedVideoSender();
|
||||
|
||||
virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE;
|
||||
|
@ -730,7 +730,8 @@ TEST_F(BweTestFramework_ChokeFilterTest, ShortTraceMaxDelay) {
|
||||
TestChoke(&filter, 25, 1, 1);
|
||||
}
|
||||
|
||||
void TestVideoSender(VideoSender* sender, int64_t run_for_ms,
|
||||
void TestVideoSender(PacketSender* sender,
|
||||
int64_t run_for_ms,
|
||||
uint32_t expected_packets,
|
||||
uint32_t expected_payload_size,
|
||||
uint32_t expected_total_payload_size) {
|
||||
@ -749,7 +750,7 @@ void TestVideoSender(VideoSender* sender, int64_t run_for_ms,
|
||||
for (PacketsIt it = packets.begin(); it != packets.end(); ++it) {
|
||||
EXPECT_LE(send_time_us, it->send_time_us());
|
||||
send_time_us = it->send_time_us();
|
||||
if (sender->max_payload_size_bytes() != it->payload_size()) {
|
||||
if (sender->source()->max_payload_size_bytes() != it->payload_size()) {
|
||||
EXPECT_EQ(expected_payload_size, it->payload_size());
|
||||
}
|
||||
total_payload_size += it->payload_size();
|
||||
@ -769,8 +770,9 @@ void TestVideoSender(VideoSender* sender, int64_t run_for_ms,
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s) {
|
||||
// 1 fps, 80 kbps
|
||||
VideoSender sender(0, NULL, 1.0f, 80, 0x1234, 0);
|
||||
EXPECT_EQ(10000u, sender.bytes_per_second());
|
||||
VideoSource source(0, 1.0f, 80, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source);
|
||||
EXPECT_EQ(10000u, source.bytes_per_second());
|
||||
// We're at 1 fps, so all packets should be generated on first call, giving 10
|
||||
// packets of each 1000 bytes, total 10000 bytes.
|
||||
TestVideoSender(&sender, 1, 9, 400, 10000);
|
||||
@ -786,8 +788,9 @@ TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s_Offset) {
|
||||
// 1 fps, 80 kbps, offset 0.5 of a frame period, ==0.5s in this case.
|
||||
VideoSender sender(0, NULL, 1.0f, 80, 0x1234, 500);
|
||||
EXPECT_EQ(10000u, sender.bytes_per_second());
|
||||
VideoSource source(0, 1.0f, 80, 0x1234, 500);
|
||||
PacketSender sender(NULL, &source);
|
||||
EXPECT_EQ(10000u, source.bytes_per_second());
|
||||
// 499ms, no output.
|
||||
TestVideoSender(&sender, 499, 0, 0, 0);
|
||||
// 500ms, first frame (this is the offset we set), 10 packets of 1000 bytes.
|
||||
@ -806,8 +809,9 @@ TEST(BweTestFramework_VideoSenderTest, Fps1Kbps80_1s_Offset) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps50Kpbs80_11s) {
|
||||
// 50 fps, 80 kbps.
|
||||
VideoSender sender(0, NULL, 50.0f, 80, 0x1234, 0);
|
||||
EXPECT_EQ(10000u, sender.bytes_per_second());
|
||||
VideoSource source(0, 50.0f, 80, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source);
|
||||
EXPECT_EQ(10000u, source.bytes_per_second());
|
||||
// 9998ms, should see 500 frames, 200 byte payloads, total 100000 bytes.
|
||||
TestVideoSender(&sender, 9998, 500, 200, 100000);
|
||||
// 9999ms, nothing.
|
||||
@ -822,8 +826,9 @@ TEST(BweTestFramework_VideoSenderTest, Fps50Kpbs80_11s) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps10Kpbs120_1s) {
|
||||
// 20 fps, 120 kbps.
|
||||
VideoSender sender(0, NULL, 20.0f, 120, 0x1234, 0);
|
||||
EXPECT_EQ(15000u, sender.bytes_per_second());
|
||||
VideoSource source(0, 20.0f, 120, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source);
|
||||
EXPECT_EQ(15000u, source.bytes_per_second());
|
||||
// 498ms, 10 frames with 750 byte payloads, total 7500 bytes.
|
||||
TestVideoSender(&sender, 498, 10, 750, 7500);
|
||||
// 499ms, nothing.
|
||||
@ -838,8 +843,9 @@ TEST(BweTestFramework_VideoSenderTest, Fps10Kpbs120_1s) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, Fps30Kbps800_20s) {
|
||||
// 20 fps, 820 kbps.
|
||||
VideoSender sender(0, NULL, 25.0f, 820, 0x1234, 0);
|
||||
EXPECT_EQ(102500u, sender.bytes_per_second());
|
||||
VideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source);
|
||||
EXPECT_EQ(102500u, source.bytes_per_second());
|
||||
// 9998ms, 250 frames. 820 kbps = 102500 bytes/s, so total should be 1025000.
|
||||
// Each frame is 102500/25=4100 bytes, or 5 packets (4 @1000 bytes, 1 @100),
|
||||
// so packet count should be 5*250=1250 and last packet of each frame has
|
||||
@ -859,8 +865,9 @@ TEST(BweTestFramework_VideoSenderTest, Fps30Kbps800_20s) {
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
// 1 fps, 80 kbps, 250ms offset.
|
||||
VideoSender sender1(0, NULL, 1.0f, 80, 0x1234, 250);
|
||||
EXPECT_EQ(10000u, sender1.bytes_per_second());
|
||||
VideoSource source1(0, 1.0f, 80, 0x1234, 250);
|
||||
PacketSender sender1(NULL, &source1);
|
||||
EXPECT_EQ(10000u, source1.bytes_per_second());
|
||||
Packets packets;
|
||||
// Generate some packets, verify they are sorted.
|
||||
sender1.RunFor(999, &packets);
|
||||
@ -874,8 +881,9 @@ TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
EXPECT_EQ(18u, packets.size());
|
||||
|
||||
// Another sender, 2 fps, 160 kbps, 150ms offset
|
||||
VideoSender sender2(0, NULL, 2.0f, 160, 0x2234, 150);
|
||||
EXPECT_EQ(20000u, sender2.bytes_per_second());
|
||||
VideoSource source2(0, 2.0f, 160, 0x2234, 150);
|
||||
PacketSender sender2(NULL, &source2);
|
||||
EXPECT_EQ(20000u, source2.bytes_per_second());
|
||||
// Generate some packets, verify that they are merged with the packets already
|
||||
// on the list.
|
||||
sender2.RunFor(999, &packets);
|
||||
@ -888,34 +896,38 @@ TEST(BweTestFramework_VideoSenderTest, TestAppendInOrder) {
|
||||
}
|
||||
|
||||
TEST(BweTestFramework_VideoSenderTest, FeedbackIneffective) {
|
||||
VideoSender sender(0, NULL, 25.0f, 820, 0x1234, 0);
|
||||
EXPECT_EQ(102500u, sender.bytes_per_second());
|
||||
VideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
PacketSender sender(NULL, &source);
|
||||
|
||||
EXPECT_EQ(102500u, source.bytes_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
|
||||
// Make sure feedback has no effect on a regular video sender.
|
||||
PacketSender::Feedback feedback = { 512000 };
|
||||
sender.GiveFeedback(feedback);
|
||||
EXPECT_EQ(102500u, sender.bytes_per_second());
|
||||
EXPECT_EQ(102500u, source.bytes_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
}
|
||||
|
||||
TEST(BweTestFramework_AdaptiveVideoSenderTest, FeedbackChangesBitrate) {
|
||||
AdaptiveVideoSender sender(0, NULL, 25.0f, 820, 0x1234, 0);
|
||||
EXPECT_EQ(102500u, sender.bytes_per_second());
|
||||
AdaptiveVideoSource source(0, 25.0f, 820, 0x1234, 0);
|
||||
RegularVideoSender sender(NULL, &source, 820);
|
||||
EXPECT_EQ(102500u, source.bytes_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
|
||||
// Make sure we can reduce the bitrate.
|
||||
PacketSender::Feedback feedback = { 512000 };
|
||||
sender.GiveFeedback(feedback);
|
||||
EXPECT_EQ(64000u, sender.bytes_per_second());
|
||||
EXPECT_EQ(64000u, source.bytes_per_second());
|
||||
TestVideoSender(&sender, 9998, 750, 160, 640000);
|
||||
|
||||
// Increase the bitrate to the initial bitrate and verify that the output is
|
||||
// the same.
|
||||
feedback.estimated_bps = 820000;
|
||||
sender.GiveFeedback(feedback);
|
||||
EXPECT_EQ(102500u, sender.bytes_per_second());
|
||||
TestVideoSender(&sender, 9998, 1000, 500, 1025000);
|
||||
Packets packets;
|
||||
sender.RunFor(10000, &packets);
|
||||
EXPECT_EQ(102500u, source.bytes_per_second());
|
||||
}
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
Loading…
Reference in New Issue
Block a user