diff --git a/webrtc/api/call/audio_receive_stream.h b/webrtc/api/call/audio_receive_stream.h index ec80a9e3f0..2fd6760d86 100644 --- a/webrtc/api/call/audio_receive_stream.h +++ b/webrtc/api/call/audio_receive_stream.h @@ -16,6 +16,7 @@ #include #include +#include "webrtc/base/optional.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder_factory.h" #include "webrtc/common_types.h" @@ -40,6 +41,7 @@ class AudioReceiveStream { uint32_t packets_lost = 0; float fraction_lost = 0.0f; std::string codec_name; + rtc::Optional codec_payload_type; uint32_t ext_seqnum = 0; uint32_t jitter_ms = 0; uint32_t jitter_buffer_ms = 0; diff --git a/webrtc/api/call/audio_send_stream.cc b/webrtc/api/call/audio_send_stream.cc index 3ce35e7a4b..b6190073c1 100644 --- a/webrtc/api/call/audio_send_stream.cc +++ b/webrtc/api/call/audio_send_stream.cc @@ -30,6 +30,7 @@ std::string ToString(const webrtc::CodecInst& codec_inst) { namespace webrtc { AudioSendStream::Stats::Stats() = default; +AudioSendStream::Stats::~Stats() = default; AudioSendStream::Config::Config(Transport* send_transport) : send_transport(send_transport) {} diff --git a/webrtc/api/call/audio_send_stream.h b/webrtc/api/call/audio_send_stream.h index aab625e7fb..b4ba61549f 100644 --- a/webrtc/api/call/audio_send_stream.h +++ b/webrtc/api/call/audio_send_stream.h @@ -15,6 +15,7 @@ #include #include +#include "webrtc/base/optional.h" #include "webrtc/config.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" #include "webrtc/transport.h" @@ -31,6 +32,7 @@ class AudioSendStream { public: struct Stats { Stats(); + ~Stats(); // TODO(solenberg): Harmonize naming and defaults with receive stream stats. uint32_t local_ssrc = 0; @@ -39,6 +41,7 @@ class AudioSendStream { int32_t packets_lost = -1; float fraction_lost = -1.0f; std::string codec_name; + rtc::Optional codec_payload_type; int32_t ext_seqnum = -1; int32_t jitter_ms = -1; int64_t rtt_ms = -1; diff --git a/webrtc/audio/audio_receive_stream.cc b/webrtc/audio/audio_receive_stream.cc index 0d75307b4b..5a8efc223e 100644 --- a/webrtc/audio/audio_receive_stream.cc +++ b/webrtc/audio/audio_receive_stream.cc @@ -184,6 +184,7 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const { stats.capture_start_ntp_time_ms = call_stats.capture_start_ntp_time_ms_; if (codec_inst.pltype != -1) { stats.codec_name = codec_inst.plname; + stats.codec_payload_type = rtc::Optional(codec_inst.pltype); } stats.ext_seqnum = call_stats.extendedMax; if (codec_inst.plfreq / 1000 > 0) { diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index 8c03dbaa48..b031762b4c 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -170,6 +170,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const { if (codec->GetSendCodec(config_.voe_channel_id, codec_inst) != -1) { RTC_DCHECK_NE(codec_inst.pltype, -1); stats.codec_name = codec_inst.plname; + stats.codec_payload_type = rtc::Optional(codec_inst.pltype); // Get data from the last remote RTCP report. for (const auto& block : channel_proxy_->GetRemoteRTCPReportBlocks()) { diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 80b9d4d44c..d4d339eb6e 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -553,6 +553,7 @@ struct MediaSenderInfo { float fraction_lost; int64_t rtt_ms; std::string codec_name; + rtc::Optional codec_payload_type; std::vector local_stats; std::vector remote_stats; }; @@ -598,6 +599,7 @@ struct MediaReceiverInfo { int packets_lost; float fraction_lost; std::string codec_name; + rtc::Optional codec_payload_type; std::vector local_stats; std::vector remote_stats; }; @@ -698,9 +700,6 @@ struct VideoSenderInfo : public MediaSenderInfo { std::vector ssrc_groups; // TODO(hbos): Move this to |VideoMediaInfo::send_codecs|? std::string encoder_implementation_name; - // TODO(hbos): Move this to |MediaSenderInfo| when supported by - // |VoiceSenderInfo| as well (which also extends that class). - rtc::Optional codec_payload_type; int packets_cached; int firs_rcvd; int plis_rcvd; @@ -746,9 +745,6 @@ struct VideoReceiverInfo : public MediaReceiverInfo { std::vector ssrc_groups; // TODO(hbos): Move this to |VideoMediaInfo::receive_codecs|? std::string decoder_implementation_name; - // TODO(hbos): Move this to |MediaReceiverInfo| when supported by - // |VoiceReceiverInfo| as well (which also extends that class). - rtc::Optional codec_payload_type; int packets_concealed; int firs_sent; int plis_sent; @@ -831,9 +827,13 @@ struct VoiceMediaInfo { void Clear() { senders.clear(); receivers.clear(); + send_codecs.clear(); + receive_codecs.clear(); } std::vector senders; std::vector receivers; + RtpCodecParametersMap send_codecs; + RtpCodecParametersMap receive_codecs; }; struct VideoMediaInfo { diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index c43dff80d3..5238348478 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -2025,8 +2025,8 @@ VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( if (parameters_.codec_settings) { info.codec_name = parameters_.codec_settings->codec.name; - info.codec_payload_type = rtc::Optional( - static_cast(parameters_.codec_settings->codec.id)); + info.codec_payload_type = rtc::Optional( + parameters_.codec_settings->codec.id); } if (stream_ == NULL) @@ -2436,8 +2436,8 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo( webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); info.decoder_implementation_name = stats.decoder_implementation_name; if (stats.current_payload_type != -1) { - info.codec_payload_type = rtc::Optional( - static_cast(stats.current_payload_type)); + info.codec_payload_type = rtc::Optional( + stats.current_payload_type); } info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + stats.rtp_stats.transmitted.header_bytes + diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index 937078c3e9..57921acb70 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -2526,7 +2526,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { RTC_DCHECK(info); // Get SSRC and stats for each sender. - RTC_DCHECK(info->senders.size() == 0); + RTC_DCHECK_EQ(info->senders.size(), 0U); for (const auto& stream : send_streams_) { webrtc::AudioSendStream::Stats stats = stream.second->GetStats(); VoiceSenderInfo sinfo; @@ -2536,6 +2536,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { sinfo.packets_lost = stats.packets_lost; sinfo.fraction_lost = stats.fraction_lost; sinfo.codec_name = stats.codec_name; + sinfo.codec_payload_type = stats.codec_payload_type; sinfo.ext_seqnum = stats.ext_seqnum; sinfo.jitter_ms = stats.jitter_ms; sinfo.rtt_ms = stats.rtt_ms; @@ -2551,7 +2552,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { } // Get SSRC and stats for each receiver. - RTC_DCHECK(info->receivers.size() == 0); + RTC_DCHECK_EQ(info->receivers.size(), 0U); for (const auto& stream : recv_streams_) { webrtc::AudioReceiveStream::Stats stats = stream.second->GetStats(); VoiceReceiverInfo rinfo; @@ -2561,6 +2562,7 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { rinfo.packets_lost = stats.packets_lost; rinfo.fraction_lost = stats.fraction_lost; rinfo.codec_name = stats.codec_name; + rinfo.codec_payload_type = stats.codec_payload_type; rinfo.ext_seqnum = stats.ext_seqnum; rinfo.jitter_ms = stats.jitter_ms; rinfo.jitter_buffer_ms = stats.jitter_buffer_ms; @@ -2584,6 +2586,18 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { info->receivers.push_back(rinfo); } + // Get codec info + for (const AudioCodec& codec : send_codecs_) { + webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); + info->send_codecs.insert( + std::make_pair(codec_params.payload_type, std::move(codec_params))); + } + for (const AudioCodec& codec : recv_codecs_) { + webrtc::RtpCodecParameters codec_params = codec.ToCodecParameters(); + info->receive_codecs.insert( + std::make_pair(codec_params.payload_type, std::move(codec_params))); + } + return true; } diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 3b4670ea3e..e4e4cf1b12 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -446,6 +446,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { stats.packets_lost = 9012; stats.fraction_lost = 34.56f; stats.codec_name = "codec_name_send"; + stats.codec_payload_type = rtc::Optional(42); stats.ext_seqnum = 789; stats.jitter_ms = 12; stats.rtt_ms = 345; @@ -473,6 +474,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(info.packets_lost, stats.packets_lost); EXPECT_EQ(info.fraction_lost, stats.fraction_lost); EXPECT_EQ(info.codec_name, stats.codec_name); + EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type); EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum); EXPECT_EQ(info.jitter_ms, stats.jitter_ms); EXPECT_EQ(info.rtt_ms, stats.rtt_ms); @@ -496,6 +498,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { stats.packets_lost = 101; stats.fraction_lost = 23.45f; stats.codec_name = "codec_name_recv"; + stats.codec_payload_type = rtc::Optional(42); stats.ext_seqnum = 678; stats.jitter_ms = 901; stats.jitter_buffer_ms = 234; @@ -530,6 +533,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(info.packets_lost, stats.packets_lost); EXPECT_EQ(info.fraction_lost, stats.fraction_lost); EXPECT_EQ(info.codec_name, stats.codec_name); + EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type); EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum); EXPECT_EQ(info.jitter_ms, stats.jitter_ms); EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms); @@ -552,6 +556,20 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_EQ(info.decoding_muted_output, stats.decoding_muted_output); EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms); } + void VerifyVoiceSendRecvCodecs(const cricket::VoiceMediaInfo& info) const { + EXPECT_EQ(send_parameters_.codecs.size(), info.send_codecs.size()); + for (const cricket::AudioCodec& codec : send_parameters_.codecs) { + ASSERT_EQ(info.send_codecs.count(codec.id), 1U); + EXPECT_EQ(info.send_codecs.find(codec.id)->second, + codec.ToCodecParameters()); + } + EXPECT_EQ(recv_parameters_.codecs.size(), info.receive_codecs.size()); + for (const cricket::AudioCodec& codec : recv_parameters_.codecs) { + ASSERT_EQ(info.receive_codecs.count(codec.id), 1U); + EXPECT_EQ(info.receive_codecs.find(codec.id)->second, + codec.ToCodecParameters()); + } + } protected: StrictMock adm_; @@ -2275,6 +2293,7 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) { for (const auto& sender : info.senders) { VerifyVoiceSenderInfo(sender, false); } + VerifyVoiceSendRecvCodecs(info); // We have added one receive stream. We should see empty stats. EXPECT_EQ(info.receivers.size(), 1u); @@ -2300,6 +2319,7 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) { EXPECT_EQ(static_cast(arraysize(kSsrcs4)), info.senders.size()); EXPECT_EQ(1u, info.receivers.size()); VerifyVoiceReceiverInfo(info.receivers[0]); + VerifyVoiceSendRecvCodecs(info); } } @@ -2483,6 +2503,7 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStats) { SetSend(true); EXPECT_EQ(true, channel_->GetStats(&info)); VerifyVoiceSenderInfo(info.senders[0], true); + VerifyVoiceSendRecvCodecs(info); } // Remove the kSsrc2 stream. No receiver stats. @@ -2504,6 +2525,7 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStats) { EXPECT_EQ(1u, info.senders.size()); EXPECT_EQ(1u, info.receivers.size()); VerifyVoiceReceiverInfo(info.receivers[0]); + VerifyVoiceSendRecvCodecs(info); } }