Add stats totalSamplesReceived and concealedSamples

Adds two new stats to RTCMediaStreamTrackStats:
* totalSamplesReceived is the total number of samples received on
      the audio channel and includes real and synthetic samples.
* concealedSamples is the total number of synthetic samples
      received on the audio channel used to conceal packet loss.

Bug: webrtc:8076
Change-Id: I36e9828525ec341490cf3310a972b56a8b443667
Reviewed-on: https://chromium-review.googlesource.com/615902
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#19506}
This commit is contained in:
Steve Anton
2017-08-24 17:15:13 -07:00
committed by Commit Bot
parent d6a5cbdf4c
commit 2dbc69fa64
20 changed files with 121 additions and 9 deletions

View File

@ -273,9 +273,11 @@ class RTCMediaStreamTrackStats final : public RTCStats {
// Audio-only members // Audio-only members
RTCStatsMember<double> audio_level; RTCStatsMember<double> audio_level;
RTCStatsMember<double> total_audio_energy; RTCStatsMember<double> total_audio_energy;
RTCStatsMember<double> total_samples_duration;
RTCStatsMember<double> echo_return_loss; RTCStatsMember<double> echo_return_loss;
RTCStatsMember<double> echo_return_loss_enhancement; RTCStatsMember<double> echo_return_loss_enhancement;
RTCStatsMember<uint64_t> total_samples_received;
RTCStatsMember<double> total_samples_duration;
RTCStatsMember<uint64_t> concealed_samples;
}; };
// https://w3c.github.io/webrtc-stats/#pcstats-dict* // https://w3c.github.io/webrtc-stats/#pcstats-dict*

View File

@ -371,6 +371,8 @@ const char* StatsReport::Value::display_name() const {
return "audioInputLevel"; return "audioInputLevel";
case kStatsValueNameBytesSent: case kStatsValueNameBytesSent:
return "bytesSent"; return "bytesSent";
case kStatsValueNameConcealedSamples:
return "concealedSamples";
case kStatsValueNamePacketsSent: case kStatsValueNamePacketsSent:
return "packetsSent"; return "packetsSent";
case kStatsValueNameBytesReceived: case kStatsValueNameBytesReceived:
@ -383,6 +385,8 @@ const char* StatsReport::Value::display_name() const {
return "packetsLost"; return "packetsLost";
case kStatsValueNameProtocol: case kStatsValueNameProtocol:
return "protocol"; return "protocol";
case kStatsValueNameTotalSamplesReceived:
return "totalSamplesReceived";
case kStatsValueNameTransportId: case kStatsValueNameTransportId:
return "transportId"; return "transportId";
case kStatsValueNameSelectedCandidatePairId: case kStatsValueNameSelectedCandidatePairId:

View File

@ -104,6 +104,7 @@ class StatsReport {
kStatsValueNameBytesReceived, kStatsValueNameBytesReceived,
kStatsValueNameBytesSent, kStatsValueNameBytesSent,
kStatsValueNameCodecImplementationName, kStatsValueNameCodecImplementationName,
kStatsValueNameConcealedSamples,
kStatsValueNameDataChannelId, kStatsValueNameDataChannelId,
kStatsValueNameFramesDecoded, kStatsValueNameFramesDecoded,
kStatsValueNameFramesEncoded, kStatsValueNameFramesEncoded,
@ -120,6 +121,7 @@ class StatsReport {
kStatsValueNameState, kStatsValueNameState,
kStatsValueNameTotalAudioEnergy, kStatsValueNameTotalAudioEnergy,
kStatsValueNameTotalSamplesDuration, kStatsValueNameTotalSamplesDuration,
kStatsValueNameTotalSamplesReceived,
kStatsValueNameTransportId, kStatsValueNameTransportId,
kStatsValueNameSentPingRequestsTotal, kStatsValueNameSentPingRequestsTotal,
kStatsValueNameSentPingRequestsBeforeFirstResponse, kStatsValueNameSentPingRequestsBeforeFirstResponse,

View File

@ -194,6 +194,8 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
auto ns = channel_proxy_->GetNetworkStatistics(); auto ns = channel_proxy_->GetNetworkStatistics();
stats.jitter_buffer_ms = ns.currentBufferSize; stats.jitter_buffer_ms = ns.currentBufferSize;
stats.jitter_buffer_preferred_ms = ns.preferredBufferSize; stats.jitter_buffer_preferred_ms = ns.preferredBufferSize;
stats.total_samples_received = ns.totalSamplesReceived;
stats.concealed_samples = ns.concealedSamples;
stats.expand_rate = Q14ToFloat(ns.currentExpandRate); stats.expand_rate = Q14ToFloat(ns.currentExpandRate);
stats.speech_expand_rate = Q14ToFloat(ns.currentSpeechExpandRate); stats.speech_expand_rate = Q14ToFloat(ns.currentSpeechExpandRate);
stats.secondary_decoded_rate = Q14ToFloat(ns.currentSecondaryDecodedRate); stats.secondary_decoded_rate = Q14ToFloat(ns.currentSecondaryDecodedRate);

View File

@ -64,8 +64,9 @@ const CallStatistics kCallStats = {
345, 678, 901, 234, -12, 3456, 7890, 567, 890, 123}; 345, 678, 901, 234, -12, 3456, 7890, 567, 890, 123};
const CodecInst kCodecInst = { const CodecInst kCodecInst = {
123, "codec_name_recv", 96000, -187, 0, -103}; 123, "codec_name_recv", 96000, -187, 0, -103};
const NetworkStatistics kNetworkStats = { const NetworkStatistics kNetworkStats = {123, 456, false, 789012, 3456, 0, {},
123, 456, false, 0, {}, 789, 12, 345, 678, 901, 0, -1, -1, -1, -1, -1, 0}; 789, 12, 345, 678, 901, 0, -1,
-1, -1, -1, -1, 0};
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest(); const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
struct ConfigHelper { struct ConfigHelper {
@ -318,7 +319,9 @@ TEST(AudioReceiveStreamTest, GetStats) {
stats.delay_estimate_ms); stats.delay_estimate_ms);
EXPECT_EQ(static_cast<int32_t>(kSpeechOutputLevel), stats.audio_level); EXPECT_EQ(static_cast<int32_t>(kSpeechOutputLevel), stats.audio_level);
EXPECT_EQ(kTotalOutputEnergy, stats.total_output_energy); EXPECT_EQ(kTotalOutputEnergy, stats.total_output_energy);
EXPECT_EQ(kNetworkStats.totalSamplesReceived, stats.total_samples_received);
EXPECT_EQ(kTotalOutputDuration, stats.total_output_duration); EXPECT_EQ(kTotalOutputDuration, stats.total_output_duration);
EXPECT_EQ(kNetworkStats.concealedSamples, stats.concealed_samples);
EXPECT_EQ(Q14ToFloat(kNetworkStats.currentExpandRate), stats.expand_rate); EXPECT_EQ(Q14ToFloat(kNetworkStats.currentExpandRate), stats.expand_rate);
EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSpeechExpandRate), EXPECT_EQ(Q14ToFloat(kNetworkStats.currentSpeechExpandRate),
stats.speech_expand_rate); stats.speech_expand_rate);

View File

@ -52,7 +52,15 @@ class AudioReceiveStream {
// See description of "totalAudioEnergy" in the WebRTC stats spec: // See description of "totalAudioEnergy" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
double total_output_energy = 0.0; double total_output_energy = 0.0;
// See description of "totalSamplesReceived" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesreceived
uint64_t total_samples_received = 0;
// See description of "totalSamplesDuration" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesduration
double total_output_duration = 0.0; double total_output_duration = 0.0;
// See description of "concealedSamples" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-concealedsamples
uint64_t concealed_samples = 0;
float expand_rate = 0.0f; float expand_rate = 0.0f;
float speech_expand_rate = 0.0f; float speech_expand_rate = 0.0f;
float secondary_decoded_rate = 0.0f; float secondary_decoded_rate = 0.0f;

View File

@ -367,6 +367,13 @@ struct NetworkStatistics {
uint16_t preferredBufferSize; uint16_t preferredBufferSize;
// adding extra delay due to "peaky jitter" // adding extra delay due to "peaky jitter"
bool jitterPeaksFound; bool jitterPeaksFound;
// Total number of audio samples received, including synthesized samples.
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesreceived
uint64_t totalSamplesReceived;
// Total number of inbound audio samples that are based on synthesized data to
// conceal packet loss.
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-concealedsamples
uint64_t concealedSamples;
// Loss rate (network + late); fraction between 0 and 1, scaled to Q14. // Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
uint16_t currentPacketLossRate; uint16_t currentPacketLossRate;
// Late loss rate; fraction between 0 and 1, scaled to Q14. // Late loss rate; fraction between 0 and 1, scaled to Q14.

View File

@ -652,7 +652,9 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
delay_estimate_ms(0), delay_estimate_ms(0),
audio_level(0), audio_level(0),
total_output_energy(0.0), total_output_energy(0.0),
total_samples_received(0),
total_output_duration(0.0), total_output_duration(0.0),
concealed_samples(0),
expand_rate(0), expand_rate(0),
speech_expand_rate(0), speech_expand_rate(0),
secondary_decoded_rate(0), secondary_decoded_rate(0),
@ -676,7 +678,15 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
// See description of "totalAudioEnergy" in the WebRTC stats spec: // See description of "totalAudioEnergy" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalaudioenergy
double total_output_energy; double total_output_energy;
// See description of "totalSamplesReceived" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesreceived
uint64_t total_samples_received;
// See description of "totalSamplesDuration" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesduration
double total_output_duration; double total_output_duration;
// See description of "concealedSamples" in the WebRTC stats spec:
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-concealedsamples
uint64_t concealed_samples;
// fraction of synthesized audio inserted through expansion. // fraction of synthesized audio inserted through expansion.
float expand_rate; float expand_rate;
// fraction of synthesized speech inserted through expansion. // fraction of synthesized speech inserted through expansion.

View File

@ -2282,7 +2282,9 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
rinfo.delay_estimate_ms = stats.delay_estimate_ms; rinfo.delay_estimate_ms = stats.delay_estimate_ms;
rinfo.audio_level = stats.audio_level; rinfo.audio_level = stats.audio_level;
rinfo.total_output_energy = stats.total_output_energy; rinfo.total_output_energy = stats.total_output_energy;
rinfo.total_samples_received = stats.total_samples_received;
rinfo.total_output_duration = stats.total_output_duration; rinfo.total_output_duration = stats.total_output_duration;
rinfo.concealed_samples = stats.concealed_samples;
rinfo.expand_rate = stats.expand_rate; rinfo.expand_rate = stats.expand_rate;
rinfo.speech_expand_rate = stats.speech_expand_rate; rinfo.speech_expand_rate = stats.speech_expand_rate;
rinfo.secondary_decoded_rate = stats.secondary_decoded_rate; rinfo.secondary_decoded_rate = stats.secondary_decoded_rate;

View File

@ -596,6 +596,8 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
stats.jitter_buffer_preferred_ms = 567; stats.jitter_buffer_preferred_ms = 567;
stats.delay_estimate_ms = 890; stats.delay_estimate_ms = 890;
stats.audio_level = 1234; stats.audio_level = 1234;
stats.total_samples_received = 5678901;
stats.concealed_samples = 234;
stats.expand_rate = 5.67f; stats.expand_rate = 5.67f;
stats.speech_expand_rate = 8.90f; stats.speech_expand_rate = 8.90f;
stats.secondary_decoded_rate = 1.23f; stats.secondary_decoded_rate = 1.23f;
@ -632,6 +634,8 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
stats.jitter_buffer_preferred_ms); stats.jitter_buffer_preferred_ms);
EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms); EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
EXPECT_EQ(info.audio_level, stats.audio_level); EXPECT_EQ(info.audio_level, stats.audio_level);
EXPECT_EQ(info.total_samples_received, stats.total_samples_received);
EXPECT_EQ(info.concealed_samples, stats.concealed_samples);
EXPECT_EQ(info.expand_rate, stats.expand_rate); EXPECT_EQ(info.expand_rate, stats.expand_rate);
EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate); EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate); EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);

View File

@ -332,6 +332,10 @@ void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
acm_stat->medianWaitingTimeMs = neteq_stat.median_waiting_time_ms; acm_stat->medianWaitingTimeMs = neteq_stat.median_waiting_time_ms;
acm_stat->minWaitingTimeMs = neteq_stat.min_waiting_time_ms; acm_stat->minWaitingTimeMs = neteq_stat.min_waiting_time_ms;
acm_stat->maxWaitingTimeMs = neteq_stat.max_waiting_time_ms; acm_stat->maxWaitingTimeMs = neteq_stat.max_waiting_time_ms;
NetEqLifetimeStatistics neteq_lifetime_stat = neteq_->GetLifetimeStatistics();
acm_stat->totalSamplesReceived = neteq_lifetime_stat.total_samples_received;
acm_stat->concealedSamples = neteq_lifetime_stat.concealed_samples;
} }
int AcmReceiver::DecoderByPayloadType(uint8_t payload_type, int AcmReceiver::DecoderByPayloadType(uint8_t payload_type,

View File

@ -58,6 +58,18 @@ struct NetEqNetworkStatistics {
int max_waiting_time_ms; int max_waiting_time_ms;
}; };
// NetEq statistics that persist over the lifetime of the class.
// These metrics are never reset.
struct NetEqLifetimeStatistics {
// Total number of audio samples received, including synthesized samples.
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-totalsamplesreceived
uint64_t total_samples_received = 0;
// Total number of inbound audio samples that are based on synthesized data to
// conceal packet loss.
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-concealedsamples
uint64_t concealed_samples = 0;
};
enum NetEqPlayoutMode { enum NetEqPlayoutMode {
kPlayoutOn, kPlayoutOn,
kPlayoutOff, kPlayoutOff,
@ -220,6 +232,10 @@ class NetEq {
// after the call. // after the call.
virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0; virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0;
// Returns a copy of this class's lifetime statistics. These statistics are
// never reset.
virtual NetEqLifetimeStatistics GetLifetimeStatistics() const = 0;
// Writes the current RTCP statistics to |stats|. The statistics are reset // Writes the current RTCP statistics to |stats|. The statistics are reset
// and a new report period is started with the call. // and a new report period is started with the call.
virtual void GetRtcpStatistics(RtcpStatistics* stats) = 0; virtual void GetRtcpStatistics(RtcpStatistics* stats) = 0;

View File

@ -380,6 +380,11 @@ int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) {
return 0; return 0;
} }
NetEqLifetimeStatistics NetEqImpl::GetLifetimeStatistics() const {
rtc::CritScope lock(&crit_sect_);
return stats_.GetLifetimeStatistics();
}
void NetEqImpl::GetRtcpStatistics(RtcpStatistics* stats) { void NetEqImpl::GetRtcpStatistics(RtcpStatistics* stats) {
rtc::CritScope lock(&crit_sect_); rtc::CritScope lock(&crit_sect_);
if (stats) { if (stats) {

View File

@ -185,6 +185,8 @@ class NetEqImpl : public webrtc::NetEq {
// and a new report period is started with the call. // and a new report period is started with the call.
void GetRtcpStatistics(RtcpStatistics* stats) override; void GetRtcpStatistics(RtcpStatistics* stats) override;
NetEqLifetimeStatistics GetLifetimeStatistics() const override;
// Same as RtcpStatistics(), but does not reset anything. // Same as RtcpStatistics(), but does not reset anything.
void GetRtcpStatisticsNoReset(RtcpStatistics* stats) override; void GetRtcpStatisticsNoReset(RtcpStatistics* stats) override;

View File

@ -153,24 +153,29 @@ void StatisticsCalculator::ResetMcu() {
void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) { void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) {
expanded_speech_samples_ += num_samples; expanded_speech_samples_ += num_samples;
lifetime_stats_.concealed_samples += num_samples;
} }
void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) { void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) {
expanded_noise_samples_ += num_samples; expanded_noise_samples_ += num_samples;
lifetime_stats_.concealed_samples += num_samples;
} }
void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) { void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) {
expanded_speech_samples_ = expanded_speech_samples_ =
AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_); AddIntToSizeTWithLowerCap(num_samples, expanded_speech_samples_);
lifetime_stats_.concealed_samples += num_samples;
} }
void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) { void StatisticsCalculator::ExpandedNoiseSamplesCorrection(int num_samples) {
expanded_noise_samples_ = expanded_noise_samples_ =
AddIntToSizeTWithLowerCap(num_samples, expanded_noise_samples_); AddIntToSizeTWithLowerCap(num_samples, expanded_noise_samples_);
lifetime_stats_.concealed_samples += num_samples;
} }
void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) { void StatisticsCalculator::PreemptiveExpandedSamples(size_t num_samples) {
preemptive_samples_ += num_samples; preemptive_samples_ += num_samples;
lifetime_stats_.concealed_samples += num_samples;
} }
void StatisticsCalculator::AcceleratedSamples(size_t num_samples) { void StatisticsCalculator::AcceleratedSamples(size_t num_samples) {
@ -205,6 +210,7 @@ void StatisticsCalculator::IncreaseCounter(size_t num_samples, int fs_hz) {
timestamps_since_last_report_ = 0; timestamps_since_last_report_ = 0;
discarded_packets_ = 0; discarded_packets_ = 0;
} }
lifetime_stats_.total_samples_received += num_samples;
} }
void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) {
@ -307,6 +313,10 @@ void StatisticsCalculator::GetNetworkStatistics(
Reset(); Reset();
} }
NetEqLifetimeStatistics StatisticsCalculator::GetLifetimeStatistics() const {
return lifetime_stats_;
}
uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator, uint16_t StatisticsCalculator::CalculateQ14Ratio(size_t numerator,
uint32_t denominator) { uint32_t denominator) {
if (numerator == 0) { if (numerator == 0) {

View File

@ -99,6 +99,10 @@ class StatisticsCalculator {
const DecisionLogic& decision_logic, const DecisionLogic& decision_logic,
NetEqNetworkStatistics *stats); NetEqNetworkStatistics *stats);
// Returns a copy of this class's lifetime statistics. These statistics are
// never reset.
NetEqLifetimeStatistics GetLifetimeStatistics() const;
private: private:
static const int kMaxReportPeriod = 60; // Seconds before auto-reset. static const int kMaxReportPeriod = 60; // Seconds before auto-reset.
static const size_t kLenWaitingTimes = 100; static const size_t kLenWaitingTimes = 100;
@ -158,6 +162,8 @@ class StatisticsCalculator {
// Calculates numerator / denominator, and returns the value in Q14. // Calculates numerator / denominator, and returns the value in Q14.
static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator); static uint16_t CalculateQ14Ratio(size_t numerator, uint32_t denominator);
// TODO(steveanton): Add unit tests for the lifetime stats.
NetEqLifetimeStatistics lifetime_stats_;
size_t preemptive_samples_; size_t preemptive_samples_;
size_t accelerate_samples_; size_t accelerate_samples_;
size_t added_zero_samples_; size_t added_zero_samples_;

View File

@ -525,6 +525,18 @@ class RTCStatsReportVerifier {
verifier.MarkMemberTested( verifier.MarkMemberTested(
media_stream_track.echo_return_loss_enhancement, true); media_stream_track.echo_return_loss_enhancement, true);
} }
// totalSamplesReceived and concealedSamples are only present on inbound
// audio tracks.
if (*media_stream_track.kind == RTCMediaStreamTrackKind::kAudio &&
*media_stream_track.remote_source) {
verifier.TestMemberIsNonNegative<uint64_t>(
media_stream_track.total_samples_received);
verifier.TestMemberIsNonNegative<uint64_t>(
media_stream_track.concealed_samples);
} else {
verifier.TestMemberIsUndefined(media_stream_track.total_samples_received);
verifier.TestMemberIsUndefined(media_stream_track.concealed_samples);
}
return verifier.ExpectAllMembersSuccessfullyTested(); return verifier.ExpectAllMembersSuccessfullyTested();
} }

View File

@ -424,8 +424,11 @@ ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
} }
audio_track_stats->total_audio_energy = audio_track_stats->total_audio_energy =
voice_receiver_info.total_output_energy; voice_receiver_info.total_output_energy;
audio_track_stats->total_samples_received =
voice_receiver_info.total_samples_received;
audio_track_stats->total_samples_duration = audio_track_stats->total_samples_duration =
voice_receiver_info.total_output_duration; voice_receiver_info.total_output_duration;
audio_track_stats->concealed_samples = voice_receiver_info.concealed_samples;
return audio_track_stats; return audio_track_stats;
} }

View File

@ -1554,7 +1554,9 @@ TEST_F(RTCStatsCollectorTest,
voice_receiver_info.local_stats[0].ssrc = 3; voice_receiver_info.local_stats[0].ssrc = 3;
voice_receiver_info.audio_level = 16383; voice_receiver_info.audio_level = 16383;
voice_receiver_info.total_output_energy = 0.125; voice_receiver_info.total_output_energy = 0.125;
voice_receiver_info.total_samples_received = 4567;
voice_receiver_info.total_output_duration = 0.25; voice_receiver_info.total_output_duration = 0.25;
voice_receiver_info.concealed_samples = 123;
test_->CreateMockRtpSendersReceiversAndChannels( test_->CreateMockRtpSendersReceiversAndChannels(
{ std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1), { std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1),
@ -1628,7 +1630,9 @@ TEST_F(RTCStatsCollectorTest,
expected_remote_audio_track.detached = false; expected_remote_audio_track.detached = false;
expected_remote_audio_track.audio_level = 16383.0 / 32767.0; expected_remote_audio_track.audio_level = 16383.0 / 32767.0;
expected_remote_audio_track.total_audio_energy = 0.125; expected_remote_audio_track.total_audio_energy = 0.125;
expected_remote_audio_track.total_samples_received = 4567;
expected_remote_audio_track.total_samples_duration = 0.25; expected_remote_audio_track.total_samples_duration = 0.25;
expected_remote_audio_track.concealed_samples = 123;
ASSERT_TRUE(report->Get(expected_remote_audio_track.id())); ASSERT_TRUE(report->Get(expected_remote_audio_track.id()));
EXPECT_EQ(expected_remote_audio_track, EXPECT_EQ(expected_remote_audio_track,
report->Get(expected_remote_audio_track.id())->cast_to< report->Get(expected_remote_audio_track.id())->cast_to<

View File

@ -379,9 +379,11 @@ WEBRTC_RTCSTATS_IMPL(RTCMediaStreamTrackStats, RTCStats, "track",
&full_frames_lost, &full_frames_lost,
&audio_level, &audio_level,
&total_audio_energy, &total_audio_energy,
&total_samples_duration,
&echo_return_loss, &echo_return_loss,
&echo_return_loss_enhancement); &echo_return_loss_enhancement,
&total_samples_received,
&total_samples_duration,
&concealed_samples);
// clang-format on // clang-format on
RTCMediaStreamTrackStats::RTCMediaStreamTrackStats( RTCMediaStreamTrackStats::RTCMediaStreamTrackStats(
@ -410,9 +412,11 @@ RTCMediaStreamTrackStats::RTCMediaStreamTrackStats(std::string&& id,
full_frames_lost("fullFramesLost"), full_frames_lost("fullFramesLost"),
audio_level("audioLevel"), audio_level("audioLevel"),
total_audio_energy("totalAudioEnergy"), total_audio_energy("totalAudioEnergy"),
total_samples_duration("totalSamplesDuration"),
echo_return_loss("echoReturnLoss"), echo_return_loss("echoReturnLoss"),
echo_return_loss_enhancement("echoReturnLossEnhancement") { echo_return_loss_enhancement("echoReturnLossEnhancement"),
total_samples_received("totalSamplesReceived"),
total_samples_duration("totalSamplesDuration"),
concealed_samples("concealedSamples") {
RTC_DCHECK(kind == RTCMediaStreamTrackKind::kAudio || RTC_DCHECK(kind == RTCMediaStreamTrackKind::kAudio ||
kind == RTCMediaStreamTrackKind::kVideo); kind == RTCMediaStreamTrackKind::kVideo);
} }
@ -437,9 +441,11 @@ RTCMediaStreamTrackStats::RTCMediaStreamTrackStats(
full_frames_lost(other.full_frames_lost), full_frames_lost(other.full_frames_lost),
audio_level(other.audio_level), audio_level(other.audio_level),
total_audio_energy(other.total_audio_energy), total_audio_energy(other.total_audio_energy),
total_samples_duration(other.total_samples_duration),
echo_return_loss(other.echo_return_loss), echo_return_loss(other.echo_return_loss),
echo_return_loss_enhancement(other.echo_return_loss_enhancement) {} echo_return_loss_enhancement(other.echo_return_loss_enhancement),
total_samples_received(other.total_samples_received),
total_samples_duration(other.total_samples_duration),
concealed_samples(other.concealed_samples) {}
RTCMediaStreamTrackStats::~RTCMediaStreamTrackStats() { RTCMediaStreamTrackStats::~RTCMediaStreamTrackStats() {
} }