Allow to negotiate absolute capture time rtp header extension.
Bug: webrtc:10739
Change-Id: I239d67a8c02bcc4175b142174b254e876bdd8d6d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169920
Commit-Queue: Minyue Li <minyue@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30746}
diff --git a/pc/media_session.cc b/pc/media_session.cc
index 05c421e..110258d 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -1075,11 +1075,15 @@
bool frame_descriptor_in_local = false;
bool dependency_descriptor_in_local = false;
+ bool abs_capture_time_in_local = false;
+
for (const webrtc::RtpExtension& ours : local_extensions) {
if (ours.uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00)
frame_descriptor_in_local = true;
else if (ours.uri == webrtc::RtpExtension::kDependencyDescriptorUri)
dependency_descriptor_in_local = true;
+ else if (ours.uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri)
+ abs_capture_time_in_local = true;
webrtc::RtpExtension theirs;
if (FindByUriWithEncryptionPreference(
offered_extensions, ours.uri,
@@ -1119,6 +1123,15 @@
enable_encrypted_rtp_header_extensions, &theirs)) {
negotiated_extensions->push_back(theirs);
}
+
+ // Absolute capture time support. If the extension is not present locally, but
+ // is in the offer, we add it to the list.
+ if (!abs_capture_time_in_local &&
+ FindByUriWithEncryptionPreference(
+ offered_extensions, webrtc::RtpExtension::kAbsoluteCaptureTimeUri,
+ enable_encrypted_rtp_header_extensions, &theirs)) {
+ negotiated_extensions->push_back(theirs);
+ }
}
static void StripCNCodecs(AudioCodecs* audio_codecs) {
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index b217051..41e2767 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -1757,6 +1757,81 @@
}
TEST_F(MediaSessionDescriptionFactoryTest,
+ NegotiateAbsoluteCaptureTimeWhenUnexposedLocally) {
+ MediaSessionOptions opts;
+ AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts);
+
+ const cricket::RtpHeaderExtensions offered_extensions = {
+ RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 7)};
+ const cricket::RtpHeaderExtensions local_extensions = {
+ RtpExtension(RtpExtension::kTransportSequenceNumberUri, 5)};
+ f1_.set_video_rtp_header_extensions(offered_extensions);
+ f1_.set_audio_rtp_header_extensions(offered_extensions);
+ f2_.set_video_rtp_header_extensions(local_extensions);
+ f2_.set_audio_rtp_header_extensions(local_extensions);
+
+ std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
+ std::unique_ptr<SessionDescription> answer =
+ f2_.CreateAnswer(offer.get(), opts, nullptr);
+ EXPECT_THAT(
+ GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(),
+ ElementsAreArray(offered_extensions));
+ EXPECT_THAT(
+ GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(),
+ ElementsAreArray(offered_extensions));
+}
+
+TEST_F(MediaSessionDescriptionFactoryTest,
+ NegotiateAbsoluteCaptureTimeWhenExposedLocally) {
+ MediaSessionOptions opts;
+ AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts);
+
+ const cricket::RtpHeaderExtensions offered_extensions = {
+ RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 7)};
+ const cricket::RtpHeaderExtensions local_extensions = {
+ RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 5)};
+ f1_.set_video_rtp_header_extensions(offered_extensions);
+ f1_.set_audio_rtp_header_extensions(offered_extensions);
+ f2_.set_video_rtp_header_extensions(local_extensions);
+ f2_.set_audio_rtp_header_extensions(local_extensions);
+
+ std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
+ std::unique_ptr<SessionDescription> answer =
+ f2_.CreateAnswer(offer.get(), opts, nullptr);
+ EXPECT_THAT(
+ GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(),
+ ElementsAreArray(offered_extensions));
+ EXPECT_THAT(
+ GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(),
+ ElementsAreArray(offered_extensions));
+}
+
+TEST_F(MediaSessionDescriptionFactoryTest,
+ DoNotNegotiateAbsoluteCaptureTimeWhenNotOffered) {
+ MediaSessionOptions opts;
+ AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts);
+
+ const cricket::RtpHeaderExtensions offered_extensions = {
+ RtpExtension(RtpExtension::kTransportSequenceNumberUri, 7)};
+ const cricket::RtpHeaderExtensions local_extensions = {
+ RtpExtension(RtpExtension::kAbsoluteCaptureTimeUri, 5)};
+ f1_.set_video_rtp_header_extensions(offered_extensions);
+ f1_.set_audio_rtp_header_extensions(offered_extensions);
+ f2_.set_video_rtp_header_extensions(local_extensions);
+ f2_.set_audio_rtp_header_extensions(local_extensions);
+
+ std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
+ std::unique_ptr<SessionDescription> answer =
+ f2_.CreateAnswer(offer.get(), opts, nullptr);
+ EXPECT_THAT(
+ GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(),
+ IsEmpty());
+ EXPECT_THAT(
+ GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(),
+ IsEmpty());
+}
+
+TEST_F(MediaSessionDescriptionFactoryTest,
TestOfferAnswerWithEncryptedRtpExtensionsBoth) {
MediaSessionOptions opts;
AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts);