Added allow_codec_switching parameter to RTCConfig.
Bug: webrtc:10795
Change-Id: I5507f1d801e262223bd18198c685b5fffa644b0b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/157891
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29612}
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index 2b7da83..cc2fa46 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -673,6 +673,9 @@
// Added to be able to control rollout of this feature.
bool enable_implicit_rollback = false;
+ // Whether network condition based codec switching is allowed.
+ absl::optional<bool> allow_codec_switching;
+
//
// Don't forget to update operator== if adding something.
//
diff --git a/media/base/media_channel.cc b/media/base/media_channel.cc
index 1bd20dc..579cbc6 100644
--- a/media/base/media_channel.cc
+++ b/media/base/media_channel.cc
@@ -47,6 +47,8 @@
// Placeholder should be pure virtual once internal supports it.
}
+void MediaChannel::SetVideoCodecSwitchingEnabled(bool enabled) {}
+
MediaSenderInfo::MediaSenderInfo() = default;
MediaSenderInfo::~MediaSenderInfo() = default;
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index 582d29c..c49f2ec 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -243,6 +243,9 @@
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor);
+ // Enable network condition based codec switching.
+ virtual void SetVideoCodecSwitchingEnabled(bool enabled);
+
// Base method to send packet using NetworkInterface.
bool SendPacket(rtc::CopyOnWriteBuffer* packet,
const rtc::PacketOptions& options) {
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 9ea80cc..cab4e12 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -739,6 +739,12 @@
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, conf] {
RTC_DCHECK_RUN_ON(&thread_checker_);
+ if (!allow_codec_switching_) {
+ RTC_LOG(LS_INFO) << "Encoder switch requested but codec switching has"
+ << " not been enabled.";
+ return;
+ }
+
for (VideoCodecSettings codec_setting : negotiated_codecs_) {
if (codec_setting.codec.name == conf.codec_name) {
if (conf.param) {
@@ -1678,6 +1684,13 @@
}
}
+void WebRtcVideoChannel::SetVideoCodecSwitchingEnabled(bool enabled) {
+ invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, enabled] {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ allow_codec_switching_ = enabled;
+ });
+}
+
bool WebRtcVideoChannel::SetBaseMinimumPlayoutDelayMs(uint32_t ssrc,
int delay_ms) {
RTC_DCHECK_RUN_ON(&thread_checker_);
diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h
index 5e5ab6e..2493edb 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -172,6 +172,8 @@
rtc::scoped_refptr<webrtc::FrameEncryptorInterface>
frame_encryptor) override;
+ void SetVideoCodecSwitchingEnabled(bool enabled) override;
+
bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override;
absl::optional<int> GetBaseMinimumPlayoutDelayMs(
@@ -569,6 +571,8 @@
std::unique_ptr<UnhandledPacketsBuffer> unknown_ssrc_packet_buffer_
RTC_GUARDED_BY(thread_checker_);
+ bool allow_codec_switching_ = false;
+
// In order for the |invoker_| to protect other members from being destructed
// as they are used in asynchronous tasks it has to be destructed first.
rtc::AsyncInvoker invoker_;
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 62bbf24..b60ab95 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -2151,6 +2151,7 @@
parameters.codecs.push_back(vp8);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
+ channel_->SetVideoCodecSwitchingEnabled(true);
VideoCodec codec;
ASSERT_TRUE(channel_->GetSendCodec(&codec));
@@ -2188,6 +2189,7 @@
parameters.codecs.push_back(vp8);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
+ channel_->SetVideoCodecSwitchingEnabled(true);
VideoCodec codec;
ASSERT_TRUE(channel_->GetSendCodec(&codec));
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 494a649..08fbe41 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -784,6 +784,7 @@
bool offer_extmap_allow_mixed;
std::string turn_logging_id;
bool enable_implicit_rollback;
+ absl::optional<bool> allow_codec_switching;
};
static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
"Did you add something to RTCConfiguration and forget to "
@@ -851,7 +852,8 @@
crypto_options == o.crypto_options &&
offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
turn_logging_id == o.turn_logging_id &&
- enable_implicit_rollback == o.enable_implicit_rollback;
+ enable_implicit_rollback == o.enable_implicit_rollback &&
+ allow_codec_switching == o.allow_codec_switching;
}
bool PeerConnectionInterface::RTCConfiguration::operator!=(
@@ -3704,6 +3706,7 @@
modified_config.use_datagram_transport_for_data_channels_receive_only =
configuration.use_datagram_transport_for_data_channels_receive_only;
modified_config.turn_logging_id = configuration.turn_logging_id;
+ modified_config.allow_codec_switching = configuration.allow_codec_switching;
if (configuration != modified_config) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
"Modifying the configuration in an unsupported way.");
@@ -3791,6 +3794,11 @@
modified_config.active_reset_srtp_params);
}
+ if (modified_config.allow_codec_switching.has_value()) {
+ video_media_channel()->SetVideoCodecSwitchingEnabled(
+ *modified_config.allow_codec_switching);
+ }
+
configuration_ = modified_config;
use_media_transport_ = configuration.use_media_transport;
return RTCError::OK();
diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java
index b981520..e675d13 100644
--- a/sdk/android/api/org/webrtc/PeerConnection.java
+++ b/sdk/android/api/org/webrtc/PeerConnection.java
@@ -548,6 +548,11 @@
// every offer/answer negotiation.This is only intended to be a workaround for crbug.com/835958
public boolean activeResetSrtpParams;
+ // Whether this client is allowed to switch encoding codec mid-stream. This is a workaround for
+ // a WebRTC bug where the receiver could get confussed if a codec switch happened mid-call.
+ // Null indicates no change to currently configured value.
+ @Nullable public Boolean allowCodecSwitching;
+
/*
* Experimental flag that enables a use of media transport. If this is true, the media transport
* factory MUST be provided to the PeerConnectionFactory.
@@ -619,6 +624,7 @@
useMediaTransportForDataChannels = false;
cryptoOptions = null;
turnLoggingId = null;
+ allowCodecSwitching = null;
}
@CalledByNative("RTCConfiguration")
@@ -828,6 +834,12 @@
return activeResetSrtpParams;
}
+ @Nullable
+ @CalledByNative("RTCConfiguration")
+ Boolean getAllowCodecSwitching() {
+ return allowCodecSwitching;
+ }
+
@CalledByNative("RTCConfiguration")
boolean getUseMediaTransport() {
return useMediaTransport;
diff --git a/sdk/android/src/jni/pc/peer_connection.cc b/sdk/android/src/jni/pc/peer_connection.cc
index f40a7bf..9b1cce6 100644
--- a/sdk/android/src/jni/pc/peer_connection.cc
+++ b/sdk/android/src/jni/pc/peer_connection.cc
@@ -279,6 +279,9 @@
rtc_config->crypto_options =
JavaToNativeOptionalCryptoOptions(jni, j_crypto_options);
+ rtc_config->allow_codec_switching = JavaToNativeOptionalBool(
+ jni, Java_RTCConfiguration_getAllowCodecSwitching(jni, j_rtc_config));
+
ScopedJavaLocalRef<jstring> j_turn_logging_id =
Java_RTCConfiguration_getTurnLoggingId(jni, j_rtc_config);
if (!IsNull(jni, j_turn_logging_id)) {