tor-browser

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

channel_receive_frame_transformer_delegate_unittest.cc (15690B)


      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/channel_receive_frame_transformer_delegate.h"
     12 
     13 #include <cstdint>
     14 #include <memory>
     15 #include <utility>
     16 
     17 #include "api/array_view.h"
     18 #include "api/frame_transformer_factory.h"
     19 #include "api/frame_transformer_interface.h"
     20 #include "api/make_ref_counted.h"
     21 #include "api/rtp_headers.h"
     22 #include "api/scoped_refptr.h"
     23 #include "api/test/mock_frame_transformer.h"
     24 #include "api/test/mock_transformable_audio_frame.h"
     25 #include "api/units/time_delta.h"
     26 #include "api/units/timestamp.h"
     27 #include "rtc_base/thread.h"
     28 #include "system_wrappers/include/ntp_time.h"
     29 #include "test/gmock.h"
     30 #include "test/gtest.h"
     31 
     32 namespace webrtc {
     33 namespace {
     34 
     35 using ::testing::_;
     36 using ::testing::ElementsAre;
     37 using ::testing::NiceMock;
     38 using ::testing::Return;
     39 using ::testing::SaveArg;
     40 
     41 constexpr Timestamp kFakeReceiveTimestamp = Timestamp::Millis(1234567);
     42 
     43 class MockChannelReceive {
     44 public:
     45  MOCK_METHOD(void,
     46              ReceiveFrame,
     47              (ArrayView<const uint8_t> packet,
     48               const RTPHeader& header,
     49               Timestamp receive_time));
     50 
     51  ChannelReceiveFrameTransformerDelegate::ReceiveFrameCallback callback() {
     52    return [this](ArrayView<const uint8_t> packet, const RTPHeader& header,
     53                  Timestamp receive_time) {
     54      ReceiveFrame(packet, header, receive_time);
     55    };
     56  }
     57 };
     58 
     59 // Test that the delegate registers itself with the frame transformer on Init().
     60 TEST(ChannelReceiveFrameTransformerDelegateTest,
     61     RegisterTransformedFrameCallbackOnInit) {
     62  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
     63      make_ref_counted<MockFrameTransformer>();
     64  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
     65      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
     66          ChannelReceiveFrameTransformerDelegate::ReceiveFrameCallback(),
     67          mock_frame_transformer, nullptr);
     68  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback);
     69  delegate->Init();
     70 }
     71 
     72 // Test that the delegate unregisters itself from the frame transformer on
     73 // Reset().
     74 TEST(ChannelReceiveFrameTransformerDelegateTest,
     75     UnregisterTransformedFrameCallbackOnReset) {
     76  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
     77      make_ref_counted<MockFrameTransformer>();
     78  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
     79      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
     80          ChannelReceiveFrameTransformerDelegate::ReceiveFrameCallback(),
     81          mock_frame_transformer, nullptr);
     82  EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback);
     83  delegate->Reset();
     84 }
     85 
     86 // Test that when the delegate receives a transformed frame from the frame
     87 // transformer, it passes it to the channel using the ReceiveFrameCallback.
     88 TEST(ChannelReceiveFrameTransformerDelegateTest,
     89     TransformRunsChannelReceiveCallback) {
     90  AutoThread main_thread;
     91  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
     92      make_ref_counted<NiceMock<MockFrameTransformer>>();
     93  MockChannelReceive mock_channel;
     94  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
     95      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
     96          mock_channel.callback(), mock_frame_transformer, Thread::Current());
     97  scoped_refptr<TransformedFrameCallback> callback;
     98  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
     99      .WillOnce(SaveArg<0>(&callback));
    100  delegate->Init();
    101  ASSERT_TRUE(callback);
    102 
    103  const uint8_t data[] = {1, 2, 3, 4};
    104  ArrayView<const uint8_t> packet(data, sizeof(data));
    105  RTPHeader header;
    106  EXPECT_CALL(mock_channel, ReceiveFrame);
    107  ON_CALL(*mock_frame_transformer, Transform)
    108      .WillByDefault(
    109          [&callback](std::unique_ptr<TransformableFrameInterface> frame) {
    110            callback->OnTransformedFrame(std::move(frame));
    111          });
    112  delegate->Transform(packet, header, /*ssrc=*/1111, /*mimeType=*/"audio/opus",
    113                      kFakeReceiveTimestamp);
    114  ThreadManager::ProcessAllMessageQueuesForTesting();
    115 }
    116 
    117 // Test that when the delegate receives a Outgoing frame from the frame
    118 // transformer, it passes it to the channel using the ReceiveFrameCallback.
    119 TEST(ChannelReceiveFrameTransformerDelegateTest,
    120     TransformRunsChannelReceiveCallbackForSenderFrame) {
    121  AutoThread main_thread;
    122  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    123      make_ref_counted<NiceMock<MockFrameTransformer>>();
    124  MockChannelReceive mock_channel;
    125  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    126      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    127          mock_channel.callback(), mock_frame_transformer, Thread::Current());
    128  scoped_refptr<TransformedFrameCallback> callback;
    129  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    130      .WillOnce(SaveArg<0>(&callback));
    131  delegate->Init();
    132  ASSERT_TRUE(callback);
    133 
    134  const uint8_t data[] = {1, 2, 3, 4};
    135  ArrayView<const uint8_t> packet(data, sizeof(data));
    136  RTPHeader header;
    137  EXPECT_CALL(mock_channel,
    138              ReceiveFrame(ElementsAre(1, 2, 3, 4), _, kFakeReceiveTimestamp));
    139  ON_CALL(*mock_frame_transformer, Transform)
    140      .WillByDefault(
    141          [&callback](std::unique_ptr<TransformableFrameInterface> frame) {
    142            auto* transformed_frame =
    143                static_cast<TransformableAudioFrameInterface*>(frame.get());
    144            callback->OnTransformedFrame(CloneAudioFrame(transformed_frame));
    145          });
    146  delegate->Transform(packet, header, /*ssrc=*/1111, /*mimeType=*/"audio/opus",
    147                      kFakeReceiveTimestamp);
    148  ThreadManager::ProcessAllMessageQueuesForTesting();
    149 }
    150 
    151 // Test that if the delegate receives a transformed frame after it has been
    152 // reset, it does not run the ReceiveFrameCallback, as the channel is destroyed
    153 // after resetting the delegate.
    154 TEST(ChannelReceiveFrameTransformerDelegateTest,
    155     OnTransformedDoesNotRunChannelReceiveCallbackAfterReset) {
    156  AutoThread main_thread;
    157  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    158      make_ref_counted<testing::NiceMock<MockFrameTransformer>>();
    159  MockChannelReceive mock_channel;
    160  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    161      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    162          mock_channel.callback(), mock_frame_transformer, Thread::Current());
    163 
    164  delegate->Reset();
    165  EXPECT_CALL(mock_channel, ReceiveFrame).Times(0);
    166  delegate->OnTransformedFrame(std::make_unique<MockTransformableAudioFrame>());
    167  ThreadManager::ProcessAllMessageQueuesForTesting();
    168 }
    169 
    170 TEST(ChannelReceiveFrameTransformerDelegateTest,
    171     ShortCircuitingSkipsTransform) {
    172  AutoThread main_thread;
    173  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    174      make_ref_counted<testing::NiceMock<MockFrameTransformer>>();
    175  MockChannelReceive mock_channel;
    176  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    177      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    178          mock_channel.callback(), mock_frame_transformer, Thread::Current());
    179  const uint8_t data[] = {1, 2, 3, 4};
    180  ArrayView<const uint8_t> packet(data, sizeof(data));
    181  RTPHeader header;
    182 
    183  delegate->StartShortCircuiting();
    184  ThreadManager::ProcessAllMessageQueuesForTesting();
    185 
    186  // Will not call the actual transformer.
    187  EXPECT_CALL(*mock_frame_transformer, Transform).Times(0);
    188  // Will pass the frame straight to the channel.
    189  EXPECT_CALL(mock_channel, ReceiveFrame);
    190  delegate->Transform(packet, header, /*ssrc=*/1111, /*mimeType=*/"audio/opus",
    191                      kFakeReceiveTimestamp);
    192 }
    193 
    194 TEST(ChannelReceiveFrameTransformerDelegateTest,
    195     AudioLevelAndCaptureTimeAbsentWithoutExtension) {
    196  AutoThread main_thread;
    197  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    198      make_ref_counted<NiceMock<MockFrameTransformer>>();
    199  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    200      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    201          /*receive_frame_callback=*/nullptr, mock_frame_transformer,
    202          Thread::Current());
    203  scoped_refptr<TransformedFrameCallback> callback;
    204  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    205      .WillOnce(SaveArg<0>(&callback));
    206  delegate->Init();
    207  ASSERT_TRUE(callback);
    208 
    209  const uint8_t data[] = {1, 2, 3, 4};
    210  ArrayView<const uint8_t> packet(data, sizeof(data));
    211  RTPHeader header;
    212  std::unique_ptr<TransformableFrameInterface> frame;
    213  ON_CALL(*mock_frame_transformer, Transform)
    214      .WillByDefault(
    215          [&](std::unique_ptr<TransformableFrameInterface> transform_frame) {
    216            frame = std::move(transform_frame);
    217          });
    218  delegate->Transform(packet, header, /*ssrc=*/1111, /*mimeType=*/"audio/opus",
    219                      kFakeReceiveTimestamp);
    220 
    221  EXPECT_TRUE(frame);
    222  auto* audio_frame =
    223      static_cast<TransformableAudioFrameInterface*>(frame.get());
    224  EXPECT_FALSE(audio_frame->AudioLevel());
    225  EXPECT_FALSE(audio_frame->CaptureTime());
    226  EXPECT_FALSE(audio_frame->SenderCaptureTimeOffset());
    227  EXPECT_EQ(audio_frame->Type(),
    228            TransformableAudioFrameInterface::FrameType::kAudioFrameCN);
    229 }
    230 
    231 TEST(ChannelReceiveFrameTransformerDelegateTest,
    232     AudioLevelPresentWithExtension) {
    233  AutoThread main_thread;
    234  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    235      make_ref_counted<NiceMock<MockFrameTransformer>>();
    236  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    237      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    238          /*receive_frame_callback=*/nullptr, mock_frame_transformer,
    239          Thread::Current());
    240  scoped_refptr<TransformedFrameCallback> callback;
    241  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    242      .WillOnce(SaveArg<0>(&callback));
    243  delegate->Init();
    244  ASSERT_TRUE(callback);
    245 
    246  const uint8_t data[] = {1, 2, 3, 4};
    247  ArrayView<const uint8_t> packet(data, sizeof(data));
    248  RTPHeader header;
    249  uint8_t audio_level_dbov = 67;
    250  AudioLevel audio_level(/*voice_activity=*/true, audio_level_dbov);
    251  header.extension.set_audio_level(audio_level);
    252  std::unique_ptr<TransformableFrameInterface> frame;
    253  ON_CALL(*mock_frame_transformer, Transform)
    254      .WillByDefault(
    255          [&](std::unique_ptr<TransformableFrameInterface> transform_frame) {
    256            frame = std::move(transform_frame);
    257          });
    258  delegate->Transform(packet, header, /*ssrc=*/1111, /*mimeType=*/"audio/opus",
    259                      kFakeReceiveTimestamp);
    260 
    261  EXPECT_TRUE(frame);
    262  auto* audio_frame =
    263      static_cast<TransformableAudioFrameInterface*>(frame.get());
    264  EXPECT_EQ(*audio_frame->AudioLevel(), audio_level_dbov);
    265  EXPECT_EQ(audio_frame->Type(),
    266            TransformableAudioFrameInterface::FrameType::kAudioFrameSpeech);
    267 }
    268 
    269 TEST(ChannelReceiveFrameTransformerDelegateTest,
    270     CaptureTimePresentWithExtension) {
    271  AutoThread main_thread;
    272  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    273      make_ref_counted<NiceMock<MockFrameTransformer>>();
    274  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    275      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    276          /*receive_frame_callback=*/nullptr, mock_frame_transformer,
    277          Thread::Current());
    278  scoped_refptr<TransformedFrameCallback> callback;
    279  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    280      .WillOnce(SaveArg<0>(&callback));
    281  delegate->Init();
    282  ASSERT_TRUE(callback);
    283 
    284  const uint8_t data[] = {1, 2, 3, 4};
    285  ArrayView<const uint8_t> packet(data, sizeof(data));
    286  Timestamp capture_time = Timestamp::Millis(1234);
    287  TimeDelta sender_capture_time_offsets[] = {TimeDelta::Millis(56),
    288                                             TimeDelta::Millis(-79)};
    289  for (auto offset : sender_capture_time_offsets) {
    290    AbsoluteCaptureTime absolute_capture_time = {
    291        .absolute_capture_timestamp = Int64MsToUQ32x32(capture_time.ms()),
    292        .estimated_capture_clock_offset = Int64MsToQ32x32(offset.ms())};
    293    RTPHeader header;
    294    header.extension.absolute_capture_time = absolute_capture_time;
    295 
    296    std::unique_ptr<TransformableFrameInterface> frame;
    297    ON_CALL(*mock_frame_transformer, Transform)
    298        .WillByDefault(
    299            [&](std::unique_ptr<TransformableFrameInterface> transform_frame) {
    300              frame = std::move(transform_frame);
    301            });
    302    delegate->Transform(packet, header, /*ssrc=*/1111,
    303                        /*mimeType=*/"audio/opus", kFakeReceiveTimestamp);
    304 
    305    EXPECT_TRUE(frame);
    306    auto* audio_frame =
    307        static_cast<TransformableAudioFrameInterface*>(frame.get());
    308    EXPECT_EQ(*audio_frame->CaptureTime(), capture_time);
    309    EXPECT_EQ(*audio_frame->SenderCaptureTimeOffset(), offset);
    310  }
    311 }
    312 
    313 TEST(ChannelReceiveFrameTransformerDelegateTest, SetAudioLevel) {
    314  AutoThread main_thread;
    315  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    316      make_ref_counted<NiceMock<MockFrameTransformer>>();
    317  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    318      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    319          /*receive_frame_callback=*/nullptr, mock_frame_transformer,
    320          Thread::Current());
    321  delegate->Init();
    322  const uint8_t data[] = {1, 2, 3, 4};
    323  ArrayView<const uint8_t> packet(data, sizeof(data));
    324  std::unique_ptr<TransformableFrameInterface> frame;
    325  ON_CALL(*mock_frame_transformer, Transform)
    326      .WillByDefault(
    327          [&](std::unique_ptr<TransformableFrameInterface> transform_frame) {
    328            frame = std::move(transform_frame);
    329          });
    330  delegate->Transform(packet, RTPHeader(), /*ssrc=*/1111,
    331                      /*mimeType=*/"audio/opus", kFakeReceiveTimestamp);
    332 
    333  EXPECT_TRUE(frame);
    334  auto* audio_frame =
    335      static_cast<TransformableAudioFrameInterface*>(frame.get());
    336  EXPECT_TRUE(audio_frame->CanSetAudioLevel());
    337  EXPECT_FALSE(audio_frame->AudioLevel().has_value());
    338 
    339  audio_frame->SetAudioLevel(67u);
    340  EXPECT_EQ(audio_frame->AudioLevel(), 67u);
    341 
    342  // Audio level is clamped to the range [0, 127].
    343  audio_frame->SetAudioLevel(128u);
    344  EXPECT_EQ(audio_frame->AudioLevel(), 127u);
    345 }
    346 
    347 TEST(ChannelReceiveFrameTransformerDelegateTest,
    348     ReceivingSenderFrameWithAudioValueSetsAudioLevelInHeader) {
    349  AutoThread main_thread;
    350  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    351      make_ref_counted<NiceMock<MockFrameTransformer>>();
    352  MockChannelReceive mock_channel;
    353  scoped_refptr<ChannelReceiveFrameTransformerDelegate> delegate =
    354      make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
    355          mock_channel.callback(), mock_frame_transformer, Thread::Current());
    356  delegate->Init();
    357 
    358  std::unique_ptr<MockTransformableAudioFrame> audio_frame =
    359      std::make_unique<NiceMock<MockTransformableAudioFrame>>();
    360  ON_CALL(*audio_frame, GetDirection())
    361      .WillByDefault(Return(TransformableFrameInterface::Direction::kSender));
    362  ON_CALL(*audio_frame, AudioLevel()).WillByDefault(Return(111u));
    363 
    364  RTPHeader header;
    365  EXPECT_CALL(mock_channel, ReceiveFrame).WillOnce(SaveArg<1>(&header));
    366  delegate->OnTransformedFrame(std::move(audio_frame));
    367  ThreadManager::ProcessAllMessageQueuesForTesting();
    368 
    369  ASSERT_TRUE(header.extension.audio_level().has_value());
    370  EXPECT_EQ(header.extension.audio_level()->level(), 111);
    371 }
    372 
    373 }  // namespace
    374 }  // namespace webrtc