blob: 4cb78fa0861cf3ac98c522a21d5daf3d951b8c6d [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellander1afca732016-02-08 04:46:452 * Copyright (c) 2009 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellander1afca732016-02-08 04:46:454 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:369 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "media/base/codec.h"
Emircan Uysaler98badbc2018-06-28 17:59:0212
Harald Alvestrand6aab4cc2024-09-12 14:02:2113#include <optional>
14#include <string>
15#include <vector>
Steve Anton2dbc6272019-05-31 20:08:5816
Harald Alvestrand7a3c07b2024-10-22 11:32:3617#include "absl/strings/str_cat.h"
Harald Alvestrand6aab4cc2024-09-12 14:02:2118#include "api/media_types.h"
19#include "api/rtp_parameters.h"
Johannes Kronc3fcee72021-04-19 07:09:2620#include "api/video_codecs/h264_profile_level_id.h"
Harald Alvestrand6aab4cc2024-09-12 14:02:2121#include "api/video_codecs/sdp_video_format.h"
Johannes Kronc3fcee72021-04-19 07:09:2622#include "api/video_codecs/vp9_profile.h"
Harald Alvestrand6aab4cc2024-09-12 14:02:2123#include "media/base/media_constants.h"
Johannes Kron3e983682020-03-29 20:17:0024#include "modules/video_coding/codecs/h264/include/h264.h"
Harald Alvestrand6aab4cc2024-09-12 14:02:2125#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:3626
henrike@webrtc.org28e20752013-07-10 00:45:3627using cricket::Codec;
henrike@webrtc.org28e20752013-07-10 00:45:3628using cricket::FeedbackParam;
pbos@webrtc.orgb5a22b12014-05-13 11:07:0129using cricket::kCodecParamAssociatedPayloadType;
30using cricket::kCodecParamMaxBitrate;
31using cricket::kCodecParamMinBitrate;
henrike@webrtc.org28e20752013-07-10 00:45:3632
htab39db842016-12-08 09:50:4833class TestCodec : public Codec {
34 public:
Mirko Bonadeic61ce0d2017-11-21 16:04:2035 TestCodec(int id, const std::string& name, int clockrate)
Florent Castelli811e24a2023-05-31 12:35:4736 : Codec(Type::kAudio, id, name, clockrate) {}
37 TestCodec() : Codec(Type::kAudio) {}
Byoungchan Lee917dcba2021-05-11 13:27:1038 TestCodec(const TestCodec& c) = default;
39 TestCodec& operator=(const TestCodec& c) = default;
htab39db842016-12-08 09:50:4840};
41
magjed9c41e472016-10-31 16:06:0342TEST(CodecTest, TestCodecOperators) {
htab39db842016-12-08 09:50:4843 TestCodec c0(96, "D", 1000);
jiayl@webrtc.org9c16c392014-05-01 18:30:3044 c0.SetParam("a", 1);
45
htab39db842016-12-08 09:50:4846 TestCodec c1 = c0;
jiayl@webrtc.org9c16c392014-05-01 18:30:3047 EXPECT_TRUE(c1 == c0);
48
49 int param_value0;
50 int param_value1;
51 EXPECT_TRUE(c0.GetParam("a", &param_value0));
52 EXPECT_TRUE(c1.GetParam("a", &param_value1));
53 EXPECT_EQ(param_value0, param_value1);
54
55 c1.id = 86;
56 EXPECT_TRUE(c0 != c1);
57
58 c1 = c0;
59 c1.name = "x";
60 EXPECT_TRUE(c0 != c1);
61
62 c1 = c0;
63 c1.clockrate = 2000;
64 EXPECT_TRUE(c0 != c1);
65
66 c1 = c0;
jiayl@webrtc.org9c16c392014-05-01 18:30:3067 c1.SetParam("a", 2);
68 EXPECT_TRUE(c0 != c1);
69
htab39db842016-12-08 09:50:4870 TestCodec c5;
Harald Alvestrand6aab4cc2024-09-12 14:02:2171 TestCodec c6(Codec::kIdNotSet, "", 0);
jiayl@webrtc.org9c16c392014-05-01 18:30:3072 EXPECT_TRUE(c5 == c6);
73}
74
magjed9c41e472016-10-31 16:06:0375TEST(CodecTest, TestAudioCodecOperators) {
Harald Alvestrandd78e30e2024-04-29 10:15:3476 Codec c0 = cricket::CreateAudioCodec(96, "A", 44100, 2);
77 Codec c1 = cricket::CreateAudioCodec(95, "A", 44100, 2);
78 Codec c2 = cricket::CreateAudioCodec(96, "x", 44100, 2);
79 Codec c3 = cricket::CreateAudioCodec(96, "A", 48000, 2);
80 Codec c4 = cricket::CreateAudioCodec(96, "A", 44100, 2);
Florent Castelli811e24a2023-05-31 12:35:4781 c4.bitrate = 10000;
Harald Alvestrandd78e30e2024-04-29 10:15:3482 Codec c5 = cricket::CreateAudioCodec(96, "A", 44100, 1);
kwibergb94491d2017-02-21 14:16:1983 EXPECT_NE(c0, c1);
84 EXPECT_NE(c0, c2);
85 EXPECT_NE(c0, c3);
86 EXPECT_NE(c0, c4);
87 EXPECT_NE(c0, c5);
henrike@webrtc.org28e20752013-07-10 00:45:3688
Harald Alvestrandd78e30e2024-04-29 10:15:3489 Codec c8 = cricket::CreateAudioCodec(0, "", 0, 0);
90 Codec c9 = c0;
kwibergb94491d2017-02-21 14:16:1991 EXPECT_EQ(c9, c0);
henrike@webrtc.org28e20752013-07-10 00:45:3692
Harald Alvestrandd78e30e2024-04-29 10:15:3493 Codec c10(c0);
94 Codec c11(c0);
95 Codec c12(c0);
96 Codec c13(c0);
henrike@webrtc.org28e20752013-07-10 00:45:3697 c10.params["x"] = "abc";
98 c11.params["x"] = "def";
99 c12.params["y"] = "abc";
100 c13.params["x"] = "abc";
kwibergb94491d2017-02-21 14:16:19101 EXPECT_NE(c10, c0);
102 EXPECT_NE(c11, c0);
103 EXPECT_NE(c11, c10);
104 EXPECT_NE(c12, c0);
105 EXPECT_NE(c12, c10);
106 EXPECT_NE(c12, c11);
107 EXPECT_EQ(c13, c10);
henrike@webrtc.org28e20752013-07-10 00:45:36108}
109
magjed9c41e472016-10-31 16:06:03110TEST(CodecTest, TestVideoCodecOperators) {
Harald Alvestrandd78e30e2024-04-29 10:15:34111 Codec c0 = cricket::CreateVideoCodec(96, "V");
112 Codec c1 = cricket::CreateVideoCodec(95, "V");
113 Codec c2 = cricket::CreateVideoCodec(96, "x");
perkj26752742016-10-24 08:21:16114
henrike@webrtc.org28e20752013-07-10 00:45:36115 EXPECT_TRUE(c0 != c1);
116 EXPECT_TRUE(c0 != c2);
henrike@webrtc.org28e20752013-07-10 00:45:36117
Harald Alvestrandd78e30e2024-04-29 10:15:34118 Codec c8 = cricket::CreateVideoCodec(0, "");
119 Codec c9 = c0;
henrike@webrtc.org28e20752013-07-10 00:45:36120 EXPECT_TRUE(c9 == c0);
121
Harald Alvestrandd78e30e2024-04-29 10:15:34122 Codec c10(c0);
123 Codec c11(c0);
124 Codec c12(c0);
125 Codec c13(c0);
henrike@webrtc.org28e20752013-07-10 00:45:36126 c10.params["x"] = "abc";
127 c11.params["x"] = "def";
128 c12.params["y"] = "abc";
129 c13.params["x"] = "abc";
130 EXPECT_TRUE(c10 != c0);
131 EXPECT_TRUE(c11 != c0);
132 EXPECT_TRUE(c11 != c10);
133 EXPECT_TRUE(c12 != c0);
134 EXPECT_TRUE(c12 != c10);
135 EXPECT_TRUE(c12 != c11);
136 EXPECT_TRUE(c13 == c10);
137}
138
Mirta Dvornicic479a3c02019-06-04 13:38:50139TEST(CodecTest, TestVideoCodecEqualsWithDifferentPacketization) {
Harald Alvestrandd78e30e2024-04-29 10:15:34140 Codec c0 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
141 Codec c1 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
142 Codec c2 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
Mirta Dvornicic479a3c02019-06-04 13:38:50143 c2.packetization = "raw";
144
145 EXPECT_EQ(c0, c1);
146 EXPECT_NE(c0, c2);
147 EXPECT_NE(c2, c0);
148 EXPECT_EQ(c2, c2);
149}
150
magjed9c41e472016-10-31 16:06:03151TEST(CodecTest, TestSetParamGetParamAndRemoveParam) {
Harald Alvestrandd78e30e2024-04-29 10:15:34152 Codec codec = cricket::CreateAudioCodec(0, "foo", 22222, 2);
henrike@webrtc.org28e20752013-07-10 00:45:36153 codec.SetParam("a", "1");
154 codec.SetParam("b", "x");
155
156 int int_value = 0;
157 EXPECT_TRUE(codec.GetParam("a", &int_value));
158 EXPECT_EQ(1, int_value);
159 EXPECT_FALSE(codec.GetParam("b", &int_value));
160 EXPECT_FALSE(codec.GetParam("c", &int_value));
161
162 std::string str_value;
163 EXPECT_TRUE(codec.GetParam("a", &str_value));
164 EXPECT_EQ("1", str_value);
165 EXPECT_TRUE(codec.GetParam("b", &str_value));
166 EXPECT_EQ("x", str_value);
167 EXPECT_FALSE(codec.GetParam("c", &str_value));
buildbot@webrtc.orgfbd13282014-06-19 19:50:55168 EXPECT_TRUE(codec.RemoveParam("a"));
169 EXPECT_FALSE(codec.RemoveParam("c"));
henrike@webrtc.org28e20752013-07-10 00:45:36170}
171
magjed9c41e472016-10-31 16:06:03172TEST(CodecTest, TestIntersectFeedbackParams) {
henrike@webrtc.org28e20752013-07-10 00:45:36173 const FeedbackParam a1("a", "1");
174 const FeedbackParam b2("b", "2");
175 const FeedbackParam b3("b", "3");
176 const FeedbackParam c3("c", "3");
htab39db842016-12-08 09:50:48177 TestCodec c1;
Steve Antone78bcb92017-10-31 16:53:08178 c1.AddFeedbackParam(a1); // Only match with c2.
179 c1.AddFeedbackParam(b2); // Same param different values.
180 c1.AddFeedbackParam(c3); // Not in c2.
htab39db842016-12-08 09:50:48181 TestCodec c2;
henrike@webrtc.org28e20752013-07-10 00:45:36182 c2.AddFeedbackParam(a1);
183 c2.AddFeedbackParam(b3);
184
185 c1.IntersectFeedbackParams(c2);
186 EXPECT_TRUE(c1.HasFeedbackParam(a1));
187 EXPECT_FALSE(c1.HasFeedbackParam(b2));
188 EXPECT_FALSE(c1.HasFeedbackParam(c3));
189}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01190
magjed9c41e472016-10-31 16:06:03191TEST(CodecTest, TestGetCodecType) {
Philipp Hancke9384bb22024-02-14 17:14:36192 // Codec type comparison should be case insensitive on names.
Harald Alvestrandd78e30e2024-04-29 10:15:34193 const Codec codec = cricket::CreateVideoCodec(96, "V");
194 const Codec rtx_codec = cricket::CreateVideoCodec(96, "rTx");
195 const Codec ulpfec_codec = cricket::CreateVideoCodec(96, "ulpFeC");
196 const Codec flexfec_codec = cricket::CreateVideoCodec(96, "FlExFeC-03");
197 const Codec red_codec = cricket::CreateVideoCodec(96, "ReD");
Florent Castelli811e24a2023-05-31 12:35:47198 EXPECT_TRUE(codec.IsMediaCodec());
199 EXPECT_EQ(codec.GetResiliencyType(), Codec::ResiliencyType::kNone);
200 EXPECT_EQ(rtx_codec.GetResiliencyType(), Codec::ResiliencyType::kRtx);
201 EXPECT_EQ(ulpfec_codec.GetResiliencyType(), Codec::ResiliencyType::kUlpfec);
202 EXPECT_EQ(flexfec_codec.GetResiliencyType(), Codec::ResiliencyType::kFlexfec);
203 EXPECT_EQ(red_codec.GetResiliencyType(), Codec::ResiliencyType::kRed);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01204}
205
magjed9c41e472016-10-31 16:06:03206TEST(CodecTest, TestCreateRtxCodec) {
Harald Alvestrandd78e30e2024-04-29 10:15:34207 const Codec rtx_codec = cricket::CreateVideoRtxCodec(96, 120);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01208 EXPECT_EQ(96, rtx_codec.id);
Florent Castelli811e24a2023-05-31 12:35:47209 EXPECT_EQ(rtx_codec.GetResiliencyType(), Codec::ResiliencyType::kRtx);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01210 int associated_payload_type;
211 ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
212 &associated_payload_type));
213 EXPECT_EQ(120, associated_payload_type);
214}
215
magjed9c41e472016-10-31 16:06:03216TEST(CodecTest, TestValidateCodecFormat) {
Harald Alvestrandd78e30e2024-04-29 10:15:34217 const Codec codec = cricket::CreateVideoCodec(96, "V");
pbos@webrtc.orgb5a22b12014-05-13 11:07:01218 ASSERT_TRUE(codec.ValidateCodecFormat());
219
220 // Accept 0-127 as payload types.
Harald Alvestrandd78e30e2024-04-29 10:15:34221 Codec low_payload_type = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01222 low_payload_type.id = 0;
Harald Alvestrandd78e30e2024-04-29 10:15:34223 Codec high_payload_type = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01224 high_payload_type.id = 127;
225 ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
226 EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
227
228 // Reject negative payloads.
Harald Alvestrandd78e30e2024-04-29 10:15:34229 Codec negative_payload_type = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01230 negative_payload_type.id = -1;
231 EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
232
233 // Reject too-high payloads.
Harald Alvestrandd78e30e2024-04-29 10:15:34234 Codec too_high_payload_type = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01235 too_high_payload_type.id = 128;
236 EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
237
pbos@webrtc.orgb5a22b12014-05-13 11:07:01238 // Reject codecs with min bitrate > max bitrate.
Harald Alvestrandd78e30e2024-04-29 10:15:34239 Codec incorrect_bitrates = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01240 incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
241 incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
242 EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
243
244 // Accept min bitrate == max bitrate.
Harald Alvestrandd78e30e2024-04-29 10:15:34245 Codec equal_bitrates = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01246 equal_bitrates.params[kCodecParamMinBitrate] = "100";
247 equal_bitrates.params[kCodecParamMaxBitrate] = "100";
248 EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
249
250 // Accept min bitrate < max bitrate.
Harald Alvestrandd78e30e2024-04-29 10:15:34251 Codec different_bitrates = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01252 different_bitrates.params[kCodecParamMinBitrate] = "99";
253 different_bitrates.params[kCodecParamMaxBitrate] = "100";
254 EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
255}
Taylor Brandstetterdb0cd9e2016-05-16 18:40:30256
magjed9c41e472016-10-31 16:06:03257TEST(CodecTest, TestToCodecParameters) {
Harald Alvestrandd78e30e2024-04-29 10:15:34258 Codec v = cricket::CreateVideoCodec(96, "V");
Florent Castellib7d9d832018-05-15 16:14:14259 v.SetParam("p1", "v1");
Taylor Brandstetterdb0cd9e2016-05-16 18:40:30260 webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters();
261 EXPECT_EQ(96, codec_params_1.payload_type);
deadbeefe702b302017-02-04 20:09:01262 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec_params_1.kind);
263 EXPECT_EQ("V", codec_params_1.name);
Oskar Sundbom78807582017-11-16 10:09:55264 EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate);
Florent Castelli8037fc62024-08-29 13:00:40265 EXPECT_EQ(std::nullopt, codec_params_1.num_channels);
Mirko Bonadeif859e552018-05-30 13:31:29266 ASSERT_EQ(1u, codec_params_1.parameters.size());
Florent Castellib7d9d832018-05-15 16:14:14267 EXPECT_EQ("p1", codec_params_1.parameters.begin()->first);
268 EXPECT_EQ("v1", codec_params_1.parameters.begin()->second);
Taylor Brandstetterdb0cd9e2016-05-16 18:40:30269
Harald Alvestrandd78e30e2024-04-29 10:15:34270 Codec a = cricket::CreateAudioCodec(97, "A", 44100, 2);
Florent Castellib7d9d832018-05-15 16:14:14271 a.SetParam("p1", "a1");
Taylor Brandstetterdb0cd9e2016-05-16 18:40:30272 webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters();
273 EXPECT_EQ(97, codec_params_2.payload_type);
deadbeefe702b302017-02-04 20:09:01274 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec_params_2.kind);
275 EXPECT_EQ("A", codec_params_2.name);
Oskar Sundbom78807582017-11-16 10:09:55276 EXPECT_EQ(44100, codec_params_2.clock_rate);
277 EXPECT_EQ(2, codec_params_2.num_channels);
Mirko Bonadeif859e552018-05-30 13:31:29278 ASSERT_EQ(1u, codec_params_2.parameters.size());
Florent Castellib7d9d832018-05-15 16:14:14279 EXPECT_EQ("p1", codec_params_2.parameters.begin()->first);
280 EXPECT_EQ("a1", codec_params_2.parameters.begin()->second);
Taylor Brandstetterdb0cd9e2016-05-16 18:40:30281}
Steve Anton2dbc6272019-05-31 20:08:58282
Johannes Kron3e983682020-03-29 20:17:00283TEST(CodecTest, H264CostrainedBaselineIsAddedIfH264IsSupported) {
284 const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
Johannes Kronc3fcee72021-04-19 07:09:26285 webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
286 webrtc::H264Level::kLevel3_1, "1"),
287 webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
288 webrtc::H264Level::kLevel3_1, "0")};
Johannes Kron3e983682020-03-29 20:17:00289
290 std::vector<webrtc::SdpVideoFormat> supported_formats =
291 kExplicitlySupportedFormats;
292 cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
293 &supported_formats);
294
295 const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization1 =
Johannes Kronc3fcee72021-04-19 07:09:26296 webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
297 webrtc::H264Level::kLevel3_1, "1");
Johannes Kron3e983682020-03-29 20:17:00298 const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization0 =
Johannes Kronc3fcee72021-04-19 07:09:26299 webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
300 webrtc::H264Level::kLevel3_1, "0");
Johannes Kron3e983682020-03-29 20:17:00301
302 EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
303 EXPECT_EQ(supported_formats[1], kExplicitlySupportedFormats[1]);
304 EXPECT_EQ(supported_formats[2], kH264ConstrainedBasedlinePacketization1);
305 EXPECT_EQ(supported_formats[3], kH264ConstrainedBasedlinePacketization0);
306}
307
308TEST(CodecTest, H264CostrainedBaselineIsNotAddedIfH264IsUnsupported) {
309 const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
310 {cricket::kVp9CodecName,
311 {{webrtc::kVP9FmtpProfileId,
312 VP9ProfileToString(webrtc::VP9Profile::kProfile0)}}}};
313
314 std::vector<webrtc::SdpVideoFormat> supported_formats =
315 kExplicitlySupportedFormats;
316 cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
317 &supported_formats);
318
319 EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
320 EXPECT_EQ(supported_formats.size(), kExplicitlySupportedFormats.size());
321}
322
323TEST(CodecTest, H264CostrainedBaselineNotAddedIfAlreadySpecified) {
324 const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
Johannes Kronc3fcee72021-04-19 07:09:26325 webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
326 webrtc::H264Level::kLevel3_1, "1"),
327 webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
328 webrtc::H264Level::kLevel3_1, "0"),
329 webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
330 webrtc::H264Level::kLevel3_1, "1"),
331 webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
332 webrtc::H264Level::kLevel3_1, "0")};
Johannes Kron3e983682020-03-29 20:17:00333
334 std::vector<webrtc::SdpVideoFormat> supported_formats =
335 kExplicitlySupportedFormats;
336 cricket::AddH264ConstrainedBaselineProfileToSupportedFormats(
337 &supported_formats);
338
339 EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
340 EXPECT_EQ(supported_formats[1], kExplicitlySupportedFormats[1]);
341 EXPECT_EQ(supported_formats[2], kExplicitlySupportedFormats[2]);
342 EXPECT_EQ(supported_formats[3], kExplicitlySupportedFormats[3]);
343 EXPECT_EQ(supported_formats.size(), kExplicitlySupportedFormats.size());
344}
Harald Alvestrand3203b622024-10-10 12:31:47345
346TEST(CodecTest, AbslStringify) {
347 Codec codec = cricket::CreateAudioCodec(47, "custom-audio", 48000, 2);
348 EXPECT_EQ(absl::StrCat(codec), "[47:audio/custom-audio/48000/2]");
349 codec.params["key"] = "value";
350 EXPECT_EQ(absl::StrCat(codec), "[47:audio/custom-audio/48000/2;key=value]");
351}