Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 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 <memory> |
| 14 | #include <utility> |
| 15 | |
| 16 | #include "rtc_base/ref_counted_object.h" |
| 17 | #include "rtc_base/task_queue_for_test.h" |
| 18 | #include "test/gmock.h" |
| 19 | #include "test/gtest.h" |
| 20 | #include "test/mock_frame_transformer.h" |
| 21 | #include "test/mock_transformable_frame.h" |
| 22 | |
| 23 | namespace webrtc { |
| 24 | namespace { |
| 25 | |
| 26 | using ::testing::NiceMock; |
| 27 | using ::testing::SaveArg; |
| 28 | |
| 29 | class MockChannelSend { |
| 30 | public: |
| 31 | MockChannelSend() = default; |
| 32 | ~MockChannelSend() = default; |
| 33 | |
| 34 | MOCK_METHOD(int32_t, |
| 35 | SendFrame, |
| 36 | (AudioFrameType frameType, |
| 37 | uint8_t payloadType, |
| 38 | uint32_t rtp_timestamp, |
| 39 | rtc::ArrayView<const uint8_t> payload, |
| 40 | int64_t absolute_capture_timestamp_ms)); |
| 41 | |
| 42 | ChannelSendFrameTransformerDelegate::SendFrameCallback callback() { |
| 43 | return [this](AudioFrameType frameType, uint8_t payloadType, |
| 44 | uint32_t rtp_timestamp, rtc::ArrayView<const uint8_t> payload, |
| 45 | int64_t absolute_capture_timestamp_ms) { |
| 46 | return SendFrame(frameType, payloadType, rtp_timestamp, payload, |
| 47 | absolute_capture_timestamp_ms); |
| 48 | }; |
| 49 | } |
| 50 | }; |
| 51 | |
| 52 | // Test that the delegate registers itself with the frame transformer on Init(). |
| 53 | TEST(ChannelSendFrameTransformerDelegateTest, |
| 54 | RegisterTransformedFrameCallbackOnInit) { |
| 55 | rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 56 | rtc::make_ref_counted<MockFrameTransformer>(); |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 57 | rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 58 | rtc::make_ref_counted<ChannelSendFrameTransformerDelegate>( |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 59 | ChannelSendFrameTransformerDelegate::SendFrameCallback(), |
| 60 | mock_frame_transformer, nullptr); |
| 61 | EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback); |
| 62 | delegate->Init(); |
| 63 | } |
| 64 | |
| 65 | // Test that the delegate unregisters itself from the frame transformer on |
| 66 | // Reset(). |
| 67 | TEST(ChannelSendFrameTransformerDelegateTest, |
| 68 | UnregisterTransformedFrameCallbackOnReset) { |
| 69 | rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 70 | rtc::make_ref_counted<MockFrameTransformer>(); |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 71 | rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 72 | rtc::make_ref_counted<ChannelSendFrameTransformerDelegate>( |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 73 | ChannelSendFrameTransformerDelegate::SendFrameCallback(), |
| 74 | mock_frame_transformer, nullptr); |
| 75 | EXPECT_CALL(*mock_frame_transformer, UnregisterTransformedFrameCallback); |
| 76 | delegate->Reset(); |
| 77 | } |
| 78 | |
| 79 | // Test that when the delegate receives a transformed frame from the frame |
| 80 | // transformer, it passes it to the channel using the SendFrameCallback. |
| 81 | TEST(ChannelSendFrameTransformerDelegateTest, |
| 82 | TransformRunsChannelSendCallback) { |
| 83 | TaskQueueForTest channel_queue("channel_queue"); |
| 84 | rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 85 | rtc::make_ref_counted<NiceMock<MockFrameTransformer>>(); |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 86 | MockChannelSend mock_channel; |
| 87 | rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 88 | rtc::make_ref_counted<ChannelSendFrameTransformerDelegate>( |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 89 | mock_channel.callback(), mock_frame_transformer, &channel_queue); |
| 90 | rtc::scoped_refptr<TransformedFrameCallback> callback; |
| 91 | EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback) |
| 92 | .WillOnce(SaveArg<0>(&callback)); |
| 93 | delegate->Init(); |
| 94 | ASSERT_TRUE(callback); |
| 95 | |
| 96 | const uint8_t data[] = {1, 2, 3, 4}; |
| 97 | EXPECT_CALL(mock_channel, SendFrame); |
| 98 | ON_CALL(*mock_frame_transformer, Transform) |
| 99 | .WillByDefault( |
| 100 | [&callback](std::unique_ptr<TransformableFrameInterface> frame) { |
| 101 | callback->OnTransformedFrame(std::move(frame)); |
| 102 | }); |
| 103 | delegate->Transform(AudioFrameType::kEmptyFrame, 0, 0, 0, data, sizeof(data), |
| 104 | 0, 0); |
| 105 | channel_queue.WaitForPreviouslyPostedTasks(); |
| 106 | } |
| 107 | |
| 108 | // Test that if the delegate receives a transformed frame after it has been |
| 109 | // reset, it does not run the SendFrameCallback, as the channel is destroyed |
| 110 | // after resetting the delegate. |
| 111 | TEST(ChannelSendFrameTransformerDelegateTest, |
| 112 | OnTransformedDoesNotRunChannelSendCallbackAfterReset) { |
| 113 | TaskQueueForTest channel_queue("channel_queue"); |
| 114 | rtc::scoped_refptr<MockFrameTransformer> mock_frame_transformer = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 115 | rtc::make_ref_counted<testing::NiceMock<MockFrameTransformer>>(); |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 116 | MockChannelSend mock_channel; |
| 117 | rtc::scoped_refptr<ChannelSendFrameTransformerDelegate> delegate = |
Tomas Gunnarsson | c1d5891 | 2021-04-22 17:21:43 | [diff] [blame] | 118 | rtc::make_ref_counted<ChannelSendFrameTransformerDelegate>( |
Marina Ciocea | d719708 | 2020-05-04 15:50:38 | [diff] [blame] | 119 | mock_channel.callback(), mock_frame_transformer, &channel_queue); |
| 120 | |
| 121 | delegate->Reset(); |
| 122 | EXPECT_CALL(mock_channel, SendFrame).Times(0); |
| 123 | delegate->OnTransformedFrame(std::make_unique<MockTransformableFrame>()); |
| 124 | channel_queue.WaitForPreviouslyPostedTasks(); |
| 125 | } |
| 126 | |
| 127 | } // namespace |
| 128 | } // namespace webrtc |