Propagate SDP negotiation of extmap-allow-mixed to RtpHeaderExtensionMap
Bug: webrtc:7990
Change-Id: I662595f90b9d0be39f7e14752e13b2bb7a1746ee
Reviewed-on: https://webrtc-review.googlesource.com/c/106020
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25421}
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index cc7ec5d..f778745 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -62,11 +62,12 @@
RtcpRttStats* rtcp_rtt_stats,
RtcEventLog* event_log,
FrameEncryptorInterface* frame_encryptor,
- const webrtc::CryptoOptions& crypto_options) {
+ const webrtc::CryptoOptions& crypto_options,
+ bool extmap_allow_mixed) {
return absl::make_unique<voe::ChannelSendProxy>(
absl::make_unique<voe::ChannelSend>(
worker_queue, module_process_thread, media_transport, rtcp_rtt_stats,
- event_log, frame_encryptor, crypto_options));
+ event_log, frame_encryptor, crypto_options, extmap_allow_mixed));
}
} // namespace
@@ -119,7 +120,8 @@
rtcp_rtt_stats,
event_log,
config.frame_encryptor,
- config.crypto_options)) {}
+ config.crypto_options,
+ config.rtp.extmap_allow_mixed)) {}
AudioSendStream::AudioSendStream(
const webrtc::AudioSendStream::Config& config,
@@ -258,6 +260,11 @@
channel_proxy->SetFrameEncryptor(new_config.frame_encryptor);
}
+ if (first_time ||
+ new_config.rtp.extmap_allow_mixed != old_config.rtp.extmap_allow_mixed) {
+ channel_proxy->SetExtmapAllowMixed(new_config.rtp.extmap_allow_mixed);
+ }
+
const ExtensionIds old_ids = FindExtensionIds(old_config.rtp.extensions);
const ExtensionIds new_ids = FindExtensionIds(new_config.rtp.extensions);
// Audio level indication
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index e17030f..6a92329 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -198,6 +198,7 @@
EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 10)).Times(1);
EXPECT_CALL(*channel_proxy_, SetFrameEncryptor(_)).Times(1);
+ EXPECT_CALL(*channel_proxy_, SetExtmapAllowMixed(false)).Times(1);
EXPECT_CALL(*channel_proxy_,
SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
.Times(1);
@@ -330,10 +331,11 @@
config.send_codec_spec->transport_cc_enabled = false;
config.send_codec_spec->cng_payload_type = 42;
config.encoder_factory = MockAudioEncoderFactory::CreateUnusedFactory();
+ config.rtp.extmap_allow_mixed = true;
config.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
EXPECT_EQ(
- "{rtp: {ssrc: 1234, extensions: [{uri: "
+ "{rtp: {ssrc: 1234, extmap-allow-mixed: true, extensions: [{uri: "
"urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 2}], nack: "
"{rtp_history_ms: 0}, c_name: foo_name}, send_transport: null, "
"media_transport: null, "
diff --git a/audio/channel_send.cc b/audio/channel_send.cc
index 4490b19..cc8b1f7 100644
--- a/audio/channel_send.cc
+++ b/audio/channel_send.cc
@@ -453,7 +453,8 @@
RtcpRttStats* rtcp_rtt_stats,
RtcEventLog* rtc_event_log,
FrameEncryptorInterface* frame_encryptor,
- const webrtc::CryptoOptions& crypto_options)
+ const webrtc::CryptoOptions& crypto_options,
+ bool extmap_allow_mixed)
: event_log_(rtc_event_log),
_timeStamp(0), // This is just an offset, RTP module will add it's own
// random offset
@@ -496,6 +497,7 @@
configuration.rtt_stats = rtcp_rtt_stats;
configuration.retransmission_rate_limiter =
retransmission_rate_limiter_.get();
+ configuration.extmap_allow_mixed = extmap_allow_mixed;
_rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
_rtpRtcpModule->SetSendingMediaStatus(false);
@@ -836,6 +838,10 @@
_rtpRtcpModule->SetMid(mid);
}
+void ChannelSend::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ _rtpRtcpModule->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
int ChannelSend::SetSendAudioLevelIndicationStatus(bool enable,
unsigned char id) {
_includeAudioLevelIndication = enable;
diff --git a/audio/channel_send.h b/audio/channel_send.h
index deca5b1..407303f 100644
--- a/audio/channel_send.h
+++ b/audio/channel_send.h
@@ -124,7 +124,8 @@
RtcpRttStats* rtcp_rtt_stats,
RtcEventLog* rtc_event_log,
FrameEncryptorInterface* frame_encryptor,
- const webrtc::CryptoOptions& crypto_options);
+ const webrtc::CryptoOptions& crypto_options,
+ bool extmap_allow_mixed);
virtual ~ChannelSend();
@@ -171,6 +172,7 @@
int SetLocalSSRC(unsigned int ssrc);
void SetMid(const std::string& mid, int extension_id);
+ void SetExtmapAllowMixed(bool extmap_allow_mixed);
int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id);
void EnableSendTransportSequenceNumber(int id);
diff --git a/audio/channel_send_proxy.cc b/audio/channel_send_proxy.cc
index 33bed43..2d0bdd3 100644
--- a/audio/channel_send_proxy.cc
+++ b/audio/channel_send_proxy.cc
@@ -88,6 +88,11 @@
RTC_DCHECK_EQ(0, error);
}
+void ChannelSendProxy::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ channel_->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
void ChannelSendProxy::SetSendAudioLevelIndicationStatus(bool enable, int id) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
int error = channel_->SetSendAudioLevelIndicationStatus(enable, id);
diff --git a/audio/channel_send_proxy.h b/audio/channel_send_proxy.h
index 9eae628..3146830 100644
--- a/audio/channel_send_proxy.h
+++ b/audio/channel_send_proxy.h
@@ -58,6 +58,7 @@
virtual void SetRTCPStatus(bool enable);
virtual void SetMid(const std::string& mid, int extension_id);
virtual void SetRTCP_CNAME(const std::string& c_name);
+ virtual void SetExtmapAllowMixed(bool extmap_allow_mixed);
virtual void SetSendAudioLevelIndicationStatus(bool enable, int id);
virtual void EnableSendTransportSequenceNumber(int id);
virtual void RegisterSenderCongestionControlObjects(
diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h
index adf85db..962152f 100644
--- a/audio/mock_voe_channel_proxy.h
+++ b/audio/mock_voe_channel_proxy.h
@@ -76,6 +76,7 @@
MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
MOCK_METHOD1(SetRTCP_CNAME, void(const std::string& c_name));
MOCK_METHOD2(SetNACKStatus, void(bool enable, int max_packets));
+ MOCK_METHOD1(SetExtmapAllowMixed, void(bool extmap_allow_mixed));
MOCK_METHOD2(SetSendAudioLevelIndicationStatus, void(bool enable, int id));
MOCK_METHOD1(EnableSendTransportSequenceNumber, void(int id));
MOCK_METHOD2(RegisterSenderCongestionControlObjects,
diff --git a/call/audio_send_stream.cc b/call/audio_send_stream.cc
index 398b722..3721268 100644
--- a/call/audio_send_stream.cc
+++ b/call/audio_send_stream.cc
@@ -52,6 +52,7 @@
char buf[1024];
rtc::SimpleStringBuilder ss(buf);
ss << "{ssrc: " << ssrc;
+ ss << ", extmap-allow-mixed: " << (extmap_allow_mixed ? "true" : "false");
ss << ", extensions: [";
for (size_t i = 0; i < extensions.size(); ++i) {
ss << extensions[i].ToString();
diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h
index 3595b6c..ba0d652 100644
--- a/call/audio_send_stream.h
+++ b/call/audio_send_stream.h
@@ -83,6 +83,9 @@
// included in the list of extensions.
std::string mid;
+ // Corresponds to the SDP attribute extmap-allow-mixed.
+ bool extmap_allow_mixed = false;
+
// RTP header extensions used for the sent stream.
std::vector<RtpExtension> extensions;
diff --git a/call/rtp_config.cc b/call/rtp_config.cc
index c4f9d41..30631f5 100644
--- a/call/rtp_config.cc
+++ b/call/rtp_config.cc
@@ -63,6 +63,7 @@
<< (rtcp_mode == RtcpMode::kCompound ? "RtcpMode::kCompound"
: "RtcpMode::kReducedSize");
ss << ", max_packet_size: " << max_packet_size;
+ ss << ", extmap-allow-mixed: " << (extmap_allow_mixed ? "true" : "false");
ss << ", extensions: [";
for (size_t i = 0; i < extensions.size(); ++i) {
ss << extensions[i].ToString();
diff --git a/call/rtp_config.h b/call/rtp_config.h
index 0acddc3..5d22182 100644
--- a/call/rtp_config.h
+++ b/call/rtp_config.h
@@ -76,6 +76,9 @@
// Max RTP packet size delivered to send transport from VideoEngine.
size_t max_packet_size = kDefaultMaxPacketSize;
+ // Corresponds to the SDP attribute extmap-allow-mixed.
+ bool extmap_allow_mixed = false;
+
// RTP header extensions to use for this send stream.
std::vector<RtpExtension> extensions;
diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc
index 7364cf9..214fe96 100644
--- a/call/rtp_video_sender.cc
+++ b/call/rtp_video_sender.cc
@@ -40,7 +40,7 @@
std::vector<std::unique_ptr<RtpRtcp>> CreateRtpRtcpModules(
const std::vector<uint32_t>& ssrcs,
- const std::vector<uint32_t>& protected_media_ssrcs,
+ const RtpConfig& rtp_config,
const RtcpConfig& rtcp_config,
Transport* send_transport,
RtcpIntraFrameObserver* intra_frame_callback,
@@ -89,9 +89,11 @@
configuration.frame_encryptor = frame_encryptor;
configuration.require_frame_encryption =
crypto_options.sframe.require_frame_encryption;
+ configuration.extmap_allow_mixed = rtp_config.extmap_allow_mixed;
std::vector<std::unique_ptr<RtpRtcp>> modules;
- const std::vector<uint32_t>& flexfec_protected_ssrcs = protected_media_ssrcs;
+ const std::vector<uint32_t>& flexfec_protected_ssrcs =
+ rtp_config.flexfec.protected_media_ssrcs;
for (uint32_t ssrc : ssrcs) {
bool enable_flexfec = flexfec_sender != nullptr &&
std::find(flexfec_protected_ssrcs.begin(),
@@ -200,27 +202,26 @@
suspended_ssrcs_(std::move(suspended_ssrcs)),
flexfec_sender_(MaybeCreateFlexfecSender(rtp_config, suspended_ssrcs_)),
fec_controller_(std::move(fec_controller)),
- rtp_modules_(
- CreateRtpRtcpModules(ssrcs,
- rtp_config.flexfec.protected_media_ssrcs,
- rtcp_config,
- send_transport,
- observers.intra_frame_callback,
- transport->GetBandwidthObserver(),
- transport,
- observers.rtcp_rtt_stats,
- flexfec_sender_.get(),
- observers.bitrate_observer,
- observers.frame_count_observer,
- observers.rtcp_type_observer,
- observers.send_delay_observer,
- observers.send_packet_observer,
- event_log,
- retransmission_limiter,
- this,
- transport->keepalive_config(),
- frame_encryptor,
- crypto_options)),
+ rtp_modules_(CreateRtpRtcpModules(ssrcs,
+ rtp_config,
+ rtcp_config,
+ send_transport,
+ observers.intra_frame_callback,
+ transport->GetBandwidthObserver(),
+ transport,
+ observers.rtcp_rtt_stats,
+ flexfec_sender_.get(),
+ observers.bitrate_observer,
+ observers.frame_count_observer,
+ observers.rtcp_type_observer,
+ observers.send_delay_observer,
+ observers.send_packet_observer,
+ event_log,
+ retransmission_limiter,
+ this,
+ transport->keepalive_config(),
+ frame_encryptor,
+ crypto_options)),
rtp_config_(rtp_config),
transport_(transport),
transport_overhead_bytes_per_packet_(0),
diff --git a/media/base/fakemediaengine.cc b/media/base/fakemediaengine.cc
index 047ad3f..b2557a9 100644
--- a/media/base/fakemediaengine.cc
+++ b/media/base/fakemediaengine.cc
@@ -79,6 +79,7 @@
const AudioSendParameters& params) {
set_send_rtcp_parameters(params.rtcp);
return (SetSendCodecs(params.codecs) &&
+ SetSendExtmapAllowMixed(params.extmap_allow_mixed) &&
SetSendRtpHeaderExtensions(params.extensions) &&
SetMaxSendBandwidth(params.max_bandwidth_bps) &&
SetOptions(params.options));
@@ -260,6 +261,7 @@
const VideoSendParameters& params) {
set_send_rtcp_parameters(params.rtcp);
return (SetSendCodecs(params.codecs) &&
+ SetSendExtmapAllowMixed(params.extmap_allow_mixed) &&
SetSendRtpHeaderExtensions(params.extensions) &&
SetMaxSendBandwidth(params.max_bandwidth_bps));
}
diff --git a/media/base/fakemediaengine.h b/media/base/fakemediaengine.h
index 08062ed..acd3faa 100644
--- a/media/base/fakemediaengine.h
+++ b/media/base/fakemediaengine.h
@@ -252,6 +252,12 @@
recv_extensions_ = extensions;
return true;
}
+ bool SetSendExtmapAllowMixed(bool extmap_allow_mixed) {
+ if (Base::ExtmapAllowMixed() != extmap_allow_mixed) {
+ Base::SetExtmapAllowMixed(extmap_allow_mixed);
+ }
+ return true;
+ }
bool SetSendRtpHeaderExtensions(const std::vector<RtpExtension>& extensions) {
send_extensions_ = extensions;
return true;
diff --git a/media/base/mediachannel.h b/media/base/mediachannel.h
index 56edab7..fefb993 100644
--- a/media/base/mediachannel.h
+++ b/media/base/mediachannel.h
@@ -262,6 +262,15 @@
return media_transport_;
}
+ // Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
+ // Set to true if it's allowed to mix one- and two-byte RTP header extensions
+ // in the same stream. The setter and getter must only be called from
+ // worker_thread.
+ void SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ extmap_allow_mixed_ = extmap_allow_mixed;
+ }
+ bool ExtmapAllowMixed() const { return extmap_allow_mixed_; }
+
protected:
virtual rtc::DiffServCodePoint PreferredDscp() const;
@@ -298,6 +307,7 @@
rtc::CriticalSection network_interface_crit_;
NetworkInterface* network_interface_ = nullptr;
webrtc::MediaTransportInterface* media_transport_ = nullptr;
+ bool extmap_allow_mixed_ = false;
};
// The stats information is structured as follows:
@@ -661,12 +671,14 @@
// This is the value to be sent in the MID RTP header extension (if the header
// extension in included in the list of extensions).
std::string mid;
+ bool extmap_allow_mixed = false;
protected:
std::map<std::string, std::string> ToStringMap() const override {
auto params = RtpParameters<Codec>::ToStringMap();
params["max_bandwidth_bps"] = rtc::ToString(max_bandwidth_bps);
params["mid"] = (mid.empty() ? "<not set>" : mid);
+ params["extmap-allow-mixed"] = extmap_allow_mixed ? "true" : "false";
return params;
}
};
diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc
index 7310e4c..d0f12c0 100644
--- a/media/engine/webrtcvideoengine.cc
+++ b/media/engine/webrtcvideoengine.cc
@@ -624,6 +624,9 @@
changed_params->codec = selected_send_codec;
// Handle RTP header extensions.
+ if (params.extmap_allow_mixed != ExtmapAllowMixed()) {
+ changed_params->extmap_allow_mixed = params.extmap_allow_mixed;
+ }
std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(
params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true);
if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) {
@@ -678,6 +681,9 @@
RTC_LOG(LS_INFO) << "Using codec: " << codec_settings.codec.ToString();
}
+ if (changed_params.extmap_allow_mixed) {
+ SetExtmapAllowMixed(*changed_params.extmap_allow_mixed);
+ }
if (changed_params.rtp_header_extensions) {
send_rtp_extensions_ = changed_params.rtp_header_extensions;
}
@@ -1064,6 +1070,7 @@
video_config_.experiment_cpu_load_estimator;
config.encoder_settings.encoder_factory = encoder_factory_;
config.crypto_options = crypto_options_;
+ config.rtp.extmap_allow_mixed = ExtmapAllowMixed();
WebRtcVideoSendStream* stream = new WebRtcVideoSendStream(
call_, sp, std::move(config), default_send_options_,
@@ -1630,7 +1637,6 @@
? webrtc::RtcpMode::kReducedSize
: webrtc::RtcpMode::kCompound;
parameters_.config.rtp.mid = send_params.mid;
-
rtp_parameters_.rtcp.reduced_size = send_params.rtcp.reduced_size;
if (codec_settings) {
@@ -1760,6 +1766,10 @@
parameters_.config.rtp.rtcp_mode == webrtc::RtcpMode::kReducedSize;
recreate_stream = true;
}
+ if (params.extmap_allow_mixed) {
+ parameters_.config.rtp.extmap_allow_mixed = *params.extmap_allow_mixed;
+ recreate_stream = true;
+ }
if (params.rtp_header_extensions) {
parameters_.config.rtp.extensions = *params.rtp_header_extensions;
rtp_parameters_.header_extensions = *params.rtp_header_extensions;
diff --git a/media/engine/webrtcvideoengine.h b/media/engine/webrtcvideoengine.h
index f327bad..083fc9f 100644
--- a/media/engine/webrtcvideoengine.h
+++ b/media/engine/webrtcvideoengine.h
@@ -219,6 +219,7 @@
absl::optional<VideoCodecSettings> codec;
absl::optional<std::vector<webrtc::RtpExtension>> rtp_header_extensions;
absl::optional<std::string> mid;
+ absl::optional<bool> extmap_allow_mixed;
absl::optional<int> max_bandwidth_bps;
absl::optional<bool> conference_mode;
absl::optional<webrtc::RtcpMode> rtcp_mode;
diff --git a/media/engine/webrtcvideoengine_unittest.cc b/media/engine/webrtcvideoengine_unittest.cc
index e269632..36a0e14 100644
--- a/media/engine/webrtcvideoengine_unittest.cc
+++ b/media/engine/webrtcvideoengine_unittest.cc
@@ -2090,6 +2090,29 @@
&BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
}
+ void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
+ // For a caller, the answer will be applied in set remote description
+ // where SetSendParameters() is called.
+ EXPECT_TRUE(
+ channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
+ send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
+ EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
+ const webrtc::VideoSendStream::Config& config =
+ fake_call_->GetVideoSendStreams()[0]->GetConfig();
+ EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
+ }
+
+ void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
+ // For a callee, the answer will be applied in set local description
+ // where SetExtmapAllowMixed() and AddSendStream() are called.
+ channel_->SetExtmapAllowMixed(extmap_allow_mixed);
+ EXPECT_TRUE(
+ channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
+ const webrtc::VideoSendStream::Config& config =
+ fake_call_->GetVideoSendStreams()[0]->GetConfig();
+ EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
+ }
+
void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
// Enable extension.
const int id = 1;
@@ -2346,6 +2369,20 @@
ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
}
+// Test propagation of extmap allow mixed setting.
+TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
+ TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
+}
+TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
+ TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
+}
+TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
+ TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
+}
+TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
+ TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
+}
+
TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
FakeVideoSendStream* send_stream =
AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
diff --git a/media/engine/webrtcvoiceengine.cc b/media/engine/webrtcvoiceengine.cc
index 889c7ec..4fc25cb 100644
--- a/media/engine/webrtcvoiceengine.cc
+++ b/media/engine/webrtcvoiceengine.cc
@@ -705,6 +705,7 @@
const std::string track_id,
const absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>&
send_codec_spec,
+ bool extmap_allow_mixed,
const std::vector<webrtc::RtpExtension>& extensions,
int max_send_bitrate_bps,
const absl::optional<std::string>& audio_network_adaptor_config,
@@ -726,6 +727,7 @@
config_.rtp.ssrc = ssrc;
config_.rtp.mid = mid;
config_.rtp.c_name = c_name;
+ config_.rtp.extmap_allow_mixed = extmap_allow_mixed;
config_.rtp.extensions = extensions;
config_.has_dscp = rtp_parameters_.encodings[0].network_priority !=
webrtc::kDefaultBitratePriority;
@@ -765,6 +767,11 @@
ReconfigureAudioSendStream();
}
+ void SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ config_.rtp.extmap_allow_mixed = extmap_allow_mixed;
+ ReconfigureAudioSendStream();
+ }
+
void SetMid(const std::string& mid) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
if (config_.rtp.mid == mid) {
@@ -1293,6 +1300,14 @@
if (!ValidateRtpExtensions(params.extensions)) {
return false;
}
+
+ if (ExtmapAllowMixed() != params.extmap_allow_mixed) {
+ SetExtmapAllowMixed(params.extmap_allow_mixed);
+ for (auto& it : send_streams_) {
+ it.second->SetExtmapAllowMixed(params.extmap_allow_mixed);
+ }
+ }
+
std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(
params.extensions, webrtc::RtpExtension::IsSupportedForAudio, true);
if (send_rtp_extensions_ != filtered_extensions) {
@@ -1794,10 +1809,10 @@
absl::optional<std::string> audio_network_adaptor_config =
GetAudioNetworkAdaptorConfig(options_);
WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
- ssrc, mid_, sp.cname, sp.id, send_codec_spec_, send_rtp_extensions_,
- max_send_bitrate_bps_, audio_network_adaptor_config, call_, this,
- media_transport(), engine()->encoder_factory_, codec_pair_id_, nullptr,
- crypto_options_);
+ ssrc, mid_, sp.cname, sp.id, send_codec_spec_, ExtmapAllowMixed(),
+ send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config,
+ call_, this, media_transport(), engine()->encoder_factory_,
+ codec_pair_id_, nullptr, crypto_options_);
send_streams_.insert(std::make_pair(ssrc, stream));
// At this point the stream's local SSRC has been updated. If it is the first
diff --git a/media/engine/webrtcvoiceengine_unittest.cc b/media/engine/webrtcvoiceengine_unittest.cc
index eefa6f0..00e552d 100644
--- a/media/engine/webrtcvoiceengine_unittest.cc
+++ b/media/engine/webrtcvoiceengine_unittest.cc
@@ -351,6 +351,30 @@
EXPECT_EQ(123, telephone_event.duration_ms);
}
+ void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
+ // For a caller, the answer will be applied in set remote description
+ // where SetSendParameters() is called.
+ EXPECT_TRUE(SetupChannel());
+ EXPECT_TRUE(
+ channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
+ send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
+ SetSendParameters(send_parameters_);
+ const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
+ EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
+ }
+
+ void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
+ // For a callee, the answer will be applied in set local description
+ // where SetExtmapAllowMixed() and AddSendStream() are called.
+ EXPECT_TRUE(SetupChannel());
+ channel_->SetExtmapAllowMixed(extmap_allow_mixed);
+ EXPECT_TRUE(
+ channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcX)));
+
+ const webrtc::AudioSendStream::Config& config = GetSendStreamConfig(kSsrcX);
+ EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
+ }
+
// Test that send bandwidth is set correctly.
// |codec| is the codec under test.
// |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
@@ -2823,6 +2847,20 @@
TestInsertDtmf(kSsrcX, false, kTelephoneEventCodec1);
}
+// Test propagation of extmap allow mixed setting.
+TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCaller) {
+ TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
+}
+TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCaller) {
+ TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
+}
+TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedAsCallee) {
+ TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
+}
+TEST_F(WebRtcVoiceEngineTestFake, SetExtmapAllowMixedDisabledAsCallee) {
+ TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
+}
+
TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
EXPECT_TRUE(SetupSendStream());
EXPECT_TRUE(AddRecvStream(kSsrcY));
diff --git a/modules/rtp_rtcp/include/rtp_header_extension_map.h b/modules/rtp_rtcp/include/rtp_header_extension_map.h
index b691cdd..391c5be 100644
--- a/modules/rtp_rtcp/include/rtp_header_extension_map.h
+++ b/modules/rtp_rtcp/include/rtp_header_extension_map.h
@@ -59,6 +59,9 @@
// Set to true if it's allowed to mix one- and two-byte RTP header extensions
// in the same stream.
bool ExtmapAllowMixed() const { return extmap_allow_mixed_; }
+ void SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ extmap_allow_mixed_ = extmap_allow_mixed;
+ }
private:
bool Register(int id, RTPExtensionType type, const char* uri);
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index 8fa0faa..265046c 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -103,6 +103,9 @@
// Require all outgoing frames to be encrypted with a FrameEncryptor.
bool require_frame_encryption = false;
+ // Corresponds to extmap-allow-mixed in SDP negotiation.
+ bool extmap_allow_mixed = false;
+
private:
RTC_DISALLOW_COPY_AND_ASSIGN(Configuration);
};
@@ -142,6 +145,8 @@
// Returns -1 on failure else 0.
virtual int32_t DeRegisterSendPayload(int8_t payload_type) = 0;
+ virtual void SetExtmapAllowMixed(bool extmap_allow_mixed) = 0;
+
// (De)registers RTP header extension type and id.
// Returns -1 on failure else 0.
virtual int32_t RegisterSendRtpHeaderExtension(RTPExtensionType type,
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index e95bdd3..9f00654 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -52,6 +52,7 @@
MOCK_METHOD2(RegisterVideoSendPayload,
void(int payload_type, const char* payload_name));
MOCK_METHOD1(DeRegisterSendPayload, int32_t(int8_t payload_type));
+ MOCK_METHOD1(SetExtmapAllowMixed, void(bool extmap_allow_mixed));
MOCK_METHOD2(RegisterSendRtpHeaderExtension,
int32_t(RTPExtensionType type, uint8_t id));
MOCK_METHOD2(RegisterRtpHeaderExtension,
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 6e40d02..5726284 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -102,7 +102,8 @@
configuration.retransmission_rate_limiter,
configuration.overhead_observer,
configuration.populate_network2_timestamp,
- configuration.frame_encryptor, configuration.require_frame_encryption));
+ configuration.frame_encryptor, configuration.require_frame_encryption,
+ configuration.extmap_allow_mixed));
// Make sure rtcp sender use same timestamp offset as rtp sender.
rtcp_sender_.SetTimestampOffset(rtp_sender_->TimestampOffset());
@@ -615,6 +616,10 @@
rtcp_sender_.UnsetRemb();
}
+void ModuleRtpRtcpImpl::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ rtp_sender_->SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
int32_t ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
const RTPExtensionType type,
const uint8_t id) {
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index c7a0c3b..37516de 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -70,6 +70,8 @@
int32_t DeRegisterSendPayload(int8_t payload_type) override;
+ void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
+
// Register RTP header extension.
int32_t RegisterSendRtpHeaderExtension(RTPExtensionType type,
uint8_t id) override;
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index d180013..5b952d0 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -121,7 +121,8 @@
OverheadObserver* overhead_observer,
bool populate_network2_timestamp,
FrameEncryptorInterface* frame_encryptor,
- bool require_frame_encryption)
+ bool require_frame_encryption,
+ bool extmap_allow_mixed)
: clock_(clock),
// TODO(holmer): Remove this conversion?
clock_delta_ms_(clock_->TimeInMilliseconds() - rtc::TimeMillis()),
@@ -144,7 +145,7 @@
max_packet_size_(IP_PACKET_SIZE - 28), // Default is IP-v4/UDP.
last_payload_type_(-1),
payload_type_map_(),
- rtp_header_extension_map_(),
+ rtp_header_extension_map_(extmap_allow_mixed),
packet_history_(clock),
flexfec_packet_history_(clock),
// Statistics
@@ -245,6 +246,11 @@
return nack_bitrate_sent_.Rate(clock_->TimeInMilliseconds()).value_or(0);
}
+void RTPSender::SetExtmapAllowMixed(bool extmap_allow_mixed) {
+ rtc::CritScope lock(&send_critsect_);
+ rtp_header_extension_map_.SetExtmapAllowMixed(extmap_allow_mixed);
+}
+
int32_t RTPSender::RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) {
rtc::CritScope lock(&send_critsect_);
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index dd70bb3..53bc8f1 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -65,7 +65,8 @@
OverheadObserver* overhead_observer,
bool populate_network2_timestamp,
FrameEncryptorInterface* frame_encryptor,
- bool require_frame_encryption);
+ bool require_frame_encryption,
+ bool extmap_allow_mixed);
~RTPSender();
@@ -118,6 +119,8 @@
uint32_t* transport_frame_id_out,
int64_t expected_retransmission_time_ms);
+ void SetExtmapAllowMixed(bool extmap_allow_mixed);
+
// RTP header extension
int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
bool RegisterRtpHeaderExtension(const std::string& uri, int id);
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index ace34ff..f30b383 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -185,7 +185,7 @@
nullptr, &seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
&retransmission_rate_limiter_, nullptr, populate_network2, nullptr,
- false));
+ false, false));
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetTimestampOffset(0);
rtp_sender_->SetSSRC(kSsrc);
@@ -383,7 +383,8 @@
rtp_sender_.reset(new RTPSender(
kEnableAudio, &fake_clock_, &transport, &mock_paced_sender_, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
- nullptr, &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ nullptr, &retransmission_rate_limiter_, nullptr, false, nullptr, false,
+ false));
rtp_sender_->SetTimestampOffset(0);
rtp_sender_->SetSSRC(kSsrc);
@@ -430,7 +431,7 @@
false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
&feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
nullptr, &retransmission_rate_limiter_, &mock_overhead_observer, false,
- nullptr, false));
+ nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber,
@@ -458,7 +459,7 @@
false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
&feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
&send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
- nullptr, false));
+ nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber,
@@ -490,7 +491,7 @@
false, &fake_clock_, &transport_, nullptr, nullptr, &seq_num_allocator_,
&feedback_observer_, nullptr, nullptr, nullptr, &mock_rtc_event_log_,
&send_packet_observer_, &retransmission_rate_limiter_, nullptr, false,
- nullptr, false));
+ nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
SendGenericPayload();
@@ -544,7 +545,7 @@
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, &send_side_delay_observer_, &mock_rtc_event_log_,
- nullptr, nullptr, nullptr, false, nullptr, false));
+ nullptr, nullptr, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
const uint8_t kPayloadType = 127;
@@ -622,7 +623,7 @@
false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
&seq_num_allocator_, &feedback_observer_, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetSSRC(kSsrc);
rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -982,7 +983,7 @@
false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr,
nullptr /* TransportSequenceNumberAllocator */, nullptr, nullptr, nullptr,
nullptr, nullptr, &send_packet_observer_, &retransmission_rate_limiter_,
- nullptr, false, nullptr, false));
+ nullptr, false, nullptr, false, false));
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetSSRC(kSsrc);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
@@ -1008,7 +1009,7 @@
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport, &mock_paced_sender_, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetSSRC(kSsrc);
rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload);
@@ -1132,7 +1133,7 @@
false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
&seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kMediaSsrc);
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -1192,7 +1193,7 @@
false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
&seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kMediaSsrc);
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetStorePacketsStatus(true, 10);
@@ -1291,7 +1292,7 @@
false, &fake_clock_, &transport_, nullptr, &flexfec_sender,
&seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kMediaSsrc);
rtp_sender_->SetSequenceNumber(kSeqNum);
@@ -1355,7 +1356,7 @@
false, &fake_clock_, &transport_, &mock_paced_sender_, &flexfec_sender,
&seq_num_allocator_, nullptr, nullptr, nullptr, nullptr,
&mock_rtc_event_log_, &send_packet_observer_,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kMediaSsrc);
rtp_sender_->SetSequenceNumber(kSeqNum);
@@ -1407,7 +1408,7 @@
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr, nullptr,
nullptr, nullptr, &callback, nullptr, nullptr, nullptr,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
const uint8_t payload_type = 127;
@@ -1470,7 +1471,7 @@
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
&callback, nullptr, nullptr, nullptr, nullptr,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
// Simulate kNumPackets sent with kPacketInterval ms intervals, with the
@@ -1530,7 +1531,7 @@
rtp_sender_.reset(new RTPSender(
true, &fake_clock_, &transport_, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
rtp_sender_->SetSequenceNumber(kSeqNum);
}
@@ -2197,7 +2198,7 @@
new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
&retransmission_rate_limiter_, &mock_overhead_observer,
- false, nullptr, false));
+ false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
// RTP overhead is 12B.
@@ -2219,7 +2220,7 @@
new RTPSender(false, &fake_clock_, &transport_, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
&retransmission_rate_limiter_, &mock_overhead_observer,
- false, nullptr, false));
+ false, nullptr, false, false));
rtp_sender_->SetSSRC(kSsrc);
EXPECT_CALL(mock_overhead_observer, OnOverheadChanged(_)).Times(1);
@@ -2232,7 +2233,7 @@
rtp_sender_.reset(new RTPSender(
false, &fake_clock_, &transport, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr,
- &retransmission_rate_limiter_, nullptr, false, nullptr, false));
+ &retransmission_rate_limiter_, nullptr, false, nullptr, false, false));
rtp_sender_->SetSequenceNumber(kSeqNum);
rtp_sender_->SetTimestampOffset(0);
rtp_sender_->SetSSRC(kSsrc);
diff --git a/pc/channel.cc b/pc/channel.cc
index 91d8cbf..8e1d5ff 100644
--- a/pc/channel.cc
+++ b/pc/channel.cc
@@ -93,6 +93,7 @@
RtpSendParameters<Codec>* send_params) {
RtpParametersFromMediaDescription(desc, extensions, send_params);
send_params->max_bandwidth_bps = desc->bandwidth();
+ send_params->extmap_allow_mixed = desc->extmap_allow_mixed();
}
BaseChannel::BaseChannel(rtc::Thread* worker_thread,
@@ -799,6 +800,7 @@
RtpHeaderExtensions rtp_header_extensions =
GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
UpdateRtpHeaderExtensionMap(rtp_header_extensions);
+ media_channel()->SetExtmapAllowMixed(audio->extmap_allow_mixed());
AudioRecvParameters recv_params = last_recv_params_;
RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
@@ -934,6 +936,7 @@
RtpHeaderExtensions rtp_header_extensions =
GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
UpdateRtpHeaderExtensionMap(rtp_header_extensions);
+ media_channel()->SetExtmapAllowMixed(video->extmap_allow_mixed());
VideoRecvParameters recv_params = last_recv_params_;
RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc
index fc3f20a..5d4d4c7 100644
--- a/pc/channel_unittest.cc
+++ b/pc/channel_unittest.cc
@@ -576,6 +576,37 @@
CodecMatches(content.codecs()[0], media_channel1_->codecs()[0]));
}
+ // Test that SetLocalContent and SetRemoteContent properly configure
+ // extmap-allow-mixed.
+ void TestSetContentsExtmapAllowMixedCaller(bool offer, bool answer) {
+ // For a caller, SetLocalContent() is called first with an offer and next
+ // SetRemoteContent() is called with the answer.
+ CreateChannels(0, 0);
+ typename T::Content content;
+ CreateContent(0, kPcmuCodec, kH264Codec, &content);
+ auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
+ auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
+ content.set_extmap_allow_mixed_enum(offer_enum);
+ EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, NULL));
+ content.set_extmap_allow_mixed_enum(answer_enum);
+ EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, NULL));
+ EXPECT_EQ(answer, media_channel1_->ExtmapAllowMixed());
+ }
+ void TestSetContentsExtmapAllowMixedCallee(bool offer, bool answer) {
+ // For a callee, SetRemoteContent() is called first with an offer and next
+ // SetLocalContent() is called with the answer.
+ CreateChannels(0, 0);
+ typename T::Content content;
+ CreateContent(0, kPcmuCodec, kH264Codec, &content);
+ auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
+ auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
+ content.set_extmap_allow_mixed_enum(offer_enum);
+ EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kOffer, NULL));
+ content.set_extmap_allow_mixed_enum(answer_enum);
+ EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kAnswer, NULL));
+ EXPECT_EQ(answer, media_channel1_->ExtmapAllowMixed());
+ }
+
// Test that SetLocalContent and SetRemoteContent properly deals
// with an empty offer.
void TestSetContentsNullOffer() {
@@ -1614,6 +1645,24 @@
Base::TestSetContents();
}
+TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VoiceChannelSingleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
+}
+
+TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VoiceChannelSingleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
+}
+
TEST_F(VoiceChannelSingleThreadTest, TestSetContentsNullOffer) {
Base::TestSetContentsNullOffer();
}
@@ -1749,6 +1798,24 @@
Base::TestSetContents();
}
+TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VoiceChannelDoubleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
+}
+
+TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VoiceChannelDoubleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
+}
+
TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsNullOffer) {
Base::TestSetContentsNullOffer();
}
@@ -1882,6 +1949,24 @@
Base::TestSetContents();
}
+TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VideoChannelSingleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
+}
+
+TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VideoChannelSingleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
+}
+
TEST_F(VideoChannelSingleThreadTest, TestSetContentsNullOffer) {
Base::TestSetContentsNullOffer();
}
@@ -2015,6 +2100,24 @@
Base::TestSetContents();
}
+TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VideoChannelDoubleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
+ Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
+}
+
+TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
+}
+
+TEST_F(VideoChannelDoubleThreadTest,
+ TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
+ Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
+}
+
TEST_F(VideoChannelDoubleThreadTest, TestSetContentsNullOffer) {
Base::TestSetContentsNullOffer();
}