tor-browser

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

channel_send_unittest.cc (20363B)


      1 /*
      2 *  Copyright 2023 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/channel_send.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <optional>
     17 #include <utility>
     18 #include <vector>
     19 
     20 #include "api/array_view.h"
     21 #include "api/audio/audio_frame.h"
     22 #include "api/audio_codecs/audio_encoder.h"
     23 #include "api/audio_codecs/audio_encoder_factory.h"
     24 #include "api/audio_codecs/audio_format.h"
     25 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
     26 #include "api/call/bitrate_allocation.h"
     27 #include "api/call/transport.h"
     28 #include "api/crypto/crypto_options.h"
     29 #include "api/environment/environment.h"
     30 #include "api/field_trials.h"
     31 #include "api/frame_transformer_interface.h"
     32 #include "api/make_ref_counted.h"
     33 #include "api/rtp_headers.h"
     34 #include "api/scoped_refptr.h"
     35 #include "api/test/mock_frame_transformer.h"
     36 #include "api/test/mock_transformable_audio_frame.h"
     37 #include "api/test/rtc_error_matchers.h"
     38 #include "api/transport/bitrate_settings.h"
     39 #include "api/units/data_rate.h"
     40 #include "api/units/time_delta.h"
     41 #include "api/units/timestamp.h"
     42 #include "call/rtp_transport_config.h"
     43 #include "call/rtp_transport_controller_send.h"
     44 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     45 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     46 #include "test/create_test_environment.h"
     47 #include "test/create_test_field_trials.h"
     48 #include "test/gmock.h"
     49 #include "test/gtest.h"
     50 #include "test/mock_transport.h"
     51 #include "test/time_controller/simulated_time_controller.h"
     52 #include "test/wait_until.h"
     53 
     54 namespace webrtc {
     55 namespace voe {
     56 namespace {
     57 
     58 using ::testing::Eq;
     59 using ::testing::Invoke;
     60 using ::testing::IsTrue;
     61 using ::testing::NiceMock;
     62 using ::testing::Return;
     63 using ::testing::SaveArg;
     64 
     65 constexpr int kRtcpIntervalMs = 1000;
     66 constexpr int kSsrc = 333;
     67 constexpr int kPayloadType = 1;
     68 constexpr int kSampleRateHz = 48000;
     69 constexpr int kRtpRateHz = 48000;
     70 
     71 BitrateConstraints GetBitrateConfig() {
     72  BitrateConstraints bitrate_config;
     73  bitrate_config.min_bitrate_bps = 10000;
     74  bitrate_config.start_bitrate_bps = 100000;
     75  bitrate_config.max_bitrate_bps = 1000000;
     76  return bitrate_config;
     77 }
     78 
     79 class ChannelSendTest : public ::testing::Test {
     80 protected:
     81  ChannelSendTest()
     82      : time_controller_(Timestamp::Seconds(1)),
     83        field_trials_(CreateTestFieldTrials()),
     84        env_(CreateTestEnvironment(
     85            {.field_trials = &field_trials_, .time = &time_controller_})),
     86        transport_controller_(
     87            RtpTransportConfig{.env = env_,
     88                               .bitrate_config = GetBitrateConfig()}) {
     89    channel_ = voe::CreateChannelSend(env_, &transport_, nullptr, nullptr,
     90                                      crypto_options_, false, kRtcpIntervalMs,
     91                                      kSsrc, nullptr, &transport_controller_);
     92    encoder_factory_ = CreateBuiltinAudioEncoderFactory();
     93    SdpAudioFormat opus = SdpAudioFormat("opus", kRtpRateHz, 2);
     94    std::unique_ptr<AudioEncoder> encoder =
     95        encoder_factory_->Create(env_, opus, {.payload_type = kPayloadType});
     96    channel_->SetEncoder(kPayloadType, opus, std::move(encoder));
     97    transport_controller_.EnsureStarted();
     98    channel_->RegisterSenderCongestionControlObjects(&transport_controller_);
     99    ON_CALL(transport_, SendRtcp).WillByDefault(Return(true));
    100    ON_CALL(transport_, SendRtp).WillByDefault(Return(true));
    101  }
    102 
    103  std::unique_ptr<AudioFrame> CreateAudioFrame(uint8_t data_init_value = 0) {
    104    auto frame = std::make_unique<AudioFrame>();
    105    frame->sample_rate_hz_ = kSampleRateHz;
    106    frame->samples_per_channel_ = kSampleRateHz / 100;
    107    frame->num_channels_ = 1;
    108    frame->set_absolute_capture_timestamp_ms(
    109        time_controller_.GetClock()->TimeInMilliseconds());
    110    int16_t* dest = frame->mutable_data();
    111    for (size_t i = 0; i < frame->samples_per_channel_ * frame->num_channels_;
    112         i++, dest++) {
    113      *dest = data_init_value;
    114    }
    115    return frame;
    116  }
    117 
    118  void ProcessNextFrame(std::unique_ptr<AudioFrame> audio_frame) {
    119    channel_->ProcessAndEncodeAudio(std::move(audio_frame));
    120    // Advance time to process the task queue.
    121    time_controller_.AdvanceTime(TimeDelta::Millis(10));
    122  }
    123 
    124  void ProcessNextFrame() { ProcessNextFrame(CreateAudioFrame()); }
    125 
    126  GlobalSimulatedTimeController time_controller_;
    127  FieldTrials field_trials_;
    128  Environment env_;
    129  NiceMock<MockTransport> transport_;
    130  CryptoOptions crypto_options_;
    131  RtpTransportControllerSend transport_controller_;
    132  std::unique_ptr<ChannelSendInterface> channel_;
    133  scoped_refptr<AudioEncoderFactory> encoder_factory_;
    134 };
    135 
    136 TEST_F(ChannelSendTest, StopSendShouldResetEncoder) {
    137  channel_->StartSend();
    138  // Insert two frames which should trigger a new packet.
    139  EXPECT_CALL(transport_, SendRtp).Times(1);
    140  ProcessNextFrame();
    141  ProcessNextFrame();
    142 
    143  EXPECT_CALL(transport_, SendRtp).Times(0);
    144  ProcessNextFrame();
    145  // StopSend should clear the previous audio frame stored in the encoder.
    146  channel_->StopSend();
    147 
    148  channel_->StartSend();
    149  // The following frame should not trigger a new packet since the encoder
    150  // needs 20 ms audio.
    151  EXPECT_CALL(transport_, SendRtp).Times(0);
    152  ProcessNextFrame();
    153 }
    154 
    155 TEST_F(ChannelSendTest, IncreaseRtpTimestampByPauseDuration) {
    156  channel_->StartSend();
    157  uint32_t timestamp;
    158  int sent_packets = 0;
    159  auto send_rtp = [&](ArrayView<const uint8_t> data,
    160                      const PacketOptions& /* options */) {
    161    ++sent_packets;
    162    RtpPacketReceived packet;
    163    packet.Parse(data);
    164    timestamp = packet.Timestamp();
    165    return true;
    166  };
    167  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    168  ProcessNextFrame();
    169  ProcessNextFrame();
    170  EXPECT_EQ(sent_packets, 1);
    171  uint32_t first_timestamp = timestamp;
    172  channel_->StopSend();
    173  time_controller_.AdvanceTime(TimeDelta::Seconds(10));
    174  channel_->StartSend();
    175 
    176  ProcessNextFrame();
    177  ProcessNextFrame();
    178  EXPECT_EQ(sent_packets, 2);
    179  int64_t timestamp_gap_ms =
    180      static_cast<int64_t>(timestamp - first_timestamp) * 1000 / kRtpRateHz;
    181  EXPECT_EQ(timestamp_gap_ms, 10020);
    182 }
    183 
    184 TEST_F(ChannelSendTest, FrameTransformerGetsCorrectTimestamp) {
    185  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    186      make_ref_counted<MockFrameTransformer>();
    187  channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
    188  scoped_refptr<TransformedFrameCallback> callback;
    189  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    190      .WillOnce(SaveArg<0>(&callback));
    191  EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
    192 
    193  std::optional<uint32_t> sent_timestamp;
    194  auto send_rtp = [&](ArrayView<const uint8_t> data,
    195                      const PacketOptions& /* options */) {
    196    RtpPacketReceived packet;
    197    packet.Parse(data);
    198    if (!sent_timestamp) {
    199      sent_timestamp = packet.Timestamp();
    200    }
    201    return true;
    202  };
    203  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    204 
    205  channel_->StartSend();
    206  int64_t transformable_frame_timestamp = -1;
    207  EXPECT_CALL(*mock_frame_transformer, Transform)
    208      .WillOnce([&](std::unique_ptr<TransformableFrameInterface> frame) {
    209        transformable_frame_timestamp = frame->GetTimestamp();
    210        callback->OnTransformedFrame(std::move(frame));
    211      });
    212  // Insert two frames which should trigger a new packet.
    213  ProcessNextFrame();
    214  ProcessNextFrame();
    215 
    216  // Ensure the RTP timestamp on the frame passed to the transformer
    217  // includes the RTP offset and matches the actual RTP timestamp on the sent
    218  // packet.
    219  EXPECT_THAT(
    220      WaitUntil([&] { return 0 + channel_->GetRtpRtcp()->StartTimestamp(); },
    221                Eq(transformable_frame_timestamp)),
    222      IsRtcOk());
    223  EXPECT_THAT(WaitUntil([&] { return sent_timestamp; }, IsTrue()), IsRtcOk());
    224  EXPECT_EQ(*sent_timestamp, transformable_frame_timestamp);
    225 }
    226 
    227 // Ensure that AudioLevel calculations are performed correctly per-packet even
    228 // if there's an async Encoded Frame Transform happening.
    229 TEST_F(ChannelSendTest, AudioLevelsAttachedToCorrectTransformedFrame) {
    230  channel_->SetSendAudioLevelIndicationStatus(true, /*id=*/1);
    231  RtpPacketReceived::ExtensionManager extension_manager;
    232  extension_manager.RegisterByType(1, kRtpExtensionAudioLevel);
    233 
    234  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    235      make_ref_counted<MockFrameTransformer>();
    236  channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
    237  scoped_refptr<TransformedFrameCallback> callback;
    238  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    239      .WillOnce(SaveArg<0>(&callback));
    240  EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
    241 
    242  std::vector<uint8_t> sent_audio_levels;
    243  auto send_rtp = [&](ArrayView<const uint8_t> data,
    244                      const PacketOptions& /* options */) {
    245    RtpPacketReceived packet(&extension_manager);
    246    packet.Parse(data);
    247    RTPHeader header;
    248    packet.GetHeader(&header);
    249    sent_audio_levels.push_back(header.extension.audio_level()->level());
    250    return true;
    251  };
    252  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    253 
    254  channel_->StartSend();
    255  std::vector<std::unique_ptr<TransformableFrameInterface>> frames;
    256  EXPECT_CALL(*mock_frame_transformer, Transform)
    257      .Times(2)
    258      .WillRepeatedly([&](std::unique_ptr<TransformableFrameInterface> frame) {
    259        frames.push_back(std::move(frame));
    260      });
    261 
    262  // Insert two frames of 7s which should trigger a new packet.
    263  ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/7));
    264  ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/7));
    265 
    266  // Insert two more frames of 3s, meaning a second packet is
    267  // prepared and sent to the transform before the first packet has
    268  // been sent.
    269  ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/3));
    270  ProcessNextFrame(CreateAudioFrame(/*data_init_value=*/3));
    271 
    272  // Wait for both packets to be encoded and sent to the transform.
    273  EXPECT_THAT(WaitUntil([&] { return frames.size(); }, Eq(2ul)), IsRtcOk());
    274  // Complete the transforms on both frames at the same time
    275  callback->OnTransformedFrame(std::move(frames[0]));
    276  callback->OnTransformedFrame(std::move(frames[1]));
    277 
    278  // Allow things posted back to the encoder queue to run.
    279  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    280 
    281  // Ensure the audio levels on both sent packets is present and
    282  // matches their contents.
    283  EXPECT_THAT(WaitUntil([&] { return sent_audio_levels.size(); }, Eq(2ul)),
    284              IsRtcOk());
    285  // rms dbov of the packet with raw audio of 7s is 73.
    286  EXPECT_EQ(sent_audio_levels[0], 73);
    287  // rms dbov of the second packet with raw audio of 3s is 81.
    288  EXPECT_EQ(sent_audio_levels[1], 81);
    289 }
    290 
    291 // Ensure that AudioLevels are attached to frames injected into the
    292 // Encoded Frame transform.
    293 TEST_F(ChannelSendTest, AudioLevelsAttachedToInsertedTransformedFrame) {
    294  channel_->SetSendAudioLevelIndicationStatus(true, /*id=*/1);
    295  RtpPacketReceived::ExtensionManager extension_manager;
    296  extension_manager.RegisterByType(1, kRtpExtensionAudioLevel);
    297 
    298  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    299      make_ref_counted<MockFrameTransformer>();
    300  channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
    301  scoped_refptr<TransformedFrameCallback> callback;
    302  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    303      .WillOnce(SaveArg<0>(&callback));
    304  EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
    305 
    306  std::optional<uint8_t> sent_audio_level;
    307  auto send_rtp = [&](ArrayView<const uint8_t> data,
    308                      const PacketOptions& /* options */) {
    309    RtpPacketReceived packet(&extension_manager);
    310    packet.Parse(data);
    311    RTPHeader header;
    312    packet.GetHeader(&header);
    313    sent_audio_level = header.extension.audio_level()->level();
    314    return true;
    315  };
    316  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    317 
    318  channel_->StartSend();
    319 
    320  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    321  // Inject a frame encoded elsewhere.
    322  auto mock_frame = std::make_unique<NiceMock<MockTransformableAudioFrame>>();
    323  uint8_t audio_level = 67;
    324  ON_CALL(*mock_frame, AudioLevel()).WillByDefault(Return(audio_level));
    325  uint8_t payload[10];
    326  ON_CALL(*mock_frame, GetData())
    327      .WillByDefault(Return(ArrayView<uint8_t>(&payload[0], 10)));
    328  EXPECT_THAT(WaitUntil([&] { return callback; }, IsTrue()), IsRtcOk());
    329  callback->OnTransformedFrame(std::move(mock_frame));
    330 
    331  // Allow things posted back to the encoder queue to run.
    332  time_controller_.AdvanceTime(TimeDelta::Millis(10));
    333 
    334  // Ensure the audio levels is set on the sent packet.
    335  EXPECT_THAT(WaitUntil([&] { return sent_audio_level; }, IsTrue()), IsRtcOk());
    336  EXPECT_EQ(*sent_audio_level, audio_level);
    337 }
    338 
    339 // Ensure that GetUsedRate returns null if no frames are coded.
    340 TEST_F(ChannelSendTest, NoUsedRateInitially) {
    341  channel_->StartSend();
    342  auto used_rate = channel_->GetUsedRate();
    343  EXPECT_EQ(used_rate, std::nullopt);
    344 }
    345 
    346 // Ensure that GetUsedRate returns value with one coded frame.
    347 TEST_F(ChannelSendTest, ValidUsedRateWithOneCodedFrame) {
    348  channel_->StartSend();
    349  EXPECT_CALL(transport_, SendRtp).Times(1);
    350  ProcessNextFrame();
    351  ProcessNextFrame();
    352  auto used_rate = channel_->GetUsedRate();
    353  EXPECT_GT(used_rate.value().bps(), 0);
    354 }
    355 
    356 // Ensure that GetUsedRate returns value with one coded frame.
    357 TEST_F(ChannelSendTest, UsedRateIsLargerofLastTwoFrames) {
    358  channel_->StartSend();
    359  channel_->CallEncoder(
    360      [&](AudioEncoder* encoder) { encoder->OnReceivedOverhead(72); });
    361  DataRate lowrate = DataRate::BitsPerSec(40000);
    362  DataRate highrate = DataRate::BitsPerSec(80000);
    363  BitrateAllocationUpdate update;
    364  update.bwe_period = TimeDelta::Millis(100);
    365 
    366  update.target_bitrate = lowrate;
    367  channel_->OnBitrateAllocation(update);
    368  EXPECT_CALL(transport_, SendRtp).Times(1);
    369  ProcessNextFrame();
    370  ProcessNextFrame();
    371  // Last two frames have rates [32kbps, -], yielding 32kbps.
    372  auto used_rate_1 = channel_->GetUsedRate();
    373 
    374  update.target_bitrate = highrate;
    375  channel_->OnBitrateAllocation(update);
    376  EXPECT_CALL(transport_, SendRtp).Times(1);
    377  ProcessNextFrame();
    378  ProcessNextFrame();
    379  // Last two frames have rates [54kbps, 32kbps], yielding 54kbps
    380  auto used_rate_2 = channel_->GetUsedRate();
    381 
    382  update.target_bitrate = lowrate;
    383  channel_->OnBitrateAllocation(update);
    384  EXPECT_CALL(transport_, SendRtp).Times(1);
    385  ProcessNextFrame();
    386  ProcessNextFrame();
    387  // Last two frames have rates [32kbps 54kbps], yielding 54kbps
    388  auto used_rate_3 = channel_->GetUsedRate();
    389 
    390  EXPECT_GT(used_rate_2, used_rate_1);
    391  EXPECT_EQ(used_rate_3, used_rate_2);
    392 }
    393 
    394 // Test that we gracefully handle packets while the congestion control objects
    395 // are not configured. This can happen during calls
    396 // AudioSendStream::ConfigureStream
    397 TEST_F(ChannelSendTest, EnqueuePacketsGracefullyHandlesNonInitializedPacer) {
    398  EXPECT_CALL(transport_, SendRtp).Times(1);
    399  channel_->StartSend();
    400  channel_->ResetSenderCongestionControlObjects();
    401  // This should trigger a packet, but congestion control is not configured
    402  // so it should be dropped
    403  ProcessNextFrame();
    404  ProcessNextFrame();
    405 
    406  channel_->RegisterSenderCongestionControlObjects(&transport_controller_);
    407  // Now that we reconfigured the congestion control objects the new frame
    408  // should be processed
    409  ProcessNextFrame();
    410  ProcessNextFrame();
    411 }
    412 
    413 TEST_F(ChannelSendTest, ConfiguredCsrcsAreIncludedInRtpPackets) {
    414  channel_->StartSend();
    415  std::vector<uint32_t> expected_csrcs = {1, 2, 3};
    416  channel_->SetCsrcs(expected_csrcs);
    417 
    418  std::vector<uint32_t> csrcs;
    419  auto send_rtp = [&](ArrayView<const uint8_t> data,
    420                      const PacketOptions& /* options */) {
    421    RtpPacketReceived packet;
    422    packet.Parse(data);
    423    csrcs = packet.Csrcs();
    424    return true;
    425  };
    426 
    427  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    428  ProcessNextFrame();
    429  ProcessNextFrame();
    430 
    431  EXPECT_EQ(csrcs, expected_csrcs);
    432 }
    433 
    434 // Creates a frame with the given CSRCs where other values are copied from the
    435 // template.
    436 std::unique_ptr<TransformableAudioFrameInterface> CreateMockFrameWithCsrcs(
    437    const TransformableAudioFrameInterface* frame_template,
    438    const std::vector<uint32_t>& csrcs) {
    439  std::unique_ptr<MockTransformableAudioFrame> mock_frame =
    440      std::make_unique<MockTransformableAudioFrame>();
    441  EXPECT_CALL(*mock_frame, GetContributingSources)
    442      .WillRepeatedly(Return(csrcs));
    443 
    444  std::vector<uint8_t> frame_data = std::vector(
    445      frame_template->GetData().begin(), frame_template->GetData().end());
    446  ON_CALL(*mock_frame, GetData).WillByDefault(Return(frame_data));
    447 
    448  ON_CALL(*mock_frame, GetTimestamp)
    449      .WillByDefault(Return(frame_template->GetTimestamp()));
    450  ON_CALL(*mock_frame, GetPayloadType)
    451      .WillByDefault(Return(frame_template->GetPayloadType()));
    452  ON_CALL(*mock_frame, GetSsrc)
    453      .WillByDefault(Return(frame_template->GetSsrc()));
    454  ON_CALL(*mock_frame, GetMimeType)
    455      .WillByDefault(Return(frame_template->GetMimeType()));
    456  ON_CALL(*mock_frame, SequenceNumber)
    457      .WillByDefault(Return(frame_template->SequenceNumber()));
    458  ON_CALL(*mock_frame, GetDirection)
    459      .WillByDefault(Return(frame_template->GetDirection()));
    460  ON_CALL(*mock_frame, AbsoluteCaptureTimestamp)
    461      .WillByDefault(Return(frame_template->AbsoluteCaptureTimestamp()));
    462  ON_CALL(*mock_frame, Type).WillByDefault(Return(frame_template->Type()));
    463  ON_CALL(*mock_frame, AudioLevel)
    464      .WillByDefault(Return(frame_template->AudioLevel()));
    465  ON_CALL(*mock_frame, ReceiveTime)
    466      .WillByDefault(Return(frame_template->ReceiveTime()));
    467  ON_CALL(*mock_frame, CaptureTime)
    468      .WillByDefault(Return(frame_template->CaptureTime()));
    469  ON_CALL(*mock_frame, SenderCaptureTimeOffset)
    470      .WillByDefault(Return(frame_template->SenderCaptureTimeOffset()));
    471  return mock_frame;
    472 }
    473 
    474 TEST_F(ChannelSendTest, FrameTransformerTakesPrecedenceOverSetCsrcs) {
    475  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    476      make_ref_counted<MockFrameTransformer>();
    477  scoped_refptr<TransformedFrameCallback> callback;
    478  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    479      .WillOnce(SaveArg<0>(&callback));
    480  EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
    481  channel_->SetEncoderToPacketizerFrameTransformer(mock_frame_transformer);
    482 
    483  // Configure the mock frame transformer to return a frame with different CSRCs
    484  // than it is provided.
    485  std::vector<uint32_t> csrcs_provided_to_frame_transformer;
    486  std::vector<uint32_t> csrcs_output_by_frame_transformer = {1, 2, 3};
    487  EXPECT_CALL(*mock_frame_transformer, Transform)
    488      .WillRepeatedly(
    489          Invoke([&](std::unique_ptr<TransformableFrameInterface> frame) {
    490            auto audio_frame =
    491                static_cast<TransformableAudioFrameInterface*>(frame.get());
    492            csrcs_provided_to_frame_transformer.assign(
    493                audio_frame->GetContributingSources().begin(),
    494                audio_frame->GetContributingSources().end());
    495            callback->OnTransformedFrame(CreateMockFrameWithCsrcs(
    496                audio_frame, csrcs_output_by_frame_transformer));
    497          }));
    498 
    499  std::vector<uint32_t> set_csrcs = {4, 5, 6};
    500  channel_->SetCsrcs(set_csrcs);
    501  channel_->StartSend();
    502 
    503  std::vector<uint32_t> sent_csrcs;
    504  auto send_rtp = [&](ArrayView<const uint8_t> data,
    505                      const PacketOptions& /* options */) {
    506    RtpPacketReceived packet;
    507    packet.Parse(data);
    508    sent_csrcs = packet.Csrcs();
    509    return true;
    510  };
    511 
    512  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(send_rtp));
    513  ProcessNextFrame();
    514  ProcessNextFrame();
    515 
    516  EXPECT_EQ(csrcs_provided_to_frame_transformer, set_csrcs)
    517      << "The CSRCs configured in ChannelSend should be passed to the frame "
    518         "transformer.";
    519  EXPECT_EQ(sent_csrcs, csrcs_output_by_frame_transformer)
    520      << "CSRCs provided by the frame transformer should propagate to the RTP "
    521         "packet.";
    522 }
    523 
    524 }  // namespace
    525 }  // namespace voe
    526 }  // namespace webrtc