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}
This commit is contained in:
Minyue Li
2018-10-03 21:19:08 +02:00
committed by Commit Bot
parent b222f495a9
commit 7f6417f480
3 changed files with 100 additions and 9 deletions

View File

@ -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 @@ DecisionLogic::DecisionLogic(int fs_hz,
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 @@ Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer,
// 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;
}

View File

@ -109,6 +109,10 @@ class DecisionLogic final {
}
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 @@ class DecisionLogic final {
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);
};

View File

@ -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 @@ TEST(DecisionLogic, CreateAndDestroy) {
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