From 7a3c07b8efe61a2780c998ad33d0e75c4f5c10ba Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 22 Oct 2024 11:32:36 +0000 Subject: [PATCH] Cleanup: Move all comparator tests to codec_comparators_unittests This CL has no functional changes. Bug: webrtc:360058654 Change-Id: I28a9347a5787efd068bc207d4ab72d27cf7400c3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366202 Reviewed-by: Florent Castelli Commit-Queue: Harald Alvestrand Commit-Queue: Florent Castelli Auto-Submit: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#43277} --- media/DEPS | 5 +- media/base/codec_comparators_unittest.cc | 300 +++++++++++++++++++++++ media/base/codec_unittest.cc | 299 +--------------------- 3 files changed, 305 insertions(+), 299 deletions(-) diff --git a/media/DEPS b/media/DEPS index 85b9c7ef3e..736601df27 100644 --- a/media/DEPS +++ b/media/DEPS @@ -42,5 +42,8 @@ specific_include_rules = { ], ".*codec\.h": [ "+absl/strings/str_format.h", - ] + ], + ".*codec_unittest\.cc": [ + "+absl/strings/str_cat.h", + ], } diff --git a/media/base/codec_comparators_unittest.cc b/media/base/codec_comparators_unittest.cc index 9b99785dd3..6f4a1990bf 100644 --- a/media/base/codec_comparators_unittest.cc +++ b/media/base/codec_comparators_unittest.cc @@ -12,6 +12,7 @@ #include #include "api/audio_codecs/audio_format.h" +#include "api/rtp_parameters.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/vp9_profile.h" #include "media/base/codec.h" @@ -204,4 +205,303 @@ INSTANTIATE_TEST_SUITE_P( return info.param.name; }); +TEST(CodecTest, TestCodecMatches) { + // Test a codec with a static payload type. + Codec c0 = cricket::CreateAudioCodec(34, "A", 44100, 1); + EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 1))); + EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0))); + EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0))); + EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 0, 0))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "", 44100, 1))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 1))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 1))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 2))); + EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 2))); + + // Test a codec with a dynamic payload type. + Codec c1 = cricket::CreateAudioCodec(96, "A", 44100, 1); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "A", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "A", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "a", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "a", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(35, "a", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(42, "a", 0, 0))); + EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(65, "a", 0, 0))); + EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(95, "A", 0, 0))); + EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(34, "A", 0, 0))); + EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "", 44100, 2))); + EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "A", 55100, 1))); + + // Test a codec with a dynamic payload type, and auto bitrate. + Codec c2 = cricket::CreateAudioCodec(97, "A", 16000, 1); + // Use default bitrate. + EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); + EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 0))); + // Use explicit bitrate. + EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); + // Backward compatibility with clients that might send "-1" (for default). + EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); + + // Stereo doesn't match channels = 0. + Codec c3 = cricket::CreateAudioCodec(96, "A", 44100, 2); + EXPECT_TRUE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 2))); + EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1))); + EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 0))); +} + +TEST(CodecTest, TestOpusAudioCodecWithDifferentParameters) { + Codec opus_with_fec = cricket::CreateAudioCodec(96, "opus", 48000, 2); + opus_with_fec.params["useinbandfec"] = "1"; + Codec opus_without_fec = cricket::CreateAudioCodec(96, "opus", 48000, 2); + + EXPECT_TRUE(opus_with_fec != opus_without_fec); + // Matches does not compare parameters for audio. + EXPECT_TRUE(opus_with_fec.Matches(opus_without_fec)); + + webrtc::RtpCodecParameters rtp_opus_with_fec = + opus_with_fec.ToCodecParameters(); + // MatchesRtpCodec takes parameters into account. + EXPECT_TRUE(opus_with_fec.MatchesRtpCodec(rtp_opus_with_fec)); + EXPECT_FALSE(opus_without_fec.MatchesRtpCodec(rtp_opus_with_fec)); +} + +TEST(CodecTest, TestVideoCodecMatches) { + // Test a codec with a static payload type. + Codec c0 = cricket::CreateVideoCodec(34, "V"); + EXPECT_TRUE(c0.Matches(cricket::CreateVideoCodec(34, ""))); + EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, ""))); + EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, "V"))); + + // Test a codec with a dynamic payload type. + Codec c1 = cricket::CreateVideoCodec(96, "V"); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "V"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "V"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "v"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "v"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(35, "v"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(42, "v"))); + EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(65, "v"))); + EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(96, ""))); + EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(95, "V"))); + EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(34, "V"))); +} + +TEST(CodecTest, TestVideoCodecMatchesWithDifferentPacketization) { + Codec c0 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName); + Codec c1 = cricket::CreateVideoCodec(101, cricket::kVp8CodecName); + c1.packetization = "raw"; + + EXPECT_TRUE(c0.Matches(c1)); + EXPECT_TRUE(c1.Matches(c0)); +} + +// AV1 codecs compare profile information. +TEST(CodecTest, TestAV1CodecMatches) { + const char kProfile0[] = "0"; + const char kProfile1[] = "1"; + const char kProfile2[] = "2"; + + Codec c_no_profile = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + Codec c_profile0 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + c_profile0.params[cricket::kAv1FmtpProfile] = kProfile0; + Codec c_profile1 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + c_profile1.params[cricket::kAv1FmtpProfile] = kProfile1; + Codec c_profile2 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + c_profile2.params[cricket::kAv1FmtpProfile] = kProfile2; + + // An AV1 entry with no profile specified should be treated as profile-0. + EXPECT_TRUE(c_profile0.Matches(c_no_profile)); + + { + // Two AV1 entries without a profile specified are treated as duplicates. + Codec c_no_profile_eq = + cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq)); + } + + { + // Two AV1 entries with profile 0 specified are treated as duplicates. + Codec c_profile0_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + c_profile0_eq.params[cricket::kAv1FmtpProfile] = kProfile0; + EXPECT_TRUE(c_profile0.Matches(c_profile0_eq)); + } + + { + // Two AV1 entries with profile 1 specified are treated as duplicates. + Codec c_profile1_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); + c_profile1_eq.params[cricket::kAv1FmtpProfile] = kProfile1; + EXPECT_TRUE(c_profile1.Matches(c_profile1_eq)); + } + + // AV1 entries with different profiles (0 and 1) are seen as distinct. + EXPECT_FALSE(c_profile0.Matches(c_profile1)); + EXPECT_FALSE(c_no_profile.Matches(c_profile1)); + + // AV1 entries with different profiles (0 and 2) are seen as distinct. + EXPECT_FALSE(c_profile0.Matches(c_profile2)); + EXPECT_FALSE(c_no_profile.Matches(c_profile2)); +} + +// VP9 codecs compare profile information. +TEST(CodecTest, TestVP9CodecMatches) { + const char kProfile0[] = "0"; + const char kProfile2[] = "2"; + + Codec c_no_profile = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); + Codec c_profile0 = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); + c_profile0.params[webrtc::kVP9FmtpProfileId] = kProfile0; + + EXPECT_TRUE(c_profile0.Matches(c_no_profile)); + + { + Codec c_profile0_eq = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); + c_profile0_eq.params[webrtc::kVP9FmtpProfileId] = kProfile0; + EXPECT_TRUE(c_profile0.Matches(c_profile0_eq)); + } + + { + Codec c_profile2 = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); + c_profile2.params[webrtc::kVP9FmtpProfileId] = kProfile2; + EXPECT_FALSE(c_profile0.Matches(c_profile2)); + EXPECT_FALSE(c_no_profile.Matches(c_profile2)); + } + + { + Codec c_no_profile_eq = + cricket::CreateVideoCodec(95, cricket::kVp9CodecName); + EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq)); + } +} + +// Matching H264 codecs also need to have matching profile-level-id and +// packetization-mode. +TEST(CodecTest, TestH264CodecMatches) { + const char kProfileLevelId1[] = "42e01f"; + const char kProfileLevelId2[] = "42a01e"; + const char kProfileLevelId3[] = "42e01e"; + + Codec pli_1_pm_0 = cricket::CreateVideoCodec(95, "H264"); + pli_1_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; + pli_1_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0"; + + { + Codec pli_1_pm_blank = cricket::CreateVideoCodec(95, "H264"); + pli_1_pm_blank.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; + pli_1_pm_blank.params.erase( + pli_1_pm_blank.params.find(cricket::kH264FmtpPacketizationMode)); + + // Matches since if packetization-mode is not specified it defaults to "0". + EXPECT_TRUE(pli_1_pm_0.Matches(pli_1_pm_blank)); + + // MatchesRtpCodec does exact comparison of parameters. + EXPECT_FALSE( + pli_1_pm_0.MatchesRtpCodec(pli_1_pm_blank.ToCodecParameters())); + } + + { + Codec pli_1_pm_1 = cricket::CreateVideoCodec(95, "H264"); + pli_1_pm_1.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; + pli_1_pm_1.params[cricket::kH264FmtpPacketizationMode] = "1"; + + // Does not match since packetization-mode is different. + EXPECT_FALSE(pli_1_pm_0.Matches(pli_1_pm_1)); + + EXPECT_FALSE(pli_1_pm_0.MatchesRtpCodec(pli_1_pm_1.ToCodecParameters())); + } + + { + Codec pli_2_pm_0 = cricket::CreateVideoCodec(95, "H264"); + pli_2_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId2; + pli_2_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0"; + + // Does not match since profile-level-id is different. + EXPECT_FALSE(pli_1_pm_0.Matches(pli_2_pm_0)); + + EXPECT_FALSE(pli_1_pm_0.MatchesRtpCodec(pli_2_pm_0.ToCodecParameters())); + } + + { + Codec pli_3_pm_0_asym = cricket::CreateVideoCodec(95, "H264"); + pli_3_pm_0_asym.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId3; + pli_3_pm_0_asym.params[cricket::kH264FmtpPacketizationMode] = "0"; + + // Does match, profile-level-id is different but the level is not compared. + // and the profile matches. + EXPECT_TRUE(pli_1_pm_0.Matches(pli_3_pm_0_asym)); + + EXPECT_FALSE( + pli_1_pm_0.MatchesRtpCodec(pli_3_pm_0_asym.ToCodecParameters())); + + // + } +} + +#ifdef RTC_ENABLE_H265 +// Matching H.265 codecs should have matching profile/tier/level and tx-mode. +TEST(CodecTest, TestH265CodecMatches) { + constexpr char kProfile1[] = "1"; + constexpr char kTier1[] = "1"; + constexpr char kLevel3_1[] = "93"; + constexpr char kLevel4[] = "120"; + constexpr char kTxMrst[] = "MRST"; + + Codec c_ptl_blank = cricket::CreateVideoCodec(95, cricket::kH265CodecName); + + { + Codec c_profile_1 = cricket::CreateVideoCodec(95, cricket::kH265CodecName); + c_profile_1.params[cricket::kH265FmtpProfileId] = kProfile1; + + // Matches since profile-id unspecified defaults to "1". + EXPECT_TRUE(c_ptl_blank.Matches(c_profile_1)); + } + + { + Codec c_tier_flag_1 = + cricket::CreateVideoCodec(95, cricket::kH265CodecName); + c_tier_flag_1.params[cricket::kH265FmtpTierFlag] = kTier1; + + // Does not match since profile-space unspecified defaults to "0". + EXPECT_FALSE(c_ptl_blank.Matches(c_tier_flag_1)); + } + + { + Codec c_level_id_3_1 = + cricket::CreateVideoCodec(95, cricket::kH265CodecName); + c_level_id_3_1.params[cricket::kH265FmtpLevelId] = kLevel3_1; + + // Matches since level-id unspecified defaults to "93". + EXPECT_TRUE(c_ptl_blank.Matches(c_level_id_3_1)); + } + + { + Codec c_level_id_4 = cricket::CreateVideoCodec(95, cricket::kH265CodecName); + c_level_id_4.params[cricket::kH265FmtpLevelId] = kLevel4; + + // Matches since we ignore level-id when matching H.265 codecs. + EXPECT_TRUE(c_ptl_blank.Matches(c_level_id_4)); + } + + { + Codec c_tx_mode_mrst = + cricket::CreateVideoCodec(95, cricket::kH265CodecName); + c_tx_mode_mrst.params[cricket::kH265FmtpTxMode] = kTxMrst; + + // Does not match since tx-mode implies to "SRST" and must be not specified + // when it is the only mode supported: + // https://datatracker.ietf.org/doc/html/draft-ietf-avtcore-hevc-webrtc + EXPECT_FALSE(c_ptl_blank.Matches(c_tx_mode_mrst)); + } +} +#endif + +TEST(CodecTest, TestMatchesRtpCodecRtx) { + const Codec rtx_codec_1 = cricket::CreateVideoRtxCodec(96, 120); + const Codec rtx_codec_2 = cricket::CreateVideoRtxCodec(96, 121); + EXPECT_TRUE(rtx_codec_1.Matches(rtx_codec_2)); + // MatchesRtpCodec ignores the different associated payload type (apt) for + // RTX. + EXPECT_TRUE(rtx_codec_1.MatchesRtpCodec(rtx_codec_2.ToCodecParameters())); +} + } // namespace webrtc diff --git a/media/base/codec_unittest.cc b/media/base/codec_unittest.cc index b3a9a910eb..1c91288a1c 100644 --- a/media/base/codec_unittest.cc +++ b/media/base/codec_unittest.cc @@ -14,6 +14,7 @@ #include #include +#include "absl/strings/str_cat.h" #include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/video_codecs/h264_profile_level_id.h" @@ -106,67 +107,6 @@ TEST(CodecTest, TestAudioCodecOperators) { EXPECT_EQ(c13, c10); } -TEST(CodecTest, TestCodecMatches) { - // Test a codec with a static payload type. - Codec c0 = cricket::CreateAudioCodec(34, "A", 44100, 1); - EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 1))); - EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0))); - EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0))); - EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 0, 0))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "", 44100, 1))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 1))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 1))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 2))); - EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 2))); - - // Test a codec with a dynamic payload type. - Codec c1 = cricket::CreateAudioCodec(96, "A", 44100, 1); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "A", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "A", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "a", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "a", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(35, "a", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(42, "a", 0, 0))); - EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(65, "a", 0, 0))); - EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(95, "A", 0, 0))); - EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(34, "A", 0, 0))); - EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "", 44100, 2))); - EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "A", 55100, 1))); - - // Test a codec with a dynamic payload type, and auto bitrate. - Codec c2 = cricket::CreateAudioCodec(97, "A", 16000, 1); - // Use default bitrate. - EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); - EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 0))); - // Use explicit bitrate. - EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); - // Backward compatibility with clients that might send "-1" (for default). - EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1))); - - // Stereo doesn't match channels = 0. - Codec c3 = cricket::CreateAudioCodec(96, "A", 44100, 2); - EXPECT_TRUE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 2))); - EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1))); - EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 0))); -} - -TEST(CodecTest, TestOpusAudioCodecWithDifferentParameters) { - Codec opus_with_fec = cricket::CreateAudioCodec(96, "opus", 48000, 2); - opus_with_fec.params["useinbandfec"] = "1"; - Codec opus_without_fec = cricket::CreateAudioCodec(96, "opus", 48000, 2); - - EXPECT_TRUE(opus_with_fec != opus_without_fec); - // Matches does not compare parameters for audio. - EXPECT_TRUE(opus_with_fec.Matches(opus_without_fec)); - - webrtc::RtpCodecParameters rtp_opus_with_fec = - opus_with_fec.ToCodecParameters(); - // MatchesRtpCodec takes parameters into account. - EXPECT_TRUE(opus_with_fec.MatchesRtpCodec(rtp_opus_with_fec)); - EXPECT_FALSE(opus_without_fec.MatchesRtpCodec(rtp_opus_with_fec)); -} - TEST(CodecTest, TestVideoCodecOperators) { Codec c0 = cricket::CreateVideoCodec(96, "V"); Codec c1 = cricket::CreateVideoCodec(95, "V"); @@ -208,234 +148,6 @@ TEST(CodecTest, TestVideoCodecEqualsWithDifferentPacketization) { EXPECT_EQ(c2, c2); } -TEST(CodecTest, TestVideoCodecMatches) { - // Test a codec with a static payload type. - Codec c0 = cricket::CreateVideoCodec(34, "V"); - EXPECT_TRUE(c0.Matches(cricket::CreateVideoCodec(34, ""))); - EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, ""))); - EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, "V"))); - - // Test a codec with a dynamic payload type. - Codec c1 = cricket::CreateVideoCodec(96, "V"); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "V"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "V"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "v"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "v"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(35, "v"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(42, "v"))); - EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(65, "v"))); - EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(96, ""))); - EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(95, "V"))); - EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(34, "V"))); -} - -TEST(CodecTest, TestVideoCodecMatchesWithDifferentPacketization) { - Codec c0 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName); - Codec c1 = cricket::CreateVideoCodec(101, cricket::kVp8CodecName); - c1.packetization = "raw"; - - EXPECT_TRUE(c0.Matches(c1)); - EXPECT_TRUE(c1.Matches(c0)); -} - -// AV1 codecs compare profile information. -TEST(CodecTest, TestAV1CodecMatches) { - const char kProfile0[] = "0"; - const char kProfile1[] = "1"; - const char kProfile2[] = "2"; - - Codec c_no_profile = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - Codec c_profile0 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile0.params[cricket::kAv1FmtpProfile] = kProfile0; - Codec c_profile1 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile1.params[cricket::kAv1FmtpProfile] = kProfile1; - Codec c_profile2 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile2.params[cricket::kAv1FmtpProfile] = kProfile2; - - // An AV1 entry with no profile specified should be treated as profile-0. - EXPECT_TRUE(c_profile0.Matches(c_no_profile)); - - { - // Two AV1 entries without a profile specified are treated as duplicates. - Codec c_no_profile_eq = - cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq)); - } - - { - // Two AV1 entries with profile 0 specified are treated as duplicates. - Codec c_profile0_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile0_eq.params[cricket::kAv1FmtpProfile] = kProfile0; - EXPECT_TRUE(c_profile0.Matches(c_profile0_eq)); - } - - { - // Two AV1 entries with profile 1 specified are treated as duplicates. - Codec c_profile1_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile1_eq.params[cricket::kAv1FmtpProfile] = kProfile1; - EXPECT_TRUE(c_profile1.Matches(c_profile1_eq)); - } - - // AV1 entries with different profiles (0 and 1) are seen as distinct. - EXPECT_FALSE(c_profile0.Matches(c_profile1)); - EXPECT_FALSE(c_no_profile.Matches(c_profile1)); - - // AV1 entries with different profiles (0 and 2) are seen as distinct. - EXPECT_FALSE(c_profile0.Matches(c_profile2)); - EXPECT_FALSE(c_no_profile.Matches(c_profile2)); -} - -// VP9 codecs compare profile information. -TEST(CodecTest, TestVP9CodecMatches) { - const char kProfile0[] = "0"; - const char kProfile2[] = "2"; - - Codec c_no_profile = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); - Codec c_profile0 = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); - c_profile0.params[webrtc::kVP9FmtpProfileId] = kProfile0; - - EXPECT_TRUE(c_profile0.Matches(c_no_profile)); - - { - Codec c_profile0_eq = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); - c_profile0_eq.params[webrtc::kVP9FmtpProfileId] = kProfile0; - EXPECT_TRUE(c_profile0.Matches(c_profile0_eq)); - } - - { - Codec c_profile2 = cricket::CreateVideoCodec(95, cricket::kVp9CodecName); - c_profile2.params[webrtc::kVP9FmtpProfileId] = kProfile2; - EXPECT_FALSE(c_profile0.Matches(c_profile2)); - EXPECT_FALSE(c_no_profile.Matches(c_profile2)); - } - - { - Codec c_no_profile_eq = - cricket::CreateVideoCodec(95, cricket::kVp9CodecName); - EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq)); - } -} - -// Matching H264 codecs also need to have matching profile-level-id and -// packetization-mode. -TEST(CodecTest, TestH264CodecMatches) { - const char kProfileLevelId1[] = "42e01f"; - const char kProfileLevelId2[] = "42a01e"; - const char kProfileLevelId3[] = "42e01e"; - - Codec pli_1_pm_0 = cricket::CreateVideoCodec(95, "H264"); - pli_1_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; - pli_1_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0"; - - { - Codec pli_1_pm_blank = cricket::CreateVideoCodec(95, "H264"); - pli_1_pm_blank.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; - pli_1_pm_blank.params.erase( - pli_1_pm_blank.params.find(cricket::kH264FmtpPacketizationMode)); - - // Matches since if packetization-mode is not specified it defaults to "0". - EXPECT_TRUE(pli_1_pm_0.Matches(pli_1_pm_blank)); - - // MatchesRtpCodec does exact comparison of parameters. - EXPECT_FALSE( - pli_1_pm_0.MatchesRtpCodec(pli_1_pm_blank.ToCodecParameters())); - } - - { - Codec pli_1_pm_1 = cricket::CreateVideoCodec(95, "H264"); - pli_1_pm_1.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1; - pli_1_pm_1.params[cricket::kH264FmtpPacketizationMode] = "1"; - - // Does not match since packetization-mode is different. - EXPECT_FALSE(pli_1_pm_0.Matches(pli_1_pm_1)); - - EXPECT_FALSE(pli_1_pm_0.MatchesRtpCodec(pli_1_pm_1.ToCodecParameters())); - } - - { - Codec pli_2_pm_0 = cricket::CreateVideoCodec(95, "H264"); - pli_2_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId2; - pli_2_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0"; - - // Does not match since profile-level-id is different. - EXPECT_FALSE(pli_1_pm_0.Matches(pli_2_pm_0)); - - EXPECT_FALSE(pli_1_pm_0.MatchesRtpCodec(pli_2_pm_0.ToCodecParameters())); - } - - { - Codec pli_3_pm_0_asym = cricket::CreateVideoCodec(95, "H264"); - pli_3_pm_0_asym.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId3; - pli_3_pm_0_asym.params[cricket::kH264FmtpPacketizationMode] = "0"; - - // Does match, profile-level-id is different but the level is not compared. - // and the profile matches. - EXPECT_TRUE(pli_1_pm_0.Matches(pli_3_pm_0_asym)); - - EXPECT_FALSE( - pli_1_pm_0.MatchesRtpCodec(pli_3_pm_0_asym.ToCodecParameters())); - - // - } -} - -#ifdef RTC_ENABLE_H265 -// Matching H.265 codecs should have matching profile/tier/level and tx-mode. -TEST(CodecTest, TestH265CodecMatches) { - constexpr char kProfile1[] = "1"; - constexpr char kTier1[] = "1"; - constexpr char kLevel3_1[] = "93"; - constexpr char kLevel4[] = "120"; - constexpr char kTxMrst[] = "MRST"; - - Codec c_ptl_blank = cricket::CreateVideoCodec(95, cricket::kH265CodecName); - - { - Codec c_profile_1 = cricket::CreateVideoCodec(95, cricket::kH265CodecName); - c_profile_1.params[cricket::kH265FmtpProfileId] = kProfile1; - - // Matches since profile-id unspecified defaults to "1". - EXPECT_TRUE(c_ptl_blank.Matches(c_profile_1)); - } - - { - Codec c_tier_flag_1 = - cricket::CreateVideoCodec(95, cricket::kH265CodecName); - c_tier_flag_1.params[cricket::kH265FmtpTierFlag] = kTier1; - - // Does not match since profile-space unspecified defaults to "0". - EXPECT_FALSE(c_ptl_blank.Matches(c_tier_flag_1)); - } - - { - Codec c_level_id_3_1 = - cricket::CreateVideoCodec(95, cricket::kH265CodecName); - c_level_id_3_1.params[cricket::kH265FmtpLevelId] = kLevel3_1; - - // Matches since level-id unspecified defaults to "93". - EXPECT_TRUE(c_ptl_blank.Matches(c_level_id_3_1)); - } - - { - Codec c_level_id_4 = cricket::CreateVideoCodec(95, cricket::kH265CodecName); - c_level_id_4.params[cricket::kH265FmtpLevelId] = kLevel4; - - // Matches since we ignore level-id when matching H.265 codecs. - EXPECT_TRUE(c_ptl_blank.Matches(c_level_id_4)); - } - - { - Codec c_tx_mode_mrst = - cricket::CreateVideoCodec(95, cricket::kH265CodecName); - c_tx_mode_mrst.params[cricket::kH265FmtpTxMode] = kTxMrst; - - // Does not match since tx-mode implies to "SRST" and must be not specified - // when it is the only mode supported: - // https://datatracker.ietf.org/doc/html/draft-ietf-avtcore-hevc-webrtc - EXPECT_FALSE(c_ptl_blank.Matches(c_tx_mode_mrst)); - } -} -#endif TEST(CodecTest, TestSetParamGetParamAndRemoveParam) { Codec codec = cricket::CreateAudioCodec(0, "foo", 22222, 2); @@ -502,15 +214,6 @@ TEST(CodecTest, TestCreateRtxCodec) { EXPECT_EQ(120, associated_payload_type); } -TEST(CodecTest, TestMatchesRtpCodecRtx) { - const Codec rtx_codec_1 = cricket::CreateVideoRtxCodec(96, 120); - const Codec rtx_codec_2 = cricket::CreateVideoRtxCodec(96, 121); - EXPECT_TRUE(rtx_codec_1.Matches(rtx_codec_2)); - // MatchesRtpCodec ignores the different associated payload type (apt) for - // RTX. - EXPECT_TRUE(rtx_codec_1.MatchesRtpCodec(rtx_codec_2.ToCodecParameters())); -} - TEST(CodecTest, TestValidateCodecFormat) { const Codec codec = cricket::CreateVideoCodec(96, "V"); ASSERT_TRUE(codec.ValidateCodecFormat());