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