Relanding of "Adding debug dump to audio network adaptor."

The original CL was https://codereview.webrtc.org/2356763002

but got reverted https://codereview.webrtc.org/2362003002/.

The error was that ana_debug_dump_proto as a proto_library was placed under rtc_include_tests.

BUG=webrtc:6303

Review-Url: https://codereview.webrtc.org/2365723002
Cr-Commit-Position: refs/heads/master@{#14363}
This commit is contained in:
minyue
2016-09-22 22:23:20 -07:00
committed by Commit bot
parent 161b3907ab
commit 25f6a39181
11 changed files with 414 additions and 9 deletions

View File

@ -696,6 +696,15 @@ rtc_source_set("webrtc_opus") {
}
}
if (rtc_enable_protobuf) {
proto_library("ana_debug_dump_proto") {
sources = [
"audio_network_adaptor/debug_dump.proto",
]
proto_out_dir = "webrtc/modules/audio_coding/audio_network_adaptor"
}
}
source_set("audio_network_adaptor") {
sources = [
"audio_network_adaptor/audio_network_adaptor.cc",
@ -709,6 +718,8 @@ source_set("audio_network_adaptor") {
"audio_network_adaptor/controller.h",
"audio_network_adaptor/controller_manager.cc",
"audio_network_adaptor/controller_manager.h",
"audio_network_adaptor/debug_dump_writer.cc",
"audio_network_adaptor/debug_dump_writer.h",
"audio_network_adaptor/dtx_controller.cc",
"audio_network_adaptor/dtx_controller.h",
"audio_network_adaptor/fec_controller.cc",
@ -721,6 +732,13 @@ source_set("audio_network_adaptor") {
]
configs += [ "../..:common_config" ]
public_configs = [ "../..:common_inherited_config" ]
if (rtc_enable_protobuf) {
deps = [
":ana_debug_dump_proto",
]
defines = [ "WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP" ]
}
}
config("neteq_config") {

View File

@ -22,6 +22,8 @@
'controller.cc',
'controller_manager.cc',
'controller_manager.h',
'debug_dump_writer.cc',
'debug_dump_writer.h',
'dtx_controller.h',
'dtx_controller.cc',
'fec_controller.h',
@ -31,7 +33,32 @@
'include/audio_network_adaptor.h',
'smoothing_filter.h',
'smoothing_filter.cc',
], # source
], # sources
'conditions': [
['enable_protobuf==1', {
'dependencies': ['debug_dump_proto'],
'defines': ['WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP'],
}],
], # conditions
},
], # targets
'conditions': [
['enable_protobuf==1', {
'targets': [
{ 'target_name': 'debug_dump_proto',
'type': 'static_library',
'sources': ['debug_dump.proto',],
'variables': {
'proto_in_dir': '.',
# Workaround to protect against gyp's pathname relativization when
# this file is included by modules.gyp.
'proto_out_protected': 'webrtc/modules/audio_coding/audio_network_adaptor',
'proto_out_dir': '<(proto_out_protected)',
},
'includes': ['../../../build/protoc.gypi',],
},
], # targets
}],
], # conditions
}

View File

@ -8,10 +8,10 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <utility>
#include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"
#include <utility>
namespace webrtc {
AudioNetworkAdaptorImpl::Config::Config() = default;
@ -21,7 +21,15 @@ AudioNetworkAdaptorImpl::Config::~Config() = default;
AudioNetworkAdaptorImpl::AudioNetworkAdaptorImpl(
const Config& config,
std::unique_ptr<ControllerManager> controller_manager)
: config_(config), controller_manager_(std::move(controller_manager)) {
: AudioNetworkAdaptorImpl(config, std::move(controller_manager), nullptr) {}
AudioNetworkAdaptorImpl::AudioNetworkAdaptorImpl(
const Config& config,
std::unique_ptr<ControllerManager> controller_manager,
std::unique_ptr<DebugDumpWriter> debug_dump_writer)
: config_(config),
controller_manager_(std::move(controller_manager)),
debug_dump_writer_(std::move(debug_dump_writer)) {
RTC_DCHECK(controller_manager_);
}
@ -29,16 +37,19 @@ AudioNetworkAdaptorImpl::~AudioNetworkAdaptorImpl() = default;
void AudioNetworkAdaptorImpl::SetUplinkBandwidth(int uplink_bandwidth_bps) {
last_metrics_.uplink_bandwidth_bps = rtc::Optional<int>(uplink_bandwidth_bps);
// TODO(minyue): Add debug dumping.
DumpNetworkMetrics();
}
void AudioNetworkAdaptorImpl::SetUplinkPacketLossFraction(
float uplink_packet_loss_fraction) {
last_metrics_.uplink_packet_loss_fraction =
rtc::Optional<float>(uplink_packet_loss_fraction);
DumpNetworkMetrics();
}
// TODO(minyue): Add debug dumping.
void AudioNetworkAdaptorImpl::SetRtt(int rtt_ms) {
last_metrics_.rtt_ms = rtc::Optional<int>(rtt_ms);
DumpNetworkMetrics();
}
AudioNetworkAdaptor::EncoderRuntimeConfig
@ -49,6 +60,9 @@ AudioNetworkAdaptorImpl::GetEncoderRuntimeConfig() {
controller->MakeDecision(last_metrics_, &config);
// TODO(minyue): Add debug dumping.
if (debug_dump_writer_)
debug_dump_writer_->DumpEncoderRuntimeConfig(
config, config_.clock->TimeInMilliseconds());
return config;
}
@ -67,7 +81,17 @@ void AudioNetworkAdaptorImpl::SetReceiverFrameLengthRange(
}
void AudioNetworkAdaptorImpl::StartDebugDump(FILE* file_handle) {
// TODO(minyue): Implement this method.
debug_dump_writer_ = DebugDumpWriter::Create(file_handle);
}
void AudioNetworkAdaptorImpl::StopDebugDump() {
debug_dump_writer_.reset(nullptr);
}
void AudioNetworkAdaptorImpl::DumpNetworkMetrics() {
if (debug_dump_writer_)
debug_dump_writer_->DumpNetworkMetrics(last_metrics_,
config_.clock->TimeInMilliseconds());
}
} // namespace webrtc

View File

@ -16,7 +16,9 @@
#include "webrtc/base/constructormagic.h"
#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/include/audio_network_adaptor.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace webrtc {
@ -25,18 +27,27 @@ class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor {
struct Config {
Config();
~Config();
const Clock* clock;
};
AudioNetworkAdaptorImpl(
const Config& config,
std::unique_ptr<ControllerManager> controller_manager);
// Dependency injection for testing.
AudioNetworkAdaptorImpl(
const Config& config,
std::unique_ptr<ControllerManager> controller_manager,
std::unique_ptr<DebugDumpWriter> debug_dump_writer = nullptr);
~AudioNetworkAdaptorImpl() override;
void SetUplinkBandwidth(int uplink_bandwidth_bps) override;
void SetUplinkPacketLossFraction(float uplink_packet_loss_fraction) override;
void SetRtt(int rtt_ms) override;
void SetReceiverFrameLengthRange(int min_frame_length_ms,
int max_frame_length_ms) override;
@ -44,11 +55,17 @@ class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor {
void StartDebugDump(FILE* file_handle) override;
void StopDebugDump() override;
private:
void DumpNetworkMetrics();
const Config config_;
std::unique_ptr<ControllerManager> controller_manager_;
std::unique_ptr<DebugDumpWriter> debug_dump_writer_;
Controller::NetworkMetrics last_metrics_;
RTC_DISALLOW_COPY_AND_ASSIGN(AudioNetworkAdaptorImpl);

View File

@ -15,20 +15,25 @@
#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"
#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_debug_dump_writer.h"
namespace webrtc {
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
namespace {
constexpr size_t kNumControllers = 2;
constexpr int64_t kClockInitialTimeMs = 12345678;
MATCHER_P(NetworkMetricsIs, metric, "") {
return arg.uplink_bandwidth_bps == metric.uplink_bandwidth_bps &&
arg.target_audio_bitrate_bps == metric.target_audio_bitrate_bps &&
arg.rtt_ms == metric.rtt_ms &&
arg.uplink_packet_loss_fraction == metric.uplink_packet_loss_fraction;
}
@ -39,9 +44,21 @@ MATCHER_P(ConstraintsReceiverFrameLengthRangeIs, frame_length_range, "") {
frame_length_range.max_frame_length_ms;
}
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 AudioNetworkAdaptorStates {
std::unique_ptr<AudioNetworkAdaptorImpl> audio_network_adaptor;
std::vector<std::unique_ptr<MockController>> mock_controllers;
std::unique_ptr<SimulatedClock> simulated_clock;
MockDebugDumpWriter* mock_debug_dump_writer;
};
AudioNetworkAdaptorStates CreateAudioNetworkAdaptor() {
@ -64,9 +81,19 @@ AudioNetworkAdaptorStates CreateAudioNetworkAdaptor() {
EXPECT_CALL(*controller_manager, GetSortedControllers(_))
.WillRepeatedly(Return(controllers));
states.simulated_clock.reset(new SimulatedClock(kClockInitialTimeMs * 1000));
auto debug_dump_writer =
std::unique_ptr<MockDebugDumpWriter>(new NiceMock<MockDebugDumpWriter>());
EXPECT_CALL(*debug_dump_writer, Die());
states.mock_debug_dump_writer = debug_dump_writer.get();
AudioNetworkAdaptorImpl::Config config;
config.clock = states.simulated_clock.get();
// AudioNetworkAdaptorImpl governs the lifetime of controller manager.
states.audio_network_adaptor.reset(new AudioNetworkAdaptorImpl(
AudioNetworkAdaptorImpl::Config(), std::move(controller_manager)));
config,
std::move(controller_manager), std::move(debug_dump_writer)));
return states;
}
@ -108,4 +135,52 @@ TEST(AudioNetworkAdaptorImplTest, SetConstraintsIsCalledOnSetFrameLengthRange) {
states.audio_network_adaptor->SetReceiverFrameLengthRange(20, 120);
}
TEST(AudioNetworkAdaptorImplTest,
DumpEncoderRuntimeConfigIsCalledOnGetEncoderRuntimeConfig) {
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.mock_debug_dump_writer,
DumpEncoderRuntimeConfig(EncoderRuntimeConfigIs(config),
kClockInitialTimeMs));
states.audio_network_adaptor->GetEncoderRuntimeConfig();
}
TEST(AudioNetworkAdaptorImplTest,
DumpNetworkMetricsIsCalledOnSetNetworkMetrics) {
auto states = CreateAudioNetworkAdaptor();
constexpr int kBandwidth = 16000;
constexpr float kPacketLoss = 0.7f;
constexpr int kRtt = 100;
Controller::NetworkMetrics check;
check.uplink_bandwidth_bps = rtc::Optional<int>(kBandwidth);
int64_t timestamp_check = kClockInitialTimeMs;
EXPECT_CALL(*states.mock_debug_dump_writer,
DumpNetworkMetrics(NetworkMetricsIs(check), timestamp_check));
states.audio_network_adaptor->SetUplinkBandwidth(kBandwidth);
states.simulated_clock->AdvanceTimeMilliseconds(100);
timestamp_check += 100;
check.uplink_packet_loss_fraction = rtc::Optional<float>(kPacketLoss);
EXPECT_CALL(*states.mock_debug_dump_writer,
DumpNetworkMetrics(NetworkMetricsIs(check), timestamp_check));
states.audio_network_adaptor->SetUplinkPacketLossFraction(kPacketLoss);
states.simulated_clock->AdvanceTimeMilliseconds(200);
timestamp_check += 200;
check.rtt_ms = rtc::Optional<int>(kRtt);
EXPECT_CALL(*states.mock_debug_dump_writer,
DumpNetworkMetrics(NetworkMetricsIs(check), timestamp_check));
states.audio_network_adaptor->SetRtt(kRtt);
}
} // namespace webrtc

View File

@ -24,6 +24,7 @@ class Controller {
rtc::Optional<int> uplink_bandwidth_bps;
rtc::Optional<float> uplink_packet_loss_fraction;
rtc::Optional<int> target_audio_bitrate_bps;
rtc::Optional<int> rtt_ms;
};
struct Constraints {

View File

@ -0,0 +1,30 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package webrtc.audio_network_adaptor.debug_dump;
message NetworkMetrics {
optional int32 uplink_bandwidth_bps = 1;
optional float uplink_packet_loss_fraction = 2;
optional int32 target_audio_bitrate_bps = 3;
optional int32 rtt_ms = 4;
}
message EncoderRuntimeConfig {
optional int32 bitrate_bps = 1;
optional int32 frame_length_ms = 2;
optional float uplink_packet_loss_fraction = 3;
optional bool enable_fec = 4;
optional bool enable_dtx = 5;
optional uint32 num_channels = 6;
}
message Event {
enum Type {
NETWORK_METRICS = 0;
ENCODER_RUNTIME_CONFIG = 1;
}
required Type type = 1;
required uint32 timestamp = 2;
optional NetworkMetrics network_metrics = 3;
optional EncoderRuntimeConfig encoder_runtime_config = 4;
}

View File

@ -0,0 +1,135 @@
/*
* 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 "webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
#include "webrtc/base/checks.h"
#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/debug_dump.pb.h"
#else
#include "webrtc/modules/audio_coding/audio_network_adaptor/debug_dump.pb.h"
#endif
#endif
namespace webrtc {
#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
namespace {
using audio_network_adaptor::debug_dump::Event;
using audio_network_adaptor::debug_dump::NetworkMetrics;
using audio_network_adaptor::debug_dump::EncoderRuntimeConfig;
void DumpEventToFile(const Event& event, FileWrapper* dump_file) {
RTC_CHECK(dump_file->is_open());
std::string dump_data;
event.SerializeToString(&dump_data);
int32_t size = event.ByteSize();
dump_file->Write(&size, sizeof(size));
dump_file->Write(dump_data.data(), dump_data.length());
}
} // namespace
#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
class DebugDumpWriterImpl final : public DebugDumpWriter {
public:
explicit DebugDumpWriterImpl(FILE* file_handle);
~DebugDumpWriterImpl() override = default;
void DumpEncoderRuntimeConfig(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config,
int64_t timestamp) override;
void DumpNetworkMetrics(const Controller::NetworkMetrics& metrics,
int64_t timestamp) override;
private:
std::unique_ptr<FileWrapper> dump_file_;
};
DebugDumpWriterImpl::DebugDumpWriterImpl(FILE* file_handle)
: dump_file_(FileWrapper::Create()) {
#ifndef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
RTC_DCHECK(false);
#endif
dump_file_->OpenFromFileHandle(file_handle);
RTC_CHECK(dump_file_->is_open());
}
void DebugDumpWriterImpl::DumpNetworkMetrics(
const Controller::NetworkMetrics& metrics,
int64_t timestamp) {
#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
Event event;
event.set_timestamp(timestamp);
event.set_type(Event::NETWORK_METRICS);
auto dump_metrics = event.mutable_network_metrics();
if (metrics.uplink_bandwidth_bps)
dump_metrics->set_uplink_bandwidth_bps(*metrics.uplink_bandwidth_bps);
if (metrics.uplink_packet_loss_fraction) {
dump_metrics->set_uplink_packet_loss_fraction(
*metrics.uplink_packet_loss_fraction);
}
if (metrics.target_audio_bitrate_bps) {
dump_metrics->set_target_audio_bitrate_bps(
*metrics.target_audio_bitrate_bps);
}
if (metrics.rtt_ms)
dump_metrics->set_rtt_ms(*metrics.rtt_ms);
DumpEventToFile(event, dump_file_.get());
#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
}
void DebugDumpWriterImpl::DumpEncoderRuntimeConfig(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config,
int64_t timestamp) {
#ifdef WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
Event event;
event.set_timestamp(timestamp);
event.set_type(Event::ENCODER_RUNTIME_CONFIG);
auto dump_config = event.mutable_encoder_runtime_config();
if (config.bitrate_bps)
dump_config->set_bitrate_bps(*config.bitrate_bps);
if (config.frame_length_ms)
dump_config->set_frame_length_ms(*config.frame_length_ms);
if (config.uplink_packet_loss_fraction) {
dump_config->set_uplink_packet_loss_fraction(
*config.uplink_packet_loss_fraction);
}
if (config.enable_fec)
dump_config->set_enable_fec(*config.enable_fec);
if (config.enable_dtx)
dump_config->set_enable_dtx(*config.enable_dtx);
if (config.num_channels)
dump_config->set_num_channels(*config.num_channels);
DumpEventToFile(event, dump_file_.get());
#endif // WEBRTC_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP
}
std::unique_ptr<DebugDumpWriter> DebugDumpWriter::Create(FILE* file_handle) {
return std::unique_ptr<DebugDumpWriter>(new DebugDumpWriterImpl(file_handle));
}
} // namespace webrtc

View File

@ -0,0 +1,40 @@
/*
* 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_DEBUG_DUMP_WRITER_H_
#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP_WRITER_H_
#include <memory>
#include <string>
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "webrtc/system_wrappers/include/file_wrapper.h"
namespace webrtc {
class DebugDumpWriter {
public:
static std::unique_ptr<DebugDumpWriter> Create(FILE* file_handle);
virtual ~DebugDumpWriter() = default;
virtual void DumpEncoderRuntimeConfig(
const AudioNetworkAdaptor::EncoderRuntimeConfig& config,
int64_t timestamp) = 0;
virtual void DumpNetworkMetrics(const Controller::NetworkMetrics& metrics,
int64_t timestamp) = 0;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_DEBUG_DUMP_WRITER_H_

View File

@ -43,12 +43,16 @@ class AudioNetworkAdaptor {
virtual void SetUplinkPacketLossFraction(
float uplink_packet_loss_fraction) = 0;
virtual void SetRtt(int rtt_ms) = 0;
virtual void SetReceiverFrameLengthRange(int min_frame_length_ms,
int max_frame_length_ms) = 0;
virtual EncoderRuntimeConfig GetEncoderRuntimeConfig() = 0;
virtual void StartDebugDump(FILE* file_handle) = 0;
virtual void StopDebugDump() = 0;
};
} // namespace webrtc

View File

@ -0,0 +1,34 @@
/*
* 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_MOCK_MOCK_DEBUG_DUMP_WRITER_H_
#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_DEBUG_DUMP_WRITER_H_
#include "testing/gmock/include/gmock/gmock.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/debug_dump_writer.h"
namespace webrtc {
class MockDebugDumpWriter : public DebugDumpWriter {
public:
virtual ~MockDebugDumpWriter() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD2(DumpEncoderRuntimeConfig,
void(const AudioNetworkAdaptor::EncoderRuntimeConfig& config,
int64_t timestamp));
MOCK_METHOD2(DumpNetworkMetrics,
void(const Controller::NetworkMetrics& metrics,
int64_t timestamp));
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_DEBUG_DUMP_WRITER_H_