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: