blob: 936a518ecd5b64cac7d87a7efa8b1e905d2c97c3 [file] [log] [blame]
Sebastian Jansson5fbebd52019-02-20 11:16:19 +01001/*
2 * Copyright 2019 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 <atomic>
11
12#include "test/gtest.h"
13#include "test/scenario/scenario.h"
14
15namespace webrtc {
16namespace test {
17namespace {
Sebastian Janssond37307c2019-02-22 17:07:49 +010018using Capture = VideoStreamConfig::Source::Capture;
19using ContentType = VideoStreamConfig::Encoder::ContentType;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010020using Codec = VideoStreamConfig::Encoder::Codec;
21using CodecImpl = VideoStreamConfig::Encoder::Implementation;
22} // namespace
23
Sebastian Janssond37307c2019-02-22 17:07:49 +010024// TODO(srte): Enable this after resolving flakiness issues.
25TEST(VideoStreamTest, DISABLED_ReceivesFramesFromFileBasedStreams) {
26 TimeDelta kRunTime = TimeDelta::ms(500);
27 std::vector<int> kFrameRates = {15, 30};
28 std::deque<std::atomic<int>> frame_counts(2);
29 frame_counts[0] = 0;
30 frame_counts[1] = 0;
31 {
32 Scenario s;
33 auto route = s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
34 {s.CreateSimulationNode(NetworkNodeConfig())},
35 s.CreateClient("callee", CallClientConfig()),
36 {s.CreateSimulationNode(NetworkNodeConfig())});
37
38 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020039 c->hooks.frame_pair_handlers = {
40 [&](const VideoFramePair&) { frame_counts[0]++; }};
Sebastian Janssond37307c2019-02-22 17:07:49 +010041 c->source.capture = Capture::kVideoFile;
42 c->source.video_file.name = "foreman_cif";
43 c->source.video_file.width = 352;
44 c->source.video_file.height = 288;
45 c->source.framerate = kFrameRates[0];
46 c->encoder.implementation = CodecImpl::kSoftware;
47 c->encoder.codec = Codec::kVideoCodecVP8;
48 });
49 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020050 c->hooks.frame_pair_handlers = {
51 [&](const VideoFramePair&) { frame_counts[1]++; }};
Sebastian Janssond37307c2019-02-22 17:07:49 +010052 c->source.capture = Capture::kImageSlides;
53 c->source.slides.images.crop.width = 320;
54 c->source.slides.images.crop.height = 240;
55 c->source.framerate = kFrameRates[1];
56 c->encoder.implementation = CodecImpl::kSoftware;
57 c->encoder.codec = Codec::kVideoCodecVP9;
58 });
59 s.RunFor(kRunTime);
60 }
61 std::vector<int> expected_counts;
62 for (int fps : kFrameRates)
63 expected_counts.push_back(
64 static_cast<int>(kRunTime.seconds<double>() * fps * 0.8));
65
66 EXPECT_GE(frame_counts[0], expected_counts[0]);
67 EXPECT_GE(frame_counts[1], expected_counts[1]);
68}
69
70// TODO(srte): Enable this after resolving flakiness issues.
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020071TEST(VideoStreamTest, RecievesVp8SimulcastFrames) {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010072 TimeDelta kRunTime = TimeDelta::ms(500);
73 int kFrameRate = 30;
74
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020075 std::deque<std::atomic<int>> frame_counts(3);
76 frame_counts[0] = 0;
77 frame_counts[1] = 0;
78 frame_counts[2] = 0;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010079 {
80 Scenario s;
81 auto route = s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
82 {s.CreateSimulationNode(NetworkNodeConfig())},
83 s.CreateClient("callee", CallClientConfig()),
84 {s.CreateSimulationNode(NetworkNodeConfig())});
85 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
86 // TODO(srte): Replace with code checking for all simulcast streams when
87 // there's a hook available for that.
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020088 c->hooks.frame_pair_handlers = {[&](const VideoFramePair& info) {
89 frame_counts[info.layer_id]++;
90 RTC_DCHECK(info.decoded);
91 printf("%i: [%3i->%3i, %i], %i->%i, \n", info.layer_id, info.capture_id,
92 info.decode_id, info.repeated, info.captured->width(),
93 info.decoded->width());
94 }};
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010095 c->source.framerate = kFrameRate;
96 // The resolution must be high enough to allow smaller layers to be
97 // created.
98 c->source.generator.width = 1024;
99 c->source.generator.height = 768;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100100 c->encoder.implementation = CodecImpl::kSoftware;
101 c->encoder.codec = Codec::kVideoCodecVP8;
102 // By enabling multiple spatial layers, simulcast will be enabled for VP8.
103 c->encoder.layers.spatial = 3;
104 });
105 s.RunFor(kRunTime);
106 }
107
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200108 // Using high error margin to avoid flakyness.
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100109 const int kExpectedCount =
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200110 static_cast<int>(kRunTime.seconds<double>() * kFrameRate * 0.5);
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100111
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200112 EXPECT_GE(frame_counts[0], kExpectedCount);
113 EXPECT_GE(frame_counts[1], kExpectedCount);
114 EXPECT_GE(frame_counts[2], kExpectedCount);
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100115}
116} // namespace test
117} // namespace webrtc