tor-browser

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

audio_channel_unittest.cc (15460B)


      1 /*
      2 *  Copyright (c) 2020 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 "audio/voip/audio_channel.h"
     12 
     13 #include <cstdint>
     14 #include <cstring>
     15 #include <memory>
     16 #include <optional>
     17 #include <utility>
     18 
     19 #include "absl/functional/any_invocable.h"
     20 #include "api/array_view.h"
     21 #include "api/audio/audio_frame.h"
     22 #include "api/audio/audio_mixer.h"
     23 #include "api/audio_codecs/audio_decoder_factory.h"
     24 #include "api/audio_codecs/audio_encoder_factory.h"
     25 #include "api/audio_codecs/audio_format.h"
     26 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
     27 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
     28 #include "api/environment/environment.h"
     29 #include "api/environment/environment_factory.h"
     30 #include "api/make_ref_counted.h"
     31 #include "api/scoped_refptr.h"
     32 #include "api/voip/voip_statistics.h"
     33 #include "audio/voip/test/mock_task_queue.h"
     34 #include "modules/audio_mixer/audio_mixer_impl.h"
     35 #include "modules/audio_mixer/sine_wave_generator.h"
     36 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     37 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     38 #include "system_wrappers/include/clock.h"
     39 #include "test/gmock.h"
     40 #include "test/gtest.h"
     41 #include "test/mock_transport.h"
     42 
     43 namespace webrtc {
     44 namespace {
     45 
     46 using ::testing::Invoke;
     47 using ::testing::NiceMock;
     48 using ::testing::Return;
     49 using ::testing::Unused;
     50 using ::testing::WithArg;
     51 
     52 constexpr uint64_t kStartTime = 123456789;
     53 constexpr uint32_t kLocalSsrc = 0xdeadc0de;
     54 constexpr int16_t kAudioLevel = 3004;  // used for sine wave level
     55 constexpr int kPcmuPayload = 0;
     56 
     57 class AudioChannelTest : public ::testing::Test {
     58 public:
     59  const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};
     60 
     61  AudioChannelTest()
     62      : fake_clock_(kStartTime),
     63        wave_generator_(1000.0, kAudioLevel),
     64        env_(CreateEnvironment(
     65            &fake_clock_,
     66            std::make_unique<MockTaskQueueFactory>(&task_queue_))) {
     67    audio_mixer_ = AudioMixerImpl::Create();
     68    encoder_factory_ = CreateBuiltinAudioEncoderFactory();
     69    decoder_factory_ = CreateBuiltinAudioDecoderFactory();
     70 
     71    // By default, run the queued task immediately.
     72    ON_CALL(task_queue_, PostTaskImpl)
     73        .WillByDefault(WithArg<0>(
     74            [](absl::AnyInvocable<void()&&> task) { std::move(task)(); }));
     75  }
     76 
     77  void SetUp() override { audio_channel_ = CreateAudioChannel(kLocalSsrc); }
     78 
     79  void TearDown() override { audio_channel_ = nullptr; }
     80 
     81  scoped_refptr<AudioChannel> CreateAudioChannel(uint32_t ssrc) {
     82    // Use same audio mixer here for simplicity sake as we are not checking
     83    // audio activity of RTP in our testcases. If we need to do test on audio
     84    // signal activity then we need to assign audio mixer for each channel.
     85    // Also this uses the same transport object for different audio channel to
     86    // simplify network routing logic.
     87    scoped_refptr<AudioChannel> audio_channel = make_ref_counted<AudioChannel>(
     88        env_, &transport_, ssrc, audio_mixer_.get(), decoder_factory_);
     89    audio_channel->SetEncoder(
     90        kPcmuPayload, kPcmuFormat,
     91        encoder_factory_->Create(env_, kPcmuFormat,
     92                                 {.payload_type = kPcmuPayload}));
     93    audio_channel->SetReceiveCodecs({{kPcmuPayload, kPcmuFormat}});
     94    audio_channel->StartSend();
     95    audio_channel->StartPlay();
     96    return audio_channel;
     97  }
     98 
     99  std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
    100    auto frame = std::make_unique<AudioFrame>();
    101    frame->sample_rate_hz_ = kPcmuFormat.clockrate_hz;
    102    frame->samples_per_channel_ = kPcmuFormat.clockrate_hz / 100;  // 10 ms.
    103    frame->num_channels_ = kPcmuFormat.num_channels;
    104    frame->timestamp_ = frame->samples_per_channel_ * order;
    105    wave_generator_.GenerateNextFrame(frame.get());
    106    return frame;
    107  }
    108 
    109  SimulatedClock fake_clock_;
    110  SineWaveGenerator wave_generator_;
    111  NiceMock<MockTransport> transport_;
    112  NiceMock<MockTaskQueue> task_queue_;
    113  const Environment env_;
    114  scoped_refptr<AudioMixer> audio_mixer_;
    115  scoped_refptr<AudioDecoderFactory> decoder_factory_;
    116  scoped_refptr<AudioEncoderFactory> encoder_factory_;
    117  scoped_refptr<AudioChannel> audio_channel_;
    118 };
    119 
    120 // Validate RTP packet generation by feeding audio frames with sine wave.
    121 // Resulted RTP packet is looped back into AudioChannel and gets decoded into
    122 // audio frame to see if it has some signal to indicate its validity.
    123 TEST_F(AudioChannelTest, PlayRtpByLocalLoop) {
    124  auto loop_rtp = [&](ArrayView<const uint8_t> packet, Unused) {
    125    audio_channel_->ReceivedRTPPacket(packet);
    126    return true;
    127  };
    128  EXPECT_CALL(transport_, SendRtp).WillOnce(Invoke(loop_rtp));
    129 
    130  auto audio_sender = audio_channel_->GetAudioSender();
    131  audio_sender->SendAudioData(GetAudioFrame(0));
    132  audio_sender->SendAudioData(GetAudioFrame(1));
    133 
    134  AudioFrame empty_frame, audio_frame;
    135  empty_frame.Mute();
    136  empty_frame.mutable_data();  // This will zero out the data.
    137  audio_frame.CopyFrom(empty_frame);
    138  audio_mixer_->Mix(/*number_of_channels*/ 1, &audio_frame);
    139 
    140  // We expect now audio frame to pick up something.
    141  EXPECT_NE(memcmp(empty_frame.data(), audio_frame.data(),
    142                   AudioFrame::kMaxDataSizeBytes),
    143            0);
    144 }
    145 
    146 // Validate assigned local SSRC is resulted in RTP packet.
    147 TEST_F(AudioChannelTest, VerifyLocalSsrcAsAssigned) {
    148  RtpPacketReceived rtp;
    149  auto loop_rtp = [&](ArrayView<const uint8_t> packet, Unused) {
    150    rtp.Parse(packet);
    151    return true;
    152  };
    153  EXPECT_CALL(transport_, SendRtp).WillOnce(Invoke(loop_rtp));
    154 
    155  auto audio_sender = audio_channel_->GetAudioSender();
    156  audio_sender->SendAudioData(GetAudioFrame(0));
    157  audio_sender->SendAudioData(GetAudioFrame(1));
    158 
    159  EXPECT_EQ(rtp.Ssrc(), kLocalSsrc);
    160 }
    161 
    162 // Check metrics after processing an RTP packet.
    163 TEST_F(AudioChannelTest, TestIngressStatistics) {
    164  auto loop_rtp = [&](ArrayView<const uint8_t> packet, Unused) {
    165    audio_channel_->ReceivedRTPPacket(packet);
    166    return true;
    167  };
    168  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(loop_rtp));
    169 
    170  auto audio_sender = audio_channel_->GetAudioSender();
    171  audio_sender->SendAudioData(GetAudioFrame(0));
    172  audio_sender->SendAudioData(GetAudioFrame(1));
    173 
    174  AudioFrame audio_frame;
    175  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    176  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    177 
    178  std::optional<IngressStatistics> ingress_stats =
    179      audio_channel_->GetIngressStatistics();
    180  EXPECT_TRUE(ingress_stats);
    181  EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 160ULL);
    182  EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 0ULL);
    183  EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 0ULL);
    184  EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
    185  EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
    186  EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
    187  // To extract the jitter buffer length in millisecond, jitter_buffer_delay_ms
    188  // needs to be divided by jitter_buffer_emitted_count (number of samples).
    189  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 1600ULL);
    190  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 160ULL);
    191  EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
    192  EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
    193  EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
    194  EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.02);
    195 
    196  // Now without any RTP pending in jitter buffer pull more.
    197  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    198  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    199 
    200  // Send another RTP packet to intentionally break PLC.
    201  audio_sender->SendAudioData(GetAudioFrame(2));
    202  audio_sender->SendAudioData(GetAudioFrame(3));
    203 
    204  ingress_stats = audio_channel_->GetIngressStatistics();
    205  EXPECT_TRUE(ingress_stats);
    206  EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 320ULL);
    207  EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 168ULL);
    208  EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 1ULL);
    209  EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
    210  EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
    211  EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
    212  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 1600ULL);
    213  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 160ULL);
    214  EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
    215  EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
    216  EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
    217  EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.04);
    218 
    219  // Pull the last RTP packet.
    220  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    221  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    222 
    223  ingress_stats = audio_channel_->GetIngressStatistics();
    224  EXPECT_TRUE(ingress_stats);
    225  EXPECT_EQ(ingress_stats->neteq_stats.total_samples_received, 480ULL);
    226  EXPECT_EQ(ingress_stats->neteq_stats.concealed_samples, 168ULL);
    227  EXPECT_EQ(ingress_stats->neteq_stats.concealment_events, 1ULL);
    228  EXPECT_EQ(ingress_stats->neteq_stats.inserted_samples_for_deceleration, 0ULL);
    229  EXPECT_EQ(ingress_stats->neteq_stats.removed_samples_for_acceleration, 0ULL);
    230  EXPECT_EQ(ingress_stats->neteq_stats.silent_concealed_samples, 0ULL);
    231  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_delay_ms, 3200ULL);
    232  EXPECT_EQ(ingress_stats->neteq_stats.jitter_buffer_emitted_count, 320ULL);
    233  EXPECT_GT(ingress_stats->neteq_stats.jitter_buffer_target_delay_ms, 0ULL);
    234  EXPECT_EQ(ingress_stats->neteq_stats.interruption_count, 0);
    235  EXPECT_EQ(ingress_stats->neteq_stats.total_interruption_duration_ms, 0);
    236  EXPECT_DOUBLE_EQ(ingress_stats->total_duration, 0.06);
    237 }
    238 
    239 // Check ChannelStatistics metric after processing RTP and RTCP packets.
    240 TEST_F(AudioChannelTest, TestChannelStatistics) {
    241  auto loop_rtp = [&](ArrayView<const uint8_t> packet, Unused) {
    242    audio_channel_->ReceivedRTPPacket(packet);
    243    return true;
    244  };
    245  auto loop_rtcp = [&](ArrayView<const uint8_t> packet, Unused) {
    246    audio_channel_->ReceivedRTCPPacket(packet);
    247    return true;
    248  };
    249  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(loop_rtp));
    250  EXPECT_CALL(transport_, SendRtcp).WillRepeatedly(Invoke(loop_rtcp));
    251 
    252  // Simulate microphone giving audio frame (10 ms). This will trigger transport
    253  // to send RTP as handled in loop_rtp above.
    254  auto audio_sender = audio_channel_->GetAudioSender();
    255  audio_sender->SendAudioData(GetAudioFrame(0));
    256  audio_sender->SendAudioData(GetAudioFrame(1));
    257 
    258  // Simulate speaker requesting audio frame (10 ms). This will trigger VoIP
    259  // engine to fetch audio samples from RTP packets stored in jitter buffer.
    260  AudioFrame audio_frame;
    261  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    262  audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    263 
    264  // Force sending RTCP SR report in order to have remote_rtcp field available
    265  // in channel statistics. This will trigger transport to send RTCP as handled
    266  // in loop_rtcp above.
    267  audio_channel_->SendRTCPReportForTesting(kRtcpSr);
    268 
    269  std::optional<ChannelStatistics> channel_stats =
    270      audio_channel_->GetChannelStatistics();
    271  EXPECT_TRUE(channel_stats);
    272 
    273  EXPECT_EQ(channel_stats->packets_sent, 1ULL);
    274  EXPECT_EQ(channel_stats->bytes_sent, 160ULL);
    275 
    276  EXPECT_EQ(channel_stats->packets_received, 1ULL);
    277  EXPECT_EQ(channel_stats->bytes_received, 160ULL);
    278  EXPECT_EQ(channel_stats->jitter, 0);
    279  EXPECT_EQ(channel_stats->packets_lost, 0);
    280  EXPECT_EQ(channel_stats->remote_ssrc.value(), kLocalSsrc);
    281 
    282  EXPECT_TRUE(channel_stats->remote_rtcp.has_value());
    283 
    284  EXPECT_EQ(channel_stats->remote_rtcp->jitter, 0);
    285  EXPECT_EQ(channel_stats->remote_rtcp->packets_lost, 0);
    286  EXPECT_EQ(channel_stats->remote_rtcp->fraction_lost, 0);
    287  EXPECT_GT(channel_stats->remote_rtcp->last_report_received_timestamp_ms, 0);
    288  EXPECT_FALSE(channel_stats->remote_rtcp->round_trip_time.has_value());
    289 }
    290 
    291 // Check ChannelStatistics RTT metric after processing RTP and RTCP packets
    292 // using three audio channels where each represents media endpoint.
    293 //
    294 //  1) AC1 <- RTP/RTCP -> AC2
    295 //  2) AC1 <- RTP/RTCP -> AC3
    296 //
    297 // During step 1), AC1 should be able to check RTT from AC2's SSRC.
    298 // During step 2), AC1 should be able to check RTT from AC3's SSRC.
    299 TEST_F(AudioChannelTest, RttIsAvailableAfterChangeOfRemoteSsrc) {
    300  // Create AC2 and AC3.
    301  constexpr uint32_t kAc2Ssrc = 0xdeadbeef;
    302  constexpr uint32_t kAc3Ssrc = 0xdeafbeef;
    303 
    304  auto ac_2 = CreateAudioChannel(kAc2Ssrc);
    305  auto ac_3 = CreateAudioChannel(kAc3Ssrc);
    306 
    307  auto send_recv_rtp = [&](scoped_refptr<AudioChannel> rtp_sender,
    308                           scoped_refptr<AudioChannel> rtp_receiver) {
    309    // Setup routing logic via transport_.
    310    auto route_rtp = [&](ArrayView<const uint8_t> packet, Unused) {
    311      rtp_receiver->ReceivedRTPPacket(packet);
    312      return true;
    313    };
    314    ON_CALL(transport_, SendRtp).WillByDefault(route_rtp);
    315 
    316    // This will trigger route_rtp callback via transport_.
    317    rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(0));
    318    rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(1));
    319 
    320    // Process received RTP in receiver.
    321    AudioFrame audio_frame;
    322    audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    323    audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
    324 
    325    // Revert to default to avoid using reference in route_rtp lambda.
    326    ON_CALL(transport_, SendRtp).WillByDefault(Return(true));
    327  };
    328 
    329  auto send_recv_rtcp = [&](scoped_refptr<AudioChannel> rtcp_sender,
    330                            scoped_refptr<AudioChannel> rtcp_receiver) {
    331    // Setup routing logic via transport_.
    332    auto route_rtcp = [&](ArrayView<const uint8_t> packet, Unused) {
    333      rtcp_receiver->ReceivedRTCPPacket(packet);
    334      return true;
    335    };
    336    ON_CALL(transport_, SendRtcp).WillByDefault(route_rtcp);
    337 
    338    // This will trigger route_rtcp callback via transport_.
    339    rtcp_sender->SendRTCPReportForTesting(kRtcpSr);
    340 
    341    // Revert to default to avoid using reference in route_rtcp lambda.
    342    ON_CALL(transport_, SendRtcp).WillByDefault(Return(true));
    343  };
    344 
    345  // AC1 <-- RTP/RTCP --> AC2
    346  send_recv_rtp(audio_channel_, ac_2);
    347  send_recv_rtp(ac_2, audio_channel_);
    348  send_recv_rtcp(audio_channel_, ac_2);
    349  send_recv_rtcp(ac_2, audio_channel_);
    350 
    351  std::optional<ChannelStatistics> channel_stats =
    352      audio_channel_->GetChannelStatistics();
    353  ASSERT_TRUE(channel_stats);
    354  EXPECT_EQ(channel_stats->remote_ssrc, kAc2Ssrc);
    355  ASSERT_TRUE(channel_stats->remote_rtcp);
    356  EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
    357 
    358  // AC1 <-- RTP/RTCP --> AC3
    359  send_recv_rtp(audio_channel_, ac_3);
    360  send_recv_rtp(ac_3, audio_channel_);
    361  send_recv_rtcp(audio_channel_, ac_3);
    362  send_recv_rtcp(ac_3, audio_channel_);
    363 
    364  channel_stats = audio_channel_->GetChannelStatistics();
    365  ASSERT_TRUE(channel_stats);
    366  EXPECT_EQ(channel_stats->remote_ssrc, kAc3Ssrc);
    367  ASSERT_TRUE(channel_stats->remote_rtcp);
    368  EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
    369 }
    370 
    371 }  // namespace
    372 }  // namespace webrtc