Expose RtpCodecParameters to VoiceMediaInfo stats.

Payload type -> RtpCodecParameters maps added for sender and receiver.
This is a follow-up to https://codereview.webrtc.org/2484193002/ which
did the same thing for VideoMediaInfo. This information will be used to
produce RTCCodecStats[1].

Voice[Sender/Receiver]Info is updated with current codec payload type
for every stream which can be used to look up the codec in
VoiceMediaInfo.

[1] https://w3c.github.io/webrtc-stats/#codec-dict*

BUG=chromium:659117

Review-Url: https://codereview.webrtc.org/2503383002
Cr-Commit-Position: refs/heads/master@{#15144}
This commit is contained in:
hbos 2016-11-17 23:43:29 -08:00 committed by Commit bot
parent 7b9feeeaad
commit 1acfbd22cc
9 changed files with 56 additions and 12 deletions

View File

@ -16,6 +16,7 @@
#include <string>
#include <vector>
#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<int> codec_payload_type;
uint32_t ext_seqnum = 0;
uint32_t jitter_ms = 0;
uint32_t jitter_buffer_ms = 0;

View File

@ -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) {}

View File

@ -15,6 +15,7 @@
#include <string>
#include <vector>
#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<int> codec_payload_type;
int32_t ext_seqnum = -1;
int32_t jitter_ms = -1;
int64_t rtt_ms = -1;

View File

@ -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<int>(codec_inst.pltype);
}
stats.ext_seqnum = call_stats.extendedMax;
if (codec_inst.plfreq / 1000 > 0) {

View File

@ -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<int>(codec_inst.pltype);
// Get data from the last remote RTCP report.
for (const auto& block : channel_proxy_->GetRemoteRTCPReportBlocks()) {

View File

@ -553,6 +553,7 @@ struct MediaSenderInfo {
float fraction_lost;
int64_t rtt_ms;
std::string codec_name;
rtc::Optional<int> codec_payload_type;
std::vector<SsrcSenderInfo> local_stats;
std::vector<SsrcReceiverInfo> remote_stats;
};
@ -598,6 +599,7 @@ struct MediaReceiverInfo {
int packets_lost;
float fraction_lost;
std::string codec_name;
rtc::Optional<int> codec_payload_type;
std::vector<SsrcReceiverInfo> local_stats;
std::vector<SsrcSenderInfo> remote_stats;
};
@ -698,9 +700,6 @@ struct VideoSenderInfo : public MediaSenderInfo {
std::vector<SsrcGroup> 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<uint32_t> codec_payload_type;
int packets_cached;
int firs_rcvd;
int plis_rcvd;
@ -746,9 +745,6 @@ struct VideoReceiverInfo : public MediaReceiverInfo {
std::vector<SsrcGroup> 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<uint32_t> 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<VoiceSenderInfo> senders;
std::vector<VoiceReceiverInfo> receivers;
RtpCodecParametersMap send_codecs;
RtpCodecParametersMap receive_codecs;
};
struct VideoMediaInfo {

View File

@ -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<uint32_t>(
static_cast<uint32_t>(parameters_.codec_settings->codec.id));
info.codec_payload_type = rtc::Optional<int>(
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<uint32_t>(
static_cast<uint32_t>(stats.current_payload_type));
info.codec_payload_type = rtc::Optional<int>(
stats.current_payload_type);
}
info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes +
stats.rtp_stats.transmitted.header_bytes +

View File

@ -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;
}

View File

@ -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<int>(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<int>(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<webrtc::test::MockAudioDeviceModule> 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<size_t>(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);
}
}