diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/api/video_codecs/sdp_video_format.cc | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.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 '')
-rw-r--r-- | third_party/libwebrtc/api/video_codecs/sdp_video_format.cc | 171 |
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 |