Reland of "Log audio network adapter decisions in event log."
This was originally reviewed https://codereview.webrtc.org/2559953002/ It was reverted due to a bug in the original CL, see https://codereview.webrtc.org/2631703002/ This CL is to fix and reland. BUG=webrtc:6845 Review-Url: https://codereview.webrtc.org/2644863002 Cr-Commit-Position: refs/heads/master@{#16242}
This commit is contained in:
parent
35a32700fc
commit
4b7c952376
@ -42,6 +42,7 @@ rtc_static_library("rtc_event_log_impl") {
|
||||
":rtc_event_log_api",
|
||||
"..:webrtc_common",
|
||||
"../call:call_interfaces",
|
||||
"../modules/audio_coding:audio_network_adaptor",
|
||||
"../modules/rtp_rtcp",
|
||||
]
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
include_rules = [
|
||||
"+webrtc/base",
|
||||
"+webrtc/call",
|
||||
"+webrtc/modules/audio_coding/audio_network_adaptor",
|
||||
"+webrtc/modules/rtp_rtcp",
|
||||
"+webrtc/system_wrappers",
|
||||
]
|
||||
|
||||
@ -58,6 +58,8 @@ class MockRtcEventLog : public RtcEventLog {
|
||||
void(int32_t bitrate,
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets));
|
||||
MOCK_METHOD1(LogAudioNetworkAdaptation,
|
||||
void(const AudioNetworkAdaptor::EncoderRuntimeConfig& config));
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -77,6 +77,8 @@ class RtcEventLogImpl final : public RtcEventLog {
|
||||
void LogBwePacketLossEvent(int32_t bitrate,
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets) override;
|
||||
void LogAudioNetworkAdaptation(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) override;
|
||||
|
||||
private:
|
||||
void StoreEvent(std::unique_ptr<rtclog::Event>* event);
|
||||
@ -434,6 +436,29 @@ void RtcEventLogImpl::LogBwePacketLossEvent(int32_t bitrate,
|
||||
StoreEvent(&event);
|
||||
}
|
||||
|
||||
void RtcEventLogImpl::LogAudioNetworkAdaptation(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) {
|
||||
std::unique_ptr<rtclog::Event> event(new rtclog::Event());
|
||||
event->set_timestamp_us(rtc::TimeMicros());
|
||||
event->set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
|
||||
auto audio_network_adaptation = event->mutable_audio_network_adaptation();
|
||||
if (config.bitrate_bps)
|
||||
audio_network_adaptation->set_bitrate_bps(*config.bitrate_bps);
|
||||
if (config.frame_length_ms)
|
||||
audio_network_adaptation->set_frame_length_ms(*config.frame_length_ms);
|
||||
if (config.uplink_packet_loss_fraction) {
|
||||
audio_network_adaptation->set_uplink_packet_loss_fraction(
|
||||
*config.uplink_packet_loss_fraction);
|
||||
}
|
||||
if (config.enable_fec)
|
||||
audio_network_adaptation->set_enable_fec(*config.enable_fec);
|
||||
if (config.enable_dtx)
|
||||
audio_network_adaptation->set_enable_dtx(*config.enable_dtx);
|
||||
if (config.num_channels)
|
||||
audio_network_adaptation->set_num_channels(*config.num_channels);
|
||||
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.";
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "webrtc/base/platform_file.h"
|
||||
#include "webrtc/call/audio_receive_stream.h"
|
||||
#include "webrtc/call/audio_send_stream.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
||||
#include "webrtc/video_receive_stream.h"
|
||||
#include "webrtc/video_send_stream.h"
|
||||
|
||||
@ -114,6 +115,10 @@ class RtcEventLog {
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets) = 0;
|
||||
|
||||
// Logs audio encoder re-configuration driven by audio network adaptor.
|
||||
virtual void LogAudioNetworkAdaptation(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) = 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.
|
||||
@ -155,6 +160,8 @@ class RtcEventLogNullImpl final : public RtcEventLog {
|
||||
void LogBwePacketLossEvent(int32_t bitrate,
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets) override {}
|
||||
void LogAudioNetworkAdaptation(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) override{};
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -37,6 +37,7 @@ message Event {
|
||||
VIDEO_SENDER_CONFIG_EVENT = 9;
|
||||
AUDIO_RECEIVER_CONFIG_EVENT = 10;
|
||||
AUDIO_SENDER_CONFIG_EVENT = 11;
|
||||
AUDIO_NETWORK_ADAPTATION_EVENT = 16;
|
||||
}
|
||||
|
||||
// required - Indicates the type of this event
|
||||
@ -65,6 +66,9 @@ message Event {
|
||||
|
||||
// optional - but required if type == AUDIO_SENDER_CONFIG_EVENT
|
||||
optional AudioSendConfig audio_sender_config = 11;
|
||||
|
||||
// optional - but required if type == AUDIO_NETWORK_ADAPTATION_EVENT
|
||||
optional AudioNetworkAdaptation audio_network_adaptation = 16;
|
||||
}
|
||||
|
||||
message RtpPacket {
|
||||
@ -227,3 +231,24 @@ message AudioSendConfig {
|
||||
// RTP header extensions used for the outgoing audio stream.
|
||||
repeated RtpHeaderExtension header_extensions = 2;
|
||||
}
|
||||
|
||||
message AudioNetworkAdaptation {
|
||||
// Bit rate that the audio encoder is operating at.
|
||||
optional int32 bitrate_bps = 1;
|
||||
|
||||
// Frame length that each encoded audio packet consists of.
|
||||
optional int32 frame_length_ms = 2;
|
||||
|
||||
// Packet loss fraction that the encoder's forward error correction (FEC) is
|
||||
// optimized for.
|
||||
optional float uplink_packet_loss_fraction = 3;
|
||||
|
||||
// Whether forward error correction (FEC) is turned on or off.
|
||||
optional bool enable_fec = 4;
|
||||
|
||||
// Whether discontinuous transmission (DTX) is turned on or off.
|
||||
optional bool enable_dtx = 5;
|
||||
|
||||
// Number of audio channels that each encoded packet consists of.
|
||||
optional uint32 num_channels = 6;
|
||||
}
|
||||
@ -79,6 +79,8 @@ ParsedRtcEventLog::EventType GetRuntimeEventType(
|
||||
return ParsedRtcEventLog::EventType::AUDIO_RECEIVER_CONFIG_EVENT;
|
||||
case rtclog::Event::AUDIO_SENDER_CONFIG_EVENT:
|
||||
return ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT;
|
||||
case rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT:
|
||||
return ParsedRtcEventLog::EventType::AUDIO_NETWORK_ADAPTATION_EVENT;
|
||||
}
|
||||
RTC_NOTREACHED();
|
||||
return ParsedRtcEventLog::EventType::UNKNOWN_EVENT;
|
||||
@ -454,4 +456,29 @@ void ParsedRtcEventLog::GetBwePacketLossEvent(size_t index,
|
||||
}
|
||||
}
|
||||
|
||||
void ParsedRtcEventLog::GetAudioNetworkAdaptation(
|
||||
size_t index,
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig* config) const {
|
||||
RTC_CHECK_LT(index, GetNumberOfEvents());
|
||||
const rtclog::Event& event = events_[index];
|
||||
RTC_CHECK(event.has_type());
|
||||
RTC_CHECK_EQ(event.type(), rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
|
||||
RTC_CHECK(event.has_audio_network_adaptation());
|
||||
const rtclog::AudioNetworkAdaptation& ana_event =
|
||||
event.audio_network_adaptation();
|
||||
if (ana_event.has_bitrate_bps())
|
||||
config->bitrate_bps = rtc::Optional<int>(ana_event.bitrate_bps());
|
||||
if (ana_event.has_enable_fec())
|
||||
config->enable_fec = rtc::Optional<bool>(ana_event.enable_fec());
|
||||
if (ana_event.has_enable_dtx())
|
||||
config->enable_dtx = rtc::Optional<bool>(ana_event.enable_dtx());
|
||||
if (ana_event.has_frame_length_ms())
|
||||
config->frame_length_ms = rtc::Optional<int>(ana_event.frame_length_ms());
|
||||
if (ana_event.has_num_channels())
|
||||
config->num_channels = rtc::Optional<size_t>(ana_event.num_channels());
|
||||
if (ana_event.has_uplink_packet_loss_fraction())
|
||||
config->uplink_packet_loss_fraction =
|
||||
rtc::Optional<float>(ana_event.uplink_packet_loss_fraction());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -47,7 +47,8 @@ class ParsedRtcEventLog {
|
||||
VIDEO_RECEIVER_CONFIG_EVENT = 8,
|
||||
VIDEO_SENDER_CONFIG_EVENT = 9,
|
||||
AUDIO_RECEIVER_CONFIG_EVENT = 10,
|
||||
AUDIO_SENDER_CONFIG_EVENT = 11
|
||||
AUDIO_SENDER_CONFIG_EVENT = 11,
|
||||
AUDIO_NETWORK_ADAPTATION_EVENT = 16
|
||||
};
|
||||
|
||||
// Reads an RtcEventLog file and returns true if parsing was successful.
|
||||
@ -123,6 +124,13 @@ class ParsedRtcEventLog {
|
||||
uint8_t* fraction_loss,
|
||||
int32_t* total_packets) const;
|
||||
|
||||
// Reads a audio network adaptation event to a (non-NULL)
|
||||
// AudioNetworkAdaptor::EncoderRuntimeConfig struct. Only the fields that are
|
||||
// stored in the protobuf will be written.
|
||||
void GetAudioNetworkAdaptation(
|
||||
size_t index,
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig* config) const;
|
||||
|
||||
private:
|
||||
std::vector<rtclog::Event> events_;
|
||||
};
|
||||
|
||||
@ -228,6 +228,19 @@ void GenerateAudioSendConfig(uint32_t extensions_bitvector,
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateAudioNetworkAdaptation(
|
||||
uint32_t extensions_bitvector,
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig* config,
|
||||
Random* prng) {
|
||||
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>());
|
||||
}
|
||||
|
||||
// Test for the RtcEventLog class. Dumps some RTP packets and other events
|
||||
// to disk, then reads them back to see if they match.
|
||||
void LogSessionAndReadBack(size_t rtp_count,
|
||||
@ -604,6 +617,22 @@ class VideoSendConfigReadWriteTest : public ConfigReadWriteTest {
|
||||
VideoSendStream::Config config;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig config;
|
||||
};
|
||||
|
||||
TEST(RtcEventLogTest, LogAudioReceiveConfig) {
|
||||
AudioReceiveConfigReadWriteTest test;
|
||||
test.DoTest();
|
||||
@ -623,4 +652,10 @@ TEST(RtcEventLogTest, LogVideoSendConfig) {
|
||||
VideoSendConfigReadWriteTest test;
|
||||
test.DoTest();
|
||||
}
|
||||
|
||||
TEST(RtcEventLogTest, LogAudioNetworkAdaptation) {
|
||||
AudioNetworkAdaptationReadWriteTest test;
|
||||
test.DoTest();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -461,6 +461,21 @@ void RtcEventLogTestHelper::VerifyBweLossEvent(
|
||||
EXPECT_EQ(total_packets, parsed_total_packets);
|
||||
}
|
||||
|
||||
void RtcEventLogTestHelper::VerifyAudioNetworkAdaptation(
|
||||
const ParsedRtcEventLog& parsed_log,
|
||||
size_t index,
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) {
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig parsed_config;
|
||||
parsed_log.GetAudioNetworkAdaptation(index, &parsed_config);
|
||||
EXPECT_EQ(config.bitrate_bps, parsed_config.bitrate_bps);
|
||||
EXPECT_EQ(config.enable_dtx, parsed_config.enable_dtx);
|
||||
EXPECT_EQ(config.enable_fec, parsed_config.enable_fec);
|
||||
EXPECT_EQ(config.frame_length_ms, parsed_config.frame_length_ms);
|
||||
EXPECT_EQ(config.num_channels, parsed_config.num_channels);
|
||||
EXPECT_EQ(config.uplink_packet_loss_fraction,
|
||||
parsed_config.uplink_packet_loss_fraction);
|
||||
}
|
||||
|
||||
void RtcEventLogTestHelper::VerifyLogStartEvent(
|
||||
const ParsedRtcEventLog& parsed_log,
|
||||
size_t index) {
|
||||
|
||||
@ -56,6 +56,11 @@ class RtcEventLogTestHelper {
|
||||
uint8_t fraction_loss,
|
||||
int32_t total_packets);
|
||||
|
||||
static void VerifyAudioNetworkAdaptation(
|
||||
const ParsedRtcEventLog& parsed_log,
|
||||
size_t index,
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config);
|
||||
|
||||
static void VerifyLogStartEvent(const ParsedRtcEventLog& parsed_log,
|
||||
size_t index);
|
||||
static void VerifyLogEndEvent(const ParsedRtcEventLog& parsed_log,
|
||||
|
||||
@ -914,6 +914,8 @@ rtc_static_library("audio_network_adaptor") {
|
||||
"audio_network_adaptor/debug_dump_writer.h",
|
||||
"audio_network_adaptor/dtx_controller.cc",
|
||||
"audio_network_adaptor/dtx_controller.h",
|
||||
"audio_network_adaptor/event_log_writer.cc",
|
||||
"audio_network_adaptor/event_log_writer.h",
|
||||
"audio_network_adaptor/fec_controller.cc",
|
||||
"audio_network_adaptor/fec_controller.h",
|
||||
"audio_network_adaptor/frame_length_controller.cc",
|
||||
@ -925,6 +927,7 @@ rtc_static_library("audio_network_adaptor") {
|
||||
"../..:webrtc_common",
|
||||
"../../base:rtc_base_approved",
|
||||
"../../common_audio",
|
||||
"../../logging:rtc_event_log_api",
|
||||
"../../system_wrappers",
|
||||
]
|
||||
|
||||
@ -935,6 +938,11 @@ rtc_static_library("audio_network_adaptor") {
|
||||
]
|
||||
defines = [ "WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP" ]
|
||||
}
|
||||
|
||||
if (!build_with_chromium && is_clang) {
|
||||
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
}
|
||||
|
||||
rtc_static_library("neteq") {
|
||||
@ -1935,6 +1943,7 @@ if (rtc_include_tests) {
|
||||
"audio_network_adaptor/channel_controller_unittest.cc",
|
||||
"audio_network_adaptor/controller_manager_unittest.cc",
|
||||
"audio_network_adaptor/dtx_controller_unittest.cc",
|
||||
"audio_network_adaptor/event_log_writer_unittest.cc",
|
||||
"audio_network_adaptor/fec_controller_unittest.cc",
|
||||
"audio_network_adaptor/frame_length_controller_unittest.cc",
|
||||
"audio_network_adaptor/mock/mock_controller.h",
|
||||
|
||||
@ -12,8 +12,16 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
constexpr int kEventLogMinBitrateChangeBps = 5000;
|
||||
constexpr float kEventLogMinBitrateChangeFraction = 0.25;
|
||||
constexpr float kEventLogMinPacketLossChangeFraction = 0.5;
|
||||
} // namespace
|
||||
|
||||
AudioNetworkAdaptorImpl::Config::Config()
|
||||
: event_log(nullptr), clock(nullptr){};
|
||||
|
||||
@ -25,7 +33,14 @@ AudioNetworkAdaptorImpl::AudioNetworkAdaptorImpl(
|
||||
std::unique_ptr<DebugDumpWriter> debug_dump_writer)
|
||||
: config_(config),
|
||||
controller_manager_(std::move(controller_manager)),
|
||||
debug_dump_writer_(std::move(debug_dump_writer)) {
|
||||
debug_dump_writer_(std::move(debug_dump_writer)),
|
||||
event_log_writer_(
|
||||
config.event_log
|
||||
? new EventLogWriter(config.event_log,
|
||||
kEventLogMinBitrateChangeBps,
|
||||
kEventLogMinBitrateChangeFraction,
|
||||
kEventLogMinPacketLossChangeFraction)
|
||||
: nullptr) {
|
||||
RTC_DCHECK(controller_manager_);
|
||||
}
|
||||
|
||||
@ -68,11 +83,13 @@ AudioNetworkAdaptorImpl::GetEncoderRuntimeConfig() {
|
||||
controller_manager_->GetSortedControllers(last_metrics_))
|
||||
controller->MakeDecision(last_metrics_, &config);
|
||||
|
||||
// TODO(minyue): Add debug dumping.
|
||||
if (debug_dump_writer_)
|
||||
debug_dump_writer_->DumpEncoderRuntimeConfig(
|
||||
config, config_.clock->TimeInMilliseconds());
|
||||
|
||||
if (event_log_writer_)
|
||||
event_log_writer_->MaybeLogEncoderConfig(config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/event_log_writer.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
|
||||
@ -65,6 +66,8 @@ class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor {
|
||||
|
||||
std::unique_ptr<DebugDumpWriter> debug_dump_writer_;
|
||||
|
||||
const std::unique_ptr<EventLogWriter> event_log_writer_;
|
||||
|
||||
Controller::NetworkMetrics last_metrics_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioNetworkAdaptorImpl);
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_controller_manager.h"
|
||||
@ -52,6 +53,7 @@ struct AudioNetworkAdaptorStates {
|
||||
std::unique_ptr<AudioNetworkAdaptorImpl> audio_network_adaptor;
|
||||
std::vector<std::unique_ptr<MockController>> mock_controllers;
|
||||
std::unique_ptr<SimulatedClock> simulated_clock;
|
||||
std::unique_ptr<MockRtcEventLog> event_log;
|
||||
MockDebugDumpWriter* mock_debug_dump_writer;
|
||||
};
|
||||
|
||||
@ -76,6 +78,7 @@ AudioNetworkAdaptorStates CreateAudioNetworkAdaptor() {
|
||||
.WillRepeatedly(Return(controllers));
|
||||
|
||||
states.simulated_clock.reset(new SimulatedClock(kClockInitialTimeMs * 1000));
|
||||
states.event_log.reset(new NiceMock<MockRtcEventLog>());
|
||||
|
||||
auto debug_dump_writer =
|
||||
std::unique_ptr<MockDebugDumpWriter>(new NiceMock<MockDebugDumpWriter>());
|
||||
@ -84,6 +87,7 @@ AudioNetworkAdaptorStates CreateAudioNetworkAdaptor() {
|
||||
|
||||
AudioNetworkAdaptorImpl::Config config;
|
||||
config.clock = states.simulated_clock.get();
|
||||
config.event_log = states.event_log.get();
|
||||
// AudioNetworkAdaptorImpl governs the lifetime of controller manager.
|
||||
states.audio_network_adaptor.reset(new AudioNetworkAdaptorImpl(
|
||||
config,
|
||||
@ -205,4 +209,20 @@ TEST(AudioNetworkAdaptorImplTest,
|
||||
states.audio_network_adaptor->SetOverhead(kOverhead);
|
||||
}
|
||||
|
||||
TEST(AudioNetworkAdaptorImplTest, LogRuntimeConfigOnGetEncoderRuntimeConfig) {
|
||||
auto states = CreateAudioNetworkAdaptor();
|
||||
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig config;
|
||||
config.bitrate_bps = rtc::Optional<int>(32000);
|
||||
config.enable_fec = rtc::Optional<bool>(true);
|
||||
|
||||
EXPECT_CALL(*states.mock_controllers[0], MakeDecision(_, _))
|
||||
.WillOnce(SetArgPointee<1>(config));
|
||||
|
||||
EXPECT_CALL(*states.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(config)))
|
||||
.Times(1);
|
||||
states.audio_network_adaptor->GetEncoderRuntimeConfig();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/event_log_writer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
EventLogWriter::EventLogWriter(RtcEventLog* event_log,
|
||||
int min_bitrate_change_bps,
|
||||
float min_bitrate_change_fraction,
|
||||
float min_packet_loss_change_fraction)
|
||||
: event_log_(event_log),
|
||||
min_bitrate_change_bps_(min_bitrate_change_bps),
|
||||
min_bitrate_change_fraction_(min_bitrate_change_fraction),
|
||||
min_packet_loss_change_fraction_(min_packet_loss_change_fraction) {
|
||||
RTC_DCHECK(event_log_);
|
||||
}
|
||||
|
||||
EventLogWriter::~EventLogWriter() = default;
|
||||
|
||||
void EventLogWriter::MaybeLogEncoderConfig(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) {
|
||||
if (last_logged_config_.num_channels != config.num_channels)
|
||||
return LogEncoderConfig(config);
|
||||
if (last_logged_config_.enable_dtx != config.enable_dtx)
|
||||
return LogEncoderConfig(config);
|
||||
if (last_logged_config_.enable_fec != config.enable_fec)
|
||||
return LogEncoderConfig(config);
|
||||
if (last_logged_config_.frame_length_ms != config.frame_length_ms)
|
||||
return LogEncoderConfig(config);
|
||||
if ((!last_logged_config_.bitrate_bps && config.bitrate_bps) ||
|
||||
(last_logged_config_.bitrate_bps && config.bitrate_bps &&
|
||||
std::abs(*last_logged_config_.bitrate_bps - *config.bitrate_bps) >=
|
||||
std::min(static_cast<int>(*last_logged_config_.bitrate_bps *
|
||||
min_bitrate_change_fraction_),
|
||||
min_bitrate_change_bps_))) {
|
||||
return LogEncoderConfig(config);
|
||||
}
|
||||
if ((!last_logged_config_.uplink_packet_loss_fraction &&
|
||||
config.uplink_packet_loss_fraction) ||
|
||||
(last_logged_config_.uplink_packet_loss_fraction &&
|
||||
config.uplink_packet_loss_fraction &&
|
||||
fabs(*last_logged_config_.uplink_packet_loss_fraction -
|
||||
*config.uplink_packet_loss_fraction) >=
|
||||
min_packet_loss_change_fraction_ *
|
||||
*last_logged_config_.uplink_packet_loss_fraction)) {
|
||||
return LogEncoderConfig(config);
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogWriter::LogEncoderConfig(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) {
|
||||
event_log_->LogAudioNetworkAdaptation(config);
|
||||
last_logged_config_ = config;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_EVENT_LOG_WRITER_H_
|
||||
#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_EVENT_LOG_WRITER_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
|
||||
|
||||
namespace webrtc {
|
||||
class RtcEventLog;
|
||||
|
||||
class EventLogWriter final {
|
||||
public:
|
||||
EventLogWriter(RtcEventLog* event_log,
|
||||
int min_bitrate_change_bps,
|
||||
float min_bitrate_change_fraction,
|
||||
float min_packet_loss_change_fraction);
|
||||
~EventLogWriter();
|
||||
void MaybeLogEncoderConfig(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config);
|
||||
|
||||
private:
|
||||
void LogEncoderConfig(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config);
|
||||
|
||||
RtcEventLog* const event_log_;
|
||||
const int min_bitrate_change_bps_;
|
||||
const float min_bitrate_change_fraction_;
|
||||
const float min_packet_loss_change_fraction_;
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig last_logged_config_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(EventLogWriter);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_EVENT_LOG_WRITER_H_
|
||||
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "webrtc/modules/audio_coding/audio_network_adaptor/event_log_writer.h"
|
||||
#include "webrtc/test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kMinBitrateChangeBps = 5000;
|
||||
constexpr float kMinPacketLossChangeFraction = 0.5;
|
||||
constexpr float kMinBitrateChangeFraction = 0.25;
|
||||
|
||||
constexpr int kHighBitrateBps = 70000;
|
||||
constexpr int kLowBitrateBps = 10000;
|
||||
constexpr int kFrameLengthMs = 60;
|
||||
constexpr bool kEnableFec = true;
|
||||
constexpr bool kEnableDtx = true;
|
||||
constexpr float kPacketLossFraction = 0.05f;
|
||||
constexpr size_t kNumChannels = 1;
|
||||
|
||||
MATCHER_P(EncoderRuntimeConfigIs, config, "") {
|
||||
return arg.bitrate_bps == config.bitrate_bps &&
|
||||
arg.frame_length_ms == config.frame_length_ms &&
|
||||
arg.uplink_packet_loss_fraction ==
|
||||
config.uplink_packet_loss_fraction &&
|
||||
arg.enable_fec == config.enable_fec &&
|
||||
arg.enable_dtx == config.enable_dtx &&
|
||||
arg.num_channels == config.num_channels;
|
||||
}
|
||||
|
||||
struct EventLogWriterStates {
|
||||
std::unique_ptr<EventLogWriter> event_log_writer;
|
||||
std::unique_ptr<testing::StrictMock<MockRtcEventLog>> event_log;
|
||||
AudioNetworkAdaptor::EncoderRuntimeConfig runtime_config;
|
||||
};
|
||||
|
||||
EventLogWriterStates CreateEventLogWriter() {
|
||||
EventLogWriterStates state;
|
||||
state.event_log.reset(new testing::StrictMock<MockRtcEventLog>());
|
||||
state.event_log_writer.reset(new EventLogWriter(
|
||||
state.event_log.get(), kMinBitrateChangeBps, kMinBitrateChangeFraction,
|
||||
kMinPacketLossChangeFraction));
|
||||
state.runtime_config.bitrate_bps = rtc::Optional<int>(kHighBitrateBps);
|
||||
state.runtime_config.frame_length_ms = rtc::Optional<int>(kFrameLengthMs);
|
||||
state.runtime_config.uplink_packet_loss_fraction =
|
||||
rtc::Optional<float>(kPacketLossFraction);
|
||||
state.runtime_config.enable_fec = rtc::Optional<bool>(kEnableFec);
|
||||
state.runtime_config.enable_dtx = rtc::Optional<bool>(kEnableDtx);
|
||||
state.runtime_config.num_channels = rtc::Optional<size_t>(kNumChannels);
|
||||
return state;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(EventLogWriterTest, FirstConfigIsLogged) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, SameConfigIsNotLogged) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogFecStateChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
|
||||
state.runtime_config.enable_fec = rtc::Optional<bool>(!kEnableFec);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogDtxStateChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
|
||||
state.runtime_config.enable_dtx = rtc::Optional<bool>(!kEnableDtx);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogChannelChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
|
||||
state.runtime_config.num_channels = rtc::Optional<size_t>(kNumChannels + 1);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogFrameLengthChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
|
||||
state.runtime_config.frame_length_ms = rtc::Optional<int>(20);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, DoNotLogSmallBitrateChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.runtime_config.bitrate_bps =
|
||||
rtc::Optional<int>(kHighBitrateBps + kMinBitrateChangeBps - 1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogLargeBitrateChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
// At high bitrate, the min fraction rule requires a larger change than the
|
||||
// min change rule. We make sure that the min change rule applies.
|
||||
RTC_DCHECK_GT(kHighBitrateBps * kMinBitrateChangeFraction,
|
||||
kMinBitrateChangeBps);
|
||||
state.runtime_config.bitrate_bps =
|
||||
rtc::Optional<int>(kHighBitrateBps + kMinBitrateChangeBps);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogMinBitrateChangeFractionOnLowBitrateChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
state.runtime_config.bitrate_bps = rtc::Optional<int>(kLowBitrateBps);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
// At high bitrate, the min change rule requires a larger change than the min
|
||||
// fraction rule. We make sure that the min fraction rule applies.
|
||||
state.runtime_config.bitrate_bps = rtc::Optional<int>(
|
||||
kLowBitrateBps + kLowBitrateBps * kMinBitrateChangeFraction);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, DoNotLogSmallPacketLossFractionChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.runtime_config.uplink_packet_loss_fraction = rtc::Optional<float>(
|
||||
kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction -
|
||||
0.001f);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogLargePacketLossFractionChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.runtime_config.uplink_packet_loss_fraction = rtc::Optional<float>(
|
||||
kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogJustOnceOnMultipleChanges) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.runtime_config.uplink_packet_loss_fraction = rtc::Optional<float>(
|
||||
kPacketLossFraction + kMinPacketLossChangeFraction * kPacketLossFraction);
|
||||
state.runtime_config.frame_length_ms = rtc::Optional<int>(20);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
|
||||
TEST(EventLogWriterTest, LogAfterGradualChange) {
|
||||
auto state = CreateEventLogWriter();
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
state.runtime_config.bitrate_bps =
|
||||
rtc::Optional<int>(kHighBitrateBps + kMinBitrateChangeBps);
|
||||
EXPECT_CALL(
|
||||
*state.event_log,
|
||||
LogAudioNetworkAdaptation(EncoderRuntimeConfigIs(state.runtime_config)))
|
||||
.Times(1);
|
||||
for (int bitrate_bps = kHighBitrateBps;
|
||||
bitrate_bps <= kHighBitrateBps + kMinBitrateChangeBps; bitrate_bps++) {
|
||||
state.runtime_config.bitrate_bps = rtc::Optional<int>(bitrate_bps);
|
||||
state.event_log_writer->MaybeLogEncoderConfig(state.runtime_config);
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
||||
@ -205,6 +205,7 @@ if (rtc_enable_protobuf) {
|
||||
"../call:call_interfaces",
|
||||
"../logging:rtc_event_log_impl",
|
||||
"../logging:rtc_event_log_parser",
|
||||
"../modules/audio_coding:ana_debug_dump_proto",
|
||||
|
||||
# TODO(kwiberg): Remove this dependency.
|
||||
"../modules/audio_coding:audio_format",
|
||||
|
||||
@ -423,6 +423,9 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log)
|
||||
bwe_loss_updates_.push_back(bwe_update);
|
||||
break;
|
||||
}
|
||||
case ParsedRtcEventLog::AUDIO_NETWORK_ADAPTATION_EVENT: {
|
||||
break;
|
||||
}
|
||||
case ParsedRtcEventLog::BWE_PACKET_DELAY_EVENT: {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -140,6 +140,14 @@ class RtcEventLogProxy final : public webrtc::RtcEventLog {
|
||||
}
|
||||
}
|
||||
|
||||
void LogAudioNetworkAdaptation(
|
||||
const AudioNetworkAdaptor::EncoderRuntimeConfig& config) override {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (event_log_) {
|
||||
event_log_->LogAudioNetworkAdaptation(config);
|
||||
}
|
||||
}
|
||||
|
||||
void SetEventLog(RtcEventLog* event_log) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
event_log_ = event_log;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user