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