ITS: Match largest preview size with video encoding capability

This test queries largest supported preview resolution, which is
used by test case to create video recording session. However,
max video encoder size on low-end targets may not match largest
preview resolution, so encoder creation may fail.

In short, video recording session should be created based on
platform's video capabilities.

Bug: 362309063
Test: run scene4/test_preview_aspect_ratio_and_crop by Qualcomm
Flag: TEST_ONLY
Change-Id: Iaa26323223598cf973cd9fd4a6c1f6a7ea907f6d
diff --git a/apps/CameraITS/utils/video_processing_utils.py b/apps/CameraITS/utils/video_processing_utils.py
index c350f8e..1922593 100644
--- a/apps/CameraITS/utils/video_processing_utils.py
+++ b/apps/CameraITS/utils/video_processing_utils.py
@@ -20,6 +20,7 @@
 
 import dataclasses
 import logging
+import math
 import os.path
 import re
 import subprocess
@@ -136,6 +137,28 @@
   return common_size_quality
 
 
+def clamp_preview_sizes(preview_sizes, min_area=0, max_area=math.inf):
+  """Returns a list of preview_sizes with areas between min/max_area.
+
+  Args:
+    preview_sizes: list; sizes to be filtered (ex. "1280x720")
+    min_area: int; optional filter to eliminate sizes <= to the specified
+        area (ex. 640*480).
+    max_area: int; optional filter to eliminate sizes >= to the specified
+        area (ex. 3840*2160).
+  Returns:
+    preview_sizes: list; filtered preview sizes clamped by min/max_area.
+  """
+  size_to_area = lambda size: int(size.split('x')[0])*int(size.split('x')[1])
+  filtered_preview_sizes = [
+      size for size in preview_sizes
+      if max_area >= size_to_area(size) >= min_area]
+  logging.debug('Filtered preview sizes: %s', filtered_preview_sizes)
+  if not filtered_preview_sizes:
+    raise AssertionError(f'No preview sizes between {min_area} and {max_area}')
+  return filtered_preview_sizes
+
+
 def log_ffmpeg_version():
   """Logs the ffmpeg version being used."""