Implement RTCInboundRTPStreamStats.JitterBufferMinimumDelay
This metric was recently added to the standard (see https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbufferminimumdelay). This CL implements it for audio streams.
Bug: webrtc:14141
Change-Id: I79d918639cd12361ebbc28c2be41549e33fa7e2a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262770
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Jakob Ivarsson <jakobi@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37567}
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index f70b37c..b078af1 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -287,6 +287,8 @@
acm_stat->jitterBufferDelayMs = neteq_lifetime_stat.jitter_buffer_delay_ms;
acm_stat->jitterBufferTargetDelayMs =
neteq_lifetime_stat.jitter_buffer_target_delay_ms;
+ acm_stat->jitterBufferMinimumDelayMs =
+ neteq_lifetime_stat.jitter_buffer_minimum_delay_ms;
acm_stat->jitterBufferEmittedCount =
neteq_lifetime_stat.jitter_buffer_emitted_count;
acm_stat->delayedPacketOutageSamples =
diff --git a/modules/audio_coding/include/audio_coding_module_typedefs.h b/modules/audio_coding/include/audio_coding_module_typedefs.h
index d2fe9ac..9d2fcfe 100644
--- a/modules/audio_coding/include/audio_coding_module_typedefs.h
+++ b/modules/audio_coding/include/audio_coding_module_typedefs.h
@@ -88,6 +88,7 @@
uint64_t concealmentEvents;
uint64_t jitterBufferDelayMs;
uint64_t jitterBufferTargetDelayMs;
+ uint64_t jitterBufferMinimumDelayMs;
uint64_t jitterBufferEmittedCount;
uint64_t insertedSamplesForDeceleration;
uint64_t removedSamplesForAcceleration;
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index 3a656a7..558774d 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -227,6 +227,10 @@
return target_delay_ms;
}
+int DecisionLogic::UnlimitedTargetLevelMs() const {
+ return delay_manager_->UnlimitedTargetLevelMs();
+}
+
int DecisionLogic::GetFilteredBufferLevel() const {
if (config_.enable_stable_playout_delay) {
return last_playout_delay_ms_ * sample_rate_khz_;
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index 1e7c9fe..2e55322 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -72,6 +72,8 @@
int TargetLevelMs() const override;
+ int UnlimitedTargetLevelMs() const override;
+
absl::optional<int> PacketArrived(int fs_hz,
bool should_update_stats,
const PacketArrivedInfo& info) override;
diff --git a/modules/audio_coding/neteq/delay_manager.cc b/modules/audio_coding/neteq/delay_manager.cc
index ba8f706..bf3a0f1 100644
--- a/modules/audio_coding/neteq/delay_manager.cc
+++ b/modules/audio_coding/neteq/delay_manager.cc
@@ -101,6 +101,7 @@
target_level_ms_ = std::max(
target_level_ms_, reorder_optimizer_->GetOptimalDelayMs().value_or(0));
}
+ unlimited_target_level_ms_ = target_level_ms_;
target_level_ms_ = std::max(target_level_ms_, effective_minimum_delay_ms_);
if (maximum_delay_ms_ > 0) {
target_level_ms_ = std::min(target_level_ms_, maximum_delay_ms_);
@@ -134,6 +135,10 @@
return target_level_ms_;
}
+int DelayManager::UnlimitedTargetLevelMs() const {
+ return unlimited_target_level_ms_;
+}
+
bool DelayManager::IsValidMinimumDelay(int delay_ms) const {
return 0 <= delay_ms && delay_ms <= MinimumDelayUpperBound();
}
diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h
index 1c4fe42..a333681 100644
--- a/modules/audio_coding/neteq/delay_manager.h
+++ b/modules/audio_coding/neteq/delay_manager.h
@@ -61,9 +61,15 @@
// Resets all state.
virtual void Reset();
- // Gets the target buffer level in milliseconds.
+ // Gets the target buffer level in milliseconds. If a minimum or maximum delay
+ // has been set, the target delay reported here also respects the configured
+ // min/max delay.
virtual int TargetDelayMs() const;
+ // Reports the target delay that would be used if no minimum/maximum delay
+ // would be set.
+ virtual int UnlimitedTargetLevelMs() const;
+
// Notifies the DelayManager of how much audio data is carried in each packet.
virtual int SetPacketAudioLength(int length_ms);
@@ -107,7 +113,8 @@
int maximum_delay_ms_; // Externally set maximum allowed delay.
int packet_len_ms_ = 0;
- int target_level_ms_; // Currently preferred buffer level.
+ int target_level_ms_ = 0; // Currently preferred buffer level.
+ int unlimited_target_level_ms_ = 0;
};
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 1637ae7..6a6367d 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -2012,7 +2012,8 @@
RTC_DCHECK(controller_);
stats_->JitterBufferDelay(packet_duration, waiting_time_ms,
- controller_->TargetLevelMs());
+ controller_->TargetLevelMs(),
+ controller_->UnlimitedTargetLevelMs());
packet_list->push_back(std::move(*packet)); // Store packet in list.
packet = absl::nullopt; // Ensure it's never used after the move.
diff --git a/modules/audio_coding/neteq/statistics_calculator.cc b/modules/audio_coding/neteq/statistics_calculator.cc
index cd5d971..9c91c85 100644
--- a/modules/audio_coding/neteq/statistics_calculator.cc
+++ b/modules/audio_coding/neteq/statistics_calculator.cc
@@ -261,12 +261,16 @@
lifetime_stats_.total_samples_received += num_samples;
}
-void StatisticsCalculator::JitterBufferDelay(size_t num_samples,
- uint64_t waiting_time_ms,
- uint64_t target_delay_ms) {
+void StatisticsCalculator::JitterBufferDelay(
+ size_t num_samples,
+ uint64_t waiting_time_ms,
+ uint64_t target_delay_ms,
+ uint64_t unlimited_target_delay_ms) {
lifetime_stats_.jitter_buffer_delay_ms += waiting_time_ms * num_samples;
lifetime_stats_.jitter_buffer_target_delay_ms +=
target_delay_ms * num_samples;
+ lifetime_stats_.jitter_buffer_minimum_delay_ms +=
+ unlimited_target_delay_ms * num_samples;
lifetime_stats_.jitter_buffer_emitted_count += num_samples;
}
diff --git a/modules/audio_coding/neteq/statistics_calculator.h b/modules/audio_coding/neteq/statistics_calculator.h
index e9b3d03..5091f31 100644
--- a/modules/audio_coding/neteq/statistics_calculator.h
+++ b/modules/audio_coding/neteq/statistics_calculator.h
@@ -84,7 +84,8 @@
// Update jitter buffer delay counter.
void JitterBufferDelay(size_t num_samples,
uint64_t waiting_time_ms,
- uint64_t target_delay_ms);
+ uint64_t target_delay_ms,
+ uint64_t unlimited_target_delay_ms);
// Stores new packet waiting time in waiting time statistics.
void StoreWaitingTime(int waiting_time_ms);