1a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling/* 2a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Copyright (C) 2014 The Android Open Source Project 3a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * 4a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Licensed under the Apache License, Version 2.0 (the "License"); 5a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * you may not use this file except in compliance with the License. 6a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * You may obtain a copy of the License at 7a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * 8a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * http://www.apache.org/licenses/LICENSE-2.0 9a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * 10a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Unless required by applicable law or agreed to in writing, software 11a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * distributed under the License is distributed on an "AS IS" BASIS, 12a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * See the License for the specific language governing permissions and 14a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * limitations under the License. 15a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling */ 16a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 17a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingpackage com.android.camera; 18a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 19a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport android.content.Context; 20a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport android.content.res.Configuration; 21a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport android.view.Surface; 22a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 23a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport com.android.camera.debug.Log; 24a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport com.android.camera.debug.Log.Tag; 25a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport com.android.camera.util.CameraUtil; 26e3dfd5a433e39d76578b379fe1539864cf924ceeSascha Haeberlingimport com.android.camera.util.Size; 27a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 28a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingimport java.util.ArrayList; 29a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 30a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling/** 31a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Common utility methods used in capture modules. 32a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling */ 33a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberlingpublic class CaptureModuleUtil { 34a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling private static final Tag TAG = new Tag("CaptureModuleUtil"); 35a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 36a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling public static int getDeviceNaturalOrientation(Context context) { 37a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling Configuration config = context.getResources().getConfiguration(); 38a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling int rotation = CameraUtil.getDisplayRotation(context); 39a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 40a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && 41a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling config.orientation == Configuration.ORIENTATION_LANDSCAPE) || 42a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && 43a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling config.orientation == Configuration.ORIENTATION_PORTRAIT)) { 44a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return Configuration.ORIENTATION_LANDSCAPE; 45a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } else { 46a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return Configuration.ORIENTATION_PORTRAIT; 47a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 48a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 49a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 50a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling /** 51a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Equivalent to the 52a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * {@link CameraUtil#getOptimalPreviewSize(android.content.Context, java.util.List, double)} 53a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * method for the camera1 api. 54a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling */ 55a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling public static Size getOptimalPreviewSize(Context context, Size[] sizes, 56a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling double targetRatio) { 57a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // TODO(andyhuibers): Don't hardcode this but use device's measurements. 58a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling final int MAX_ASPECT_HEIGHT = 1080; 59a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 60a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // Count sizes with height <= 1080p to mimic camera1 api behavior. 61a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling int count = 0; 62a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling for (Size s : sizes) { 63a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (s.getHeight() <= MAX_ASPECT_HEIGHT) { 64a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling count++; 65a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 66a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 67f2627903d11faf47c5052884bc2b23e27b8d5f94Sascha Haeberling ArrayList<Size> camera1Sizes = new ArrayList<Size>(count); 68a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 69a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // Set array of all sizes with height <= 1080p 70a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling for (Size s : sizes) { 71a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (s.getHeight() <= MAX_ASPECT_HEIGHT) { 72f2627903d11faf47c5052884bc2b23e27b8d5f94Sascha Haeberling camera1Sizes.add(new Size(s.getWidth(), s.getHeight())); 73a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 74a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 75a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 76a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling int optimalIndex = CameraUtil 77a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling .getOptimalPreviewSizeIndex(context, camera1Sizes, targetRatio); 78a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 79a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (optimalIndex == -1) { 80a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return null; 81a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 82a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 83f2627903d11faf47c5052884bc2b23e27b8d5f94Sascha Haeberling Size optimal = camera1Sizes.get(optimalIndex); 84a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling for (Size s : sizes) { 85f2627903d11faf47c5052884bc2b23e27b8d5f94Sascha Haeberling if (s.getWidth() == optimal.getWidth() && s.getHeight() == optimal.getHeight()) { 86a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return s; 87a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 88a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 89a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return null; 90a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 91a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 92a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling /** 93a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * Selects the preview buffer dimensions that are closest in size to the 94a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling * size of the view containing the preview. 95a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling */ 96a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling public static Size pickBufferDimensions(Size[] supportedPreviewSizes, 97a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling double bestPreviewAspectRatio, 98a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling Context context) { 99a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // Swap dimensions if the device is not in its natural orientation. 100a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling boolean swapDimens = (CameraUtil.getDisplayRotation(context) % 180) == 90; 101a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // Swap dimensions if the device's natural orientation doesn't match 102a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling // the sensor orientation. 103a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (CaptureModuleUtil.getDeviceNaturalOrientation(context) 104a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling == Configuration.ORIENTATION_PORTRAIT) { 105a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling swapDimens = !swapDimens; 106a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 107a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling double bestAspect = bestPreviewAspectRatio; 108a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling if (swapDimens) { 109a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling bestAspect = 1 / bestAspect; 110a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 111a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling 112a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling Size pick = CaptureModuleUtil.getOptimalPreviewSize(context, supportedPreviewSizes, 113a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling bestPreviewAspectRatio); 114a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling Log.d(TAG, "Picked buffer size: " + pick.toString()); 115a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling return pick; 116a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling } 117a5c41b83304218f05a6454bf40fc6d236c218338Sascha Haeberling} 118