summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java')
-rw-r--r--third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java206
1 files changed, 206 insertions, 0 deletions
diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java
new file mode 100644
index 0000000000..0c3188fffe
--- /dev/null
+++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/CameraEnumerationAndroid.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+package org.webrtc;
+
+import static java.lang.Math.abs;
+
+import android.graphics.ImageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+@SuppressWarnings("deprecation")
+public class CameraEnumerationAndroid {
+ private final static String TAG = "CameraEnumerationAndroid";
+
+ static final ArrayList<Size> COMMON_RESOLUTIONS = new ArrayList<Size>(Arrays.asList(
+ // 0, Unknown resolution
+ new Size(160, 120), // 1, QQVGA
+ new Size(240, 160), // 2, HQVGA
+ new Size(320, 240), // 3, QVGA
+ new Size(400, 240), // 4, WQVGA
+ new Size(480, 320), // 5, HVGA
+ new Size(640, 360), // 6, nHD
+ new Size(640, 480), // 7, VGA
+ new Size(768, 480), // 8, WVGA
+ new Size(854, 480), // 9, FWVGA
+ new Size(800, 600), // 10, SVGA
+ new Size(960, 540), // 11, qHD
+ new Size(960, 640), // 12, DVGA
+ new Size(1024, 576), // 13, WSVGA
+ new Size(1024, 600), // 14, WVSGA
+ new Size(1280, 720), // 15, HD
+ new Size(1280, 1024), // 16, SXGA
+ new Size(1920, 1080), // 17, Full HD
+ new Size(1920, 1440), // 18, Full HD 4:3
+ new Size(2560, 1440), // 19, QHD
+ new Size(3840, 2160) // 20, UHD
+ ));
+
+ public static class CaptureFormat {
+ // Class to represent a framerate range. The framerate varies because of lightning conditions.
+ // The values are multiplied by 1000, so 1000 represents one frame per second.
+ public static class FramerateRange {
+ public int min;
+ public int max;
+
+ public FramerateRange(int min, int max) {
+ this.min = min;
+ this.max = max;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + (min / 1000.0f) + ":" + (max / 1000.0f) + "]";
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof FramerateRange)) {
+ return false;
+ }
+ final FramerateRange otherFramerate = (FramerateRange) other;
+ return min == otherFramerate.min && max == otherFramerate.max;
+ }
+
+ @Override
+ public int hashCode() {
+ // Use prime close to 2^16 to avoid collisions for normal values less than 2^16.
+ return 1 + 65537 * min + max;
+ }
+ }
+
+ public final int width;
+ public final int height;
+ public final FramerateRange framerate;
+
+ // TODO(hbos): If VideoCapturer.startCapture is updated to support other image formats then this
+ // needs to be updated and VideoCapturer.getSupportedFormats need to return CaptureFormats of
+ // all imageFormats.
+ public final int imageFormat = ImageFormat.NV21;
+
+ public CaptureFormat(int width, int height, int minFramerate, int maxFramerate) {
+ this.width = width;
+ this.height = height;
+ this.framerate = new FramerateRange(minFramerate, maxFramerate);
+ }
+
+ public CaptureFormat(int width, int height, FramerateRange framerate) {
+ this.width = width;
+ this.height = height;
+ this.framerate = framerate;
+ }
+
+ // Calculates the frame size of this capture format.
+ public int frameSize() {
+ return frameSize(width, height, imageFormat);
+ }
+
+ // Calculates the frame size of the specified image format. Currently only
+ // supporting ImageFormat.NV21.
+ // The size is width * height * number of bytes per pixel.
+ // http://developer.android.com/reference/android/hardware/Camera.html#addCallbackBuffer(byte[])
+ public static int frameSize(int width, int height, int imageFormat) {
+ if (imageFormat != ImageFormat.NV21) {
+ throw new UnsupportedOperationException("Don't know how to calculate "
+ + "the frame size of non-NV21 image formats.");
+ }
+ return (width * height * ImageFormat.getBitsPerPixel(imageFormat)) / 8;
+ }
+
+ @Override
+ public String toString() {
+ return width + "x" + height + "@" + framerate;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof CaptureFormat)) {
+ return false;
+ }
+ final CaptureFormat otherFormat = (CaptureFormat) other;
+ return width == otherFormat.width && height == otherFormat.height
+ && framerate.equals(otherFormat.framerate);
+ }
+
+ @Override
+ public int hashCode() {
+ return 1 + (width * 65497 + height) * 251 + framerate.hashCode();
+ }
+ }
+
+ // Helper class for finding the closest supported format for the two functions below. It creates a
+ // comparator based on the difference to some requested parameters, where the element with the
+ // minimum difference is the element that is closest to the requested parameters.
+ private static abstract class ClosestComparator<T> implements Comparator<T> {
+ // Difference between supported and requested parameter.
+ abstract int diff(T supportedParameter);
+
+ @Override
+ public int compare(T t1, T t2) {
+ return diff(t1) - diff(t2);
+ }
+ }
+
+ // Prefer a fps range with an upper bound close to `framerate`. Also prefer a fps range with a low
+ // lower bound, to allow the framerate to fluctuate based on lightning conditions.
+ public static CaptureFormat.FramerateRange getClosestSupportedFramerateRange(
+ List<CaptureFormat.FramerateRange> supportedFramerates, final int requestedFps) {
+ return Collections.min(
+ supportedFramerates, new ClosestComparator<CaptureFormat.FramerateRange>() {
+ // Progressive penalty if the upper bound is further away than `MAX_FPS_DIFF_THRESHOLD`
+ // from requested.
+ private static final int MAX_FPS_DIFF_THRESHOLD = 5000;
+ private static final int MAX_FPS_LOW_DIFF_WEIGHT = 1;
+ private static final int MAX_FPS_HIGH_DIFF_WEIGHT = 3;
+
+ // Progressive penalty if the lower bound is bigger than `MIN_FPS_THRESHOLD`.
+ private static final int MIN_FPS_THRESHOLD = 8000;
+ private static final int MIN_FPS_LOW_VALUE_WEIGHT = 1;
+ private static final int MIN_FPS_HIGH_VALUE_WEIGHT = 4;
+
+ // Use one weight for small `value` less than `threshold`, and another weight above.
+ private int progressivePenalty(int value, int threshold, int lowWeight, int highWeight) {
+ return (value < threshold) ? value * lowWeight
+ : threshold * lowWeight + (value - threshold) * highWeight;
+ }
+
+ @Override
+ int diff(CaptureFormat.FramerateRange range) {
+ final int minFpsError = progressivePenalty(
+ range.min, MIN_FPS_THRESHOLD, MIN_FPS_LOW_VALUE_WEIGHT, MIN_FPS_HIGH_VALUE_WEIGHT);
+ final int maxFpsError = progressivePenalty(Math.abs(requestedFps * 1000 - range.max),
+ MAX_FPS_DIFF_THRESHOLD, MAX_FPS_LOW_DIFF_WEIGHT, MAX_FPS_HIGH_DIFF_WEIGHT);
+ return minFpsError + maxFpsError;
+ }
+ });
+ }
+
+ public static Size getClosestSupportedSize(
+ List<Size> supportedSizes, final int requestedWidth, final int requestedHeight) {
+ return Collections.min(supportedSizes, new ClosestComparator<Size>() {
+ @Override
+ int diff(Size size) {
+ return abs(requestedWidth - size.width) + abs(requestedHeight - size.height);
+ }
+ });
+ }
+
+ // Helper method for camera classes.
+ static void reportCameraResolution(Histogram histogram, Size resolution) {
+ int index = COMMON_RESOLUTIONS.indexOf(resolution);
+ // 0 is reserved for unknown resolution, so add 1.
+ // indexOf returns -1 for unknown resolutions so it becomes 0 automatically.
+ histogram.addSample(index + 1);
+ }
+}