LegacyMetadataMapper.java revision 3e4fed203fe7c945c53c6d6bb9f160932a1d15b3
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 android.hardware.camera2.legacy; 18 19import android.graphics.ImageFormat; 20import android.hardware.Camera; 21import android.hardware.Camera.CameraInfo; 22import android.hardware.Camera.Size; 23import android.hardware.camera2.CameraCharacteristics; 24import android.hardware.camera2.impl.CameraMetadataNative; 25import android.hardware.camera2.params.StreamConfiguration; 26import android.hardware.camera2.params.StreamConfigurationDuration; 27import android.util.Log; 28 29import java.util.ArrayList; 30import java.util.List; 31 32import static com.android.internal.util.Preconditions.*; 33import static android.hardware.camera2.CameraCharacteristics.*; 34 35/** 36 * Provide legacy-specific implementations of camera2 metadata for legacy devices, such as the 37 * camera characteristics. 38 */ 39public class LegacyMetadataMapper { 40 private static final String TAG = "LegacyMetadataMapper"; 41 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 42 43 // from graphics.h 44 private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22; 45 private static final int HAL_PIXEL_FORMAT_BLOB = 0x21; 46 47 private static final long APPROXIMATE_CAPTURE_DELAY_MS = 200; // ms 48 private static final long APPROXIMATE_SENSOR_AREA = (1 << 20); // 8mp 49 private static final long APPROXIMATE_JPEG_ENCODE_TIME = 600; // ms 50 private static final long NS_PER_MS = 1000000; 51 52 /** 53 * Create characteristics for a legacy device by mapping the {@code parameters} 54 * and {@code info} 55 * 56 * @param parameters A string parseable by {@link Camera.Parameters#unflatten} 57 * @param info Camera info with camera facing direction and angle of orientation 58 * @return static camera characteristics for a camera device 59 * 60 * @throws NullPointerException if any of the args were {@code null} 61 */ 62 public static CameraCharacteristics createCharacteristics(String parameters, 63 android.hardware.CameraInfo info) { 64 checkNotNull(parameters, "parameters must not be null"); 65 checkNotNull(info, "info must not be null"); 66 checkNotNull(info.info, "info.info must not be null"); 67 68 CameraMetadataNative m = new CameraMetadataNative(); 69 70 mapCameraInfo(m, info.info); 71 72 Camera.Parameters params = Camera.getEmptyParameters(); 73 params.unflatten(parameters); 74 mapCameraParameters(m, params); 75 76 if (VERBOSE) { 77 Log.v(TAG, "createCharacteristics metadata:"); 78 Log.v(TAG, "--------------------------------------------------- (start)"); 79 m.dumpToLog(); 80 Log.v(TAG, "--------------------------------------------------- (end)"); 81 } 82 83 return new CameraCharacteristics(m); 84 } 85 86 private static void mapCameraInfo(CameraMetadataNative m, CameraInfo i) { 87 m.set(LENS_FACING, i.facing == CameraInfo.CAMERA_FACING_BACK ? 88 LENS_FACING_BACK : LENS_FACING_FRONT); 89 m.set(SENSOR_ORIENTATION, i.orientation); 90 } 91 92 private static void mapCameraParameters(CameraMetadataNative m, Camera.Parameters p) { 93 mapStreamConfigs(m, p); 94 95 // TODO: map other fields 96 } 97 98 private static void mapStreamConfigs(CameraMetadataNative m, Camera.Parameters p) { 99 100 ArrayList<StreamConfiguration> availableStreamConfigs = new ArrayList<>(); 101 /* 102 * Implementation-defined (preview, recording, etc) -> use camera1 preview sizes 103 * YUV_420_888 cpu callbacks -> use camera1 preview sizes 104 * Other preview callbacks (CPU) -> use camera1 preview sizes 105 * JPEG still capture -> use camera1 still capture sizes 106 * 107 * Use platform-internal format constants here, since StreamConfigurationMap does the 108 * remapping to public format constants. 109 */ 110 List<Size> previewSizes = p.getSupportedPreviewSizes(); 111 appendStreamConfig(availableStreamConfigs, 112 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes); 113 appendStreamConfig(availableStreamConfigs, 114 ImageFormat.YUV_420_888, previewSizes); 115 for (int format : p.getSupportedPreviewFormats()) { 116 if (ImageFormat.isPublicFormat(format)) { 117 appendStreamConfig(availableStreamConfigs, format, previewSizes); 118 } else { 119 /* 120 * Do not add any formats unknown to us 121 * (since it would fail runtime checks in StreamConfigurationMap) 122 */ 123 Log.w(TAG, 124 String.format("mapStreamConfigs - Skipping non-public format %x", format)); 125 } 126 } 127 128 List<Camera.Size> jpegSizes = p.getSupportedPictureSizes(); 129 appendStreamConfig(availableStreamConfigs, 130 HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes()); 131 m.set(SCALER_AVAILABLE_STREAM_CONFIGURATIONS, 132 availableStreamConfigs.toArray(new StreamConfiguration[0])); 133 134 // No frame durations available 135 m.set(SCALER_AVAILABLE_MIN_FRAME_DURATIONS, new StreamConfigurationDuration[0]); 136 137 StreamConfigurationDuration[] jpegStalls = 138 new StreamConfigurationDuration[jpegSizes.size()]; 139 int i = 0; 140 for (Camera.Size s : jpegSizes) { 141 jpegStalls[i++] = new StreamConfigurationDuration(HAL_PIXEL_FORMAT_BLOB, s.width, 142 s.height, calculateJpegStallDuration(s)); 143 } 144 // Set stall durations for jpeg, other formats use default stall duration 145 m.set(SCALER_AVAILABLE_STALL_DURATIONS, jpegStalls); 146 } 147 148 private static void appendStreamConfig( 149 ArrayList<StreamConfiguration> configs, int format, List<Camera.Size> sizes) { 150 for (Camera.Size size : sizes) { 151 StreamConfiguration config = 152 new StreamConfiguration(format, size.width, size.height, /*input*/false); 153 configs.add(config); 154 } 155 } 156 157 /** 158 * Return the stall duration for a given output jpeg size in nanoseconds. 159 * 160 * <p>An 8mp image is chosen to have a stall duration of 0.8 seconds.</p> 161 */ 162 private static long calculateJpegStallDuration(Camera.Size size) { 163 long baseDuration = APPROXIMATE_CAPTURE_DELAY_MS * NS_PER_MS; // 200ms for capture 164 long area = size.width * (long) size.height; 165 long stallPerArea = APPROXIMATE_JPEG_ENCODE_TIME * NS_PER_MS / 166 APPROXIMATE_SENSOR_AREA; // 600ms stall for 8mp 167 return baseDuration + area * stallPerArea; 168 } 169} 170