diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc index a1312baea..304368037 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.cc @@ -10,9 +10,11 @@ #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test.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_framework.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" +#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" @@ -23,13 +25,13 @@ namespace webrtc { namespace testing { namespace bwe { -class TestedEstimator : public RemoteBitrateObserver { +class PacketReceiver : public RemoteBitrateObserver { public: static const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; static const int kDelayPlotIntervalMs = 100; - TestedEstimator(const string& test_name, - const BweTestConfig::EstimatorConfig& config) + PacketReceiver(const string& test_name, + const BweTestConfig::EstimatorConfig& config) : debug_name_(config.debug_name), delay_log_prefix_(), estimate_log_prefix_(), @@ -38,9 +40,12 @@ class TestedEstimator : public RemoteBitrateObserver { plot_estimate_(config.plot_estimate), clock_(0), stats_(), + recv_stats_(ReceiveStatistics::Create(&clock_)), latest_estimate_bps_(-1), estimator_(config.estimator_factory->Create( - this, &clock_, config.control_type, + this, + &clock_, + config.control_type, kRemoteBitrateEstimatorMinBitrateBps)), baseline_(BaseLineFileInterface::Create(test_name + "_" + debug_name_, config.update_baseline)) { @@ -60,6 +65,8 @@ class TestedEstimator : public RemoteBitrateObserver { void EatPacket(const Packet& packet) { BWE_TEST_LOGGING_CONTEXT(debug_name_); + recv_stats_->IncomingPacket(packet.header(), packet.payload_size(), false); + latest_estimate_bps_ = -1; // We're treating the send time (from previous filter) as the arrival @@ -89,12 +96,19 @@ class TestedEstimator : public RemoteBitrateObserver { ASSERT_TRUE(packet_time_ms == clock_.TimeInMilliseconds()); } - bool CheckEstimate(PacketSender::Feedback* feedback) { + bool GetFeedback(PacketSender::Feedback* feedback) { assert(feedback); BWE_TEST_LOGGING_CONTEXT(debug_name_); uint32_t estimated_bps = 0; if (LatestEstimate(&estimated_bps)) { feedback->estimated_bps = estimated_bps; + StatisticianMap statisticians = recv_stats_->GetActiveStatisticians(); + if (statisticians.empty()) { + feedback->report_block = RTCPReportBlock(); + } else { + feedback->report_block = + BuildReportBlock(statisticians.begin()->second); + } baseline_->Estimate(clock_.TimeInMilliseconds(), estimated_bps); double estimated_kbps = static_cast(estimated_bps) / 1000.0; @@ -123,6 +137,18 @@ class TestedEstimator : public RemoteBitrateObserver { } private: + static RTCPReportBlock BuildReportBlock(StreamStatistician* statistician) { + RTCPReportBlock report_block; + RtcpStatistics stats; + if (!statistician->GetStatistics(&stats, true)) + return report_block; + report_block.fractionLost = stats.fraction_lost; + report_block.cumulativeLost = stats.cumulative_lost; + report_block.extendedHighSeqNum = stats.extended_max_sequence_number; + report_block.jitter = stats.jitter; + return report_block; + } + bool LatestEstimate(uint32_t* estimate_bps) { if (latest_estimate_bps_ < 0) { vector ssrcs; @@ -144,11 +170,12 @@ class TestedEstimator : public RemoteBitrateObserver { bool plot_estimate_; SimulatedClock clock_; Stats stats_; + scoped_ptr recv_stats_; int64_t latest_estimate_bps_; scoped_ptr estimator_; scoped_ptr baseline_; - DISALLOW_IMPLICIT_CONSTRUCTORS(TestedEstimator); + DISALLOW_IMPLICIT_CONSTRUCTORS(PacketReceiver); }; class PacketProcessorRunner { @@ -242,8 +269,8 @@ void BweTest::SetupTestFromConfig(const BweTestConfig& config) { for (vector::const_iterator it = config.estimator_configs.begin(); it != config.estimator_configs.end(); ++it) { - estimators_.insert(std::make_pair(it->flow_id, new TestedEstimator( - test_name, *it))); + estimators_.insert( + std::make_pair(it->flow_id, new PacketReceiver(test_name, *it))); } BWE_TEST_LOGGING_GLOBAL_ENABLE(false); } @@ -277,7 +304,7 @@ void BweTest::VerboseLogging(bool enable) { } void BweTest::GiveFeedbackToAffectedSenders(int flow_id, - TestedEstimator* estimator) { + PacketReceiver* estimator) { std::list affected_senders; for (std::vector::iterator psit = senders_.begin(); psit != senders_.end(); ++psit) { @@ -287,7 +314,7 @@ void BweTest::GiveFeedbackToAffectedSenders(int flow_id, } } PacketSender::Feedback feedback = {0}; - if (estimator->CheckEstimate(&feedback) && !affected_senders.empty()) { + if (estimator->GetFeedback(&feedback) && !affected_senders.empty()) { // Allocate the bitrate evenly between the senders. feedback.estimated_bps /= affected_senders.size(); for (std::list::iterator psit = affected_senders.begin(); diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h index d02e06455..e3e0097dc 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test.h @@ -86,7 +86,7 @@ struct BweTestConfig { std::vector estimator_configs; }; -class TestedEstimator; +class PacketReceiver; class PacketProcessorRunner; class BweTest : public PacketProcessorListener { @@ -104,11 +104,11 @@ class BweTest : public PacketProcessorListener { std::string GetTestName() const; private: - typedef std::map EstimatorMap; + typedef std::map EstimatorMap; void FindPacketsToProcess(const FlowIds& flow_ids, Packets* in, Packets* out); - void GiveFeedbackToAffectedSenders(int flow_id, TestedEstimator* estimator); + void GiveFeedbackToAffectedSenders(int flow_id, PacketReceiver* estimator); int64_t run_time_ms_; int64_t time_now_ms_; diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc index 246c7711a..73aa407e1 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.cc @@ -538,10 +538,8 @@ void TraceBasedDeliveryFilter::ProceedToNextSlot() { PacketSender::PacketSender(PacketProcessorListener* listener) : PacketProcessor(listener, true) {} -PacketSender::PacketSender(PacketProcessorListener* listener, - const FlowIds& flow_ids) - : PacketProcessor(listener, flow_ids, true) { - +PacketSender::PacketSender(PacketProcessorListener* listener, int flow_id) + : PacketProcessor(listener, FlowIds(1, flow_id), true) { } VideoSender::VideoSender(int flow_id, @@ -550,7 +548,7 @@ VideoSender::VideoSender(int flow_id, uint32_t kbps, uint32_t ssrc, int64_t first_frame_offset_ms) - : PacketSender(listener, FlowIds(1, flow_id)), + : PacketSender(listener, flow_id), kMaxPayloadSizeBytes(1200), kTimestampBase(0xff80ff00ul), frame_period_ms_(1000.0 / fps), @@ -677,17 +675,73 @@ uint32_t PeriodicKeyFrameSender::NextPacketSize(uint32_t frame_size, return std::min(avg_size, remaining_payload); } +RegularVideoSender::RegularVideoSender(PacketProcessorListener* listener, + uint32_t kbps, + AdaptiveVideoSender* source) + // 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()[0]), + clock_(0), + start_of_run_ms_(0), + bitrate_controller_(BitrateController::CreateBitrateController(&clock_, + false)), + feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()), + source_(source), + modules_() { + const int kMinBitrateBps = 10000; + const int kMaxBitrateBps = 20000000; + bitrate_controller_->SetBitrateObserver(this, 1000 * kbps, kMinBitrateBps, + kMaxBitrateBps); + modules_.push_back(bitrate_controller_.get()); +} + +RegularVideoSender::~RegularVideoSender() { +} + +void RegularVideoSender::GiveFeedback(const Feedback& feedback) { + feedback_observer_->OnReceivedEstimatedBitrate(feedback.estimated_bps); + ReportBlockList report_blocks; + report_blocks.push_back(feedback.report_block); + feedback_observer_->OnReceivedRtcpReceiverReport(report_blocks, 0, + clock_.TimeInMilliseconds()); + bitrate_controller_->Process(); +} + +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); +} + +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); + std::stringstream ss; + ss << "SendEstimate_" << flow_ids()[0] << "#1"; + BWE_TEST_LOGGING_PLOT(ss.str(), clock_.TimeInMilliseconds(), + target_bitrate_bps / 1000); +} + PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, uint32_t kbps, AdaptiveVideoSender* source) // 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()), - clock_(0), - start_of_run_ms_(0), - pacer_(&clock_, this, kbps, PacedSender::kDefaultPaceMultiplier* kbps, 0), - source_(source) { + : RegularVideoSender(listener, kbps, source), + pacer_(&clock_, + this, + kbps, + PacedSender::kDefaultPaceMultiplier* kbps, + 0) { + modules_.push_back(&pacer_); +} + +PacedVideoSender::~PacedVideoSender() { } void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) { @@ -698,18 +752,18 @@ void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) { int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms; Packets::iterator it = generated_packets.begin(); while (clock_.TimeInMilliseconds() <= end_time_ms) { - int64_t time_until_process_ms = pacer_.TimeUntilNextProcess(); - if (time_until_process_ms < 0) - time_until_process_ms = 0; + int64_t time_until_process_ms = TimeUntilNextProcess(modules_); + int time_until_packet_ms = time_ms; if (it != generated_packets.end()) time_until_packet_ms = (it->send_time_us() + 500) / 1000 - clock_.TimeInMilliseconds(); assert(time_until_packet_ms >= 0); + int time_until_next_event_ms = time_until_packet_ms; - if (time_until_process_ms < time_until_packet_ms && - pacer_.QueueSizePackets() > 0) + if (time_until_process_ms < time_until_packet_ms) { time_until_next_event_ms = time_until_process_ms; + } if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) { clock_.AdvanceTimeMilliseconds(end_time_ms - clock_.TimeInMilliseconds()); @@ -718,7 +772,7 @@ void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) { clock_.AdvanceTimeMilliseconds(time_until_next_event_ms); if (time_until_process_ms < time_until_packet_ms) { // Time to process. - pacer_.Process(); + CallProcess(modules_); } else { // Time to send next packet to pacer. pacer_.SendPacket(PacedSender::kNormalPriority, @@ -738,6 +792,27 @@ void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) { QueuePackets(in_out, end_time_ms * 1000); } +int64_t PacedVideoSender::TimeUntilNextProcess( + const std::list& modules) { + int64_t time_until_next_process_ms = 10; + for (auto* module : modules) { + int64_t next_process_ms = module->TimeUntilNextProcess(); + if (next_process_ms < time_until_next_process_ms) + time_until_next_process_ms = next_process_ms; + } + if (time_until_next_process_ms < 0) + time_until_next_process_ms = 0; + return time_until_next_process_ms; +} + +void PacedVideoSender::CallProcess(const std::list& modules) { + for (auto* module : modules) { + if (module->TimeUntilNextProcess() <= 0) { + module->Process(); + } + } +} + void PacedVideoSender::QueuePackets(Packets* batch, int64_t end_of_batch_time_us) { queue_.merge(*batch); @@ -755,14 +830,6 @@ void PacedVideoSender::QueuePackets(Packets* batch, batch->merge(to_transfer); } -void PacedVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) { - source_->GiveFeedback(feedback); - pacer_.UpdateBitrate( - feedback.estimated_bps / 1000, - PacedSender::kDefaultPaceMultiplier * feedback.estimated_bps / 1000, - 0); -} - bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms, @@ -786,6 +853,15 @@ bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, size_t PacedVideoSender::TimeToSendPadding(size_t bytes) { return 0; } + +void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, + uint8_t fraction_lost, + int64_t rtt) { + RegularVideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); + pacer_.UpdateBitrate( + target_bitrate_bps / 1000, + PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0); +} } // namespace bwe } // namespace testing } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h index a42266c49..1efae4fd3 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h +++ b/webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h @@ -21,13 +21,18 @@ #include #include +#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" #include "webrtc/modules/interface/module_common_types.h" #include "webrtc/modules/pacing/include/paced_sender.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" namespace webrtc { + +class RtcpBandwidthObserver; + namespace testing { namespace bwe { @@ -365,10 +370,11 @@ class PacketSender : public PacketProcessor { public: struct Feedback { uint32_t estimated_bps; + RTCPReportBlock report_block; }; explicit PacketSender(PacketProcessorListener* listener); - PacketSender(PacketProcessorListener* listener, const FlowIds& flow_ids); + PacketSender(PacketProcessorListener* listener, int flow_id); virtual ~PacketSender() {} virtual uint32_t GetCapacityKbps() const { return 0; } @@ -462,16 +468,45 @@ class PeriodicKeyFrameSender : public AdaptiveVideoSender { DISALLOW_IMPLICIT_CONSTRUCTORS(PeriodicKeyFrameSender); }; -class PacedVideoSender : public PacketSender, public PacedSender::Callback { +class RegularVideoSender : public PacketSender, public BitrateObserver { public: - PacedVideoSender(PacketProcessorListener* listener, - uint32_t kbps, AdaptiveVideoSender* source); - virtual ~PacedVideoSender() {} + RegularVideoSender(PacketProcessorListener* listener, + uint32_t kbps, + AdaptiveVideoSender* source); + virtual ~RegularVideoSender(); virtual int GetFeedbackIntervalMs() const OVERRIDE { return 100; } virtual void GiveFeedback(const Feedback& feedback) OVERRIDE; virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE; + // Implements BitrateObserver. + virtual void OnNetworkChanged(uint32_t target_bitrate_bps, + uint8_t fraction_lost, + int64_t rtt) OVERRIDE; + + protected: + static const int64_t kInitialTimeMs = 0; + SimulatedClock clock_; + int64_t start_of_run_ms_; + scoped_ptr bitrate_controller_; + scoped_ptr feedback_observer_; + AdaptiveVideoSender* source_; + std::list modules_; + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(RegularVideoSender); +}; + +class PacedVideoSender : public RegularVideoSender, + public PacedSender::Callback { + public: + PacedVideoSender(PacketProcessorListener* listener, + uint32_t kbps, + AdaptiveVideoSender* source); + virtual ~PacedVideoSender(); + + virtual void RunFor(int64_t time_ms, Packets* in_out) OVERRIDE; + // Implements PacedSender::Callback. virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, @@ -479,6 +514,11 @@ class PacedVideoSender : public PacketSender, public PacedSender::Callback { bool retransmission) OVERRIDE; virtual size_t TimeToSendPadding(size_t bytes) OVERRIDE; + // Implements BitrateObserver. + virtual void OnNetworkChanged(uint32_t target_bitrate_bps, + uint8_t fraction_lost, + int64_t rtt) OVERRIDE; + private: class ProbingPacedSender : public PacedSender { public: @@ -496,15 +536,13 @@ class PacedVideoSender : public PacketSender, public PacedSender::Callback { virtual bool ProbingExperimentIsEnabled() const OVERRIDE { return true; } }; + int64_t TimeUntilNextProcess(const std::list& modules); + void CallProcess(const std::list& modules); void QueuePackets(Packets* batch, int64_t end_of_batch_time_us); - static const int64_t kInitialTimeMs = 0; - SimulatedClock clock_; - int64_t start_of_run_ms_; ProbingPacedSender pacer_; - Packets pacer_queue_; Packets queue_; - AdaptiveVideoSender* source_; + Packets pacer_queue_; DISALLOW_IMPLICIT_CONSTRUCTORS(PacedVideoSender); };