1 /*
2 * Copyright 2018 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 <memory>
12
13 #include "api/test/create_frame_generator.h"
14 #include "api/test/frame_generator_interface.h"
15 #include "api/test/simulated_network.h"
16 #include "call/fake_network_pipe.h"
17 #include "call/simulated_network.h"
18 #include "rtc_base/task_queue_for_test.h"
19 #include "system_wrappers/include/sleep.h"
20 #include "test/call_test.h"
21 #include "test/field_trial.h"
22 #include "test/frame_forwarder.h"
23 #include "test/gtest.h"
24 #include "test/null_transport.h"
25
26 namespace webrtc {
27
28 class CallOperationEndToEndTest : public test::CallTest {};
29
TEST_F(CallOperationEndToEndTest,ReceiverCanBeStartedTwice)30 TEST_F(CallOperationEndToEndTest, ReceiverCanBeStartedTwice) {
31 CreateCalls();
32
33 test::NullTransport transport;
34 CreateSendConfig(1, 0, 0, &transport);
35 CreateMatchingReceiveConfigs(&transport);
36
37 CreateVideoStreams();
38
39 video_receive_streams_[0]->Start();
40 video_receive_streams_[0]->Start();
41
42 DestroyStreams();
43 }
44
TEST_F(CallOperationEndToEndTest,ReceiverCanBeStoppedTwice)45 TEST_F(CallOperationEndToEndTest, ReceiverCanBeStoppedTwice) {
46 CreateCalls();
47
48 test::NullTransport transport;
49 CreateSendConfig(1, 0, 0, &transport);
50 CreateMatchingReceiveConfigs(&transport);
51
52 CreateVideoStreams();
53
54 video_receive_streams_[0]->Stop();
55 video_receive_streams_[0]->Stop();
56
57 DestroyStreams();
58 }
59
TEST_F(CallOperationEndToEndTest,ReceiverCanBeStoppedAndRestarted)60 TEST_F(CallOperationEndToEndTest, ReceiverCanBeStoppedAndRestarted) {
61 CreateCalls();
62
63 test::NullTransport transport;
64 CreateSendConfig(1, 0, 0, &transport);
65 CreateMatchingReceiveConfigs(&transport);
66
67 CreateVideoStreams();
68
69 video_receive_streams_[0]->Stop();
70 video_receive_streams_[0]->Start();
71 video_receive_streams_[0]->Stop();
72
73 DestroyStreams();
74 }
75
TEST_F(CallOperationEndToEndTest,RendersSingleDelayedFrame)76 TEST_F(CallOperationEndToEndTest, RendersSingleDelayedFrame) {
77 static const int kWidth = 320;
78 static const int kHeight = 240;
79 // This constant is chosen to be higher than the timeout in the video_render
80 // module. This makes sure that frames aren't dropped if there are no other
81 // frames in the queue.
82 static const int kRenderDelayMs = 1000;
83
84 class Renderer : public rtc::VideoSinkInterface<VideoFrame> {
85 public:
86 void OnFrame(const VideoFrame& video_frame) override {
87 SleepMs(kRenderDelayMs);
88 event_.Set();
89 }
90
91 bool Wait() { return event_.Wait(kDefaultTimeout); }
92
93 rtc::Event event_;
94 } renderer;
95
96 test::FrameForwarder frame_forwarder;
97 std::unique_ptr<test::DirectTransport> sender_transport;
98 std::unique_ptr<test::DirectTransport> receiver_transport;
99
100 SendTask(
101 task_queue(), [this, &renderer, &frame_forwarder, &sender_transport,
102 &receiver_transport]() {
103 CreateCalls();
104
105 sender_transport = std::make_unique<test::DirectTransport>(
106 task_queue(),
107 std::make_unique<FakeNetworkPipe>(
108 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
109 BuiltInNetworkBehaviorConfig())),
110 sender_call_.get(), payload_type_map_);
111 receiver_transport = std::make_unique<test::DirectTransport>(
112 task_queue(),
113 std::make_unique<FakeNetworkPipe>(
114 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
115 BuiltInNetworkBehaviorConfig())),
116 receiver_call_.get(), payload_type_map_);
117 sender_transport->SetReceiver(receiver_call_->Receiver());
118 receiver_transport->SetReceiver(sender_call_->Receiver());
119
120 CreateSendConfig(1, 0, 0, sender_transport.get());
121 CreateMatchingReceiveConfigs(receiver_transport.get());
122
123 video_receive_configs_[0].renderer = &renderer;
124
125 CreateVideoStreams();
126 Start();
127
128 // Create frames that are smaller than the send width/height, this is
129 // done to check that the callbacks are done after processing video.
130 std::unique_ptr<test::FrameGeneratorInterface> frame_generator(
131 test::CreateSquareFrameGenerator(kWidth, kHeight, absl::nullopt,
132 absl::nullopt));
133 GetVideoSendStream()->SetSource(
134 &frame_forwarder, DegradationPreference::MAINTAIN_FRAMERATE);
135
136 test::FrameGeneratorInterface::VideoFrameData frame_data =
137 frame_generator->NextFrame();
138 VideoFrame frame = VideoFrame::Builder()
139 .set_video_frame_buffer(frame_data.buffer)
140 .set_update_rect(frame_data.update_rect)
141 .build();
142 frame_forwarder.IncomingCapturedFrame(frame);
143 });
144
145 EXPECT_TRUE(renderer.Wait())
146 << "Timed out while waiting for the frame to render.";
147
148 SendTask(task_queue(), [this, &sender_transport, &receiver_transport]() {
149 Stop();
150 DestroyStreams();
151 sender_transport.reset();
152 receiver_transport.reset();
153 DestroyCalls();
154 });
155 }
156
TEST_F(CallOperationEndToEndTest,TransmitsFirstFrame)157 TEST_F(CallOperationEndToEndTest, TransmitsFirstFrame) {
158 class Renderer : public rtc::VideoSinkInterface<VideoFrame> {
159 public:
160 void OnFrame(const VideoFrame& video_frame) override { event_.Set(); }
161
162 bool Wait() { return event_.Wait(kDefaultTimeout); }
163
164 rtc::Event event_;
165 } renderer;
166
167 std::unique_ptr<test::FrameGeneratorInterface> frame_generator;
168 test::FrameForwarder frame_forwarder;
169
170 std::unique_ptr<test::DirectTransport> sender_transport;
171 std::unique_ptr<test::DirectTransport> receiver_transport;
172
173 SendTask(
174 task_queue(), [this, &renderer, &frame_generator, &frame_forwarder,
175 &sender_transport, &receiver_transport]() {
176 CreateCalls();
177
178 sender_transport = std::make_unique<test::DirectTransport>(
179 task_queue(),
180 std::make_unique<FakeNetworkPipe>(
181 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
182 BuiltInNetworkBehaviorConfig())),
183 sender_call_.get(), payload_type_map_);
184 receiver_transport = std::make_unique<test::DirectTransport>(
185 task_queue(),
186 std::make_unique<FakeNetworkPipe>(
187 Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
188 BuiltInNetworkBehaviorConfig())),
189 receiver_call_.get(), payload_type_map_);
190 sender_transport->SetReceiver(receiver_call_->Receiver());
191 receiver_transport->SetReceiver(sender_call_->Receiver());
192
193 CreateSendConfig(1, 0, 0, sender_transport.get());
194 CreateMatchingReceiveConfigs(receiver_transport.get());
195 video_receive_configs_[0].renderer = &renderer;
196
197 CreateVideoStreams();
198 Start();
199
200 frame_generator = test::CreateSquareFrameGenerator(
201 kDefaultWidth, kDefaultHeight, absl::nullopt, absl::nullopt);
202 GetVideoSendStream()->SetSource(
203 &frame_forwarder, DegradationPreference::MAINTAIN_FRAMERATE);
204 test::FrameGeneratorInterface::VideoFrameData frame_data =
205 frame_generator->NextFrame();
206 VideoFrame frame = VideoFrame::Builder()
207 .set_video_frame_buffer(frame_data.buffer)
208 .set_update_rect(frame_data.update_rect)
209 .build();
210 frame_forwarder.IncomingCapturedFrame(frame);
211 });
212
213 EXPECT_TRUE(renderer.Wait())
214 << "Timed out while waiting for the frame to render.";
215
216 SendTask(task_queue(), [this, &sender_transport, &receiver_transport]() {
217 Stop();
218 DestroyStreams();
219 sender_transport.reset();
220 receiver_transport.reset();
221 DestroyCalls();
222 });
223 }
224
225 } // namespace webrtc
226