xref: /aosp_15_r20/external/webrtc/media/base/video_adapter_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2010 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 
11 #include "media/base/video_adapter.h"
12 
13 #include <limits>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 
18 #include "api/video/resolution.h"
19 #include "api/video/video_frame.h"
20 #include "api/video/video_source_interface.h"
21 #include "media/base/fake_frame_source.h"
22 #include "rtc_base/arraysize.h"
23 #include "rtc_base/time_utils.h"
24 #include "test/field_trial.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27 
28 namespace cricket {
29 namespace {
30 const int kWidth = 1280;
31 const int kHeight = 720;
32 const int kDefaultFps = 30;
33 
34 using ::testing::_;
35 using ::testing::Eq;
36 using ::testing::Pair;
37 using webrtc::Resolution;
38 
BuildSinkWants(absl::optional<int> target_pixel_count,int max_pixel_count,int max_framerate_fps,int sink_alignment=1)39 rtc::VideoSinkWants BuildSinkWants(absl::optional<int> target_pixel_count,
40                                    int max_pixel_count,
41                                    int max_framerate_fps,
42                                    int sink_alignment = 1) {
43   rtc::VideoSinkWants wants;
44   wants.target_pixel_count = target_pixel_count;
45   wants.max_pixel_count = max_pixel_count;
46   wants.max_framerate_fps = max_framerate_fps;
47   wants.resolution_alignment = sink_alignment;
48   wants.is_active = true;
49   wants.aggregates.emplace(rtc::VideoSinkWants::Aggregates());
50   wants.aggregates->any_active_without_requested_resolution = false;
51   return wants;
52 }
53 
BuildSinkWants(absl::optional<webrtc::Resolution> requested_resolution,bool any_active_without_requested_resolution)54 rtc::VideoSinkWants BuildSinkWants(
55     absl::optional<webrtc::Resolution> requested_resolution,
56     bool any_active_without_requested_resolution) {
57   rtc::VideoSinkWants wants;
58   wants.max_framerate_fps = kDefaultFps;
59   wants.resolution_alignment = 1;
60   wants.is_active = true;
61   if (requested_resolution) {
62     wants.target_pixel_count = requested_resolution->PixelCount();
63     wants.max_pixel_count = requested_resolution->PixelCount();
64     wants.requested_resolution.emplace(rtc::VideoSinkWants::FrameSize(
65         requested_resolution->width, requested_resolution->height));
66   } else {
67     wants.target_pixel_count = kWidth * kHeight;
68     wants.max_pixel_count = kWidth * kHeight;
69   }
70   wants.aggregates.emplace(rtc::VideoSinkWants::Aggregates());
71   wants.aggregates->any_active_without_requested_resolution =
72       any_active_without_requested_resolution;
73   return wants;
74 }
75 
76 }  // namespace
77 
78 class VideoAdapterTest : public ::testing::Test,
79                          public ::testing::WithParamInterface<bool> {
80  public:
VideoAdapterTest()81   VideoAdapterTest() : VideoAdapterTest("", 1) {}
VideoAdapterTest(const std::string & field_trials,int source_resolution_alignment)82   explicit VideoAdapterTest(const std::string& field_trials,
83                             int source_resolution_alignment)
84       : override_field_trials_(field_trials),
85         frame_source_(std::make_unique<FakeFrameSource>(
86             kWidth,
87             kHeight,
88             VideoFormat::FpsToInterval(kDefaultFps) /
89                 rtc::kNumNanosecsPerMicrosec)),
90         adapter_(source_resolution_alignment),
91         adapter_wrapper_(std::make_unique<VideoAdapterWrapper>(&adapter_)),
92         use_new_format_request_(GetParam()) {}
93 
94  protected:
95   // Wrap a VideoAdapter and collect stats.
96   class VideoAdapterWrapper {
97    public:
98     struct Stats {
99       int captured_frames = 0;
100       int dropped_frames = 0;
101       bool last_adapt_was_no_op = false;
102 
103       int cropped_width = 0;
104       int cropped_height = 0;
105       int out_width = 0;
106       int out_height = 0;
107     };
108 
VideoAdapterWrapper(VideoAdapter * adapter)109     explicit VideoAdapterWrapper(VideoAdapter* adapter)
110         : video_adapter_(adapter) {}
111 
AdaptFrame(const webrtc::VideoFrame & frame)112     void AdaptFrame(const webrtc::VideoFrame& frame) {
113       const int in_width = frame.width();
114       const int in_height = frame.height();
115       int cropped_width;
116       int cropped_height;
117       int out_width;
118       int out_height;
119       if (video_adapter_->AdaptFrameResolution(
120               in_width, in_height,
121               frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec,
122               &cropped_width, &cropped_height, &out_width, &out_height)) {
123         stats_.cropped_width = cropped_width;
124         stats_.cropped_height = cropped_height;
125         stats_.out_width = out_width;
126         stats_.out_height = out_height;
127         stats_.last_adapt_was_no_op =
128             (in_width == cropped_width && in_height == cropped_height &&
129              in_width == out_width && in_height == out_height);
130       } else {
131         ++stats_.dropped_frames;
132       }
133       ++stats_.captured_frames;
134     }
135 
GetStats() const136     Stats GetStats() const { return stats_; }
137 
138    private:
139     VideoAdapter* video_adapter_;
140     Stats stats_;
141   };
142 
VerifyAdaptedResolution(const VideoAdapterWrapper::Stats & stats,int cropped_width,int cropped_height,int out_width,int out_height)143   void VerifyAdaptedResolution(const VideoAdapterWrapper::Stats& stats,
144                                int cropped_width,
145                                int cropped_height,
146                                int out_width,
147                                int out_height) {
148     EXPECT_EQ(cropped_width, stats.cropped_width);
149     EXPECT_EQ(cropped_height, stats.cropped_height);
150     EXPECT_EQ(out_width, stats.out_width);
151     EXPECT_EQ(out_height, stats.out_height);
152   }
153 
OnOutputFormatRequest(int width,int height,const absl::optional<int> & fps)154   void OnOutputFormatRequest(int width,
155                              int height,
156                              const absl::optional<int>& fps) {
157     if (use_new_format_request_) {
158       absl::optional<std::pair<int, int>> target_aspect_ratio =
159           std::make_pair(width, height);
160       absl::optional<int> max_pixel_count = width * height;
161       absl::optional<int> max_fps = fps;
162       adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
163                                      max_fps);
164       return;
165     }
166     adapter_.OnOutputFormatRequest(
167         VideoFormat(width, height, fps ? VideoFormat::FpsToInterval(*fps) : 0,
168                     cricket::FOURCC_I420));
169   }
170 
171   // Return pair of <out resolution, cropping>
AdaptFrameResolution(webrtc::Resolution res)172   std::pair<webrtc::Resolution, webrtc::Resolution> AdaptFrameResolution(
173       webrtc::Resolution res) {
174     webrtc::Resolution out;
175     webrtc::Resolution cropped;
176     timestamp_ns_ += 1000000000;
177     EXPECT_TRUE(adapter_.AdaptFrameResolution(
178         res.width, res.height, timestamp_ns_, &cropped.width, &cropped.height,
179         &out.width, &out.height));
180     return std::make_pair(out, cropped);
181   }
182 
183   webrtc::test::ScopedFieldTrials override_field_trials_;
184   const std::unique_ptr<FakeFrameSource> frame_source_;
185   VideoAdapter adapter_;
186   int64_t timestamp_ns_ = 0;
187   int cropped_width_;
188   int cropped_height_;
189   int out_width_;
190   int out_height_;
191   const std::unique_ptr<VideoAdapterWrapper> adapter_wrapper_;
192   const bool use_new_format_request_;
193 };
194 
195 INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
196                          VideoAdapterTest,
197                          ::testing::Values(true, false));
198 
199 // Do not adapt the frame rate or the resolution. Expect no frame drop, no
200 // cropping, and no resolution change.
TEST_P(VideoAdapterTest,AdaptNothing)201 TEST_P(VideoAdapterTest, AdaptNothing) {
202   for (int i = 0; i < 10; ++i)
203     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
204 
205   // Verify no frame drop and no resolution change.
206   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
207   EXPECT_GE(stats.captured_frames, 10);
208   EXPECT_EQ(0, stats.dropped_frames);
209   VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
210   EXPECT_TRUE(stats.last_adapt_was_no_op);
211 }
212 
TEST_P(VideoAdapterTest,AdaptZeroInterval)213 TEST_P(VideoAdapterTest, AdaptZeroInterval) {
214   OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
215   for (int i = 0; i < 40; ++i)
216     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
217 
218   // Verify no crash and that frames aren't dropped.
219   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
220   EXPECT_GE(stats.captured_frames, 40);
221   EXPECT_EQ(0, stats.dropped_frames);
222   VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
223 }
224 
225 // Adapt the frame rate to be half of the capture rate at the beginning. Expect
226 // the number of dropped frames to be half of the number the captured frames.
TEST_P(VideoAdapterTest,AdaptFramerateToHalf)227 TEST_P(VideoAdapterTest, AdaptFramerateToHalf) {
228   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
229 
230   // Capture 10 frames and verify that every other frame is dropped. The first
231   // frame should not be dropped.
232   for (int i = 0; i < 10; ++i)
233     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
234   EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
235   EXPECT_EQ(5, adapter_wrapper_->GetStats().dropped_frames);
236 }
237 
238 // Adapt the frame rate to be two thirds of the capture rate at the beginning.
239 // Expect the number of dropped frames to be one thirds of the number the
240 // captured frames.
TEST_P(VideoAdapterTest,AdaptFramerateToTwoThirds)241 TEST_P(VideoAdapterTest, AdaptFramerateToTwoThirds) {
242   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2 / 3);
243 
244   // Capture 10 frames and verify that every third frame is dropped. The first
245   // frame should not be dropped.
246   for (int i = 0; i < 10; ++i)
247     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
248   EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
249   EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
250 }
251 
252 // Request frame rate twice as high as captured frame rate. Expect no frame
253 // drop.
TEST_P(VideoAdapterTest,AdaptFramerateHighLimit)254 TEST_P(VideoAdapterTest, AdaptFramerateHighLimit) {
255   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps * 2);
256 
257   for (int i = 0; i < 10; ++i)
258     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
259 
260   // Verify no frame drop.
261   EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
262 }
263 
264 // Adapt the frame rate to be half of the capture rate. No resolution limit set.
265 // Expect the number of dropped frames to be half of the number the captured
266 // frames.
TEST_P(VideoAdapterTest,AdaptFramerateToHalfWithNoPixelLimit)267 TEST_P(VideoAdapterTest, AdaptFramerateToHalfWithNoPixelLimit) {
268   adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, kDefaultFps / 2);
269 
270   // Capture 10 frames and verify that every other frame is dropped. The first
271   // frame should not be dropped.
272   int expected_dropped_frames = 0;
273   for (int i = 0; i < 10; ++i) {
274     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
275     EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, i + 1);
276     if (i % 2 == 1)
277       ++expected_dropped_frames;
278     EXPECT_EQ(expected_dropped_frames,
279               adapter_wrapper_->GetStats().dropped_frames);
280     VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
281                             kWidth, kHeight);
282   }
283 }
284 
285 // Adapt the frame rate to be half of the capture rate after capturing no less
286 // than 10 frames. Expect no frame dropped before adaptation and frame dropped
287 // after adaptation.
TEST_P(VideoAdapterTest,AdaptFramerateOntheFly)288 TEST_P(VideoAdapterTest, AdaptFramerateOntheFly) {
289   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
290   for (int i = 0; i < 10; ++i)
291     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
292 
293   // Verify no frame drop before adaptation.
294   EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
295 
296   // Adapt the frame rate.
297   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
298   for (int i = 0; i < 20; ++i)
299     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
300 
301   // Verify frame drop after adaptation.
302   EXPECT_GT(adapter_wrapper_->GetStats().dropped_frames, 0);
303 }
304 
305 // Do not adapt the frame rate or the resolution. Expect no frame drop, no
306 // cropping, and no resolution change.
TEST_P(VideoAdapterTest,AdaptFramerateRequestMax)307 TEST_P(VideoAdapterTest, AdaptFramerateRequestMax) {
308   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
309                                       std::numeric_limits<int>::max(),
310                                       std::numeric_limits<int>::max()));
311 
312   for (int i = 0; i < 10; ++i)
313     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
314 
315   // Verify no frame drop and no resolution change.
316   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
317   EXPECT_GE(stats.captured_frames, 10);
318   EXPECT_EQ(0, stats.dropped_frames);
319   VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
320   EXPECT_TRUE(stats.last_adapt_was_no_op);
321 }
322 
TEST_P(VideoAdapterTest,AdaptFramerateRequestZero)323 TEST_P(VideoAdapterTest, AdaptFramerateRequestZero) {
324   adapter_.OnSinkWants(
325       BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(), 0));
326   for (int i = 0; i < 10; ++i)
327     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
328 
329   // Verify no crash and that frames aren't dropped.
330   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
331   EXPECT_GE(stats.captured_frames, 10);
332   EXPECT_EQ(10, stats.dropped_frames);
333 }
334 
335 // Adapt the frame rate to be half of the capture rate at the beginning. Expect
336 // the number of dropped frames to be half of the number the captured frames.
TEST_P(VideoAdapterTest,AdaptFramerateRequestHalf)337 TEST_P(VideoAdapterTest, AdaptFramerateRequestHalf) {
338   adapter_.OnSinkWants(BuildSinkWants(
339       absl::nullopt, std::numeric_limits<int>::max(), kDefaultFps / 2));
340   for (int i = 0; i < 10; ++i)
341     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
342 
343   // Verify no crash and that frames aren't dropped.
344   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
345   EXPECT_GE(stats.captured_frames, 10);
346   EXPECT_EQ(5, stats.dropped_frames);
347   VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth, kHeight);
348 }
349 
350 // Set a very high output pixel resolution. Expect no cropping or resolution
351 // change.
TEST_P(VideoAdapterTest,AdaptFrameResolutionHighLimit)352 TEST_P(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
353   OnOutputFormatRequest(kWidth * 10, kHeight * 10, kDefaultFps);
354   EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
355                                             &cropped_height_, &out_width_,
356                                             &out_height_));
357   EXPECT_EQ(kWidth, cropped_width_);
358   EXPECT_EQ(kHeight, cropped_height_);
359   EXPECT_EQ(kWidth, out_width_);
360   EXPECT_EQ(kHeight, out_height_);
361 }
362 
363 // Adapt the frame resolution to be the same as capture resolution. Expect no
364 // cropping or resolution change.
TEST_P(VideoAdapterTest,AdaptFrameResolutionIdentical)365 TEST_P(VideoAdapterTest, AdaptFrameResolutionIdentical) {
366   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
367   EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
368                                             &cropped_height_, &out_width_,
369                                             &out_height_));
370   EXPECT_EQ(kWidth, cropped_width_);
371   EXPECT_EQ(kHeight, cropped_height_);
372   EXPECT_EQ(kWidth, out_width_);
373   EXPECT_EQ(kHeight, out_height_);
374 }
375 
376 // Adapt the frame resolution to be a quarter of the capture resolution. Expect
377 // no cropping, but a resolution change.
TEST_P(VideoAdapterTest,AdaptFrameResolutionQuarter)378 TEST_P(VideoAdapterTest, AdaptFrameResolutionQuarter) {
379   OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
380   EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0, &cropped_width_,
381                                             &cropped_height_, &out_width_,
382                                             &out_height_));
383   EXPECT_EQ(kWidth, cropped_width_);
384   EXPECT_EQ(kHeight, cropped_height_);
385   EXPECT_EQ(kWidth / 2, out_width_);
386   EXPECT_EQ(kHeight / 2, out_height_);
387 }
388 
389 // Adapt the pixel resolution to 0. Expect frame drop.
TEST_P(VideoAdapterTest,AdaptFrameResolutionDrop)390 TEST_P(VideoAdapterTest, AdaptFrameResolutionDrop) {
391   OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
392   EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
393                                              &cropped_width_, &cropped_height_,
394                                              &out_width_, &out_height_));
395 }
396 
397 // Adapt the frame resolution to be a quarter of the capture resolution at the
398 // beginning. Expect no cropping but a resolution change.
TEST_P(VideoAdapterTest,AdaptResolution)399 TEST_P(VideoAdapterTest, AdaptResolution) {
400   OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
401   for (int i = 0; i < 10; ++i)
402     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
403 
404   // Verify no frame drop, no cropping, and resolution change.
405   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
406   EXPECT_EQ(0, stats.dropped_frames);
407   VerifyAdaptedResolution(stats, kWidth, kHeight, kWidth / 2, kHeight / 2);
408 }
409 
410 // Adapt the frame resolution to be a quarter of the capture resolution after
411 // capturing no less than 10 frames. Expect no resolution change before
412 // adaptation and resolution change after adaptation.
TEST_P(VideoAdapterTest,AdaptResolutionOnTheFly)413 TEST_P(VideoAdapterTest, AdaptResolutionOnTheFly) {
414   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps);
415   for (int i = 0; i < 10; ++i)
416     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
417 
418   // Verify no resolution change before adaptation.
419   VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight, kWidth,
420                           kHeight);
421 
422   // Adapt the frame resolution.
423   OnOutputFormatRequest(kWidth / 2, kHeight / 2, kDefaultFps);
424   for (int i = 0; i < 10; ++i)
425     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
426 
427   // Verify resolution change after adaptation.
428   VerifyAdaptedResolution(adapter_wrapper_->GetStats(), kWidth, kHeight,
429                           kWidth / 2, kHeight / 2);
430 }
431 
432 // Drop all frames for resolution 0x0.
TEST_P(VideoAdapterTest,DropAllFrames)433 TEST_P(VideoAdapterTest, DropAllFrames) {
434   OnOutputFormatRequest(kWidth * 0, kHeight * 0, kDefaultFps);
435   for (int i = 0; i < 10; ++i)
436     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
437 
438   // Verify all frames are dropped.
439   VideoAdapterWrapper::Stats stats = adapter_wrapper_->GetStats();
440   EXPECT_GE(stats.captured_frames, 10);
441   EXPECT_EQ(stats.captured_frames, stats.dropped_frames);
442 }
443 
TEST_P(VideoAdapterTest,TestOnOutputFormatRequest)444 TEST_P(VideoAdapterTest, TestOnOutputFormatRequest) {
445   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
446                                             &cropped_height_, &out_width_,
447                                             &out_height_));
448   EXPECT_EQ(640, cropped_width_);
449   EXPECT_EQ(400, cropped_height_);
450   EXPECT_EQ(640, out_width_);
451   EXPECT_EQ(400, out_height_);
452 
453   // Format request 640x400.
454   OnOutputFormatRequest(640, 400, absl::nullopt);
455   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
456                                             &cropped_height_, &out_width_,
457                                             &out_height_));
458   EXPECT_EQ(640, cropped_width_);
459   EXPECT_EQ(400, cropped_height_);
460   EXPECT_EQ(640, out_width_);
461   EXPECT_EQ(400, out_height_);
462 
463   // Request 1280x720, higher than input, but aspect 16:9. Expect cropping but
464   // no scaling.
465   OnOutputFormatRequest(1280, 720, absl::nullopt);
466   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
467                                             &cropped_height_, &out_width_,
468                                             &out_height_));
469   EXPECT_EQ(640, cropped_width_);
470   EXPECT_EQ(360, cropped_height_);
471   EXPECT_EQ(640, out_width_);
472   EXPECT_EQ(360, out_height_);
473 
474   // Request 0x0.
475   OnOutputFormatRequest(0, 0, absl::nullopt);
476   EXPECT_FALSE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
477                                              &cropped_height_, &out_width_,
478                                              &out_height_));
479 
480   // Request 320x200. Expect scaling, but no cropping.
481   OnOutputFormatRequest(320, 200, absl::nullopt);
482   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
483                                             &cropped_height_, &out_width_,
484                                             &out_height_));
485   EXPECT_EQ(640, cropped_width_);
486   EXPECT_EQ(400, cropped_height_);
487   EXPECT_EQ(320, out_width_);
488   EXPECT_EQ(200, out_height_);
489 
490   // Request resolution close to 2/3 scale. Expect adapt down. Scaling to 2/3
491   // is not optimized and not allowed, therefore 1/2 scaling will be used
492   // instead.
493   OnOutputFormatRequest(424, 265, absl::nullopt);
494   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
495                                             &cropped_height_, &out_width_,
496                                             &out_height_));
497   EXPECT_EQ(640, cropped_width_);
498   EXPECT_EQ(400, cropped_height_);
499   EXPECT_EQ(320, out_width_);
500   EXPECT_EQ(200, out_height_);
501 
502   // Request resolution of 3 / 8. Expect adapt down.
503   OnOutputFormatRequest(640 * 3 / 8, 400 * 3 / 8, absl::nullopt);
504   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
505                                             &cropped_height_, &out_width_,
506                                             &out_height_));
507   EXPECT_EQ(640, cropped_width_);
508   EXPECT_EQ(400, cropped_height_);
509   EXPECT_EQ(640 * 3 / 8, out_width_);
510   EXPECT_EQ(400 * 3 / 8, out_height_);
511 
512   // Switch back up. Expect adapt.
513   OnOutputFormatRequest(320, 200, absl::nullopt);
514   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
515                                             &cropped_height_, &out_width_,
516                                             &out_height_));
517   EXPECT_EQ(640, cropped_width_);
518   EXPECT_EQ(400, cropped_height_);
519   EXPECT_EQ(320, out_width_);
520   EXPECT_EQ(200, out_height_);
521 
522   // Format request 480x300.
523   OnOutputFormatRequest(480, 300, absl::nullopt);
524   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
525                                             &cropped_height_, &out_width_,
526                                             &out_height_));
527   EXPECT_EQ(640, cropped_width_);
528   EXPECT_EQ(400, cropped_height_);
529   EXPECT_EQ(480, out_width_);
530   EXPECT_EQ(300, out_height_);
531 }
532 
TEST_P(VideoAdapterTest,TestViewRequestPlusCameraSwitch)533 TEST_P(VideoAdapterTest, TestViewRequestPlusCameraSwitch) {
534   // Start at HD.
535   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
536                                             &cropped_height_, &out_width_,
537                                             &out_height_));
538   EXPECT_EQ(1280, cropped_width_);
539   EXPECT_EQ(720, cropped_height_);
540   EXPECT_EQ(1280, out_width_);
541   EXPECT_EQ(720, out_height_);
542 
543   // Format request for VGA.
544   OnOutputFormatRequest(640, 360, absl::nullopt);
545   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
546                                             &cropped_height_, &out_width_,
547                                             &out_height_));
548   EXPECT_EQ(1280, cropped_width_);
549   EXPECT_EQ(720, cropped_height_);
550   EXPECT_EQ(640, out_width_);
551   EXPECT_EQ(360, out_height_);
552 
553   // Now, the camera reopens at VGA.
554   // Both the frame and the output format should be 640x360.
555   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
556                                             &cropped_height_, &out_width_,
557                                             &out_height_));
558   EXPECT_EQ(640, cropped_width_);
559   EXPECT_EQ(360, cropped_height_);
560   EXPECT_EQ(640, out_width_);
561   EXPECT_EQ(360, out_height_);
562 
563   // And another view request comes in for 640x360, which should have no
564   // real impact.
565   OnOutputFormatRequest(640, 360, absl::nullopt);
566   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
567                                             &cropped_height_, &out_width_,
568                                             &out_height_));
569   EXPECT_EQ(640, cropped_width_);
570   EXPECT_EQ(360, cropped_height_);
571   EXPECT_EQ(640, out_width_);
572   EXPECT_EQ(360, out_height_);
573 }
574 
TEST_P(VideoAdapterTest,TestVgaWidth)575 TEST_P(VideoAdapterTest, TestVgaWidth) {
576   // Requested output format is 640x360.
577   OnOutputFormatRequest(640, 360, absl::nullopt);
578 
579   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
580                                             &cropped_height_, &out_width_,
581                                             &out_height_));
582   // Expect cropping.
583   EXPECT_EQ(640, cropped_width_);
584   EXPECT_EQ(360, cropped_height_);
585   EXPECT_EQ(640, out_width_);
586   EXPECT_EQ(360, out_height_);
587 
588   // But if frames come in at 640x360, we shouldn't adapt them down.
589   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
590                                             &cropped_height_, &out_width_,
591                                             &out_height_));
592   EXPECT_EQ(640, cropped_width_);
593   EXPECT_EQ(360, cropped_height_);
594   EXPECT_EQ(640, out_width_);
595   EXPECT_EQ(360, out_height_);
596 
597   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
598                                             &cropped_height_, &out_width_,
599                                             &out_height_));
600   EXPECT_EQ(640, cropped_width_);
601   EXPECT_EQ(360, cropped_height_);
602   EXPECT_EQ(640, out_width_);
603   EXPECT_EQ(360, out_height_);
604 }
605 
TEST_P(VideoAdapterTest,TestOnResolutionRequestInSmallSteps)606 TEST_P(VideoAdapterTest, TestOnResolutionRequestInSmallSteps) {
607   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
608                                             &cropped_height_, &out_width_,
609                                             &out_height_));
610   EXPECT_EQ(1280, cropped_width_);
611   EXPECT_EQ(720, cropped_height_);
612   EXPECT_EQ(1280, out_width_);
613   EXPECT_EQ(720, out_height_);
614 
615   // Adapt down one step.
616   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 1280 * 720 - 1,
617                                       std::numeric_limits<int>::max()));
618   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
619                                             &cropped_height_, &out_width_,
620                                             &out_height_));
621   EXPECT_EQ(1280, cropped_width_);
622   EXPECT_EQ(720, cropped_height_);
623   EXPECT_EQ(960, out_width_);
624   EXPECT_EQ(540, out_height_);
625 
626   // Adapt down one step more.
627   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 540 - 1,
628                                       std::numeric_limits<int>::max()));
629   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
630                                             &cropped_height_, &out_width_,
631                                             &out_height_));
632   EXPECT_EQ(1280, cropped_width_);
633   EXPECT_EQ(720, cropped_height_);
634   EXPECT_EQ(640, out_width_);
635   EXPECT_EQ(360, out_height_);
636 
637   // Adapt down one step more.
638   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
639                                       std::numeric_limits<int>::max()));
640   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
641                                             &cropped_height_, &out_width_,
642                                             &out_height_));
643   EXPECT_EQ(1280, cropped_width_);
644   EXPECT_EQ(720, cropped_height_);
645   EXPECT_EQ(480, out_width_);
646   EXPECT_EQ(270, out_height_);
647 
648   // Adapt up one step.
649   adapter_.OnSinkWants(
650       BuildSinkWants(640 * 360, 960 * 540, std::numeric_limits<int>::max()));
651   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
652                                             &cropped_height_, &out_width_,
653                                             &out_height_));
654   EXPECT_EQ(1280, cropped_width_);
655   EXPECT_EQ(720, cropped_height_);
656   EXPECT_EQ(640, out_width_);
657   EXPECT_EQ(360, out_height_);
658 
659   // Adapt up one step more.
660   adapter_.OnSinkWants(
661       BuildSinkWants(960 * 540, 1280 * 720, std::numeric_limits<int>::max()));
662   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
663                                             &cropped_height_, &out_width_,
664                                             &out_height_));
665   EXPECT_EQ(1280, cropped_width_);
666   EXPECT_EQ(720, cropped_height_);
667   EXPECT_EQ(960, out_width_);
668   EXPECT_EQ(540, out_height_);
669 
670   // Adapt up one step more.
671   adapter_.OnSinkWants(
672       BuildSinkWants(1280 * 720, 1920 * 1080, std::numeric_limits<int>::max()));
673   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
674                                             &cropped_height_, &out_width_,
675                                             &out_height_));
676   EXPECT_EQ(1280, cropped_width_);
677   EXPECT_EQ(720, cropped_height_);
678   EXPECT_EQ(1280, out_width_);
679   EXPECT_EQ(720, out_height_);
680 }
681 
TEST_P(VideoAdapterTest,TestOnResolutionRequestMaxZero)682 TEST_P(VideoAdapterTest, TestOnResolutionRequestMaxZero) {
683   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
684                                             &cropped_height_, &out_width_,
685                                             &out_height_));
686   EXPECT_EQ(1280, cropped_width_);
687   EXPECT_EQ(720, cropped_height_);
688   EXPECT_EQ(1280, out_width_);
689   EXPECT_EQ(720, out_height_);
690 
691   adapter_.OnSinkWants(
692       BuildSinkWants(absl::nullopt, 0, std::numeric_limits<int>::max()));
693   EXPECT_FALSE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
694                                              &cropped_height_, &out_width_,
695                                              &out_height_));
696 }
697 
TEST_P(VideoAdapterTest,TestOnResolutionRequestInLargeSteps)698 TEST_P(VideoAdapterTest, TestOnResolutionRequestInLargeSteps) {
699   // Large step down.
700   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
701                                       std::numeric_limits<int>::max()));
702   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
703                                             &cropped_height_, &out_width_,
704                                             &out_height_));
705   EXPECT_EQ(1280, cropped_width_);
706   EXPECT_EQ(720, cropped_height_);
707   EXPECT_EQ(480, out_width_);
708   EXPECT_EQ(270, out_height_);
709 
710   // Large step up.
711   adapter_.OnSinkWants(
712       BuildSinkWants(1280 * 720, 1920 * 1080, std::numeric_limits<int>::max()));
713   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
714                                             &cropped_height_, &out_width_,
715                                             &out_height_));
716   EXPECT_EQ(1280, cropped_width_);
717   EXPECT_EQ(720, cropped_height_);
718   EXPECT_EQ(1280, out_width_);
719   EXPECT_EQ(720, out_height_);
720 }
721 
TEST_P(VideoAdapterTest,TestOnOutputFormatRequestCapsMaxResolution)722 TEST_P(VideoAdapterTest, TestOnOutputFormatRequestCapsMaxResolution) {
723   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
724                                       std::numeric_limits<int>::max()));
725   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
726                                             &cropped_height_, &out_width_,
727                                             &out_height_));
728   EXPECT_EQ(1280, cropped_width_);
729   EXPECT_EQ(720, cropped_height_);
730   EXPECT_EQ(480, out_width_);
731   EXPECT_EQ(270, out_height_);
732 
733   OnOutputFormatRequest(640, 360, absl::nullopt);
734   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
735                                             &cropped_height_, &out_width_,
736                                             &out_height_));
737   EXPECT_EQ(1280, cropped_width_);
738   EXPECT_EQ(720, cropped_height_);
739   EXPECT_EQ(480, out_width_);
740   EXPECT_EQ(270, out_height_);
741 
742   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 960 * 720,
743                                       std::numeric_limits<int>::max()));
744   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
745                                             &cropped_height_, &out_width_,
746                                             &out_height_));
747   EXPECT_EQ(1280, cropped_width_);
748   EXPECT_EQ(720, cropped_height_);
749   EXPECT_EQ(640, out_width_);
750   EXPECT_EQ(360, out_height_);
751 }
752 
TEST_P(VideoAdapterTest,TestOnResolutionRequestReset)753 TEST_P(VideoAdapterTest, TestOnResolutionRequestReset) {
754   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
755                                             &cropped_height_, &out_width_,
756                                             &out_height_));
757   EXPECT_EQ(1280, cropped_width_);
758   EXPECT_EQ(720, cropped_height_);
759   EXPECT_EQ(1280, out_width_);
760   EXPECT_EQ(720, out_height_);
761 
762   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
763                                       std::numeric_limits<int>::max()));
764   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
765                                             &cropped_height_, &out_width_,
766                                             &out_height_));
767   EXPECT_EQ(1280, cropped_width_);
768   EXPECT_EQ(720, cropped_height_);
769   EXPECT_EQ(480, out_width_);
770   EXPECT_EQ(270, out_height_);
771 
772   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
773                                       std::numeric_limits<int>::max(),
774                                       std::numeric_limits<int>::max()));
775   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
776                                             &cropped_height_, &out_width_,
777                                             &out_height_));
778   EXPECT_EQ(1280, cropped_width_);
779   EXPECT_EQ(720, cropped_height_);
780   EXPECT_EQ(1280, out_width_);
781   EXPECT_EQ(720, out_height_);
782 }
783 
TEST_P(VideoAdapterTest,TestOnOutputFormatRequestResolutionReset)784 TEST_P(VideoAdapterTest, TestOnOutputFormatRequestResolutionReset) {
785   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
786                                             &cropped_height_, &out_width_,
787                                             &out_height_));
788   EXPECT_EQ(1280, cropped_width_);
789   EXPECT_EQ(720, cropped_height_);
790   EXPECT_EQ(1280, out_width_);
791   EXPECT_EQ(720, out_height_);
792 
793   adapter_.OnOutputFormatRequest(absl::nullopt, 640 * 360 - 1, absl::nullopt);
794   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
795                                             &cropped_height_, &out_width_,
796                                             &out_height_));
797   EXPECT_EQ(1280, cropped_width_);
798   EXPECT_EQ(720, cropped_height_);
799   EXPECT_EQ(480, out_width_);
800   EXPECT_EQ(270, out_height_);
801 
802   adapter_.OnOutputFormatRequest(absl::nullopt, absl::nullopt, absl::nullopt);
803   EXPECT_TRUE(adapter_.AdaptFrameResolution(1280, 720, 0, &cropped_width_,
804                                             &cropped_height_, &out_width_,
805                                             &out_height_));
806   EXPECT_EQ(1280, cropped_width_);
807   EXPECT_EQ(720, cropped_height_);
808   EXPECT_EQ(1280, out_width_);
809   EXPECT_EQ(720, out_height_);
810 }
811 
TEST_P(VideoAdapterTest,TestOnOutputFormatRequestFpsReset)812 TEST_P(VideoAdapterTest, TestOnOutputFormatRequestFpsReset) {
813   OnOutputFormatRequest(kWidth, kHeight, kDefaultFps / 2);
814   for (int i = 0; i < 10; ++i)
815     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
816 
817   // Verify frame drop.
818   const int dropped_frames = adapter_wrapper_->GetStats().dropped_frames;
819   EXPECT_GT(dropped_frames, 0);
820 
821   // Reset frame rate.
822   OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);
823   for (int i = 0; i < 20; ++i)
824     adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
825 
826   // Verify no frame drop after reset.
827   EXPECT_EQ(dropped_frames, adapter_wrapper_->GetStats().dropped_frames);
828 }
829 
TEST_P(VideoAdapterTest,RequestAspectRatio)830 TEST_P(VideoAdapterTest, RequestAspectRatio) {
831   // Request aspect ratio 320/180 (16:9), smaller than input, but no resolution
832   // limit. Expect cropping but no scaling.
833   adapter_.OnOutputFormatRequest(std::make_pair(320, 180), absl::nullopt,
834                                  absl::nullopt);
835   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
836                                             &cropped_height_, &out_width_,
837                                             &out_height_));
838   EXPECT_EQ(640, cropped_width_);
839   EXPECT_EQ(360, cropped_height_);
840   EXPECT_EQ(640, out_width_);
841   EXPECT_EQ(360, out_height_);
842 }
843 
TEST_P(VideoAdapterTest,RequestAspectRatioWithDifferentOrientation)844 TEST_P(VideoAdapterTest, RequestAspectRatioWithDifferentOrientation) {
845   // Request 720x1280, higher than input, but aspect 16:9. Orientation should
846   // not matter, expect cropping but no scaling.
847   OnOutputFormatRequest(720, 1280, absl::nullopt);
848   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
849                                             &cropped_height_, &out_width_,
850                                             &out_height_));
851   EXPECT_EQ(640, cropped_width_);
852   EXPECT_EQ(360, cropped_height_);
853   EXPECT_EQ(640, out_width_);
854   EXPECT_EQ(360, out_height_);
855 }
856 
TEST_P(VideoAdapterTest,InvalidAspectRatioIgnored)857 TEST_P(VideoAdapterTest, InvalidAspectRatioIgnored) {
858   // Request aspect ratio 320/0. Expect no cropping.
859   adapter_.OnOutputFormatRequest(std::make_pair(320, 0), absl::nullopt,
860                                  absl::nullopt);
861   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 400, 0, &cropped_width_,
862                                             &cropped_height_, &out_width_,
863                                             &out_height_));
864   EXPECT_EQ(640, cropped_width_);
865   EXPECT_EQ(400, cropped_height_);
866   EXPECT_EQ(640, out_width_);
867   EXPECT_EQ(400, out_height_);
868 }
869 
TEST_P(VideoAdapterTest,TestCroppingWithResolutionRequest)870 TEST_P(VideoAdapterTest, TestCroppingWithResolutionRequest) {
871   // Ask for 640x360 (16:9 aspect).
872   OnOutputFormatRequest(640, 360, absl::nullopt);
873   // Send 640x480 (4:3 aspect).
874   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
875                                             &cropped_height_, &out_width_,
876                                             &out_height_));
877   // Expect cropping to 16:9 format and no scaling.
878   EXPECT_EQ(640, cropped_width_);
879   EXPECT_EQ(360, cropped_height_);
880   EXPECT_EQ(640, out_width_);
881   EXPECT_EQ(360, out_height_);
882 
883   // Adapt down one step.
884   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 360 - 1,
885                                       std::numeric_limits<int>::max()));
886   // Expect cropping to 16:9 format and 3/4 scaling.
887   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
888                                             &cropped_height_, &out_width_,
889                                             &out_height_));
890   EXPECT_EQ(640, cropped_width_);
891   EXPECT_EQ(360, cropped_height_);
892   EXPECT_EQ(480, out_width_);
893   EXPECT_EQ(270, out_height_);
894 
895   // Adapt down one step more.
896   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 480 * 270 - 1,
897                                       std::numeric_limits<int>::max()));
898   // Expect cropping to 16:9 format and 1/2 scaling.
899   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
900                                             &cropped_height_, &out_width_,
901                                             &out_height_));
902   EXPECT_EQ(640, cropped_width_);
903   EXPECT_EQ(360, cropped_height_);
904   EXPECT_EQ(320, out_width_);
905   EXPECT_EQ(180, out_height_);
906 
907   // Adapt up one step.
908   adapter_.OnSinkWants(
909       BuildSinkWants(480 * 270, 640 * 360, std::numeric_limits<int>::max()));
910   // Expect cropping to 16:9 format and 3/4 scaling.
911   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
912                                             &cropped_height_, &out_width_,
913                                             &out_height_));
914   EXPECT_EQ(640, cropped_width_);
915   EXPECT_EQ(360, cropped_height_);
916   EXPECT_EQ(480, out_width_);
917   EXPECT_EQ(270, out_height_);
918 
919   // Adapt up one step more.
920   adapter_.OnSinkWants(
921       BuildSinkWants(640 * 360, 960 * 540, std::numeric_limits<int>::max()));
922   // Expect cropping to 16:9 format and no scaling.
923   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
924                                             &cropped_height_, &out_width_,
925                                             &out_height_));
926   EXPECT_EQ(640, cropped_width_);
927   EXPECT_EQ(360, cropped_height_);
928   EXPECT_EQ(640, out_width_);
929   EXPECT_EQ(360, out_height_);
930 
931   // Try to adapt up one step more.
932   adapter_.OnSinkWants(
933       BuildSinkWants(960 * 540, 1280 * 720, std::numeric_limits<int>::max()));
934   // Expect cropping to 16:9 format and no scaling.
935   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
936                                             &cropped_height_, &out_width_,
937                                             &out_height_));
938   EXPECT_EQ(640, cropped_width_);
939   EXPECT_EQ(360, cropped_height_);
940   EXPECT_EQ(640, out_width_);
941   EXPECT_EQ(360, out_height_);
942 }
943 
TEST_P(VideoAdapterTest,TestCroppingOddResolution)944 TEST_P(VideoAdapterTest, TestCroppingOddResolution) {
945   // Ask for 640x360 (16:9 aspect), with 3/16 scaling.
946   OnOutputFormatRequest(640, 360, absl::nullopt);
947   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
948                                       640 * 360 * 3 / 16 * 3 / 16,
949                                       std::numeric_limits<int>::max()));
950 
951   // Send 640x480 (4:3 aspect).
952   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 480, 0, &cropped_width_,
953                                             &cropped_height_, &out_width_,
954                                             &out_height_));
955 
956   // Instead of getting the exact aspect ratio with cropped resolution 640x360,
957   // the resolution should be adjusted to get a perfect scale factor instead.
958   EXPECT_EQ(640, cropped_width_);
959   EXPECT_EQ(368, cropped_height_);
960   EXPECT_EQ(120, out_width_);
961   EXPECT_EQ(69, out_height_);
962 }
963 
TEST_P(VideoAdapterTest,TestAdaptToVerySmallResolution)964 TEST_P(VideoAdapterTest, TestAdaptToVerySmallResolution) {
965   // Ask for 1920x1080 (16:9 aspect), with 1/16 scaling.
966   const int w = 1920;
967   const int h = 1080;
968   OnOutputFormatRequest(w, h, absl::nullopt);
969   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, w * h * 1 / 16 * 1 / 16,
970                                       std::numeric_limits<int>::max()));
971 
972   // Send 1920x1080 (16:9 aspect).
973   EXPECT_TRUE(adapter_.AdaptFrameResolution(
974       w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
975 
976   // Instead of getting the exact aspect ratio with cropped resolution 1920x1080
977   // the resolution should be adjusted to get a perfect scale factor instead.
978   EXPECT_EQ(1920, cropped_width_);
979   EXPECT_EQ(1072, cropped_height_);
980   EXPECT_EQ(120, out_width_);
981   EXPECT_EQ(67, out_height_);
982 
983   // Adapt back up one step to 3/32.
984   adapter_.OnSinkWants(BuildSinkWants(w * h * 3 / 32 * 3 / 32,
985                                       w * h * 1 / 8 * 1 / 8,
986                                       std::numeric_limits<int>::max()));
987 
988   // Send 1920x1080 (16:9 aspect).
989   EXPECT_TRUE(adapter_.AdaptFrameResolution(
990       w, h, 0, &cropped_width_, &cropped_height_, &out_width_, &out_height_));
991 
992   EXPECT_EQ(160, out_width_);
993   EXPECT_EQ(90, out_height_);
994 }
995 
TEST_P(VideoAdapterTest,AdaptFrameResolutionDropWithResolutionRequest)996 TEST_P(VideoAdapterTest, AdaptFrameResolutionDropWithResolutionRequest) {
997   OnOutputFormatRequest(0, 0, kDefaultFps);
998   EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
999                                              &cropped_width_, &cropped_height_,
1000                                              &out_width_, &out_height_));
1001 
1002   adapter_.OnSinkWants(BuildSinkWants(960 * 540,
1003                                       std::numeric_limits<int>::max(),
1004                                       std::numeric_limits<int>::max()));
1005 
1006   // Still expect all frames to be dropped
1007   EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1008                                              &cropped_width_, &cropped_height_,
1009                                              &out_width_, &out_height_));
1010 
1011   adapter_.OnSinkWants(BuildSinkWants(absl::nullopt, 640 * 480 - 1,
1012                                       std::numeric_limits<int>::max()));
1013 
1014   // Still expect all frames to be dropped
1015   EXPECT_FALSE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1016                                              &cropped_width_, &cropped_height_,
1017                                              &out_width_, &out_height_));
1018 }
1019 
1020 // Test that we will adapt to max given a target pixel count close to max.
TEST_P(VideoAdapterTest,TestAdaptToMax)1021 TEST_P(VideoAdapterTest, TestAdaptToMax) {
1022   OnOutputFormatRequest(640, 360, kDefaultFps);
1023   adapter_.OnSinkWants(BuildSinkWants(640 * 360 - 1 /* target */,
1024                                       std::numeric_limits<int>::max(),
1025                                       std::numeric_limits<int>::max()));
1026 
1027   EXPECT_TRUE(adapter_.AdaptFrameResolution(640, 360, 0, &cropped_width_,
1028                                             &cropped_height_, &out_width_,
1029                                             &out_height_));
1030   EXPECT_EQ(640, out_width_);
1031   EXPECT_EQ(360, out_height_);
1032 }
1033 
1034 // Test adjusting to 16:9 in landscape, and 9:16 in portrait.
TEST(VideoAdapterTestMultipleOrientation,TestNormal)1035 TEST(VideoAdapterTestMultipleOrientation, TestNormal) {
1036   VideoAdapter video_adapter;
1037   video_adapter.OnOutputFormatRequest(std::make_pair(640, 360), 640 * 360,
1038                                       std::make_pair(360, 640), 360 * 640, 30);
1039 
1040   int cropped_width;
1041   int cropped_height;
1042   int out_width;
1043   int out_height;
1044   EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1045       /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1046       &cropped_width, &cropped_height, &out_width, &out_height));
1047   EXPECT_EQ(640, cropped_width);
1048   EXPECT_EQ(360, cropped_height);
1049   EXPECT_EQ(640, out_width);
1050   EXPECT_EQ(360, out_height);
1051 
1052   EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1053       /* in_width= */ 480, /* in_height= */ 640,
1054       /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1055       &cropped_height, &out_width, &out_height));
1056   EXPECT_EQ(360, cropped_width);
1057   EXPECT_EQ(640, cropped_height);
1058   EXPECT_EQ(360, out_width);
1059   EXPECT_EQ(640, out_height);
1060 }
1061 
1062 // Force output to be 9:16, even for landscape input.
TEST(VideoAdapterTestMultipleOrientation,TestForcePortrait)1063 TEST(VideoAdapterTestMultipleOrientation, TestForcePortrait) {
1064   VideoAdapter video_adapter;
1065   video_adapter.OnOutputFormatRequest(std::make_pair(360, 640), 640 * 360,
1066                                       std::make_pair(360, 640), 360 * 640, 30);
1067 
1068   int cropped_width;
1069   int cropped_height;
1070   int out_width;
1071   int out_height;
1072   EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1073       /* in_width= */ 640, /* in_height= */ 480, /* in_timestamp_ns= */ 0,
1074       &cropped_width, &cropped_height, &out_width, &out_height));
1075   EXPECT_EQ(270, cropped_width);
1076   EXPECT_EQ(480, cropped_height);
1077   EXPECT_EQ(270, out_width);
1078   EXPECT_EQ(480, out_height);
1079 
1080   EXPECT_TRUE(video_adapter.AdaptFrameResolution(
1081       /* in_width= */ 480, /* in_height= */ 640,
1082       /* in_timestamp_ns= */ rtc::kNumNanosecsPerSec / 30, &cropped_width,
1083       &cropped_height, &out_width, &out_height));
1084   EXPECT_EQ(360, cropped_width);
1085   EXPECT_EQ(640, cropped_height);
1086   EXPECT_EQ(360, out_width);
1087   EXPECT_EQ(640, out_height);
1088 }
1089 
TEST_P(VideoAdapterTest,AdaptResolutionInStepsFirst3_4)1090 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst3_4) {
1091   const int kWidth = 1280;
1092   const int kHeight = 720;
1093   OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 16:9 aspect.
1094 
1095   // Scale factors: 3/4, 2/3, 3/4, 2/3, ...
1096   // Scale        : 3/4, 1/2, 3/8, 1/4, 3/16, 1/8.
1097   const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160};
1098   const int kExpectedHeights[] = {540, 360, 270, 180, 135, 90};
1099 
1100   int request_width = kWidth;
1101   int request_height = kHeight;
1102 
1103   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1104     // Adapt down one step.
1105     adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1106                                         request_width * request_height - 1,
1107                                         std::numeric_limits<int>::max()));
1108     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1109                                               &cropped_width_, &cropped_height_,
1110                                               &out_width_, &out_height_));
1111     EXPECT_EQ(kExpectedWidths[i], out_width_);
1112     EXPECT_EQ(kExpectedHeights[i], out_height_);
1113     request_width = out_width_;
1114     request_height = out_height_;
1115   }
1116 }
1117 
TEST_P(VideoAdapterTest,AdaptResolutionInStepsFirst2_3)1118 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst2_3) {
1119   const int kWidth = 1920;
1120   const int kHeight = 1080;
1121   OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 16:9 aspect.
1122 
1123   // Scale factors: 2/3, 3/4, 2/3, 3/4, ...
1124   // Scale:         2/3, 1/2, 1/3, 1/4, 1/6, 1/8, 1/12.
1125   const int kExpectedWidths[] = {1280, 960, 640, 480, 320, 240, 160};
1126   const int kExpectedHeights[] = {720, 540, 360, 270, 180, 135, 90};
1127 
1128   int request_width = kWidth;
1129   int request_height = kHeight;
1130 
1131   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1132     // Adapt down one step.
1133     adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1134                                         request_width * request_height - 1,
1135                                         std::numeric_limits<int>::max()));
1136     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1137                                               &cropped_width_, &cropped_height_,
1138                                               &out_width_, &out_height_));
1139     EXPECT_EQ(kExpectedWidths[i], out_width_);
1140     EXPECT_EQ(kExpectedHeights[i], out_height_);
1141     request_width = out_width_;
1142     request_height = out_height_;
1143   }
1144 }
1145 
TEST_P(VideoAdapterTest,AdaptResolutionInStepsFirst2x2_3)1146 TEST_P(VideoAdapterTest, AdaptResolutionInStepsFirst2x2_3) {
1147   const int kWidth = 1440;
1148   const int kHeight = 1080;
1149   OnOutputFormatRequest(kWidth, kHeight, absl::nullopt);  // 4:3 aspect.
1150 
1151   // Scale factors: 2/3, 2/3, 3/4, 2/3, 3/4, ...
1152   // Scale        : 2/3, 4/9, 1/3, 2/9, 1/6, 1/9, 1/12, 1/18, 1/24, 1/36.
1153   const int kExpectedWidths[] = {960, 640, 480, 320, 240, 160, 120, 80, 60, 40};
1154   const int kExpectedHeights[] = {720, 480, 360, 240, 180, 120, 90, 60, 45, 30};
1155 
1156   int request_width = kWidth;
1157   int request_height = kHeight;
1158 
1159   for (size_t i = 0; i < arraysize(kExpectedWidths); ++i) {
1160     // Adapt down one step.
1161     adapter_.OnSinkWants(BuildSinkWants(absl::nullopt,
1162                                         request_width * request_height - 1,
1163                                         std::numeric_limits<int>::max()));
1164     EXPECT_TRUE(adapter_.AdaptFrameResolution(kWidth, kHeight, 0,
1165                                               &cropped_width_, &cropped_height_,
1166                                               &out_width_, &out_height_));
1167     EXPECT_EQ(kExpectedWidths[i], out_width_);
1168     EXPECT_EQ(kExpectedHeights[i], out_height_);
1169     request_width = out_width_;
1170     request_height = out_height_;
1171   }
1172 }
1173 
TEST_P(VideoAdapterTest,AdaptResolutionWithSinkAlignment)1174 TEST_P(VideoAdapterTest, AdaptResolutionWithSinkAlignment) {
1175   constexpr int kSourceWidth = 1280;
1176   constexpr int kSourceHeight = 720;
1177   constexpr int kSourceFramerate = 30;
1178   constexpr int kRequestedWidth = 480;
1179   constexpr int kRequestedHeight = 270;
1180   constexpr int kRequestedFramerate = 30;
1181 
1182   OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1183 
1184   int frame_num = 1;
1185   for (const int sink_alignment : {2, 3, 4, 5}) {
1186     adapter_.OnSinkWants(
1187         BuildSinkWants(absl::nullopt, std::numeric_limits<int>::max(),
1188                        std::numeric_limits<int>::max(), sink_alignment));
1189     EXPECT_TRUE(adapter_.AdaptFrameResolution(
1190         kSourceWidth, kSourceHeight,
1191         frame_num * rtc::kNumNanosecsPerSec / kSourceFramerate, &cropped_width_,
1192         &cropped_height_, &out_width_, &out_height_));
1193     EXPECT_EQ(out_width_ % sink_alignment, 0);
1194     EXPECT_EQ(out_height_ % sink_alignment, 0);
1195 
1196     ++frame_num;
1197   }
1198 }
1199 
1200 // Verify the cases the OnOutputFormatRequest is ignored and
1201 // requested_resolution is used instead.
TEST_P(VideoAdapterTest,UseRequestedResolutionInsteadOfOnOutputFormatRequest)1202 TEST_P(VideoAdapterTest, UseRequestedResolutionInsteadOfOnOutputFormatRequest) {
1203   {
1204     // Both new and old API active => Use OnOutputFormatRequest
1205     OnOutputFormatRequest(640, 360, kDefaultFps);
1206     adapter_.OnSinkWants(
1207         BuildSinkWants(Resolution{.width = 960, .height = 540},
1208                        /* any_active_without_requested_resolution= */ true));
1209 
1210     EXPECT_THAT(
1211         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1212             .first,
1213         Eq(Resolution{.width = 640, .height = 360}));
1214   }
1215   {
1216     // New API active, old API inactive, ignore OnOutputFormatRequest and use
1217     // requested_resolution.
1218     OnOutputFormatRequest(640, 360, kDefaultFps);
1219     adapter_.OnSinkWants(
1220         BuildSinkWants(Resolution{.width = 960, .height = 540},
1221                        /* any_active_without_requested_resolution= */ false));
1222 
1223     EXPECT_THAT(
1224         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1225             .first,
1226         Eq(Resolution{.width = 960, .height = 540}));
1227   }
1228 
1229   {
1230     // New API inactive, old API inactive, use OnOutputFormatRequest.
1231     OnOutputFormatRequest(640, 360, kDefaultFps);
1232     adapter_.OnSinkWants(
1233         BuildSinkWants(absl::nullopt,
1234                        /* any_active_without_requested_resolution= */ false));
1235 
1236     EXPECT_THAT(
1237         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1238             .first,
1239         Eq(Resolution{.width = 640, .height = 360}));
1240   }
1241 
1242   {
1243     // New API active, old API inactive, remember OnOutputFormatRequest.
1244     OnOutputFormatRequest(640, 360, kDefaultFps);
1245     adapter_.OnSinkWants(
1246         BuildSinkWants(Resolution{.width = 960, .height = 540},
1247                        /* any_active_without_requested_resolution= */ false));
1248 
1249     EXPECT_THAT(
1250         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1251             .first,
1252         Eq(Resolution{.width = 960, .height = 540}));
1253 
1254     // This is ignored since there is not any active NOT using
1255     // requested_resolution.
1256     OnOutputFormatRequest(320, 180, kDefaultFps);
1257 
1258     EXPECT_THAT(
1259         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1260             .first,
1261         Eq(Resolution{.width = 960, .height = 540}));
1262 
1263     // Disable new API => fallback to last OnOutputFormatRequest.
1264     adapter_.OnSinkWants(
1265         BuildSinkWants(absl::nullopt,
1266                        /* any_active_without_requested_resolution= */ false));
1267 
1268     EXPECT_THAT(
1269         AdaptFrameResolution(/* input frame */ {.width = 1280, .height = 720})
1270             .first,
1271         Eq(Resolution{.width = 320, .height = 180}));
1272   }
1273 }
1274 
1275 class VideoAdapterWithSourceAlignmentTest : public VideoAdapterTest {
1276  protected:
1277   static constexpr int kSourceResolutionAlignment = 7;
1278 
VideoAdapterWithSourceAlignmentTest()1279   VideoAdapterWithSourceAlignmentTest()
1280       : VideoAdapterTest(/*field_trials=*/"", kSourceResolutionAlignment) {}
1281 };
1282 
TEST_P(VideoAdapterWithSourceAlignmentTest,AdaptResolution)1283 TEST_P(VideoAdapterWithSourceAlignmentTest, AdaptResolution) {
1284   constexpr int kSourceWidth = 1280;
1285   constexpr int kSourceHeight = 720;
1286   constexpr int kRequestedWidth = 480;
1287   constexpr int kRequestedHeight = 270;
1288   constexpr int kRequestedFramerate = 30;
1289 
1290   OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1291 
1292   EXPECT_TRUE(adapter_.AdaptFrameResolution(
1293       kSourceWidth, kSourceHeight, /*in_timestamp_ns=*/0, &cropped_width_,
1294       &cropped_height_, &out_width_, &out_height_));
1295   EXPECT_EQ(out_width_ % kSourceResolutionAlignment, 0);
1296   EXPECT_EQ(out_height_ % kSourceResolutionAlignment, 0);
1297 }
1298 
TEST_P(VideoAdapterWithSourceAlignmentTest,AdaptResolutionWithSinkAlignment)1299 TEST_P(VideoAdapterWithSourceAlignmentTest, AdaptResolutionWithSinkAlignment) {
1300   constexpr int kSourceWidth = 1280;
1301   constexpr int kSourceHeight = 720;
1302   // 7 and 8 neither divide 480 nor 270.
1303   constexpr int kRequestedWidth = 480;
1304   constexpr int kRequestedHeight = 270;
1305   constexpr int kRequestedFramerate = 30;
1306   constexpr int kSinkResolutionAlignment = 8;
1307 
1308   OnOutputFormatRequest(kRequestedWidth, kRequestedHeight, kRequestedFramerate);
1309 
1310   adapter_.OnSinkWants(BuildSinkWants(
1311       absl::nullopt, std::numeric_limits<int>::max(),
1312       std::numeric_limits<int>::max(), kSinkResolutionAlignment));
1313   EXPECT_TRUE(adapter_.AdaptFrameResolution(
1314       kSourceWidth, kSourceHeight, /*in_timestamp_ns=*/0, &cropped_width_,
1315       &cropped_height_, &out_width_, &out_height_));
1316   EXPECT_EQ(out_width_ % kSourceResolutionAlignment, 0);
1317   EXPECT_EQ(out_height_ % kSourceResolutionAlignment, 0);
1318   EXPECT_EQ(out_width_ % kSinkResolutionAlignment, 0);
1319   EXPECT_EQ(out_height_ % kSinkResolutionAlignment, 0);
1320 }
1321 
1322 INSTANTIATE_TEST_SUITE_P(OnOutputFormatRequests,
1323                          VideoAdapterWithSourceAlignmentTest,
1324                          ::testing::Values(true, false));
1325 
1326 }  // namespace cricket
1327