2015-07-30 12:45:18 +02:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-04-22 12:40:37 -07:00
|
|
|
#include <map>
|
2016-03-12 06:10:44 -08:00
|
|
|
#include <memory>
|
2015-07-30 12:45:18 +02:00
|
|
|
#include <string>
|
2015-12-01 11:26:34 +01:00
|
|
|
#include <utility>
|
2015-07-30 12:45:18 +02:00
|
|
|
#include <vector>
|
|
|
|
|
|
2016-12-07 04:52:58 -08:00
|
|
|
#include "webrtc/call/call.h"
|
Moved RtcEventLog files from call/ to logging/
The RtcEventLog headers need to be accessible from any place which needs
logging, and the implementation needs access to data structures that are
logged.
After a discussion in the code review, we all agreed to move the RtcEventLog implementation into its own top level directory - which I called "logging/" in expectation that other types of logging may have similar requirements. The directory contains two main build targets - "rtc_event_log_api", which is just rtc_event_log.h, that has no external dependencies and can be used from anywhere, and "rtc_event_log_impl" which contains the rest of the implementation and has many dependencies (more in the future).
The "api" target can be referenced from anywhere, while the "impl" target is only needed at the place of instantiation (currently Call, soon to be moved to PeerConnection by https://codereview.webrtc.org/2353033005/).
This change allows using RtcEventLog in the p2p/ directory, so that we
can log STUN pings and ICE state transitions.
BUG=webrtc:6393
R=kjellander@webrtc.org, kwiberg@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, terelius@webrtc.org
Review URL: https://codereview.webrtc.org/2380683005 .
Cr-Commit-Position: refs/heads/master@{#14485}
2016-10-03 18:31:22 -07:00
|
|
|
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
|
|
|
|
|
#include "webrtc/logging/rtc_event_log/rtc_event_log_parser.h"
|
|
|
|
|
#include "webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h"
|
2017-04-06 05:59:10 -07:00
|
|
|
#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
2017-04-11 00:49:44 -07:00
|
|
|
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
|
2017-06-12 15:05:44 +02:00
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
2015-11-06 09:00:18 -08:00
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
|
2016-01-18 02:43:32 -08:00
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
|
2016-08-10 13:23:23 +02:00
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
|
2017-07-06 19:44:34 +02:00
|
|
|
#include "webrtc/rtc_base/buffer.h"
|
|
|
|
|
#include "webrtc/rtc_base/checks.h"
|
|
|
|
|
#include "webrtc/rtc_base/fakeclock.h"
|
|
|
|
|
#include "webrtc/rtc_base/random.h"
|
2016-09-30 22:29:43 -07:00
|
|
|
#include "webrtc/test/gtest.h"
|
2015-07-30 12:45:18 +02:00
|
|
|
#include "webrtc/test/testsupport/fileutils.h"
|
|
|
|
|
|
|
|
|
|
// Files generated at build-time by the protobuf compiler.
|
|
|
|
|
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
|
Moved RtcEventLog files from call/ to logging/
The RtcEventLog headers need to be accessible from any place which needs
logging, and the implementation needs access to data structures that are
logged.
After a discussion in the code review, we all agreed to move the RtcEventLog implementation into its own top level directory - which I called "logging/" in expectation that other types of logging may have similar requirements. The directory contains two main build targets - "rtc_event_log_api", which is just rtc_event_log.h, that has no external dependencies and can be used from anywhere, and "rtc_event_log_impl" which contains the rest of the implementation and has many dependencies (more in the future).
The "api" target can be referenced from anywhere, while the "impl" target is only needed at the place of instantiation (currently Call, soon to be moved to PeerConnection by https://codereview.webrtc.org/2353033005/).
This change allows using RtcEventLog in the p2p/ directory, so that we
can log STUN pings and ICE state transitions.
BUG=webrtc:6393
R=kjellander@webrtc.org, kwiberg@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, terelius@webrtc.org
Review URL: https://codereview.webrtc.org/2380683005 .
Cr-Commit-Position: refs/heads/master@{#14485}
2016-10-03 18:31:22 -07:00
|
|
|
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
|
2015-07-30 12:45:18 +02:00
|
|
|
#else
|
Moved RtcEventLog files from call/ to logging/
The RtcEventLog headers need to be accessible from any place which needs
logging, and the implementation needs access to data structures that are
logged.
After a discussion in the code review, we all agreed to move the RtcEventLog implementation into its own top level directory - which I called "logging/" in expectation that other types of logging may have similar requirements. The directory contains two main build targets - "rtc_event_log_api", which is just rtc_event_log.h, that has no external dependencies and can be used from anywhere, and "rtc_event_log_impl" which contains the rest of the implementation and has many dependencies (more in the future).
The "api" target can be referenced from anywhere, while the "impl" target is only needed at the place of instantiation (currently Call, soon to be moved to PeerConnection by https://codereview.webrtc.org/2353033005/).
This change allows using RtcEventLog in the p2p/ directory, so that we
can log STUN pings and ICE state transitions.
BUG=webrtc:6393
R=kjellander@webrtc.org, kwiberg@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, terelius@webrtc.org
Review URL: https://codereview.webrtc.org/2380683005 .
Cr-Commit-Position: refs/heads/master@{#14485}
2016-10-03 18:31:22 -07:00
|
|
|
#include "webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
|
2015-07-30 12:45:18 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2015-09-04 03:39:42 -07:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
const RTPExtensionType kExtensionTypes[] = {
|
|
|
|
|
RTPExtensionType::kRtpExtensionTransmissionTimeOffset,
|
|
|
|
|
RTPExtensionType::kRtpExtensionAudioLevel,
|
|
|
|
|
RTPExtensionType::kRtpExtensionAbsoluteSendTime,
|
|
|
|
|
RTPExtensionType::kRtpExtensionVideoRotation,
|
|
|
|
|
RTPExtensionType::kRtpExtensionTransportSequenceNumber};
|
2016-05-26 11:24:55 -07:00
|
|
|
const char* kExtensionNames[] = {
|
|
|
|
|
RtpExtension::kTimestampOffsetUri, RtpExtension::kAudioLevelUri,
|
|
|
|
|
RtpExtension::kAbsSendTimeUri, RtpExtension::kVideoRotationUri,
|
|
|
|
|
RtpExtension::kTransportSequenceNumberUri};
|
2015-09-04 03:39:42 -07:00
|
|
|
const size_t kNumExtensions = 5;
|
|
|
|
|
|
2016-05-13 00:42:59 -07:00
|
|
|
void PrintActualEvents(const ParsedRtcEventLog& parsed_log) {
|
|
|
|
|
std::map<int, size_t> actual_event_counts;
|
|
|
|
|
for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) {
|
|
|
|
|
actual_event_counts[parsed_log.GetEventType(i)]++;
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
printf("Actual events: ");
|
|
|
|
|
for (auto kv : actual_event_counts) {
|
|
|
|
|
printf("%d_count = %zu, ", kv.first, kv.second);
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
printf("\n");
|
|
|
|
|
for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) {
|
|
|
|
|
printf("%4d ", parsed_log.GetEventType(i));
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
printf("\n");
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
2016-05-13 00:42:59 -07:00
|
|
|
void PrintExpectedEvents(size_t rtp_count,
|
|
|
|
|
size_t rtcp_count,
|
|
|
|
|
size_t playout_count,
|
|
|
|
|
size_t bwe_loss_count) {
|
|
|
|
|
printf(
|
|
|
|
|
"Expected events: rtp_count = %zu, rtcp_count = %zu,"
|
|
|
|
|
"playout_count = %zu, bwe_loss_count = %zu\n",
|
|
|
|
|
rtp_count, rtcp_count, playout_count, bwe_loss_count);
|
|
|
|
|
size_t rtcp_index = 1, playout_index = 1, bwe_loss_index = 1;
|
|
|
|
|
printf("strt cfg cfg ");
|
|
|
|
|
for (size_t i = 1; i <= rtp_count; i++) {
|
|
|
|
|
printf(" rtp ");
|
|
|
|
|
if (i * rtcp_count >= rtcp_index * rtp_count) {
|
|
|
|
|
printf("rtcp ");
|
|
|
|
|
rtcp_index++;
|
|
|
|
|
}
|
|
|
|
|
if (i * playout_count >= playout_index * rtp_count) {
|
|
|
|
|
printf("play ");
|
|
|
|
|
playout_index++;
|
|
|
|
|
}
|
|
|
|
|
if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
|
|
|
|
|
printf("loss ");
|
|
|
|
|
bwe_loss_index++;
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
printf("end \n");
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
} // namespace
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2015-09-04 03:39:42 -07:00
|
|
|
/*
|
|
|
|
|
* Bit number i of extension_bitvector is set to indicate the
|
|
|
|
|
* presence of extension number i from kExtensionTypes / kExtensionNames.
|
|
|
|
|
* The least significant bit extension_bitvector has number 0.
|
|
|
|
|
*/
|
2016-08-10 13:23:23 +02:00
|
|
|
RtpPacketToSend GenerateRtpPacket(const RtpHeaderExtensionMap* extensions,
|
|
|
|
|
uint32_t csrcs_count,
|
|
|
|
|
size_t packet_size,
|
|
|
|
|
Random* prng) {
|
2015-09-17 00:24:34 -07:00
|
|
|
RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions);
|
2015-09-04 03:39:42 -07:00
|
|
|
|
|
|
|
|
std::vector<uint32_t> csrcs;
|
|
|
|
|
for (unsigned i = 0; i < csrcs_count; i++) {
|
2015-11-06 05:13:55 -08:00
|
|
|
csrcs.push_back(prng->Rand<uint32_t>());
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
|
2016-08-10 13:23:23 +02:00
|
|
|
RtpPacketToSend rtp_packet(extensions, packet_size);
|
|
|
|
|
rtp_packet.SetPayloadType(prng->Rand(127));
|
|
|
|
|
rtp_packet.SetMarker(prng->Rand<bool>());
|
|
|
|
|
rtp_packet.SetSequenceNumber(prng->Rand<uint16_t>());
|
|
|
|
|
rtp_packet.SetSsrc(prng->Rand<uint32_t>());
|
|
|
|
|
rtp_packet.SetTimestamp(prng->Rand<uint32_t>());
|
|
|
|
|
rtp_packet.SetCsrcs(csrcs);
|
|
|
|
|
|
|
|
|
|
rtp_packet.SetExtension<TransmissionOffset>(prng->Rand(0x00ffffff));
|
|
|
|
|
rtp_packet.SetExtension<AudioLevel>(prng->Rand<bool>(), prng->Rand(127));
|
2017-06-12 15:43:55 +02:00
|
|
|
rtp_packet.SetExtension<AbsoluteSendTime>(prng->Rand(0x00ffffff));
|
2016-08-10 13:23:23 +02:00
|
|
|
rtp_packet.SetExtension<VideoOrientation>(prng->Rand(2));
|
|
|
|
|
rtp_packet.SetExtension<TransportSequenceNumber>(prng->Rand<uint16_t>());
|
|
|
|
|
|
|
|
|
|
size_t payload_size = packet_size - rtp_packet.headers_size();
|
|
|
|
|
uint8_t* payload = rtp_packet.AllocatePayload(payload_size);
|
|
|
|
|
for (size_t i = 0; i < payload_size; i++) {
|
|
|
|
|
payload[i] = prng->Rand<uint8_t>();
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
2016-08-10 13:23:23 +02:00
|
|
|
return rtp_packet;
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
|
2016-02-17 03:11:42 -08:00
|
|
|
rtc::Buffer GenerateRtcpPacket(Random* prng) {
|
2015-11-06 09:00:18 -08:00
|
|
|
rtcp::ReportBlock report_block;
|
2016-09-27 09:27:47 -07:00
|
|
|
report_block.SetMediaSsrc(prng->Rand<uint32_t>()); // Remote SSRC.
|
|
|
|
|
report_block.SetFractionLost(prng->Rand(50));
|
2015-11-06 09:00:18 -08:00
|
|
|
|
|
|
|
|
rtcp::SenderReport sender_report;
|
2016-09-27 09:27:47 -07:00
|
|
|
sender_report.SetSenderSsrc(prng->Rand<uint32_t>());
|
|
|
|
|
sender_report.SetNtp(NtpTime(prng->Rand<uint32_t>(), prng->Rand<uint32_t>()));
|
|
|
|
|
sender_report.SetPacketCount(prng->Rand<uint32_t>());
|
|
|
|
|
sender_report.AddReportBlock(report_block);
|
2015-11-06 09:00:18 -08:00
|
|
|
|
|
|
|
|
return sender_report.Build();
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GenerateVideoReceiveConfig(uint32_t extensions_bitvector,
|
2017-05-22 03:26:49 -07:00
|
|
|
rtclog::StreamConfig* config,
|
2015-12-10 01:50:55 -08:00
|
|
|
Random* prng) {
|
2015-07-30 12:45:18 +02:00
|
|
|
// Add SSRCs for the stream.
|
2017-05-22 03:26:49 -07:00
|
|
|
config->remote_ssrc = prng->Rand<uint32_t>();
|
|
|
|
|
config->local_ssrc = prng->Rand<uint32_t>();
|
2015-07-30 12:45:18 +02:00
|
|
|
// Add extensions and settings for RTCP.
|
2017-05-22 03:26:49 -07:00
|
|
|
config->rtcp_mode =
|
2015-11-06 05:13:55 -08:00
|
|
|
prng->Rand<bool>() ? RtcpMode::kCompound : RtcpMode::kReducedSize;
|
2017-05-22 03:26:49 -07:00
|
|
|
config->remb = prng->Rand<bool>();
|
|
|
|
|
config->rtx_ssrc = prng->Rand<uint32_t>();
|
|
|
|
|
config->codecs.emplace_back(prng->Rand<bool>() ? "VP8" : "H264",
|
|
|
|
|
prng->Rand(1, 127), prng->Rand(1, 127));
|
2015-09-04 03:39:42 -07:00
|
|
|
// Add header extensions.
|
|
|
|
|
for (unsigned i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (extensions_bitvector & (1u << i)) {
|
2017-05-22 03:26:49 -07:00
|
|
|
config->rtp_extensions.emplace_back(kExtensionNames[i],
|
|
|
|
|
prng->Rand<int>());
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
2015-09-04 03:39:42 -07:00
|
|
|
void GenerateVideoSendConfig(uint32_t extensions_bitvector,
|
2017-05-22 04:08:28 -07:00
|
|
|
rtclog::StreamConfig* config,
|
2015-12-10 01:50:55 -08:00
|
|
|
Random* prng) {
|
2017-05-22 04:08:28 -07:00
|
|
|
config->codecs.emplace_back(prng->Rand<bool>() ? "VP8" : "H264",
|
|
|
|
|
prng->Rand(1, 127), prng->Rand(1, 127));
|
|
|
|
|
config->local_ssrc = prng->Rand<uint32_t>();
|
|
|
|
|
config->rtx_ssrc = prng->Rand<uint32_t>();
|
2015-09-04 03:39:42 -07:00
|
|
|
// Add header extensions.
|
|
|
|
|
for (unsigned i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (extensions_bitvector & (1u << i)) {
|
2017-05-22 04:08:28 -07:00
|
|
|
config->rtp_extensions.push_back(
|
2015-11-06 05:13:55 -08:00
|
|
|
RtpExtension(kExtensionNames[i], prng->Rand<int>()));
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-10 05:12:51 -07:00
|
|
|
void GenerateAudioReceiveConfig(uint32_t extensions_bitvector,
|
2017-05-22 09:36:28 -07:00
|
|
|
rtclog::StreamConfig* config,
|
2016-10-10 05:12:51 -07:00
|
|
|
Random* prng) {
|
|
|
|
|
// Add SSRCs for the stream.
|
2017-05-22 09:36:28 -07:00
|
|
|
config->remote_ssrc = prng->Rand<uint32_t>();
|
|
|
|
|
config->local_ssrc = prng->Rand<uint32_t>();
|
2016-10-10 05:12:51 -07:00
|
|
|
// Add header extensions.
|
|
|
|
|
for (unsigned i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (extensions_bitvector & (1u << i)) {
|
2017-05-22 09:36:28 -07:00
|
|
|
config->rtp_extensions.push_back(
|
2016-10-10 05:12:51 -07:00
|
|
|
RtpExtension(kExtensionNames[i], prng->Rand<int>()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GenerateAudioSendConfig(uint32_t extensions_bitvector,
|
2017-05-22 10:12:26 -07:00
|
|
|
rtclog::StreamConfig* config,
|
2016-10-10 05:12:51 -07:00
|
|
|
Random* prng) {
|
|
|
|
|
// Add SSRC to the stream.
|
2017-05-22 10:12:26 -07:00
|
|
|
config->local_ssrc = prng->Rand<uint32_t>();
|
2016-10-10 05:12:51 -07:00
|
|
|
// Add header extensions.
|
|
|
|
|
for (unsigned i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (extensions_bitvector & (1u << i)) {
|
2017-05-22 10:12:26 -07:00
|
|
|
config->rtp_extensions.push_back(
|
2016-10-10 05:12:51 -07:00
|
|
|
RtpExtension(kExtensionNames[i], prng->Rand<int>()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-06 05:59:10 -07:00
|
|
|
void GenerateAudioNetworkAdaptation(uint32_t extensions_bitvector,
|
|
|
|
|
AudioEncoderRuntimeConfig* config,
|
|
|
|
|
Random* prng) {
|
2017-01-24 04:54:59 -08:00
|
|
|
config->bitrate_bps = rtc::Optional<int>(prng->Rand(0, 3000000));
|
|
|
|
|
config->enable_fec = rtc::Optional<bool>(prng->Rand<bool>());
|
|
|
|
|
config->enable_dtx = rtc::Optional<bool>(prng->Rand<bool>());
|
|
|
|
|
config->frame_length_ms = rtc::Optional<int>(prng->Rand(10, 120));
|
|
|
|
|
config->num_channels = rtc::Optional<size_t>(prng->Rand(1, 2));
|
|
|
|
|
config->uplink_packet_loss_fraction =
|
|
|
|
|
rtc::Optional<float>(prng->Rand<float>());
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-16 08:51:08 -07:00
|
|
|
// Test for the RtcEventLog class. Dumps some RTP packets and other events
|
|
|
|
|
// to disk, then reads them back to see if they match.
|
2015-09-04 03:39:42 -07:00
|
|
|
void LogSessionAndReadBack(size_t rtp_count,
|
|
|
|
|
size_t rtcp_count,
|
2015-10-08 18:07:41 +02:00
|
|
|
size_t playout_count,
|
2015-11-05 12:02:15 -08:00
|
|
|
size_t bwe_loss_count,
|
2015-09-04 03:39:42 -07:00
|
|
|
uint32_t extensions_bitvector,
|
|
|
|
|
uint32_t csrcs_count,
|
2015-10-16 08:51:08 -07:00
|
|
|
unsigned int random_seed) {
|
2015-09-04 03:39:42 -07:00
|
|
|
ASSERT_LE(rtcp_count, rtp_count);
|
2015-10-08 18:07:41 +02:00
|
|
|
ASSERT_LE(playout_count, rtp_count);
|
2015-11-05 12:02:15 -08:00
|
|
|
ASSERT_LE(bwe_loss_count, rtp_count);
|
2016-08-10 13:23:23 +02:00
|
|
|
std::vector<RtpPacketToSend> rtp_packets;
|
2016-02-17 03:11:42 -08:00
|
|
|
std::vector<rtc::Buffer> rtcp_packets;
|
2015-09-17 16:30:16 +02:00
|
|
|
std::vector<uint32_t> playout_ssrcs;
|
2015-11-05 12:02:15 -08:00
|
|
|
std::vector<std::pair<int32_t, uint8_t> > bwe_loss_updates;
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2017-05-22 03:26:49 -07:00
|
|
|
rtclog::StreamConfig receiver_config;
|
2017-05-22 04:08:28 -07:00
|
|
|
rtclog::StreamConfig sender_config;
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2015-12-10 01:50:55 -08:00
|
|
|
Random prng(random_seed);
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2016-08-10 13:23:23 +02:00
|
|
|
// Initialize rtp header extensions to be used in generated rtp packets.
|
|
|
|
|
RtpHeaderExtensionMap extensions;
|
|
|
|
|
for (unsigned i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (extensions_bitvector & (1u << i)) {
|
|
|
|
|
extensions.Register(kExtensionTypes[i], i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
// Create rtp_count RTP packets containing random data.
|
|
|
|
|
for (size_t i = 0; i < rtp_count; i++) {
|
2015-11-06 05:13:55 -08:00
|
|
|
size_t packet_size = prng.Rand(1000, 1100);
|
2016-08-10 13:23:23 +02:00
|
|
|
rtp_packets.push_back(
|
|
|
|
|
GenerateRtpPacket(&extensions, csrcs_count, packet_size, &prng));
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2015-09-04 03:39:42 -07:00
|
|
|
// Create rtcp_count RTCP packets containing random data.
|
|
|
|
|
for (size_t i = 0; i < rtcp_count; i++) {
|
2015-11-06 09:00:18 -08:00
|
|
|
rtcp_packets.push_back(GenerateRtcpPacket(&prng));
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2015-10-08 18:07:41 +02:00
|
|
|
// Create playout_count random SSRCs to use when logging AudioPlayout events.
|
|
|
|
|
for (size_t i = 0; i < playout_count; i++) {
|
2015-11-06 05:13:55 -08:00
|
|
|
playout_ssrcs.push_back(prng.Rand<uint32_t>());
|
2015-09-17 16:30:16 +02:00
|
|
|
}
|
2017-02-20 05:14:41 -08:00
|
|
|
// Create bwe_loss_count random bitrate updates for LossBasedBwe.
|
2015-11-05 12:02:15 -08:00
|
|
|
for (size_t i = 0; i < bwe_loss_count; i++) {
|
2015-11-06 09:00:18 -08:00
|
|
|
bwe_loss_updates.push_back(
|
|
|
|
|
std::make_pair(prng.Rand<int32_t>(), prng.Rand<uint8_t>()));
|
2015-11-05 12:02:15 -08:00
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
// Create configurations for the video streams.
|
2015-11-06 05:13:55 -08:00
|
|
|
GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config, &prng);
|
|
|
|
|
GenerateVideoSendConfig(extensions_bitvector, &sender_config, &prng);
|
2015-09-04 03:39:42 -07:00
|
|
|
const int config_count = 2;
|
2015-07-30 12:45:18 +02:00
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
|
|
// When log_dumper goes out of scope, it causes the log file to be flushed
|
|
|
|
|
// to disk.
|
|
|
|
|
{
|
2016-12-20 05:03:58 -08:00
|
|
|
rtc::ScopedFakeClock fake_clock;
|
|
|
|
|
fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
|
|
|
|
|
std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
|
2015-07-30 12:45:18 +02:00
|
|
|
log_dumper->LogVideoReceiveStreamConfig(receiver_config);
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-07-30 12:45:18 +02:00
|
|
|
log_dumper->LogVideoSendStreamConfig(sender_config);
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-11-05 12:02:15 -08:00
|
|
|
size_t rtcp_index = 1;
|
|
|
|
|
size_t playout_index = 1;
|
|
|
|
|
size_t bwe_loss_index = 1;
|
2015-09-04 03:39:42 -07:00
|
|
|
for (size_t i = 1; i <= rtp_count; i++) {
|
2015-07-30 12:45:18 +02:00
|
|
|
log_dumper->LogRtpHeader(
|
2016-01-21 05:42:04 -08:00
|
|
|
(i % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
|
2015-09-04 03:39:42 -07:00
|
|
|
rtp_packets[i - 1].data(), rtp_packets[i - 1].size());
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-09-04 03:39:42 -07:00
|
|
|
if (i * rtcp_count >= rtcp_index * rtp_count) {
|
|
|
|
|
log_dumper->LogRtcpPacket(
|
2016-01-21 05:42:04 -08:00
|
|
|
(rtcp_index % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
|
2016-02-17 03:11:42 -08:00
|
|
|
rtcp_packets[rtcp_index - 1].data(),
|
|
|
|
|
rtcp_packets[rtcp_index - 1].size());
|
2015-09-04 03:39:42 -07:00
|
|
|
rtcp_index++;
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
2015-10-08 18:07:41 +02:00
|
|
|
if (i * playout_count >= playout_index * rtp_count) {
|
|
|
|
|
log_dumper->LogAudioPlayout(playout_ssrcs[playout_index - 1]);
|
|
|
|
|
playout_index++;
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
2015-11-05 12:02:15 -08:00
|
|
|
if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
|
2017-02-20 05:14:41 -08:00
|
|
|
log_dumper->LogLossBasedBweUpdate(
|
2015-11-05 12:02:15 -08:00
|
|
|
bwe_loss_updates[bwe_loss_index - 1].first,
|
|
|
|
|
bwe_loss_updates[bwe_loss_index - 1].second, i);
|
|
|
|
|
bwe_loss_index++;
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-11-05 12:02:15 -08:00
|
|
|
}
|
2015-09-04 03:39:42 -07:00
|
|
|
if (i == rtp_count / 2) {
|
|
|
|
|
log_dumper->StartLogging(temp_filename, 10000000);
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
2016-04-22 12:40:37 -07:00
|
|
|
log_dumper->StopLogging();
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read the generated file from disk.
|
2016-05-13 00:42:59 -07:00
|
|
|
ParsedRtcEventLog parsed_log;
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2016-05-13 00:42:59 -07:00
|
|
|
ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2015-10-16 08:51:08 -07:00
|
|
|
// Verify that what we read back from the event log is the same as
|
|
|
|
|
// what we wrote down. For RTCP we log the full packets, but for
|
|
|
|
|
// RTP we should only log the header.
|
2016-05-13 00:42:59 -07:00
|
|
|
const size_t event_count = config_count + playout_count + bwe_loss_count +
|
|
|
|
|
rtcp_count + rtp_count + 2;
|
|
|
|
|
EXPECT_GE(1000u, event_count); // The events must fit in the message queue.
|
|
|
|
|
EXPECT_EQ(event_count, parsed_log.GetNumberOfEvents());
|
|
|
|
|
if (event_count != parsed_log.GetNumberOfEvents()) {
|
2016-04-22 12:40:37 -07:00
|
|
|
// Print the expected and actual event types for easier debugging.
|
2016-05-13 00:42:59 -07:00
|
|
|
PrintActualEvents(parsed_log);
|
|
|
|
|
PrintExpectedEvents(rtp_count, rtcp_count, playout_count, bwe_loss_count);
|
2016-04-22 12:40:37 -07:00
|
|
|
}
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
|
2016-10-10 05:12:51 -07:00
|
|
|
RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig(parsed_log, 1,
|
|
|
|
|
receiver_config);
|
|
|
|
|
RtcEventLogTestHelper::VerifyVideoSendStreamConfig(parsed_log, 2,
|
|
|
|
|
sender_config);
|
2016-04-22 12:40:37 -07:00
|
|
|
size_t event_index = config_count + 1;
|
2015-11-05 12:02:15 -08:00
|
|
|
size_t rtcp_index = 1;
|
|
|
|
|
size_t playout_index = 1;
|
|
|
|
|
size_t bwe_loss_index = 1;
|
2015-09-04 03:39:42 -07:00
|
|
|
for (size_t i = 1; i <= rtp_count; i++) {
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyRtpEvent(
|
|
|
|
|
parsed_log, event_index,
|
|
|
|
|
(i % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
|
2016-08-10 13:23:23 +02:00
|
|
|
rtp_packets[i - 1].data(), rtp_packets[i - 1].headers_size(),
|
2016-05-13 00:42:59 -07:00
|
|
|
rtp_packets[i - 1].size());
|
2015-09-04 03:39:42 -07:00
|
|
|
event_index++;
|
|
|
|
|
if (i * rtcp_count >= rtcp_index * rtp_count) {
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyRtcpEvent(
|
|
|
|
|
parsed_log, event_index,
|
|
|
|
|
rtcp_index % 2 == 0 ? kIncomingPacket : kOutgoingPacket,
|
|
|
|
|
rtcp_packets[rtcp_index - 1].data(),
|
|
|
|
|
rtcp_packets[rtcp_index - 1].size());
|
2015-09-04 03:39:42 -07:00
|
|
|
event_index++;
|
|
|
|
|
rtcp_index++;
|
|
|
|
|
}
|
2015-10-08 18:07:41 +02:00
|
|
|
if (i * playout_count >= playout_index * rtp_count) {
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyPlayoutEvent(
|
|
|
|
|
parsed_log, event_index, playout_ssrcs[playout_index - 1]);
|
2015-09-04 03:39:42 -07:00
|
|
|
event_index++;
|
2015-10-08 18:07:41 +02:00
|
|
|
playout_index++;
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
2015-11-05 12:02:15 -08:00
|
|
|
if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyBweLossEvent(
|
|
|
|
|
parsed_log, event_index, bwe_loss_updates[bwe_loss_index - 1].first,
|
|
|
|
|
bwe_loss_updates[bwe_loss_index - 1].second, i);
|
2015-11-05 12:02:15 -08:00
|
|
|
event_index++;
|
|
|
|
|
bwe_loss_index++;
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clean up temporary file - can be pretty slow.
|
|
|
|
|
remove(temp_filename.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(RtcEventLogTest, LogSessionAndReadBack) {
|
2015-11-05 12:02:15 -08:00
|
|
|
// Log 5 RTP, 2 RTCP, 0 playout events and 0 BWE events
|
|
|
|
|
// with no header extensions or CSRCS.
|
|
|
|
|
LogSessionAndReadBack(5, 2, 0, 0, 0, 0, 321);
|
2015-09-04 03:39:42 -07:00
|
|
|
|
2015-11-05 12:02:15 -08:00
|
|
|
// Enable AbsSendTime and TransportSequenceNumbers.
|
2015-09-04 03:39:42 -07:00
|
|
|
uint32_t extensions = 0;
|
|
|
|
|
for (uint32_t i = 0; i < kNumExtensions; i++) {
|
|
|
|
|
if (kExtensionTypes[i] == RTPExtensionType::kRtpExtensionAbsoluteSendTime ||
|
|
|
|
|
kExtensionTypes[i] ==
|
|
|
|
|
RTPExtensionType::kRtpExtensionTransportSequenceNumber) {
|
|
|
|
|
extensions |= 1u << i;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-11-05 12:02:15 -08:00
|
|
|
LogSessionAndReadBack(8, 2, 0, 0, extensions, 0, 3141592653u);
|
2015-09-04 03:39:42 -07:00
|
|
|
|
2015-11-05 12:02:15 -08:00
|
|
|
extensions = (1u << kNumExtensions) - 1; // Enable all header extensions.
|
|
|
|
|
LogSessionAndReadBack(9, 2, 3, 2, extensions, 2, 2718281828u);
|
2015-09-04 03:39:42 -07:00
|
|
|
|
|
|
|
|
// Try all combinations of header extensions and up to 2 CSRCS.
|
|
|
|
|
for (extensions = 0; extensions < (1u << kNumExtensions); extensions++) {
|
|
|
|
|
for (uint32_t csrcs_count = 0; csrcs_count < 3; csrcs_count++) {
|
|
|
|
|
LogSessionAndReadBack(5 + extensions, // Number of RTP packets.
|
|
|
|
|
2 + csrcs_count, // Number of RTCP packets.
|
2015-11-05 12:02:15 -08:00
|
|
|
3 + csrcs_count, // Number of playout events.
|
|
|
|
|
1 + csrcs_count, // Number of BWE loss events.
|
|
|
|
|
extensions, // Bit vector choosing extensions.
|
|
|
|
|
csrcs_count, // Number of contributing sources.
|
2015-12-10 01:50:55 -08:00
|
|
|
extensions * 3 + csrcs_count + 1); // Random seed.
|
2015-09-04 03:39:42 -07:00
|
|
|
}
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
}
|
|
|
|
|
|
2016-04-22 12:40:37 -07:00
|
|
|
TEST(RtcEventLogTest, LogEventAndReadBack) {
|
|
|
|
|
Random prng(987654321);
|
2015-10-16 08:51:08 -07:00
|
|
|
|
2016-04-22 12:40:37 -07:00
|
|
|
// Create one RTP and one RTCP packet containing random data.
|
2015-11-06 05:13:55 -08:00
|
|
|
size_t packet_size = prng.Rand(1000, 1100);
|
2016-08-10 13:23:23 +02:00
|
|
|
RtpPacketToSend rtp_packet =
|
|
|
|
|
GenerateRtpPacket(nullptr, 0, packet_size, &prng);
|
2016-04-22 12:40:37 -07:00
|
|
|
rtc::Buffer rtcp_packet = GenerateRtcpPacket(&prng);
|
2015-10-16 08:51:08 -07:00
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
2016-04-22 12:40:37 -07:00
|
|
|
// Add RTP, start logging, add RTCP and then stop logging
|
2016-12-20 05:03:58 -08:00
|
|
|
rtc::ScopedFakeClock fake_clock;
|
|
|
|
|
fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
|
|
|
|
|
std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2017-05-30 03:52:10 -07:00
|
|
|
log_dumper->LogRtpHeader(kIncomingPacket, rtp_packet.data(),
|
2016-04-22 12:40:37 -07:00
|
|
|
rtp_packet.size());
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2016-04-22 12:40:37 -07:00
|
|
|
|
|
|
|
|
log_dumper->StartLogging(temp_filename, 10000000);
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2017-05-30 03:52:10 -07:00
|
|
|
log_dumper->LogRtcpPacket(kOutgoingPacket, rtcp_packet.data(),
|
|
|
|
|
rtcp_packet.size());
|
2016-12-20 05:03:58 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2016-04-22 12:40:37 -07:00
|
|
|
|
|
|
|
|
log_dumper->StopLogging();
|
2015-10-16 08:51:08 -07:00
|
|
|
|
|
|
|
|
// Read the generated file from disk.
|
2016-05-13 00:42:59 -07:00
|
|
|
ParsedRtcEventLog parsed_log;
|
|
|
|
|
ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
|
2015-10-16 08:51:08 -07:00
|
|
|
|
|
|
|
|
// Verify that what we read back from the event log is the same as
|
2016-04-22 12:40:37 -07:00
|
|
|
// what we wrote down.
|
2016-05-13 00:42:59 -07:00
|
|
|
EXPECT_EQ(4u, parsed_log.GetNumberOfEvents());
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2016-08-10 13:23:23 +02:00
|
|
|
RtcEventLogTestHelper::VerifyRtpEvent(
|
2017-05-30 03:52:10 -07:00
|
|
|
parsed_log, 1, kIncomingPacket, rtp_packet.data(),
|
2016-08-10 13:23:23 +02:00
|
|
|
rtp_packet.headers_size(), rtp_packet.size());
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2017-05-30 03:52:10 -07:00
|
|
|
RtcEventLogTestHelper::VerifyRtcpEvent(
|
|
|
|
|
parsed_log, 2, kOutgoingPacket, rtcp_packet.data(), rtcp_packet.size());
|
2016-04-22 12:40:37 -07:00
|
|
|
|
2016-05-13 00:42:59 -07:00
|
|
|
RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 3);
|
2015-10-16 08:51:08 -07:00
|
|
|
|
|
|
|
|
// Clean up temporary file - can be pretty slow.
|
|
|
|
|
remove(temp_filename.c_str());
|
|
|
|
|
}
|
2015-07-30 12:45:18 +02:00
|
|
|
|
2017-02-20 05:14:41 -08:00
|
|
|
TEST(RtcEventLogTest, LogLossBasedBweUpdateAndReadBack) {
|
2017-02-17 03:38:28 -08:00
|
|
|
Random prng(1234);
|
|
|
|
|
|
|
|
|
|
// Generate a random packet loss event.
|
|
|
|
|
int32_t bitrate = prng.Rand(0, 10000000);
|
|
|
|
|
uint8_t fraction_lost = prng.Rand<uint8_t>();
|
|
|
|
|
int32_t total_packets = prng.Rand(1, 1000);
|
|
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
|
|
// Start logging, add the packet loss event and then stop logging.
|
|
|
|
|
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);
|
|
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2017-02-20 05:14:41 -08:00
|
|
|
log_dumper->LogLossBasedBweUpdate(bitrate, fraction_lost, total_packets);
|
2017-02-17 03:38:28 -08:00
|
|
|
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(3u, parsed_log.GetNumberOfEvents());
|
|
|
|
|
RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
|
|
|
|
|
RtcEventLogTestHelper::VerifyBweLossEvent(parsed_log, 1, bitrate,
|
|
|
|
|
fraction_lost, total_packets);
|
|
|
|
|
RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 2);
|
|
|
|
|
|
|
|
|
|
// Clean up temporary file - can be pretty slow.
|
|
|
|
|
remove(temp_filename.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-20 05:14:41 -08:00
|
|
|
TEST(RtcEventLogTest, LogDelayBasedBweUpdateAndReadBack) {
|
2017-02-17 03:38:28 -08:00
|
|
|
Random prng(1234);
|
|
|
|
|
|
|
|
|
|
// Generate 3 random packet delay event.
|
|
|
|
|
int32_t bitrate1 = prng.Rand(0, 10000000);
|
|
|
|
|
int32_t bitrate2 = prng.Rand(0, 10000000);
|
|
|
|
|
int32_t bitrate3 = 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();
|
|
|
|
|
|
|
|
|
|
// Start logging, add the packet delay events and then stop logging.
|
|
|
|
|
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);
|
|
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2017-04-11 00:49:44 -07:00
|
|
|
log_dumper->LogDelayBasedBweUpdate(bitrate1, BandwidthUsage::kBwNormal);
|
2017-02-17 03:38:28 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2017-04-11 00:49:44 -07:00
|
|
|
log_dumper->LogDelayBasedBweUpdate(bitrate2, BandwidthUsage::kBwOverusing);
|
2017-02-17 03:38:28 -08:00
|
|
|
fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
|
2017-04-11 00:49:44 -07:00
|
|
|
log_dumper->LogDelayBasedBweUpdate(bitrate3, BandwidthUsage::kBwUnderusing);
|
2017-02-17 03:38:28 -08:00
|
|
|
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::VerifyBweDelayEvent(parsed_log, 1, bitrate1,
|
2017-04-11 00:49:44 -07:00
|
|
|
BandwidthUsage::kBwNormal);
|
2017-02-17 03:38:28 -08:00
|
|
|
RtcEventLogTestHelper::VerifyBweDelayEvent(parsed_log, 2, bitrate2,
|
2017-04-11 00:49:44 -07:00
|
|
|
BandwidthUsage::kBwOverusing);
|
2017-02-17 03:38:28 -08:00
|
|
|
RtcEventLogTestHelper::VerifyBweDelayEvent(parsed_log, 3, bitrate3,
|
2017-04-11 00:49:44 -07:00
|
|
|
BandwidthUsage::kBwUnderusing);
|
2017-02-17 03:38:28 -08:00
|
|
|
RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);
|
|
|
|
|
|
|
|
|
|
// Clean up temporary file - can be pretty slow.
|
|
|
|
|
remove(temp_filename.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 02:18:46 -08:00
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-10 05:12:51 -07:00
|
|
|
class ConfigReadWriteTest {
|
|
|
|
|
public:
|
|
|
|
|
ConfigReadWriteTest() : prng(987654321) {}
|
|
|
|
|
virtual ~ConfigReadWriteTest() {}
|
|
|
|
|
virtual void GenerateConfig(uint32_t extensions_bitvector) = 0;
|
|
|
|
|
virtual void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) = 0;
|
|
|
|
|
virtual void LogConfig(RtcEventLog* event_log) = 0;
|
|
|
|
|
|
|
|
|
|
void DoTest() {
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
|
|
// Use all extensions.
|
|
|
|
|
uint32_t extensions_bitvector = (1u << kNumExtensions) - 1;
|
|
|
|
|
GenerateConfig(extensions_bitvector);
|
|
|
|
|
|
|
|
|
|
// Log a single config event and stop logging.
|
2016-12-20 05:03:58 -08:00
|
|
|
rtc::ScopedFakeClock fake_clock;
|
|
|
|
|
fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
|
|
|
|
|
std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
|
2016-10-10 05:12:51 -07:00
|
|
|
|
|
|
|
|
log_dumper->StartLogging(temp_filename, 10000000);
|
|
|
|
|
LogConfig(log_dumper.get());
|
|
|
|
|
log_dumper->StopLogging();
|
|
|
|
|
|
|
|
|
|
// Read the generated file from disk.
|
|
|
|
|
ParsedRtcEventLog parsed_log;
|
|
|
|
|
ASSERT_TRUE(parsed_log.ParseFile(temp_filename));
|
|
|
|
|
|
|
|
|
|
// Check the generated number of events.
|
|
|
|
|
EXPECT_EQ(3u, parsed_log.GetNumberOfEvents());
|
|
|
|
|
|
|
|
|
|
RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
|
|
|
|
|
|
|
|
|
|
// Verify that the parsed config struct matches the one that was logged.
|
|
|
|
|
VerifyConfig(parsed_log, 1);
|
|
|
|
|
|
|
|
|
|
RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 2);
|
|
|
|
|
|
|
|
|
|
// Clean up temporary file - can be pretty slow.
|
|
|
|
|
remove(temp_filename.c_str());
|
|
|
|
|
}
|
|
|
|
|
Random prng;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class AudioReceiveConfigReadWriteTest : public ConfigReadWriteTest {
|
|
|
|
|
public:
|
|
|
|
|
void GenerateConfig(uint32_t extensions_bitvector) override {
|
|
|
|
|
GenerateAudioReceiveConfig(extensions_bitvector, &config, &prng);
|
|
|
|
|
}
|
|
|
|
|
void LogConfig(RtcEventLog* event_log) override {
|
|
|
|
|
event_log->LogAudioReceiveStreamConfig(config);
|
|
|
|
|
}
|
|
|
|
|
void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) override {
|
|
|
|
|
RtcEventLogTestHelper::VerifyAudioReceiveStreamConfig(parsed_log, index,
|
|
|
|
|
config);
|
|
|
|
|
}
|
2017-05-22 09:36:28 -07:00
|
|
|
rtclog::StreamConfig config;
|
2016-10-10 05:12:51 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class AudioSendConfigReadWriteTest : public ConfigReadWriteTest {
|
|
|
|
|
public:
|
2017-05-22 10:12:26 -07:00
|
|
|
AudioSendConfigReadWriteTest() {}
|
2016-10-10 05:12:51 -07:00
|
|
|
void GenerateConfig(uint32_t extensions_bitvector) override {
|
|
|
|
|
GenerateAudioSendConfig(extensions_bitvector, &config, &prng);
|
|
|
|
|
}
|
|
|
|
|
void LogConfig(RtcEventLog* event_log) override {
|
|
|
|
|
event_log->LogAudioSendStreamConfig(config);
|
|
|
|
|
}
|
|
|
|
|
void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) override {
|
|
|
|
|
RtcEventLogTestHelper::VerifyAudioSendStreamConfig(parsed_log, index,
|
|
|
|
|
config);
|
|
|
|
|
}
|
2017-05-22 10:12:26 -07:00
|
|
|
rtclog::StreamConfig config;
|
2016-10-10 05:12:51 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VideoReceiveConfigReadWriteTest : public ConfigReadWriteTest {
|
|
|
|
|
public:
|
2017-05-22 03:26:49 -07:00
|
|
|
VideoReceiveConfigReadWriteTest() {}
|
2016-10-10 05:12:51 -07:00
|
|
|
void GenerateConfig(uint32_t extensions_bitvector) override {
|
|
|
|
|
GenerateVideoReceiveConfig(extensions_bitvector, &config, &prng);
|
|
|
|
|
}
|
|
|
|
|
void LogConfig(RtcEventLog* event_log) override {
|
|
|
|
|
event_log->LogVideoReceiveStreamConfig(config);
|
|
|
|
|
}
|
|
|
|
|
void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) override {
|
|
|
|
|
RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig(parsed_log, index,
|
|
|
|
|
config);
|
|
|
|
|
}
|
2017-05-22 03:26:49 -07:00
|
|
|
rtclog::StreamConfig config;
|
2016-10-10 05:12:51 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VideoSendConfigReadWriteTest : public ConfigReadWriteTest {
|
|
|
|
|
public:
|
2017-05-22 04:08:28 -07:00
|
|
|
VideoSendConfigReadWriteTest() {}
|
2016-10-10 05:12:51 -07:00
|
|
|
void GenerateConfig(uint32_t extensions_bitvector) override {
|
|
|
|
|
GenerateVideoSendConfig(extensions_bitvector, &config, &prng);
|
|
|
|
|
}
|
|
|
|
|
void LogConfig(RtcEventLog* event_log) override {
|
|
|
|
|
event_log->LogVideoSendStreamConfig(config);
|
|
|
|
|
}
|
|
|
|
|
void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) override {
|
|
|
|
|
RtcEventLogTestHelper::VerifyVideoSendStreamConfig(parsed_log, index,
|
|
|
|
|
config);
|
|
|
|
|
}
|
2017-05-22 04:08:28 -07:00
|
|
|
rtclog::StreamConfig config;
|
2016-10-10 05:12:51 -07:00
|
|
|
};
|
|
|
|
|
|
2017-01-24 04:54:59 -08:00
|
|
|
class AudioNetworkAdaptationReadWriteTest : public ConfigReadWriteTest {
|
|
|
|
|
public:
|
|
|
|
|
void GenerateConfig(uint32_t extensions_bitvector) override {
|
|
|
|
|
GenerateAudioNetworkAdaptation(extensions_bitvector, &config, &prng);
|
|
|
|
|
}
|
|
|
|
|
void LogConfig(RtcEventLog* event_log) override {
|
|
|
|
|
event_log->LogAudioNetworkAdaptation(config);
|
|
|
|
|
}
|
|
|
|
|
void VerifyConfig(const ParsedRtcEventLog& parsed_log,
|
|
|
|
|
size_t index) override {
|
|
|
|
|
RtcEventLogTestHelper::VerifyAudioNetworkAdaptation(parsed_log, index,
|
|
|
|
|
config);
|
|
|
|
|
}
|
2017-04-06 05:59:10 -07:00
|
|
|
AudioEncoderRuntimeConfig config;
|
2017-01-24 04:54:59 -08:00
|
|
|
};
|
|
|
|
|
|
2016-10-10 05:12:51 -07:00
|
|
|
TEST(RtcEventLogTest, LogAudioReceiveConfig) {
|
|
|
|
|
AudioReceiveConfigReadWriteTest test;
|
|
|
|
|
test.DoTest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(RtcEventLogTest, LogAudioSendConfig) {
|
|
|
|
|
AudioSendConfigReadWriteTest test;
|
|
|
|
|
test.DoTest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(RtcEventLogTest, LogVideoReceiveConfig) {
|
|
|
|
|
VideoReceiveConfigReadWriteTest test;
|
|
|
|
|
test.DoTest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(RtcEventLogTest, LogVideoSendConfig) {
|
|
|
|
|
VideoSendConfigReadWriteTest test;
|
|
|
|
|
test.DoTest();
|
|
|
|
|
}
|
2017-01-24 04:54:59 -08:00
|
|
|
|
|
|
|
|
TEST(RtcEventLogTest, LogAudioNetworkAdaptation) {
|
|
|
|
|
AudioNetworkAdaptationReadWriteTest test;
|
|
|
|
|
test.DoTest();
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-19 14:42:02 -07:00
|
|
|
} // namespace webrtc
|