Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Unified Diff: webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc

Issue 1329083005: Add TransportFeedback adapter, adapting remote feedback to bwe estiamtor (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Bad merge, test issue Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1bf4b1ec3e7df8f03e971f24333b1bcfdd223567
--- /dev/null
+++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <limits>
+#include <vector>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
+#include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
+#include "webrtc/modules/utility/interface/mock/mock_process_thread.h"
+#include "webrtc/system_wrappers/interface/clock.h"
+
+using ::testing::_;
+using ::testing::Invoke;
+
+namespace webrtc {
+namespace test {
+
+class TransportFeedbackAdapterTest : public ::testing::Test {
+ public:
+ TransportFeedbackAdapterTest()
+ : clock_(0),
+ bitrate_estimator_(nullptr),
+ receiver_estimated_bitrate_(0) {}
+
+ virtual ~TransportFeedbackAdapterTest() {}
+
+ virtual void SetUp() {
+ adapter_.reset(new TransportFeedbackAdapter(
+ new RtcpBandwidthObserverAdapter(this), &clock_, &process_thread_));
+
+ bitrate_estimator_ = new MockRemoteBitrateEstimator();
+ EXPECT_CALL(process_thread_, RegisterModule(bitrate_estimator_)).Times(1);
+ adapter_->SetBitrateEstimator(bitrate_estimator_);
+ }
+
+ virtual void TearDown() {
+ EXPECT_CALL(process_thread_, DeRegisterModule(bitrate_estimator_)).Times(1);
+ adapter_.reset();
+ }
+
+ protected:
+ // Proxy class used since TransportFeedbackAdapter will own the instance
+ // passed at construction.
+ class RtcpBandwidthObserverAdapter : public RtcpBandwidthObserver {
+ public:
+ explicit RtcpBandwidthObserverAdapter(TransportFeedbackAdapterTest* owner)
+ : owner_(owner) {}
+
+ void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
+ owner_->receiver_estimated_bitrate_ = bitrate;
+ }
+
+ void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
+ int64_t rtt,
+ int64_t now_ms) override {
+ RTC_NOTREACHED();
+ }
+
+ TransportFeedbackAdapterTest* const owner_;
+ };
+
+ void OnReceivedEstimatedBitrate(uint32_t bitrate) {}
+
+ void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
+ int64_t rtt,
+ int64_t now_ms) {}
+
+ void ComparePacketVectors(const std::vector<PacketInfo>& truth,
+ const std::vector<PacketInfo>& input) {
+ ASSERT_EQ(truth.size(), input.size());
+ size_t len = truth.size();
+ // truth contains the input data for the test, and input is what will be
+ // sent to the bandwidth estimator. truth.arrival_tims_ms is used to
+ // populate the transport feedback messages. As these times may be changed
+ // (because of resolution limits in the packets, and because of the time
+ // base adjustment performed by the TransportFeedbackAdapter at the first
+ // packet, the truth[x].arrival_time and input[x].arrival_time may not be
+ // equal. However, the difference must be the same for all x.
+ int64_t arrival_time_delta =
+ truth[0].arrival_time_ms - input[0].arrival_time_ms;
+ for (size_t i = 0; i < len; ++i) {
+ EXPECT_EQ(truth[i].arrival_time_ms,
+ input[i].arrival_time_ms + arrival_time_delta);
+ EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
+ EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
+ EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
+ EXPECT_EQ(truth[i].was_paced, input[i].was_paced);
+ }
+ }
+
+ // Utility method, to reset arrival_time_ms before adding send time.
+ void OnPacketSent(PacketInfo info) {
+ info.arrival_time_ms = 0;
+ adapter_->OnPacketSent(info);
+ }
+
+ SimulatedClock clock_;
+ MockProcessThread process_thread_;
+ MockRemoteBitrateEstimator* bitrate_estimator_;
+ rtc::scoped_ptr<TransportFeedbackAdapter> adapter_;
+
+ uint32_t receiver_estimated_bitrate_;
+};
+
+TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) {
+ std::vector<PacketInfo> packets;
+ packets.push_back(PacketInfo(100, 200, 0, 1500, true));
+ packets.push_back(PacketInfo(110, 210, 1, 1500, true));
+ packets.push_back(PacketInfo(120, 220, 2, 1500, true));
+ packets.push_back(PacketInfo(130, 230, 3, 1500, true));
+ packets.push_back(PacketInfo(140, 240, 4, 1500, true));
+
+ for (const PacketInfo& packet : packets)
+ OnPacketSent(packet);
+
+ rtcp::TransportFeedback feedback;
+ feedback.WithBase(packets[0].sequence_number,
+ packets[0].arrival_time_ms * 1000);
+
+ for (const PacketInfo& packet : packets) {
+ EXPECT_TRUE(feedback.WithReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ }
+
+ feedback.Build();
+
+ EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
+ .Times(1)
+ .WillOnce(Invoke(
+ [packets, this](const std::vector<PacketInfo>& feedback_vector) {
+ ComparePacketVectors(packets, feedback_vector);
+ }));
+ adapter_->OnTransportFeedback(feedback);
+}
+
+TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) {
+ std::vector<PacketInfo> packets;
+ packets.push_back(PacketInfo(100, 200, 0, 1500, true));
+ packets.push_back(PacketInfo(110, 210, 1, 1500, true));
+ packets.push_back(PacketInfo(120, 220, 2, 1500, true));
+ packets.push_back(PacketInfo(130, 230, 3, 1500, true));
+ packets.push_back(PacketInfo(140, 240, 4, 1500, true));
+
+ const uint16_t kSendSideDropBefore = 1;
+ const uint16_t kReceiveSideDropAfter = 3;
+
+ for (const PacketInfo& packet : packets) {
+ if (packet.sequence_number >= kSendSideDropBefore)
+ OnPacketSent(packet);
+ }
+
+ rtcp::TransportFeedback feedback;
+ feedback.WithBase(packets[0].sequence_number,
+ packets[0].arrival_time_ms * 1000);
+
+ for (const PacketInfo& packet : packets) {
+ if (packet.sequence_number <= kReceiveSideDropAfter) {
+ EXPECT_TRUE(feedback.WithReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ }
+ }
+
+ feedback.Build();
+
+ std::vector<PacketInfo> expected_packets(
+ packets.begin() + kSendSideDropBefore,
+ packets.begin() + kReceiveSideDropAfter + 1);
+
+ EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
+ .Times(1)
+ .WillOnce(Invoke([expected_packets,
+ this](const std::vector<PacketInfo>& feedback_vector) {
+ ComparePacketVectors(expected_packets, feedback_vector);
+ }));
+ adapter_->OnTransportFeedback(feedback);
+}
+
+TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) {
+ int64_t kHighArrivalTimeMs = rtcp::TransportFeedback::kDeltaScaleFactor *
+ static_cast<int64_t>(1 << 8) *
+ static_cast<int64_t>((1 << 23) - 1) / 1000;
+ std::vector<PacketInfo> packets;
+ packets.push_back(PacketInfo(kHighArrivalTimeMs - 64, 200, 0, 1500, true));
+ packets.push_back(PacketInfo(kHighArrivalTimeMs + 64, 210, 1, 1500, true));
+ packets.push_back(PacketInfo(kHighArrivalTimeMs, 220, 2, 1500, true));
+
+ for (const PacketInfo& packet : packets)
+ OnPacketSent(packet);
+
+ for (size_t i = 0; i < packets.size(); ++i) {
+ rtc::scoped_ptr<rtcp::TransportFeedback> feedback(
+ new rtcp::TransportFeedback());
+ feedback->WithBase(packets[i].sequence_number,
+ packets[i].arrival_time_ms * 1000);
+
+ EXPECT_TRUE(feedback->WithReceivedPacket(
+ packets[i].sequence_number, packets[i].arrival_time_ms * 1000));
+
+ rtc::scoped_ptr<rtcp::RawPacket> raw_packet = feedback->Build();
+ feedback = rtcp::TransportFeedback::ParseFrom(raw_packet->Buffer(),
+ raw_packet->Length());
+
+ std::vector<PacketInfo> expected_packets;
+ expected_packets.push_back(packets[i]);
+
+ EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
+ .Times(1)
+ .WillOnce(Invoke([expected_packets, this](
+ const std::vector<PacketInfo>& feedback_vector) {
+ ComparePacketVectors(expected_packets, feedback_vector);
+ }));
+ adapter_->OnTransportFeedback(*feedback.get());
+ }
+}
+
+TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
+ std::vector<PacketInfo> sent_packets;
+ const int64_t kSmallDeltaUs =
+ rtcp::TransportFeedback::kDeltaScaleFactor * ((1 << 8) - 1);
+ const int64_t kLargePositiveDeltaUs =
+ rtcp::TransportFeedback::kDeltaScaleFactor *
+ std::numeric_limits<int16_t>::max();
+ const int64_t kLargeNegativeDeltaUs =
+ rtcp::TransportFeedback::kDeltaScaleFactor *
+ std::numeric_limits<int16_t>::min();
+
+ PacketInfo info(100, 200, 0, 1500, true);
+ sent_packets.push_back(info);
+
+ info.send_time_ms += kSmallDeltaUs / 1000;
+ info.arrival_time_ms += kSmallDeltaUs / 1000;
+ ++info.sequence_number;
+ sent_packets.push_back(info);
+
+ info.send_time_ms += kLargePositiveDeltaUs / 1000;
+ info.arrival_time_ms += kLargePositiveDeltaUs / 1000;
+ ++info.sequence_number;
+ sent_packets.push_back(info);
+
+ info.send_time_ms += kLargeNegativeDeltaUs / 1000;
+ info.arrival_time_ms += kLargeNegativeDeltaUs / 1000;
+ ++info.sequence_number;
+ sent_packets.push_back(info);
+
+ // Too large, delta - will need two feedback messages.
+ info.send_time_ms += (kLargePositiveDeltaUs + 1000) / 1000;
+ info.arrival_time_ms += (kLargePositiveDeltaUs + 1000) / 1000;
+ ++info.sequence_number;
+
+ // Packets will be added to send history.
+ for (const PacketInfo& packet : sent_packets)
+ OnPacketSent(packet);
+ OnPacketSent(info);
+
+ // Create expected feedback and send into adapter.
+ rtc::scoped_ptr<rtcp::TransportFeedback> feedback(
+ new rtcp::TransportFeedback());
+ feedback->WithBase(sent_packets[0].sequence_number,
+ sent_packets[0].arrival_time_ms * 1000);
+
+ for (const PacketInfo& packet : sent_packets) {
+ EXPECT_TRUE(feedback->WithReceivedPacket(packet.sequence_number,
+ packet.arrival_time_ms * 1000));
+ }
+ EXPECT_FALSE(feedback->WithReceivedPacket(info.sequence_number,
+ info.arrival_time_ms * 1000));
+
+ rtc::scoped_ptr<rtcp::RawPacket> raw_packet = feedback->Build();
+ feedback = rtcp::TransportFeedback::ParseFrom(raw_packet->Buffer(),
+ raw_packet->Length());
+
+ std::vector<PacketInfo> received_feedback;
+
+ EXPECT_TRUE(feedback.get() != nullptr);
+ EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
+ .Times(1)
+ .WillOnce(Invoke([sent_packets, &received_feedback](
+ const std::vector<PacketInfo>& feedback_vector) {
+ EXPECT_EQ(sent_packets.size(), feedback_vector.size());
+ received_feedback = feedback_vector;
+ }));
+ adapter_->OnTransportFeedback(*feedback.get());
+
+ // Create a new feedback message and add the trailing item.
+ feedback.reset(new rtcp::TransportFeedback());
+ feedback->WithBase(info.sequence_number, info.arrival_time_ms * 1000);
+ EXPECT_TRUE(feedback->WithReceivedPacket(info.sequence_number,
+ info.arrival_time_ms * 1000));
+ raw_packet = feedback->Build();
+ feedback = rtcp::TransportFeedback::ParseFrom(raw_packet->Buffer(),
+ raw_packet->Length());
+
+ EXPECT_TRUE(feedback.get() != nullptr);
+ EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
+ .Times(1)
+ .WillOnce(Invoke(
+ [&received_feedback](const std::vector<PacketInfo>& feedback_vector) {
+ EXPECT_EQ(1u, feedback_vector.size());
+ received_feedback.push_back(feedback_vector[0]);
+ }));
+ adapter_->OnTransportFeedback(*feedback.get());
+
+ sent_packets.push_back(info);
+
+ ComparePacketVectors(sent_packets, received_feedback);
+}
+
+} // namespace test
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698