Restricting NetEq postpone decoding after expand.
Bug: webrtc:9289
Change-Id: I923f304e6c12423fe5323c62484a27346033b19a
Reviewed-on: https://webrtc-review.googlesource.com/c/98320
Commit-Queue: Minyue Li <minyue@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24966}
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index 6b61555..349fdab 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -21,8 +21,38 @@
#include "modules/audio_coding/neteq/packet_buffer.h"
#include "modules/audio_coding/neteq/sync_buffer.h"
#include "modules/include/module_common_types.h"
+#include "rtc_base/logging.h"
#include "system_wrappers/include/field_trial.h"
+namespace {
+constexpr char kPostponeDecodingFieldTrial[] =
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand";
+
+int GetPostponeDecodingLevel() {
+ const bool enabled =
+ webrtc::field_trial::IsEnabled(kPostponeDecodingFieldTrial);
+ if (!enabled)
+ return 0;
+
+ constexpr int kDefaultPostponeDecodingLevel = 50;
+ const std::string field_trial_string =
+ webrtc::field_trial::FindFullName(kPostponeDecodingFieldTrial);
+ int value = -1;
+ if (sscanf(field_trial_string.c_str(), "Enabled-%d", &value) == 1) {
+ if (value >= 0 && value <= 100) {
+ return value;
+ } else {
+ RTC_LOG(LS_WARNING)
+ << "Wrong value (" << value
+ << ") for postpone decoding after expand, using default ("
+ << kDefaultPostponeDecodingLevel << ")";
+ }
+ }
+ return kDefaultPostponeDecodingLevel;
+}
+
+} // namespace
+
namespace webrtc {
DecisionLogic* DecisionLogic::Create(int fs_hz,
@@ -59,8 +89,7 @@
timescale_countdown_(
tick_timer_->GetNewCountdown(kMinTimescaleInterval + 1)),
num_consecutive_expands_(0),
- postpone_decoding_after_expand_(field_trial::IsEnabled(
- "WebRTC-Audio-NetEqPostponeDecodingAfterExpand")) {
+ postpone_decoding_level_(GetPostponeDecodingLevel()) {
delay_manager_->set_streaming_mode(false);
SetSampleRate(fs_hz, output_size_samples);
}
@@ -164,12 +193,13 @@
// if the mute factor is low enough (otherwise the expansion was short enough
// to not be noticable).
// Note that the MuteFactor is in Q14, so a value of 16384 corresponds to 1.
- if (postpone_decoding_after_expand_ &&
- (prev_mode == kModeExpand || prev_mode == kModeCodecPlc) &&
- !packet_buffer_.ContainsDtxOrCngPacket(decoder_database_) &&
- cur_size_samples<static_cast<size_t>(delay_manager_->TargetLevel() *
- packet_length_samples_)>> 8 &&
- expand.MuteFactor(0) < 16384 / 2) {
+ if ((prev_mode == kModeExpand || prev_mode == kModeCodecPlc) &&
+ expand.MuteFactor(0) < 16384 / 2 &&
+ cur_size_samples < static_cast<size_t>(
+ delay_manager_->TargetLevel() * packet_length_samples_ *
+ postpone_decoding_level_ / 100) >> 8 &&
+ !packet_buffer_.ContainsDtxOrCngPacket(decoder_database_)) {
+ RTC_DCHECK(webrtc::field_trial::IsEnabled(kPostponeDecodingFieldTrial));
return kExpand;
}
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index 00b8620..39761da 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -109,6 +109,10 @@
}
void set_prev_time_scale(bool value) { prev_time_scale_ = value; }
+ int postpone_decoding_level_for_test() const {
+ return postpone_decoding_level_;
+ }
+
private:
// The value 5 sets maximum time-stretch rate to about 100 ms/s.
static const int kMinTimescaleInterval = 5;
@@ -181,7 +185,7 @@
bool disallow_time_stretching_;
std::unique_ptr<TickTimer::Countdown> timescale_countdown_;
int num_consecutive_expands_;
- const bool postpone_decoding_after_expand_;
+ const int postpone_decoding_level_;
RTC_DISALLOW_COPY_AND_ASSIGN(DecisionLogic);
};
diff --git a/modules/audio_coding/neteq/decision_logic_unittest.cc b/modules/audio_coding/neteq/decision_logic_unittest.cc
index 6929daa..08720d1 100644
--- a/modules/audio_coding/neteq/decision_logic_unittest.cc
+++ b/modules/audio_coding/neteq/decision_logic_unittest.cc
@@ -17,6 +17,7 @@
#include "modules/audio_coding/neteq/delay_peak_detector.h"
#include "modules/audio_coding/neteq/packet_buffer.h"
#include "modules/audio_coding/neteq/tick_timer.h"
+#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
@@ -38,6 +39,62 @@
delete logic;
}
+TEST(DecisionLogic, PostponeDecodingAfterExpansionSettings) {
+ constexpr int kDefaultPostponeDecodingLevel = 50;
+ constexpr int kFsHz = 8000;
+ constexpr int kOutputSizeSamples = kFsHz / 100; // Samples per 10 ms.
+ DecoderDatabase decoder_database(
+ new rtc::RefCountedObject<MockAudioDecoderFactory>, absl::nullopt);
+ TickTimer tick_timer;
+ PacketBuffer packet_buffer(10, &tick_timer);
+ DelayPeakDetector delay_peak_detector(&tick_timer);
+ DelayManager delay_manager(240, &delay_peak_detector, &tick_timer);
+ BufferLevelFilter buffer_level_filter;
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand/Enabled/");
+ DecisionLogic logic(kFsHz, kOutputSizeSamples, false, &decoder_database,
+ packet_buffer, &delay_manager, &buffer_level_filter,
+ &tick_timer);
+ EXPECT_EQ(kDefaultPostponeDecodingLevel,
+ logic.postpone_decoding_level_for_test());
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand/Enabled-65/");
+ DecisionLogic logic(kFsHz, kOutputSizeSamples, false, &decoder_database,
+ packet_buffer, &delay_manager, &buffer_level_filter,
+ &tick_timer);
+ EXPECT_EQ(65, logic.postpone_decoding_level_for_test());
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand/Disabled/");
+ DecisionLogic logic(kFsHz, kOutputSizeSamples, false, &decoder_database,
+ packet_buffer, &delay_manager, &buffer_level_filter,
+ &tick_timer);
+ EXPECT_EQ(0, logic.postpone_decoding_level_for_test());
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand/Enabled--1/");
+ DecisionLogic logic(kFsHz, kOutputSizeSamples, false, &decoder_database,
+ packet_buffer, &delay_manager, &buffer_level_filter,
+ &tick_timer);
+ EXPECT_EQ(kDefaultPostponeDecodingLevel,
+ logic.postpone_decoding_level_for_test());
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqPostponeDecodingAfterExpand/Enabled-101/");
+ DecisionLogic logic(kFsHz, kOutputSizeSamples, false, &decoder_database,
+ packet_buffer, &delay_manager, &buffer_level_filter,
+ &tick_timer);
+ EXPECT_EQ(kDefaultPostponeDecodingLevel,
+ logic.postpone_decoding_level_for_test());
+ }
+}
+
// TODO(hlundin): Write more tests.
} // namespace webrtc