1/* 2 * Copyright (C) 2015 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 17package com.android.camera.one.v2.photo.zsl; 18 19import android.hardware.camera2.CaptureResult; 20import android.hardware.camera2.TotalCaptureResult; 21 22import com.android.camera.async.Updatable; 23import com.android.camera.debug.Log; 24import com.android.camera.debug.Logger; 25import com.android.camera.one.v2.camera2proxy.CaptureRequestProxy; 26import com.android.camera.one.v2.camera2proxy.CaptureResultProxy; 27import com.android.camera.one.v2.camera2proxy.TotalCaptureResultProxy; 28import com.google.common.base.Objects; 29import com.google.common.base.Preconditions; 30import com.google.common.base.Predicate; 31 32import java.util.List; 33import java.util.concurrent.atomic.AtomicBoolean; 34 35import javax.annotation.Nonnull; 36import javax.annotation.Nullable; 37import javax.annotation.ParametersAreNonnullByDefault; 38 39/** 40 * Like {@link AcceptableZslImageFilter}, but determines whether or not to 41 * filter ZSL images by AE convergence based on the most-recent converged AE 42 * result. This enables an optimization in which pictures can be taken with zero 43 * shutter lag when flash is AUTO even if AE is searching. 44 * <p> 45 * For example, when flash is AUTO, we can only capture images via the ZSL 46 * buffer if we know that flash is not required. We know that flash is not 47 * required when CONTROL_AE_STATE == CONTROL_AE_STATE_CONVERGED. However, when 48 * the AE system is scanning, we do not know if flash is required. So, instead 49 * of waiting until it converges, we can cache the most recent result and allow 50 * capturing an image instantly. 51 * <p> 52 * Note that this optimization presents a trade-off between speed and 53 * quality/accuracy. For example, if a user moves the camera from a bright scene 54 * to a dark scene and tries to immediately take a picture before AE has 55 * converged, then the flash may not fire. However, it enables faster capture if 56 * the user moves the camera from a bright scene to another bright scene with a 57 * different level of illumination, which would not otherwise require flash. 58 */ 59@ParametersAreNonnullByDefault 60public final class AutoFlashZslImageFilter implements Predicate<TotalCaptureResultProxy>, 61 Updatable<CaptureResultProxy> { 62 private final Logger mLog; 63 private final AcceptableZslImageFilter mDefaultFilter; 64 65 private AtomicBoolean mRequireAEConvergence; 66 private long mLastFrameNumber; 67 68 private AutoFlashZslImageFilter(Logger.Factory logFactory, 69 AcceptableZslImageFilter defaultFilter) { 70 mDefaultFilter = defaultFilter; 71 mLog = logFactory.create(new Log.Tag("AutoFlashZslImgFltr")); 72 mRequireAEConvergence = new AtomicBoolean(true); 73 mLastFrameNumber = -1; 74 } 75 76 /** 77 * Wraps a TotalCaptureResult, converting 78 * CaptureResult.CONTROL_AE_STATE_SEARCHING into 79 * CaptureResult.CONTROL_AE_STATE_CONVERGED. 80 */ 81 private static class AEConvergedTotalCaptureResult implements TotalCaptureResultProxy { 82 private final TotalCaptureResultProxy mDelegate; 83 84 public AEConvergedTotalCaptureResult(TotalCaptureResultProxy delegate) { 85 mDelegate = delegate; 86 } 87 88 @Nullable 89 @Override 90 public <T> T get(CaptureResult.Key<T> key) { 91 if (key == TotalCaptureResult.CONTROL_AE_STATE) { 92 Integer aeState = (Integer) mDelegate.get(key); 93 if (Objects.equal(aeState, CaptureResult.CONTROL_AE_STATE_SEARCHING)) { 94 return (T) ((Integer) CaptureResult.CONTROL_AE_STATE_CONVERGED); 95 } 96 } 97 return mDelegate.get(key); 98 } 99 100 @Nonnull 101 @Override 102 public List<CaptureResult.Key<?>> getKeys() { 103 return mDelegate.getKeys(); 104 } 105 106 @Nonnull 107 @Override 108 public CaptureRequestProxy getRequest() { 109 return mDelegate.getRequest(); 110 } 111 112 @Override 113 public long getFrameNumber() { 114 return mDelegate.getFrameNumber(); 115 } 116 117 @Override 118 public int getSequenceId() { 119 return mDelegate.getSequenceId(); 120 } 121 122 @Nonnull 123 @Override 124 public List<CaptureResultProxy> getPartialResults() { 125 return mDelegate.getPartialResults(); 126 } 127 } 128 129 public static AutoFlashZslImageFilter create(Logger.Factory logFactory, 130 boolean requireAFConvergence) { 131 return new AutoFlashZslImageFilter( 132 logFactory, 133 new AcceptableZslImageFilter(requireAFConvergence, /* aeConvergence */true)); 134 } 135 136 @Override 137 public boolean apply(TotalCaptureResultProxy totalCaptureResultProxy) { 138 if (!mRequireAEConvergence.get()) { 139 // If AE was previously converged, wrap the metadata to appear as if AE is currently 140 // converged. 141 totalCaptureResultProxy = new AEConvergedTotalCaptureResult(totalCaptureResultProxy); 142 } 143 return mDefaultFilter.apply(totalCaptureResultProxy); 144 } 145 146 @Override 147 public void update(@Nonnull CaptureResultProxy captureResult) { 148 if (captureResult.getFrameNumber() > mLastFrameNumber) { 149 Integer aeState = captureResult.get(CaptureResult.CONTROL_AE_STATE); 150 if (aeState != null) { 151 if (aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) { 152 boolean previousValue = mRequireAEConvergence.getAndSet(true); 153 if (previousValue != true) { 154 // Only log changes 155 mLog.i("Flash required"); 156 } 157 } else if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { 158 boolean previousValue = mRequireAEConvergence.getAndSet(false); 159 if (previousValue != false) { 160 // Only log changes 161 mLog.i("Flash not required"); 162 } 163 } 164 mLastFrameNumber = captureResult.getFrameNumber(); 165 } 166 } 167 } 168} 169