Sync definitions of IsSameCodecSpecific

until the code duplication can be removed which requires breaking
up the circular dependency.

BUG=webrtc:15847

Change-Id: Icc5f27dfcda26b1fcf16b19f79005d8b52fb6af3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339903
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#41771}
diff --git a/api/video_codecs/sdp_video_format.cc b/api/video_codecs/sdp_video_format.cc
index 5abde8f..08dfed4 100644
--- a/api/video_codecs/sdp_video_format.cc
+++ b/api/video_codecs/sdp_video_format.cc
@@ -29,6 +29,8 @@
 
 namespace {
 
+// TODO(bugs.webrtc.org/15847): remove code duplication of IsSameCodecSpecific
+// in media/base/codec.cc
 std::string GetFmtpParameterOrDefault(const CodecParameterMap& params,
                                       const std::string& name,
                                       const std::string& default_value) {
@@ -74,29 +76,45 @@
   return AV1GetLevelIdxOrDefault(left) == AV1GetLevelIdxOrDefault(right);
 }
 
+#ifdef RTC_ENABLE_H265
+std::string GetH265TxModeOrDefault(const CodecParameterMap& params) {
+  // If TxMode is not present, a value of "SRST" must be inferred.
+  // https://tools.ietf.org/html/rfc7798@section-7.1
+  return GetFmtpParameterOrDefault(params, cricket::kH265FmtpTxMode, "SRST");
+}
+
+bool IsSameH265TxMode(const CodecParameterMap& left,
+                      const CodecParameterMap& right) {
+  return absl::EqualsIgnoreCase(GetH265TxModeOrDefault(left),
+                                GetH265TxModeOrDefault(right));
+}
+#endif
+
 // 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) {
+bool IsSameCodecSpecific(const std::string& name1,
+                         const CodecParameterMap& params1,
+                         const std::string& name2,
+                         const CodecParameterMap& params2) {
   // The assumption when calling this function is that the two formats have the
   // same name.
-  RTC_DCHECK(absl::EqualsIgnoreCase(format1.name, format2.name));
+  RTC_DCHECK(absl::EqualsIgnoreCase(name1, name2));
 
-  VideoCodecType codec_type = PayloadStringToCodecType(format1.name);
+  VideoCodecType codec_type = PayloadStringToCodecType(name1);
   switch (codec_type) {
     case kVideoCodecH264:
-      return H264IsSameProfile(format1.parameters, format2.parameters) &&
-             H264IsSamePacketizationMode(format1.parameters,
-                                         format2.parameters);
+      return H264IsSameProfile(params1, params2) &&
+             H264IsSamePacketizationMode(params1, params2);
     case kVideoCodecVP9:
-      return VP9IsSameProfile(format1.parameters, format2.parameters);
+      return VP9IsSameProfile(params1, params2);
     case kVideoCodecAV1:
-      return AV1IsSameProfile(format1.parameters, format2.parameters) &&
-             AV1IsSameTier(format1.parameters, format2.parameters) &&
-             AV1IsSameLevelIdx(format1.parameters, format2.parameters);
+      return AV1IsSameProfile(params1, params2) &&
+             AV1IsSameTier(params1, params2) &&
+             AV1IsSameLevelIdx(params1, params2);
 #ifdef RTC_ENABLE_H265
     case kVideoCodecH265:
-      return H265IsSameProfileTierLevel(format1.parameters, format2.parameters);
+      return H265IsSameProfileTierLevel(params1, params2) &&
+             IsSameH265TxMode(params1, params2);
 #endif
     default:
       return true;
@@ -156,7 +174,7 @@
   // 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);
+         IsSameCodecSpecific(name, parameters, other.name, other.parameters);
 }
 
 bool SdpVideoFormat::IsCodecInList(
diff --git a/media/base/codec.cc b/media/base/codec.cc
index 8abc865..2e7cc6a 100644
--- a/media/base/codec.cc
+++ b/media/base/codec.cc
@@ -28,32 +28,59 @@
 namespace cricket {
 namespace {
 
-std::string GetH264PacketizationModeOrDefault(
-    const webrtc::CodecParameterMap& params) {
-  auto it = params.find(kH264FmtpPacketizationMode);
+// TODO(bugs.webrtc.org/15847): remove code duplication of IsSameCodecSpecific
+// in api/video_codecs/sdp_video_format.cc
+std::string GetFmtpParameterOrDefault(const webrtc::CodecParameterMap& params,
+                                      const std::string& name,
+                                      const std::string& default_value) {
+  const auto it = params.find(name);
   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";
+  return default_value;
 }
 
-bool IsSameH264PacketizationMode(const webrtc::CodecParameterMap& left,
+std::string H264GetPacketizationModeOrDefault(
+    const webrtc::CodecParameterMap& params) {
+  // If packetization-mode is not present, default to "0".
+  // https://tools.ietf.org/html/rfc6184#section-6.2
+  return GetFmtpParameterOrDefault(params, cricket::kH264FmtpPacketizationMode,
+                                   "0");
+}
+
+bool H264IsSamePacketizationMode(const webrtc::CodecParameterMap& left,
                                  const webrtc::CodecParameterMap& right) {
-  return GetH264PacketizationModeOrDefault(left) ==
-         GetH264PacketizationModeOrDefault(right);
+  return H264GetPacketizationModeOrDefault(left) ==
+         H264GetPacketizationModeOrDefault(right);
+}
+
+std::string AV1GetTierOrDefault(const webrtc::CodecParameterMap& params) {
+  // If the parameter is not present, the tier MUST be inferred to be 0.
+  // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters
+  return GetFmtpParameterOrDefault(params, cricket::kAv1FmtpTier, "0");
+}
+
+bool AV1IsSameTier(const webrtc::CodecParameterMap& left,
+                   const webrtc::CodecParameterMap& right) {
+  return AV1GetTierOrDefault(left) == AV1GetTierOrDefault(right);
+}
+
+std::string AV1GetLevelIdxOrDefault(const webrtc::CodecParameterMap& params) {
+  // If the parameter is not present, it MUST be inferred to be 5 (level 3.1).
+  // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters
+  return GetFmtpParameterOrDefault(params, cricket::kAv1FmtpLevelIdx, "5");
+}
+
+bool AV1IsSameLevelIdx(const webrtc::CodecParameterMap& left,
+                       const webrtc::CodecParameterMap& right) {
+  return AV1GetLevelIdxOrDefault(left) == AV1GetLevelIdxOrDefault(right);
 }
 
 #ifdef RTC_ENABLE_H265
 std::string GetH265TxModeOrDefault(const webrtc::CodecParameterMap& params) {
-  auto it = params.find(kH265FmtpTxMode);
-  if (it != params.end()) {
-    return it->second;
-  }
   // If TxMode is not present, a value of "SRST" must be inferred.
   // https://tools.ietf.org/html/rfc7798@section-7.1
-  return "SRST";
+  return GetFmtpParameterOrDefault(params, kH265FmtpTxMode, "SRST");
 }
 
 bool IsSameH265TxMode(const webrtc::CodecParameterMap& left,
@@ -76,11 +103,13 @@
   };
   if (either_name_matches(kH264CodecName))
     return webrtc::H264IsSameProfile(params1, params2) &&
-           IsSameH264PacketizationMode(params1, params2);
+           H264IsSamePacketizationMode(params1, params2);
   if (either_name_matches(kVp9CodecName))
     return webrtc::VP9IsSameProfile(params1, params2);
   if (either_name_matches(kAv1CodecName))
-    return webrtc::AV1IsSameProfile(params1, params2);
+    return webrtc::AV1IsSameProfile(params1, params2) &&
+           AV1IsSameTier(params1, params2) &&
+           AV1IsSameLevelIdx(params1, params2);
 #ifdef RTC_ENABLE_H265
   if (either_name_matches(kH265CodecName)) {
     return webrtc::H265IsSameProfileTierLevel(params1, params2) &&