SimpleOneCameraFactory.java revision ffae1b53110ddae98b810bdb9a5c9dc210d96551
1/* 2 * Copyright (C) 2014 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; 18 19import android.annotation.TargetApi; 20import android.graphics.ImageFormat; 21import android.hardware.camera2.CameraDevice; 22import android.hardware.camera2.CaptureRequest; 23import android.os.Build; 24import android.view.Surface; 25 26import com.android.camera.FatalErrorHandler; 27import com.android.camera.async.HandlerFactory; 28import com.android.camera.async.Lifetime; 29import com.android.camera.async.MainThread; 30import com.android.camera.async.Observable; 31import com.android.camera.async.Observables; 32import com.android.camera.async.Updatable; 33import com.android.camera.burst.BurstFacade; 34import com.android.camera.debug.Loggers; 35import com.android.camera.one.OneCamera; 36import com.android.camera.one.OneCameraCharacteristics; 37import com.android.camera.one.config.OneCameraFeatureConfig; 38import com.android.camera.one.v2.camera2proxy.AndroidImageReaderProxy; 39import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy; 40import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy; 41import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory; 42import com.android.camera.one.v2.camera2proxy.ImageReaderProxy; 43import com.android.camera.one.v2.camera2proxy.TotalCaptureResultProxy; 44import com.android.camera.one.v2.commands.CameraCommandExecutor; 45import com.android.camera.one.v2.commands.zsl.BasicPreviewCommandFactory; 46import com.android.camera.one.v2.common.BasicCameraFactory; 47import com.android.camera.one.v2.common.SimpleCaptureStream; 48import com.android.camera.one.v2.core.FrameServerFactory; 49import com.android.camera.one.v2.core.RequestBuilder; 50import com.android.camera.one.v2.core.RequestTemplate; 51import com.android.camera.one.v2.core.ResponseListeners; 52import com.android.camera.one.v2.errorhandling.FramerateJankDetector; 53import com.android.camera.one.v2.imagesaver.ImageSaver; 54import com.android.camera.one.v2.initialization.CameraStarter; 55import com.android.camera.one.v2.initialization.InitializedOneCameraFactory; 56import com.android.camera.one.v2.photo.ImageRotationCalculator; 57import com.android.camera.one.v2.photo.LegacyPictureTakerFactory; 58import com.android.camera.one.v2.photo.PictureTaker; 59import com.android.camera.one.v2.photo.PictureTakerFactory; 60import com.android.camera.one.v2.sharedimagereader.ManagedImageReader; 61import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory; 62import com.android.camera.stats.UsageStatistics; 63import com.android.camera.util.AndroidContext; 64import com.android.camera.util.GservicesHelper; 65import com.android.camera.util.Provider; 66import com.android.camera.util.Size; 67import com.google.common.base.Supplier; 68 69import java.util.ArrayList; 70import java.util.Arrays; 71import java.util.List; 72import java.util.concurrent.ExecutorService; 73import java.util.concurrent.Executors; 74 75/** 76 * Creates a camera which takes jpeg images using the hardware encoder with 77 * baseline functionality. 78 */ 79@TargetApi(Build.VERSION_CODES.LOLLIPOP) 80public class SimpleOneCameraFactory implements OneCameraFactory { 81 private final int mImageFormat; 82 private final int mMaxImageCount; 83 private final ImageRotationCalculator mImageRotationCalculator; 84 85 /** 86 * @param imageFormat The {@link ImageFormat} to use for full-size images to 87 * be saved. 88 * @param maxImageCount The size of the image reader to use for full-size 89 * images. 90 */ 91 public SimpleOneCameraFactory(int imageFormat, int maxImageCount, 92 ImageRotationCalculator imageRotationCalculator) { 93 mImageFormat = imageFormat; 94 mMaxImageCount = maxImageCount; 95 mImageRotationCalculator = imageRotationCalculator; 96 } 97 98 @Override 99 public OneCamera createOneCamera(final CameraDeviceProxy device, 100 final OneCameraCharacteristics characteristics, 101 final OneCameraFeatureConfig.CaptureSupportLevel supportLevel, 102 final MainThread mainExecutor, 103 final Size pictureSize, 104 final ImageSaver.Builder imageSaverBuilder, 105 final Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting, 106 final Observable<Integer> exposureSetting, 107 final Observable<Boolean> hdrSceneSetting, 108 final BurstFacade burstFacade, 109 final FatalErrorHandler fatalErrorHandler) { 110 final Lifetime lifetime = new Lifetime(); 111 112 final ImageReaderProxy imageReader = new CloseWhenDoneImageReader(new LoggingImageReader( 113 AndroidImageReaderProxy.newInstance( 114 pictureSize.getWidth(), pictureSize.getHeight(), 115 mImageFormat, mMaxImageCount), 116 Loggers.tagFactory())); 117 118 lifetime.add(imageReader); 119 lifetime.add(device); 120 121 List<Surface> outputSurfaces = new ArrayList<>(); 122 outputSurfaces.add(imageReader.getSurface()); 123 124 /** 125 * Finishes constructing the camera when prerequisites, e.g. the preview 126 * stream and capture session, are ready. 127 */ 128 CameraStarter cameraStarter = new CameraStarter() { 129 @Override 130 public CameraStarter.CameraControls startCamera(Lifetime cameraLifetime, 131 CameraCaptureSessionProxy cameraCaptureSession, 132 Surface previewSurface, 133 Observable<Float> zoomState, 134 Updatable<TotalCaptureResultProxy> metadataCallback, 135 Updatable<Boolean> readyState) { 136 // Create the FrameServer from the CaptureSession. 137 FrameServerFactory frameServerComponent = new FrameServerFactory( 138 new Lifetime(cameraLifetime), cameraCaptureSession, new HandlerFactory()); 139 140 CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor( 141 Loggers.tagFactory(), 142 new Provider<ExecutorService>() { 143 @Override 144 public ExecutorService get() { 145 // Use a dynamically-expanding thread pool to 146 // allow any number of commands to execute 147 // simultaneously. 148 return Executors.newCachedThreadPool(); 149 } 150 }); 151 152 // Create the shared image reader. 153 SharedImageReaderFactory sharedImageReaderFactory = 154 new SharedImageReaderFactory(new Lifetime(cameraLifetime), imageReader, 155 new HandlerFactory()); 156 Updatable<Long> globalTimestampCallback = 157 sharedImageReaderFactory.provideGlobalTimestampQueue(); 158 ManagedImageReader managedImageReader = 159 sharedImageReaderFactory.provideSharedImageReader(); 160 161 // Create the request builder used by all camera operations. 162 // Streams, ResponseListeners, and Parameters added to 163 // this will be applied to *all* requests sent to the camera. 164 RequestTemplate rootBuilder = new RequestTemplate 165 (new CameraDeviceRequestBuilderFactory(device)); 166 // The shared image reader must be wired to receive every 167 // timestamp for every image (including the preview). 168 rootBuilder.addResponseListener( 169 ResponseListeners.forTimestamps(globalTimestampCallback)); 170 rootBuilder.addStream(new SimpleCaptureStream(previewSurface)); 171 rootBuilder.addResponseListener(ResponseListeners.forFinalMetadata( 172 metadataCallback)); 173 174 // Create basic functionality (zoom, AE, AF). 175 BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime 176 (cameraLifetime), 177 characteristics, 178 frameServerComponent.provideEphemeralFrameServer(), 179 rootBuilder, 180 cameraCommandExecutor, 181 new BasicPreviewCommandFactory(cameraCommandExecutor), 182 flashSetting, 183 exposureSetting, 184 zoomState, 185 hdrSceneSetting, 186 CameraDevice.TEMPLATE_PREVIEW); 187 188 // Register the dynamic updater via orientation supplier 189 rootBuilder.setParam(CaptureRequest.JPEG_ORIENTATION, 190 mImageRotationCalculator.getSupplier()); 191 192 if (GservicesHelper.isJankStatisticsEnabled(AndroidContext.instance().get() 193 .getContentResolver())) { 194 rootBuilder.addResponseListener( 195 new FramerateJankDetector(Loggers.tagFactory(), 196 UsageStatistics.instance())); 197 } 198 199 RequestBuilder.Factory meteredZoomedRequestBuilder = 200 basicCameraFactory.provideMeteredZoomedRequestBuilder(); 201 202 // Create the picture-taker. 203 PictureTaker pictureTaker; 204 if (supportLevel == OneCameraFeatureConfig.CaptureSupportLevel.LEGACY_JPEG) { 205 pictureTaker = new LegacyPictureTakerFactory(imageSaverBuilder, 206 cameraCommandExecutor, mainExecutor, 207 frameServerComponent.provideFrameServer(), 208 meteredZoomedRequestBuilder, managedImageReader).providePictureTaker(); 209 } else { 210 pictureTaker = PictureTakerFactory.create(Loggers.tagFactory(), mainExecutor, 211 cameraCommandExecutor, imageSaverBuilder, 212 frameServerComponent.provideFrameServer(), 213 meteredZoomedRequestBuilder, managedImageReader, flashSetting) 214 .providePictureTaker(); 215 } 216 217 // Wire-together ready-state. 218 final Observable<Integer> availableImageCount = sharedImageReaderFactory 219 .provideAvailableImageCount(); 220 final Observable<Boolean> frameServerAvailability = frameServerComponent 221 .provideReadyState(); 222 Observable<Boolean> ready = Observables.transform( 223 Arrays.asList(availableImageCount, frameServerAvailability), 224 new Supplier<Boolean>() { 225 @Override 226 public Boolean get() { 227 boolean atLeastOneImageAvailable = availableImageCount.get() >= 1; 228 boolean frameServerAvailable = frameServerAvailability.get(); 229 return atLeastOneImageAvailable && frameServerAvailable; 230 } 231 }); 232 233 lifetime.add(Observables.addThreadSafeCallback(ready, readyState)); 234 235 basicCameraFactory.providePreviewUpdater().run(); 236 237 return new CameraStarter.CameraControls( 238 pictureTaker, 239 basicCameraFactory.provideManualAutoFocus()); 240 } 241 }; 242 243 float maxZoom = characteristics.getAvailableMaxDigitalZoom(); 244 List<Size> supportedPreviewSizes = characteristics.getSupportedPreviewSizes(); 245 OneCamera.Facing direction = characteristics.getCameraDirection(); 246 247 return new InitializedOneCameraFactory(lifetime, cameraStarter, device, outputSurfaces, 248 mainExecutor, new HandlerFactory(), maxZoom, supportedPreviewSizes, 249 characteristics.getLensFocusRange(), direction) 250 .provideOneCamera(); 251 } 252} 253