diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index 173d49ade2..e8f9815a45 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -75,6 +75,7 @@ rtc_library("video_codecs_api") { "../../api:array_view", "../../modules/video_coding:codec_globals_headers", "../../rtc_base:checks", + "../../rtc_base:logging", "../../rtc_base:macromagic", "../../rtc_base:refcount", "../../rtc_base:stringutils", diff --git a/api/video_codecs/sdp_video_format.cc b/api/video_codecs/sdp_video_format.cc index 3543806b51..cb7e98a682 100644 --- a/api/video_codecs/sdp_video_format.cc +++ b/api/video_codecs/sdp_video_format.cc @@ -11,11 +11,14 @@ #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 { @@ -133,4 +136,36 @@ bool operator==(const SdpVideoFormat& a, const SdpVideoFormat& b) { a.scalability_modes == b.scalability_modes; } +absl::optional FuzzyMatchSdpVideoFormat( + rtc::ArrayView supported_formats, + const SdpVideoFormat& format) { + absl::optional 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 diff --git a/api/video_codecs/sdp_video_format.h b/api/video_codecs/sdp_video_format.h index 850632eb9e..faaa66c241 100644 --- a/api/video_codecs/sdp_video_format.h +++ b/api/video_codecs/sdp_video_format.h @@ -15,6 +15,7 @@ #include #include "absl/container/inlined_vector.h" +#include "absl/types/optional.h" #include "api/array_view.h" #include "api/video_codecs/scalability_mode.h" #include "rtc_base/system/rtc_export.h" @@ -61,6 +62,14 @@ struct RTC_EXPORT SdpVideoFormat { absl::InlinedVector scalability_modes; }; +// For not so good reasons sometimes additional parameters are added to an +// SdpVideoFormat, which makes instances that should compare equal to not match +// anymore. Until we stop misusing SdpVideoFormats provide this convenience +// function to perform fuzzy matching. +absl::optional FuzzyMatchSdpVideoFormat( + rtc::ArrayView supported_formats, + const SdpVideoFormat& format); + } // namespace webrtc #endif // API_VIDEO_CODECS_SDP_VIDEO_FORMAT_H_ diff --git a/media/engine/internal_encoder_factory.cc b/media/engine/internal_encoder_factory.cc index 4243f52481..7b5fc24e0a 100644 --- a/media/engine/internal_encoder_factory.cc +++ b/media/engine/internal_encoder_factory.cc @@ -38,32 +38,6 @@ using Factory = webrtc::LibaomAv1EncoderTemplateAdapter, #endif webrtc::LibvpxVp9EncoderTemplateAdapter>; - -absl::optional MatchOriginalFormat( - const SdpVideoFormat& format) { - const auto supported_formats = Factory().GetSupportedFormats(); - - absl::optional 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; - } - } - } - - return res; -} } // namespace std::vector InternalEncoderFactory::GetSupportedFormats() @@ -73,7 +47,8 @@ std::vector InternalEncoderFactory::GetSupportedFormats() std::unique_ptr InternalEncoderFactory::CreateVideoEncoder( const SdpVideoFormat& format) { - auto original_format = MatchOriginalFormat(format); + auto original_format = + FuzzyMatchSdpVideoFormat(Factory().GetSupportedFormats(), format); return original_format ? Factory().CreateVideoEncoder(*original_format) : nullptr; } @@ -81,7 +56,8 @@ std::unique_ptr InternalEncoderFactory::CreateVideoEncoder( VideoEncoderFactory::CodecSupport InternalEncoderFactory::QueryCodecSupport( const SdpVideoFormat& format, absl::optional scalability_mode) const { - auto original_format = MatchOriginalFormat(format); + auto original_format = + FuzzyMatchSdpVideoFormat(Factory().GetSupportedFormats(), format); return original_format ? Factory().QueryCodecSupport(*original_format, scalability_mode) : VideoEncoderFactory::CodecSupport{.is_supported = false};