Currently there are two structs that are identical and track extension details: webrtc::RtpExtension cricket::RtpHeaderExtension The use of the structs is mixed in the code to track the extensions being supported. This results in duplicate definition of the URI constants and there is code to convert between the two structs. Clean up to use a single RtpHeader throughout the codebase. The actual location of RtpHeader may change in future (perhaps to be located in api/). Additionally, this CL renames some of the constants to clarify Uri and Id use. BUG= webrtc:5895 Review-Url: https://codereview.webrtc.org/1984983002 Cr-Commit-Position: refs/heads/master@{#12924}
410 lines
17 KiB
C++
410 lines
17 KiB
C++
/*
|
|
* Copyright (c) 2016 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.
|
|
*/
|
|
|
|
#ifdef ENABLE_RTC_EVENT_LOG
|
|
|
|
#include "webrtc/call/rtc_event_log_unittest_helper.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <string>
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/test/test_suite.h"
|
|
#include "webrtc/test/testsupport/fileutils.h"
|
|
|
|
// Files generated at build-time by the protobuf compiler.
|
|
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
|
|
#include "external/webrtc/webrtc/call/rtc_event_log.pb.h"
|
|
#else
|
|
#include "webrtc/call/rtc_event_log.pb.h"
|
|
#endif
|
|
|
|
namespace webrtc {
|
|
|
|
namespace {
|
|
MediaType GetRuntimeMediaType(rtclog::MediaType media_type) {
|
|
switch (media_type) {
|
|
case rtclog::MediaType::ANY:
|
|
return MediaType::ANY;
|
|
case rtclog::MediaType::AUDIO:
|
|
return MediaType::AUDIO;
|
|
case rtclog::MediaType::VIDEO:
|
|
return MediaType::VIDEO;
|
|
case rtclog::MediaType::DATA:
|
|
return MediaType::DATA;
|
|
}
|
|
RTC_NOTREACHED();
|
|
return MediaType::ANY;
|
|
}
|
|
} // namespace
|
|
|
|
// Checks that the event has a timestamp, a type and exactly the data field
|
|
// corresponding to the type.
|
|
::testing::AssertionResult IsValidBasicEvent(const rtclog::Event& event) {
|
|
if (!event.has_timestamp_us()) {
|
|
return ::testing::AssertionFailure() << "Event has no timestamp";
|
|
}
|
|
if (!event.has_type()) {
|
|
return ::testing::AssertionFailure() << "Event has no event type";
|
|
}
|
|
rtclog::Event_EventType type = event.type();
|
|
if ((type == rtclog::Event::RTP_EVENT) != event.has_rtp_packet()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_rtp_packet() ? "" : "no ") << "RTP packet";
|
|
}
|
|
if ((type == rtclog::Event::RTCP_EVENT) != event.has_rtcp_packet()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_rtcp_packet() ? "" : "no ") << "RTCP packet";
|
|
}
|
|
if ((type == rtclog::Event::AUDIO_PLAYOUT_EVENT) !=
|
|
event.has_audio_playout_event()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_audio_playout_event() ? "" : "no ")
|
|
<< "audio_playout event";
|
|
}
|
|
if ((type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT) !=
|
|
event.has_video_receiver_config()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_video_receiver_config() ? "" : "no ")
|
|
<< "receiver config";
|
|
}
|
|
if ((type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT) !=
|
|
event.has_video_sender_config()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_video_sender_config() ? "" : "no ") << "sender config";
|
|
}
|
|
if ((type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT) !=
|
|
event.has_audio_receiver_config()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_audio_receiver_config() ? "" : "no ")
|
|
<< "audio receiver config";
|
|
}
|
|
if ((type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT) !=
|
|
event.has_audio_sender_config()) {
|
|
return ::testing::AssertionFailure()
|
|
<< "Event of type " << type << " has "
|
|
<< (event.has_audio_sender_config() ? "" : "no ")
|
|
<< "audio sender config";
|
|
}
|
|
return ::testing::AssertionSuccess();
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyReceiveStreamConfig(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
const VideoReceiveStream::Config& config) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT, event.type());
|
|
const rtclog::VideoReceiveConfig& receiver_config =
|
|
event.video_receiver_config();
|
|
// Check SSRCs.
|
|
ASSERT_TRUE(receiver_config.has_remote_ssrc());
|
|
EXPECT_EQ(config.rtp.remote_ssrc, receiver_config.remote_ssrc());
|
|
ASSERT_TRUE(receiver_config.has_local_ssrc());
|
|
EXPECT_EQ(config.rtp.local_ssrc, receiver_config.local_ssrc());
|
|
// Check RTCP settings.
|
|
ASSERT_TRUE(receiver_config.has_rtcp_mode());
|
|
if (config.rtp.rtcp_mode == RtcpMode::kCompound) {
|
|
EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_COMPOUND,
|
|
receiver_config.rtcp_mode());
|
|
} else {
|
|
EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE,
|
|
receiver_config.rtcp_mode());
|
|
}
|
|
ASSERT_TRUE(receiver_config.has_remb());
|
|
EXPECT_EQ(config.rtp.remb, receiver_config.remb());
|
|
// Check RTX map.
|
|
ASSERT_EQ(static_cast<int>(config.rtp.rtx.size()),
|
|
receiver_config.rtx_map_size());
|
|
for (const rtclog::RtxMap& rtx_map : receiver_config.rtx_map()) {
|
|
ASSERT_TRUE(rtx_map.has_payload_type());
|
|
ASSERT_TRUE(rtx_map.has_config());
|
|
EXPECT_EQ(1u, config.rtp.rtx.count(rtx_map.payload_type()));
|
|
const rtclog::RtxConfig& rtx_config = rtx_map.config();
|
|
const VideoReceiveStream::Config::Rtp::Rtx& rtx =
|
|
config.rtp.rtx.at(rtx_map.payload_type());
|
|
ASSERT_TRUE(rtx_config.has_rtx_ssrc());
|
|
ASSERT_TRUE(rtx_config.has_rtx_payload_type());
|
|
EXPECT_EQ(rtx.ssrc, rtx_config.rtx_ssrc());
|
|
EXPECT_EQ(rtx.payload_type, rtx_config.rtx_payload_type());
|
|
}
|
|
// Check header extensions.
|
|
ASSERT_EQ(static_cast<int>(config.rtp.extensions.size()),
|
|
receiver_config.header_extensions_size());
|
|
for (int i = 0; i < receiver_config.header_extensions_size(); i++) {
|
|
ASSERT_TRUE(receiver_config.header_extensions(i).has_name());
|
|
ASSERT_TRUE(receiver_config.header_extensions(i).has_id());
|
|
const std::string& name = receiver_config.header_extensions(i).name();
|
|
int id = receiver_config.header_extensions(i).id();
|
|
EXPECT_EQ(config.rtp.extensions[i].id, id);
|
|
EXPECT_EQ(config.rtp.extensions[i].uri, name);
|
|
}
|
|
// Check decoders.
|
|
ASSERT_EQ(static_cast<int>(config.decoders.size()),
|
|
receiver_config.decoders_size());
|
|
for (int i = 0; i < receiver_config.decoders_size(); i++) {
|
|
ASSERT_TRUE(receiver_config.decoders(i).has_name());
|
|
ASSERT_TRUE(receiver_config.decoders(i).has_payload_type());
|
|
const std::string& decoder_name = receiver_config.decoders(i).name();
|
|
int decoder_type = receiver_config.decoders(i).payload_type();
|
|
EXPECT_EQ(config.decoders[i].payload_name, decoder_name);
|
|
EXPECT_EQ(config.decoders[i].payload_type, decoder_type);
|
|
}
|
|
|
|
// Check consistency of the parser.
|
|
VideoReceiveStream::Config parsed_config(nullptr);
|
|
parsed_log.GetVideoReceiveConfig(index, &parsed_config);
|
|
EXPECT_EQ(config.rtp.remote_ssrc, parsed_config.rtp.remote_ssrc);
|
|
EXPECT_EQ(config.rtp.local_ssrc, parsed_config.rtp.local_ssrc);
|
|
// Check RTCP settings.
|
|
EXPECT_EQ(config.rtp.rtcp_mode, parsed_config.rtp.rtcp_mode);
|
|
EXPECT_EQ(config.rtp.remb, parsed_config.rtp.remb);
|
|
// Check RTX map.
|
|
EXPECT_EQ(config.rtp.rtx.size(), parsed_config.rtp.rtx.size());
|
|
for (const auto& kv : config.rtp.rtx) {
|
|
auto parsed_kv = parsed_config.rtp.rtx.find(kv.first);
|
|
EXPECT_EQ(kv.first, parsed_kv->first);
|
|
EXPECT_EQ(kv.second.ssrc, parsed_kv->second.ssrc);
|
|
EXPECT_EQ(kv.second.payload_type, parsed_kv->second.payload_type);
|
|
}
|
|
// Check header extensions.
|
|
EXPECT_EQ(config.rtp.extensions.size(), parsed_config.rtp.extensions.size());
|
|
for (size_t i = 0; i < parsed_config.rtp.extensions.size(); i++) {
|
|
EXPECT_EQ(config.rtp.extensions[i].uri,
|
|
parsed_config.rtp.extensions[i].uri);
|
|
EXPECT_EQ(config.rtp.extensions[i].id, parsed_config.rtp.extensions[i].id);
|
|
}
|
|
// Check decoders.
|
|
EXPECT_EQ(config.decoders.size(), parsed_config.decoders.size());
|
|
for (size_t i = 0; i < parsed_config.decoders.size(); i++) {
|
|
EXPECT_EQ(config.decoders[i].payload_name,
|
|
parsed_config.decoders[i].payload_name);
|
|
EXPECT_EQ(config.decoders[i].payload_type,
|
|
parsed_config.decoders[i].payload_type);
|
|
}
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifySendStreamConfig(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
const VideoSendStream::Config& config) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT, event.type());
|
|
const rtclog::VideoSendConfig& sender_config = event.video_sender_config();
|
|
// Check SSRCs.
|
|
ASSERT_EQ(static_cast<int>(config.rtp.ssrcs.size()),
|
|
sender_config.ssrcs_size());
|
|
for (int i = 0; i < sender_config.ssrcs_size(); i++) {
|
|
EXPECT_EQ(config.rtp.ssrcs[i], sender_config.ssrcs(i));
|
|
}
|
|
// Check header extensions.
|
|
ASSERT_EQ(static_cast<int>(config.rtp.extensions.size()),
|
|
sender_config.header_extensions_size());
|
|
for (int i = 0; i < sender_config.header_extensions_size(); i++) {
|
|
ASSERT_TRUE(sender_config.header_extensions(i).has_name());
|
|
ASSERT_TRUE(sender_config.header_extensions(i).has_id());
|
|
const std::string& name = sender_config.header_extensions(i).name();
|
|
int id = sender_config.header_extensions(i).id();
|
|
EXPECT_EQ(config.rtp.extensions[i].id, id);
|
|
EXPECT_EQ(config.rtp.extensions[i].uri, name);
|
|
}
|
|
// Check RTX settings.
|
|
ASSERT_EQ(static_cast<int>(config.rtp.rtx.ssrcs.size()),
|
|
sender_config.rtx_ssrcs_size());
|
|
for (int i = 0; i < sender_config.rtx_ssrcs_size(); i++) {
|
|
EXPECT_EQ(config.rtp.rtx.ssrcs[i], sender_config.rtx_ssrcs(i));
|
|
}
|
|
if (sender_config.rtx_ssrcs_size() > 0) {
|
|
ASSERT_TRUE(sender_config.has_rtx_payload_type());
|
|
EXPECT_EQ(config.rtp.rtx.payload_type, sender_config.rtx_payload_type());
|
|
}
|
|
// Check encoder.
|
|
ASSERT_TRUE(sender_config.has_encoder());
|
|
ASSERT_TRUE(sender_config.encoder().has_name());
|
|
ASSERT_TRUE(sender_config.encoder().has_payload_type());
|
|
EXPECT_EQ(config.encoder_settings.payload_name,
|
|
sender_config.encoder().name());
|
|
EXPECT_EQ(config.encoder_settings.payload_type,
|
|
sender_config.encoder().payload_type());
|
|
|
|
// Check consistency of the parser.
|
|
VideoSendStream::Config parsed_config(nullptr);
|
|
parsed_log.GetVideoSendConfig(index, &parsed_config);
|
|
// Check SSRCs
|
|
EXPECT_EQ(config.rtp.ssrcs.size(), parsed_config.rtp.ssrcs.size());
|
|
for (size_t i = 0; i < config.rtp.ssrcs.size(); i++) {
|
|
EXPECT_EQ(config.rtp.ssrcs[i], parsed_config.rtp.ssrcs[i]);
|
|
}
|
|
// Check header extensions.
|
|
EXPECT_EQ(config.rtp.extensions.size(), parsed_config.rtp.extensions.size());
|
|
for (size_t i = 0; i < parsed_config.rtp.extensions.size(); i++) {
|
|
EXPECT_EQ(config.rtp.extensions[i].uri,
|
|
parsed_config.rtp.extensions[i].uri);
|
|
EXPECT_EQ(config.rtp.extensions[i].id, parsed_config.rtp.extensions[i].id);
|
|
}
|
|
// Check RTX settings.
|
|
EXPECT_EQ(config.rtp.rtx.ssrcs.size(), parsed_config.rtp.rtx.ssrcs.size());
|
|
for (size_t i = 0; i < config.rtp.rtx.ssrcs.size(); i++) {
|
|
EXPECT_EQ(config.rtp.rtx.ssrcs[i], parsed_config.rtp.rtx.ssrcs[i]);
|
|
}
|
|
EXPECT_EQ(config.rtp.rtx.payload_type, parsed_config.rtp.rtx.payload_type);
|
|
// Check encoder.
|
|
EXPECT_EQ(config.encoder_settings.payload_name,
|
|
parsed_config.encoder_settings.payload_name);
|
|
EXPECT_EQ(config.encoder_settings.payload_type,
|
|
parsed_config.encoder_settings.payload_type);
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyRtpEvent(const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
PacketDirection direction,
|
|
MediaType media_type,
|
|
const uint8_t* header,
|
|
size_t header_size,
|
|
size_t total_size) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::RTP_EVENT, event.type());
|
|
const rtclog::RtpPacket& rtp_packet = event.rtp_packet();
|
|
ASSERT_TRUE(rtp_packet.has_incoming());
|
|
EXPECT_EQ(direction == kIncomingPacket, rtp_packet.incoming());
|
|
ASSERT_TRUE(rtp_packet.has_type());
|
|
EXPECT_EQ(media_type, GetRuntimeMediaType(rtp_packet.type()));
|
|
ASSERT_TRUE(rtp_packet.has_packet_length());
|
|
EXPECT_EQ(total_size, rtp_packet.packet_length());
|
|
ASSERT_TRUE(rtp_packet.has_header());
|
|
ASSERT_EQ(header_size, rtp_packet.header().size());
|
|
for (size_t i = 0; i < header_size; i++) {
|
|
EXPECT_EQ(header[i], static_cast<uint8_t>(rtp_packet.header()[i]));
|
|
}
|
|
|
|
// Check consistency of the parser.
|
|
PacketDirection parsed_direction;
|
|
MediaType parsed_media_type;
|
|
uint8_t parsed_header[1500];
|
|
size_t parsed_header_size, parsed_total_size;
|
|
parsed_log.GetRtpHeader(index, &parsed_direction, &parsed_media_type,
|
|
parsed_header, &parsed_header_size,
|
|
&parsed_total_size);
|
|
EXPECT_EQ(direction, parsed_direction);
|
|
EXPECT_EQ(media_type, parsed_media_type);
|
|
ASSERT_EQ(header_size, parsed_header_size);
|
|
EXPECT_EQ(0, std::memcmp(header, parsed_header, header_size));
|
|
EXPECT_EQ(total_size, parsed_total_size);
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyRtcpEvent(const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
PacketDirection direction,
|
|
MediaType media_type,
|
|
const uint8_t* packet,
|
|
size_t total_size) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::RTCP_EVENT, event.type());
|
|
const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet();
|
|
ASSERT_TRUE(rtcp_packet.has_incoming());
|
|
EXPECT_EQ(direction == kIncomingPacket, rtcp_packet.incoming());
|
|
ASSERT_TRUE(rtcp_packet.has_type());
|
|
EXPECT_EQ(media_type, GetRuntimeMediaType(rtcp_packet.type()));
|
|
ASSERT_TRUE(rtcp_packet.has_packet_data());
|
|
ASSERT_EQ(total_size, rtcp_packet.packet_data().size());
|
|
for (size_t i = 0; i < total_size; i++) {
|
|
EXPECT_EQ(packet[i], static_cast<uint8_t>(rtcp_packet.packet_data()[i]));
|
|
}
|
|
|
|
// Check consistency of the parser.
|
|
PacketDirection parsed_direction;
|
|
MediaType parsed_media_type;
|
|
uint8_t parsed_packet[1500];
|
|
size_t parsed_total_size;
|
|
parsed_log.GetRtcpPacket(index, &parsed_direction, &parsed_media_type,
|
|
parsed_packet, &parsed_total_size);
|
|
EXPECT_EQ(direction, parsed_direction);
|
|
EXPECT_EQ(media_type, parsed_media_type);
|
|
ASSERT_EQ(total_size, parsed_total_size);
|
|
EXPECT_EQ(0, std::memcmp(packet, parsed_packet, total_size));
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyPlayoutEvent(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
uint32_t ssrc) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::AUDIO_PLAYOUT_EVENT, event.type());
|
|
const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
|
|
ASSERT_TRUE(playout_event.has_local_ssrc());
|
|
EXPECT_EQ(ssrc, playout_event.local_ssrc());
|
|
|
|
// Check consistency of the parser.
|
|
uint32_t parsed_ssrc;
|
|
parsed_log.GetAudioPlayout(index, &parsed_ssrc);
|
|
EXPECT_EQ(ssrc, parsed_ssrc);
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyBweLossEvent(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index,
|
|
int32_t bitrate,
|
|
uint8_t fraction_loss,
|
|
int32_t total_packets) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
ASSERT_EQ(rtclog::Event::BWE_PACKET_LOSS_EVENT, event.type());
|
|
const rtclog::BwePacketLossEvent& bwe_event = event.bwe_packet_loss_event();
|
|
ASSERT_TRUE(bwe_event.has_bitrate());
|
|
EXPECT_EQ(bitrate, bwe_event.bitrate());
|
|
ASSERT_TRUE(bwe_event.has_fraction_loss());
|
|
EXPECT_EQ(fraction_loss, bwe_event.fraction_loss());
|
|
ASSERT_TRUE(bwe_event.has_total_packets());
|
|
EXPECT_EQ(total_packets, bwe_event.total_packets());
|
|
|
|
// Check consistency of the parser.
|
|
int32_t parsed_bitrate;
|
|
uint8_t parsed_fraction_loss;
|
|
int32_t parsed_total_packets;
|
|
parsed_log.GetBwePacketLossEvent(
|
|
index, &parsed_bitrate, &parsed_fraction_loss, &parsed_total_packets);
|
|
EXPECT_EQ(bitrate, parsed_bitrate);
|
|
EXPECT_EQ(fraction_loss, parsed_fraction_loss);
|
|
EXPECT_EQ(total_packets, parsed_total_packets);
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyLogStartEvent(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
EXPECT_EQ(rtclog::Event::LOG_START, event.type());
|
|
}
|
|
|
|
void RtcEventLogTestHelper::VerifyLogEndEvent(
|
|
const ParsedRtcEventLog& parsed_log,
|
|
size_t index) {
|
|
const rtclog::Event& event = parsed_log.stream_[index];
|
|
ASSERT_TRUE(IsValidBasicEvent(event));
|
|
EXPECT_EQ(rtclog::Event::LOG_END, event.type());
|
|
}
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // ENABLE_RTC_EVENT_LOG
|