Add header extension filtering for WebRtcVoiceEngine/MediaChannel.
Rework filtering functionality to be reused for both Audio+Video.
BUG=webrtc:4690
Review URL: https://codereview.webrtc.org/1481963002
Cr-Commit-Position: refs/heads/master@{#10869}
diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp
index 265c37b..be64c5e 100755
--- a/talk/libjingle_tests.gyp
+++ b/talk/libjingle_tests.gyp
@@ -91,15 +91,15 @@
'media/base/videocapturer_unittest.cc',
'media/base/videocommon_unittest.cc',
'media/base/videoengine_unittest.h',
+ 'media/base/videoframe_unittest.h',
'media/devices/dummydevicemanager_unittest.cc',
'media/devices/filevideocapturer_unittest.cc',
'media/sctp/sctpdataengine_unittest.cc',
'media/webrtc/simulcast_unittest.cc',
+ 'media/webrtc/webrtcmediaengine_unittest.cc',
'media/webrtc/webrtcvideocapturer_unittest.cc',
- 'media/base/videoframe_unittest.h',
'media/webrtc/webrtcvideoframe_unittest.cc',
'media/webrtc/webrtcvideoframefactory_unittest.cc',
-
# Disabled because some tests fail.
# TODO(ronghuawu): Reenable these tests.
# 'media/devices/devicemanager_unittest.cc',
diff --git a/talk/media/base/mediachannel.h b/talk/media/base/mediachannel.h
index 3f777b3..f9ffffa 100644
--- a/talk/media/base/mediachannel.h
+++ b/talk/media/base/mediachannel.h
@@ -413,8 +413,8 @@
std::string ToString() const {
std::ostringstream ost;
ost << "{";
- ost << "id: , " << id;
ost << "uri: " << uri;
+ ost << ", id: " << id;
ost << "}";
return ost.str();
}
@@ -936,7 +936,7 @@
template <class Codec>
struct RtpParameters {
- virtual std::string ToString() {
+ virtual std::string ToString() const {
std::ostringstream ost;
ost << "{";
ost << "codecs: " << VectorToString(codecs) << ", ";
@@ -952,7 +952,7 @@
template <class Codec, class Options>
struct RtpSendParameters : RtpParameters<Codec> {
- std::string ToString() override {
+ std::string ToString() const override {
std::ostringstream ost;
ost << "{";
ost << "codecs: " << VectorToString(this->codecs) << ", ";
@@ -1160,13 +1160,13 @@
enum SendDataResult { SDR_SUCCESS, SDR_ERROR, SDR_BLOCK };
struct DataOptions {
- std::string ToString() {
+ std::string ToString() const {
return "{}";
}
};
struct DataSendParameters : RtpSendParameters<DataCodec, DataOptions> {
- std::string ToString() {
+ std::string ToString() const {
std::ostringstream ost;
// Options and extensions aren't used.
ost << "{";
diff --git a/talk/media/webrtc/webrtcmediaengine.cc b/talk/media/webrtc/webrtcmediaengine.cc
index e1d4ac2..31e5025 100644
--- a/talk/media/webrtc/webrtcmediaengine.cc
+++ b/talk/media/webrtc/webrtcmediaengine.cc
@@ -26,9 +26,11 @@
*/
#include "talk/media/webrtc/webrtcmediaengine.h"
+
+#include <algorithm>
+
#include "talk/media/webrtc/webrtcvideoengine2.h"
#include "talk/media/webrtc/webrtcvoiceengine.h"
-#include "webrtc/base/arraysize.h"
namespace cricket {
@@ -69,43 +71,85 @@
return CreateWebRtcMediaEngine(adm, encoder_factory, decoder_factory);
}
-const char* kBweExtensionPriorities[] = {
- kRtpTransportSequenceNumberHeaderExtension,
- kRtpAbsoluteSenderTimeHeaderExtension, kRtpTimestampOffsetHeaderExtension};
-
-const size_t kBweExtensionPrioritiesLength = arraysize(kBweExtensionPriorities);
-
-int GetPriority(const RtpHeaderExtension& extension,
- const char* extension_prios[],
- size_t extension_prios_length) {
- for (size_t i = 0; i < extension_prios_length; ++i) {
- if (extension.uri == extension_prios[i])
- return static_cast<int>(i);
- }
- return -1;
-}
-
-std::vector<RtpHeaderExtension> FilterRedundantRtpExtensions(
- const std::vector<RtpHeaderExtension>& extensions,
- const char* extension_prios[],
- size_t extension_prios_length) {
- if (extensions.empty())
- return std::vector<RtpHeaderExtension>();
- std::vector<RtpHeaderExtension> filtered;
- std::map<int, const RtpHeaderExtension*> sorted;
- for (auto& extension : extensions) {
- int priority =
- GetPriority(extension, extension_prios, extension_prios_length);
- if (priority == -1) {
- filtered.push_back(extension);
- continue;
- } else {
- sorted[priority] = &extension;
+namespace {
+// Remove mutually exclusive extensions with lower priority.
+void DiscardRedundantExtensions(
+ std::vector<webrtc::RtpExtension>* extensions,
+ rtc::ArrayView<const char*> extensions_decreasing_prio) {
+ RTC_DCHECK(extensions);
+ bool found = false;
+ for (const char* name : extensions_decreasing_prio) {
+ auto it = std::find_if(extensions->begin(), extensions->end(),
+ [name](const webrtc::RtpExtension& rhs) {
+ return rhs.name == name;
+ });
+ if (it != extensions->end()) {
+ if (found) {
+ extensions->erase(it);
+ }
+ found = true;
}
}
- if (!sorted.empty())
- filtered.push_back(*sorted.begin()->second);
- return filtered;
+}
+} // namespace
+
+bool ValidateRtpExtensions(const std::vector<RtpHeaderExtension>& extensions) {
+ bool id_used[14] = {false};
+ for (const auto& extension : extensions) {
+ if (extension.id <= 0 || extension.id >= 15) {
+ LOG(LS_ERROR) << "Bad RTP extension ID: " << extension.ToString();
+ return false;
+ }
+ if (id_used[extension.id - 1]) {
+ LOG(LS_ERROR) << "Duplicate RTP extension ID: " << extension.ToString();
+ return false;
+ }
+ id_used[extension.id - 1] = true;
+ }
+ return true;
}
+std::vector<webrtc::RtpExtension> FilterRtpExtensions(
+ const std::vector<RtpHeaderExtension>& extensions,
+ bool (*supported)(const std::string&),
+ bool filter_redundant_extensions) {
+ RTC_DCHECK(ValidateRtpExtensions(extensions));
+ RTC_DCHECK(supported);
+ std::vector<webrtc::RtpExtension> result;
+
+ // Ignore any extensions that we don't recognize.
+ for (const auto& extension : extensions) {
+ if (supported(extension.uri)) {
+ result.push_back({extension.uri, extension.id});
+ } else {
+ LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
+ }
+ }
+
+ // Sort by name, ascending, so that we don't reset extensions if they were
+ // specified in a different order (also allows us to use std::unique below).
+ std::sort(result.begin(), result.end(),
+ [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
+ return rhs.name < lhs.name;
+ });
+
+ // Remove unnecessary extensions (used on send side).
+ if (filter_redundant_extensions) {
+ auto it = std::unique(result.begin(), result.end(),
+ [](const webrtc::RtpExtension& rhs, const webrtc::RtpExtension& lhs) {
+ return rhs.name == lhs.name;
+ });
+ result.erase(it, result.end());
+
+ // Keep just the highest priority extension of any in the following list.
+ static const char* kBweExtensionPriorities[] = {
+ kRtpTransportSequenceNumberHeaderExtension,
+ kRtpAbsoluteSenderTimeHeaderExtension,
+ kRtpTimestampOffsetHeaderExtension
+ };
+ DiscardRedundantExtensions(&result, kBweExtensionPriorities);
+ }
+
+ return result;
+}
} // namespace cricket
diff --git a/talk/media/webrtc/webrtcmediaengine.h b/talk/media/webrtc/webrtcmediaengine.h
index 8d754040..831d072 100644
--- a/talk/media/webrtc/webrtcmediaengine.h
+++ b/talk/media/webrtc/webrtcmediaengine.h
@@ -28,7 +28,11 @@
#ifndef TALK_MEDIA_WEBRTCMEDIAENGINE_H_
#define TALK_MEDIA_WEBRTCMEDIAENGINE_H_
+#include <string>
+#include <vector>
+
#include "talk/media/base/mediaengine.h"
+#include "webrtc/config.h"
namespace webrtc {
class AudioDeviceModule;
@@ -48,13 +52,18 @@
WebRtcVideoDecoderFactory* decoder_factory);
};
-extern const char* kBweExtensionPriorities[];
-extern const size_t kBweExtensionPrioritiesLength;
+// Verify that extension IDs are within 1-byte extension range and are not
+// overlapping.
+bool ValidateRtpExtensions(const std::vector<RtpHeaderExtension>& extensions);
-std::vector<RtpHeaderExtension> FilterRedundantRtpExtensions(
+// Convert cricket::RtpHeaderExtension:s to webrtc::RtpExtension:s, discarding
+// any extensions not validated by the 'supported' predicate. Duplicate
+// extensions are removed if 'filter_redundant_extensions' is set, and also any
+// mutually exclusive extensions (see implementation for details).
+std::vector<webrtc::RtpExtension> FilterRtpExtensions(
const std::vector<RtpHeaderExtension>& extensions,
- const char* extension_prios[],
- size_t extension_prios_length);
+ bool (*supported)(const std::string&),
+ bool filter_redundant_extensions);
} // namespace cricket
diff --git a/talk/media/webrtc/webrtcmediaengine_unittest.cc b/talk/media/webrtc/webrtcmediaengine_unittest.cc
new file mode 100644
index 0000000..7c80e77
--- /dev/null
+++ b/talk/media/webrtc/webrtcmediaengine_unittest.cc
@@ -0,0 +1,205 @@
+/*
+ * libjingle
+ * Copyright 2015 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "talk/media/webrtc/webrtcmediaengine.h"
+
+namespace cricket {
+namespace {
+
+std::vector<RtpHeaderExtension> MakeUniqueExtensions() {
+ std::vector<RtpHeaderExtension> result;
+ char name[] = "a";
+ for (int i = 0; i < 7; ++i) {
+ result.push_back(RtpHeaderExtension(name, 1 + i));
+ name[0]++;
+ result.push_back(RtpHeaderExtension(name, 14 - i));
+ name[0]++;
+ }
+ return result;
+}
+
+std::vector<RtpHeaderExtension> MakeRedundantExtensions() {
+ std::vector<RtpHeaderExtension> result;
+ char name[] = "a";
+ for (int i = 0; i < 7; ++i) {
+ result.push_back(RtpHeaderExtension(name, 1 + i));
+ result.push_back(RtpHeaderExtension(name, 14 - i));
+ name[0]++;
+ }
+ return result;
+}
+
+bool SupportedExtensions1(const std::string& name) {
+ return name == "c" || name == "i";
+}
+
+bool SupportedExtensions2(const std::string& name) {
+ return name != "a" && name != "n";
+}
+
+bool IsSorted(const std::vector<webrtc::RtpExtension>& extensions) {
+ const std::string* last = nullptr;
+ for (const auto& extension : extensions) {
+ if (last && *last > extension.name) {
+ return false;
+ }
+ last = &extension.name;
+ }
+ return true;
+}
+} // namespace
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_EmptyList) {
+ std::vector<RtpHeaderExtension> extensions;
+ EXPECT_TRUE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_AllGood) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ EXPECT_TRUE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_OutOfRangeId_Low) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ extensions.push_back(RtpHeaderExtension("foo", 0));
+ EXPECT_FALSE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_OutOfRangeId_High) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ extensions.push_back(RtpHeaderExtension("foo", 15));
+ EXPECT_FALSE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_OverlappingIds_StartOfSet) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ extensions.push_back(RtpHeaderExtension("foo", 1));
+ EXPECT_FALSE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, ValidateRtpExtensions_OverlappingIds_EndOfSet) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ extensions.push_back(RtpHeaderExtension("foo", 14));
+ EXPECT_FALSE(ValidateRtpExtensions(extensions));
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_EmptyList) {
+ std::vector<RtpHeaderExtension> extensions;
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions1, true);
+ EXPECT_EQ(0, filtered.size());
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_IncludeOnlySupported) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions1, false);
+ EXPECT_EQ(2, filtered.size());
+ EXPECT_EQ("c", filtered[0].name);
+ EXPECT_EQ("i", filtered[1].name);
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_SortedByName_1) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, false);
+ EXPECT_EQ(12, filtered.size());
+ EXPECT_TRUE(IsSorted(filtered));
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_SortedByName_2) {
+ std::vector<RtpHeaderExtension> extensions = MakeUniqueExtensions();
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, true);
+ EXPECT_EQ(12, filtered.size());
+ EXPECT_TRUE(IsSorted(filtered));
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_DontRemoveRedundant) {
+ std::vector<RtpHeaderExtension> extensions = MakeRedundantExtensions();
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, false);
+ EXPECT_EQ(12, filtered.size());
+ EXPECT_TRUE(IsSorted(filtered));
+ EXPECT_EQ(filtered[0].name, filtered[1].name);
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundant) {
+ std::vector<RtpHeaderExtension> extensions = MakeRedundantExtensions();
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, true);
+ EXPECT_EQ(6, filtered.size());
+ EXPECT_TRUE(IsSorted(filtered));
+ EXPECT_NE(filtered[0].name, filtered[1].name);
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_1) {
+ std::vector<RtpHeaderExtension> extensions;
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTransportSequenceNumberHeaderExtension, 3));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 9));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 6));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTransportSequenceNumberHeaderExtension, 1));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 14));
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, true);
+ EXPECT_EQ(1, filtered.size());
+ EXPECT_EQ(kRtpTransportSequenceNumberHeaderExtension, filtered[0].name);
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_2) {
+ std::vector<RtpHeaderExtension> extensions;
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 1));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 14));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 7));
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, true);
+ EXPECT_EQ(1, filtered.size());
+ EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtension, filtered[0].name);
+}
+
+TEST(WebRtcMediaEngineTest, FilterRtpExtensions_RemoveRedundantBwe_3) {
+ std::vector<RtpHeaderExtension> extensions;
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 2));
+ extensions.push_back(
+ RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 14));
+ std::vector<webrtc::RtpExtension> filtered =
+ FilterRtpExtensions(extensions, SupportedExtensions2, true);
+ EXPECT_EQ(1, filtered.size());
+ EXPECT_EQ(kRtpTimestampOffsetHeaderExtension, filtered[0].name);
+}
+} // namespace cricket
diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc
index 2f07687..308b68b 100644
--- a/talk/media/webrtc/webrtcvideoengine2.cc
+++ b/talk/media/webrtc/webrtcvideoengine2.cc
@@ -243,20 +243,6 @@
return true;
}
-static std::string RtpExtensionsToString(
- const std::vector<RtpHeaderExtension>& extensions) {
- std::stringstream out;
- out << '{';
- for (size_t i = 0; i < extensions.size(); ++i) {
- out << "{" << extensions[i].uri << ": " << extensions[i].id << "}";
- if (i != extensions.size() - 1) {
- out << ", ";
- }
- }
- out << '}';
- return out.str();
-}
-
inline const webrtc::RtpExtension* FindHeaderExtension(
const std::vector<webrtc::RtpExtension>& extensions,
const std::string& name) {
@@ -370,60 +356,6 @@
return false;
}
-static bool ValidateRtpHeaderExtensionIds(
- const std::vector<RtpHeaderExtension>& extensions) {
- std::set<int> extensions_used;
- for (size_t i = 0; i < extensions.size(); ++i) {
- if (extensions[i].id <= 0 || extensions[i].id >= 15 ||
- !extensions_used.insert(extensions[i].id).second) {
- LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids.";
- return false;
- }
- }
- return true;
-}
-
-static bool CompareRtpHeaderExtensionIds(
- const webrtc::RtpExtension& extension1,
- const webrtc::RtpExtension& extension2) {
- // Sorting on ID is sufficient, more than one extension per ID is unsupported.
- return extension1.id > extension2.id;
-}
-
-static std::vector<webrtc::RtpExtension> FilterRtpExtensions(
- const std::vector<RtpHeaderExtension>& extensions) {
- std::vector<webrtc::RtpExtension> webrtc_extensions;
- for (size_t i = 0; i < extensions.size(); ++i) {
- // Unsupported extensions will be ignored.
- if (webrtc::RtpExtension::IsSupportedForVideo(extensions[i].uri)) {
- webrtc_extensions.push_back(webrtc::RtpExtension(
- extensions[i].uri, extensions[i].id));
- } else {
- LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri;
- }
- }
-
- // Sort filtered headers to make sure that they can later be compared
- // regardless of in which order they were entered.
- std::sort(webrtc_extensions.begin(), webrtc_extensions.end(),
- CompareRtpHeaderExtensionIds);
- return webrtc_extensions;
-}
-
-static bool RtpExtensionsHaveChanged(
- const std::vector<webrtc::RtpExtension>& before,
- const std::vector<webrtc::RtpExtension>& after) {
- if (before.size() != after.size())
- return true;
- for (size_t i = 0; i < before.size(); ++i) {
- if (before[i].id != after[i].id)
- return true;
- if (before[i].name != after[i].name)
- return true;
- }
- return false;
-}
-
std::vector<webrtc::VideoStream>
WebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams(
const VideoCodec& codec,
@@ -856,6 +788,7 @@
}
bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) {
+ LOG(LS_INFO) << "SetSendParameters: " << params.ToString();
// TODO(pbos): Refactor this to only recreate the send streams once
// instead of 4 times.
return (SetSendCodecs(params.codecs) &&
@@ -865,6 +798,7 @@
}
bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) {
+ LOG(LS_INFO) << "SetRecvParameters: " << params.ToString();
// TODO(pbos): Refactor this to only recreate the recv streams once
// instead of twice.
return (SetRecvCodecs(params.codecs) &&
@@ -1507,20 +1441,17 @@
bool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) {
TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions");
- LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: "
- << RtpExtensionsToString(extensions);
- if (!ValidateRtpHeaderExtensionIds(extensions))
+ if (!ValidateRtpExtensions(extensions)) {
return false;
-
- std::vector<webrtc::RtpExtension> filtered_extensions =
- FilterRtpExtensions(extensions);
- if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) {
+ }
+ std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(
+ extensions, webrtc::RtpExtension::IsSupportedForVideo, false);
+ if (recv_rtp_extensions_ == filtered_extensions) {
LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because "
"header extensions haven't changed.";
return true;
}
-
- recv_rtp_extensions_ = filtered_extensions;
+ recv_rtp_extensions_.swap(filtered_extensions);
rtc::CritScope stream_lock(&stream_crit_);
for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it =
@@ -1534,21 +1465,17 @@
bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) {
TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions");
- LOG(LS_INFO) << "SetSendRtpHeaderExtensions: "
- << RtpExtensionsToString(extensions);
- if (!ValidateRtpHeaderExtensionIds(extensions))
+ if (!ValidateRtpExtensions(extensions)) {
return false;
-
- std::vector<webrtc::RtpExtension> filtered_extensions =
- FilterRtpExtensions(FilterRedundantRtpExtensions(
- extensions, kBweExtensionPriorities, kBweExtensionPrioritiesLength));
- if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) {
- LOG(LS_INFO) << "Ignoring call to SetSendRtpHeaderExtensions because "
+ }
+ std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(
+ extensions, webrtc::RtpExtension::IsSupportedForVideo, true);
+ if (send_rtp_extensions_ == filtered_extensions) {
+ LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because "
"header extensions haven't changed.";
return true;
}
-
- send_rtp_extensions_ = filtered_extensions;
+ send_rtp_extensions_.swap(filtered_extensions);
const webrtc::RtpExtension* cvo_extension = FindHeaderExtension(
send_rtp_extensions_, kRtpVideoRotationHeaderExtension);
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index 8869a98..76c0c01 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -42,6 +42,7 @@
#include "talk/media/base/audiorenderer.h"
#include "talk/media/base/constants.h"
#include "talk/media/base/streamparams.h"
+#include "talk/media/webrtc/webrtcmediaengine.h"
#include "talk/media/webrtc/webrtcvoe.h"
#include "webrtc/base/arraysize.h"
#include "webrtc/base/base64.h"
@@ -296,20 +297,6 @@
return config;
}
-std::vector<webrtc::RtpExtension> FindAudioRtpHeaderExtensions(
- const std::vector<RtpHeaderExtension>& extensions) {
- std::vector<webrtc::RtpExtension> result;
- for (const auto& extension : extensions) {
- if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension ||
- extension.uri == kRtpAudioLevelHeaderExtension) {
- result.push_back({extension.uri, extension.id});
- } else {
- LOG(LS_WARNING) << "Unsupported RTP extension: " << extension.ToString();
- }
- }
- return result;
-}
-
class WebRtcVoiceCodecs final {
public:
// TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec
@@ -1450,6 +1437,8 @@
bool WebRtcVoiceMediaChannel::SetSendParameters(
const AudioSendParameters& params) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendParameters: "
+ << params.ToString();
// TODO(pthatcher): Refactor this to be more clean now that we have
// all the information at once.
@@ -1457,10 +1446,14 @@
return false;
}
- std::vector<webrtc::RtpExtension> send_rtp_extensions =
- FindAudioRtpHeaderExtensions(params.extensions);
- if (send_rtp_extensions_ != send_rtp_extensions) {
- send_rtp_extensions_.swap(send_rtp_extensions);
+ if (!ValidateRtpExtensions(params.extensions)) {
+ return false;
+ }
+ std::vector<webrtc::RtpExtension> filtered_extensions =
+ FilterRtpExtensions(params.extensions,
+ webrtc::RtpExtension::IsSupportedForAudio, true);
+ if (send_rtp_extensions_ != filtered_extensions) {
+ send_rtp_extensions_.swap(filtered_extensions);
for (auto& it : send_streams_) {
it.second->RecreateAudioSendStream(send_rtp_extensions_);
}
@@ -1475,6 +1468,8 @@
bool WebRtcVoiceMediaChannel::SetRecvParameters(
const AudioRecvParameters& params) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetRecvParameters: "
+ << params.ToString();
// TODO(pthatcher): Refactor this to be more clean now that we have
// all the information at once.
@@ -1482,10 +1477,14 @@
return false;
}
- std::vector<webrtc::RtpExtension> recv_rtp_extensions =
- FindAudioRtpHeaderExtensions(params.extensions);
- if (recv_rtp_extensions_ != recv_rtp_extensions) {
- recv_rtp_extensions_.swap(recv_rtp_extensions);
+ if (!ValidateRtpExtensions(params.extensions)) {
+ return false;
+ }
+ std::vector<webrtc::RtpExtension> filtered_extensions =
+ FilterRtpExtensions(params.extensions,
+ webrtc::RtpExtension::IsSupportedForAudio, false);
+ if (recv_rtp_extensions_ != filtered_extensions) {
+ recv_rtp_extensions_.swap(filtered_extensions);
for (auto& it : recv_streams_) {
it.second->RecreateAudioReceiveStream(recv_rtp_extensions_);
}