From e1198e068bdcb01dcb8799d6871018092711714e Mon Sep 17 00:00:00 2001 From: ivoc Date: Fri, 8 Sep 2017 08:13:19 -0700 Subject: [PATCH] Add new ANA stats to the old GetStats() to count the number of actions taken by each controller. This CL only wires up the new stats but does not set the values yet. This will be added in a follow-up CL. BUG=webrtc:8127 Review-Url: https://codereview.webrtc.org/3011623002 Cr-Commit-Position: refs/heads/master@{#19751} --- webrtc/api/audio_codecs/audio_encoder.cc | 8 ++++ webrtc/api/audio_codecs/audio_encoder.h | 30 +++++++++++++ webrtc/api/statstypes.cc | 10 +++++ webrtc/api/statstypes.h | 5 +++ webrtc/audio/audio_send_stream.cc | 1 + webrtc/audio/audio_send_stream_unittest.cc | 2 + webrtc/call/audio_send_stream.h | 2 + webrtc/media/base/mediachannel.h | 2 + webrtc/media/engine/webrtcvoiceengine.cc | 1 + .../engine/webrtcvoiceengine_unittest.cc | 16 +++++++ webrtc/modules/audio_coding/BUILD.gn | 1 + .../audio_coding/acm2/audio_coding_module.cc | 10 +++++ .../audio_network_adaptor_impl.cc | 6 +++ .../audio_network_adaptor_impl.h | 2 + .../audio_network_adaptor_impl_unittest.cc | 32 ++++++++++++++ .../include/audio_network_adaptor.h | 4 +- .../mock/mock_audio_network_adaptor.h | 2 + .../codecs/opus/audio_encoder_opus.cc | 7 ++++ .../codecs/opus/audio_encoder_opus.h | 1 + .../include/audio_coding_module.h | 2 + webrtc/pc/statscollector.cc | 20 +++++++++ webrtc/pc/statscollector_unittest.cc | 42 +++++++++++++++++++ webrtc/test/mock_voe_channel_proxy.h | 1 + webrtc/voice_engine/channel.cc | 4 ++ webrtc/voice_engine/channel.h | 1 + webrtc/voice_engine/channel_proxy.cc | 5 +++ webrtc/voice_engine/channel_proxy.h | 1 + 27 files changed, 217 insertions(+), 1 deletion(-) diff --git a/webrtc/api/audio_codecs/audio_encoder.cc b/webrtc/api/audio_codecs/audio_encoder.cc index 3ee371f1ce..d5be26c5a1 100644 --- a/webrtc/api/audio_codecs/audio_encoder.cc +++ b/webrtc/api/audio_codecs/audio_encoder.cc @@ -15,6 +15,10 @@ namespace webrtc { +ANAStats::ANAStats() = default; +ANAStats::~ANAStats() = default; +ANAStats::ANAStats(const ANAStats&) = default; + AudioEncoder::EncodedInfo::EncodedInfo() = default; AudioEncoder::EncodedInfo::EncodedInfo(const EncodedInfo&) = default; AudioEncoder::EncodedInfo::EncodedInfo(EncodedInfo&&) = default; @@ -95,4 +99,8 @@ void AudioEncoder::OnReceivedOverhead(size_t overhead_bytes_per_packet) {} void AudioEncoder::SetReceiverFrameLengthRange(int min_frame_length_ms, int max_frame_length_ms) {} +ANAStats AudioEncoder::GetANAStats() const { + return ANAStats(); +} + } // namespace webrtc diff --git a/webrtc/api/audio_codecs/audio_encoder.h b/webrtc/api/audio_codecs/audio_encoder.h index 7406d7d653..a77894b7da 100644 --- a/webrtc/api/audio_codecs/audio_encoder.h +++ b/webrtc/api/audio_codecs/audio_encoder.h @@ -27,6 +27,33 @@ namespace webrtc { class Clock; class RtcEventLog; +// Statistics related to Audio Network Adaptation. +struct ANAStats { + ANAStats(); + ANAStats(const ANAStats&); + ~ANAStats(); + // Number of actions taken by the ANA bitrate controller since the start of + // the call. If this value is not set, it indicates that the bitrate + // controller is disabled. + rtc::Optional bitrate_action_counter; + // Number of actions taken by the ANA channel controller since the start of + // the call. If this value is not set, it indicates that the channel + // controller is disabled. + rtc::Optional channel_action_counter; + // Number of actions taken by the ANA DTX controller since the start of the + // call. If this value is not set, it indicates that the DTX controller is + // disabled. + rtc::Optional dtx_action_counter; + // Number of actions taken by the ANA FEC controller since the start of the + // call. If this value is not set, it indicates that the FEC controller is + // disabled. + rtc::Optional fec_action_counter; + // Number of actions taken by the ANA frame length controller since the start + // of the call. If this value is not set, it indicates that the frame length + // controller is disabled. + rtc::Optional frame_length_action_counter; +}; + // This is the interface class for encoders in AudioCoding module. Each codec // type must have an implementation of this class. class AudioEncoder { @@ -203,6 +230,9 @@ class AudioEncoder { virtual void SetReceiverFrameLengthRange(int min_frame_length_ms, int max_frame_length_ms); + // Get statistics related to audio network adaptation. + virtual ANAStats GetANAStats() const; + protected: // Subclasses implement this to perform the actual encoding. Called by // Encode(). diff --git a/webrtc/api/statstypes.cc b/webrtc/api/statstypes.cc index 714d36b54b..67bf49e336 100644 --- a/webrtc/api/statstypes.cc +++ b/webrtc/api/statstypes.cc @@ -586,6 +586,16 @@ const char* StatsReport::Value::display_name() const { return "googResidualEchoLikelihood"; case kStatsValueNameResidualEchoLikelihoodRecentMax: return "googResidualEchoLikelihoodRecentMax"; + case kStatsValueNameAnaBitrateActionCounter: + return "googAnaBitrateActionCounter"; + case kStatsValueNameAnaChannelActionCounter: + return "googAnaChannelActionCounter"; + case kStatsValueNameAnaDtxActionCounter: + return "googAnaDtxActionCounter"; + case kStatsValueNameAnaFecActionCounter: + return "googAnaFecActionCounter"; + case kStatsValueNameAnaFrameLengthActionCounter: + return "googAnaFrameLengthActionCounter"; case kStatsValueNameRetransmitBitrate: return "googRetransmitBitrate"; case kStatsValueNameRtt: diff --git a/webrtc/api/statstypes.h b/webrtc/api/statstypes.h index 42e3601209..219995ed83 100644 --- a/webrtc/api/statstypes.h +++ b/webrtc/api/statstypes.h @@ -208,6 +208,11 @@ class StatsReport { kStatsValueNameRenderDelayMs, kStatsValueNameResidualEchoLikelihood, kStatsValueNameResidualEchoLikelihoodRecentMax, + kStatsValueNameAnaBitrateActionCounter, + kStatsValueNameAnaChannelActionCounter, + kStatsValueNameAnaDtxActionCounter, + kStatsValueNameAnaFecActionCounter, + kStatsValueNameAnaFrameLengthActionCounter, kStatsValueNameRetransmitBitrate, kStatsValueNameRtt, kStatsValueNameSecondaryDecodedRate, diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index 5bf6f2b807..cb73e84a23 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -333,6 +333,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { internal::AudioState* audio_state = static_cast(audio_state_.get()); stats.typing_noise_detected = audio_state->typing_noise_detected(); + stats.ana_statistics = channel_proxy_->GetANAStatistics(); return stats; } diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc index 1308657d0e..4c29f6ac63 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -301,6 +301,8 @@ struct ConfigHelper { .WillRepeatedly(Return(kCallStats)); EXPECT_CALL(*channel_proxy_, GetRemoteRTCPReportBlocks()) .WillRepeatedly(Return(report_blocks)); + EXPECT_CALL(*channel_proxy_, GetANAStatistics()) + .WillRepeatedly(Return(ANAStats())); EXPECT_CALL(voice_engine_, transmit_mixer()) .WillRepeatedly(Return(&transmit_mixer_)); diff --git a/webrtc/call/audio_send_stream.h b/webrtc/call/audio_send_stream.h index 4f7f8c0f84..ac962c5ada 100644 --- a/webrtc/call/audio_send_stream.h +++ b/webrtc/call/audio_send_stream.h @@ -15,6 +15,7 @@ #include #include +#include "webrtc/api/audio_codecs/audio_encoder.h" #include "webrtc/api/audio_codecs/audio_encoder_factory.h" #include "webrtc/api/audio_codecs/audio_format.h" #include "webrtc/api/call/transport.h" @@ -61,6 +62,7 @@ class AudioSendStream { float residual_echo_likelihood = -1.0f; float residual_echo_likelihood_recent_max = -1.0f; bool typing_noise_detected = false; + ANAStats ana_statistics; }; struct Config { diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index cea85e6c3d..7e7b815821 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -15,6 +15,7 @@ #include #include +#include "webrtc/api/audio_codecs/audio_encoder.h" #include "webrtc/api/optional.h" #include "webrtc/api/rtpparameters.h" #include "webrtc/api/rtpreceiverinterface.h" @@ -641,6 +642,7 @@ struct VoiceSenderInfo : public MediaSenderInfo { float residual_echo_likelihood; float residual_echo_likelihood_recent_max; bool typing_noise_detected; + webrtc::ANAStats ana_statistics; }; struct VoiceReceiverInfo : public MediaReceiverInfo { diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index 8c45e953e4..d202106be0 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -2260,6 +2260,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { sinfo.residual_echo_likelihood_recent_max = stats.residual_echo_likelihood_recent_max; sinfo.typing_noise_detected = (send_ ? stats.typing_noise_detected : false); + sinfo.ana_statistics = stats.ana_statistics; info->senders.push_back(sinfo); } diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 5ccd7d6bb6..67fde12194 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -546,6 +546,12 @@ class WebRtcVoiceEngineTestFake : public testing::Test { stats.echo_return_loss_enhancement = 1234; stats.residual_echo_likelihood = 0.432f; stats.residual_echo_likelihood_recent_max = 0.6f; + stats.ana_statistics.bitrate_action_counter = rtc::Optional(321); + stats.ana_statistics.channel_action_counter = rtc::Optional(432); + stats.ana_statistics.dtx_action_counter = rtc::Optional(543); + stats.ana_statistics.fec_action_counter = rtc::Optional(654); + stats.ana_statistics.frame_length_action_counter = + rtc::Optional(765); stats.typing_noise_detected = true; return stats; } @@ -577,6 +583,16 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(info.residual_echo_likelihood, stats.residual_echo_likelihood); EXPECT_EQ(info.residual_echo_likelihood_recent_max, stats.residual_echo_likelihood_recent_max); + EXPECT_EQ(info.ana_statistics.bitrate_action_counter, + stats.ana_statistics.bitrate_action_counter); + EXPECT_EQ(info.ana_statistics.channel_action_counter, + stats.ana_statistics.channel_action_counter); + EXPECT_EQ(info.ana_statistics.dtx_action_counter, + stats.ana_statistics.dtx_action_counter); + EXPECT_EQ(info.ana_statistics.fec_action_counter, + stats.ana_statistics.fec_action_counter); + EXPECT_EQ(info.ana_statistics.frame_length_action_counter, + stats.ana_statistics.frame_length_action_counter); EXPECT_EQ(info.typing_noise_detected, stats.typing_noise_detected && is_sending); } diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index 32d5336ce9..898723b8ca 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -913,6 +913,7 @@ rtc_static_library("audio_network_adaptor") { deps = [ "../..:webrtc_common", "../../api:optional", + "../../api/audio_codecs:audio_codecs_api", "../../common_audio", "../../logging:rtc_event_log_api", "../../rtc_base:protobuf_utils", diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module.cc index f7607c6521..0244882de6 100644 --- a/webrtc/modules/audio_coding/acm2/audio_coding_module.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module.cc @@ -204,6 +204,8 @@ class AudioCodingModuleImpl final : public AudioCodingModule { void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override; + ANAStats GetANAStats() const override; + private: struct InputData { uint32_t input_timestamp; @@ -1273,6 +1275,14 @@ void AudioCodingModuleImpl::GetDecodingCallStatistics( receiver_.GetDecodingCallStatistics(call_stats); } +ANAStats AudioCodingModuleImpl::GetANAStats() const { + rtc::CritScope lock(&acm_crit_sect_); + if (encoder_stack_) + return encoder_stack_->GetANAStats(); + // If no encoder is set, return default stats. + return ANAStats(); +} + } // namespace AudioCodingModule::Config::Config() diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc index 7645c4a1f2..5eff4b3571 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.cc @@ -135,6 +135,12 @@ void AudioNetworkAdaptorImpl::StopDebugDump() { debug_dump_writer_.reset(nullptr); } +ANAStats AudioNetworkAdaptorImpl::GetStats() const { + // TODO(ivoc): Actually implement the stat. + // Tracking bug: https://crbug.com/webrtc/8127 + return ANAStats(); +} + void AudioNetworkAdaptorImpl::DumpNetworkMetrics() { if (debug_dump_writer_) debug_dump_writer_->DumpNetworkMetrics(last_metrics_, rtc::TimeMillis()); diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h index 7d7a2cb086..bd2a250f66 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h @@ -58,6 +58,8 @@ class AudioNetworkAdaptorImpl final : public AudioNetworkAdaptor { void StopDebugDump() override; + ANAStats GetStats() const override; + private: void DumpNetworkMetrics(); diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc index 1914939566..c29b1e8c17 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc +++ b/webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl_unittest.cc @@ -270,4 +270,36 @@ TEST(AudioNetworkAdaptorImplTest, LogRuntimeConfigOnGetEncoderRuntimeConfig) { states.audio_network_adaptor->GetEncoderRuntimeConfig(); } +TEST(AudioNetworkAdaptorImplTest, TestANAStats) { + auto states = CreateAudioNetworkAdaptor(); + + // Simulate some adaptation, otherwise the stats will not show anything. + AudioEncoderRuntimeConfig config1, config2; + config1.bitrate_bps = rtc::Optional(32000); + config1.enable_fec = rtc::Optional(true); + config2.bitrate_bps = rtc::Optional(16000); + config2.enable_fec = rtc::Optional(false); + + EXPECT_CALL(*states.mock_controllers[0], MakeDecision(_)) + .WillOnce(SetArgPointee<0>(config1)); + states.audio_network_adaptor->GetEncoderRuntimeConfig(); + EXPECT_CALL(*states.mock_controllers[0], MakeDecision(_)) + .WillOnce(SetArgPointee<0>(config2)); + states.audio_network_adaptor->GetEncoderRuntimeConfig(); + + auto ana_stats = states.audio_network_adaptor->GetStats(); + + // Check that the default stats are returned, as these have not been + // implemented yet). Tracking bug: https://crbug.com/8127 + auto default_stats = ANAStats(); + EXPECT_EQ(ana_stats.bitrate_action_counter, + default_stats.bitrate_action_counter); + EXPECT_EQ(ana_stats.channel_action_counter, + default_stats.channel_action_counter); + EXPECT_EQ(ana_stats.dtx_action_counter, default_stats.dtx_action_counter); + EXPECT_EQ(ana_stats.fec_action_counter, default_stats.fec_action_counter); + EXPECT_EQ(ana_stats.frame_length_action_counter, + default_stats.frame_length_action_counter); +} + } // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h b/webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h index fa742e69f6..0097d70bd8 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h @@ -11,6 +11,7 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_H_ #define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_INCLUDE_AUDIO_NETWORK_ADAPTOR_H_ +#include "webrtc/api/audio_codecs/audio_encoder.h" #include "webrtc/api/optional.h" namespace webrtc { @@ -38,7 +39,6 @@ struct AudioEncoderRuntimeConfig { // encoder based on network metrics. class AudioNetworkAdaptor { public: - virtual ~AudioNetworkAdaptor() = default; virtual void SetUplinkBandwidth(int uplink_bandwidth_bps) = 0; @@ -60,6 +60,8 @@ class AudioNetworkAdaptor { virtual void StartDebugDump(FILE* file_handle) = 0; virtual void StopDebugDump() = 0; + + virtual ANAStats GetStats() const = 0; }; } // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h index 4b9a4772a1..f58a48285b 100644 --- a/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h +++ b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_network_adaptor.h @@ -40,6 +40,8 @@ class MockAudioNetworkAdaptor : public AudioNetworkAdaptor { MOCK_METHOD1(StartDebugDump, void(FILE* file_handle)); MOCK_METHOD0(StopDebugDump, void()); + + MOCK_CONST_METHOD0(GetStats, ANAStats()); }; } // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index cd47bf4265..3b4473a921 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -773,4 +773,11 @@ void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() { } } +ANAStats AudioEncoderOpus::GetANAStats() const { + if (audio_network_adaptor_) { + return audio_network_adaptor_->GetStats(); + } + return ANAStats(); +} + } // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h index 588f268e7f..f966dbe74d 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h @@ -116,6 +116,7 @@ class AudioEncoderOpus final : public AudioEncoder { void OnReceivedOverhead(size_t overhead_bytes_per_packet) override; void SetReceiverFrameLengthRange(int min_frame_length_ms, int max_frame_length_ms) override; + ANAStats GetANAStats() const override; rtc::ArrayView supported_frame_lengths_ms() const { return config_.supported_frame_lengths_ms; } diff --git a/webrtc/modules/audio_coding/include/audio_coding_module.h b/webrtc/modules/audio_coding/include/audio_coding_module.h index 4ceade25d0..eb59404dd1 100644 --- a/webrtc/modules/audio_coding/include/audio_coding_module.h +++ b/webrtc/modules/audio_coding/include/audio_coding_module.h @@ -823,6 +823,8 @@ class AudioCodingModule { virtual void GetDecodingCallStatistics( AudioDecodingCallStats* call_stats) const = 0; + + virtual ANAStats GetANAStats() const = 0; }; } // namespace webrtc diff --git a/webrtc/pc/statscollector.cc b/webrtc/pc/statscollector.cc index 08cf464568..b96428353a 100644 --- a/webrtc/pc/statscollector.cc +++ b/webrtc/pc/statscollector.cc @@ -224,6 +224,26 @@ void ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) { } } report->AddString(StatsReport::kStatsValueNameMediaType, "audio"); + if (info.ana_statistics.bitrate_action_counter) { + report->AddInt(StatsReport::kStatsValueNameAnaBitrateActionCounter, + *info.ana_statistics.bitrate_action_counter); + } + if (info.ana_statistics.channel_action_counter) { + report->AddInt(StatsReport::kStatsValueNameAnaChannelActionCounter, + *info.ana_statistics.channel_action_counter); + } + if (info.ana_statistics.dtx_action_counter) { + report->AddInt(StatsReport::kStatsValueNameAnaDtxActionCounter, + *info.ana_statistics.dtx_action_counter); + } + if (info.ana_statistics.fec_action_counter) { + report->AddInt(StatsReport::kStatsValueNameAnaFecActionCounter, + *info.ana_statistics.fec_action_counter); + } + if (info.ana_statistics.frame_length_action_counter) { + report->AddInt(StatsReport::kStatsValueNameAnaFrameLengthActionCounter, + *info.ana_statistics.frame_length_action_counter); + } } void ExtractStats(const cricket::VideoReceiverInfo& info, StatsReport* report) { diff --git a/webrtc/pc/statscollector_unittest.cc b/webrtc/pc/statscollector_unittest.cc index 56d4fca14d..57346760e7 100644 --- a/webrtc/pc/statscollector_unittest.cc +++ b/webrtc/pc/statscollector_unittest.cc @@ -430,6 +430,37 @@ void VerifyVoiceSenderInfoReport(const StatsReport* report, report, StatsReport::kStatsValueNameTypingNoiseState, &value_in_report)); std::string typing_detected = sinfo.typing_noise_detected ? "true" : "false"; EXPECT_EQ(typing_detected, value_in_report); + EXPECT_TRUE(GetValue(report, + StatsReport::kStatsValueNameAnaBitrateActionCounter, + &value_in_report)); + ASSERT_TRUE(sinfo.ana_statistics.bitrate_action_counter); + EXPECT_EQ( + rtc::ToString(*sinfo.ana_statistics.bitrate_action_counter), + value_in_report); + EXPECT_TRUE(GetValue(report, + StatsReport::kStatsValueNameAnaChannelActionCounter, + &value_in_report)); + ASSERT_TRUE(sinfo.ana_statistics.channel_action_counter); + EXPECT_EQ( + rtc::ToString(*sinfo.ana_statistics.channel_action_counter), + value_in_report); + EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaDtxActionCounter, + &value_in_report)); + ASSERT_TRUE(sinfo.ana_statistics.dtx_action_counter); + EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.dtx_action_counter), + value_in_report); + EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameAnaFecActionCounter, + &value_in_report)); + ASSERT_TRUE(sinfo.ana_statistics.fec_action_counter); + EXPECT_EQ(rtc::ToString(*sinfo.ana_statistics.fec_action_counter), + value_in_report); + EXPECT_TRUE(GetValue(report, + StatsReport::kStatsValueNameAnaFrameLengthActionCounter, + &value_in_report)); + ASSERT_TRUE(sinfo.ana_statistics.frame_length_action_counter); + EXPECT_EQ(rtc::ToString( + *sinfo.ana_statistics.frame_length_action_counter), + value_in_report); } // Helper methods to avoid duplication of code. @@ -450,6 +481,16 @@ void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) { voice_sender_info->echo_delay_std_ms = 111; voice_sender_info->aec_quality_min = 112.0f; voice_sender_info->typing_noise_detected = false; + voice_sender_info->ana_statistics.bitrate_action_counter = + rtc::Optional(113); + voice_sender_info->ana_statistics.channel_action_counter = + rtc::Optional(114); + voice_sender_info->ana_statistics.dtx_action_counter = + rtc::Optional(115); + voice_sender_info->ana_statistics.fec_action_counter = + rtc::Optional(116); + voice_sender_info->ana_statistics.frame_length_action_counter = + rtc::Optional(117); } void UpdateVoiceSenderInfoFromAudioTrack( @@ -1988,6 +2029,7 @@ TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) { stats.AddLocalAudioTrack(audio_track_, kSsrcOfTrack); cricket::VoiceSenderInfo voice_sender_info; + InitVoiceSenderInfo(&voice_sender_info); voice_sender_info.add_ssrc(kSsrcOfTrack); cricket::VoiceMediaInfo stats_read; diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h index 6aa60857d1..b151aa8e0e 100644 --- a/webrtc/test/mock_voe_channel_proxy.h +++ b/webrtc/test/mock_voe_channel_proxy.h @@ -52,6 +52,7 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_CONST_METHOD0(GetRemoteRTCPReportBlocks, std::vector()); MOCK_CONST_METHOD0(GetNetworkStatistics, NetworkStatistics()); MOCK_CONST_METHOD0(GetDecodingCallStatistics, AudioDecodingCallStats()); + MOCK_CONST_METHOD0(GetANAStatistics, ANAStats()); MOCK_CONST_METHOD0(GetSpeechOutputLevel, int()); MOCK_CONST_METHOD0(GetSpeechOutputLevelFullRange, int()); MOCK_CONST_METHOD0(GetTotalOutputEnergy, double()); diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index 1a56e81181..0e83989ccf 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -2856,6 +2856,10 @@ void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { audio_coding_->GetDecodingCallStatistics(stats); } +ANAStats Channel::GetANAStatistics() const { + return audio_coding_->GetANAStats(); +} + uint32_t Channel::GetDelayEstimate() const { rtc::CritScope lock(&video_sync_lock_); return audio_coding_->FilteredCurrentDelayMs() + playout_delay_ms_; diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 0d71a41d82..89c2b430ec 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -268,6 +268,7 @@ class Channel // Stats. int GetNetworkStatistics(NetworkStatistics& stats); void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; + ANAStats GetANAStatistics() const; // Audio+Video Sync. uint32_t GetDelayEstimate() const; diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc index cdd4b6624f..5f4f98a78f 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -144,6 +144,11 @@ AudioDecodingCallStats ChannelProxy::GetDecodingCallStatistics() const { return stats; } +ANAStats ChannelProxy::GetANAStatistics() const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + return channel()->GetANAStatistics(); +} + int ChannelProxy::GetSpeechOutputLevel() const { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); return channel()->GetSpeechOutputLevel(); diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h index 5aa2839feb..826117b9aa 100644 --- a/webrtc/voice_engine/channel_proxy.h +++ b/webrtc/voice_engine/channel_proxy.h @@ -81,6 +81,7 @@ class ChannelProxy : public RtpPacketSinkInterface { virtual std::vector GetRemoteRTCPReportBlocks() const; virtual NetworkStatistics GetNetworkStatistics() const; virtual AudioDecodingCallStats GetDecodingCallStatistics() const; + virtual ANAStats GetANAStatistics() const; virtual int GetSpeechOutputLevel() const; virtual int GetSpeechOutputLevelFullRange() const; // See description of "totalAudioEnergy" in the WebRTC stats spec: