diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc index f6003f6ab9..b4d6bccf8c 100644 --- a/talk/app/webrtc/peerconnection_unittest.cc +++ b/talk/app/webrtc/peerconnection_unittest.cc @@ -85,7 +85,7 @@ using webrtc::StreamCollectionInterface; static const int kMaxWaitMs = 2000; static const int kMaxWaitForStatsMs = 3000; -static const int kMaxWaitForFramesMs = 5000; +static const int kMaxWaitForFramesMs = 10000; static const int kEndAudioFrameCount = 3; static const int kEndVideoFrameCount = 3; diff --git a/talk/app/webrtc/statscollector.cc b/talk/app/webrtc/statscollector.cc index 013e83f252..23d3205897 100644 --- a/talk/app/webrtc/statscollector.cc +++ b/talk/app/webrtc/statscollector.cc @@ -63,6 +63,18 @@ const char StatsReport::kStatsValueNameComponent[] = "googComponent"; const char StatsReport::kStatsValueNameContentName[] = "googContentName"; const char StatsReport::kStatsValueNameCpuLimitedResolution[] = "googCpuLimitedResolution"; +const char StatsReport::kStatsValueNameDecodingCTSG[] = + "googDecodingCTSG"; +const char StatsReport::kStatsValueNameDecodingCTN[] = + "googDecodingCTN"; +const char StatsReport::kStatsValueNameDecodingNormal[] = + "googDecodingNormal"; +const char StatsReport::kStatsValueNameDecodingPLC[] = + "googDecodingPLC"; +const char StatsReport::kStatsValueNameDecodingCNG[] = + "googDecodingCNG"; +const char StatsReport::kStatsValueNameDecodingPLCCNG[] = + "googDecodingPLCCNG"; const char StatsReport::kStatsValueNameDer[] = "googDerBase64"; // Echo metrics from the audio processing module. const char StatsReport::kStatsValueNameEchoCancellationQualityMin[] = @@ -273,6 +285,18 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) { info.packets_rcvd); report->AddValue(StatsReport::kStatsValueNamePacketsLost, info.packets_lost); + report->AddValue(StatsReport::kStatsValueNameDecodingCTSG, + info.decoding_calls_to_silence_generator); + report->AddValue(StatsReport::kStatsValueNameDecodingCTN, + info.decoding_calls_to_neteq); + report->AddValue(StatsReport::kStatsValueNameDecodingNormal, + info.decoding_normal); + report->AddValue(StatsReport::kStatsValueNameDecodingPLC, + info.decoding_plc); + report->AddValue(StatsReport::kStatsValueNameDecodingCNG, + info.decoding_cng); + report->AddValue(StatsReport::kStatsValueNameDecodingPLCCNG, + info.decoding_plc_cng); } void ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) { diff --git a/talk/app/webrtc/statscollector_unittest.cc b/talk/app/webrtc/statscollector_unittest.cc index 24be20af16..fb55969715 100644 --- a/talk/app/webrtc/statscollector_unittest.cc +++ b/talk/app/webrtc/statscollector_unittest.cc @@ -263,6 +263,58 @@ void CheckCertChainReports(const StatsReports& reports, EXPECT_EQ(ders.size(), i); } +void VerifyVoiceReceiverInfoReport(const StatsReport* report, + const cricket::VoiceReceiverInfo& sinfo) { + std::string value_in_report; + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameAudioOutputLevel, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.audio_level), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameBytesReceived, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.bytes_rcvd), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameJitterReceived, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.jitter_ms), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameJitterBufferMs, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.jitter_buffer_ms), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNamePreferredJitterBufferMs, + &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.jitter_buffer_preferred_ms), + value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameCurrentDelayMs, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.delay_estimate_ms), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameExpandRate, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.expand_rate), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.packets_rcvd), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_calls_to_silence_generator), + value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingCTN, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_calls_to_neteq), + value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingNormal, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_normal), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingPLC, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_plc), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingCNG, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_cng), value_in_report); + EXPECT_TRUE(GetValue( + report, StatsReport::kStatsValueNameDecodingPLCCNG, &value_in_report)); + EXPECT_EQ(talk_base::ToString(sinfo.decoding_plc_cng), value_in_report); +} + + void VerifyVoiceSenderInfoReport(const StatsReport* report, const cricket::VoiceSenderInfo& sinfo) { std::string value_in_report; @@ -1067,6 +1119,66 @@ TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) { VerifyVoiceSenderInfoReport(track_report, voice_sender_info); } + +// This test verifies that audio receive streams populate stats reports +// correctly. +TEST_F(StatsCollectorTest, GetStatsFromRemoteStream) { + webrtc::StatsCollector stats; // Implementation under test. + MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel(); + // The content_name known by the voice channel. + const std::string kVcName("vcname"); + cricket::VoiceChannel voice_channel(talk_base::Thread::Current(), + media_engine_, media_channel, &session_, kVcName, false); + stream_ = webrtc::MediaStream::Create("remoteStreamLabel"); + stats.AddStream(stream_); + + stats.set_session(&session_); + + // Instruct the session to return stats containing the transport channel. + InitSessionStats(kVcName); + EXPECT_CALL(session_, GetStats(_)) + .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), + Return(true))); + + cricket::VoiceReceiverInfo voice_receiver_info; + voice_receiver_info.add_ssrc(kSsrcOfTrack); + voice_receiver_info.bytes_rcvd = 100; + voice_receiver_info.packets_rcvd = 101; + voice_receiver_info.packets_lost = 102; + voice_receiver_info.fraction_lost = 103; + voice_receiver_info.packets_lost = 104; + voice_receiver_info.ext_seqnum = 105; + voice_receiver_info.jitter_ms = 106; + voice_receiver_info.jitter_buffer_ms = 107; + voice_receiver_info.jitter_buffer_preferred_ms = 108; + voice_receiver_info.delay_estimate_ms = 109; + voice_receiver_info.audio_level = 110; + voice_receiver_info.expand_rate = 111; + + // Constructs an ssrc stats update. + cricket::VoiceMediaInfo stats_read; + stats_read.receivers.push_back(voice_receiver_info); + + EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel)); + EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull()); + EXPECT_CALL(*media_channel, GetStats(_)) + .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read), + Return(true))); + EXPECT_CALL(session_, GetTrackIdBySsrc(kSsrcOfTrack, _)) + .WillRepeatedly(Return(true)); + + StatsReports reports; // returned values. + stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); + stats.GetStats(NULL, &reports); + + // Verify the remote report. + const StatsReport* report = FindNthReportByType( + reports, StatsReport::kStatsReportTypeSsrc, 1); + EXPECT_FALSE(report == NULL); + VerifyVoiceReceiverInfoReport(report, voice_receiver_info); +} + + // This test verifies that a local stats object won't update its statistics // after a RemoveLocalAudioTrack() call. TEST_F(StatsCollectorTest, GetStatsAfterRemoveAudioStream) { diff --git a/talk/app/webrtc/statstypes.h b/talk/app/webrtc/statstypes.h index dd9da0dba8..e471dc9e50 100644 --- a/talk/app/webrtc/statstypes.h +++ b/talk/app/webrtc/statstypes.h @@ -200,6 +200,12 @@ class StatsReport { static const char kStatsValueNameRecvPacketGroupArrivalTimeDebug[]; static const char kStatsValueNameRecvPacketGroupPropagationDeltaDebug[]; static const char kStatsValueNameRecvPacketGroupPropagationDeltaSumDebug[]; + static const char kStatsValueNameDecodingCTSG[]; + static const char kStatsValueNameDecodingCTN[]; + static const char kStatsValueNameDecodingNormal[]; + static const char kStatsValueNameDecodingPLC[]; + static const char kStatsValueNameDecodingCNG[]; + static const char kStatsValueNameDecodingPLCCNG[]; }; typedef std::vector StatsReports; diff --git a/talk/app/webrtc/test/peerconnectiontestwrapper.cc b/talk/app/webrtc/test/peerconnectiontestwrapper.cc index d7c30a82d8..7d3664fd1c 100644 --- a/talk/app/webrtc/test/peerconnectiontestwrapper.cc +++ b/talk/app/webrtc/test/peerconnectiontestwrapper.cc @@ -36,7 +36,7 @@ static const char kStreamLabelBase[] = "stream_label"; static const char kVideoTrackLabelBase[] = "video_track"; static const char kAudioTrackLabelBase[] = "audio_track"; -static const int kMaxWait = 5000; +static const int kMaxWait = 10000; static const int kTestAudioFrameCount = 3; static const int kTestVideoFrameCount = 3;