Ship GenericDescriptor00 by default.
The change ships GenericDescriptor00 and authentication by default, but doesn't expose it by default, and makes WebRTC respond to offers carrying it. The change adds a unit test for the new semantics. Tests well in munge-sdp. Frame marking replaced by http://www.webrtc.org/experiments/rtp-hdrext/generic-frame-descriptor-00 in the offer results in an answer containing the extension as first entry. Bug: webrtc:11367 Change-Id: I0ef91b7d4096d949c3d547ece7d6c4d39aa241da Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168661 Reviewed-by: Magnus Flodman <mflodman@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30542}
This commit is contained in:
parent
e45763139c
commit
c1cbf6be7e
@ -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);
|
||||
|
||||
|
||||
@ -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<RTPVideoHeaderLegacyGeneric>(&header.video_type_header);
|
||||
ASSERT_TRUE(generic);
|
||||
|
||||
@ -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<const uint8_t> additional_data;
|
||||
if (generic_descriptor_auth_experiment_) {
|
||||
additional_data = generic_descriptor_raw;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
|
||||
std::unique_ptr<SessionDescription> 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<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
|
||||
std::unique_ptr<SessionDescription> 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;
|
||||
|
||||
@ -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<uint8_t> 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<uint8_t> additional_data;
|
||||
if (generic_descriptor_auth_experiment_) {
|
||||
additional_data = RtpDescriptorAuthentication(frame->GetRtpVideoHeader());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user