LegacyRequestMapper.java revision 442395751d46aa0f569ad479202a84713a260be0
109109567e9816d20f51b5ce0175751116836635fDaichi Hirono/* 209109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Copyright (C) 2014 The Android Open Source Project 309109567e9816d20f51b5ce0175751116836635fDaichi Hirono * 409109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Licensed under the Apache License, Version 2.0 (the "License"); 509109567e9816d20f51b5ce0175751116836635fDaichi Hirono * you may not use this file except in compliance with the License. 609109567e9816d20f51b5ce0175751116836635fDaichi Hirono * You may obtain a copy of the License at 709109567e9816d20f51b5ce0175751116836635fDaichi Hirono * 809109567e9816d20f51b5ce0175751116836635fDaichi Hirono * http://www.apache.org/licenses/LICENSE-2.0 909109567e9816d20f51b5ce0175751116836635fDaichi Hirono * 1009109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Unless required by applicable law or agreed to in writing, software 1109109567e9816d20f51b5ce0175751116836635fDaichi Hirono * distributed under the License is distributed on an "AS IS" BASIS, 1209109567e9816d20f51b5ce0175751116836635fDaichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309109567e9816d20f51b5ce0175751116836635fDaichi Hirono * See the License for the specific language governing permissions and 1409109567e9816d20f51b5ce0175751116836635fDaichi Hirono * limitations under the License. 1509109567e9816d20f51b5ce0175751116836635fDaichi Hirono */ 1609109567e9816d20f51b5ce0175751116836635fDaichi Hirono 1709109567e9816d20f51b5ce0175751116836635fDaichi Hironopackage android.hardware.camera2.legacy; 1809109567e9816d20f51b5ce0175751116836635fDaichi Hirono 1909109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.graphics.Rect; 20b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewskiimport android.hardware.Camera; 2152652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewskiimport android.hardware.Camera.Parameters; 2220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hironoimport android.hardware.camera2.CameraCharacteristics; 2309109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.hardware.camera2.CaptureRequest; 2409109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.hardware.camera2.params.MeteringRectangle; 250f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hironoimport android.hardware.camera2.utils.ListUtils; 26e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hironoimport android.hardware.camera2.utils.ParamsUtils; 2709109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.location.Location; 2809109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.util.Log; 2935b2ec551f670562a779925fe152307f20ad67cdDaichi Hironoimport android.util.Range; 3009109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.util.Size; 316ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hirono 32b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewskiimport java.util.ArrayList; 33b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewskiimport java.util.Arrays; 346baa16e9109046661fef8dcc25b8754ac68bcdaeDaichi Hironoimport java.util.List; 35e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hironoimport java.util.Objects; 36e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono 37e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hironoimport static com.android.internal.util.Preconditions.*; 3820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hironoimport static android.hardware.camera2.CaptureRequest.*; 39bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski 40124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono/** 41124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono * Provide legacy-specific implementations of camera2 CaptureRequest for legacy devices. 42124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono */ 4364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono@SuppressWarnings("deprecation") 4409109567e9816d20f51b5ce0175751116836635fDaichi Hironopublic class LegacyRequestMapper { 456ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hirono private static final String TAG = "LegacyRequestMapper"; 4609109567e9816d20f51b5ce0175751116836635fDaichi Hirono private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 4709109567e9816d20f51b5ce0175751116836635fDaichi Hirono 4809109567e9816d20f51b5ce0175751116836635fDaichi Hirono private static final byte DEFAULT_JPEG_QUALITY = 85; 4920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono 5020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono /** 5109109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Set the legacy parameters using the {@link LegacyRequest legacy request}. 5209109567e9816d20f51b5ce0175751116836635fDaichi Hirono * 53bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski * <p>The legacy request's parameters are changed as a side effect of calling this 54bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski * method.</p> 55124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono * 56124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono * @param legacyRequest a non-{@code null} legacy request 57bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski */ 58bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski public static void convertRequestMetadata(LegacyRequest legacyRequest) { 59e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono CameraCharacteristics characteristics = legacyRequest.characteristics; 60e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono CaptureRequest request = legacyRequest.captureRequest; 6152652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski Size previewSize = legacyRequest.previewSize; 6252652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski Camera.Parameters params = legacyRequest.parameters; 638ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono 648ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 65b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski 66b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski /* 67b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski * scaler.cropRegion 68b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski */ 693faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono ParameterUtils.ZoomData zoomData; 703faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono { 713faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono zoomData = ParameterUtils.convertScalerCropRegion(activeArray, 723faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono request.get(SCALER_CROP_REGION), 7364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono previewSize, 7464111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono params); 7564111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono 7664111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono if (params.isZoomSupported()) { 7709109567e9816d20f51b5ce0175751116836635fDaichi Hirono params.setZoom(zoomData.zoomIndex); 78f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono } else if (VERBOSE) { 7920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono Log.v(TAG, "convertRequestToMetadata - zoom is not supported"); 8020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 8120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 8220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono 8320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono /* 8420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono * colorCorrection.* 8520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono */ 86ebd24051599280443435606cab220de33b9356adDaichi Hirono // colorCorrection.aberrationMode 87ebd24051599280443435606cab220de33b9356adDaichi Hirono { 8820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono int aberrationMode = ParamsUtils.getOrDefault(request, 8909109567e9816d20f51b5ce0175751116836635fDaichi Hirono COLOR_CORRECTION_ABERRATION_MODE, 9020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST); 9109109567e9816d20f51b5ce0175751116836635fDaichi Hirono 9209109567e9816d20f51b5ce0175751116836635fDaichi Hirono if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST) { 9309109567e9816d20f51b5ce0175751116836635fDaichi Hirono Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + 94f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono "colorCorrection.aberrationMode = " + aberrationMode); 9520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 964e94b8deaa646f176bad9b80d5924ce64142743eDaichi Hirono } 9709109567e9816d20f51b5ce0175751116836635fDaichi Hirono 9809109567e9816d20f51b5ce0175751116836635fDaichi Hirono /* 990f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono * control.ae* 1000f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono */ 1010f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono // control.aeAntibandingMode 1020f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono { 1030f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono String legacyMode; 10409109567e9816d20f51b5ce0175751116836635fDaichi Hirono Integer antiBandingMode = request.get(CONTROL_AE_ANTIBANDING_MODE); 10509109567e9816d20f51b5ce0175751116836635fDaichi Hirono if (antiBandingMode != null) { 10609109567e9816d20f51b5ce0175751116836635fDaichi Hirono legacyMode = convertAeAntiBandingModeToLegacy(antiBandingMode); 107f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono } else { 10820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono legacyMode = ListUtils.listSelectFirstFrom(params.getSupportedAntibanding(), 1094e94b8deaa646f176bad9b80d5924ce64142743eDaichi Hirono new String[] { 11020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono Parameters.ANTIBANDING_AUTO, 11109109567e9816d20f51b5ce0175751116836635fDaichi Hirono Parameters.ANTIBANDING_OFF, 11220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono Parameters.ANTIBANDING_50HZ, 11320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono Parameters.ANTIBANDING_60HZ, 114ebd24051599280443435606cab220de33b9356adDaichi Hirono }); 11537a655aac1d61ce2fe346531f78cbcfbf51388e9Daichi Hirono } 11609109567e9816d20f51b5ce0175751116836635fDaichi Hirono 11709109567e9816d20f51b5ce0175751116836635fDaichi Hirono if (legacyMode != null) { 11809109567e9816d20f51b5ce0175751116836635fDaichi Hirono params.setAntibanding(legacyMode); 119bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski } 120124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono } 121bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski 122bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski /* 123124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono * control.aeRegions, afRegions 124bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski */ 125124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono { 126124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono // aeRegions 127124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono { 128124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono // Use aeRegions if available, fall back to using awbRegions if present 129124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS); 130124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono if (request.get(CONTROL_AWB_REGIONS) != null) { 131124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono Log.w(TAG, "convertRequestMetadata - control.awbRegions setting is not " + 132124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono "supported, ignoring value"); 133124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono } 134124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono int maxNumMeteringAreas = params.getMaxNumMeteringAreas(); 135124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono List<Camera.Area> meteringAreaList = convertMeteringRegionsToLegacy( 136e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono activeArray, zoomData, aeRegions, maxNumMeteringAreas, 137e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono /*regionName*/"AE"); 138e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono 139b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null). 140b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski if (maxNumMeteringAreas > 0) { 141b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski params.setMeteringAreas(meteringAreaList); 14252652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski } 14352652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski } 14452652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski 14552652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski // afRegions 14652652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski { 1478ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS); 14852652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski int maxNumFocusAreas = params.getMaxNumFocusAreas(); 1498ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono List<Camera.Area> focusAreaList = convertMeteringRegionsToLegacy( 1508ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono activeArray, zoomData, afRegions, maxNumFocusAreas, 1518ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono /*regionName*/"AF"); 1528ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono 153df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null). 154b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski if (maxNumFocusAreas > 0) { 15535b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono params.setFocusAreas(focusAreaList); 15635b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono } 15735b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono } 158df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski } 159df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski 160b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski // control.aeTargetFpsRange 161b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski Range<Integer> aeFpsRange = request.get(CONTROL_AE_TARGET_FPS_RANGE); 162f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono if (aeFpsRange != null) { 163f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange); 164f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono 165df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski // TODO - Should we enforce that all HAL1 devices must include (30, 30) FPS range? 166df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski boolean supported = false; 167df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski for(int[] range : params.getSupportedPreviewFpsRange()) { 168df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski if (legacyFps[0] == range[0] && legacyFps[1] == range[1]) { 169df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski supported = true; 170df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski break; 171df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski } 172df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski } 173df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski if (supported) { 174df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski params.setPreviewFpsRange(legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], 175df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); 176b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski } else { 177df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski Log.w(TAG, "Unsupported FPS range set [" + legacyFps[0] + "," + legacyFps[1] + "]"); 178b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski } 179b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski } 180b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski 1813faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono /* 1823faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono * control 1833faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono */ 1843faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono 1853faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono // control.aeExposureCompensation 1863faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono { 1873faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono Range<Integer> compensationRange = 1883faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE); 1893faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono int compensation = ParamsUtils.getOrDefault(request, 1903faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono CONTROL_AE_EXPOSURE_COMPENSATION, 1915fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono /*defaultValue*/0); 1925fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono 193bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski if (!compensationRange.contains(compensation)) { 194bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski Log.w(TAG, 1955fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono "convertRequestMetadata - control.aeExposureCompensation " + 1965fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono "is out of range, ignoring value"); 1975fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono compensation = 0; 1985fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono } 1995fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono 2005fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono params.setExposureCompensation(compensation); 201ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski } 2025fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono 203ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski // control.aeLock 204ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski { 2055fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono Boolean aeLock = getIfSupported(request, CONTROL_AE_LOCK, /*defaultValue*/false, 2065fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono params.isAutoExposureLockSupported(), 2075fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono /*allowedValue*/false); 2085fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono 2095fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono if (aeLock != null) { 2105fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono params.setAutoExposureLock(aeLock); 211cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono } 212cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono 213cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono if (VERBOSE) { 214b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock); 215b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono } 216b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono 217b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono // TODO: Don't add control.aeLock to availableRequestKeys if it's not supported 218b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono } 219b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono 220b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono // control.aeMode, flash.mode 221b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono mapAeAndFlashMode(request, /*out*/params); 222b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono 223b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono // control.afMode 224b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono { 225b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono int afMode = ParamsUtils.getOrDefault(request, CONTROL_AF_MODE, 22664111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono /*defaultValue*/CONTROL_AF_MODE_OFF); 22764111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono String focusMode = LegacyMetadataMapper.convertAfModeToLegacy(afMode, 22864111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono params.getSupportedFocusModes()); 22964111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono 23064111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono if (focusMode != null) { 23164111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono params.setFocusMode(focusMode); 23264111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono } 23364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono 23464111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono if (VERBOSE) { 23564111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono Log.v(TAG, "convertRequestToMetadata - control.afMode " 23609109567e9816d20f51b5ce0175751116836635fDaichi Hirono + afMode + " mapped to " + focusMode); 237 } 238 } 239 240 // control.awbMode 241 { 242 Integer awbMode = getIfSupported(request, CONTROL_AWB_MODE, 243 /*defaultValue*/CONTROL_AWB_MODE_AUTO, 244 params.getSupportedWhiteBalance() != null, 245 /*allowedValue*/CONTROL_AWB_MODE_AUTO); 246 247 String whiteBalanceMode = null; 248 if (awbMode != null) { // null iff AWB is not supported by camera1 api 249 whiteBalanceMode = convertAwbModeToLegacy(awbMode); 250 params.setWhiteBalance(whiteBalanceMode); 251 } 252 253 if (VERBOSE) { 254 Log.v(TAG, "convertRequestToMetadata - control.awbMode " 255 + awbMode + " mapped to " + whiteBalanceMode); 256 } 257 } 258 259 // control.awbLock 260 { 261 Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false, 262 params.isAutoWhiteBalanceLockSupported(), 263 /*allowedValue*/false); 264 265 if (awbLock != null) { 266 params.setAutoWhiteBalanceLock(awbLock); 267 } 268 269 // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported 270 } 271 272 // control.captureIntent 273 { 274 int captureIntent = ParamsUtils.getOrDefault(request, 275 CONTROL_CAPTURE_INTENT, 276 /*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW); 277 278 captureIntent = filterSupportedCaptureIntent(captureIntent); 279 280 params.setRecordingHint( 281 captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD || 282 captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT); 283 } 284 285 // control.videoStabilizationMode 286 { 287 Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE, 288 /*defaultValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF, 289 params.isVideoStabilizationSupported(), 290 /*allowedValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF); 291 292 if (stabMode != null) { 293 params.setVideoStabilization(stabMode == CONTROL_VIDEO_STABILIZATION_MODE_ON); 294 } 295 } 296 297 // lens.focusDistance 298 { 299 boolean infinityFocusSupported = 300 ListUtils.listContains(params.getSupportedFocusModes(), 301 Parameters.FOCUS_MODE_INFINITY); 302 Float focusDistance = getIfSupported(request, LENS_FOCUS_DISTANCE, 303 /*defaultValue*/0f, infinityFocusSupported, /*allowedValue*/0f); 304 305 if (focusDistance == null || focusDistance != 0f) { 306 Log.w(TAG, 307 "convertRequestToMetadata - Ignoring android.lens.focusDistance " 308 + infinityFocusSupported + ", only 0.0f is supported"); 309 } 310 } 311 312 // control.sceneMode, control.mode 313 { 314 // TODO: Map FACE_PRIORITY scene mode to face detection. 315 316 if (params.getSupportedSceneModes() != null) { 317 int controlMode = ParamsUtils.getOrDefault(request, CONTROL_MODE, 318 /*defaultValue*/CONTROL_MODE_AUTO); 319 String modeToSet; 320 switch (controlMode) { 321 case CONTROL_MODE_USE_SCENE_MODE: { 322 int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE, 323 /*defaultValue*/CONTROL_SCENE_MODE_DISABLED); 324 String legacySceneMode = LegacyMetadataMapper. 325 convertSceneModeToLegacy(sceneMode); 326 if (legacySceneMode != null) { 327 modeToSet = legacySceneMode; 328 } else { 329 modeToSet = Parameters.SCENE_MODE_AUTO; 330 Log.w(TAG, "Skipping unknown requested scene mode: " + sceneMode); 331 } 332 break; 333 } 334 case CONTROL_MODE_AUTO: { 335 modeToSet = Parameters.SCENE_MODE_AUTO; 336 break; 337 } 338 default: { 339 Log.w(TAG, "Control mode " + controlMode + 340 " is unsupported, defaulting to AUTO"); 341 modeToSet = Parameters.SCENE_MODE_AUTO; 342 } 343 } 344 params.setSceneMode(modeToSet); 345 } 346 } 347 348 // control.effectMode 349 { 350 if (params.getSupportedColorEffects() != null) { 351 int effectMode = ParamsUtils.getOrDefault(request, CONTROL_EFFECT_MODE, 352 /*defaultValue*/CONTROL_EFFECT_MODE_OFF); 353 String legacyEffectMode = LegacyMetadataMapper.convertEffectModeToLegacy(effectMode); 354 if (legacyEffectMode != null) { 355 params.setColorEffect(legacyEffectMode); 356 } else { 357 params.setColorEffect(Parameters.EFFECT_NONE); 358 Log.w(TAG, "Skipping unknown requested effect mode: " + effectMode); 359 } 360 } 361 } 362 363 /* 364 * sensor 365 */ 366 367 // sensor.testPattern 368 { 369 int testPatternMode = ParamsUtils.getOrDefault(request, SENSOR_TEST_PATTERN_MODE, 370 /*defaultValue*/SENSOR_TEST_PATTERN_MODE_OFF); 371 if (testPatternMode != SENSOR_TEST_PATTERN_MODE_OFF) { 372 Log.w(TAG, "convertRequestToMetadata - ignoring sensor.testPatternMode " 373 + testPatternMode + "; only OFF is supported"); 374 } 375 } 376 377 /* 378 * jpeg.* 379 */ 380 381 // jpeg.gpsLocation 382 { 383 Location location = request.get(JPEG_GPS_LOCATION); 384 if (location != null) { 385 if (checkForCompleteGpsData(location)) { 386 params.setGpsAltitude(location.getAltitude()); 387 params.setGpsLatitude(location.getLatitude()); 388 params.setGpsLongitude(location.getLongitude()); 389 params.setGpsProcessingMethod(location.getProvider().toUpperCase()); 390 params.setGpsTimestamp(location.getTime()); 391 } else { 392 Log.w(TAG, "Incomplete GPS parameters provided in location " + location); 393 } 394 } else { 395 params.removeGpsData(); 396 } 397 } 398 399 // jpeg.orientation 400 { 401 int orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); 402 params.setRotation(ParamsUtils.getOrDefault(request, JPEG_ORIENTATION, orientation)); 403 } 404 405 // jpeg.quality 406 { 407 params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_QUALITY, 408 DEFAULT_JPEG_QUALITY)); 409 } 410 411 // jpeg.thumbnailQuality 412 { 413 params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_THUMBNAIL_QUALITY, 414 DEFAULT_JPEG_QUALITY)); 415 } 416 417 // jpeg.thumbnailSize 418 { 419 List<Camera.Size> sizes = params.getSupportedJpegThumbnailSizes(); 420 421 if (sizes != null && sizes.size() > 0) { 422 Size s = request.get(JPEG_THUMBNAIL_SIZE); 423 boolean invalidSize = (s == null) ? false : !ParameterUtils.containsSize(sizes, 424 s.getWidth(), s.getHeight()); 425 if (invalidSize) { 426 Log.w(TAG, "Invalid JPEG thumbnail size set " + s + ", skipping thumbnail..."); 427 } 428 if (s == null || invalidSize) { 429 // (0,0) = "no thumbnail" in Camera API 1 430 params.setJpegThumbnailSize(/*width*/0, /*height*/0); 431 } else { 432 params.setJpegThumbnailSize(s.getWidth(), s.getHeight()); 433 } 434 } 435 } 436 437 /* 438 * noiseReduction.* 439 */ 440 // noiseReduction.mode 441 { 442 int mode = ParamsUtils.getOrDefault(request, 443 NOISE_REDUCTION_MODE, 444 /*defaultValue*/NOISE_REDUCTION_MODE_FAST); 445 446 if (mode != NOISE_REDUCTION_MODE_FAST) { 447 Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " + 448 "noiseReduction.mode = " + mode); 449 } 450 } 451 } 452 453 private static boolean checkForCompleteGpsData(Location location) { 454 return location != null && location.getProvider() != null && location.getTime() != 0; 455 } 456 457 static int filterSupportedCaptureIntent(int captureIntent) { 458 switch (captureIntent) { 459 case CONTROL_CAPTURE_INTENT_CUSTOM: 460 case CONTROL_CAPTURE_INTENT_PREVIEW: 461 case CONTROL_CAPTURE_INTENT_STILL_CAPTURE: 462 case CONTROL_CAPTURE_INTENT_VIDEO_RECORD: 463 case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT: 464 break; 465 case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG: 466 case CONTROL_CAPTURE_INTENT_MANUAL: 467 captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; 468 Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent 469 + "; default to PREVIEW"); 470 default: 471 captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW; 472 Log.w(TAG, "Unknown control.captureIntent value " + captureIntent 473 + "; default to PREVIEW"); 474 } 475 476 return captureIntent; 477 } 478 479 private static List<Camera.Area> convertMeteringRegionsToLegacy( 480 Rect activeArray, ParameterUtils.ZoomData zoomData, 481 MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) { 482 if (meteringRegions == null || maxNumMeteringAreas <= 0) { 483 if (maxNumMeteringAreas > 0) { 484 return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT); 485 } else { 486 return null; 487 } 488 } 489 490 // Add all non-zero weight regions to the list 491 List<MeteringRectangle> meteringRectangleList = new ArrayList<>(); 492 for (MeteringRectangle rect : meteringRegions) { 493 if (rect.getMeteringWeight() != MeteringRectangle.METERING_WEIGHT_DONT_CARE) { 494 meteringRectangleList.add(rect); 495 } 496 } 497 498 // Ignore any regions beyond our maximum supported count 499 int countMeteringAreas = 500 Math.min(maxNumMeteringAreas, meteringRectangleList.size()); 501 List<Camera.Area> meteringAreaList = new ArrayList<>(countMeteringAreas); 502 503 for (int i = 0; i < countMeteringAreas; ++i) { 504 MeteringRectangle rect = meteringRectangleList.get(i); 505 506 ParameterUtils.MeteringData meteringData = 507 ParameterUtils.convertMeteringRectangleToLegacy(activeArray, rect, zoomData); 508 meteringAreaList.add(meteringData.meteringArea); 509 } 510 511 if (maxNumMeteringAreas < meteringRectangleList.size()) { 512 Log.w(TAG, 513 "convertMeteringRegionsToLegacy - Too many requested " + regionName + 514 " regions, ignoring all beyond the first " + maxNumMeteringAreas); 515 } 516 517 if (VERBOSE) { 518 Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = " 519 + ParameterUtils.stringFromAreaList(meteringAreaList)); 520 } 521 522 return meteringAreaList; 523 } 524 525 private static void mapAeAndFlashMode(CaptureRequest r, /*out*/Parameters p) { 526 int flashMode = ParamsUtils.getOrDefault(r, FLASH_MODE, FLASH_MODE_OFF); 527 int aeMode = ParamsUtils.getOrDefault(r, CONTROL_AE_MODE, CONTROL_AE_MODE_ON); 528 529 List<String> supportedFlashModes = p.getSupportedFlashModes(); 530 531 String flashModeSetting = null; 532 533 // Flash is OFF by default, on cameras that support flash 534 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_OFF)) { 535 flashModeSetting = Parameters.FLASH_MODE_OFF; 536 } 537 538 /* 539 * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it 540 */ 541 542 // Ignore flash.mode controls unless aeMode == ON 543 if (aeMode == CONTROL_AE_MODE_ON) { 544 if (flashMode == FLASH_MODE_TORCH) { 545 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) { 546 flashModeSetting = Parameters.FLASH_MODE_TORCH; 547 } else { 548 Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == TORCH;" + 549 "camera does not support it"); 550 } 551 } else if (flashMode == FLASH_MODE_SINGLE) { 552 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) { 553 flashModeSetting = Parameters.FLASH_MODE_ON; 554 } else { 555 Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == SINGLE;" + 556 "camera does not support it"); 557 } 558 } else { 559 // Use the default FLASH_MODE_OFF 560 } 561 } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH) { 562 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) { 563 flashModeSetting = Parameters.FLASH_MODE_ON; 564 } else { 565 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_ALWAYS_FLASH;" + 566 "camera does not support it"); 567 } 568 } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH) { 569 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) { 570 flashModeSetting = Parameters.FLASH_MODE_AUTO; 571 } else { 572 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;" + 573 "camera does not support it"); 574 } 575 } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) { 576 if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) { 577 flashModeSetting = Parameters.FLASH_MODE_RED_EYE; 578 } else { 579 Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH_REDEYE;" 580 + "camera does not support it"); 581 } 582 } else { 583 // Default to aeMode == ON, flash = OFF 584 } 585 586 if (flashModeSetting != null) { 587 p.setFlashMode(flashModeSetting); 588 } 589 590 if (VERBOSE) { 591 Log.v(TAG, 592 "mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting 593 + ", requested (api2) " + flashMode 594 + ", supported (api1) " + ListUtils.listToString(supportedFlashModes)); 595 } 596 } 597 598 /** 599 * Returns null if the anti-banding mode enum is not supported. 600 */ 601 private static String convertAeAntiBandingModeToLegacy(int mode) { 602 switch (mode) { 603 case CONTROL_AE_ANTIBANDING_MODE_OFF: { 604 return Parameters.ANTIBANDING_OFF; 605 } 606 case CONTROL_AE_ANTIBANDING_MODE_50HZ: { 607 return Parameters.ANTIBANDING_50HZ; 608 } 609 case CONTROL_AE_ANTIBANDING_MODE_60HZ: { 610 return Parameters.ANTIBANDING_60HZ; 611 } 612 case CONTROL_AE_ANTIBANDING_MODE_AUTO: { 613 return Parameters.ANTIBANDING_AUTO; 614 } 615 default: { 616 return null; 617 } 618 } 619 } 620 621 private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) { 622 int[] legacyFps = new int[2]; 623 legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower(); 624 legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper(); 625 return legacyFps; 626 } 627 628 private static String convertAwbModeToLegacy(int mode) { 629 switch (mode) { 630 case CONTROL_AWB_MODE_AUTO: 631 return Camera.Parameters.WHITE_BALANCE_AUTO; 632 case CONTROL_AWB_MODE_INCANDESCENT: 633 return Camera.Parameters.WHITE_BALANCE_INCANDESCENT; 634 case CONTROL_AWB_MODE_FLUORESCENT: 635 return Camera.Parameters.WHITE_BALANCE_FLUORESCENT; 636 case CONTROL_AWB_MODE_WARM_FLUORESCENT: 637 return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT; 638 case CONTROL_AWB_MODE_DAYLIGHT: 639 return Camera.Parameters.WHITE_BALANCE_DAYLIGHT; 640 case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT: 641 return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT; 642 case CONTROL_AWB_MODE_TWILIGHT: 643 return Camera.Parameters.WHITE_BALANCE_TWILIGHT; 644 default: 645 Log.w(TAG, "convertAwbModeToLegacy - unrecognized control.awbMode" + mode); 646 return Camera.Parameters.WHITE_BALANCE_AUTO; 647 } 648 } 649 650 651 /** 652 * Return {@code null} if the value is not supported, otherwise return the retrieved key's 653 * value from the request (or the default value if it wasn't set). 654 * 655 * <p>If the fetched value in the request is equivalent to {@code allowedValue}, 656 * then omit the warning (e.g. turning off AF lock on a camera 657 * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p> 658 * 659 * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p. 660 */ 661 private static <T> T getIfSupported( 662 CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported, 663 T allowedValue) { 664 T val = ParamsUtils.getOrDefault(r, key, defaultValue); 665 666 if (!isSupported) { 667 if (!Objects.equals(val, allowedValue)) { 668 Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val); 669 } 670 return null; 671 } 672 673 return val; 674 } 675} 676