summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/api/video_codecs/sdp_video_format.cc')
-rw-r--r--third_party/libwebrtc/api/video_codecs/sdp_video_format.cc171
1 files changed, 171 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc b/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
new file mode 100644
index 0000000000..cb7e98a682
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/sdp_video_format.h"
+
+#include "absl/strings/match.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/video_codecs/av1_profile.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/vp9_profile.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+namespace {
+
+std::string H264GetPacketizationModeOrDefault(
+ const SdpVideoFormat::Parameters& params) {
+ constexpr char kH264FmtpPacketizationMode[] = "packetization-mode";
+ const auto it = params.find(kH264FmtpPacketizationMode);
+ if (it != params.end()) {
+ return it->second;
+ }
+ // If packetization-mode is not present, default to "0".
+ // https://tools.ietf.org/html/rfc6184#section-6.2
+ return "0";
+}
+
+bool H264IsSamePacketizationMode(const SdpVideoFormat::Parameters& left,
+ const SdpVideoFormat::Parameters& right) {
+ return H264GetPacketizationModeOrDefault(left) ==
+ H264GetPacketizationModeOrDefault(right);
+}
+
+// Some (video) codecs are actually families of codecs and rely on parameters
+// to distinguish different incompatible family members.
+bool IsSameCodecSpecific(const SdpVideoFormat& format1,
+ const SdpVideoFormat& format2) {
+ // The assumption when calling this function is that the two formats have the
+ // same name.
+ RTC_DCHECK(absl::EqualsIgnoreCase(format1.name, format2.name));
+
+ VideoCodecType codec_type = PayloadStringToCodecType(format1.name);
+ switch (codec_type) {
+ case kVideoCodecH264:
+ return H264IsSameProfile(format1.parameters, format2.parameters) &&
+ H264IsSamePacketizationMode(format1.parameters,
+ format2.parameters);
+ case kVideoCodecVP9:
+ return VP9IsSameProfile(format1.parameters, format2.parameters);
+ case kVideoCodecAV1:
+ return AV1IsSameProfile(format1.parameters, format2.parameters);
+ default:
+ return true;
+ }
+}
+} // namespace
+
+SdpVideoFormat::SdpVideoFormat(const std::string& name) : name(name) {}
+
+SdpVideoFormat::SdpVideoFormat(const std::string& name,
+ const Parameters& parameters)
+ : name(name), parameters(parameters) {}
+
+SdpVideoFormat::SdpVideoFormat(
+ const std::string& name,
+ const Parameters& parameters,
+ const absl::InlinedVector<ScalabilityMode, kScalabilityModeCount>&
+ scalability_modes)
+ : name(name),
+ parameters(parameters),
+ scalability_modes(scalability_modes) {}
+
+SdpVideoFormat::SdpVideoFormat(const SdpVideoFormat&) = default;
+SdpVideoFormat::SdpVideoFormat(SdpVideoFormat&&) = default;
+SdpVideoFormat& SdpVideoFormat::operator=(const SdpVideoFormat&) = default;
+SdpVideoFormat& SdpVideoFormat::operator=(SdpVideoFormat&&) = default;
+
+SdpVideoFormat::~SdpVideoFormat() = default;
+
+std::string SdpVideoFormat::ToString() const {
+ rtc::StringBuilder builder;
+ builder << "Codec name: " << name << ", parameters: {";
+ for (const auto& kv : parameters) {
+ builder << " " << kv.first << "=" << kv.second;
+ }
+
+ builder << " }";
+ if (!scalability_modes.empty()) {
+ builder << ", scalability_modes: [";
+ bool first = true;
+ for (const auto scalability_mode : scalability_modes) {
+ if (first) {
+ first = false;
+ } else {
+ builder << ", ";
+ }
+ builder << ScalabilityModeToString(scalability_mode);
+ }
+ builder << "]";
+ }
+
+ return builder.str();
+}
+
+bool SdpVideoFormat::IsSameCodec(const SdpVideoFormat& other) const {
+ // Two codecs are considered the same if the name matches (case insensitive)
+ // and certain codec-specific parameters match.
+ return absl::EqualsIgnoreCase(name, other.name) &&
+ IsSameCodecSpecific(*this, other);
+}
+
+bool SdpVideoFormat::IsCodecInList(
+ rtc::ArrayView<const webrtc::SdpVideoFormat> formats) const {
+ for (const auto& format : formats) {
+ if (IsSameCodec(format)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool operator==(const SdpVideoFormat& a, const SdpVideoFormat& b) {
+ return a.name == b.name && a.parameters == b.parameters &&
+ a.scalability_modes == b.scalability_modes;
+}
+
+absl::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
+ rtc::ArrayView<const SdpVideoFormat> supported_formats,
+ const SdpVideoFormat& format) {
+ absl::optional<SdpVideoFormat> res;
+ int best_parameter_match = 0;
+ for (const auto& supported_format : supported_formats) {
+ if (absl::EqualsIgnoreCase(supported_format.name, format.name)) {
+ int matching_parameters = 0;
+ for (const auto& kv : supported_format.parameters) {
+ auto it = format.parameters.find(kv.first);
+ if (it != format.parameters.end() && it->second == kv.second) {
+ matching_parameters += 1;
+ }
+ }
+
+ if (!res || matching_parameters > best_parameter_match) {
+ res = supported_format;
+ best_parameter_match = matching_parameters;
+ }
+ }
+ }
+
+ if (!res) {
+ RTC_LOG(LS_INFO) << "Failed to match SdpVideoFormat " << format.ToString();
+ } else if (*res != format) {
+ RTC_LOG(LS_INFO) << "Matched SdpVideoFormat " << format.ToString()
+ << " with " << res->ToString();
+ }
+
+ return res;
+}
+
+} // namespace webrtc