Add probe logging to RtcEventLog.
In this CL:
- Add message BweProbeCluster and BweProbeResult to rtc_event_log.proto.
- Add corresponding log functions to RtcEventLog.
- Add optional field |probe_cluster_id| to RtpPacket message and added
an overload function to log with this information.
- Propagate the probe_cluster_id to where RTP packets are logged.
BUG=webrtc:6984
Review-Url: https://codereview.webrtc.org/2666533002
Cr-Commit-Position: refs/heads/master@{#16857}
diff --git a/webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h b/webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h
index 7366c29..fcc5700 100644
--- a/webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h
+++ b/webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h
@@ -46,6 +46,13 @@
const uint8_t* header,
size_t packet_length));
+ MOCK_METHOD5(LogRtpHeader,
+ void(PacketDirection direction,
+ MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id));
+
MOCK_METHOD4(LogRtcpPacket,
void(PacketDirection direction,
MediaType media_type,
@@ -64,6 +71,13 @@
MOCK_METHOD1(LogAudioNetworkAdaptation,
void(const AudioNetworkAdaptor::EncoderRuntimeConfig& config));
+
+ MOCK_METHOD4(LogProbeClusterCreated,
+ void(int id, int bitrate_bps, int min_probes, int min_bytes));
+
+ MOCK_METHOD2(LogProbeResultSuccess, void(int id, int bitrate_bps));
+ MOCK_METHOD2(LogProbeResultFailure,
+ void(int id, ProbeFailureReason failure_reason));
};
} // namespace webrtc
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log.cc b/webrtc/logging/rtc_event_log/rtc_event_log.cc
index 88f6b3a..902ce42 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log.cc
+++ b/webrtc/logging/rtc_event_log/rtc_event_log.cc
@@ -69,6 +69,11 @@
MediaType media_type,
const uint8_t* header,
size_t packet_length) override;
+ void LogRtpHeader(PacketDirection direction,
+ MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id) override;
void LogRtcpPacket(PacketDirection direction,
MediaType media_type,
const uint8_t* packet,
@@ -81,9 +86,19 @@
BandwidthUsage detector_state) override;
void LogAudioNetworkAdaptation(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) override;
+ void LogProbeClusterCreated(int id,
+ int bitrate_bps,
+ int min_probes,
+ int min_bytes) override;
+ void LogProbeResultSuccess(int id, int bitrate_bps) override;
+ void LogProbeResultFailure(int id,
+ ProbeFailureReason failure_reason) override;
private:
void StoreEvent(std::unique_ptr<rtclog::Event>* event);
+ void LogProbeResult(int id,
+ rtclog::BweProbeResult::ResultType result,
+ int bitrate_bps);
// Message queue for passing control messages to the logging thread.
SwapQueue<RtcEventLogHelperThread::ControlMessage> message_queue_;
@@ -145,6 +160,20 @@
return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
}
+rtclog::BweProbeResult::ResultType ConvertProbeResultType(
+ ProbeFailureReason failure_reason) {
+ switch (failure_reason) {
+ case kInvalidSendReceiveInterval:
+ return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL;
+ case kInvalidSendReceiveRatio:
+ return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO;
+ case kTimeout:
+ return rtclog::BweProbeResult::TIMEOUT;
+ }
+ RTC_NOTREACHED();
+ return rtclog::BweProbeResult::SUCCESS;
+}
+
// The RTP and RTCP buffers reserve space for twice the expected number of
// sent packets because they also contain received packets.
static const int kEventsPerSecond = 1000;
@@ -354,6 +383,15 @@
MediaType media_type,
const uint8_t* header,
size_t packet_length) {
+ LogRtpHeader(direction, media_type, header, packet_length,
+ PacedPacketInfo::kNotAProbe);
+}
+
+void RtcEventLogImpl::LogRtpHeader(PacketDirection direction,
+ MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id) {
// Read header length (in bytes) from packet data.
if (packet_length < 12u) {
return; // Don't read outside the packet.
@@ -377,6 +415,8 @@
rtp_event->mutable_rtp_packet()->set_type(ConvertMediaType(media_type));
rtp_event->mutable_rtp_packet()->set_packet_length(packet_length);
rtp_event->mutable_rtp_packet()->set_header(header, header_length);
+ if (probe_cluster_id != PacedPacketInfo::kNotAProbe)
+ rtp_event->mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id);
StoreEvent(&rtp_event);
}
@@ -486,6 +526,48 @@
StoreEvent(&event);
}
+void RtcEventLogImpl::LogProbeClusterCreated(int id,
+ int bitrate_bps,
+ int min_probes,
+ int min_bytes) {
+ std::unique_ptr<rtclog::Event> event(new rtclog::Event());
+ event->set_timestamp_us(rtc::TimeMicros());
+ event->set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
+
+ auto probe_cluster = event->mutable_probe_cluster();
+ probe_cluster->set_id(id);
+ probe_cluster->set_bitrate_bps(bitrate_bps);
+ probe_cluster->set_min_packets(min_probes);
+ probe_cluster->set_min_bytes(min_bytes);
+ StoreEvent(&event);
+}
+
+void RtcEventLogImpl::LogProbeResultSuccess(int id, int bitrate_bps) {
+ LogProbeResult(id, rtclog::BweProbeResult::SUCCESS, bitrate_bps);
+}
+
+void RtcEventLogImpl::LogProbeResultFailure(int id,
+ ProbeFailureReason failure_reason) {
+ rtclog::BweProbeResult::ResultType result =
+ ConvertProbeResultType(failure_reason);
+ LogProbeResult(id, result, -1);
+}
+
+void RtcEventLogImpl::LogProbeResult(int id,
+ rtclog::BweProbeResult::ResultType result,
+ int bitrate_bps) {
+ std::unique_ptr<rtclog::Event> event(new rtclog::Event());
+ event->set_timestamp_us(rtc::TimeMicros());
+ event->set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
+
+ auto probe_result = event->mutable_probe_result();
+ probe_result->set_id(id);
+ probe_result->set_result(result);
+ if (result == rtclog::BweProbeResult::SUCCESS)
+ probe_result->set_bitrate_bps(bitrate_bps);
+ StoreEvent(&event);
+}
+
void RtcEventLogImpl::StoreEvent(std::unique_ptr<rtclog::Event>* event) {
if (!event_queue_.Insert(event)) {
LOG(LS_ERROR) << "WebRTC event log queue full. Dropping event.";
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log.h b/webrtc/logging/rtc_event_log/rtc_event_log.h
index f1bbcbb..ccb37b3 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log.h
+++ b/webrtc/logging/rtc_event_log/rtc_event_log.h
@@ -36,6 +36,11 @@
enum class MediaType;
enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket };
+enum ProbeFailureReason {
+ kInvalidSendReceiveInterval,
+ kInvalidSendReceiveRatio,
+ kTimeout
+};
class RtcEventLog {
public:
@@ -102,6 +107,14 @@
const uint8_t* header,
size_t packet_length) = 0;
+ // Same as above but used on the sender side to log packets that are part of
+ // a probe cluster.
+ virtual void LogRtpHeader(PacketDirection direction,
+ MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id) = 0;
+
// Logs an incoming or outgoing RTCP packet.
virtual void LogRtcpPacket(PacketDirection direction,
MediaType media_type,
@@ -124,6 +137,19 @@
virtual void LogAudioNetworkAdaptation(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) = 0;
+ // Logs when a probe cluster is created.
+ virtual void LogProbeClusterCreated(int id,
+ int bitrate_bps,
+ int min_probes,
+ int min_bytes) = 0;
+
+ // Logs the result of a successful probing attempt.
+ virtual void LogProbeResultSuccess(int id, int bitrate_bps) = 0;
+
+ // Logs the result of an unsuccessful probing attempt.
+ virtual void LogProbeResultFailure(int id,
+ ProbeFailureReason failure_reason) = 0;
+
// Reads an RtcEventLog file and returns true when reading was successful.
// The result is stored in the given EventStream object.
// The order of the events in the EventStream is implementation defined.
@@ -157,6 +183,11 @@
MediaType media_type,
const uint8_t* header,
size_t packet_length) override {}
+ void LogRtpHeader(PacketDirection direction,
+ MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id) override {}
void LogRtcpPacket(PacketDirection direction,
MediaType media_type,
const uint8_t* packet,
@@ -169,6 +200,13 @@
BandwidthUsage detector_state) override {}
void LogAudioNetworkAdaptation(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) override {}
+ void LogProbeClusterCreated(int id,
+ int bitrate_bps,
+ int min_probes,
+ int min_bytes) override{};
+ void LogProbeResultSuccess(int id, int bitrate_bps) override{};
+ void LogProbeResultFailure(int id,
+ ProbeFailureReason failure_reason) override{};
};
} // namespace webrtc
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log.proto b/webrtc/logging/rtc_event_log/rtc_event_log.proto
index 21f64223..26d55a7 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log.proto
+++ b/webrtc/logging/rtc_event_log/rtc_event_log.proto
@@ -38,6 +38,8 @@
AUDIO_RECEIVER_CONFIG_EVENT = 10;
AUDIO_SENDER_CONFIG_EVENT = 11;
AUDIO_NETWORK_ADAPTATION_EVENT = 16;
+ BWE_PROBE_CLUSTER_CREATED_EVENT = 17;
+ BWE_PROBE_RESULT_EVENT = 18;
}
// required - Indicates the type of this event
@@ -72,6 +74,12 @@
// optional - but required if type == AUDIO_NETWORK_ADAPTATION_EVENT
optional AudioNetworkAdaptation audio_network_adaptation = 16;
+
+ // optional - but required if type == BWE_PROBE_CLUSTER_CREATED_EVENT
+ optional BweProbeCluster probe_cluster = 17;
+
+ // optional - but required if type == BWE_PROBE_RESULT_EVENT
+ optional BweProbeResult probe_result = 18;
}
message RtpPacket {
@@ -87,6 +95,9 @@
// required - The RTP header only.
optional bytes header = 4;
+ // optional - The probe cluster id.
+ optional uint32 probe_cluster_id = 5;
+
// Do not add code to log user payload data without a privacy review!
}
@@ -271,3 +282,35 @@
// Number of audio channels that each encoded packet consists of.
optional uint32 num_channels = 6;
}
+
+message BweProbeCluster {
+ // required - The id of this probe cluster.
+ optional uint32 id = 1;
+
+ // required - The bitrate in bps that this probe cluster is meant to probe.
+ optional uint64 bitrate_bps = 2;
+
+ // required - The minimum number of packets used to probe the given bitrate.
+ optional uint32 min_packets = 3;
+
+ // required - The minimum number of bytes used to probe the given bitrate.
+ optional uint32 min_bytes = 4;
+}
+
+message BweProbeResult {
+ // required - The id of this probe cluster.
+ optional uint32 id = 1;
+
+ enum ResultType {
+ SUCCESS = 0;
+ INVALID_SEND_RECEIVE_INTERVAL = 1;
+ INVALID_SEND_RECEIVE_RATIO = 2;
+ TIMEOUT = 3;
+ }
+
+ // required - The result of this probing attempt.
+ optional ResultType result = 2;
+
+ // optional - but required if result == SUCCESS. The resulting bitrate in bps.
+ optional uint64 bitrate_bps = 3;
+}
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc b/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc
index 713d4fc..a0cc642 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc
+++ b/webrtc/logging/rtc_event_log/rtc_event_log_parser.cc
@@ -83,6 +83,10 @@
return ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT;
case rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT:
return ParsedRtcEventLog::EventType::AUDIO_NETWORK_ADAPTATION_EVENT;
+ case rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT:
+ return ParsedRtcEventLog::EventType::BWE_PROBE_CLUSTER_CREATED_EVENT;
+ case rtclog::Event::BWE_PROBE_RESULT_EVENT:
+ return ParsedRtcEventLog::EventType::BWE_PROBE_RESULT_EVENT;
}
RTC_NOTREACHED();
return ParsedRtcEventLog::EventType::UNKNOWN_EVENT;
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_parser.h b/webrtc/logging/rtc_event_log/rtc_event_log_parser.h
index 739ccee..1460a4c 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log_parser.h
+++ b/webrtc/logging/rtc_event_log/rtc_event_log_parser.h
@@ -48,7 +48,9 @@
VIDEO_SENDER_CONFIG_EVENT = 9,
AUDIO_RECEIVER_CONFIG_EVENT = 10,
AUDIO_SENDER_CONFIG_EVENT = 11,
- AUDIO_NETWORK_ADAPTATION_EVENT = 16
+ AUDIO_NETWORK_ADAPTATION_EVENT = 16,
+ BWE_PROBE_CLUSTER_CREATED_EVENT = 17,
+ BWE_PROBE_RESULT_EVENT = 18
};
// Reads an RtcEventLog file and returns true if parsing was successful.
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_unittest.cc b/webrtc/logging/rtc_event_log/rtc_event_log_unittest.cc
index ae264aa..71c588c 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log_unittest.cc
+++ b/webrtc/logging/rtc_event_log/rtc_event_log_unittest.cc
@@ -588,6 +588,148 @@
remove(temp_filename.c_str());
}
+TEST(RtcEventLogTest, LogProbeClusterCreatedAndReadBack) {
+ Random prng(794613);
+
+ int bitrate_bps0 = prng.Rand(0, 10000000);
+ int bitrate_bps1 = prng.Rand(0, 10000000);
+ int bitrate_bps2 = prng.Rand(0, 10000000);
+ int min_probes0 = prng.Rand(0, 100);
+ int min_probes1 = prng.Rand(0, 100);
+ int min_probes2 = prng.Rand(0, 100);
+ int min_bytes0 = prng.Rand(0, 10000);
+ int min_bytes1 = prng.Rand(0, 10000);
+ int min_bytes2 = prng.Rand(0, 10000);
+
+ // Find the name of the current test, in order to use it as a temporary
+ // filename.
+ auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+ const std::string temp_filename =
+ test::OutputPath() + test_info->test_case_name() + test_info->name();
+
+ rtc::ScopedFakeClock fake_clock;
+ fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
+ std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
+
+ log_dumper->StartLogging(temp_filename, 10000000);
+ log_dumper->LogProbeClusterCreated(0, bitrate_bps0, min_probes0, min_bytes0);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeClusterCreated(1, bitrate_bps1, min_probes1, min_bytes1);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeClusterCreated(2, bitrate_bps2, min_probes2, min_bytes2);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->StopLogging();
+
+ // Read the generated file from disk.
+ ParsedRtcEventLog parsed_log;
+ ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
+
+ // Verify that what we read back from the event log is the same as
+ // what we wrote down.
+ EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
+ RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
+ RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 1, 0, bitrate_bps0,
+ min_probes0, min_bytes0);
+ RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 2, 1, bitrate_bps1,
+ min_probes1, min_bytes1);
+ RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 3, 2, bitrate_bps2,
+ min_probes2, min_bytes2);
+ RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);
+
+ // Clean up temporary file - can be pretty slow.
+ remove(temp_filename.c_str());
+}
+
+TEST(RtcEventLogTest, LogProbeResultSuccessAndReadBack) {
+ Random prng(192837);
+
+ int bitrate_bps0 = prng.Rand(0, 10000000);
+ int bitrate_bps1 = prng.Rand(0, 10000000);
+ int bitrate_bps2 = prng.Rand(0, 10000000);
+
+ // Find the name of the current test, in order to use it as a temporary
+ // filename.
+ auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+ const std::string temp_filename =
+ test::OutputPath() + test_info->test_case_name() + test_info->name();
+
+ rtc::ScopedFakeClock fake_clock;
+ fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
+ std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
+
+ log_dumper->StartLogging(temp_filename, 10000000);
+ log_dumper->LogProbeResultSuccess(0, bitrate_bps0);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeResultSuccess(1, bitrate_bps1);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeResultSuccess(2, bitrate_bps2);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->StopLogging();
+
+ // Read the generated file from disk.
+ ParsedRtcEventLog parsed_log;
+ ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
+
+ // Verify that what we read back from the event log is the same as
+ // what we wrote down.
+ EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
+ RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
+ RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 1, 0,
+ bitrate_bps0);
+ RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 2, 1,
+ bitrate_bps1);
+ RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 3, 2,
+ bitrate_bps2);
+ RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);
+
+ // Clean up temporary file - can be pretty slow.
+ remove(temp_filename.c_str());
+}
+
+TEST(RtcEventLogTest, LogProbeResultFailureAndReadBack) {
+ Random prng(192837);
+
+ // Find the name of the current test, in order to use it as a temporary
+ // filename.
+ auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+ const std::string temp_filename =
+ test::OutputPath() + test_info->test_case_name() + test_info->name();
+
+ rtc::ScopedFakeClock fake_clock;
+ fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
+ std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
+
+ log_dumper->StartLogging(temp_filename, 10000000);
+ log_dumper->LogProbeResultFailure(
+ 0, ProbeFailureReason::kInvalidSendReceiveInterval);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeResultFailure(
+ 1, ProbeFailureReason::kInvalidSendReceiveRatio);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->LogProbeResultFailure(2, ProbeFailureReason::kTimeout);
+ fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
+ log_dumper->StopLogging();
+
+ // Read the generated file from disk.
+ ParsedRtcEventLog parsed_log;
+ ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
+
+ // Verify that what we read back from the event log is the same as
+ // what we wrote down.
+ EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
+ RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
+ RtcEventLogTestHelper::VerifyProbeResultFailure(
+ parsed_log, 1, 0, ProbeFailureReason::kInvalidSendReceiveInterval);
+ RtcEventLogTestHelper::VerifyProbeResultFailure(
+ parsed_log, 2, 1, ProbeFailureReason::kInvalidSendReceiveRatio);
+ RtcEventLogTestHelper::VerifyProbeResultFailure(parsed_log, 3, 2,
+ ProbeFailureReason::kTimeout);
+ RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);
+
+ // Clean up temporary file - can be pretty slow.
+ remove(temp_filename.c_str());
+}
+
class ConfigReadWriteTest {
public:
ConfigReadWriteTest() : prng(987654321) {}
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
index e7db593..e66c090 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
+++ b/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
@@ -56,6 +56,20 @@
RTC_NOTREACHED();
return kBwNormal;
}
+
+rtclog::BweProbeResult::ResultType GetProbeResultType(
+ ProbeFailureReason failure_reason) {
+ switch (failure_reason) {
+ case kInvalidSendReceiveInterval:
+ return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL;
+ case kInvalidSendReceiveRatio:
+ return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO;
+ case kTimeout:
+ return rtclog::BweProbeResult::TIMEOUT;
+ }
+ RTC_NOTREACHED();
+ return rtclog::BweProbeResult::SUCCESS;
+}
} // namespace
// Checks that the event has a timestamp, a type and exactly the data field
@@ -132,6 +146,18 @@
<< (event.has_audio_network_adaptation() ? "" : "no ")
<< "audio network adaptation";
}
+ if ((type == rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT) !=
+ event.has_probe_cluster()) {
+ return ::testing::AssertionFailure()
+ << "Event of type " << type << " has "
+ << (event.has_probe_cluster() ? "" : "no ") << "bwe probe cluster";
+ }
+ if ((type == rtclog::Event::BWE_PROBE_RESULT_EVENT) !=
+ event.has_probe_result()) {
+ return ::testing::AssertionFailure()
+ << "Event of type " << type << " has "
+ << (event.has_probe_result() ? "" : "no ") << "bwe probe result";
+ }
return ::testing::AssertionSuccess();
}
@@ -550,4 +576,67 @@
EXPECT_EQ(rtclog::Event::LOG_END, event.type());
}
+void RtcEventLogTestHelper::VerifyBweProbeCluster(
+ const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ uint32_t bitrate_bps,
+ uint32_t min_probes,
+ uint32_t min_bytes) {
+ const rtclog::Event& event = parsed_log.events_[index];
+ ASSERT_TRUE(IsValidBasicEvent(event));
+ EXPECT_EQ(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT, event.type());
+
+ const rtclog::BweProbeCluster& bwe_event = event.probe_cluster();
+ ASSERT_TRUE(bwe_event.has_id());
+ EXPECT_EQ(id, bwe_event.id());
+ ASSERT_TRUE(bwe_event.has_bitrate_bps());
+ EXPECT_EQ(bitrate_bps, bwe_event.bitrate_bps());
+ ASSERT_TRUE(bwe_event.has_min_packets());
+ EXPECT_EQ(min_probes, bwe_event.min_packets());
+ ASSERT_TRUE(bwe_event.has_min_bytes());
+ EXPECT_EQ(min_bytes, bwe_event.min_bytes());
+
+ // TODO(philipel): Verify the parser when parsing has been implemented.
+}
+
+void RtcEventLogTestHelper::VerifyProbeResultSuccess(
+ const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ uint32_t bitrate_bps) {
+ const rtclog::Event& event = parsed_log.events_[index];
+ ASSERT_TRUE(IsValidBasicEvent(event));
+ EXPECT_EQ(rtclog::Event::BWE_PROBE_RESULT_EVENT, event.type());
+
+ const rtclog::BweProbeResult& bwe_event = event.probe_result();
+ ASSERT_TRUE(bwe_event.has_id());
+ EXPECT_EQ(id, bwe_event.id());
+ ASSERT_TRUE(bwe_event.has_bitrate_bps());
+ EXPECT_EQ(bitrate_bps, bwe_event.bitrate_bps());
+ ASSERT_TRUE(bwe_event.has_result());
+ EXPECT_EQ(rtclog::BweProbeResult::SUCCESS, bwe_event.result());
+
+ // TODO(philipel): Verify the parser when parsing has been implemented.
+}
+
+void RtcEventLogTestHelper::VerifyProbeResultFailure(
+ const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ ProbeFailureReason failure_reason) {
+ const rtclog::Event& event = parsed_log.events_[index];
+ ASSERT_TRUE(IsValidBasicEvent(event));
+ EXPECT_EQ(rtclog::Event::BWE_PROBE_RESULT_EVENT, event.type());
+
+ const rtclog::BweProbeResult& bwe_event = event.probe_result();
+ ASSERT_TRUE(bwe_event.has_id());
+ EXPECT_EQ(id, bwe_event.id());
+ ASSERT_TRUE(bwe_event.has_result());
+ EXPECT_EQ(GetProbeResultType(failure_reason), bwe_event.result());
+ ASSERT_FALSE(bwe_event.has_bitrate_bps());
+
+ // TODO(philipel): Verify the parser when parsing has been implemented.
+}
+
} // namespace webrtc
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h
index 5efb8c8..0ca2d62 100644
--- a/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h
+++ b/webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h
@@ -69,6 +69,23 @@
size_t index);
static void VerifyLogEndEvent(const ParsedRtcEventLog& parsed_log,
size_t index);
+
+ static void VerifyBweProbeCluster(const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ uint32_t bitrate_bps,
+ uint32_t min_probes,
+ uint32_t min_bytes);
+
+ static void VerifyProbeResultSuccess(const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ uint32_t bitrate_bps);
+
+ static void VerifyProbeResultFailure(const ParsedRtcEventLog& parsed_log,
+ size_t index,
+ uint32_t id,
+ ProbeFailureReason failure_reason);
};
} // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
index a84b4be..12be6d6 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc
@@ -578,7 +578,7 @@
pacing_info);
}
- if (!SendPacketToNetwork(padding_packet, options))
+ if (!SendPacketToNetwork(padding_packet, options, pacing_info))
break;
bytes_sent += padding_bytes_in_packet;
@@ -630,7 +630,8 @@
}
bool RTPSender::SendPacketToNetwork(const RtpPacketToSend& packet,
- const PacketOptions& options) {
+ const PacketOptions& options,
+ const PacedPacketInfo& pacing_info) {
int bytes_sent = -1;
if (transport_) {
UpdateRtpOverhead(packet);
@@ -639,7 +640,7 @@
: -1;
if (event_log_ && bytes_sent > 0) {
event_log_->LogRtpHeader(kOutgoingPacket, MediaType::ANY, packet.data(),
- packet.size());
+ packet.size(), pacing_info.probe_cluster_id);
}
}
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
@@ -760,7 +761,7 @@
packet->Ssrc());
}
- if (!SendPacketToNetwork(*packet_to_send, options))
+ if (!SendPacketToNetwork(*packet_to_send, options, pacing_info))
return false;
{
@@ -890,7 +891,7 @@
UpdateOnSendPacket(options.packet_id, packet->capture_time_ms(),
packet->Ssrc());
- bool sent = SendPacketToNetwork(*packet, options);
+ bool sent = SendPacketToNetwork(*packet, options, PacedPacketInfo());
if (sent) {
{
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
index 1fd4917..64eb679 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h
@@ -230,7 +230,8 @@
const RtpPacketToSend& packet);
bool SendPacketToNetwork(const RtpPacketToSend& packet,
- const PacketOptions& options);
+ const PacketOptions& options,
+ const PacedPacketInfo& pacing_info);
void UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms);
void UpdateOnSendPacket(int packet_id,
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 93aeae8..e349a70 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -426,7 +426,7 @@
EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
kSsrc, kSeqNum, _, _, _));
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _));
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _));
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@@ -471,7 +471,7 @@
EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
kSsrc, kSeqNum, _, _, _));
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _));
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _));
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@@ -525,7 +525,7 @@
EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority,
kSsrc, kSeqNum, _, _, _));
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _))
.Times(1 + 4 + 1);
uint16_t seq_num = kSeqNum;
@@ -726,7 +726,7 @@
InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _))
.Times(kNumPayloadSizes);
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _))
.Times(kNumPayloadSizes);
// Send 10 packets of increasing size.
@@ -740,7 +740,7 @@
}
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _))
.Times(::testing::AtLeast(4));
// The amount of padding to send it too small to send a payload packet.
@@ -835,7 +835,7 @@
.WillOnce(testing::SaveArg<2>(&flexfec_seq_num));
SendGenericPayload();
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _))
.Times(2);
EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum,
fake_clock_.TimeInMilliseconds(),
@@ -881,7 +881,7 @@
rtp_sender_->SetFecParameters(params, params);
EXPECT_CALL(mock_rtc_event_log_,
- LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _))
+ LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _, _))
.Times(2);
SendGenericPayload();
ASSERT_EQ(2, transport_.packets_sent());
diff --git a/webrtc/tools/event_log_visualizer/analyzer.cc b/webrtc/tools/event_log_visualizer/analyzer.cc
index 428c55c..564357c 100644
--- a/webrtc/tools/event_log_visualizer/analyzer.cc
+++ b/webrtc/tools/event_log_visualizer/analyzer.cc
@@ -457,6 +457,12 @@
audio_network_adaptation_events_.push_back(ana_event);
break;
}
+ case ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT: {
+ break;
+ }
+ case ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT: {
+ break;
+ }
case ParsedRtcEventLog::UNKNOWN_EVENT: {
break;
}
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 5f29fe4..1d54821 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -108,9 +108,19 @@
webrtc::MediaType media_type,
const uint8_t* header,
size_t packet_length) override {
+ LogRtpHeader(direction, media_type, header, packet_length,
+ PacedPacketInfo::kNotAProbe);
+ }
+
+ void LogRtpHeader(webrtc::PacketDirection direction,
+ webrtc::MediaType media_type,
+ const uint8_t* header,
+ size_t packet_length,
+ int probe_cluster_id) override {
rtc::CritScope lock(&crit_);
if (event_log_) {
- event_log_->LogRtpHeader(direction, media_type, header, packet_length);
+ event_log_->LogRtpHeader(direction, media_type, header, packet_length,
+ probe_cluster_id);
}
}
@@ -157,6 +167,32 @@
}
}
+ void LogProbeClusterCreated(int id,
+ int bitrate_bps,
+ int min_probes,
+ int min_bytes) override {
+ rtc::CritScope lock(&crit_);
+ if (event_log_) {
+ event_log_->LogProbeClusterCreated(id, bitrate_bps, min_probes,
+ min_bytes);
+ }
+ };
+
+ void LogProbeResultSuccess(int id, int bitrate_bps) override {
+ rtc::CritScope lock(&crit_);
+ if (event_log_) {
+ event_log_->LogProbeResultSuccess(id, bitrate_bps);
+ }
+ };
+
+ void LogProbeResultFailure(int id,
+ ProbeFailureReason failure_reason) override {
+ rtc::CritScope lock(&crit_);
+ if (event_log_) {
+ event_log_->LogProbeResultFailure(id, failure_reason);
+ }
+ };
+
void SetEventLog(RtcEventLog* event_log) {
rtc::CritScope lock(&crit_);
event_log_ = event_log;