Add PeerConnection option to enable RTX handling in the audio jitter buffer.
Bug: webrtc:10178
Change-Id: I70abce0c7b74124d2b1978d9a5eb8216b6233d1a
Reviewed-on: https://webrtc-review.googlesource.com/c/116784
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26203}
diff --git a/api/audio_options.cc b/api/audio_options.cc
index 6fd90b2..16c0430 100644
--- a/api/audio_options.cc
+++ b/api/audio_options.cc
@@ -52,6 +52,8 @@
change.audio_jitter_buffer_fast_accelerate);
SetFrom(&audio_jitter_buffer_min_delay_ms,
change.audio_jitter_buffer_min_delay_ms);
+ SetFrom(&audio_jitter_buffer_enable_rtx_handling,
+ change.audio_jitter_buffer_enable_rtx_handling);
SetFrom(&typing_detection, change.typing_detection);
SetFrom(&experimental_agc, change.experimental_agc);
SetFrom(&extended_filter_aec, change.extended_filter_aec);
@@ -81,6 +83,8 @@
o.audio_jitter_buffer_fast_accelerate &&
audio_jitter_buffer_min_delay_ms ==
o.audio_jitter_buffer_min_delay_ms &&
+ audio_jitter_buffer_enable_rtx_handling ==
+ o.audio_jitter_buffer_enable_rtx_handling &&
typing_detection == o.typing_detection &&
experimental_agc == o.experimental_agc &&
extended_filter_aec == o.extended_filter_aec &&
@@ -114,6 +118,8 @@
audio_jitter_buffer_fast_accelerate);
ToStringIfSet(&result, "audio_jitter_buffer_min_delay_ms",
audio_jitter_buffer_min_delay_ms);
+ ToStringIfSet(&result, "audio_jitter_buffer_enable_rtx_handling",
+ audio_jitter_buffer_enable_rtx_handling);
ToStringIfSet(&result, "typing", typing_detection);
ToStringIfSet(&result, "experimental_agc", experimental_agc);
ToStringIfSet(&result, "extended_filter_aec", extended_filter_aec);
diff --git a/api/audio_options.h b/api/audio_options.h
index c2d1f44..478bff6 100644
--- a/api/audio_options.h
+++ b/api/audio_options.h
@@ -56,6 +56,8 @@
absl::optional<bool> audio_jitter_buffer_fast_accelerate;
// Audio receiver jitter buffer (NetEq) minimum target delay in milliseconds.
absl::optional<int> audio_jitter_buffer_min_delay_ms;
+ // Audio receiver jitter buffer (NetEq) should handle retransmitted packets.
+ absl::optional<bool> audio_jitter_buffer_enable_rtx_handling;
// Audio processing to detect typing.
absl::optional<bool> typing_detection;
absl::optional<bool> experimental_agc;
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index c2fb6a3..91d71b4 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -454,6 +454,10 @@
// The minimum delay in milliseconds for the audio jitter buffer.
int audio_jitter_buffer_min_delay_ms = 0;
+ // Whether the audio jitter buffer adapts the delay to retransmitted
+ // packets.
+ bool audio_jitter_buffer_enable_rtx_handling = false;
+
// Timeout in milliseconds before an ICE candidate pair is considered to be
// "not receiving", after which a lower priority candidate pair may be
// selected.
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 143c6f7..2e874ba 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -79,8 +79,8 @@
config.media_transport, config.rtcp_send_transport, event_log,
config.rtp.remote_ssrc, config.jitter_buffer_max_packets,
config.jitter_buffer_fast_accelerate, config.jitter_buffer_min_delay_ms,
- config.decoder_factory, config.codec_pair_id, config.frame_decryptor,
- config.crypto_options);
+ config.jitter_buffer_enable_rtx_handling, config.decoder_factory,
+ config.codec_pair_id, config.frame_decryptor, config.crypto_options);
}
} // namespace
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index 7ae2e26..e5bcad3 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -104,6 +104,7 @@
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
int jitter_buffer_min_delay_ms,
+ bool jitter_buffer_enable_rtx_handling,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id,
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
@@ -453,6 +454,7 @@
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
int jitter_buffer_min_delay_ms,
+ bool jitter_buffer_enable_rtx_handling,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id,
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
@@ -487,6 +489,8 @@
acm_config.neteq_config.enable_fast_accelerate = jitter_buffer_fast_playout;
acm_config.neteq_config.min_delay_ms = jitter_buffer_min_delay_ms;
acm_config.neteq_config.enable_muted_state = true;
+ acm_config.neteq_config.enable_rtx_handling =
+ jitter_buffer_enable_rtx_handling;
audio_coding_.reset(AudioCodingModule::Create(acm_config));
_outputAudioLevel.Clear();
@@ -988,6 +992,7 @@
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
int jitter_buffer_min_delay_ms,
+ bool jitter_buffer_enable_rtx_handling,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id,
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
@@ -996,8 +1001,8 @@
module_process_thread, audio_device_module, media_transport,
rtcp_send_transport, rtc_event_log, remote_ssrc,
jitter_buffer_max_packets, jitter_buffer_fast_playout,
- jitter_buffer_min_delay_ms, decoder_factory, codec_pair_id,
- frame_decryptor, crypto_options);
+ jitter_buffer_min_delay_ms, jitter_buffer_enable_rtx_handling,
+ decoder_factory, codec_pair_id, frame_decryptor, crypto_options);
}
} // namespace voe
diff --git a/audio/channel_receive.h b/audio/channel_receive.h
index 6bbf990..2c45a8f 100644
--- a/audio/channel_receive.h
+++ b/audio/channel_receive.h
@@ -139,6 +139,7 @@
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
int jitter_buffer_min_delay_ms,
+ bool jitter_buffer_enable_rtx_handling,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id,
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor,
diff --git a/call/audio_receive_stream.h b/call/audio_receive_stream.h
index 36cc059..476ddab 100644
--- a/call/audio_receive_stream.h
+++ b/call/audio_receive_stream.h
@@ -115,6 +115,7 @@
size_t jitter_buffer_max_packets = 50;
bool jitter_buffer_fast_accelerate = false;
int jitter_buffer_min_delay_ms = 0;
+ bool jitter_buffer_enable_rtx_handling = false;
// Identifier for an A/V synchronization group. Empty string to disable.
// TODO(pbos): Synchronize streams in a sync group, not just one video
diff --git a/media/engine/webrtcvoiceengine.cc b/media/engine/webrtcvoiceengine.cc
index c7a4169..40abb66 100644
--- a/media/engine/webrtcvoiceengine.cc
+++ b/media/engine/webrtcvoiceengine.cc
@@ -280,6 +280,7 @@
options.audio_jitter_buffer_max_packets = 50;
options.audio_jitter_buffer_fast_accelerate = false;
options.audio_jitter_buffer_min_delay_ms = 0;
+ options.audio_jitter_buffer_enable_rtx_handling = false;
options.typing_detection = true;
options.experimental_agc = false;
options.extended_filter_aec = false;
@@ -489,6 +490,12 @@
audio_jitter_buffer_min_delay_ms_ =
*options.audio_jitter_buffer_min_delay_ms;
}
+ if (options.audio_jitter_buffer_enable_rtx_handling) {
+ RTC_LOG(LS_INFO) << "NetEq handle reordered packets? "
+ << *options.audio_jitter_buffer_enable_rtx_handling;
+ audio_jitter_buffer_enable_rtx_handling_ =
+ *options.audio_jitter_buffer_enable_rtx_handling;
+ }
if (options.typing_detection) {
RTC_LOG(LS_INFO) << "Typing detection is enabled? "
@@ -1096,6 +1103,7 @@
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_accelerate,
int jitter_buffer_min_delay_ms,
+ bool jitter_buffer_enable_rtx_handling,
rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor,
const webrtc::CryptoOptions& crypto_options)
: call_(call), config_() {
@@ -1110,6 +1118,8 @@
config_.jitter_buffer_max_packets = jitter_buffer_max_packets;
config_.jitter_buffer_fast_accelerate = jitter_buffer_fast_accelerate;
config_.jitter_buffer_min_delay_ms = jitter_buffer_min_delay_ms;
+ config_.jitter_buffer_enable_rtx_handling =
+ jitter_buffer_enable_rtx_handling;
if (!stream_ids.empty()) {
config_.sync_group = stream_ids[0];
}
@@ -1909,6 +1919,7 @@
codec_pair_id_, engine()->audio_jitter_buffer_max_packets_,
engine()->audio_jitter_buffer_fast_accelerate_,
engine()->audio_jitter_buffer_min_delay_ms_,
+ engine()->audio_jitter_buffer_enable_rtx_handling_,
unsignaled_frame_decryptor_, crypto_options_)));
recv_streams_[ssrc]->SetPlayout(playout_);
diff --git a/media/engine/webrtcvoiceengine.h b/media/engine/webrtcvoiceengine.h
index 213f1b3..494b4f6 100644
--- a/media/engine/webrtcvoiceengine.h
+++ b/media/engine/webrtcvoiceengine.h
@@ -133,6 +133,7 @@
size_t audio_jitter_buffer_max_packets_ = 50;
bool audio_jitter_buffer_fast_accelerate_ = false;
int audio_jitter_buffer_min_delay_ms_ = 0;
+ bool audio_jitter_buffer_enable_rtx_handling_ = false;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcVoiceEngine);
};
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index 7e6c3dd..518a2e6 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -706,6 +706,7 @@
int audio_jitter_buffer_max_packets;
bool audio_jitter_buffer_fast_accelerate;
int audio_jitter_buffer_min_delay_ms;
+ bool audio_jitter_buffer_enable_rtx_handling;
int ice_connection_receiving_timeout;
int ice_backup_candidate_pair_ping_interval;
ContinualGatheringPolicy continual_gathering_policy;
@@ -745,6 +746,8 @@
o.audio_jitter_buffer_fast_accelerate &&
audio_jitter_buffer_min_delay_ms ==
o.audio_jitter_buffer_min_delay_ms &&
+ audio_jitter_buffer_enable_rtx_handling ==
+ o.audio_jitter_buffer_enable_rtx_handling &&
ice_connection_receiving_timeout ==
o.ice_connection_receiving_timeout &&
ice_backup_candidate_pair_ping_interval ==
@@ -1071,6 +1074,9 @@
audio_options_.audio_jitter_buffer_min_delay_ms =
configuration.audio_jitter_buffer_min_delay_ms;
+ audio_options_.audio_jitter_buffer_enable_rtx_handling =
+ configuration.audio_jitter_buffer_enable_rtx_handling;
+
// Whether the certificate generator/certificate is null or not determines
// what PeerConnectionDescriptionFactory will do, so make sure that we give it
// the right instructions by clearing the variables if needed.