diff --git a/call/rtp_payload_params.cc b/call/rtp_payload_params.cc index f69a52b05e..31cb743d9d 100644 --- a/call/rtp_payload_params.cc +++ b/call/rtp_payload_params.cc @@ -140,7 +140,7 @@ RtpPayloadParams::RtpPayloadParams(const uint32_t ssrc, generic_picture_id_experiment_( field_trial::IsEnabled("WebRTC-GenericPictureId")), generic_descriptor_experiment_( - field_trial::IsEnabled("WebRTC-GenericDescriptor")) { + !field_trial::IsDisabled("WebRTC-GenericDescriptor")) { for (auto& spatial_layer : last_shared_frame_id_) spatial_layer.fill(-1); diff --git a/call/rtp_payload_params_unittest.cc b/call/rtp_payload_params_unittest.cc index b8fd4a574e..54b4025ceb 100644 --- a/call/rtp_payload_params_unittest.cc +++ b/call/rtp_payload_params_unittest.cc @@ -160,7 +160,7 @@ TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) { h264info->temporal_idx = kNoTemporalIdx; RTPVideoHeader header = - params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); + params.GetRtpVideoHeader(encoded_image, &codec_info, 10); EXPECT_EQ(0, header.simulcastIdx); EXPECT_EQ(kVideoCodecH264, header.codec); @@ -172,7 +172,7 @@ TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) { h264info->base_layer_sync = true; h264info->idr_frame = false; - header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); + header = params.GetRtpVideoHeader(encoded_image, &codec_info, 20); EXPECT_EQ(kVideoCodecH264, header.codec); EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1); @@ -185,7 +185,7 @@ TEST(RtpPayloadParamsTest, InfoMappedToRtpVideoHeader_H264) { h264info->base_layer_sync = false; h264info->idr_frame = true; - header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); + header = params.GetRtpVideoHeader(encoded_image, &codec_info, 30); EXPECT_EQ(kVideoCodecH264, header.codec); EXPECT_EQ(header.frame_marking.tl0_pic_idx, kInitialTl0PicIdx1 + 1); @@ -327,10 +327,11 @@ TEST(RtpPayloadParamsTest, PictureIdForOldGenericFormat) { EncodedImage encoded_image; CodecSpecificInfo codec_info; codec_info.codecType = kVideoCodecGeneric; + encoded_image._frameType = VideoFrameType::kVideoFrameKey; RtpPayloadParams params(kSsrc1, &state); RTPVideoHeader header = - params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); + params.GetRtpVideoHeader(encoded_image, &codec_info, 10); EXPECT_EQ(kVideoCodecGeneric, header.codec); const auto* generic = @@ -338,7 +339,8 @@ TEST(RtpPayloadParamsTest, PictureIdForOldGenericFormat) { ASSERT_TRUE(generic); EXPECT_EQ(0, generic->picture_id); - header = params.GetRtpVideoHeader(encoded_image, &codec_info, kDontCare); + encoded_image._frameType = VideoFrameType::kVideoFrameDelta; + header = params.GetRtpVideoHeader(encoded_image, &codec_info, 20); generic = absl::get_if(&header.video_type_header); ASSERT_TRUE(generic); diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index 2696514ffb..78ece7ffef 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -269,7 +269,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) require_frame_encryption_(config.require_frame_encryption), generic_descriptor_auth_experiment_( config.field_trials->Lookup("WebRTC-GenericDescriptorAuth") - .find("Enabled") == 0), + .find("Disabled") != 0), exclude_transport_sequence_number_from_fec_experiment_( config.field_trials ->Lookup(kExcludeTransportSequenceNumberFromFecFieldTrial) @@ -656,7 +656,7 @@ bool RTPSenderVideo::SendVideo( size_t bytes_written = 0; - // Only enable header authentication if the field trial is enabled. + // Enable header authentication if the field trial isn't disabled. rtc::ArrayView additional_data; if (generic_descriptor_auth_experiment_) { additional_data = generic_descriptor_raw; diff --git a/pc/media_session.cc b/pc/media_session.cc index 35dd2e597d..3df918a2b6 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -961,13 +961,13 @@ static bool FindByUri(const RtpHeaderExtensions& extensions, static bool FindByUriWithEncryptionPreference( const RtpHeaderExtensions& extensions, - const webrtc::RtpExtension& ext_to_match, + absl::string_view uri_to_match, bool encryption_preference, webrtc::RtpExtension* found_extension) { const webrtc::RtpExtension* unencrypted_extension = nullptr; for (const webrtc::RtpExtension& extension : extensions) { // We assume that all URIs are given in a canonical format. - if (extension.uri == ext_to_match.uri) { + if (extension.uri == uri_to_match) { if (!encryption_preference || extension.encrypt) { if (found_extension) { *found_extension = extension; @@ -1037,7 +1037,7 @@ static void AddEncryptedVersionsOfHdrExts(RtpHeaderExtensions* extensions, // extensions. if (extension.encrypt || !webrtc::RtpExtension::IsEncryptionSupported(extension.uri) || - (FindByUriWithEncryptionPreference(*extensions, extension, true, + (FindByUriWithEncryptionPreference(*extensions, extension.uri, true, &existing) && existing.encrypt)) { continue; @@ -1073,11 +1073,14 @@ static void NegotiateRtpHeaderExtensions( offered_extensions, webrtc::RtpExtension::kTransportSequenceNumberV2Uri); + bool frame_descriptor_in_local = false; for (const webrtc::RtpExtension& ours : local_extensions) { + if (ours.uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00) + frame_descriptor_in_local = true; webrtc::RtpExtension theirs; if (FindByUriWithEncryptionPreference( - offered_extensions, ours, enable_encrypted_rtp_header_extensions, - &theirs)) { + offered_extensions, ours.uri, + enable_encrypted_rtp_header_extensions, &theirs)) { if (transport_sequence_number_v2_offer && ours.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) { // Don't respond to @@ -1096,6 +1099,17 @@ static void NegotiateRtpHeaderExtensions( // Respond that we support kTransportSequenceNumberV2Uri. negotiated_extensions->push_back(*transport_sequence_number_v2_offer); } + + // Frame descriptor support. If the extension is not present locally, but is + // in the offer, we add it to the list. + if (!frame_descriptor_in_local) { + webrtc::RtpExtension theirs; + if (FindByUriWithEncryptionPreference( + offered_extensions, + webrtc::RtpExtension::kGenericFrameDescriptorUri00, + 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 a2416c4dcc..389b6a0a48 100644 --- a/pc/media_session_unittest.cc +++ b/pc/media_session_unittest.cc @@ -238,6 +238,12 @@ static const RtpExtension kRtpExtensionTransportSequenceNumber02[] = { 2), }; +static const RtpExtension kRtpExtensionGenericFrameDescriptorUri00[] = { + RtpExtension("http://www.webrtc.org/experiments/rtp-hdrext/" + "generic-frame-descriptor-00", + 3), +}; + static const uint32_t kSimulcastParamsSsrc[] = {10, 11, 20, 21, 30, 31}; static const uint32_t kSimSsrc[] = {10, 20, 30}; static const uint32_t kFec1Ssrc[] = {10, 11}; @@ -1671,6 +1677,50 @@ TEST_F(MediaSessionDescriptionFactoryTest, MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. } +TEST_F(MediaSessionDescriptionFactoryTest, + TestNegotiateFrameDescriptorWhenUnexposedLocally) { + MediaSessionOptions opts; + AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); + + const auto offered = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f1_.set_audio_rtp_header_extensions(offered); + f1_.set_video_rtp_header_extensions(offered); + const auto local = MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01); + f2_.set_audio_rtp_header_extensions(local); + f2_.set_video_rtp_header_extensions(local); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); + std::unique_ptr answer = + f2_.CreateAnswer(offer.get(), opts, nullptr); + EXPECT_THAT( + GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(), + ElementsAreArray(offered)); + EXPECT_THAT( + GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(), + ElementsAreArray(offered)); +} + +TEST_F(MediaSessionDescriptionFactoryTest, + TestNegotiateFrameDescriptorWhenExposedLocally) { + MediaSessionOptions opts; + AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); + + const auto offered = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f1_.set_audio_rtp_header_extensions(offered); + f1_.set_video_rtp_header_extensions(offered); + const auto local = MAKE_VECTOR(kRtpExtensionGenericFrameDescriptorUri00); + f2_.set_audio_rtp_header_extensions(local); + f2_.set_video_rtp_header_extensions(local); + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); + std::unique_ptr answer = + f2_.CreateAnswer(offer.get(), opts, nullptr); + EXPECT_THAT( + GetFirstAudioContentDescription(answer.get())->rtp_header_extensions(), + ElementsAreArray(offered)); + EXPECT_THAT( + GetFirstVideoContentDescription(answer.get())->rtp_header_extensions(), + ElementsAreArray(offered)); +} + TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithEncryptedRtpExtensionsBoth) { MediaSessionOptions opts; diff --git a/video/buffered_frame_decryptor.cc b/video/buffered_frame_decryptor.cc index ae83da940c..fc9dff5b02 100644 --- a/video/buffered_frame_decryptor.cc +++ b/video/buffered_frame_decryptor.cc @@ -24,7 +24,7 @@ BufferedFrameDecryptor::BufferedFrameDecryptor( OnDecryptedFrameCallback* decrypted_frame_callback, OnDecryptionStatusChangeCallback* decryption_status_change_callback) : generic_descriptor_auth_experiment_( - field_trial::IsEnabled("WebRTC-GenericDescriptorAuth")), + !field_trial::IsDisabled("WebRTC-GenericDescriptorAuth")), decrypted_frame_callback_(decrypted_frame_callback), decryption_status_change_callback_(decryption_status_change_callback) {} @@ -76,7 +76,7 @@ BufferedFrameDecryptor::FrameDecision BufferedFrameDecryptor::DecryptFrame( rtc::ArrayView inline_decrypted_bitstream(frame->data(), max_plaintext_byte_size); - // Only enable authenticating the header if the field trial is enabled. + // Enable authenticating the header if the field trial isn't disabled. std::vector additional_data; if (generic_descriptor_auth_experiment_) { additional_data = RtpDescriptorAuthentication(frame->GetRtpVideoHeader());