• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2009 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "media/base/codec.h"
12 
13 #include <tuple>
14 
15 #include "common_types.h"  // NOLINT(build/include)
16 #include "media/base/h264_profile_level_id.h"
17 #include "media/base/vp9_profile.h"
18 #include "modules/video_coding/codecs/h264/include/h264.h"
19 #include "rtc_base/gunit.h"
20 
21 using cricket::AudioCodec;
22 using cricket::Codec;
23 using cricket::DataCodec;
24 using cricket::FeedbackParam;
25 using cricket::kCodecParamAssociatedPayloadType;
26 using cricket::kCodecParamMaxBitrate;
27 using cricket::kCodecParamMinBitrate;
28 using cricket::VideoCodec;
29 
30 class TestCodec : public Codec {
31  public:
TestCodec(int id,const std::string & name,int clockrate)32   TestCodec(int id, const std::string& name, int clockrate)
33       : Codec(id, name, clockrate) {}
TestCodec()34   TestCodec() : Codec() {}
TestCodec(const TestCodec & c)35   TestCodec(const TestCodec& c) : Codec(c) {}
36 };
37 
TEST(CodecTest,TestCodecOperators)38 TEST(CodecTest, TestCodecOperators) {
39   TestCodec c0(96, "D", 1000);
40   c0.SetParam("a", 1);
41 
42   TestCodec c1 = c0;
43   EXPECT_TRUE(c1 == c0);
44 
45   int param_value0;
46   int param_value1;
47   EXPECT_TRUE(c0.GetParam("a", &param_value0));
48   EXPECT_TRUE(c1.GetParam("a", &param_value1));
49   EXPECT_EQ(param_value0, param_value1);
50 
51   c1.id = 86;
52   EXPECT_TRUE(c0 != c1);
53 
54   c1 = c0;
55   c1.name = "x";
56   EXPECT_TRUE(c0 != c1);
57 
58   c1 = c0;
59   c1.clockrate = 2000;
60   EXPECT_TRUE(c0 != c1);
61 
62   c1 = c0;
63   c1.SetParam("a", 2);
64   EXPECT_TRUE(c0 != c1);
65 
66   TestCodec c5;
67   TestCodec c6(0, "", 0);
68   EXPECT_TRUE(c5 == c6);
69 }
70 
TEST(CodecTest,TestAudioCodecOperators)71 TEST(CodecTest, TestAudioCodecOperators) {
72   AudioCodec c0(96, "A", 44100, 20000, 2);
73   AudioCodec c1(95, "A", 44100, 20000, 2);
74   AudioCodec c2(96, "x", 44100, 20000, 2);
75   AudioCodec c3(96, "A", 48000, 20000, 2);
76   AudioCodec c4(96, "A", 44100, 10000, 2);
77   AudioCodec c5(96, "A", 44100, 20000, 1);
78   EXPECT_NE(c0, c1);
79   EXPECT_NE(c0, c2);
80   EXPECT_NE(c0, c3);
81   EXPECT_NE(c0, c4);
82   EXPECT_NE(c0, c5);
83 
84   AudioCodec c7;
85   AudioCodec c8(0, "", 0, 0, 0);
86   AudioCodec c9 = c0;
87   EXPECT_EQ(c8, c7);
88   EXPECT_NE(c9, c7);
89   EXPECT_EQ(c9, c0);
90 
91   AudioCodec c10(c0);
92   AudioCodec c11(c0);
93   AudioCodec c12(c0);
94   AudioCodec c13(c0);
95   c10.params["x"] = "abc";
96   c11.params["x"] = "def";
97   c12.params["y"] = "abc";
98   c13.params["x"] = "abc";
99   EXPECT_NE(c10, c0);
100   EXPECT_NE(c11, c0);
101   EXPECT_NE(c11, c10);
102   EXPECT_NE(c12, c0);
103   EXPECT_NE(c12, c10);
104   EXPECT_NE(c12, c11);
105   EXPECT_EQ(c13, c10);
106 }
107 
TEST(CodecTest,TestAudioCodecMatches)108 TEST(CodecTest, TestAudioCodecMatches) {
109   // Test a codec with a static payload type.
110   AudioCodec c0(95, "A", 44100, 20000, 1);
111   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 1)));
112   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 0)));
113   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 0, 0)));
114   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 0, 0, 0)));
115   EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 1)));
116   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 1)));
117   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 1)));
118   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2)));
119   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 2)));
120 
121   // Test a codec with a dynamic payload type.
122   AudioCodec c1(96, "A", 44100, 20000, 1);
123   EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0)));
124   EXPECT_TRUE(c1.Matches(AudioCodec(97, "A", 0, 0, 0)));
125   EXPECT_TRUE(c1.Matches(AudioCodec(96, "a", 0, 0, 0)));
126   EXPECT_TRUE(c1.Matches(AudioCodec(97, "a", 0, 0, 0)));
127   EXPECT_FALSE(c1.Matches(AudioCodec(95, "A", 0, 0, 0)));
128   EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2)));
129   EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1)));
130 
131   // Test a codec with a dynamic payload type, and auto bitrate.
132   AudioCodec c2(97, "A", 16000, 0, 1);
133   // Use default bitrate.
134   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1)));
135   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0)));
136   // Use explicit bitrate.
137   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1)));
138   // Backward compatibility with clients that might send "-1" (for default).
139   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1)));
140 
141   // Stereo doesn't match channels = 0.
142   AudioCodec c3(96, "A", 44100, 20000, 2);
143   EXPECT_TRUE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 2)));
144   EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 1)));
145   EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 0)));
146 }
147 
TEST(CodecTest,TestVideoCodecOperators)148 TEST(CodecTest, TestVideoCodecOperators) {
149   VideoCodec c0(96, "V");
150   VideoCodec c1(95, "V");
151   VideoCodec c2(96, "x");
152 
153   EXPECT_TRUE(c0 != c1);
154   EXPECT_TRUE(c0 != c2);
155 
156   VideoCodec c7;
157   VideoCodec c8(0, "");
158   VideoCodec c9 = c0;
159   EXPECT_TRUE(c8 == c7);
160   EXPECT_TRUE(c9 != c7);
161   EXPECT_TRUE(c9 == c0);
162 
163   VideoCodec c10(c0);
164   VideoCodec c11(c0);
165   VideoCodec c12(c0);
166   VideoCodec c13(c0);
167   c10.params["x"] = "abc";
168   c11.params["x"] = "def";
169   c12.params["y"] = "abc";
170   c13.params["x"] = "abc";
171   EXPECT_TRUE(c10 != c0);
172   EXPECT_TRUE(c11 != c0);
173   EXPECT_TRUE(c11 != c10);
174   EXPECT_TRUE(c12 != c0);
175   EXPECT_TRUE(c12 != c10);
176   EXPECT_TRUE(c12 != c11);
177   EXPECT_TRUE(c13 == c10);
178 }
179 
TEST(CodecTest,TestVideoCodecIntersectPacketization)180 TEST(CodecTest, TestVideoCodecIntersectPacketization) {
181   VideoCodec c1;
182   c1.packetization = "raw";
183   VideoCodec c2;
184   c2.packetization = "raw";
185   VideoCodec c3;
186 
187   EXPECT_EQ(VideoCodec::IntersectPacketization(c1, c2), "raw");
188   EXPECT_EQ(VideoCodec::IntersectPacketization(c1, c3), absl::nullopt);
189 }
190 
TEST(CodecTest,TestVideoCodecEqualsWithDifferentPacketization)191 TEST(CodecTest, TestVideoCodecEqualsWithDifferentPacketization) {
192   VideoCodec c0(100, cricket::kVp8CodecName);
193   VideoCodec c1(100, cricket::kVp8CodecName);
194   VideoCodec c2(100, cricket::kVp8CodecName);
195   c2.packetization = "raw";
196 
197   EXPECT_EQ(c0, c1);
198   EXPECT_NE(c0, c2);
199   EXPECT_NE(c2, c0);
200   EXPECT_EQ(c2, c2);
201 }
202 
TEST(CodecTest,TestVideoCodecMatches)203 TEST(CodecTest, TestVideoCodecMatches) {
204   // Test a codec with a static payload type.
205   VideoCodec c0(95, "V");
206   EXPECT_TRUE(c0.Matches(VideoCodec(95, "")));
207   EXPECT_FALSE(c0.Matches(VideoCodec(96, "")));
208 
209   // Test a codec with a dynamic payload type.
210   VideoCodec c1(96, "V");
211   EXPECT_TRUE(c1.Matches(VideoCodec(96, "V")));
212   EXPECT_TRUE(c1.Matches(VideoCodec(97, "V")));
213   EXPECT_TRUE(c1.Matches(VideoCodec(96, "v")));
214   EXPECT_TRUE(c1.Matches(VideoCodec(97, "v")));
215   EXPECT_FALSE(c1.Matches(VideoCodec(96, "")));
216   EXPECT_FALSE(c1.Matches(VideoCodec(95, "V")));
217 }
218 
TEST(CodecTest,TestVideoCodecMatchesWithDifferentPacketization)219 TEST(CodecTest, TestVideoCodecMatchesWithDifferentPacketization) {
220   VideoCodec c0(100, cricket::kVp8CodecName);
221   VideoCodec c1(101, cricket::kVp8CodecName);
222   c1.packetization = "raw";
223 
224   EXPECT_TRUE(c0.Matches(c1));
225   EXPECT_TRUE(c1.Matches(c0));
226 }
227 
228 // VP9 codecs compare profile information.
TEST(CodecTest,TestVP9CodecMatches)229 TEST(CodecTest, TestVP9CodecMatches) {
230   const char kProfile0[] = "0";
231   const char kProfile2[] = "2";
232 
233   VideoCodec c_no_profile(95, cricket::kVp9CodecName);
234   VideoCodec c_profile0(95, cricket::kVp9CodecName);
235   c_profile0.params[webrtc::kVP9FmtpProfileId] = kProfile0;
236 
237   EXPECT_TRUE(c_profile0.Matches(c_no_profile));
238 
239   {
240     VideoCodec c_profile0_eq(95, cricket::kVp9CodecName);
241     c_profile0_eq.params[webrtc::kVP9FmtpProfileId] = kProfile0;
242     EXPECT_TRUE(c_profile0.Matches(c_profile0_eq));
243   }
244 
245   {
246     VideoCodec c_profile2(95, cricket::kVp9CodecName);
247     c_profile2.params[webrtc::kVP9FmtpProfileId] = kProfile2;
248     EXPECT_FALSE(c_profile0.Matches(c_profile2));
249     EXPECT_FALSE(c_no_profile.Matches(c_profile2));
250   }
251 
252   {
253     VideoCodec c_no_profile_eq(95, cricket::kVp9CodecName);
254     EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq));
255   }
256 }
257 
258 // Matching H264 codecs also need to have matching profile-level-id and
259 // packetization-mode.
TEST(CodecTest,TestH264CodecMatches)260 TEST(CodecTest, TestH264CodecMatches) {
261   const char kProfileLevelId1[] = "42e01f";
262   const char kProfileLevelId2[] = "42a01e";
263 
264   VideoCodec pli_1_pm_0(95, "H264");
265   pli_1_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
266   pli_1_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0";
267 
268   {
269     VideoCodec pli_1_pm_blank(95, "H264");
270     pli_1_pm_blank.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
271     pli_1_pm_blank.params.erase(
272         pli_1_pm_blank.params.find(cricket::kH264FmtpPacketizationMode));
273 
274     // Matches since if packetization-mode is not specified it defaults to "0".
275     EXPECT_TRUE(pli_1_pm_0.Matches(pli_1_pm_blank));
276   }
277 
278   {
279     VideoCodec pli_1_pm_1(95, "H264");
280     pli_1_pm_1.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
281     pli_1_pm_1.params[cricket::kH264FmtpPacketizationMode] = "1";
282 
283     // Does not match since packetization-mode is different.
284     EXPECT_FALSE(pli_1_pm_0.Matches(pli_1_pm_1));
285   }
286 
287   {
288     VideoCodec pli_2_pm_0(95, "H264");
289     pli_2_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId2;
290     pli_2_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0";
291 
292     // Does not match since profile-level-id is different.
293     EXPECT_FALSE(pli_1_pm_0.Matches(pli_2_pm_0));
294   }
295 }
296 
TEST(CodecTest,TestDataCodecMatches)297 TEST(CodecTest, TestDataCodecMatches) {
298   // Test a codec with a static payload type.
299   DataCodec c0(95, "D");
300   EXPECT_TRUE(c0.Matches(DataCodec(95, "")));
301   EXPECT_FALSE(c0.Matches(DataCodec(96, "")));
302 
303   // Test a codec with a dynamic payload type.
304   DataCodec c1(96, "D");
305   EXPECT_TRUE(c1.Matches(DataCodec(96, "D")));
306   EXPECT_TRUE(c1.Matches(DataCodec(97, "D")));
307   EXPECT_TRUE(c1.Matches(DataCodec(96, "d")));
308   EXPECT_TRUE(c1.Matches(DataCodec(97, "d")));
309   EXPECT_FALSE(c1.Matches(DataCodec(96, "")));
310   EXPECT_FALSE(c1.Matches(DataCodec(95, "D")));
311 }
312 
TEST(CodecTest,TestSetParamGetParamAndRemoveParam)313 TEST(CodecTest, TestSetParamGetParamAndRemoveParam) {
314   AudioCodec codec;
315   codec.SetParam("a", "1");
316   codec.SetParam("b", "x");
317 
318   int int_value = 0;
319   EXPECT_TRUE(codec.GetParam("a", &int_value));
320   EXPECT_EQ(1, int_value);
321   EXPECT_FALSE(codec.GetParam("b", &int_value));
322   EXPECT_FALSE(codec.GetParam("c", &int_value));
323 
324   std::string str_value;
325   EXPECT_TRUE(codec.GetParam("a", &str_value));
326   EXPECT_EQ("1", str_value);
327   EXPECT_TRUE(codec.GetParam("b", &str_value));
328   EXPECT_EQ("x", str_value);
329   EXPECT_FALSE(codec.GetParam("c", &str_value));
330   EXPECT_TRUE(codec.RemoveParam("a"));
331   EXPECT_FALSE(codec.RemoveParam("c"));
332 }
333 
TEST(CodecTest,TestIntersectFeedbackParams)334 TEST(CodecTest, TestIntersectFeedbackParams) {
335   const FeedbackParam a1("a", "1");
336   const FeedbackParam b2("b", "2");
337   const FeedbackParam b3("b", "3");
338   const FeedbackParam c3("c", "3");
339   TestCodec c1;
340   c1.AddFeedbackParam(a1);  // Only match with c2.
341   c1.AddFeedbackParam(b2);  // Same param different values.
342   c1.AddFeedbackParam(c3);  // Not in c2.
343   TestCodec c2;
344   c2.AddFeedbackParam(a1);
345   c2.AddFeedbackParam(b3);
346 
347   c1.IntersectFeedbackParams(c2);
348   EXPECT_TRUE(c1.HasFeedbackParam(a1));
349   EXPECT_FALSE(c1.HasFeedbackParam(b2));
350   EXPECT_FALSE(c1.HasFeedbackParam(c3));
351 }
352 
TEST(CodecTest,TestGetCodecType)353 TEST(CodecTest, TestGetCodecType) {
354   // Codec type comparison should be case insenstive on names.
355   const VideoCodec codec(96, "V");
356   const VideoCodec rtx_codec(96, "rTx");
357   const VideoCodec ulpfec_codec(96, "ulpFeC");
358   const VideoCodec flexfec_codec(96, "FlExFeC-03");
359   const VideoCodec red_codec(96, "ReD");
360   EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
361   EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
362   EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
363   EXPECT_EQ(VideoCodec::CODEC_FLEXFEC, flexfec_codec.GetCodecType());
364   EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
365 }
366 
TEST(CodecTest,TestCreateRtxCodec)367 TEST(CodecTest, TestCreateRtxCodec) {
368   VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
369   EXPECT_EQ(96, rtx_codec.id);
370   EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
371   int associated_payload_type;
372   ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
373                                  &associated_payload_type));
374   EXPECT_EQ(120, associated_payload_type);
375 }
376 
TEST(CodecTest,TestValidateCodecFormat)377 TEST(CodecTest, TestValidateCodecFormat) {
378   const VideoCodec codec(96, "V");
379   ASSERT_TRUE(codec.ValidateCodecFormat());
380 
381   // Accept 0-127 as payload types.
382   VideoCodec low_payload_type = codec;
383   low_payload_type.id = 0;
384   VideoCodec high_payload_type = codec;
385   high_payload_type.id = 127;
386   ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
387   EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
388 
389   // Reject negative payloads.
390   VideoCodec negative_payload_type = codec;
391   negative_payload_type.id = -1;
392   EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
393 
394   // Reject too-high payloads.
395   VideoCodec too_high_payload_type = codec;
396   too_high_payload_type.id = 128;
397   EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
398 
399   // Reject codecs with min bitrate > max bitrate.
400   VideoCodec incorrect_bitrates = codec;
401   incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
402   incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
403   EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
404 
405   // Accept min bitrate == max bitrate.
406   VideoCodec equal_bitrates = codec;
407   equal_bitrates.params[kCodecParamMinBitrate] = "100";
408   equal_bitrates.params[kCodecParamMaxBitrate] = "100";
409   EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
410 
411   // Accept min bitrate < max bitrate.
412   VideoCodec different_bitrates = codec;
413   different_bitrates.params[kCodecParamMinBitrate] = "99";
414   different_bitrates.params[kCodecParamMaxBitrate] = "100";
415   EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
416 }
417 
TEST(CodecTest,TestToCodecParameters)418 TEST(CodecTest, TestToCodecParameters) {
419   VideoCodec v(96, "V");
420   v.SetParam("p1", "v1");
421   webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters();
422   EXPECT_EQ(96, codec_params_1.payload_type);
423   EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec_params_1.kind);
424   EXPECT_EQ("V", codec_params_1.name);
425   EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate);
426   EXPECT_EQ(absl::nullopt, codec_params_1.num_channels);
427   ASSERT_EQ(1u, codec_params_1.parameters.size());
428   EXPECT_EQ("p1", codec_params_1.parameters.begin()->first);
429   EXPECT_EQ("v1", codec_params_1.parameters.begin()->second);
430 
431   AudioCodec a(97, "A", 44100, 20000, 2);
432   a.SetParam("p1", "a1");
433   webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters();
434   EXPECT_EQ(97, codec_params_2.payload_type);
435   EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec_params_2.kind);
436   EXPECT_EQ("A", codec_params_2.name);
437   EXPECT_EQ(44100, codec_params_2.clock_rate);
438   EXPECT_EQ(2, codec_params_2.num_channels);
439   ASSERT_EQ(1u, codec_params_2.parameters.size());
440   EXPECT_EQ("p1", codec_params_2.parameters.begin()->first);
441   EXPECT_EQ("a1", codec_params_2.parameters.begin()->second);
442 }
443 
TEST(CodecTest,H264CostrainedBaselineIsAddedIfH264IsSupported)444 TEST(CodecTest, H264CostrainedBaselineIsAddedIfH264IsSupported) {
445   const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
446       webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
447                                webrtc::H264::kLevel3_1, "1"),
448       webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
449                                webrtc::H264::kLevel3_1, "0")};
450 
451   std::vector<webrtc::SdpVideoFormat> supported_formats =
452       kExplicitlySupportedFormats;
453   cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
454       &supported_formats);
455 
456   const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization1 =
457       webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
458                                webrtc::H264::kLevel3_1, "1");
459   const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization0 =
460       webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
461                                webrtc::H264::kLevel3_1, "0");
462 
463   EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
464   EXPECT_EQ(supported_formats[1], kExplicitlySupportedFormats[1]);
465   EXPECT_EQ(supported_formats[2], kH264ConstrainedBasedlinePacketization1);
466   EXPECT_EQ(supported_formats[3], kH264ConstrainedBasedlinePacketization0);
467 }
468 
TEST(CodecTest,H264CostrainedBaselineIsNotAddedIfH264IsUnsupported)469 TEST(CodecTest, H264CostrainedBaselineIsNotAddedIfH264IsUnsupported) {
470   const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
471       {cricket::kVp9CodecName,
472        {{webrtc::kVP9FmtpProfileId,
473          VP9ProfileToString(webrtc::VP9Profile::kProfile0)}}}};
474 
475   std::vector<webrtc::SdpVideoFormat> supported_formats =
476       kExplicitlySupportedFormats;
477   cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
478       &supported_formats);
479 
480   EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
481   EXPECT_EQ(supported_formats.size(), kExplicitlySupportedFormats.size());
482 }
483 
TEST(CodecTest,H264CostrainedBaselineNotAddedIfAlreadySpecified)484 TEST(CodecTest, H264CostrainedBaselineNotAddedIfAlreadySpecified) {
485   const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
486       webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
487                                webrtc::H264::kLevel3_1, "1"),
488       webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
489                                webrtc::H264::kLevel3_1, "0"),
490       webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
491                                webrtc::H264::kLevel3_1, "1"),
492       webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
493                                webrtc::H264::kLevel3_1, "0")};
494 
495   std::vector<webrtc::SdpVideoFormat> supported_formats =
496       kExplicitlySupportedFormats;
497   cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
498       &supported_formats);
499 
500   EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
501   EXPECT_EQ(supported_formats[1], kExplicitlySupportedFormats[1]);
502   EXPECT_EQ(supported_formats[2], kExplicitlySupportedFormats[2]);
503   EXPECT_EQ(supported_formats[3], kExplicitlySupportedFormats[3]);
504   EXPECT_EQ(supported_formats.size(), kExplicitlySupportedFormats.size());
505 }
506 
507 // Tests that the helper IsSameCodec returns the correct value for codecs that
508 // must also be matched on particular parameter values.
509 using IsSameCodecParamsTestCase =
510     std::tuple<cricket::CodecParameterMap, cricket::CodecParameterMap>;
511 class IsSameCodecParamsTest
512     : public ::testing::TestWithParam<
513           std::tuple<std::string, bool, IsSameCodecParamsTestCase>> {
514  protected:
IsSameCodecParamsTest()515   IsSameCodecParamsTest() {
516     name_ = std::get<0>(GetParam());
517     expected_ = std::get<1>(GetParam());
518     const auto& test_case = std::get<2>(GetParam());
519     params_left_ = std::get<0>(test_case);
520     params_right_ = std::get<1>(test_case);
521   }
522 
523   std::string name_;
524   bool expected_;
525   cricket::CodecParameterMap params_left_;
526   cricket::CodecParameterMap params_right_;
527 };
528 
TEST_P(IsSameCodecParamsTest,Expected)529 TEST_P(IsSameCodecParamsTest, Expected) {
530   EXPECT_EQ(expected_,
531             cricket::IsSameCodec(name_, params_left_, name_, params_right_));
532 }
533 
TEST_P(IsSameCodecParamsTest,Commutative)534 TEST_P(IsSameCodecParamsTest, Commutative) {
535   EXPECT_EQ(expected_,
536             cricket::IsSameCodec(name_, params_right_, name_, params_left_));
537 }
538 
MakeTestCase(cricket::CodecParameterMap left,cricket::CodecParameterMap right)539 IsSameCodecParamsTestCase MakeTestCase(cricket::CodecParameterMap left,
540                                        cricket::CodecParameterMap right) {
541   return std::make_tuple(left, right);
542 }
543 
544 const IsSameCodecParamsTestCase kH264ParamsSameTestCases[] = {
545     // Both have the same defaults.
546     MakeTestCase({}, {}),
547     // packetization-mode: 0 is the default.
548     MakeTestCase({{cricket::kH264FmtpPacketizationMode, "0"}}, {}),
549     // Non-default packetization-mode matches.
550     MakeTestCase({{cricket::kH264FmtpPacketizationMode, "1"}},
551                  {{cricket::kH264FmtpPacketizationMode, "1"}}),
552 };
553 INSTANTIATE_TEST_SUITE_P(
554     H264_Same,
555     IsSameCodecParamsTest,
556     ::testing::Combine(::testing::Values("H264"),
557                        ::testing::Values(true),
558                        ::testing::ValuesIn(kH264ParamsSameTestCases)));
559 
560 const IsSameCodecParamsTestCase kH264ParamsNotSameTestCases[] = {
561     // packetization-mode does not match the default of "0".
562     MakeTestCase({{cricket::kH264FmtpPacketizationMode, "1"}}, {}),
563 };
564 INSTANTIATE_TEST_SUITE_P(
565     H264_NotSame,
566     IsSameCodecParamsTest,
567     ::testing::Combine(::testing::Values("H264"),
568                        ::testing::Values(false),
569                        ::testing::ValuesIn(kH264ParamsNotSameTestCases)));
570 
571 const IsSameCodecParamsTestCase kVP9ParamsSameTestCases[] = {
572     // Both have the same defaults.
573     MakeTestCase({}, {}),
574     // profile-id: 0 is the default.
575     MakeTestCase({{webrtc::kVP9FmtpProfileId, "0"}}, {}),
576     // Non-default profile-id matches.
577     MakeTestCase({{webrtc::kVP9FmtpProfileId, "2"}},
578                  {{webrtc::kVP9FmtpProfileId, "2"}}),
579 };
580 INSTANTIATE_TEST_SUITE_P(
581     VP9_Same,
582     IsSameCodecParamsTest,
583     ::testing::Combine(::testing::Values("VP9"),
584                        ::testing::Values(true),
585                        ::testing::ValuesIn(kVP9ParamsSameTestCases)));
586 
587 const IsSameCodecParamsTestCase kVP9ParamsNotSameTestCases[] = {
588     // profile-id missing from right.
589     MakeTestCase({{webrtc::kVP9FmtpProfileId, "2"}}, {}),
590 };
591 INSTANTIATE_TEST_SUITE_P(
592     VP9_NotSame,
593     IsSameCodecParamsTest,
594     ::testing::Combine(::testing::Values("VP9"),
595                        ::testing::Values(false),
596                        ::testing::ValuesIn(kVP9ParamsNotSameTestCases)));
597