blob: dbd234b8edff3ee870fb340cde5d502b58a61870 [file] [log] [blame]
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +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 <stdio.h>
11
12#include <deque>
13#include <map>
14
pbos@webrtc.org69215d82013-07-10 15:02:02 +000015#include "testing/gtest/include/gtest/gtest.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000016
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000017#include "webrtc/call.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000018#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
19#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000020#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000021#include "webrtc/system_wrappers/interface/clock.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.org94015242013-10-16 11:05:37 +000025#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000026#include "webrtc/system_wrappers/interface/thread_annotations.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000027#include "webrtc/test/direct_transport.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000028#include "webrtc/test/encoder_settings.h"
29#include "webrtc/test/fake_encoder.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000030#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000031#include "webrtc/test/statistics.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000032#include "webrtc/test/testsupport/fileutils.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000033#include "webrtc/typedefs.h"
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000034
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000035namespace webrtc {
36
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000037static const uint32_t kSendSsrc = 0x654321;
pbos@webrtc.org023b1012014-05-13 11:26:40 +000038static const int kFullStackTestDurationSecs = 10;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000039
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000040struct FullStackTestParams {
41 const char* test_label;
42 struct {
43 const char* name;
pbos@webrtc.orgf3f13582013-07-09 14:04:46 +000044 size_t width, height;
45 int fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000046 } clip;
pbos@webrtc.orgf3f13582013-07-09 14:04:46 +000047 unsigned int bitrate;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000048 double avg_psnr_threshold;
49 double avg_ssim_threshold;
50};
51
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000052FullStackTestParams paris_qcif = {
53 "net_delay_0_0_plr_0", {"paris_qcif", 176, 144, 30}, 300, 36.0, 0.96};
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000054
55// TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif.
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000056FullStackTestParams foreman_cif = {
57 "foreman_cif_net_delay_0_0_plr_0",
58 {"foreman_cif", 352, 288, 30},
59 700,
60 0.0,
61 0.0};
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000062
63class FullStackTest : public ::testing::TestWithParam<FullStackTestParams> {
64 protected:
65 std::map<uint32_t, bool> reserved_ssrcs_;
66};
67
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000068class VideoAnalyzer : public PacketReceiver,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000069 public newapi::Transport,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000070 public VideoRenderer,
71 public VideoSendStreamInput {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000072 public:
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000073 VideoAnalyzer(VideoSendStreamInput* input,
74 Transport* transport,
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000075 const char* test_label,
76 double avg_psnr_threshold,
77 double avg_ssim_threshold,
pbos@webrtc.org94015242013-10-16 11:05:37 +000078 int duration_frames)
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000079 : input_(input),
80 transport_(transport),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000081 receiver_(NULL),
82 test_label_(test_label),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000083 frames_left_(duration_frames),
pbos@webrtc.org94015242013-10-16 11:05:37 +000084 dropped_frames_(0),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000085 last_render_time_(0),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000086 rtp_timestamp_delta_(0),
87 crit_(CriticalSectionWrapper::CreateCriticalSection()),
88 first_send_frame_(NULL),
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000089 avg_psnr_threshold_(avg_psnr_threshold),
90 avg_ssim_threshold_(avg_ssim_threshold),
pbos@webrtc.org94015242013-10-16 11:05:37 +000091 comparison_lock_(CriticalSectionWrapper::CreateCriticalSection()),
92 comparison_thread_(ThreadWrapper::CreateThread(&FrameComparisonThread,
93 this)),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000094 done_(EventWrapper::Create()) {
pbos@webrtc.org94015242013-10-16 11:05:37 +000095 unsigned int id;
96 EXPECT_TRUE(comparison_thread_->Start(id));
97 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000098
99 ~VideoAnalyzer() {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000100 EXPECT_TRUE(comparison_thread_->Stop());
101
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000102 while (!frames_.empty()) {
103 delete frames_.back();
104 frames_.pop_back();
105 }
106 while (!frame_pool_.empty()) {
107 delete frame_pool_.back();
108 frame_pool_.pop_back();
109 }
110 }
111
pbos@webrtc.org94015242013-10-16 11:05:37 +0000112 virtual void SetReceiver(PacketReceiver* receiver) { receiver_ = receiver; }
113
pbos@webrtc.org40523702013-08-05 12:49:22 +0000114 virtual bool DeliverPacket(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000115 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
116 RTPHeader header;
pbos@webrtc.org40523702013-08-05 12:49:22 +0000117 parser->Parse(packet, static_cast<int>(length), &header);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000118 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000119 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000120 recv_times_[header.timestamp - rtp_timestamp_delta_] =
121 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
122 }
123
124 return receiver_->DeliverPacket(packet, length);
125 }
126
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000127 virtual void PutFrame(const I420VideoFrame& video_frame) OVERRIDE {
128 ADD_FAILURE() << "PutFrame() should not have been called in this test.";
129 }
130
131 virtual void SwapFrame(I420VideoFrame* video_frame) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000132 I420VideoFrame* copy = NULL;
133 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000134 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000135 if (frame_pool_.size() > 0) {
136 copy = frame_pool_.front();
137 frame_pool_.pop_front();
138 }
139 }
140 if (copy == NULL)
141 copy = new I420VideoFrame();
142
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000143 copy->CopyFrame(*video_frame);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000144 copy->set_timestamp(copy->render_time_ms() * 90);
145
146 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000147 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000148 if (first_send_frame_ == NULL && rtp_timestamp_delta_ == 0)
149 first_send_frame_ = copy;
150
151 frames_.push_back(copy);
152 }
153
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000154 input_->SwapFrame(video_frame);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000155 }
156
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000157 virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000158 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
159 RTPHeader header;
160 parser->Parse(packet, static_cast<int>(length), &header);
161
162 {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000163 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000164 if (rtp_timestamp_delta_ == 0) {
165 rtp_timestamp_delta_ =
166 header.timestamp - first_send_frame_->timestamp();
167 first_send_frame_ = NULL;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000168 }
pbos@webrtc.org7fb9ce02013-08-05 09:29:50 +0000169 send_times_[header.timestamp - rtp_timestamp_delta_] =
170 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000171 }
172
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000173 return transport_->SendRtp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000174 }
175
pbos@webrtc.org27326b62013-11-20 12:17:04 +0000176 virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
177 return transport_->SendRtcp(packet, length);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000178 }
179
180 virtual void RenderFrame(const I420VideoFrame& video_frame,
181 int time_to_render_ms) OVERRIDE {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000182 int64_t render_time_ms =
183 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000184 uint32_t send_timestamp = video_frame.timestamp() - rtp_timestamp_delta_;
185
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000186 CriticalSectionScoped lock(crit_.get());
187 while (frames_.front()->timestamp() < send_timestamp) {
188 AddFrameComparison(
189 frames_.front(), &last_rendered_frame_, true, render_time_ms);
190 frame_pool_.push_back(frames_.front());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000191 frames_.pop_front();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000192 }
193
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000194 I420VideoFrame* reference_frame = frames_.front();
195 frames_.pop_front();
196 assert(reference_frame != NULL);
197 EXPECT_EQ(reference_frame->timestamp(), send_timestamp);
198 assert(reference_frame->timestamp() == send_timestamp);
199
200 AddFrameComparison(reference_frame, &video_frame, false, render_time_ms);
201 frame_pool_.push_back(reference_frame);
202
pbos@webrtc.org94015242013-10-16 11:05:37 +0000203 last_rendered_frame_.CopyFrame(video_frame);
204 }
205
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000206 void Wait() { done_->Wait(120 * 1000); }
pbos@webrtc.org94015242013-10-16 11:05:37 +0000207
208 VideoSendStreamInput* input_;
209 Transport* transport_;
210 PacketReceiver* receiver_;
211
212 private:
213 struct FrameComparison {
214 FrameComparison(const I420VideoFrame* reference,
215 const I420VideoFrame* render,
216 bool dropped,
217 int64_t send_time_ms,
218 int64_t recv_time_ms,
219 int64_t render_time_ms)
220 : dropped(dropped),
221 send_time_ms(send_time_ms),
222 recv_time_ms(recv_time_ms),
223 render_time_ms(render_time_ms) {
224 this->reference.CopyFrame(*reference);
225 this->render.CopyFrame(*render);
226 }
227
228 FrameComparison(const FrameComparison& compare)
229 : dropped(compare.dropped),
230 send_time_ms(compare.send_time_ms),
231 recv_time_ms(compare.recv_time_ms),
232 render_time_ms(compare.render_time_ms) {
233 this->reference.CopyFrame(compare.reference);
234 this->render.CopyFrame(compare.render);
235 }
236
237 ~FrameComparison() {}
238
239 I420VideoFrame reference;
240 I420VideoFrame render;
241 bool dropped;
242 int64_t send_time_ms;
243 int64_t recv_time_ms;
244 int64_t render_time_ms;
245 };
246
247 void AddFrameComparison(const I420VideoFrame* reference,
248 const I420VideoFrame* render,
249 bool dropped,
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000250 int64_t render_time_ms)
251 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
pbos@webrtc.org94015242013-10-16 11:05:37 +0000252 int64_t send_time_ms = send_times_[reference->timestamp()];
253 send_times_.erase(reference->timestamp());
254 int64_t recv_time_ms = recv_times_[reference->timestamp()];
255 recv_times_.erase(reference->timestamp());
256
257 CriticalSectionScoped crit(comparison_lock_.get());
258 comparisons_.push_back(FrameComparison(reference,
259 render,
260 dropped,
261 send_time_ms,
262 recv_time_ms,
263 render_time_ms));
264 }
265
266 static bool FrameComparisonThread(void* obj) {
267 return static_cast<VideoAnalyzer*>(obj)->CompareFrames();
268 }
269
270 bool CompareFrames() {
271 assert(frames_left_ > 0);
272
273 I420VideoFrame reference;
274 I420VideoFrame render;
275 bool dropped;
276 int64_t send_time_ms;
277 int64_t recv_time_ms;
278 int64_t render_time_ms;
279
280 SleepMs(10);
281
282 while (true) {
283 {
284 CriticalSectionScoped crit(comparison_lock_.get());
285 if (comparisons_.empty())
286 return true;
287 reference.SwapFrame(&comparisons_.front().reference);
288 render.SwapFrame(&comparisons_.front().render);
289 dropped = comparisons_.front().dropped;
290 send_time_ms = comparisons_.front().send_time_ms;
291 recv_time_ms = comparisons_.front().recv_time_ms;
292 render_time_ms = comparisons_.front().render_time_ms;
293 comparisons_.pop_front();
294 }
295
296 PerformFrameComparison(&reference,
297 &render,
298 dropped,
299 send_time_ms,
300 recv_time_ms,
301 render_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000302
303 if (--frames_left_ == 0) {
304 PrintResult("psnr", psnr_, " dB");
305 PrintResult("ssim", ssim_, "");
306 PrintResult("sender_time", sender_time_, " ms");
pbos@webrtc.org94015242013-10-16 11:05:37 +0000307 printf(
308 "RESULT dropped_frames: %s = %d\n", test_label_, dropped_frames_);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000309 PrintResult("receiver_time", receiver_time_, " ms");
310 PrintResult("total_delay_incl_network", end_to_end_, " ms");
311 PrintResult("time_between_rendered_frames", rendered_delta_, " ms");
312 EXPECT_GT(psnr_.Mean(), avg_psnr_threshold_);
313 EXPECT_GT(ssim_.Mean(), avg_ssim_threshold_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000314 done_->Set();
pbos@webrtc.org94015242013-10-16 11:05:37 +0000315
316 return false;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000317 }
318 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000319 }
320
pbos@webrtc.org94015242013-10-16 11:05:37 +0000321 void PerformFrameComparison(const I420VideoFrame* reference,
322 const I420VideoFrame* render,
323 bool dropped,
324 int64_t send_time_ms,
325 int64_t recv_time_ms,
326 int64_t render_time_ms) {
327 psnr_.AddSample(I420PSNR(reference, render));
328 ssim_.AddSample(I420SSIM(reference, render));
329 if (dropped) {
330 ++dropped_frames_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000331 return;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000332 }
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000333 if (last_render_time_ != 0)
pbos@webrtc.org94015242013-10-16 11:05:37 +0000334 rendered_delta_.AddSample(render_time_ms - last_render_time_);
335 last_render_time_ = render_time_ms;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000336
pbos@webrtc.org94015242013-10-16 11:05:37 +0000337 int64_t input_time_ms = reference->render_time_ms();
338 sender_time_.AddSample(send_time_ms - input_time_ms);
339 receiver_time_.AddSample(render_time_ms - recv_time_ms);
340 end_to_end_.AddSample(render_time_ms - input_time_ms);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000341 }
342
343 void PrintResult(const char* result_type,
344 test::Statistics stats,
345 const char* unit) {
346 printf("RESULT %s: %s = {%f, %f}%s\n",
347 result_type,
348 test_label_,
349 stats.Mean(),
350 stats.StandardDeviation(),
351 unit);
352 }
353
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000354 const char* const test_label_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000355 test::Statistics sender_time_;
356 test::Statistics receiver_time_;
357 test::Statistics psnr_;
358 test::Statistics ssim_;
359 test::Statistics end_to_end_;
360 test::Statistics rendered_delta_;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000361 int frames_left_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000362 int dropped_frames_;
363 int64_t last_render_time_;
364 uint32_t rtp_timestamp_delta_;
365
366 const scoped_ptr<CriticalSectionWrapper> crit_;
367 std::deque<I420VideoFrame*> frames_ GUARDED_BY(crit_);
368 std::deque<I420VideoFrame*> frame_pool_ GUARDED_BY(crit_);
369 I420VideoFrame last_rendered_frame_ GUARDED_BY(crit_);
370 std::map<uint32_t, int64_t> send_times_ GUARDED_BY(crit_);
371 std::map<uint32_t, int64_t> recv_times_ GUARDED_BY(crit_);
372 I420VideoFrame* first_send_frame_ GUARDED_BY(crit_);
373 double avg_psnr_threshold_ GUARDED_BY(crit_);
374 double avg_ssim_threshold_ GUARDED_BY(crit_);
375
376 const scoped_ptr<CriticalSectionWrapper> comparison_lock_;
377 const scoped_ptr<ThreadWrapper> comparison_thread_;
378 std::deque<FrameComparison> comparisons_ GUARDED_BY(comparison_lock_);
379 const scoped_ptr<EventWrapper> done_;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000380};
381
pbos@webrtc.org94015242013-10-16 11:05:37 +0000382TEST_P(FullStackTest, NoPacketLoss) {
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +0000383 static const uint32_t kReceiverLocalSsrc = 0x123456;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000384 FullStackTestParams params = GetParam();
385
pbos@webrtc.org96684672013-08-12 12:59:04 +0000386 test::DirectTransport transport;
pbos@webrtc.org94015242013-10-16 11:05:37 +0000387 VideoAnalyzer analyzer(NULL,
388 &transport,
389 params.test_label,
390 params.avg_psnr_threshold,
391 params.avg_ssim_threshold,
pbos@webrtc.org023b1012014-05-13 11:26:40 +0000392 kFullStackTestDurationSecs * params.clip.fps);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000393
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000394 Call::Config call_config(&analyzer);
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +0000395
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000396 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org94015242013-10-16 11:05:37 +0000397 analyzer.SetReceiver(call->Receiver());
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000398 transport.SetReceiver(&analyzer);
399
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000400 VideoSendStream::Config send_config = call->GetDefaultSendConfig();
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +0000401 send_config.rtp.ssrcs.push_back(kSendSsrc);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000402
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000403 scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
404 send_config.encoder_settings =
405 test::CreateEncoderSettings(encoder.get(), "VP8", 124, 1);
406 VideoStream* stream = &send_config.encoder_settings.streams[0];
407 stream->width = params.clip.width;
408 stream->height = params.clip.height;
409 stream->min_bitrate_bps = stream->target_bitrate_bps =
410 stream->max_bitrate_bps = params.bitrate * 1000;
411 stream->max_framerate = params.clip.fps;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000412
pbos@webrtc.org5a636552013-11-20 10:40:25 +0000413 VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000414 analyzer.input_ = send_stream->Input();
415
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000416 scoped_ptr<test::FrameGeneratorCapturer> file_capturer(
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000417 test::FrameGeneratorCapturer::CreateFromYuvFile(
pbos@webrtc.org4c966012013-08-21 12:07:37 +0000418 &analyzer,
andresp@webrtc.orgab654952013-09-19 12:14:03 +0000419 test::ResourcePath(params.clip.name, "yuv").c_str(),
420 params.clip.width,
421 params.clip.height,
422 params.clip.fps,
423 Clock::GetRealTimeClock()));
pbos@webrtc.org94015242013-10-16 11:05:37 +0000424 ASSERT_TRUE(file_capturer.get() != NULL)
425 << "Could not create capturer for " << params.clip.name
426 << ".yuv. Is this resource file present?";
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000427
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000428 VideoReceiveStream::Config receive_config = call->GetDefaultReceiveConfig();
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000429 VideoCodec codec =
430 test::CreateDecoderVideoCodec(send_config.encoder_settings);
431 receive_config.codecs.push_back(codec);
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +0000432 receive_config.rtp.remote_ssrc = send_config.rtp.ssrcs[0];
433 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000434 receive_config.renderer = &analyzer;
435
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000436 VideoReceiveStream* receive_stream =
pbos@webrtc.org5a636552013-11-20 10:40:25 +0000437 call->CreateVideoReceiveStream(receive_config);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000438
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000439 receive_stream->Start();
440 send_stream->Start();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000441 file_capturer->Start();
442
443 analyzer.Wait();
444
445 file_capturer->Stop();
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000446 send_stream->Stop();
447 receive_stream->Stop();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000448
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000449 call->DestroyVideoReceiveStream(receive_stream);
450 call->DestroyVideoSendStream(send_stream);
pbos@webrtc.org96684672013-08-12 12:59:04 +0000451
452 transport.StopSending();
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000453}
454
455INSTANTIATE_TEST_CASE_P(FullStack,
456 FullStackTest,
457 ::testing::Values(paris_qcif, foreman_cif));
458
459} // namespace webrtc