channel_send_frame_transformer_delegate_unittest.cc (16081B)
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_send_frame_transformer_delegate.h" 12 13 #include <cstdint> 14 #include <memory> 15 #include <optional> 16 #include <utility> 17 #include <vector> 18 19 #include "absl/memory/memory.h" 20 #include "api/array_view.h" 21 #include "api/frame_transformer_interface.h" 22 #include "api/make_ref_counted.h" 23 #include "api/scoped_refptr.h" 24 #include "api/test/mock_frame_transformer.h" 25 #include "api/test/mock_transformable_audio_frame.h" 26 #include "api/units/timestamp.h" 27 #include "modules/audio_coding/include/audio_coding_module_typedefs.h" 28 #include "rtc_base/task_queue_for_test.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::ElementsAreArray; 38 using ::testing::NiceMock; 39 using ::testing::Optional; 40 using ::testing::Return; 41 using ::testing::SaveArg; 42 43 const uint8_t mock_data[] = {1, 2, 3, 4}; 44 45 class MockChannelSend { 46 public: 47 MockChannelSend() = default; 48 ~MockChannelSend() = default; 49 50 MOCK_METHOD(int32_t, 51 SendFrame, 52 (AudioFrameType frameType, 53 uint8_t payloadType, 54 uint32_t rtp_timestamp, 55 ArrayView<const uint8_t> payload, 56 int64_t absolute_capture_timestamp_ms, 57 ArrayView<const uint32_t> csrcs, 58 std::optional<uint8_t> audio_level_dbov)); 59 60 ChannelSendFrameTransformerDelegate::SendFrameCallback callback() { 61 return [this](AudioFrameType frameType, uint8_t payloadType, 62 uint32_t rtp_timestamp, ArrayView<const uint8_t> payload, 63 int64_t absolute_capture_timestamp_ms, 64 ArrayView<const uint32_t> csrcs, 65 std::optional<uint8_t> audio_level_dbov) { 66 return SendFrame(frameType, payloadType, rtp_timestamp, payload, 67 absolute_capture_timestamp_ms, csrcs, audio_level_dbov); 68 }; 69 } 70 }; 71 72 std::unique_ptr<TransformableAudioFrameInterface> CreateMockReceiverFrame( 73 const std::vector<uint32_t>& csrcs, 74 std::optional<uint8_t> audio_level_dbov) { 75 std::unique_ptr<MockTransformableAudioFrame> mock_frame = 76 std::make_unique<NiceMock<MockTransformableAudioFrame>>(); 77 ArrayView<const uint8_t> payload(mock_data); 78 ON_CALL(*mock_frame, GetData).WillByDefault(Return(payload)); 79 ON_CALL(*mock_frame, GetPayloadType).WillByDefault(Return(0)); 80 ON_CALL(*mock_frame, GetDirection) 81 .WillByDefault(Return(TransformableFrameInterface::Direction::kReceiver)); 82 ON_CALL(*mock_frame, GetContributingSources).WillByDefault(Return(csrcs)); 83 ON_CALL(*mock_frame, SequenceNumber).WillByDefault(Return(987654321)); 84 ON_CALL(*mock_frame, AudioLevel).WillByDefault(Return(audio_level_dbov)); 85 return mock_frame; 86 } 87 88 std::unique_ptr<TransformableAudioFrameInterface> CreateFrame() { 89 TaskQueueForTest channel_queue("channel_queue"); 90 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 91 make_ref_counted<NiceMock<MockFrameTransformer>>(); 92 MockChannelSend mock_channel; 93 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 94 make_ref_counted<ChannelSendFrameTransformerDelegate>( 95 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 96 97 std::unique_ptr<TransformableFrameInterface> frame; 98 ON_CALL(*mock_frame_transformer, Transform) 99 .WillByDefault( 100 [&frame]( 101 std::unique_ptr<TransformableFrameInterface> transform_frame) { 102 frame = std::move(transform_frame); 103 }); 104 delegate->Transform( 105 AudioFrameType::kEmptyFrame, 0, 0, mock_data, sizeof(mock_data), 0, 106 /*ssrc=*/0, /*mimeType=*/"audio/opus", /*audio_level_dbov=*/123); 107 return absl::WrapUnique( 108 static_cast<TransformableAudioFrameInterface*>(frame.release())); 109 } 110 111 // Test that the delegate registers itself with the frame transformer on Init(). 112 TEST(ChannelSendFrameTransformerDelegateTest, 113 RegisterTransformedFrameCallbackOnInit) { 114 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 115 make_ref_counted<MockFrameTransformer>(); 116 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 117 make_ref_counted<ChannelSendFrameTransformerDelegate>( 118 ChannelSendFrameTransformerDelegate::SendFrameCallback(), 119 mock_frame_transformer, nullptr); 120 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback); 121 delegate->Init(); 122 } 123 124 // Test that the delegate unregisters itself from the frame transformer on 125 // Reset(). 126 TEST(ChannelSendFrameTransformerDelegateTest, 127 UnregisterTransformedFrameCallbackOnReset) { 128 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 129 make_ref_counted<MockFrameTransformer>(); 130 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 131 make_ref_counted<ChannelSendFrameTransformerDelegate>( 132 ChannelSendFrameTransformerDelegate::SendFrameCallback(), 133 mock_frame_transformer, nullptr); 134 EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback); 135 delegate->Reset(); 136 } 137 138 // Test that when the delegate receives a transformed frame from the frame 139 // transformer, it passes it to the channel using the SendFrameCallback. 140 TEST(ChannelSendFrameTransformerDelegateTest, 141 TransformRunsChannelSendCallback) { 142 TaskQueueForTest channel_queue("channel_queue"); 143 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 144 make_ref_counted<NiceMock<MockFrameTransformer>>(); 145 MockChannelSend mock_channel; 146 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 147 make_ref_counted<ChannelSendFrameTransformerDelegate>( 148 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 149 scoped_refptr<TransformedFrameCallback> callback; 150 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback) 151 .WillOnce(SaveArg<0>(&callback)); 152 delegate->Init(); 153 ASSERT_TRUE(callback); 154 155 const uint8_t data[] = {1, 2, 3, 4}; 156 EXPECT_CALL(mock_channel, SendFrame); 157 ON_CALL(*mock_frame_transformer, Transform) 158 .WillByDefault( 159 [&callback](std::unique_ptr<TransformableFrameInterface> frame) { 160 callback->OnTransformedFrame(std::move(frame)); 161 }); 162 delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, data, sizeof(data), 0, 163 /*ssrc=*/0, /*mimeType=*/"audio/opus", 164 /*audio_level_dbov=*/31); 165 channel_queue.WaitForPreviouslyPostedTasks(); 166 } 167 168 // Test that when the delegate receives a Incoming frame from the frame 169 // transformer, it passes it to the channel using the SendFrameCallback. 170 TEST(ChannelSendFrameTransformerDelegateTest, 171 TransformRunsChannelSendCallbackForIncomingFrame) { 172 TaskQueueForTest channel_queue("channel_queue"); 173 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 174 make_ref_counted<NiceMock<MockFrameTransformer>>(); 175 MockChannelSend mock_channel; 176 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 177 make_ref_counted<ChannelSendFrameTransformerDelegate>( 178 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 179 scoped_refptr<TransformedFrameCallback> callback; 180 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback) 181 .WillOnce(SaveArg<0>(&callback)); 182 delegate->Init(); 183 ASSERT_TRUE(callback); 184 185 const std::vector<uint32_t> csrcs = {123, 234, 345, 456}; 186 const uint8_t audio_level_dbov = 17; 187 EXPECT_CALL(mock_channel, SendFrame).Times(0); 188 EXPECT_CALL(mock_channel, 189 SendFrame(_, 0, 0, ElementsAreArray(mock_data), _, 190 ElementsAreArray(csrcs), Optional(audio_level_dbov))); 191 ON_CALL(*mock_frame_transformer, Transform) 192 .WillByDefault( 193 [&](std::unique_ptr<TransformableFrameInterface> /* frame */) { 194 callback->OnTransformedFrame(CreateMockReceiverFrame( 195 csrcs, std::optional<uint8_t>(audio_level_dbov))); 196 }); 197 delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, mock_data, 198 sizeof(mock_data), 0, 199 /*ssrc=*/0, /*mimeType=*/"audio/opus", 200 /*audio_level_dbov=*/std::nullopt); 201 channel_queue.WaitForPreviouslyPostedTasks(); 202 } 203 204 // Test that CSRCs are propagated correctly from the Transform call to the frame 205 // transformer. 206 TEST(ChannelSendFrameTransformerDelegateTest, 207 TransformForwardsCsrcsViaFrameTransformer) { 208 TaskQueueForTest channel_queue("channel_queue"); 209 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 210 make_ref_counted<NiceMock<MockFrameTransformer>>(); 211 MockChannelSend mock_channel; 212 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 213 make_ref_counted<ChannelSendFrameTransformerDelegate>( 214 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 215 scoped_refptr<TransformedFrameCallback> callback; 216 EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback) 217 .WillOnce(SaveArg<0>(&callback)); 218 delegate->Init(); 219 ASSERT_TRUE(callback); 220 221 std::vector<uint32_t> csrcs = {123, 234, 345, 456}; 222 EXPECT_CALL(mock_channel, 223 SendFrame(_, _, _, _, _, ElementsAreArray(csrcs), _)); 224 ON_CALL(*mock_frame_transformer, Transform) 225 .WillByDefault( 226 [&callback](std::unique_ptr<TransformableFrameInterface> frame) { 227 callback->OnTransformedFrame(std::move(frame)); 228 }); 229 delegate->Transform( 230 AudioFrameType::kEmptyFrame, 0, 0, mock_data, sizeof(mock_data), 0, 231 /*ssrc=*/0, /*mimeType=*/"audio/opus", /*audio_level_dbov=*/31, csrcs); 232 channel_queue.WaitForPreviouslyPostedTasks(); 233 } 234 235 // Test that CSRCs are propagated correctly from the Transform call to the send 236 // frame callback when short circuiting is enabled. 237 TEST(ChannelSendFrameTransformerDelegateTest, 238 TransformForwardsCsrcsViaShortCircuiting) { 239 TaskQueueForTest channel_queue("channel_queue"); 240 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 241 make_ref_counted<testing::NiceMock<MockFrameTransformer>>(); 242 MockChannelSend mock_channel; 243 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 244 make_ref_counted<ChannelSendFrameTransformerDelegate>( 245 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 246 247 std::vector<uint32_t> csrcs = {123, 234, 345, 456}; 248 delegate->StartShortCircuiting(); 249 EXPECT_CALL(mock_channel, 250 SendFrame(_, _, _, _, _, ElementsAreArray(csrcs), _)); 251 delegate->Transform( 252 AudioFrameType::kEmptyFrame, 0, 0, mock_data, sizeof(mock_data), 0, 253 /*ssrc=*/0, /*mimeType=*/"audio/opus", /*audio_level_dbov=*/31, csrcs); 254 channel_queue.WaitForPreviouslyPostedTasks(); 255 } 256 257 // Test that if the delegate receives a transformed frame after it has been 258 // reset, it does not run the SendFrameCallback, as the channel is destroyed 259 // after resetting the delegate. 260 TEST(ChannelSendFrameTransformerDelegateTest, 261 OnTransformedDoesNotRunChannelSendCallbackAfterReset) { 262 TaskQueueForTest channel_queue("channel_queue"); 263 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 264 make_ref_counted<testing::NiceMock<MockFrameTransformer>>(); 265 MockChannelSend mock_channel; 266 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 267 make_ref_counted<ChannelSendFrameTransformerDelegate>( 268 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 269 270 delegate->Reset(); 271 EXPECT_CALL(mock_channel, SendFrame).Times(0); 272 delegate->OnTransformedFrame(std::make_unique<MockTransformableAudioFrame>()); 273 channel_queue.WaitForPreviouslyPostedTasks(); 274 } 275 276 TEST(ChannelSendFrameTransformerDelegateTest, ShortCircuitingSkipsTransform) { 277 TaskQueueForTest channel_queue("channel_queue"); 278 scoped_refptr<MockFrameTransformer> mock_frame_transformer = 279 make_ref_counted<testing::NiceMock<MockFrameTransformer>>(); 280 MockChannelSend mock_channel; 281 scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = 282 make_ref_counted<ChannelSendFrameTransformerDelegate>( 283 mock_channel.callback(), mock_frame_transformer, channel_queue.Get()); 284 285 delegate->StartShortCircuiting(); 286 287 // Will not call the actual transformer. 288 EXPECT_CALL(*mock_frame_transformer, Transform).Times(0); 289 // Will pass the frame straight to the channel. 290 EXPECT_CALL(mock_channel, SendFrame); 291 const uint8_t data[] = {1, 2, 3, 4}; 292 delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, data, sizeof(data), 0, 293 /*ssrc=*/0, /*mimeType=*/"audio/opus", 294 /*audio_level_dbov=*/std::nullopt); 295 } 296 297 TEST(ChannelSendFrameTransformerDelegateTest, 298 CloningSenderFramePreservesInformation) { 299 std::unique_ptr<TransformableAudioFrameInterface> frame = CreateFrame(); 300 std::unique_ptr<TransformableAudioFrameInterface> cloned_frame = 301 CloneSenderAudioFrame(frame.get()); 302 303 EXPECT_EQ(cloned_frame->GetTimestamp(), frame->GetTimestamp()); 304 EXPECT_EQ(cloned_frame->GetSsrc(), frame->GetSsrc()); 305 EXPECT_EQ(cloned_frame->Type(), frame->Type()); 306 EXPECT_EQ(cloned_frame->GetPayloadType(), frame->GetPayloadType()); 307 EXPECT_EQ(cloned_frame->GetMimeType(), frame->GetMimeType()); 308 EXPECT_THAT(cloned_frame->GetContributingSources(), 309 ElementsAreArray(frame->GetContributingSources())); 310 EXPECT_EQ(cloned_frame->AudioLevel(), frame->AudioLevel()); 311 } 312 313 TEST(ChannelSendFrameTransformerDelegateTest, CloningReceiverFrameWithCsrcs) { 314 std::unique_ptr<TransformableAudioFrameInterface> frame = 315 CreateMockReceiverFrame(/*csrcs=*/{123, 234, 345}, 316 std::optional<uint8_t>(72)); 317 std::unique_ptr<TransformableAudioFrameInterface> cloned_frame = 318 CloneSenderAudioFrame(frame.get()); 319 320 EXPECT_EQ(cloned_frame->GetTimestamp(), frame->GetTimestamp()); 321 EXPECT_EQ(cloned_frame->GetSsrc(), frame->GetSsrc()); 322 EXPECT_EQ(cloned_frame->Type(), frame->Type()); 323 EXPECT_EQ(cloned_frame->GetPayloadType(), frame->GetPayloadType()); 324 EXPECT_EQ(cloned_frame->GetMimeType(), frame->GetMimeType()); 325 EXPECT_EQ(cloned_frame->AbsoluteCaptureTimestamp(), 326 frame->AbsoluteCaptureTimestamp()); 327 328 ASSERT_NE(frame->GetContributingSources().size(), 0u); 329 EXPECT_THAT(cloned_frame->GetContributingSources(), 330 ElementsAreArray(frame->GetContributingSources())); 331 EXPECT_EQ(cloned_frame->SequenceNumber(), frame->SequenceNumber()); 332 EXPECT_EQ(cloned_frame->AudioLevel(), frame->AudioLevel()); 333 } 334 335 TEST(ChannelSendFrameTransformerDelegateTest, SetCaptureTime) { 336 std::unique_ptr<TransformableAudioFrameInterface> frame = CreateFrame(); 337 EXPECT_TRUE(frame->CanSetCaptureTime()); 338 frame->SetCaptureTime(webrtc::Timestamp::Millis(100)); 339 EXPECT_EQ(frame->CaptureTime(), webrtc::Timestamp::Millis(100)); 340 frame->SetCaptureTime(std::nullopt); 341 EXPECT_FALSE(frame->CaptureTime().has_value()); 342 } 343 344 TEST(ChannelSendFrameTransformerDelegateTest, SetPayloadType) { 345 std::unique_ptr<TransformableAudioFrameInterface> frame = CreateFrame(); 346 EXPECT_TRUE(frame->CanSetPayloadType()); 347 frame->SetPayloadType(45); 348 EXPECT_EQ(frame->GetPayloadType(), 45); 349 } 350 351 TEST(ChannelSendFrameTransformerDelegateTest, SetAudioLevel) { 352 std::unique_ptr<TransformableAudioFrameInterface> frame = CreateFrame(); 353 EXPECT_TRUE(frame->CanSetAudioLevel()); 354 frame->SetAudioLevel(45u); 355 EXPECT_EQ(frame->AudioLevel(), 45u); 356 frame->SetAudioLevel(std::nullopt); 357 EXPECT_FALSE(frame->AudioLevel().has_value()); 358 } 359 360 TEST(ChannelSendFrameTransformerDelegateTest, SetAudioLevelIsClamped) { 361 std::unique_ptr<TransformableAudioFrameInterface> frame = CreateFrame(); 362 EXPECT_TRUE(frame->CanSetAudioLevel()); 363 frame->SetAudioLevel(128u); 364 EXPECT_EQ(frame->AudioLevel(), 127u); 365 } 366 367 } // namespace 368 } // namespace webrtc