Expose new audio stats on the API
Several new audio stats were recently standardized and implemented in WebRTC in https://webrtc-review.googlesource.com/c/src/+/133887. This CL adds these to the GetStats API. Bug: webrtc:10442, webrtc:10443, webrtc:10444 Change-Id: I0e898ac14777e82b1a9099b5e0a5584eb9cb5934 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/134213 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Ivo Creusen <ivoc@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27839}
This commit is contained in:
parent
e847481dc8
commit
8d8ffdbcca
@ -315,7 +315,10 @@ class RTC_EXPORT RTCMediaStreamTrackStats final : public RTCStats {
|
||||
RTCStatsMember<uint64_t> total_samples_received;
|
||||
RTCStatsMember<double> total_samples_duration;
|
||||
RTCStatsMember<uint64_t> concealed_samples;
|
||||
RTCStatsMember<uint64_t> silent_concealed_samples;
|
||||
RTCStatsMember<uint64_t> concealment_events;
|
||||
RTCStatsMember<uint64_t> inserted_samples_for_deceleration;
|
||||
RTCStatsMember<uint64_t> removed_samples_for_acceleration;
|
||||
// Non-standard audio-only member
|
||||
// TODO(kuddai): Add description to standard. crbug.com/webrtc/10042
|
||||
RTCNonStandardStatsMember<uint64_t> jitter_buffer_flushes;
|
||||
@ -399,6 +402,8 @@ class RTC_EXPORT RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
|
||||
~RTCInboundRTPStreamStats() override;
|
||||
|
||||
RTCStatsMember<uint32_t> packets_received;
|
||||
RTCStatsMember<uint64_t> fec_packets_received;
|
||||
RTCStatsMember<uint64_t> fec_packets_discarded;
|
||||
RTCStatsMember<uint64_t> bytes_received;
|
||||
RTCStatsMember<int32_t> packets_lost; // Signed per RFC 3550
|
||||
RTCStatsMember<double> last_packet_received_timestamp;
|
||||
|
||||
@ -206,15 +206,20 @@ webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
|
||||
|
||||
// Get jitter buffer and total delay (alg + jitter + playout) stats.
|
||||
auto ns = channel_receive_->GetNetworkStatistics();
|
||||
stats.fec_packets_received = ns.fecPacketsReceived;
|
||||
stats.fec_packets_discarded = ns.fecPacketsDiscarded;
|
||||
stats.jitter_buffer_ms = ns.currentBufferSize;
|
||||
stats.jitter_buffer_preferred_ms = ns.preferredBufferSize;
|
||||
stats.total_samples_received = ns.totalSamplesReceived;
|
||||
stats.concealed_samples = ns.concealedSamples;
|
||||
stats.silent_concealed_samples = ns.silentConcealedSamples;
|
||||
stats.concealment_events = ns.concealmentEvents;
|
||||
stats.jitter_buffer_delay_seconds =
|
||||
static_cast<double>(ns.jitterBufferDelayMs) /
|
||||
static_cast<double>(rtc::kNumMillisecsPerSec);
|
||||
stats.jitter_buffer_emitted_count = ns.jitterBufferEmittedCount;
|
||||
stats.inserted_samples_for_deceleration = ns.insertedSamplesForDeceleration;
|
||||
stats.removed_samples_for_acceleration = ns.removedSamplesForAcceleration;
|
||||
stats.expand_rate = Q14ToFloat(ns.currentExpandRate);
|
||||
stats.speech_expand_rate = Q14ToFloat(ns.currentSpeechExpandRate);
|
||||
stats.secondary_decoded_rate = Q14ToFloat(ns.currentSecondaryDecodedRate);
|
||||
|
||||
@ -67,8 +67,9 @@ const std::pair<int, SdpAudioFormat> kReceiveCodec = {
|
||||
123,
|
||||
{"codec_name_recv", 96000, 0}};
|
||||
const NetworkStatistics kNetworkStats = {
|
||||
123, 456, false, 789012, 3456, 123, 456, 789, 0, {}, 789,
|
||||
12, 345, 678, 901, 0, -1, -1, -1, -1, -1, 0};
|
||||
123, 456, false, 789012, 3456, 123, 456, 789, 543, 432,
|
||||
321, 123, 101, 0, {}, 789, 12, 345, 678, 901,
|
||||
0, -1, -1, -1, -1, -1, 0, 0, 0, 0};
|
||||
const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
||||
|
||||
struct ConfigHelper {
|
||||
|
||||
@ -38,6 +38,8 @@ class AudioReceiveStream {
|
||||
uint32_t remote_ssrc = 0;
|
||||
int64_t bytes_rcvd = 0;
|
||||
uint32_t packets_rcvd = 0;
|
||||
uint64_t fec_packets_received = 0;
|
||||
uint64_t fec_packets_discarded = 0;
|
||||
uint32_t packets_lost = 0;
|
||||
float fraction_lost = 0.0f;
|
||||
std::string codec_name;
|
||||
@ -54,9 +56,12 @@ class AudioReceiveStream {
|
||||
uint64_t total_samples_received = 0;
|
||||
double total_output_duration = 0.0;
|
||||
uint64_t concealed_samples = 0;
|
||||
uint64_t silent_concealed_samples = 0;
|
||||
uint64_t concealment_events = 0;
|
||||
double jitter_buffer_delay_seconds = 0.0;
|
||||
uint64_t jitter_buffer_emitted_count = 0;
|
||||
uint64_t inserted_samples_for_deceleration = 0;
|
||||
uint64_t removed_samples_for_acceleration = 0;
|
||||
// Stats below DO NOT correspond directly to anything in the WebRTC stats
|
||||
float expand_rate = 0.0f;
|
||||
float speech_expand_rate = 0.0f;
|
||||
|
||||
@ -479,9 +479,14 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
|
||||
uint64_t total_samples_received = 0;
|
||||
double total_output_duration = 0.0;
|
||||
uint64_t concealed_samples = 0;
|
||||
uint64_t silent_concealed_samples = 0;
|
||||
uint64_t concealment_events = 0;
|
||||
double jitter_buffer_delay_seconds = 0.0;
|
||||
uint64_t jitter_buffer_emitted_count = 0;
|
||||
uint64_t inserted_samples_for_deceleration = 0;
|
||||
uint64_t removed_samples_for_acceleration = 0;
|
||||
uint64_t fec_packets_received = 0;
|
||||
uint64_t fec_packets_discarded = 0;
|
||||
// Stats below DO NOT correspond directly to anything in the WebRTC stats
|
||||
// fraction of synthesized audio inserted through expansion.
|
||||
float expand_rate = 0.0f;
|
||||
|
||||
@ -2226,6 +2226,8 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
|
||||
rinfo.add_ssrc(stats.remote_ssrc);
|
||||
rinfo.bytes_rcvd = stats.bytes_rcvd;
|
||||
rinfo.packets_rcvd = stats.packets_rcvd;
|
||||
rinfo.fec_packets_received = stats.fec_packets_received;
|
||||
rinfo.fec_packets_discarded = stats.fec_packets_discarded;
|
||||
rinfo.packets_lost = stats.packets_lost;
|
||||
rinfo.fraction_lost = stats.fraction_lost;
|
||||
rinfo.codec_name = stats.codec_name;
|
||||
@ -2240,9 +2242,14 @@ bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
|
||||
rinfo.total_samples_received = stats.total_samples_received;
|
||||
rinfo.total_output_duration = stats.total_output_duration;
|
||||
rinfo.concealed_samples = stats.concealed_samples;
|
||||
rinfo.silent_concealed_samples = stats.silent_concealed_samples;
|
||||
rinfo.concealment_events = stats.concealment_events;
|
||||
rinfo.jitter_buffer_delay_seconds = stats.jitter_buffer_delay_seconds;
|
||||
rinfo.jitter_buffer_emitted_count = stats.jitter_buffer_emitted_count;
|
||||
rinfo.inserted_samples_for_deceleration =
|
||||
stats.inserted_samples_for_deceleration;
|
||||
rinfo.removed_samples_for_acceleration =
|
||||
stats.removed_samples_for_acceleration;
|
||||
rinfo.expand_rate = stats.expand_rate;
|
||||
rinfo.speech_expand_rate = stats.speech_expand_rate;
|
||||
rinfo.secondary_decoded_rate = stats.secondary_decoded_rate;
|
||||
|
||||
@ -251,6 +251,8 @@ void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
|
||||
NetEqLifetimeStatistics neteq_lifetime_stat = neteq_->GetLifetimeStatistics();
|
||||
acm_stat->totalSamplesReceived = neteq_lifetime_stat.total_samples_received;
|
||||
acm_stat->concealedSamples = neteq_lifetime_stat.concealed_samples;
|
||||
acm_stat->silentConcealedSamples =
|
||||
neteq_lifetime_stat.silent_concealed_samples;
|
||||
acm_stat->concealmentEvents = neteq_lifetime_stat.concealment_events;
|
||||
acm_stat->jitterBufferDelayMs = neteq_lifetime_stat.jitter_buffer_delay_ms;
|
||||
acm_stat->jitterBufferEmittedCount =
|
||||
@ -262,6 +264,12 @@ void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) {
|
||||
acm_stat->interruptionCount = neteq_lifetime_stat.interruption_count;
|
||||
acm_stat->totalInterruptionDurationMs =
|
||||
neteq_lifetime_stat.total_interruption_duration_ms;
|
||||
acm_stat->insertedSamplesForDeceleration =
|
||||
neteq_lifetime_stat.inserted_samples_for_deceleration;
|
||||
acm_stat->removedSamplesForAcceleration =
|
||||
neteq_lifetime_stat.removed_samples_for_acceleration;
|
||||
acm_stat->fecPacketsReceived = neteq_lifetime_stat.fec_packets_received;
|
||||
acm_stat->fecPacketsDiscarded = neteq_lifetime_stat.fec_packets_discarded;
|
||||
|
||||
NetEqOperationsAndState neteq_operations_and_state =
|
||||
neteq_->GetOperationsAndState();
|
||||
|
||||
@ -84,9 +84,14 @@ struct NetworkStatistics {
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
|
||||
uint64_t totalSamplesReceived;
|
||||
uint64_t concealedSamples;
|
||||
uint64_t silentConcealedSamples;
|
||||
uint64_t concealmentEvents;
|
||||
uint64_t jitterBufferDelayMs;
|
||||
uint64_t jitterBufferEmittedCount;
|
||||
uint64_t insertedSamplesForDeceleration;
|
||||
uint64_t removedSamplesForAcceleration;
|
||||
uint64_t fecPacketsReceived;
|
||||
uint64_t fecPacketsDiscarded;
|
||||
// Stats below DO NOT correspond directly to anything in the WebRTC stats
|
||||
// Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
|
||||
uint16_t currentPacketLossRate;
|
||||
|
||||
@ -250,6 +250,10 @@ void SetInboundRTPStreamStatsFromVoiceReceiverInfo(
|
||||
*voice_receiver_info.last_packet_received_timestamp_ms) /
|
||||
rtc::kNumMillisecsPerSec;
|
||||
}
|
||||
inbound_audio->fec_packets_received =
|
||||
voice_receiver_info.fec_packets_received;
|
||||
inbound_audio->fec_packets_discarded =
|
||||
voice_receiver_info.fec_packets_discarded;
|
||||
}
|
||||
|
||||
void SetInboundRTPStreamStatsFromVideoReceiverInfo(
|
||||
@ -475,6 +479,10 @@ ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
|
||||
voice_receiver_info.jitter_buffer_delay_seconds;
|
||||
audio_track_stats->jitter_buffer_emitted_count =
|
||||
voice_receiver_info.jitter_buffer_emitted_count;
|
||||
audio_track_stats->inserted_samples_for_deceleration =
|
||||
voice_receiver_info.inserted_samples_for_deceleration;
|
||||
audio_track_stats->removed_samples_for_acceleration =
|
||||
voice_receiver_info.removed_samples_for_acceleration;
|
||||
audio_track_stats->total_audio_energy =
|
||||
voice_receiver_info.total_output_energy;
|
||||
audio_track_stats->total_samples_received =
|
||||
@ -482,6 +490,8 @@ ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
|
||||
audio_track_stats->total_samples_duration =
|
||||
voice_receiver_info.total_output_duration;
|
||||
audio_track_stats->concealed_samples = voice_receiver_info.concealed_samples;
|
||||
audio_track_stats->silent_concealed_samples =
|
||||
voice_receiver_info.silent_concealed_samples;
|
||||
audio_track_stats->concealment_events =
|
||||
voice_receiver_info.concealment_events;
|
||||
audio_track_stats->jitter_buffer_flushes =
|
||||
@ -921,7 +931,7 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThreadImpl(
|
||||
void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
|
||||
int64_t timestamp_us) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
// Touching |network_report_| on this thread is safe by this method because
|
||||
// Touching |network_report_| on this thread is safe by this method because
|
||||
// |network_report_event_| is reset before this method is invoked.
|
||||
network_report_ = RTCStatsReport::Create(timestamp_us);
|
||||
|
||||
|
||||
@ -1424,6 +1424,9 @@ TEST_F(RTCStatsCollectorTest,
|
||||
voice_receiver_info.total_output_duration = 0.25;
|
||||
voice_receiver_info.concealed_samples = 123;
|
||||
voice_receiver_info.concealment_events = 12;
|
||||
voice_receiver_info.inserted_samples_for_deceleration = 987;
|
||||
voice_receiver_info.removed_samples_for_acceleration = 876;
|
||||
voice_receiver_info.silent_concealed_samples = 765;
|
||||
voice_receiver_info.jitter_buffer_delay_seconds = 3456;
|
||||
voice_receiver_info.jitter_buffer_emitted_count = 13;
|
||||
voice_receiver_info.jitter_buffer_flushes = 7;
|
||||
@ -1463,6 +1466,9 @@ TEST_F(RTCStatsCollectorTest,
|
||||
expected_remote_audio_track.total_samples_duration = 0.25;
|
||||
expected_remote_audio_track.concealed_samples = 123;
|
||||
expected_remote_audio_track.concealment_events = 12;
|
||||
expected_remote_audio_track.inserted_samples_for_deceleration = 987;
|
||||
expected_remote_audio_track.removed_samples_for_acceleration = 876;
|
||||
expected_remote_audio_track.silent_concealed_samples = 765;
|
||||
expected_remote_audio_track.jitter_buffer_delay = 3456;
|
||||
expected_remote_audio_track.jitter_buffer_emitted_count = 13;
|
||||
expected_remote_audio_track.jitter_buffer_flushes = 7;
|
||||
@ -1625,6 +1631,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
||||
voice_media_info.receivers[0].local_stats[0].ssrc = 1;
|
||||
voice_media_info.receivers[0].packets_lost = -1; // Signed per RFC3550
|
||||
voice_media_info.receivers[0].packets_rcvd = 2;
|
||||
voice_media_info.receivers[0].fec_packets_discarded = 5566;
|
||||
voice_media_info.receivers[0].fec_packets_received = 6677;
|
||||
voice_media_info.receivers[0].bytes_rcvd = 3;
|
||||
voice_media_info.receivers[0].codec_payload_type = 42;
|
||||
voice_media_info.receivers[0].jitter_ms = 4500;
|
||||
@ -1660,6 +1668,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
||||
expected_audio.transport_id = "RTCTransport_TransportName_1";
|
||||
expected_audio.codec_id = "RTCCodec_AudioMid_Inbound_42";
|
||||
expected_audio.packets_received = 2;
|
||||
expected_audio.fec_packets_discarded = 5566;
|
||||
expected_audio.fec_packets_received = 6677;
|
||||
expected_audio.bytes_received = 3;
|
||||
expected_audio.packets_lost = -1;
|
||||
// |expected_audio.last_packet_received_timestamp| should be undefined.
|
||||
|
||||
@ -648,6 +648,12 @@ class RTCStatsReportVerifier {
|
||||
media_stream_track.concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.concealment_events);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.inserted_samples_for_deceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.removed_samples_for_acceleration);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.silent_concealed_samples);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
media_stream_track.jitter_buffer_flushes);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
@ -722,6 +728,13 @@ class RTCStatsReportVerifier {
|
||||
verifier.TestMemberIsUndefined(inbound_stream.qp_sum);
|
||||
}
|
||||
verifier.TestMemberIsNonNegative<uint32_t>(inbound_stream.packets_received);
|
||||
if (inbound_stream.media_type.is_defined() &&
|
||||
*inbound_stream.media_type == "audio") {
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
inbound_stream.fec_packets_received);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
inbound_stream.fec_packets_discarded);
|
||||
}
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(inbound_stream.bytes_received);
|
||||
// packets_lost is defined as signed, but this should never happen in
|
||||
// this test. See RFC 3550.
|
||||
|
||||
@ -433,7 +433,10 @@ RTCMediaStreamTrackStats::RTCMediaStreamTrackStats(std::string&& id,
|
||||
total_samples_received("totalSamplesReceived"),
|
||||
total_samples_duration("totalSamplesDuration"),
|
||||
concealed_samples("concealedSamples"),
|
||||
silent_concealed_samples("silentConcealedSamples"),
|
||||
concealment_events("concealmentEvents"),
|
||||
inserted_samples_for_deceleration("insertedSamplesForDeceleration"),
|
||||
removed_samples_for_acceleration("removedSamplesForAcceleration"),
|
||||
jitter_buffer_flushes(
|
||||
"jitterBufferFlushes",
|
||||
{NonStandardGroupId::kRtcAudioJitterBufferMaxPackets}),
|
||||
@ -484,7 +487,11 @@ RTCMediaStreamTrackStats::RTCMediaStreamTrackStats(
|
||||
total_samples_received(other.total_samples_received),
|
||||
total_samples_duration(other.total_samples_duration),
|
||||
concealed_samples(other.concealed_samples),
|
||||
silent_concealed_samples(other.silent_concealed_samples),
|
||||
concealment_events(other.concealment_events),
|
||||
inserted_samples_for_deceleration(
|
||||
other.inserted_samples_for_deceleration),
|
||||
removed_samples_for_acceleration(other.removed_samples_for_acceleration),
|
||||
jitter_buffer_flushes(other.jitter_buffer_flushes),
|
||||
delayed_packet_outage_samples(other.delayed_packet_outage_samples),
|
||||
relative_packet_arrival_delay(other.relative_packet_arrival_delay),
|
||||
@ -610,6 +617,8 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string&& id,
|
||||
int64_t timestamp_us)
|
||||
: RTCRTPStreamStats(std::move(id), timestamp_us),
|
||||
packets_received("packetsReceived"),
|
||||
fec_packets_received("fecPacketsReceived"),
|
||||
fec_packets_discarded("fecPacketsDiscarded"),
|
||||
bytes_received("bytesReceived"),
|
||||
packets_lost("packetsLost"),
|
||||
last_packet_received_timestamp("lastPacketReceivedTimestamp"),
|
||||
@ -633,6 +642,8 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
|
||||
const RTCInboundRTPStreamStats& other)
|
||||
: RTCRTPStreamStats(other),
|
||||
packets_received(other.packets_received),
|
||||
fec_packets_received(other.fec_packets_received),
|
||||
fec_packets_discarded(other.fec_packets_discarded),
|
||||
bytes_received(other.bytes_received),
|
||||
packets_lost(other.packets_lost),
|
||||
last_packet_received_timestamp(other.last_packet_received_timestamp),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user