CaptureConfig.java
/*
* Copyright (C) 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;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureRequest.Key;
import android.view.Surface;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.camera.core.Config.Option;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Configurations needed for a capture request.
*
* <p>The CaptureConfig contains all the {@link android.hardware.camera2} parameters that are
* required to issue a {@link CaptureRequest}.
*
* @hide
*/
@RestrictTo(Scope.LIBRARY_GROUP)
public final class CaptureConfig {
/** The set of {@link Surface} that data from the camera will be put into. */
final List<DeferrableSurface> mSurfaces;
/** The parameters used to configure the {@link CaptureRequest}. */
final Map<Key<?>, CaptureRequestParameter<?>> mCaptureRequestParameters;
final Config mImplementationOptions;
/**
* The templates used for configuring a {@link CaptureRequest}. This must match the constants
* defined by {@link CameraDevice}
*/
final int mTemplateType;
/** The camera capture callback for a {@link CameraCaptureSession}. */
final List<CameraCaptureCallback> mCameraCaptureCallbacks;
/** True if this capture request needs a repeating surface */
private final boolean mUseRepeatingSurface;
/** The tag for associating capture result with capture request. */
private final Object mTag;
/**
* Private constructor for a CaptureConfig.
*
* <p>In practice, the {@link CaptureConfig.Builder} will be used to construct a CaptureConfig.
*
* @param surfaces The set of {@link Surface} where data will be put into.
* @param captureRequestParameters The parameters used to configure the {@link CaptureRequest}.
* @param implementationOptions The generic parameters to be passed to the {@link BaseCamera}
* class.
* @param templateType The template for parameters of the CaptureRequest. This
* must match the
* constants defined by {@link CameraDevice}.
* @param cameraCaptureCallbacks All camera capture callbacks.
*/
CaptureConfig(
List<DeferrableSurface> surfaces,
Map<Key<?>, CaptureRequestParameter<?>> captureRequestParameters,
Config implementationOptions,
int templateType,
List<CameraCaptureCallback> cameraCaptureCallbacks,
boolean useRepeatingSurface,
Object tag) {
mSurfaces = surfaces;
mCaptureRequestParameters = captureRequestParameters;
mImplementationOptions = implementationOptions;
mTemplateType = templateType;
mCameraCaptureCallbacks = Collections.unmodifiableList(cameraCaptureCallbacks);
mUseRepeatingSurface = useRepeatingSurface;
mTag = tag;
}
/** Get all the surfaces that the request will write data to. */
public List<DeferrableSurface> getSurfaces() {
return Collections.unmodifiableList(mSurfaces);
}
public Map<Key<?>, CaptureRequestParameter<?>> getCameraCharacteristics() {
return Collections.unmodifiableMap(mCaptureRequestParameters);
}
public Config getImplementationOptions() {
return mImplementationOptions;
}
int getTemplateType() {
return mTemplateType;
}
public boolean isUseRepeatingSurface() {
return mUseRepeatingSurface;
}
/** Obtains all registered {@link CameraCaptureCallback} callbacks. */
public List<CameraCaptureCallback> getCameraCaptureCallbacks() {
return mCameraCaptureCallbacks;
}
public Object getTag() {
return mTag;
}
/**
* Return the builder of a {@link CaptureRequest} which can be issued.
*
* <p>Returns {@code null} if a valid {@link CaptureRequest} can not be constructed.
*/
@Nullable
public CaptureRequest.Builder buildCaptureRequest(@Nullable CameraDevice device)
throws CameraAccessException {
if (device == null) {
return null;
}
CaptureRequest.Builder builder = device.createCaptureRequest(mTemplateType);
for (CaptureRequestParameter<?> captureRequestParameter :
mCaptureRequestParameters.values()) {
captureRequestParameter.apply(builder);
}
List<Surface> surfaceList = DeferrableSurfaces.surfaceList(mSurfaces);
if (surfaceList.isEmpty()) {
return null;
}
for (Surface surface : surfaceList) {
builder.addTarget(surface);
}
builder.setTag(mTag);
return builder;
}
/**
* Builder for easy modification/rebuilding of a {@link CaptureConfig}.
*
* @hide
*/
@RestrictTo(Scope.LIBRARY_GROUP)
public static final class Builder {
private final Set<DeferrableSurface> mSurfaces = new HashSet<>();
private final Map<Key<?>, CaptureRequestParameter<?>> mCaptureRequestParameters =
new HashMap<>();
private MutableConfig mImplementationOptions = MutableOptionsBundle.create();
private int mTemplateType = -1;
private List<CameraCaptureCallback> mCameraCaptureCallbacks = new ArrayList<>();
private boolean mUseRepeatingSurface = false;
private Object mTag = null;
public Builder() {
}
private Builder(CaptureConfig base) {
mSurfaces.addAll(base.mSurfaces);
mCaptureRequestParameters.putAll(base.mCaptureRequestParameters);
mImplementationOptions = MutableOptionsBundle.from(base.mImplementationOptions);
mTemplateType = base.mTemplateType;
mCameraCaptureCallbacks.addAll(base.getCameraCaptureCallbacks());
mUseRepeatingSurface = base.isUseRepeatingSurface();
mTag = base.getTag();
}
/** Create a {@link Builder} from a {@link CaptureConfig} */
public static Builder from(CaptureConfig base) {
return new Builder(base);
}
int getTemplateType() {
return mTemplateType;
}
/**
* Set the template characteristics of the CaptureConfig.
*
* @param templateType Template constant that must match those defined by {@link
* CameraDevice}
*/
public void setTemplateType(int templateType) {
mTemplateType = templateType;
}
/**
* Adds a {@link CameraCaptureSession.StateCallback} callback.
* @throws IllegalArgumentException if the callback already exists in the configuration.
*/
public void addCameraCaptureCallback(CameraCaptureCallback cameraCaptureCallback) {
if (mCameraCaptureCallbacks.contains(cameraCaptureCallback)) {
throw new IllegalArgumentException("duplicate camera capture callback");
}
mCameraCaptureCallbacks.add(cameraCaptureCallback);
}
/**
* Adds all {@link CameraCaptureSession.StateCallback} callbacks.
* @throws IllegalArgumentException if any callback already exists in the configuration.
*/
public void addAllCameraCaptureCallbacks(
Collection<CameraCaptureCallback> cameraCaptureCallbacks) {
for (CameraCaptureCallback c : cameraCaptureCallbacks) {
addCameraCaptureCallback(c);
}
}
/** Add a surface that the request will write data to. */
public void addSurface(DeferrableSurface surface) {
mSurfaces.add(surface);
}
/** Remove a surface that the request will write data to. */
public void removeSurface(DeferrableSurface surface) {
mSurfaces.remove(surface);
}
/** Remove all the surfaces that the request will write data to. */
public void clearSurfaces() {
mSurfaces.clear();
}
Set<DeferrableSurface> getSurfaces() {
return mSurfaces;
}
/** Add a {@link CaptureRequest.Key}-value pair to the request. */
public <T> void addCharacteristic(Key<T> key, T value) {
mCaptureRequestParameters.put(key, CaptureRequestParameter.create(key, value));
}
/** Add a set of {@link CaptureRequest.Key}-value pairs to the request. */
public void addCharacteristics(Map<Key<?>, CaptureRequestParameter<?>> characteristics) {
mCaptureRequestParameters.putAll(characteristics);
}
public void setImplementationOptions(Config config) {
mImplementationOptions = MutableOptionsBundle.from(config);
}
/** Add a set of implementation specific options to the request. */
public void addImplementationOptions(Config config) {
for (Option<?> option : config.listOptions()) {
@SuppressWarnings("unchecked") // Options/values are being copied directly
Option<Object> objectOpt = (Option<Object>) option;
mImplementationOptions.insertOption(objectOpt, config.retrieveOption(objectOpt));
}
}
Map<Key<?>, CaptureRequestParameter<?>> getCharacteristic() {
return mCaptureRequestParameters;
}
boolean isUseRepeatingSurface() {
return mUseRepeatingSurface;
}
public void setUseRepeatingSurface(boolean useRepeatingSurface) {
mUseRepeatingSurface = useRepeatingSurface;
}
public void setTag(Object tag) {
mTag = tag;
}
/**
* Builds an instance of a CaptureConfig that has all the combined parameters of the
* CaptureConfig that have been added to the Builder.
*/
public CaptureConfig build() {
return new CaptureConfig(
new ArrayList<>(mSurfaces),
new HashMap<>(mCaptureRequestParameters),
OptionsBundle.from(mImplementationOptions),
mTemplateType,
mCameraCaptureCallbacks,
mUseRepeatingSurface,
mTag);
}
}
}