CameraUtils.cpp revision b3afa1e3c2af242e0d31a7619713b170d43c7e88
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 17#define LOG_TAG "CameraUtils" 18//#define LOG_NDEBUG 0 19 20#include <camera/CameraUtils.h> 21 22#include <system/window.h> 23#include <system/graphics.h> 24 25#include <utils/Log.h> 26 27namespace android { 28 29status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo, 30 /*out*/int32_t* transform) { 31 ALOGV("%s", __FUNCTION__); 32 33 if (transform == NULL) { 34 ALOGW("%s: null transform", __FUNCTION__); 35 return BAD_VALUE; 36 } 37 38 *transform = 0; 39 40 camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION); 41 if (entry.count == 0) { 42 ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__); 43 return INVALID_OPERATION; 44 } 45 46 camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING); 47 if (entry.count == 0) { 48 ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__); 49 return INVALID_OPERATION; 50 } 51 52 int32_t& flags = *transform; 53 54 bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT); 55 int orientation = entry.data.i32[0]; 56 if (!mirror) { 57 switch (orientation) { 58 case 0: 59 flags = 0; 60 break; 61 case 90: 62 flags = NATIVE_WINDOW_TRANSFORM_ROT_90; 63 break; 64 case 180: 65 flags = NATIVE_WINDOW_TRANSFORM_ROT_180; 66 break; 67 case 270: 68 flags = NATIVE_WINDOW_TRANSFORM_ROT_270; 69 break; 70 default: 71 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", 72 __FUNCTION__, orientation); 73 return INVALID_OPERATION; 74 } 75 } else { 76 // Front camera needs to be horizontally flipped for mirror-like behavior. 77 // Note: Flips are applied before rotates; using XOR here as some of these flags are 78 // composed in terms of other flip/rotation flags, and are not bitwise-ORable. 79 switch (orientation) { 80 case 0: 81 flags = NATIVE_WINDOW_TRANSFORM_FLIP_H; 82 break; 83 case 90: 84 flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ 85 NATIVE_WINDOW_TRANSFORM_ROT_270; 86 break; 87 case 180: 88 flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ 89 NATIVE_WINDOW_TRANSFORM_ROT_180; 90 break; 91 case 270: 92 flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^ 93 NATIVE_WINDOW_TRANSFORM_ROT_90; 94 95 break; 96 default: 97 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d", 98 __FUNCTION__, orientation); 99 return INVALID_OPERATION; 100 } 101 102 } 103 104 /** 105 * This magic flag makes surfaceflinger un-rotate the buffers 106 * to counter the extra global device UI rotation whenever the user 107 * physically rotates the device. 108 * 109 * By doing this, the camera buffer always ends up aligned 110 * with the physical camera for a "see through" effect. 111 * 112 * In essence, the buffer only gets rotated during preview use-cases. 113 * The user is still responsible to re-create streams of the proper 114 * aspect ratio, or the preview will end up looking non-uniformly 115 * stretched. 116 */ 117 flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 118 119 ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags); 120 121 return OK; 122} 123 124 125} /* namespace android */ 126