blob: 8e3e0279c050c8cfd4cb4c307b94bf98c588c2e4 [file] [log] [blame]
pbos@webrtc.org744fbc72013-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
16#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
17#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
18#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
19#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
20#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
21#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
22#include "webrtc/system_wrappers/interface/event_wrapper.h"
23#include "webrtc/system_wrappers/interface/scoped_ptr.h"
24#include "webrtc/video_engine/new_include/call.h"
25#include "webrtc/video_engine/test/common/direct_transport.h"
26#include "webrtc/video_engine/test/common/fake_decoder.h"
27#include "webrtc/video_engine/test/common/fake_encoder.h"
28#include "webrtc/video_engine/test/common/frame_generator.h"
29#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
30#include "webrtc/video_engine/test/common/generate_ssrcs.h"
31
32namespace webrtc {
33
pbos@webrtc.org29023282013-09-11 10:14:56 +000034namespace {
35 static const int kTOffsetExtensionId = 7;
36}
37
pbos@webrtc.org744fbc72013-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()),
47 feedback_transport_(new TransportWrapper(feedback_transport)),
48 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();
57 config.outgoing_transport = feedback_transport_.get();
58 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
59 rtp_rtcp_->SetREMBStatus(true);
60 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
61 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
pbos@webrtc.org29023282013-09-11 10:14:56 +000062 kTOffsetExtensionId);
pbos@webrtc.org744fbc72013-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
77 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
78 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
91 virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
92 return true;
93 }
94
95 EventTypeWrapper Wait() { return all_ssrcs_sent_->Wait(120 * 1000); }
96
97 private:
98 class TransportWrapper : public webrtc::Transport {
99 public:
100 explicit TransportWrapper(newapi::Transport* new_transport)
101 : new_transport_(new_transport) {}
102
103 virtual int SendPacket(int channel, const void* data, int len) OVERRIDE {
104 return new_transport_->SendRTP(static_cast<const uint8_t*>(data), len)
105 ? len
106 : -1;
107 }
108
109 virtual int SendRTCPPacket(int channel,
110 const void* data,
111 int len) OVERRIDE {
112 return new_transport_->SendRTCP(static_cast<const uint8_t*>(data), len)
113 ? len
114 : -1;
115 }
116
117 private:
118 newapi::Transport* new_transport_;
119 };
120
121 static const unsigned int kExpectedBitrateBps = 1200000;
122
123 scoped_ptr<CriticalSectionWrapper> critical_section_;
124 scoped_ptr<EventWrapper> all_ssrcs_sent_;
125 scoped_ptr<RtpHeaderParser> rtp_parser_;
126 scoped_ptr<RtpRtcp> rtp_rtcp_;
127 scoped_ptr<TransportWrapper> feedback_transport_;
128 scoped_ptr<ReceiveStatistics> receive_stats_;
129 scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
130 Clock* clock_;
131 const size_t num_expected_ssrcs_;
132};
133
134class RampUpTest : public ::testing::TestWithParam<bool> {
135 public:
136 virtual void SetUp() { reserved_ssrcs_.clear(); }
137
138 protected:
139 std::map<uint32_t, bool> reserved_ssrcs_;
140};
141
142TEST_P(RampUpTest, RampUpWithPadding) {
143 test::DirectTransport receiver_transport;
144 StreamObserver stream_observer(
145 3, &receiver_transport, Clock::GetRealTimeClock());
146 Call::Config call_config(&stream_observer);
147 scoped_ptr<Call> call(Call::Create(call_config));
148 VideoSendStream::Config send_config = call->GetDefaultSendConfig();
149
150 receiver_transport.SetReceiver(call->Receiver());
151
152 test::FakeEncoder encoder(Clock::GetRealTimeClock());
153 send_config.encoder = &encoder;
154 send_config.internal_source = false;
155 test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
156 send_config.pacing = GetParam();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000157 send_config.rtp.extensions.push_back(
158 RtpExtension("toffset", kTOffsetExtensionId));
pbos@webrtc.org744fbc72013-09-10 09:26:25 +0000159
160 test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
161
162 VideoSendStream* send_stream = call->CreateSendStream(send_config);
163
164 VideoReceiveStream::Config receive_config;
165 receive_config.rtp.ssrc = send_config.rtp.ssrcs[0];
166 receive_config.rtp.nack.rtp_history_ms = send_config.rtp.nack.rtp_history_ms;
167 VideoReceiveStream* receive_stream =
168 call->CreateReceiveStream(receive_config);
169
170 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
171 test::FrameGeneratorCapturer::Create(
172 send_stream->Input(),
173 test::FrameGenerator::Create(send_config.codec.width,
174 send_config.codec.height,
175 Clock::GetRealTimeClock()),
176 30));
177
178 receive_stream->StartReceive();
179 send_stream->StartSend();
180 frame_generator_capturer->Start();
181
182 EXPECT_EQ(kEventSignaled, stream_observer.Wait());
183
184 frame_generator_capturer->Stop();
185 send_stream->StopSend();
186 receive_stream->StopReceive();
187
188 call->DestroyReceiveStream(receive_stream);
189 call->DestroySendStream(send_stream);
190}
191
192INSTANTIATE_TEST_CASE_P(RampUpTest, RampUpTest, ::testing::Bool());
193
194} // namespace webrtc