Stop CNG after a timeout.

After having generated one second of comfort noise and not received any packets, switch to expand mode which will fade out to silence and enter the efficient muted mode.

The behavior is enabled by default but can be disabled through a field trial.

Bug: webrtc:12790
Change-Id: I1e2c1acced3e4a2c1c1595824f1303a0c339aeb5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/290578
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39043}
This commit is contained in:
Jakob Ivarsson 2023-01-09 15:36:51 +01:00 committed by WebRTC LUCI CQ
parent 11dfb42fe9
commit 1d6a5087d2
3 changed files with 21 additions and 1 deletions

View File

@ -71,6 +71,7 @@ DecisionLogic::Config::Config() {
"enable_stable_playout_delay", &enable_stable_playout_delay, // "enable_stable_playout_delay", &enable_stable_playout_delay, //
"reinit_after_expands", &reinit_after_expands, // "reinit_after_expands", &reinit_after_expands, //
"packet_history_size_ms", &packet_history_size_ms, // "packet_history_size_ms", &packet_history_size_ms, //
"cng_timeout_ms", &cng_timeout_ms, //
"deceleration_target_level_offset_ms", "deceleration_target_level_offset_ms",
&deceleration_target_level_offset_ms) &deceleration_target_level_offset_ms)
->Parse(webrtc::field_trial::FindFullName( ->Parse(webrtc::field_trial::FindFullName(
@ -80,6 +81,7 @@ DecisionLogic::Config::Config() {
<< enable_stable_playout_delay << enable_stable_playout_delay
<< " reinit_after_expands=" << reinit_after_expands << " reinit_after_expands=" << reinit_after_expands
<< " packet_history_size_ms=" << packet_history_size_ms << " packet_history_size_ms=" << packet_history_size_ms
<< " cng_timeout_ms=" << cng_timeout_ms.value_or(-1)
<< " deceleration_target_level_offset_ms=" << " deceleration_target_level_offset_ms="
<< deceleration_target_level_offset_ms; << deceleration_target_level_offset_ms;
} }
@ -320,7 +322,12 @@ NetEq::Operation DecisionLogic::NoPacket(NetEqController::NetEqStatus status) {
// Keep on playing comfort noise. // Keep on playing comfort noise.
return NetEq::Operation::kRfc3389CngNoPacket; return NetEq::Operation::kRfc3389CngNoPacket;
} else if (cng_state_ == kCngInternalOn) { } else if (cng_state_ == kCngInternalOn) {
// Keep on playing codec internal comfort noise. // Stop CNG after a timeout.
if (config_.cng_timeout_ms &&
status.generated_noise_samples >
static_cast<size_t>(*config_.cng_timeout_ms * sample_rate_khz_)) {
return NetEq::Operation::kExpand;
}
return NetEq::Operation::kCodecInternalCng; return NetEq::Operation::kCodecInternalCng;
} else if (status.play_dtmf) { } else if (status.play_dtmf) {
return NetEq::Operation::kDtmf; return NetEq::Operation::kDtmf;

View File

@ -175,6 +175,7 @@ class DecisionLogic : public NetEqController {
int reinit_after_expands = 100; int reinit_after_expands = 100;
int deceleration_target_level_offset_ms = 85; int deceleration_target_level_offset_ms = 85;
int packet_history_size_ms = 2000; int packet_history_size_ms = 2000;
absl::optional<int> cng_timeout_ms = 1000;
}; };
Config config_; Config config_;
std::unique_ptr<DelayManager> delay_manager_; std::unique_ptr<DelayManager> delay_manager_;

View File

@ -201,4 +201,16 @@ TEST_F(DecisionLogicTest, TimeStrechComfortNoise) {
} }
} }
TEST_F(DecisionLogicTest, CngTimeout) {
auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 0);
status.next_packet = absl::nullopt;
status.generated_noise_samples = kSamplesPerMs * 500;
bool reset_decoder = false;
EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
NetEq::Operation::kCodecInternalCng);
status.generated_noise_samples = kSamplesPerMs * 1010;
EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
NetEq::Operation::kExpand);
}
} // namespace webrtc } // namespace webrtc