Added RTCMediaStreamTrackStats.concealmentEvents

The number of concealment events. This counter increases every time a concealed sample is
synthesized after a non-concealed sample. That is, multiple consecutive concealed samples
will increase the concealedSamples count multiple times but is a single concealment event.

Bug: webrtc:8246
Change-Id: I7ef404edab765218b1f11e3128072c5391e83049
Reviewed-on: https://webrtc-review.googlesource.com/1221
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#19881}
This commit is contained in:
Gustaf Ullberg
2017-09-18 09:28:20 +02:00
committed by Commit Bot
parent 35dee81321
commit 9a2e906b0c
20 changed files with 90 additions and 36 deletions

View File

@ -61,13 +61,11 @@ struct NetEqNetworkStatistics {
// 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
// Stats below correspond to similarly-named fields in the WebRTC stats spec.
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
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;
uint64_t concealment_events = 0;
};
enum NetEqPlayoutMode {

View File

@ -847,7 +847,7 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, bool* muted) {
: timestamp_scaler_->ToExternal(playout_timestamp_) -
static_cast<uint32_t>(audio_frame->samples_per_channel_);
audio_frame->num_channels_ = sync_buffer_->Channels();
stats_.ExpandedNoiseSamples(output_size_samples_);
stats_.ExpandedNoiseSamples(output_size_samples_, false);
*muted = true;
return 0;
}
@ -1573,14 +1573,15 @@ int NetEqImpl::DoExpand(bool play_dtmf) {
algorithm_buffer_->Clear();
int return_value = expand_->Process(algorithm_buffer_.get());
size_t length = algorithm_buffer_->Size();
bool is_new_concealment_event = (last_mode_ != kModeExpand);
// Update in-call and post-call statistics.
if (expand_->MuteFactor(0) == 0) {
// Expand operation generates only noise.
stats_.ExpandedNoiseSamples(length);
stats_.ExpandedNoiseSamples(length, is_new_concealment_event);
} else {
// Expand operation generates more than only noise.
stats_.ExpandedVoiceSamples(length);
stats_.ExpandedVoiceSamples(length, is_new_concealment_event);
}
last_mode_ = kModeExpand;

View File

@ -1634,4 +1634,38 @@ TEST_F(NetEqDecodingTest, LastDecodedTimestampsTwoDecoded) {
neteq_->LastDecodedTimestamps());
}
TEST_F(NetEqDecodingTest, TestConcealmentEvents) {
const int kNumConcealmentEvents = 19;
const size_t kSamples = 10 * 16;
const size_t kPayloadBytes = kSamples * 2;
int seq_no = 0;
RTPHeader rtp_info;
rtp_info.ssrc = 0x1234; // Just an arbitrary SSRC.
rtp_info.payloadType = 94; // PCM16b WB codec.
rtp_info.markerBit = 0;
const uint8_t payload[kPayloadBytes] = {0};
bool muted;
for (int i = 0; i < kNumConcealmentEvents; i++) {
// Insert some packets of 10 ms size.
for (int j = 0; j < 10; j++) {
rtp_info.sequenceNumber = seq_no++;
rtp_info.timestamp = rtp_info.sequenceNumber * kSamples;
neteq_->InsertPacket(rtp_info, payload, 0);
neteq_->GetAudio(&out_frame_, &muted);
}
// Lose a number of packets.
int num_lost = 1 + i;
for (int j = 0; j < num_lost; j++) {
seq_no++;
neteq_->GetAudio(&out_frame_, &muted);
}
}
// Check number of concealment events.
NetEqLifetimeStatistics stats = neteq_->GetLifetimeStatistics();
EXPECT_EQ(kNumConcealmentEvents, static_cast<int>(stats.concealment_events));
}
} // namespace webrtc

View File

@ -151,14 +151,18 @@ void StatisticsCalculator::ResetMcu() {
timestamps_since_last_report_ = 0;
}
void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples) {
void StatisticsCalculator::ExpandedVoiceSamples(size_t num_samples,
bool is_new_concealment_event) {
expanded_speech_samples_ += num_samples;
lifetime_stats_.concealed_samples += num_samples;
lifetime_stats_.concealment_events += is_new_concealment_event;
}
void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples) {
void StatisticsCalculator::ExpandedNoiseSamples(size_t num_samples,
bool is_new_concealment_event) {
expanded_noise_samples_ += num_samples;
lifetime_stats_.concealed_samples += num_samples;
lifetime_stats_.concealment_events += is_new_concealment_event;
}
void StatisticsCalculator::ExpandedVoiceSamplesCorrection(int num_samples) {

View File

@ -39,11 +39,11 @@ class StatisticsCalculator {
// Reports that |num_samples| samples were produced through expansion, and
// that the expansion produced other than just noise samples.
void ExpandedVoiceSamples(size_t num_samples);
void ExpandedVoiceSamples(size_t num_samples, bool is_new_concealment_event);
// Reports that |num_samples| samples were produced through expansion, and
// that the expansion produced only noise samples.
void ExpandedNoiseSamples(size_t num_samples);
void ExpandedNoiseSamples(size_t num_samples, bool is_new_concealment_event);
// Corrects the statistics for number of samples produced through non-noise
// expansion by adding |num_samples| (negative or positive) to the current