mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Dynamically assign ids to header extensions not enabled by default
by creating an id collision and letting UsedIds resolve it. Also avoid id=15 which is forbidden by https://www.rfc-editor.org/rfc/rfc8285#section-4.2 so might cause interop issues in offers to implementations not supporting two-byte extensions. BUG=webrtc:15378 Change-Id: I27926f065f8e396257294da7acf2be9802169805 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/319280 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Philipp Hancke <phancke@microsoft.com> Cr-Commit-Position: refs/heads/main@{#41696}
This commit is contained in:
parent
3e613c2590
commit
cea1c0b9a9
4 changed files with 21 additions and 16 deletions
|
@ -811,6 +811,8 @@ std::vector<VideoCodec> WebRtcVideoEngine::recv_codecs(bool include_rtx) const {
|
||||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||||
WebRtcVideoEngine::GetRtpHeaderExtensions() const {
|
WebRtcVideoEngine::GetRtpHeaderExtensions() const {
|
||||||
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
||||||
|
// id is *not* incremented for non-default extensions, UsedIds needs to
|
||||||
|
// resolve conflicts.
|
||||||
int id = 1;
|
int id = 1;
|
||||||
for (const auto& uri :
|
for (const auto& uri :
|
||||||
{webrtc::RtpExtension::kTimestampOffsetUri,
|
{webrtc::RtpExtension::kTimestampOffsetUri,
|
||||||
|
@ -825,27 +827,26 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const {
|
||||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
||||||
}
|
}
|
||||||
for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) {
|
for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) {
|
||||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kStopped);
|
result.emplace_back(uri, id, webrtc::RtpTransceiverDirection::kStopped);
|
||||||
}
|
}
|
||||||
result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id++,
|
result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id,
|
||||||
IsEnabled(trials_, "WebRTC-GenericDescriptorAdvertised")
|
IsEnabled(trials_, "WebRTC-GenericDescriptorAdvertised")
|
||||||
? webrtc::RtpTransceiverDirection::kSendRecv
|
? webrtc::RtpTransceiverDirection::kSendRecv
|
||||||
: webrtc::RtpTransceiverDirection::kStopped);
|
: webrtc::RtpTransceiverDirection::kStopped);
|
||||||
result.emplace_back(
|
result.emplace_back(
|
||||||
webrtc::RtpExtension::kDependencyDescriptorUri, id++,
|
webrtc::RtpExtension::kDependencyDescriptorUri, id,
|
||||||
IsEnabled(trials_, "WebRTC-DependencyDescriptorAdvertised")
|
IsEnabled(trials_, "WebRTC-DependencyDescriptorAdvertised")
|
||||||
? webrtc::RtpTransceiverDirection::kSendRecv
|
? webrtc::RtpTransceiverDirection::kSendRecv
|
||||||
: webrtc::RtpTransceiverDirection::kStopped);
|
: webrtc::RtpTransceiverDirection::kStopped);
|
||||||
|
|
||||||
result.emplace_back(
|
result.emplace_back(
|
||||||
webrtc::RtpExtension::kVideoLayersAllocationUri, id++,
|
webrtc::RtpExtension::kVideoLayersAllocationUri, id,
|
||||||
IsEnabled(trials_, "WebRTC-VideoLayersAllocationAdvertised")
|
IsEnabled(trials_, "WebRTC-VideoLayersAllocationAdvertised")
|
||||||
? webrtc::RtpTransceiverDirection::kSendRecv
|
? webrtc::RtpTransceiverDirection::kSendRecv
|
||||||
: webrtc::RtpTransceiverDirection::kStopped);
|
: webrtc::RtpTransceiverDirection::kStopped);
|
||||||
|
|
||||||
// VideoFrameTrackingId is a test-only extension.
|
// VideoFrameTrackingId is a test-only extension.
|
||||||
if (IsEnabled(trials_, "WebRTC-VideoFrameTrackingIdAdvertised")) {
|
if (IsEnabled(trials_, "WebRTC-VideoFrameTrackingIdAdvertised")) {
|
||||||
result.emplace_back(webrtc::RtpExtension::kVideoFrameTrackingIdUri, id++,
|
result.emplace_back(webrtc::RtpExtension::kVideoFrameTrackingIdUri, id,
|
||||||
webrtc::RtpTransceiverDirection::kSendRecv);
|
webrtc::RtpTransceiverDirection::kSendRecv);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -643,6 +643,8 @@ std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||||
WebRtcVoiceEngine::GetRtpHeaderExtensions() const {
|
WebRtcVoiceEngine::GetRtpHeaderExtensions() const {
|
||||||
RTC_DCHECK(signal_thread_checker_.IsCurrent());
|
RTC_DCHECK(signal_thread_checker_.IsCurrent());
|
||||||
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
||||||
|
// id is *not* incremented for non-default extensions, UsedIds needs to
|
||||||
|
// resolve conflicts.
|
||||||
int id = 1;
|
int id = 1;
|
||||||
for (const auto& uri : {webrtc::RtpExtension::kAudioLevelUri,
|
for (const auto& uri : {webrtc::RtpExtension::kAudioLevelUri,
|
||||||
webrtc::RtpExtension::kAbsSendTimeUri,
|
webrtc::RtpExtension::kAbsSendTimeUri,
|
||||||
|
@ -651,7 +653,7 @@ WebRtcVoiceEngine::GetRtpHeaderExtensions() const {
|
||||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
||||||
}
|
}
|
||||||
for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) {
|
for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) {
|
||||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kStopped);
|
result.emplace_back(uri, id, webrtc::RtpTransceiverDirection::kStopped);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,15 +147,15 @@ class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Returns the first unused id in reverse order from the max id of one byte
|
// Returns the first unused id in reverse order from the max id of one byte
|
||||||
// header extensions. This hopefully reduce the risk of more collisions. We
|
// header extensions. This hopefully reduces the risk of more collisions. We
|
||||||
// want to change the default ids as little as possible. If no unused id is
|
// want to change the default ids as little as possible. If no unused id is
|
||||||
// found and two byte header extensions are enabled (i.e.,
|
// found and two byte header extensions are enabled (i.e.,
|
||||||
// `extmap_allow_mixed_` is true), search for unused ids from 15 to 255.
|
// `extmap_allow_mixed_` is true), search for unused ids from 16 to 255.
|
||||||
int FindUnusedId() override {
|
int FindUnusedId() override {
|
||||||
if (next_extension_id_ <=
|
if (next_extension_id_ <=
|
||||||
webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) {
|
webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) {
|
||||||
// First search in reverse order from the max id of one byte header
|
// First search in reverse order from the max id of one byte header
|
||||||
// extensions.
|
// extensions (14).
|
||||||
while (IsIdUsed(next_extension_id_) &&
|
while (IsIdUsed(next_extension_id_) &&
|
||||||
next_extension_id_ >= min_allowed_id_) {
|
next_extension_id_ >= min_allowed_id_) {
|
||||||
--next_extension_id_;
|
--next_extension_id_;
|
||||||
|
@ -165,9 +165,10 @@ class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> {
|
||||||
if (id_domain_ == IdDomain::kTwoByteAllowed) {
|
if (id_domain_ == IdDomain::kTwoByteAllowed) {
|
||||||
if (next_extension_id_ < min_allowed_id_) {
|
if (next_extension_id_ < min_allowed_id_) {
|
||||||
// We have searched among all one-byte IDs without finding an unused ID,
|
// We have searched among all one-byte IDs without finding an unused ID,
|
||||||
// continue at the first two-byte ID.
|
// continue at the first two-byte ID (16; avoid 15 since it is somewhat
|
||||||
|
// special per https://www.rfc-editor.org/rfc/rfc8285#section-4.2
|
||||||
next_extension_id_ =
|
next_extension_id_ =
|
||||||
webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 1;
|
webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_extension_id_ >
|
if (next_extension_id_ >
|
||||||
|
|
|
@ -119,7 +119,8 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) {
|
||||||
UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed);
|
UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed);
|
||||||
|
|
||||||
// Fill all one byte IDs.
|
// Fill all one byte IDs.
|
||||||
for (int i = 1; i < 15; ++i) {
|
for (int i = 1; i <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId;
|
||||||
|
++i) {
|
||||||
webrtc::RtpExtension id("", i);
|
webrtc::RtpExtension id("", i);
|
||||||
used_ids.FindAndSetIdUsed(&id);
|
used_ids.FindAndSetIdUsed(&id);
|
||||||
}
|
}
|
||||||
|
@ -131,11 +132,11 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) {
|
||||||
|
|
||||||
// Expect to reassign to two-byte header extension IDs.
|
// Expect to reassign to two-byte header extension IDs.
|
||||||
used_ids.FindAndSetIdUsed(&id1_collision);
|
used_ids.FindAndSetIdUsed(&id1_collision);
|
||||||
EXPECT_EQ(id1_collision.id, 15);
|
EXPECT_EQ(id1_collision.id, 16);
|
||||||
used_ids.FindAndSetIdUsed(&id2_collision);
|
used_ids.FindAndSetIdUsed(&id2_collision);
|
||||||
EXPECT_EQ(id2_collision.id, 16);
|
EXPECT_EQ(id2_collision.id, 17);
|
||||||
used_ids.FindAndSetIdUsed(&id3_collision);
|
used_ids.FindAndSetIdUsed(&id3_collision);
|
||||||
EXPECT_EQ(id3_collision.id, 17);
|
EXPECT_EQ(id3_collision.id, 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Death tests.
|
// Death tests.
|
||||||
|
|
Loading…
Reference in a new issue