blob: 84384d0b34e23593273ceab994aa325f9dc4ba66 [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;
Sebastian Janssonef86d142019-04-15 14:42:42 +020033 auto route =
34 s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
35 {s.CreateSimulationNode(NetworkSimulationConfig())},
36 s.CreateClient("callee", CallClientConfig()),
37 {s.CreateSimulationNode(NetworkSimulationConfig())});
Sebastian Janssond37307c2019-02-22 17:07:49 +010038
39 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020040 c->hooks.frame_pair_handlers = {
41 [&](const VideoFramePair&) { frame_counts[0]++; }};
Sebastian Janssond37307c2019-02-22 17:07:49 +010042 c->source.capture = Capture::kVideoFile;
43 c->source.video_file.name = "foreman_cif";
44 c->source.video_file.width = 352;
45 c->source.video_file.height = 288;
46 c->source.framerate = kFrameRates[0];
47 c->encoder.implementation = CodecImpl::kSoftware;
48 c->encoder.codec = Codec::kVideoCodecVP8;
49 });
50 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020051 c->hooks.frame_pair_handlers = {
52 [&](const VideoFramePair&) { frame_counts[1]++; }};
Sebastian Janssond37307c2019-02-22 17:07:49 +010053 c->source.capture = Capture::kImageSlides;
54 c->source.slides.images.crop.width = 320;
55 c->source.slides.images.crop.height = 240;
56 c->source.framerate = kFrameRates[1];
57 c->encoder.implementation = CodecImpl::kSoftware;
58 c->encoder.codec = Codec::kVideoCodecVP9;
59 });
60 s.RunFor(kRunTime);
61 }
62 std::vector<int> expected_counts;
63 for (int fps : kFrameRates)
64 expected_counts.push_back(
65 static_cast<int>(kRunTime.seconds<double>() * fps * 0.8));
66
67 EXPECT_GE(frame_counts[0], expected_counts[0]);
68 EXPECT_GE(frame_counts[1], expected_counts[1]);
69}
70
71// TODO(srte): Enable this after resolving flakiness issues.
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020072TEST(VideoStreamTest, RecievesVp8SimulcastFrames) {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010073 TimeDelta kRunTime = TimeDelta::ms(500);
74 int kFrameRate = 30;
75
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020076 std::deque<std::atomic<int>> frame_counts(3);
77 frame_counts[0] = 0;
78 frame_counts[1] = 0;
79 frame_counts[2] = 0;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010080 {
81 Scenario s;
Sebastian Janssonef86d142019-04-15 14:42:42 +020082 auto route =
83 s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
84 {s.CreateSimulationNode(NetworkSimulationConfig())},
85 s.CreateClient("callee", CallClientConfig()),
86 {s.CreateSimulationNode(NetworkSimulationConfig())});
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010087 s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
88 // TODO(srte): Replace with code checking for all simulcast streams when
89 // there's a hook available for that.
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +020090 c->hooks.frame_pair_handlers = {[&](const VideoFramePair& info) {
91 frame_counts[info.layer_id]++;
92 RTC_DCHECK(info.decoded);
93 printf("%i: [%3i->%3i, %i], %i->%i, \n", info.layer_id, info.capture_id,
94 info.decode_id, info.repeated, info.captured->width(),
95 info.decoded->width());
96 }};
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010097 c->source.framerate = kFrameRate;
98 // The resolution must be high enough to allow smaller layers to be
99 // created.
100 c->source.generator.width = 1024;
101 c->source.generator.height = 768;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100102 c->encoder.implementation = CodecImpl::kSoftware;
103 c->encoder.codec = Codec::kVideoCodecVP8;
104 // By enabling multiple spatial layers, simulcast will be enabled for VP8.
105 c->encoder.layers.spatial = 3;
106 });
107 s.RunFor(kRunTime);
108 }
109
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200110 // Using high error margin to avoid flakyness.
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100111 const int kExpectedCount =
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200112 static_cast<int>(kRunTime.seconds<double>() * kFrameRate * 0.5);
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100113
Sebastian Janssoncf2df2f2019-04-02 11:51:28 +0200114 EXPECT_GE(frame_counts[0], kExpectedCount);
115 EXPECT_GE(frame_counts[1], kExpectedCount);
116 EXPECT_GE(frame_counts[2], kExpectedCount);
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100117}
118} // namespace test
119} // namespace webrtc