tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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.