1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.video; 18 19 import static android.media.CamcorderProfile.QUALITY_1080P; 20 import static android.media.CamcorderProfile.QUALITY_2160P; 21 import static android.media.CamcorderProfile.QUALITY_480P; 22 import static android.media.CamcorderProfile.QUALITY_720P; 23 import static android.media.CamcorderProfile.QUALITY_HIGH; 24 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_1080P; 25 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_2160P; 26 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_480P; 27 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_720P; 28 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_HIGH; 29 import static android.media.CamcorderProfile.QUALITY_HIGH_SPEED_LOW; 30 import static android.media.CamcorderProfile.QUALITY_LOW; 31 32 import static java.util.Arrays.asList; 33 import static java.util.Collections.emptyList; 34 import static java.util.Collections.singletonList; 35 import static java.util.Collections.unmodifiableList; 36 37 import android.util.Size; 38 39 import androidx.annotation.IntDef; 40 import androidx.annotation.RestrictTo; 41 import androidx.annotation.RestrictTo.Scope; 42 43 import com.google.auto.value.AutoValue; 44 45 import org.jspecify.annotations.NonNull; 46 47 import java.lang.annotation.Retention; 48 import java.lang.annotation.RetentionPolicy; 49 import java.util.ArrayList; 50 import java.util.HashSet; 51 import java.util.List; 52 import java.util.Set; 53 54 /** 55 * A class representing video quality constraints that will be used by {@link QualitySelector} to 56 * choose video resolution and appropriate encoding parameters. 57 */ 58 public class Quality { 59 60 // Restrict access to sealed class Quality()61 private Quality() { 62 } 63 64 /** 65 * Standard Definition (SD) 480p video quality. 66 * 67 * <p>This video quality usually corresponds to a resolution of 720 x 480 or 640 x 480 (480p) 68 * pixels. 69 */ 70 @NonNull 71 public static final Quality SD = ConstantQuality.of( 72 QUALITY_480P, 73 QUALITY_HIGH_SPEED_480P, 74 "SD", 75 unmodifiableList(asList(new Size(720, 480), new Size(640, 480)) 76 )); 77 78 /** 79 * High Definition (HD) video quality. 80 * 81 * <p>This video quality usually corresponds to a resolution of 1280 x 720 (720p) pixels. 82 */ 83 @NonNull 84 public static final Quality HD = ConstantQuality.of( 85 QUALITY_720P, 86 QUALITY_HIGH_SPEED_720P, 87 "HD", 88 singletonList(new Size(1280, 720) 89 )); 90 91 /** 92 * Full High Definition (FHD) 1080p video quality. 93 * 94 * <p>This video quality usually corresponds to a resolution of 1920 x 1080 (1080p) pixels. 95 */ 96 @NonNull 97 public static final Quality FHD = ConstantQuality.of( 98 QUALITY_1080P, 99 QUALITY_HIGH_SPEED_1080P, 100 "FHD", 101 singletonList(new Size(1920, 1080) 102 )); 103 104 /** 105 * Ultra High Definition (UHD) 2160p video quality. 106 * 107 * <p>This video quality usually corresponds to a resolution of 3840 x 2160 (2160p) pixels. 108 */ 109 @NonNull 110 public static final Quality UHD = ConstantQuality.of( 111 QUALITY_2160P, 112 QUALITY_HIGH_SPEED_2160P, 113 "UHD", 114 singletonList(new Size(3840, 2160) 115 )); 116 117 /** 118 * The lowest video quality supported by the video frame producer. 119 */ 120 @NonNull 121 public static final Quality LOWEST = ConstantQuality.of( 122 QUALITY_LOW, 123 QUALITY_HIGH_SPEED_LOW, 124 "LOWEST", 125 emptyList() 126 ); 127 128 /** 129 * The highest video quality supported by the video frame producer. 130 */ 131 @NonNull 132 public static final Quality HIGHEST = ConstantQuality.of( 133 QUALITY_HIGH, 134 QUALITY_HIGH_SPEED_HIGH, 135 "HIGHEST", 136 emptyList() 137 ); 138 139 static final Quality NONE = ConstantQuality.of(-1, -1, "NONE", emptyList()); 140 141 /** All quality constants. */ 142 private static final Set<Quality> QUALITIES = 143 new HashSet<>(asList(LOWEST, HIGHEST, SD, HD, FHD, UHD)); 144 145 /** Quality constants with size from large to small. */ 146 private static final List<Quality> QUALITIES_ORDER_BY_SIZE = asList(UHD, FHD, HD, SD); 147 containsQuality(@onNull Quality quality)148 static boolean containsQuality(@NonNull Quality quality) { 149 return QUALITIES.contains(quality); 150 } 151 152 @RestrictTo(RestrictTo.Scope.LIBRARY) 153 public static final int QUALITY_SOURCE_REGULAR = 1; 154 155 @RestrictTo(RestrictTo.Scope.LIBRARY) 156 public static final int QUALITY_SOURCE_HIGH_SPEED = 2; 157 158 @IntDef({QUALITY_SOURCE_REGULAR, QUALITY_SOURCE_HIGH_SPEED}) 159 @Retention(RetentionPolicy.SOURCE) 160 @RestrictTo(RestrictTo.Scope.LIBRARY) 161 public @interface QualitySource { 162 } 163 164 /** 165 * Gets all video quality constants with clearly defined size sorted from largest to smallest. 166 * 167 * <p>{@link #HIGHEST} and {@link #LOWEST} are not included. 168 */ 169 @RestrictTo(Scope.LIBRARY) getSortedQualities()170 public static @NonNull List<Quality> getSortedQualities() { 171 return new ArrayList<>(QUALITIES_ORDER_BY_SIZE); 172 } 173 174 @RestrictTo(Scope.LIBRARY) 175 @AutoValue 176 public abstract static class ConstantQuality extends Quality { of(int value, int highSpeedValue, @NonNull String name, @NonNull List<Size> typicalSizes)177 static ConstantQuality of(int value, int highSpeedValue, @NonNull String name, 178 @NonNull List<Size> typicalSizes) { 179 return new AutoValue_Quality_ConstantQuality(value, highSpeedValue, name, typicalSizes); 180 } 181 182 /** Gets the quality value corresponding to CamcorderProfile quality constant. */ getValue()183 abstract int getValue(); 184 185 /** Gets the quality value corresponding to CamcorderProfile high speed quality constant. */ getHighSpeedValue()186 abstract int getHighSpeedValue(); 187 188 /** Gets the quality name. */ getName()189 public abstract @NonNull String getName(); 190 191 /** Gets the typical sizes of the quality. */ 192 @SuppressWarnings("AutoValueImmutableFields") getTypicalSizes()193 public abstract @NonNull List<Size> getTypicalSizes(); 194 195 /** Gets the quality value for the given quality source. */ getQualityValue(@ualitySource int qualitySource)196 public int getQualityValue(@QualitySource int qualitySource) { 197 switch (qualitySource) { 198 case QUALITY_SOURCE_REGULAR: 199 return getValue(); 200 case QUALITY_SOURCE_HIGH_SPEED: 201 return getHighSpeedValue(); 202 default: 203 throw new AssertionError("Unknown quality source: " + qualitySource); 204 205 } 206 } 207 } 208 } 209