audioconduit_unittests.cpp (33592B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #define GTEST_HAS_RTTI 0 8 #include "gtest/gtest.h" 9 10 #include "api/audio_codecs/opus/audio_encoder_opus_config.h" 11 #include "AudioConduit.h" 12 #include "Canonicals.h" 13 14 #include "MockCall.h" 15 16 using namespace mozilla; 17 using namespace testing; 18 using namespace webrtc; 19 20 namespace test { 21 22 class AudioConduitTest : public ::testing::Test { 23 public: 24 AudioConduitTest() 25 : mCallWrapper(MockCallWrapper::Create()), 26 mAudioConduit(MakeRefPtr<WebrtcAudioConduit>( 27 mCallWrapper, GetCurrentSerialEventTarget())), 28 mControl(GetCurrentSerialEventTarget()) { 29 mControl.Update( 30 [&](auto& aControl) { mAudioConduit->InitControl(&mControl); }); 31 } 32 33 ~AudioConduitTest() override { 34 (void)WaitFor(mAudioConduit->Shutdown()); 35 mCallWrapper->Destroy(); 36 } 37 38 MockCall* Call() { return mCallWrapper->GetMockCall(); } 39 40 const RefPtr<MockCallWrapper> mCallWrapper; 41 const RefPtr<WebrtcAudioConduit> mAudioConduit; 42 ConcreteControl mControl; 43 }; 44 45 TEST_F(AudioConduitTest, TestConfigureSendMediaCodec) { 46 mControl.Update([&](auto& aControl) { 47 // defaults 48 aControl.mAudioSendCodec = 49 Some(AudioCodecConfig(114, "opus", 48000, 2, false)); 50 aControl.mTransmitting = true; 51 }); 52 53 ASSERT_TRUE(Call()->mAudioSendConfig); 54 { 55 const webrtc::SdpAudioFormat& f = 56 Call()->mAudioSendConfig->send_codec_spec->format; 57 ASSERT_EQ(f.name, "opus"); 58 ASSERT_EQ(f.clockrate_hz, 48000); 59 ASSERT_EQ(f.num_channels, 2UL); 60 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 61 ASSERT_EQ(f.parameters.at("stereo"), "1"); 62 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 63 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 64 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 65 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 66 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 67 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 68 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 69 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 70 } 71 72 mControl.Update([&](auto& aControl) { 73 // empty codec name 74 aControl.mAudioSendCodec = Some(AudioCodecConfig(114, "", 48000, 2, false)); 75 }); 76 77 ASSERT_TRUE(Call()->mAudioSendConfig); 78 { 79 // Invalid codec was ignored. 80 const webrtc::SdpAudioFormat& f = 81 Call()->mAudioSendConfig->send_codec_spec->format; 82 ASSERT_EQ(f.name, "opus"); 83 } 84 } 85 86 TEST_F(AudioConduitTest, TestConfigureSendOpusMono) { 87 mControl.Update([&](auto& aControl) { 88 // opus mono 89 aControl.mAudioSendCodec = 90 Some(AudioCodecConfig(114, "opus", 48000, 1, false)); 91 aControl.mTransmitting = true; 92 }); 93 94 ASSERT_TRUE(Call()->mAudioSendConfig); 95 { 96 const webrtc::SdpAudioFormat& f = 97 Call()->mAudioSendConfig->send_codec_spec->format; 98 ASSERT_EQ(f.name, "opus"); 99 ASSERT_EQ(f.clockrate_hz, 48000); 100 ASSERT_EQ(f.num_channels, 1UL); 101 ASSERT_EQ(f.parameters.find("stereo"), f.parameters.end()); 102 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 103 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 104 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 105 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 106 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 107 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 108 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 109 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 110 } 111 } 112 113 TEST_F(AudioConduitTest, TestConfigureSendOpusFEC) { 114 mControl.Update([&](auto& aControl) { 115 // opus with inband Forward Error Correction 116 AudioCodecConfig codecConfig = 117 AudioCodecConfig(114, "opus", 48000, 2, true); 118 aControl.mAudioSendCodec = Some(codecConfig); 119 aControl.mTransmitting = true; 120 }); 121 122 ASSERT_TRUE(Call()->mAudioSendConfig); 123 { 124 const webrtc::SdpAudioFormat& f = 125 Call()->mAudioSendConfig->send_codec_spec->format; 126 ASSERT_EQ(f.name, "opus"); 127 ASSERT_EQ(f.clockrate_hz, 48000); 128 ASSERT_EQ(f.num_channels, 2UL); 129 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 130 ASSERT_EQ(f.parameters.at("stereo"), "1"); 131 ASSERT_NE(f.parameters.find("useinbandfec"), f.parameters.end()); 132 ASSERT_EQ(f.parameters.at("useinbandfec"), "1"); 133 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 134 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 135 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 136 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 137 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 138 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 139 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 140 } 141 } 142 143 TEST_F(AudioConduitTest, TestConfigureSendOpusMaxPlaybackRate) { 144 mControl.Update([&](auto& aControl) { 145 AudioCodecConfig codecConfig = 146 AudioCodecConfig(114, "opus", 48000, 2, false); 147 codecConfig.mMaxPlaybackRate = 1234; 148 aControl.mAudioSendCodec = Some(codecConfig); 149 aControl.mTransmitting = true; 150 }); 151 152 ASSERT_TRUE(Call()->mAudioSendConfig); 153 { 154 const webrtc::SdpAudioFormat& f = 155 Call()->mAudioSendConfig->send_codec_spec->format; 156 ASSERT_EQ(f.name, "opus"); 157 ASSERT_EQ(f.clockrate_hz, 48000); 158 ASSERT_EQ(f.num_channels, 2UL); 159 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 160 ASSERT_EQ(f.parameters.at("stereo"), "1"); 161 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 162 ASSERT_NE(f.parameters.find("maxplaybackrate"), f.parameters.end()); 163 ASSERT_EQ(f.parameters.at("maxplaybackrate"), "1234"); 164 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 165 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 166 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 167 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 168 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 169 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 170 } 171 } 172 173 TEST_F(AudioConduitTest, TestConfigureSendOpusMaxAverageBitrate) { 174 mControl.Update([&](auto& aControl) { 175 AudioCodecConfig codecConfig = 176 AudioCodecConfig(114, "opus", 48000, 2, false); 177 codecConfig.mMaxAverageBitrate = 12345; 178 aControl.mAudioSendCodec = Some(codecConfig); 179 aControl.mTransmitting = true; 180 }); 181 182 ASSERT_TRUE(Call()->mAudioSendConfig); 183 { 184 const webrtc::SdpAudioFormat& f = 185 Call()->mAudioSendConfig->send_codec_spec->format; 186 ASSERT_EQ(f.name, "opus"); 187 ASSERT_EQ(f.clockrate_hz, 48000); 188 ASSERT_EQ(f.num_channels, 2UL); 189 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 190 ASSERT_EQ(f.parameters.at("stereo"), "1"); 191 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 192 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 193 ASSERT_NE(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 194 ASSERT_EQ(f.parameters.at("maxaveragebitrate"), "12345"); 195 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 196 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 197 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 198 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 199 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 200 } 201 } 202 203 TEST_F(AudioConduitTest, TestConfigureSendOpusDtx) { 204 mControl.Update([&](auto& aControl) { 205 AudioCodecConfig codecConfig = 206 AudioCodecConfig(114, "opus", 48000, 2, false); 207 codecConfig.mDTXEnabled = true; 208 aControl.mAudioSendCodec = Some(codecConfig); 209 aControl.mTransmitting = true; 210 }); 211 212 ASSERT_TRUE(Call()->mAudioSendConfig); 213 { 214 const webrtc::SdpAudioFormat& f = 215 Call()->mAudioSendConfig->send_codec_spec->format; 216 ASSERT_EQ(f.name, "opus"); 217 ASSERT_EQ(f.clockrate_hz, 48000); 218 ASSERT_EQ(f.num_channels, 2UL); 219 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 220 ASSERT_EQ(f.parameters.at("stereo"), "1"); 221 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 222 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 223 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 224 ASSERT_NE(f.parameters.find("usedtx"), f.parameters.end()); 225 ASSERT_EQ(f.parameters.at("usedtx"), "1"); 226 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 227 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 228 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 229 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 230 } 231 } 232 233 TEST_F(AudioConduitTest, TestConfigureSendOpusCbr) { 234 mControl.Update([&](auto& aControl) { 235 AudioCodecConfig codecConfig = 236 AudioCodecConfig(114, "opus", 48000, 2, false); 237 codecConfig.mCbrEnabled = true; 238 aControl.mAudioSendCodec = Some(codecConfig); 239 aControl.mTransmitting = true; 240 }); 241 242 ASSERT_TRUE(Call()->mAudioSendConfig); 243 { 244 const webrtc::SdpAudioFormat& f = 245 Call()->mAudioSendConfig->send_codec_spec->format; 246 ASSERT_EQ(f.name, "opus"); 247 ASSERT_EQ(f.clockrate_hz, 48000); 248 ASSERT_EQ(f.num_channels, 2UL); 249 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 250 ASSERT_EQ(f.parameters.at("stereo"), "1"); 251 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 252 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 253 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 254 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 255 ASSERT_NE(f.parameters.find("cbr"), f.parameters.end()); 256 ASSERT_EQ(f.parameters.at("cbr"), "1"); 257 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 258 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 259 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 260 } 261 } 262 263 TEST_F(AudioConduitTest, TestConfigureSendOpusPtime) { 264 mControl.Update([&](auto& aControl) { 265 AudioCodecConfig codecConfig = 266 AudioCodecConfig(114, "opus", 48000, 2, false); 267 codecConfig.mFrameSizeMs = 100; 268 aControl.mAudioSendCodec = Some(codecConfig); 269 aControl.mTransmitting = true; 270 }); 271 272 ASSERT_TRUE(Call()->mAudioSendConfig); 273 { 274 const webrtc::SdpAudioFormat& f = 275 Call()->mAudioSendConfig->send_codec_spec->format; 276 ASSERT_EQ(f.name, "opus"); 277 ASSERT_EQ(f.clockrate_hz, 48000); 278 ASSERT_EQ(f.num_channels, 2UL); 279 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 280 ASSERT_EQ(f.parameters.at("stereo"), "1"); 281 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 282 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 283 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 284 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 285 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 286 ASSERT_NE(f.parameters.find("ptime"), f.parameters.end()); 287 ASSERT_EQ(f.parameters.at("ptime"), "100"); 288 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 289 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 290 } 291 } 292 293 TEST_F(AudioConduitTest, TestConfigureSendOpusMinPtime) { 294 mControl.Update([&](auto& aControl) { 295 AudioCodecConfig codecConfig = 296 AudioCodecConfig(114, "opus", 48000, 2, false); 297 codecConfig.mMinFrameSizeMs = 201; 298 aControl.mAudioSendCodec = Some(codecConfig); 299 aControl.mTransmitting = true; 300 }); 301 302 ASSERT_TRUE(Call()->mAudioSendConfig); 303 { 304 const webrtc::SdpAudioFormat& f = 305 Call()->mAudioSendConfig->send_codec_spec->format; 306 ASSERT_EQ(f.name, "opus"); 307 ASSERT_EQ(f.clockrate_hz, 48000); 308 ASSERT_EQ(f.num_channels, 2UL); 309 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 310 ASSERT_EQ(f.parameters.at("stereo"), "1"); 311 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 312 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 313 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 314 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 315 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 316 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 317 ASSERT_NE(f.parameters.find("minptime"), f.parameters.end()); 318 ASSERT_EQ(f.parameters.at("minptime"), "201"); 319 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 320 } 321 } 322 323 TEST_F(AudioConduitTest, TestConfigureSendOpusMaxPtime) { 324 mControl.Update([&](auto& aControl) { 325 AudioCodecConfig codecConfig = 326 AudioCodecConfig(114, "opus", 48000, 2, false); 327 codecConfig.mMaxFrameSizeMs = 321; 328 aControl.mAudioSendCodec = Some(codecConfig); 329 aControl.mTransmitting = true; 330 }); 331 332 ASSERT_TRUE(Call()->mAudioSendConfig); 333 { 334 const webrtc::SdpAudioFormat& f = 335 Call()->mAudioSendConfig->send_codec_spec->format; 336 ASSERT_EQ(f.name, "opus"); 337 ASSERT_EQ(f.clockrate_hz, 48000); 338 ASSERT_EQ(f.num_channels, 2UL); 339 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 340 ASSERT_EQ(f.parameters.at("stereo"), "1"); 341 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 342 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 343 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 344 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 345 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 346 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 347 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 348 ASSERT_NE(f.parameters.find("maxptime"), f.parameters.end()); 349 ASSERT_EQ(f.parameters.at("maxptime"), "321"); 350 } 351 } 352 353 TEST_F(AudioConduitTest, TestConfigureSendOpusAllParams) { 354 mControl.Update([&](auto& aControl) { 355 AudioCodecConfig codecConfig = 356 AudioCodecConfig(114, "opus", 48000, 2, true); 357 codecConfig.mMaxPlaybackRate = 5432; 358 codecConfig.mMaxAverageBitrate = 54321; 359 codecConfig.mDTXEnabled = true; 360 codecConfig.mCbrEnabled = true; 361 codecConfig.mFrameSizeMs = 999; 362 codecConfig.mMinFrameSizeMs = 123; 363 codecConfig.mMaxFrameSizeMs = 789; 364 aControl.mAudioSendCodec = Some(codecConfig); 365 aControl.mTransmitting = true; 366 }); 367 368 ASSERT_TRUE(Call()->mAudioSendConfig); 369 { 370 const webrtc::SdpAudioFormat& f = 371 Call()->mAudioSendConfig->send_codec_spec->format; 372 ASSERT_EQ(f.name, "opus"); 373 ASSERT_EQ(f.clockrate_hz, 48000); 374 ASSERT_EQ(f.num_channels, 2UL); 375 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 376 ASSERT_EQ(f.parameters.at("stereo"), "1"); 377 ASSERT_NE(f.parameters.find("useinbandfec"), f.parameters.end()); 378 ASSERT_EQ(f.parameters.at("useinbandfec"), "1"); 379 ASSERT_NE(f.parameters.find("maxplaybackrate"), f.parameters.end()); 380 ASSERT_EQ(f.parameters.at("maxplaybackrate"), "5432"); 381 ASSERT_NE(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 382 ASSERT_EQ(f.parameters.at("maxaveragebitrate"), "54321"); 383 ASSERT_NE(f.parameters.find("usedtx"), f.parameters.end()); 384 ASSERT_EQ(f.parameters.at("usedtx"), "1"); 385 ASSERT_NE(f.parameters.find("cbr"), f.parameters.end()); 386 ASSERT_EQ(f.parameters.at("cbr"), "1"); 387 ASSERT_NE(f.parameters.find("ptime"), f.parameters.end()); 388 ASSERT_EQ(f.parameters.at("ptime"), "999"); 389 ASSERT_NE(f.parameters.find("minptime"), f.parameters.end()); 390 ASSERT_EQ(f.parameters.at("minptime"), "123"); 391 ASSERT_NE(f.parameters.find("maxptime"), f.parameters.end()); 392 ASSERT_EQ(f.parameters.at("maxptime"), "789"); 393 } 394 } 395 396 TEST_F(AudioConduitTest, TestConfigureReceiveMediaCodecs) { 397 mControl.Update([&](auto& aControl) { 398 // just default opus stereo 399 std::vector<mozilla::AudioCodecConfig> codecs; 400 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, false)); 401 aControl.mAudioRecvCodecs = codecs; 402 aControl.mReceiving = true; 403 }); 404 ASSERT_TRUE(Call()->mAudioReceiveConfig); 405 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, ""); 406 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 407 { 408 const webrtc::SdpAudioFormat& f = 409 Call()->mAudioReceiveConfig->decoder_map.at(114); 410 ASSERT_EQ(f.name, "opus"); 411 ASSERT_EQ(f.clockrate_hz, 48000); 412 ASSERT_EQ(f.num_channels, 2UL); 413 ASSERT_EQ(f.parameters.at("stereo"), "1"); 414 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 415 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 416 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 417 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 418 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 419 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 420 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 421 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 422 } 423 424 mControl.Update([&](auto& aControl) { 425 // multiple codecs 426 std::vector<mozilla::AudioCodecConfig> codecs; 427 codecs.emplace_back(AudioCodecConfig(9, "g722", 16000, 2, false)); 428 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, false)); 429 aControl.mAudioRecvCodecs = codecs; 430 aControl.mReceiving = true; 431 }); 432 ASSERT_TRUE(Call()->mAudioReceiveConfig); 433 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, ""); 434 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 2U); 435 { 436 const webrtc::SdpAudioFormat& f = 437 Call()->mAudioReceiveConfig->decoder_map.at(9); 438 ASSERT_EQ(f.name, "g722"); 439 ASSERT_EQ(f.clockrate_hz, 16000); 440 ASSERT_EQ(f.num_channels, 2U); 441 ASSERT_EQ(f.parameters.size(), 0U); 442 } 443 { 444 const webrtc::SdpAudioFormat& f = 445 Call()->mAudioReceiveConfig->decoder_map.at(114); 446 ASSERT_EQ(f.name, "opus"); 447 ASSERT_EQ(f.clockrate_hz, 48000); 448 ASSERT_EQ(f.num_channels, 2U); 449 ASSERT_EQ(f.parameters.at("stereo"), "1"); 450 } 451 452 mControl.Update([&](auto& aControl) { 453 // no codecs 454 std::vector<mozilla::AudioCodecConfig> codecs; 455 aControl.mAudioRecvCodecs = codecs; 456 }); 457 ASSERT_TRUE(Call()->mAudioReceiveConfig); 458 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 0U); 459 460 mControl.Update([&](auto& aControl) { 461 // invalid codec name 462 std::vector<mozilla::AudioCodecConfig> codecs; 463 codecs.emplace_back(AudioCodecConfig(114, "", 48000, 2, false)); 464 aControl.mAudioRecvCodecs = codecs; 465 }); 466 ASSERT_TRUE(Call()->mAudioReceiveConfig); 467 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 0U); 468 469 mControl.Update([&](auto& aControl) { 470 // invalid number of channels 471 std::vector<mozilla::AudioCodecConfig> codecs; 472 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 42, false)); 473 aControl.mAudioRecvCodecs = codecs; 474 }); 475 ASSERT_TRUE(Call()->mAudioReceiveConfig); 476 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 0U); 477 } 478 479 TEST_F(AudioConduitTest, TestConfigureReceiveOpusMono) { 480 mControl.Update([&](auto& aControl) { 481 // opus mono 482 std::vector<mozilla::AudioCodecConfig> codecs; 483 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 1, false)); 484 aControl.mAudioRecvCodecs = codecs; 485 aControl.mReceiving = true; 486 }); 487 ASSERT_TRUE(Call()->mAudioReceiveConfig); 488 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, ""); 489 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 490 { 491 const webrtc::SdpAudioFormat& f = 492 Call()->mAudioReceiveConfig->decoder_map.at(114); 493 ASSERT_EQ(f.name, "opus"); 494 ASSERT_EQ(f.clockrate_hz, 48000); 495 ASSERT_EQ(f.num_channels, 1UL); 496 ASSERT_EQ(f.parameters.find("stereo"), f.parameters.end()); 497 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 498 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 499 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 500 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 501 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 502 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 503 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 504 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 505 } 506 } 507 508 TEST_F(AudioConduitTest, TestConfigureReceiveOpusDtx) { 509 mControl.Update([&](auto& aControl) { 510 // opus mono 511 std::vector<mozilla::AudioCodecConfig> codecs; 512 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, false)); 513 codecs[0].mDTXEnabled = true; 514 aControl.mAudioRecvCodecs = codecs; 515 aControl.mReceiving = true; 516 }); 517 ASSERT_TRUE(Call()->mAudioReceiveConfig); 518 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, ""); 519 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 520 { 521 const webrtc::SdpAudioFormat& f = 522 Call()->mAudioReceiveConfig->decoder_map.at(114); 523 ASSERT_EQ(f.name, "opus"); 524 ASSERT_EQ(f.clockrate_hz, 48000); 525 ASSERT_EQ(f.num_channels, 2UL); 526 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 527 ASSERT_EQ(f.parameters.at("stereo"), "1"); 528 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 529 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 530 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 531 ASSERT_NE(f.parameters.find("usedtx"), f.parameters.end()); 532 ASSERT_EQ(f.parameters.at("usedtx"), "1"); 533 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 534 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 535 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 536 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 537 } 538 } 539 540 TEST_F(AudioConduitTest, TestConfigureReceiveOpusFEC) { 541 mControl.Update([&](auto& aControl) { 542 // opus with inband Forward Error Correction 543 std::vector<mozilla::AudioCodecConfig> codecs; 544 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, true)); 545 aControl.mAudioRecvCodecs = codecs; 546 aControl.mReceiving = true; 547 }); 548 ASSERT_TRUE(Call()->mAudioReceiveConfig); 549 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, ""); 550 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 551 { 552 const webrtc::SdpAudioFormat& f = 553 Call()->mAudioReceiveConfig->decoder_map.at(114); 554 ASSERT_EQ(f.name, "opus"); 555 ASSERT_EQ(f.clockrate_hz, 48000); 556 ASSERT_EQ(f.num_channels, 2UL); 557 ASSERT_NE(f.parameters.find("stereo"), f.parameters.end()); 558 ASSERT_EQ(f.parameters.at("stereo"), "1"); 559 ASSERT_NE(f.parameters.find("useinbandfec"), f.parameters.end()); 560 ASSERT_EQ(f.parameters.at("useinbandfec"), "1"); 561 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 562 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 563 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 564 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 565 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 566 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 567 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 568 } 569 } 570 571 TEST_F(AudioConduitTest, TestConfigureReceiveOpusMaxPlaybackRate) { 572 std::vector<mozilla::AudioCodecConfig> codecs; 573 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, false)); 574 575 mControl.Update([&](auto& aControl) { 576 codecs[0].mMaxPlaybackRate = 0; 577 aControl.mAudioRecvCodecs = codecs; 578 aControl.mReceiving = true; 579 }); 580 ASSERT_TRUE(Call()->mAudioReceiveConfig); 581 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 582 { 583 const webrtc::SdpAudioFormat& f = 584 Call()->mAudioReceiveConfig->decoder_map.at(114); 585 ASSERT_EQ(f.name, "opus"); 586 ASSERT_EQ(f.clockrate_hz, 48000); 587 ASSERT_EQ(f.num_channels, 2UL); 588 ASSERT_EQ(f.parameters.at("stereo"), "1"); 589 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 590 ASSERT_EQ(f.parameters.count("maxplaybackrate"), 0U); 591 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 592 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 593 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 594 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 595 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 596 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 597 } 598 599 mControl.Update([&](auto& aControl) { 600 codecs[0].mMaxPlaybackRate = 8000; 601 aControl.mAudioRecvCodecs = codecs; 602 }); 603 ASSERT_TRUE(Call()->mAudioReceiveConfig); 604 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 605 { 606 const webrtc::SdpAudioFormat& f = 607 Call()->mAudioReceiveConfig->decoder_map.at(114); 608 ASSERT_EQ(f.name, "opus"); 609 ASSERT_EQ(f.clockrate_hz, 48000); 610 ASSERT_EQ(f.num_channels, 2UL); 611 ASSERT_EQ(f.parameters.at("stereo"), "1"); 612 ASSERT_EQ(f.parameters.at("maxplaybackrate"), "8000"); 613 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 614 ASSERT_EQ(f.parameters.find("maxaveragebitrate"), f.parameters.end()); 615 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 616 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 617 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 618 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 619 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 620 } 621 } 622 623 TEST_F(AudioConduitTest, TestConfigureReceiveOpusMaxAverageBitrate) { 624 std::vector<mozilla::AudioCodecConfig> codecs; 625 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, false)); 626 mControl.Update([&](auto& aControl) { 627 codecs[0].mMaxAverageBitrate = 0; 628 aControl.mAudioRecvCodecs = codecs; 629 aControl.mReceiving = true; 630 }); 631 ASSERT_TRUE(Call()->mAudioReceiveConfig); 632 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 633 { 634 const webrtc::SdpAudioFormat& f = 635 Call()->mAudioReceiveConfig->decoder_map.at(114); 636 ASSERT_EQ(f.name, "opus"); 637 ASSERT_EQ(f.clockrate_hz, 48000); 638 ASSERT_EQ(f.num_channels, 2UL); 639 ASSERT_EQ(f.parameters.at("stereo"), "1"); 640 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 641 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 642 ASSERT_EQ(f.parameters.count("maxaveragebitrate"), 0U); 643 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 644 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 645 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 646 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 647 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 648 } 649 650 mControl.Update([&](auto& aControl) { 651 codecs[0].mMaxAverageBitrate = 8000; 652 aControl.mAudioRecvCodecs = codecs; 653 }); 654 ASSERT_TRUE(Call()->mAudioReceiveConfig); 655 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 656 { 657 const webrtc::SdpAudioFormat& f = 658 Call()->mAudioReceiveConfig->decoder_map.at(114); 659 ASSERT_EQ(f.name, "opus"); 660 ASSERT_EQ(f.clockrate_hz, 48000); 661 ASSERT_EQ(f.num_channels, 2UL); 662 ASSERT_EQ(f.parameters.at("stereo"), "1"); 663 ASSERT_EQ(f.parameters.find("useinbandfec"), f.parameters.end()); 664 ASSERT_EQ(f.parameters.find("maxplaybackrate"), f.parameters.end()); 665 ASSERT_EQ(f.parameters.at("maxaveragebitrate"), "8000"); 666 ASSERT_EQ(f.parameters.find("usedtx"), f.parameters.end()); 667 ASSERT_EQ(f.parameters.find("cbr"), f.parameters.end()); 668 ASSERT_EQ(f.parameters.find("ptime"), f.parameters.end()); 669 ASSERT_EQ(f.parameters.find("minptime"), f.parameters.end()); 670 ASSERT_EQ(f.parameters.find("maxptime"), f.parameters.end()); 671 } 672 } 673 674 TEST_F(AudioConduitTest, TestConfigureReceiveOpusAllParameters) { 675 std::vector<mozilla::AudioCodecConfig> codecs; 676 codecs.emplace_back(AudioCodecConfig(114, "opus", 48000, 2, true)); 677 678 mControl.Update([&](auto& aControl) { 679 codecs[0].mMaxPlaybackRate = 8000; 680 codecs[0].mMaxAverageBitrate = 9000; 681 codecs[0].mDTXEnabled = true; 682 codecs[0].mCbrEnabled = true; 683 codecs[0].mFrameSizeMs = 10; 684 codecs[0].mMinFrameSizeMs = 20; 685 codecs[0].mMaxFrameSizeMs = 30; 686 687 aControl.mAudioRecvCodecs = codecs; 688 aControl.mReceiving = true; 689 }); 690 ASSERT_TRUE(Call()->mAudioReceiveConfig); 691 ASSERT_EQ(Call()->mAudioReceiveConfig->decoder_map.size(), 1U); 692 { 693 const webrtc::SdpAudioFormat& f = 694 Call()->mAudioReceiveConfig->decoder_map.at(114); 695 ASSERT_EQ(f.name, "opus"); 696 ASSERT_EQ(f.clockrate_hz, 48000); 697 ASSERT_EQ(f.num_channels, 2UL); 698 ASSERT_EQ(f.parameters.at("stereo"), "1"); 699 ASSERT_EQ(f.parameters.at("useinbandfec"), "1"); 700 ASSERT_EQ(f.parameters.at("maxplaybackrate"), "8000"); 701 ASSERT_EQ(f.parameters.at("maxaveragebitrate"), "9000"); 702 ASSERT_EQ(f.parameters.at("usedtx"), "1"); 703 ASSERT_EQ(f.parameters.at("cbr"), "1"); 704 ASSERT_EQ(f.parameters.at("ptime"), "10"); 705 ASSERT_EQ(f.parameters.at("minptime"), "20"); 706 ASSERT_EQ(f.parameters.at("maxptime"), "30"); 707 } 708 } 709 710 TEST_F(AudioConduitTest, TestSetLocalRTPExtensions) { 711 // Empty extensions 712 mControl.Update([&](auto& aControl) { 713 RtpExtList extensions; 714 aControl.mLocalRecvRtpExtensions = extensions; 715 aControl.mReceiving = true; 716 aControl.mLocalSendRtpExtensions = extensions; 717 aControl.mTransmitting = true; 718 }); 719 ASSERT_TRUE(Call()->mAudioReceiveConfig); 720 ASSERT_TRUE(Call()->mAudioSendConfig); 721 ASSERT_TRUE(Call()->mAudioSendConfig->rtp.extensions.empty()); 722 723 // Audio level 724 mControl.Update([&](auto& aControl) { 725 RtpExtList extensions; 726 webrtc::RtpExtension extension; 727 extension.uri = webrtc::RtpExtension::kAudioLevelUri; 728 extensions.emplace_back(extension); 729 aControl.mLocalRecvRtpExtensions = extensions; 730 aControl.mLocalSendRtpExtensions = extensions; 731 }); 732 ASSERT_TRUE(Call()->mAudioReceiveConfig); 733 ASSERT_TRUE(Call()->mAudioSendConfig); 734 ASSERT_EQ(Call()->mAudioSendConfig->rtp.extensions.back().uri, 735 webrtc::RtpExtension::kAudioLevelUri); 736 737 // Contributing sources audio level 738 mControl.Update([&](auto& aControl) { 739 // We do not support configuring sending csrc-audio-level. It will be 740 // ignored. 741 RtpExtList extensions; 742 webrtc::RtpExtension extension; 743 extension.uri = webrtc::RtpExtension::kCsrcAudioLevelsUri; 744 extensions.emplace_back(extension); 745 aControl.mLocalRecvRtpExtensions = extensions; 746 aControl.mLocalSendRtpExtensions = extensions; 747 }); 748 ASSERT_TRUE(Call()->mAudioReceiveConfig); 749 ASSERT_TRUE(Call()->mAudioSendConfig); 750 ASSERT_TRUE(Call()->mAudioSendConfig->rtp.extensions.empty()); 751 752 // Mid 753 mControl.Update([&](auto& aControl) { 754 // We do not support configuring receiving MId. It will be ignored. 755 RtpExtList extensions; 756 webrtc::RtpExtension extension; 757 extension.uri = webrtc::RtpExtension::kMidUri; 758 extensions.emplace_back(extension); 759 aControl.mLocalRecvRtpExtensions = extensions; 760 aControl.mLocalSendRtpExtensions = extensions; 761 }); 762 ASSERT_TRUE(Call()->mAudioReceiveConfig); 763 ASSERT_EQ(Call()->mAudioSendConfig->rtp.extensions.back().uri, 764 webrtc::RtpExtension::kMidUri); 765 } 766 767 TEST_F(AudioConduitTest, TestSyncGroup) { 768 mControl.Update([&](auto& aControl) { 769 aControl.mSyncGroup = "test"; 770 aControl.mReceiving = true; 771 }); 772 ASSERT_TRUE(Call()->mAudioReceiveConfig); 773 ASSERT_EQ(Call()->mAudioReceiveConfig->sync_group, "test"); 774 } 775 776 TEST_F(AudioConduitTest, TestConfigureSendMediaCodecOpusMaxBr) { 777 using Config = AudioEncoderOpusConfig; 778 mControl.Update([&](auto& aControl) { 779 aControl.mTransmitting = true; 780 AudioCodecConfig codecConfig(109, "opus", 48000, 2, /*FECEnabled=*/true); 781 codecConfig.mEncodingConstraints.maxBitrateBps = Some(5000); 782 aControl.mAudioSendCodec = Some(codecConfig); 783 }); 784 ASSERT_TRUE(Call()->mAudioSendConfig); 785 EXPECT_EQ(Call()->mAudioSendConfig->send_codec_spec->target_bitrate_bps, 786 std::clamp(5000, Config::kMinBitrateBps, Config::kMaxBitrateBps)); 787 788 mControl.Update([&](auto& aControl) { 789 auto c = aControl.mAudioSendCodec.Ref(); 790 c->mEncodingConstraints.maxBitrateBps = Some(256000); 791 aControl.mAudioSendCodec = c; 792 }); 793 ASSERT_TRUE(Call()->mAudioSendConfig); 794 EXPECT_EQ(Call()->mAudioSendConfig->send_codec_spec->target_bitrate_bps, 795 std::clamp(256000, Config::kMinBitrateBps, Config::kMaxBitrateBps)); 796 } 797 798 TEST_F(AudioConduitTest, TestConfigureSendMediaCodecG722MaxBr) { 799 constexpr int kFixedG722BitratePerChannelBps = 64000; 800 mControl.Update([&](auto& aControl) { 801 aControl.mTransmitting = true; 802 AudioCodecConfig codecConfig(9, "G722", 8000, 1, /*FECEnabled=*/false); 803 codecConfig.mEncodingConstraints.maxBitrateBps = Some(5000); 804 aControl.mAudioSendCodec = Some(codecConfig); 805 }); 806 ASSERT_TRUE(Call()->mAudioSendConfig); 807 EXPECT_EQ(Call()->mAudioSendConfig->send_codec_spec->target_bitrate_bps, 808 kFixedG722BitratePerChannelBps); 809 810 mControl.Update([&](auto& aControl) { 811 AudioCodecConfig codecConfig(9, "G722", 8000, 2, /*FECEnabled=*/false); 812 codecConfig.mEncodingConstraints.maxBitrateBps = Some(256000); 813 aControl.mAudioSendCodec = Some(codecConfig); 814 }); 815 ASSERT_TRUE(Call()->mAudioSendConfig); 816 EXPECT_EQ(Call()->mAudioSendConfig->send_codec_spec->target_bitrate_bps, 817 2 * kFixedG722BitratePerChannelBps); 818 } 819 820 } // End namespace test.