blob: 18c1688a3d0324e7538dcdb1d151645e84c9c893 [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
34class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
35 public:
36 typedef std::map<uint32_t, int> BytesSentMap;
37 StreamObserver(int num_expected_ssrcs,
38 newapi::Transport* feedback_transport,
39 Clock* clock)
40 : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
41 all_ssrcs_sent_(EventWrapper::Create()),
42 rtp_parser_(RtpHeaderParser::Create()),
43 feedback_transport_(new TransportWrapper(feedback_transport)),
44 receive_stats_(ReceiveStatistics::Create(clock)),
45 clock_(clock),
46 num_expected_ssrcs_(num_expected_ssrcs) {
47 // Ideally we would only have to instantiate an RtcpSender, an
48 // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current
49 // state of the RTP module we need a full module and receive statistics to
50 // be able to produce an RTCP with REMB.
51 RtpRtcp::Configuration config;
52 config.receive_statistics = receive_stats_.get();
53 config.outgoing_transport = feedback_transport_.get();
54 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
55 rtp_rtcp_->SetREMBStatus(true);
56 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
57 rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset,
58 1);
59 AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
60 remote_bitrate_estimator_.reset(rbe_factory.Create(this, clock));
61 }
62
63 virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
64 unsigned int bitrate) {
65 CriticalSectionScoped lock(critical_section_.get());
66 if (ssrcs.size() == num_expected_ssrcs_ && bitrate >= kExpectedBitrateBps)
67 all_ssrcs_sent_->Set();
68 rtp_rtcp_->SetREMBData(
69 bitrate, static_cast<uint8_t>(ssrcs.size()), &ssrcs[0]);
70 rtp_rtcp_->Process();
71 }
72
73 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
74 CriticalSectionScoped lock(critical_section_.get());
75 RTPHeader header;
76 EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
77 receive_stats_->IncomingPacket(header, length, false);
78 rtp_rtcp_->SetRemoteSSRC(header.ssrc);
79 remote_bitrate_estimator_->IncomingPacket(
80 clock_->TimeInMilliseconds(), static_cast<int>(length - 12), header);
81 if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
82 remote_bitrate_estimator_->Process();
83 }
84 return true;
85 }
86
87 virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
88 return true;
89 }
90
91 EventTypeWrapper Wait() { return all_ssrcs_sent_->Wait(120 * 1000); }
92
93 private:
94 class TransportWrapper : public webrtc::Transport {
95 public:
96 explicit TransportWrapper(newapi::Transport* new_transport)
97 : new_transport_(new_transport) {}
98
99 virtual int SendPacket(int channel, const void* data, int len) OVERRIDE {
100 return new_transport_->SendRTP(static_cast<const uint8_t*>(data), len)
101 ? len
102 : -1;
103 }
104
105 virtual int SendRTCPPacket(int channel,
106 const void* data,
107 int len) OVERRIDE {
108 return new_transport_->SendRTCP(static_cast<const uint8_t*>(data), len)
109 ? len
110 : -1;
111 }
112
113 private:
114 newapi::Transport* new_transport_;
115 };
116
117 static const unsigned int kExpectedBitrateBps = 1200000;
118
119 scoped_ptr<CriticalSectionWrapper> critical_section_;
120 scoped_ptr<EventWrapper> all_ssrcs_sent_;
121 scoped_ptr<RtpHeaderParser> rtp_parser_;
122 scoped_ptr<RtpRtcp> rtp_rtcp_;
123 scoped_ptr<TransportWrapper> feedback_transport_;
124 scoped_ptr<ReceiveStatistics> receive_stats_;
125 scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
126 Clock* clock_;
127 const size_t num_expected_ssrcs_;
128};
129
130class RampUpTest : public ::testing::TestWithParam<bool> {
131 public:
132 virtual void SetUp() { reserved_ssrcs_.clear(); }
133
134 protected:
135 std::map<uint32_t, bool> reserved_ssrcs_;
136};
137
138TEST_P(RampUpTest, RampUpWithPadding) {
139 test::DirectTransport receiver_transport;
140 StreamObserver stream_observer(
141 3, &receiver_transport, Clock::GetRealTimeClock());
142 Call::Config call_config(&stream_observer);
143 scoped_ptr<Call> call(Call::Create(call_config));
144 VideoSendStream::Config send_config = call->GetDefaultSendConfig();
145
146 receiver_transport.SetReceiver(call->Receiver());
147
148 test::FakeEncoder encoder(Clock::GetRealTimeClock());
149 send_config.encoder = &encoder;
150 send_config.internal_source = false;
151 test::FakeEncoder::SetCodecSettings(&send_config.codec, 3);
152 send_config.pacing = GetParam();
153
154 test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_);
155
156 VideoSendStream* send_stream = call->CreateSendStream(send_config);
157
158 VideoReceiveStream::Config receive_config;
159 receive_config.rtp.ssrc = send_config.rtp.ssrcs[0];
160 receive_config.rtp.nack.rtp_history_ms = send_config.rtp.nack.rtp_history_ms;
161 VideoReceiveStream* receive_stream =
162 call->CreateReceiveStream(receive_config);
163
164 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
165 test::FrameGeneratorCapturer::Create(
166 send_stream->Input(),
167 test::FrameGenerator::Create(send_config.codec.width,
168 send_config.codec.height,
169 Clock::GetRealTimeClock()),
170 30));
171
172 receive_stream->StartReceive();
173 send_stream->StartSend();
174 frame_generator_capturer->Start();
175
176 EXPECT_EQ(kEventSignaled, stream_observer.Wait());
177
178 frame_generator_capturer->Stop();
179 send_stream->StopSend();
180 receive_stream->StopReceive();
181
182 call->DestroyReceiveStream(receive_stream);
183 call->DestroySendStream(send_stream);
184}
185
186INSTANTIATE_TEST_CASE_P(RampUpTest, RampUpTest, ::testing::Bool());
187
188} // namespace webrtc