• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 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 #include <functional>
11 #include <list>
12 #include <memory>
13 #include <string>
14 
15 #include "api/test/create_frame_generator.h"
16 #include "call/call.h"
17 #include "call/fake_network_pipe.h"
18 #include "call/simulated_network.h"
19 #include "rtc_base/checks.h"
20 #include "rtc_base/event.h"
21 #include "rtc_base/logging.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "rtc_base/task_queue_for_test.h"
24 #include "rtc_base/thread_annotations.h"
25 #include "test/call_test.h"
26 #include "test/direct_transport.h"
27 #include "test/encoder_settings.h"
28 #include "test/fake_decoder.h"
29 #include "test/fake_encoder.h"
30 #include "test/frame_generator_capturer.h"
31 #include "test/gtest.h"
32 
33 namespace webrtc {
34 namespace {
35 // Note: If you consider to re-use this class, think twice and instead consider
36 // writing tests that don't depend on the logging system.
37 class LogObserver {
38  public:
LogObserver()39   LogObserver() { rtc::LogMessage::AddLogToStream(&callback_, rtc::LS_INFO); }
40 
~LogObserver()41   ~LogObserver() { rtc::LogMessage::RemoveLogToStream(&callback_); }
42 
PushExpectedLogLine(const std::string & expected_log_line)43   void PushExpectedLogLine(const std::string& expected_log_line) {
44     callback_.PushExpectedLogLine(expected_log_line);
45   }
46 
Wait()47   bool Wait() { return callback_.Wait(); }
48 
49  private:
50   class Callback : public rtc::LogSink {
51    public:
OnLogMessage(const std::string & message)52     void OnLogMessage(const std::string& message) override {
53       MutexLock lock(&mutex_);
54       // Ignore log lines that are due to missing AST extensions, these are
55       // logged when we switch back from AST to TOF until the wrapping bitrate
56       // estimator gives up on using AST.
57       if (message.find("BitrateEstimator") != std::string::npos &&
58           message.find("packet is missing") == std::string::npos) {
59         received_log_lines_.push_back(message);
60       }
61 
62       int num_popped = 0;
63       while (!received_log_lines_.empty() && !expected_log_lines_.empty()) {
64         std::string a = received_log_lines_.front();
65         std::string b = expected_log_lines_.front();
66         received_log_lines_.pop_front();
67         expected_log_lines_.pop_front();
68         num_popped++;
69         EXPECT_TRUE(a.find(b) != std::string::npos) << a << " != " << b;
70       }
71       if (expected_log_lines_.empty()) {
72         if (num_popped > 0) {
73           done_.Set();
74         }
75         return;
76       }
77     }
78 
Wait()79     bool Wait() { return done_.Wait(test::CallTest::kDefaultTimeoutMs); }
80 
PushExpectedLogLine(const std::string & expected_log_line)81     void PushExpectedLogLine(const std::string& expected_log_line) {
82       MutexLock lock(&mutex_);
83       expected_log_lines_.push_back(expected_log_line);
84     }
85 
86    private:
87     typedef std::list<std::string> Strings;
88     Mutex mutex_;
89     Strings received_log_lines_ RTC_GUARDED_BY(mutex_);
90     Strings expected_log_lines_ RTC_GUARDED_BY(mutex_);
91     rtc::Event done_;
92   };
93 
94   Callback callback_;
95 };
96 }  // namespace
97 
98 static const int kTOFExtensionId = 4;
99 static const int kASTExtensionId = 5;
100 
101 class BitrateEstimatorTest : public test::CallTest {
102  public:
BitrateEstimatorTest()103   BitrateEstimatorTest() : receive_config_(nullptr) {}
104 
~BitrateEstimatorTest()105   virtual ~BitrateEstimatorTest() { EXPECT_TRUE(streams_.empty()); }
106 
SetUp()107   virtual void SetUp() {
108     SendTask(RTC_FROM_HERE, task_queue(), [this]() {
109       CreateCalls();
110 
111       send_transport_.reset(new test::DirectTransport(
112           task_queue(),
113           std::make_unique<FakeNetworkPipe>(
114               Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
115                                              BuiltInNetworkBehaviorConfig())),
116           sender_call_.get(), payload_type_map_));
117       send_transport_->SetReceiver(receiver_call_->Receiver());
118       receive_transport_.reset(new test::DirectTransport(
119           task_queue(),
120           std::make_unique<FakeNetworkPipe>(
121               Clock::GetRealTimeClock(), std::make_unique<SimulatedNetwork>(
122                                              BuiltInNetworkBehaviorConfig())),
123           receiver_call_.get(), payload_type_map_));
124       receive_transport_->SetReceiver(sender_call_->Receiver());
125 
126       VideoSendStream::Config video_send_config(send_transport_.get());
127       video_send_config.rtp.ssrcs.push_back(kVideoSendSsrcs[0]);
128       video_send_config.encoder_settings.encoder_factory =
129           &fake_encoder_factory_;
130       video_send_config.encoder_settings.bitrate_allocator_factory =
131           bitrate_allocator_factory_.get();
132       video_send_config.rtp.payload_name = "FAKE";
133       video_send_config.rtp.payload_type = kFakeVideoSendPayloadType;
134       SetVideoSendConfig(video_send_config);
135       VideoEncoderConfig video_encoder_config;
136       test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config);
137       SetVideoEncoderConfig(video_encoder_config);
138 
139       receive_config_ = VideoReceiveStream::Config(receive_transport_.get());
140       // receive_config_.decoders will be set by every stream separately.
141       receive_config_.rtp.remote_ssrc = GetVideoSendConfig()->rtp.ssrcs[0];
142       receive_config_.rtp.local_ssrc = kReceiverLocalVideoSsrc;
143       receive_config_.rtp.extensions.push_back(
144           RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
145       receive_config_.rtp.extensions.push_back(
146           RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
147     });
148   }
149 
TearDown()150   virtual void TearDown() {
151     SendTask(RTC_FROM_HERE, task_queue(), [this]() {
152       for (auto* stream : streams_) {
153         stream->StopSending();
154         delete stream;
155       }
156       streams_.clear();
157 
158       send_transport_.reset();
159       receive_transport_.reset();
160 
161       DestroyCalls();
162     });
163   }
164 
165  protected:
166   friend class Stream;
167 
168   class Stream {
169    public:
Stream(BitrateEstimatorTest * test)170     explicit Stream(BitrateEstimatorTest* test)
171         : test_(test),
172           is_sending_receiving_(false),
173           send_stream_(nullptr),
174           frame_generator_capturer_(),
175           decoder_factory_(
176               []() { return std::make_unique<test::FakeDecoder>(); }) {
177       test_->GetVideoSendConfig()->rtp.ssrcs[0]++;
178       send_stream_ = test_->sender_call_->CreateVideoSendStream(
179           test_->GetVideoSendConfig()->Copy(),
180           test_->GetVideoEncoderConfig()->Copy());
181       RTC_DCHECK_EQ(1, test_->GetVideoEncoderConfig()->number_of_streams);
182       frame_generator_capturer_ =
183           std::make_unique<test::FrameGeneratorCapturer>(
184               test->clock_,
185               test::CreateSquareFrameGenerator(kDefaultWidth, kDefaultHeight,
186                                                absl::nullopt, absl::nullopt),
187               kDefaultFramerate, *test->task_queue_factory_);
188       frame_generator_capturer_->Init();
189       send_stream_->SetSource(frame_generator_capturer_.get(),
190                               DegradationPreference::MAINTAIN_FRAMERATE);
191       send_stream_->Start();
192 
193       VideoReceiveStream::Decoder decoder;
194       decoder.decoder_factory = &decoder_factory_;
195       decoder.payload_type = test_->GetVideoSendConfig()->rtp.payload_type;
196       decoder.video_format =
197           SdpVideoFormat(test_->GetVideoSendConfig()->rtp.payload_name);
198       test_->receive_config_.decoders.clear();
199       test_->receive_config_.decoders.push_back(decoder);
200       test_->receive_config_.rtp.remote_ssrc =
201           test_->GetVideoSendConfig()->rtp.ssrcs[0];
202       test_->receive_config_.rtp.local_ssrc++;
203       test_->receive_config_.renderer = &test->fake_renderer_;
204       video_receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
205           test_->receive_config_.Copy());
206       video_receive_stream_->Start();
207       is_sending_receiving_ = true;
208     }
209 
~Stream()210     ~Stream() {
211       EXPECT_FALSE(is_sending_receiving_);
212       test_->sender_call_->DestroyVideoSendStream(send_stream_);
213       frame_generator_capturer_.reset(nullptr);
214       send_stream_ = nullptr;
215       if (video_receive_stream_) {
216         test_->receiver_call_->DestroyVideoReceiveStream(video_receive_stream_);
217         video_receive_stream_ = nullptr;
218       }
219     }
220 
StopSending()221     void StopSending() {
222       if (is_sending_receiving_) {
223         send_stream_->Stop();
224         if (video_receive_stream_) {
225           video_receive_stream_->Stop();
226         }
227         is_sending_receiving_ = false;
228       }
229     }
230 
231    private:
232     BitrateEstimatorTest* test_;
233     bool is_sending_receiving_;
234     VideoSendStream* send_stream_;
235     VideoReceiveStream* video_receive_stream_;
236     std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
237 
238     test::FunctionVideoDecoderFactory decoder_factory_;
239   };
240 
241   LogObserver receiver_log_;
242   std::unique_ptr<test::DirectTransport> send_transport_;
243   std::unique_ptr<test::DirectTransport> receive_transport_;
244   VideoReceiveStream::Config receive_config_;
245   std::vector<Stream*> streams_;
246 };
247 
248 static const char* kAbsSendTimeLog =
249     "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
250 static const char* kSingleStreamLog =
251     "RemoteBitrateEstimatorSingleStream: Instantiating.";
252 
TEST_F(BitrateEstimatorTest,InstantiatesTOFPerDefaultForVideo)253 TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
254   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
255     GetVideoSendConfig()->rtp.extensions.push_back(
256         RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
257     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
258     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
259     streams_.push_back(new Stream(this));
260   });
261   EXPECT_TRUE(receiver_log_.Wait());
262 }
263 
TEST_F(BitrateEstimatorTest,ImmediatelySwitchToASTForVideo)264 TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) {
265   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
266     GetVideoSendConfig()->rtp.extensions.push_back(
267         RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
268     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
269     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
270     receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
271     receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
272     streams_.push_back(new Stream(this));
273   });
274   EXPECT_TRUE(receiver_log_.Wait());
275 }
276 
TEST_F(BitrateEstimatorTest,SwitchesToASTForVideo)277 TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
278   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
279     GetVideoSendConfig()->rtp.extensions.push_back(
280         RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
281     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
282     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
283     streams_.push_back(new Stream(this));
284   });
285   EXPECT_TRUE(receiver_log_.Wait());
286 
287   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
288     GetVideoSendConfig()->rtp.extensions[0] =
289         RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
290     receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
291     receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
292     streams_.push_back(new Stream(this));
293   });
294   EXPECT_TRUE(receiver_log_.Wait());
295 }
296 
297 // This test is flaky. See webrtc:5790.
TEST_F(BitrateEstimatorTest,DISABLED_SwitchesToASTThenBackToTOFForVideo)298 TEST_F(BitrateEstimatorTest, DISABLED_SwitchesToASTThenBackToTOFForVideo) {
299   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
300     GetVideoSendConfig()->rtp.extensions.push_back(
301         RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
302     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
303     receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
304     receiver_log_.PushExpectedLogLine(kSingleStreamLog);
305     streams_.push_back(new Stream(this));
306   });
307   EXPECT_TRUE(receiver_log_.Wait());
308 
309   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
310     GetVideoSendConfig()->rtp.extensions[0] =
311         RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
312     receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
313     receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
314     streams_.push_back(new Stream(this));
315   });
316   EXPECT_TRUE(receiver_log_.Wait());
317 
318   SendTask(RTC_FROM_HERE, task_queue(), [this]() {
319     GetVideoSendConfig()->rtp.extensions[0] =
320         RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId);
321     receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
322     receiver_log_.PushExpectedLogLine(
323         "WrappingBitrateEstimator: Switching to transmission time offset RBE.");
324     streams_.push_back(new Stream(this));
325     streams_[0]->StopSending();
326     streams_[1]->StopSending();
327   });
328   EXPECT_TRUE(receiver_log_.Wait());
329 }
330 }  // namespace webrtc
331