blob: b294c70bf886026afd0ad863b8c1fc20f82d10be [file] [log] [blame]
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +00001/*
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 <assert.h>
11
12#include <map>
13
14#include "testing/gtest/include/gtest/gtest.h"
15
pbos@webrtc.org24e20892013-10-28 16:32:01 +000016#include "webrtc/call.h"
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000017#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
18#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
19#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
20#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
21#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
22#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
23#include "webrtc/system_wrappers/interface/event_wrapper.h"
24#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.org24e20892013-10-28 16:32:01 +000025#include "webrtc/test/direct_transport.h"
26#include "webrtc/test/fake_decoder.h"
27#include "webrtc/test/fake_encoder.h"
28#include "webrtc/test/frame_generator_capturer.h"
29#include "webrtc/test/generate_ssrcs.h"
pbos@webrtc.org3009c812013-11-20 12:17:04 +000030#include "webrtc/video/transport_adapter.h"
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000031
32namespace webrtc {
33
pbos@webrtc.org990c5e32013-09-11 10:14:56 +000034namespace {
35 static const int kTOffsetExtensionId = 7;
36}
37
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000038class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
39 public:
40 typedef std::map<uint32_t, int> BytesSentMap;
41 StreamObserver(int num_expected_ssrcs,
42 newapi::Transport* feedback_transport,
43 Clock* clock)
44 : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
45 all_ssrcs_sent_(EventWrapper::Create()),
46 rtp_parser_(RtpHeaderParser::Create()),
pbos@webrtc.org3009c812013-11-20 12:17:04 +000047 feedback_transport_(feedback_transport),
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000048 receive_stats_(ReceiveStatistics::Create(clock)),
49 clock_(clock),
50 num_expected_ssrcs_(num_expected_ssrcs) {
51 // Ideally we would only have to instantiate an RtcpSender, an
52 // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current
53 // state of the RTP module we need a full module and receive statistics to
54 // be able to produce an RTCP with REMB.
55 RtpRtcp::Configuration config;
56 config.receive_statistics = receive_stats_.get();
pbos@webrtc.org3009c812013-11-20 12:17:04 +000057 config.outgoing_transport = &feedback_transport_;
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000058 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
59 rtp_rtcp_->SetREMBStatus(true);
60 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
61 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
pbos@webrtc.org990c5e32013-09-11 10:14:56 +000062 kTOffsetExtensionId);
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000063 AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
64 remote_bitrate_estimator_.reset(rbe_factory.Create(this, clock));
65 }
66
67 virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
68 unsigned int bitrate) {
69 CriticalSectionScoped lock(critical_section_.get());
70 if (ssrcs.size() == num_expected_ssrcs_ && bitrate >= kExpectedBitrateBps)
71 all_ssrcs_sent_->Set();
72 rtp_rtcp_->SetREMBData(
73 bitrate, static_cast<uint8_t>(ssrcs.size()), &ssrcs[0]);
74 rtp_rtcp_->Process();
75 }
76
pbos@webrtc.org3009c812013-11-20 12:17:04 +000077 virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000078 CriticalSectionScoped lock(critical_section_.get());
79 RTPHeader header;
80 EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
81 receive_stats_->IncomingPacket(header, length, false);
82 rtp_rtcp_->SetRemoteSSRC(header.ssrc);
83 remote_bitrate_estimator_->IncomingPacket(
84 clock_->TimeInMilliseconds(), static_cast<int>(length - 12), header);
85 if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
86 remote_bitrate_estimator_->Process();
87 }
88 return true;
89 }
90
pbos@webrtc.org3009c812013-11-20 12:17:04 +000091 virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000092 return true;
93 }
94
95 EventTypeWrapper Wait() { return all_ssrcs_sent_->Wait(120 * 1000); }
96
97 private:
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000098 static const unsigned int kExpectedBitrateBps = 1200000;
99
100 scoped_ptr<CriticalSectionWrapper> critical_section_;
101 scoped_ptr<EventWrapper> all_ssrcs_sent_;
102 scoped_ptr<RtpHeaderParser> rtp_parser_;
103 scoped_ptr<RtpRtcp> rtp_rtcp_;
pbos@webrtc.org3009c812013-11-20 12:17:04 +0000104 internal::TransportAdapter feedback_transport_;
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000105 scoped_ptr<ReceiveStatistics> receive_stats_;
106 scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
107 Clock* clock_;
108 const size_t num_expected_ssrcs_;
109};
110
111class RampUpTest : public ::testing::TestWithParam<bool> {
112 public:
113 virtual void SetUp() { reserved_ssrcs_.clear(); }
114
115 protected:
116 std::map<uint32_t, bool> reserved_ssrcs_;
117};
118
119TEST_P(RampUpTest, RampUpWithPadding) {
120 test::DirectTransport receiver_transport;
121 StreamObserver stream_observer(
122 3, &receiver_transport, Clock::GetRealTimeClock());
123 Call::Config call_config(&stream_observer);
124 scoped_ptr<Call> call(Call::Create(call_config));
125 VideoSendStream::Config send_config = call->GetDefaultSendConfig();
126
127 receiver_transport.SetReceiver(call->Receiver());
128
129 test::FakeEncoder encoder(Clock::GetRealTimeClock());
130 send_config.encoder = &encoder;
131 send_config.internal_source = false;
132 test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
stefan@webrtc.org4985c7b2013-11-15 12:32:15 +0000133 send_config.codec.plType = 125;
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000134 send_config.pacing = GetParam();
pbos@webrtc.org990c5e32013-09-11 10:14:56 +0000135 send_config.rtp.extensions.push_back(
pbos@webrtc.org346dbe72013-11-20 11:48:56 +0000136 RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId));
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000137
138 test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
139
pbos@webrtc.org964d78e2013-11-20 10:40:25 +0000140 VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000141
142 VideoReceiveStream::Config receive_config;
143 receive_config.rtp.ssrc = send_config.rtp.ssrcs[0];
144 receive_config.rtp.nack.rtp_history_ms = send_config.rtp.nack.rtp_history_ms;
145 VideoReceiveStream* receive_stream =
pbos@webrtc.org964d78e2013-11-20 10:40:25 +0000146 call->CreateVideoReceiveStream(receive_config);
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000147
148 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
andresp@webrtc.org28631e72013-09-19 12:14:03 +0000149 test::FrameGeneratorCapturer::Create(send_stream->Input(),
150 send_config.codec.width,
151 send_config.codec.height,
152 30,
153 Clock::GetRealTimeClock()));
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000154
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +0000155 receive_stream->StartReceiving();
156 send_stream->StartSending();
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000157 frame_generator_capturer->Start();
158
159 EXPECT_EQ(kEventSignaled, stream_observer.Wait());
160
161 frame_generator_capturer->Stop();
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +0000162 send_stream->StopSending();
163 receive_stream->StopReceiving();
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000164
pbos@webrtc.org12a93e02013-11-21 13:49:43 +0000165 call->DestroyVideoReceiveStream(receive_stream);
166 call->DestroyVideoSendStream(send_stream);
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +0000167}
168
169INSTANTIATE_TEST_CASE_P(RampUpTest, RampUpTest, ::testing::Bool());
170
171} // namespace webrtc