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