1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "cast/streaming/capture_recommendations.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include "absl/types/optional.h"
8*3f982cf4SFabien Sanglard #include "cast/streaming/answer_messages.h"
9*3f982cf4SFabien Sanglard #include "cast/streaming/resolution.h"
10*3f982cf4SFabien Sanglard #include "gmock/gmock.h"
11*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
12*3f982cf4SFabien Sanglard #include "util/chrono_helpers.h"
13*3f982cf4SFabien Sanglard
14*3f982cf4SFabien Sanglard namespace openscreen {
15*3f982cf4SFabien Sanglard namespace cast {
16*3f982cf4SFabien Sanglard namespace capture_recommendations {
17*3f982cf4SFabien Sanglard namespace {
18*3f982cf4SFabien Sanglard
19*3f982cf4SFabien Sanglard const Recommendations kDefaultRecommendations{
20*3f982cf4SFabien Sanglard Audio{BitRateLimits{32000, 256000}, milliseconds(400), 2, 48000, 16000},
21*3f982cf4SFabien Sanglard Video{BitRateLimits{300000, 1920 * 1080 * 30}, Resolution{320, 240},
22*3f982cf4SFabien Sanglard Dimensions{1920, 1080, 30}, false, milliseconds(400),
23*3f982cf4SFabien Sanglard 1920 * 1080 * 30 / 8}};
24*3f982cf4SFabien Sanglard
25*3f982cf4SFabien Sanglard const DisplayDescription kEmptyDescription{};
26*3f982cf4SFabien Sanglard
27*3f982cf4SFabien Sanglard const DisplayDescription kValidOnlyResolution{
28*3f982cf4SFabien Sanglard Dimensions{1024, 768, SimpleFraction{60, 1}}, absl::nullopt, absl::nullopt};
29*3f982cf4SFabien Sanglard
30*3f982cf4SFabien Sanglard const DisplayDescription kValidOnlyAspectRatio{absl::nullopt, AspectRatio{4, 3},
31*3f982cf4SFabien Sanglard absl::nullopt};
32*3f982cf4SFabien Sanglard
33*3f982cf4SFabien Sanglard const DisplayDescription kValidOnlyAspectRatioSixteenNine{
34*3f982cf4SFabien Sanglard absl::nullopt, AspectRatio{16, 9}, absl::nullopt};
35*3f982cf4SFabien Sanglard
36*3f982cf4SFabien Sanglard const DisplayDescription kValidOnlyVariable{absl::nullopt, absl::nullopt,
37*3f982cf4SFabien Sanglard AspectRatioConstraint::kVariable};
38*3f982cf4SFabien Sanglard
39*3f982cf4SFabien Sanglard const DisplayDescription kInvalidOnlyFixed{absl::nullopt, absl::nullopt,
40*3f982cf4SFabien Sanglard AspectRatioConstraint::kFixed};
41*3f982cf4SFabien Sanglard
42*3f982cf4SFabien Sanglard const DisplayDescription kValidFixedAspectRatio{
43*3f982cf4SFabien Sanglard absl::nullopt, AspectRatio{4, 3}, AspectRatioConstraint::kFixed};
44*3f982cf4SFabien Sanglard
45*3f982cf4SFabien Sanglard const DisplayDescription kValidVariableAspectRatio{
46*3f982cf4SFabien Sanglard absl::nullopt, AspectRatio{4, 3}, AspectRatioConstraint::kVariable};
47*3f982cf4SFabien Sanglard
48*3f982cf4SFabien Sanglard const DisplayDescription kValidFixedMissingAspectRatio{
49*3f982cf4SFabien Sanglard Dimensions{1024, 768, SimpleFraction{60, 1}}, absl::nullopt,
50*3f982cf4SFabien Sanglard AspectRatioConstraint::kFixed};
51*3f982cf4SFabien Sanglard
52*3f982cf4SFabien Sanglard const DisplayDescription kValidDisplayFhd{
53*3f982cf4SFabien Sanglard Dimensions{1920, 1080, SimpleFraction{30, 1}}, AspectRatio{16, 9},
54*3f982cf4SFabien Sanglard AspectRatioConstraint::kVariable};
55*3f982cf4SFabien Sanglard
56*3f982cf4SFabien Sanglard const DisplayDescription kValidDisplayXga{
57*3f982cf4SFabien Sanglard Dimensions{1024, 768, SimpleFraction{60, 1}}, AspectRatio{4, 3},
58*3f982cf4SFabien Sanglard AspectRatioConstraint::kFixed};
59*3f982cf4SFabien Sanglard
60*3f982cf4SFabien Sanglard const DisplayDescription kValidDisplayTiny{
61*3f982cf4SFabien Sanglard Dimensions{300, 200, SimpleFraction{30, 1}}, AspectRatio{3, 2},
62*3f982cf4SFabien Sanglard AspectRatioConstraint::kFixed};
63*3f982cf4SFabien Sanglard
64*3f982cf4SFabien Sanglard const DisplayDescription kValidDisplayMismatched{
65*3f982cf4SFabien Sanglard Dimensions{300, 200, SimpleFraction{30, 1}}, AspectRatio{3, 4},
66*3f982cf4SFabien Sanglard AspectRatioConstraint::kFixed};
67*3f982cf4SFabien Sanglard
68*3f982cf4SFabien Sanglard const Constraints kEmptyConstraints{};
69*3f982cf4SFabien Sanglard
70*3f982cf4SFabien Sanglard const Constraints kValidConstraintsHighEnd{
71*3f982cf4SFabien Sanglard {96100, 5, 96000, 500000, std::chrono::seconds(6)},
72*3f982cf4SFabien Sanglard {6000000, Dimensions{640, 480, SimpleFraction{30, 1}},
73*3f982cf4SFabien Sanglard Dimensions{3840, 2160, SimpleFraction{144, 1}}, 600000, 6000000,
74*3f982cf4SFabien Sanglard std::chrono::seconds(6)}};
75*3f982cf4SFabien Sanglard
76*3f982cf4SFabien Sanglard const Constraints kValidConstraintsLowEnd{
77*3f982cf4SFabien Sanglard {22000, 2, 24000, 50000, std::chrono::seconds(1)},
78*3f982cf4SFabien Sanglard {60000, Dimensions{120, 80, SimpleFraction{10, 1}},
79*3f982cf4SFabien Sanglard Dimensions{1200, 800, SimpleFraction{30, 1}}, 100000, 1000000,
80*3f982cf4SFabien Sanglard std::chrono::seconds(1)}};
81*3f982cf4SFabien Sanglard
82*3f982cf4SFabien Sanglard } // namespace
83*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,UsesDefaultsIfNoReceiverInformationAvailable)84*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, UsesDefaultsIfNoReceiverInformationAvailable) {
85*3f982cf4SFabien Sanglard EXPECT_EQ(kDefaultRecommendations, GetRecommendations(Answer{}));
86*3f982cf4SFabien Sanglard }
87*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,EmptyDisplayDescription)88*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, EmptyDisplayDescription) {
89*3f982cf4SFabien Sanglard Answer answer;
90*3f982cf4SFabien Sanglard answer.display = kEmptyDescription;
91*3f982cf4SFabien Sanglard EXPECT_EQ(kDefaultRecommendations, GetRecommendations(answer));
92*3f982cf4SFabien Sanglard }
93*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,OnlyResolution)94*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, OnlyResolution) {
95*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
96*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1024, 768, 60.0};
97*3f982cf4SFabien Sanglard expected.video.bit_rate_limits.maximum = 47185920;
98*3f982cf4SFabien Sanglard Answer answer;
99*3f982cf4SFabien Sanglard answer.display = kValidOnlyResolution;
100*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
101*3f982cf4SFabien Sanglard }
102*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,OnlyAspectRatioFourThirds)103*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, OnlyAspectRatioFourThirds) {
104*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
105*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{320, 240};
106*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1440, 1080, 30.0};
107*3f982cf4SFabien Sanglard Answer answer;
108*3f982cf4SFabien Sanglard answer.display = kValidOnlyAspectRatio;
109*3f982cf4SFabien Sanglard
110*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
111*3f982cf4SFabien Sanglard }
112*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,OnlyAspectRatioSixteenNine)113*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, OnlyAspectRatioSixteenNine) {
114*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
115*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{426, 240};
116*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1920, 1080, 30.0};
117*3f982cf4SFabien Sanglard Answer answer;
118*3f982cf4SFabien Sanglard answer.display = kValidOnlyAspectRatioSixteenNine;
119*3f982cf4SFabien Sanglard
120*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
121*3f982cf4SFabien Sanglard }
122*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,OnlyAspectRatioConstraint)123*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, OnlyAspectRatioConstraint) {
124*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
125*3f982cf4SFabien Sanglard expected.video.supports_scaling = true;
126*3f982cf4SFabien Sanglard Answer answer;
127*3f982cf4SFabien Sanglard answer.display = kValidOnlyVariable;
128*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
129*3f982cf4SFabien Sanglard }
130*3f982cf4SFabien Sanglard
131*3f982cf4SFabien Sanglard // It doesn't make sense to just provide a "fixed" aspect ratio with no
132*3f982cf4SFabien Sanglard // other dimension information, so we just return default recommendations
133*3f982cf4SFabien Sanglard // in this case and assume the sender will handle it elsewhere, e.g. on
134*3f982cf4SFabien Sanglard // ANSWER message parsing.
TEST(CaptureRecommendationsTest,OnlyInvalidAspectRatioConstraint)135*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, OnlyInvalidAspectRatioConstraint) {
136*3f982cf4SFabien Sanglard Answer answer;
137*3f982cf4SFabien Sanglard answer.display = kInvalidOnlyFixed;
138*3f982cf4SFabien Sanglard EXPECT_EQ(kDefaultRecommendations, GetRecommendations(answer));
139*3f982cf4SFabien Sanglard }
140*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,FixedAspectRatioConstraint)141*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, FixedAspectRatioConstraint) {
142*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
143*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{320, 240};
144*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1440, 1080, 30.0};
145*3f982cf4SFabien Sanglard expected.video.supports_scaling = false;
146*3f982cf4SFabien Sanglard Answer answer;
147*3f982cf4SFabien Sanglard answer.display = kValidFixedAspectRatio;
148*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
149*3f982cf4SFabien Sanglard }
150*3f982cf4SFabien Sanglard
151*3f982cf4SFabien Sanglard // Our behavior is actually the same whether the constraint is passed, we
152*3f982cf4SFabien Sanglard // just percolate the constraint up to the capture devices so that intermediate
153*3f982cf4SFabien Sanglard // frame sizes between minimum and maximum can be properly scaled.
TEST(CaptureRecommendationsTest,VariableAspectRatioConstraint)154*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, VariableAspectRatioConstraint) {
155*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
156*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{320, 240};
157*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1440, 1080, 30.0};
158*3f982cf4SFabien Sanglard expected.video.supports_scaling = true;
159*3f982cf4SFabien Sanglard Answer answer;
160*3f982cf4SFabien Sanglard answer.display = kValidVariableAspectRatio;
161*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
162*3f982cf4SFabien Sanglard }
163*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,ResolutionWithFixedConstraint)164*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, ResolutionWithFixedConstraint) {
165*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
166*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{320, 240};
167*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1024, 768, 60.0};
168*3f982cf4SFabien Sanglard expected.video.supports_scaling = false;
169*3f982cf4SFabien Sanglard expected.video.bit_rate_limits.maximum = 47185920;
170*3f982cf4SFabien Sanglard Answer answer;
171*3f982cf4SFabien Sanglard answer.display = kValidFixedMissingAspectRatio;
172*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
173*3f982cf4SFabien Sanglard }
174*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,ExplicitFhdChangesMinimum)175*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, ExplicitFhdChangesMinimum) {
176*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
177*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{426, 240};
178*3f982cf4SFabien Sanglard expected.video.supports_scaling = true;
179*3f982cf4SFabien Sanglard Answer answer;
180*3f982cf4SFabien Sanglard answer.display = kValidDisplayFhd;
181*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
182*3f982cf4SFabien Sanglard }
183*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,XgaResolution)184*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, XgaResolution) {
185*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
186*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{320, 240};
187*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{1024, 768, 60.0};
188*3f982cf4SFabien Sanglard expected.video.supports_scaling = false;
189*3f982cf4SFabien Sanglard expected.video.bit_rate_limits.maximum = 47185920;
190*3f982cf4SFabien Sanglard Answer answer;
191*3f982cf4SFabien Sanglard answer.display = kValidDisplayXga;
192*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
193*3f982cf4SFabien Sanglard }
194*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,MismatchedDisplayAndAspectRatio)195*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, MismatchedDisplayAndAspectRatio) {
196*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
197*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{150, 200};
198*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{150, 200, 30.0};
199*3f982cf4SFabien Sanglard expected.video.supports_scaling = false;
200*3f982cf4SFabien Sanglard expected.video.bit_rate_limits.maximum = 300 * 200 * 30;
201*3f982cf4SFabien Sanglard Answer answer;
202*3f982cf4SFabien Sanglard answer.display = kValidDisplayMismatched;
203*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
204*3f982cf4SFabien Sanglard }
205*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,TinyDisplay)206*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, TinyDisplay) {
207*3f982cf4SFabien Sanglard Recommendations expected = kDefaultRecommendations;
208*3f982cf4SFabien Sanglard expected.video.minimum = Resolution{300, 200};
209*3f982cf4SFabien Sanglard expected.video.maximum = Dimensions{300, 200, 30.0};
210*3f982cf4SFabien Sanglard expected.video.supports_scaling = false;
211*3f982cf4SFabien Sanglard expected.video.bit_rate_limits.maximum = 300 * 200 * 30;
212*3f982cf4SFabien Sanglard Answer answer;
213*3f982cf4SFabien Sanglard answer.display = kValidDisplayTiny;
214*3f982cf4SFabien Sanglard EXPECT_EQ(expected, GetRecommendations(answer));
215*3f982cf4SFabien Sanglard }
216*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,EmptyConstraints)217*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, EmptyConstraints) {
218*3f982cf4SFabien Sanglard Answer answer;
219*3f982cf4SFabien Sanglard answer.constraints = kEmptyConstraints;
220*3f982cf4SFabien Sanglard EXPECT_EQ(kDefaultRecommendations, GetRecommendations(answer));
221*3f982cf4SFabien Sanglard }
222*3f982cf4SFabien Sanglard
223*3f982cf4SFabien Sanglard // Generally speaking, if the receiver gives us constraints higher than our
224*3f982cf4SFabien Sanglard // defaults we will accept them, with the exception of maximum resolutions
225*3f982cf4SFabien Sanglard // exceeding 1080P.
TEST(CaptureRecommendationsTest,HandlesHighEnd)226*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, HandlesHighEnd) {
227*3f982cf4SFabien Sanglard const Recommendations kExpected{
228*3f982cf4SFabien Sanglard Audio{BitRateLimits{96000, 500000}, milliseconds(6000), 5, 96100, 16000},
229*3f982cf4SFabien Sanglard Video{BitRateLimits{600000, 6000000}, Resolution{640, 480},
230*3f982cf4SFabien Sanglard Dimensions{1920, 1080, 30}, false, milliseconds(6000), 6000000}};
231*3f982cf4SFabien Sanglard Answer answer;
232*3f982cf4SFabien Sanglard answer.constraints = kValidConstraintsHighEnd;
233*3f982cf4SFabien Sanglard EXPECT_EQ(kExpected, GetRecommendations(answer));
234*3f982cf4SFabien Sanglard }
235*3f982cf4SFabien Sanglard
236*3f982cf4SFabien Sanglard // However, if the receiver gives us constraints lower than our minimum
237*3f982cf4SFabien Sanglard // defaults, we will ignore them--they would result in an unacceptable cast
238*3f982cf4SFabien Sanglard // experience.
TEST(CaptureRecommendationsTest,HandlesLowEnd)239*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, HandlesLowEnd) {
240*3f982cf4SFabien Sanglard const Recommendations kExpected{
241*3f982cf4SFabien Sanglard Audio{BitRateLimits{32000, 50000}, milliseconds(1000), 2, 22000, 16000},
242*3f982cf4SFabien Sanglard Video{BitRateLimits{300000, 1000000}, Resolution{320, 240},
243*3f982cf4SFabien Sanglard Dimensions{1200, 800, 30}, false, milliseconds(1000), 60000}};
244*3f982cf4SFabien Sanglard Answer answer;
245*3f982cf4SFabien Sanglard answer.constraints = kValidConstraintsLowEnd;
246*3f982cf4SFabien Sanglard EXPECT_EQ(kExpected, GetRecommendations(answer));
247*3f982cf4SFabien Sanglard }
248*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,HandlesTooSmallScreen)249*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, HandlesTooSmallScreen) {
250*3f982cf4SFabien Sanglard const Recommendations kExpected{
251*3f982cf4SFabien Sanglard Audio{BitRateLimits{32000, 50000}, milliseconds(1000), 2, 22000, 16000},
252*3f982cf4SFabien Sanglard Video{BitRateLimits{300000, 1000000}, Resolution{320, 240},
253*3f982cf4SFabien Sanglard Dimensions{320, 240, 30}, false, milliseconds(1000), 60000}};
254*3f982cf4SFabien Sanglard Answer answer;
255*3f982cf4SFabien Sanglard answer.constraints = kValidConstraintsLowEnd;
256*3f982cf4SFabien Sanglard answer.constraints->video.max_dimensions =
257*3f982cf4SFabien Sanglard answer.constraints->video.min_resolution.value();
258*3f982cf4SFabien Sanglard EXPECT_EQ(kExpected, GetRecommendations(answer));
259*3f982cf4SFabien Sanglard }
260*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,HandlesMinimumSizeScreen)261*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, HandlesMinimumSizeScreen) {
262*3f982cf4SFabien Sanglard const Recommendations kExpected{
263*3f982cf4SFabien Sanglard Audio{BitRateLimits{32000, 50000}, milliseconds(1000), 2, 22000, 16000},
264*3f982cf4SFabien Sanglard Video{BitRateLimits{300000, 1000000}, Resolution{320, 240},
265*3f982cf4SFabien Sanglard Dimensions{320, 240, 30}, false, milliseconds(1000), 60000}};
266*3f982cf4SFabien Sanglard Answer answer;
267*3f982cf4SFabien Sanglard answer.constraints = kValidConstraintsLowEnd;
268*3f982cf4SFabien Sanglard answer.constraints->video.max_dimensions =
269*3f982cf4SFabien Sanglard Dimensions{320, 240, SimpleFraction{30, 1}};
270*3f982cf4SFabien Sanglard EXPECT_EQ(kExpected, GetRecommendations(answer));
271*3f982cf4SFabien Sanglard }
272*3f982cf4SFabien Sanglard
TEST(CaptureRecommendationsTest,UsesIntersectionOfDisplayAndConstraints)273*3f982cf4SFabien Sanglard TEST(CaptureRecommendationsTest, UsesIntersectionOfDisplayAndConstraints) {
274*3f982cf4SFabien Sanglard const Recommendations kExpected{
275*3f982cf4SFabien Sanglard Audio{BitRateLimits{96000, 500000}, milliseconds(6000), 5, 96100, 16000},
276*3f982cf4SFabien Sanglard Video{BitRateLimits{600000, 6000000}, Resolution{640, 480},
277*3f982cf4SFabien Sanglard // Max resolution should be 1080P, since that's the display
278*3f982cf4SFabien Sanglard // resolution. No reason to capture at 4K, even though the
279*3f982cf4SFabien Sanglard // receiver supports it.
280*3f982cf4SFabien Sanglard Dimensions{1920, 1080, 30}, true, milliseconds(6000), 6000000}};
281*3f982cf4SFabien Sanglard Answer answer;
282*3f982cf4SFabien Sanglard answer.display = kValidDisplayFhd;
283*3f982cf4SFabien Sanglard answer.constraints = kValidConstraintsHighEnd;
284*3f982cf4SFabien Sanglard EXPECT_EQ(kExpected, GetRecommendations(answer));
285*3f982cf4SFabien Sanglard }
286*3f982cf4SFabien Sanglard
287*3f982cf4SFabien Sanglard } // namespace capture_recommendations
288*3f982cf4SFabien Sanglard } // namespace cast
289*3f982cf4SFabien Sanglard } // namespace openscreen
290