SurfaceConfig.java
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.core.impl;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCaptureSession.StateCallback;
import android.os.Handler;
import android.util.Size;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.internal.utils.SizeUtil;
import com.google.auto.value.AutoValue;
import java.util.List;
/**
* Surface configuration type and size pair
*
* <p>{@link android.hardware.camera2.CameraDevice#createCaptureSession} defines the default
* guaranteed stream combinations for different hardware level devices. It defines what combination
* of surface configuration type and size pairs can be supported for different hardware level camera
* devices.
*/
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
@AutoValue
public abstract class SurfaceConfig {
/** Prevent subclassing */
SurfaceConfig() {
}
/**
* Creates a new instance of SurfaceConfig with the given parameters.
*/
@NonNull
public static SurfaceConfig create(@NonNull ConfigType type, @NonNull ConfigSize size) {
return new AutoValue_SurfaceConfig(type, size);
}
/** Returns the configuration type. */
@NonNull
public abstract ConfigType getConfigType();
/** Returns the configuration size. */
@NonNull
public abstract ConfigSize getConfigSize();
/**
* Check whether the input surface configuration has a smaller size than this object and can be
* supported
*
* @param surfaceConfig the surface configuration to be compared
* @return the check result that whether it could be supported
*/
public final boolean isSupported(@NonNull SurfaceConfig surfaceConfig) {
boolean isSupported = false;
ConfigType configType = surfaceConfig.getConfigType();
ConfigSize configSize = surfaceConfig.getConfigSize();
// Check size and type to make sure it could be supported
if (configSize.getId() <= getConfigSize().getId() && configType == getConfigType()) {
isSupported = true;
}
return isSupported;
}
/**
* Gets {@link ConfigType} from image format.
*
* <p> PRIV refers to any target whose available sizes are found using
* StreamConfigurationMap.getOutputSizes(Class) with no direct application-visible format,
* YUV refers to a target Surface using the ImageFormat.YUV_420_888 format, JPEG refers to
* the ImageFormat.JPEG format, and RAW refers to the ImageFormat.RAW_SENSOR format.
*/
@NonNull
public static SurfaceConfig.ConfigType getConfigType(int imageFormat) {
if (imageFormat == ImageFormat.YUV_420_888) {
return SurfaceConfig.ConfigType.YUV;
} else if (imageFormat == ImageFormat.JPEG) {
return SurfaceConfig.ConfigType.JPEG;
} else if (imageFormat == ImageFormat.RAW_SENSOR) {
return SurfaceConfig.ConfigType.RAW;
} else {
return SurfaceConfig.ConfigType.PRIV;
}
}
/**
* Transform to a SurfaceConfig object with image format and size info
*
* @param imageFormat the image format info for the surface configuration object
* @param size the size info for the surface configuration object
* @param surfaceSizeDefinition the surface definition for the surface configuration object
* @return new {@link SurfaceConfig} object
*/
@NonNull
public static SurfaceConfig transformSurfaceConfig(int imageFormat, @NonNull Size size,
@NonNull SurfaceSizeDefinition surfaceSizeDefinition) {
ConfigType configType =
SurfaceConfig.getConfigType(imageFormat);
ConfigSize configSize = ConfigSize.NOT_SUPPORT;
// Compare with surface size definition to determine the surface configuration size
int sizeArea = SizeUtil.getArea(size);
if (sizeArea <= SizeUtil.getArea(surfaceSizeDefinition.getAnalysisSize())) {
configSize = ConfigSize.VGA;
} else if (sizeArea
<= SizeUtil.getArea(surfaceSizeDefinition.getPreviewSize())) {
configSize = ConfigSize.PREVIEW;
} else if (sizeArea
<= SizeUtil.getArea(surfaceSizeDefinition.getRecordSize())) {
configSize = ConfigSize.RECORD;
} else {
configSize = ConfigSize.MAXIMUM;
}
return SurfaceConfig.create(configType, configSize);
}
/**
* The Camera2 configuration type for the surface.
*
* <p>These are the enumerations defined in {@link
* android.hardware.camera2.CameraDevice#createCaptureSession(List, StateCallback, Handler)}.
*/
public enum ConfigType {
PRIV,
YUV,
JPEG,
RAW
}
/**
* The Camera2 stream sizes for the surface.
*
* <p>These are the enumerations defined in {@link
* android.hardware.camera2.CameraDevice#createCaptureSession(List, StateCallback, Handler)}.
*/
public enum ConfigSize {
/** Default VGA size is 640x480, which is the default size of Image Analysis. */
VGA(0),
/**
* PREVIEW refers to the best size match to the device's screen resolution, or to 1080p
* (1920x1080), whichever is smaller.
*/
PREVIEW(1),
/**
* RECORD refers to the camera device's maximum supported recording resolution, as
* determined by CamcorderProfile.
*/
RECORD(2),
/**
* MAXIMUM refers to the camera device's maximum output resolution for that format or target
* from StreamConfigurationMap.getOutputSizes(int)
*/
MAXIMUM(3),
/** NOT_SUPPORT is for the size larger than MAXIMUM */
NOT_SUPPORT(4);
final int mId;
ConfigSize(int id) {
mId = id;
}
int getId() {
return mId;
}
}
}