xref: /aosp_15_r20/frameworks/av/camera/CameraUtils.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "CameraUtils"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <camera/CameraUtils.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <camera/camera2/OutputConfiguration.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <media/hardware/HardwareAPI.h>
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker #include <android-base/properties.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <system/window.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <system/graphics.h>
27*ec779b8eSAndroid Build Coastguard Worker 
28*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker namespace android {
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker const char *kCameraServiceDisabledProperty = "config.disable_cameraservice";
33*ec779b8eSAndroid Build Coastguard Worker 
getRotationTransform(const CameraMetadata & staticInfo,int mirrorMode,bool enableTransformInverseDisplay,int32_t * transform)34*ec779b8eSAndroid Build Coastguard Worker status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
35*ec779b8eSAndroid Build Coastguard Worker         int mirrorMode,  bool enableTransformInverseDisplay, /*out*/int32_t* transform) {
36*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __FUNCTION__);
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker     if (transform == NULL) {
39*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: null transform", __FUNCTION__);
40*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
41*ec779b8eSAndroid Build Coastguard Worker     }
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker     *transform = 0;
44*ec779b8eSAndroid Build Coastguard Worker 
45*ec779b8eSAndroid Build Coastguard Worker     camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
46*ec779b8eSAndroid Build Coastguard Worker     if (entry.count == 0) {
47*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__);
48*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
49*ec779b8eSAndroid Build Coastguard Worker     }
50*ec779b8eSAndroid Build Coastguard Worker 
51*ec779b8eSAndroid Build Coastguard Worker     camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
52*ec779b8eSAndroid Build Coastguard Worker     if (entryFacing.count == 0) {
53*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__);
54*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
55*ec779b8eSAndroid Build Coastguard Worker     }
56*ec779b8eSAndroid Build Coastguard Worker 
57*ec779b8eSAndroid Build Coastguard Worker     int32_t& flags = *transform;
58*ec779b8eSAndroid Build Coastguard Worker 
59*ec779b8eSAndroid Build Coastguard Worker     int32_t mirror = 0;
60*ec779b8eSAndroid Build Coastguard Worker     if (mirrorMode == OutputConfiguration::MIRROR_MODE_AUTO &&
61*ec779b8eSAndroid Build Coastguard Worker             entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT) {
62*ec779b8eSAndroid Build Coastguard Worker         mirror = NATIVE_WINDOW_TRANSFORM_FLIP_H;
63*ec779b8eSAndroid Build Coastguard Worker     } else if (mirrorMode == OutputConfiguration::MIRROR_MODE_H) {
64*ec779b8eSAndroid Build Coastguard Worker         mirror = NATIVE_WINDOW_TRANSFORM_FLIP_H;
65*ec779b8eSAndroid Build Coastguard Worker     } else if (mirrorMode == OutputConfiguration::MIRROR_MODE_V) {
66*ec779b8eSAndroid Build Coastguard Worker         mirror = NATIVE_WINDOW_TRANSFORM_FLIP_V;
67*ec779b8eSAndroid Build Coastguard Worker     }
68*ec779b8eSAndroid Build Coastguard Worker 
69*ec779b8eSAndroid Build Coastguard Worker     int orientation = entry.data.i32[0];
70*ec779b8eSAndroid Build Coastguard Worker     if (mirror == 0) {
71*ec779b8eSAndroid Build Coastguard Worker         switch (orientation) {
72*ec779b8eSAndroid Build Coastguard Worker             case 0:
73*ec779b8eSAndroid Build Coastguard Worker                 flags = 0;
74*ec779b8eSAndroid Build Coastguard Worker                 break;
75*ec779b8eSAndroid Build Coastguard Worker             case 90:
76*ec779b8eSAndroid Build Coastguard Worker                 flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
77*ec779b8eSAndroid Build Coastguard Worker                 break;
78*ec779b8eSAndroid Build Coastguard Worker             case 180:
79*ec779b8eSAndroid Build Coastguard Worker                 flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
80*ec779b8eSAndroid Build Coastguard Worker                 break;
81*ec779b8eSAndroid Build Coastguard Worker             case 270:
82*ec779b8eSAndroid Build Coastguard Worker                 flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
83*ec779b8eSAndroid Build Coastguard Worker                 break;
84*ec779b8eSAndroid Build Coastguard Worker             default:
85*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
86*ec779b8eSAndroid Build Coastguard Worker                       __FUNCTION__, orientation);
87*ec779b8eSAndroid Build Coastguard Worker                 return INVALID_OPERATION;
88*ec779b8eSAndroid Build Coastguard Worker         }
89*ec779b8eSAndroid Build Coastguard Worker     } else {
90*ec779b8eSAndroid Build Coastguard Worker         // - Front camera needs to be horizontally flipped for mirror-like behavior.
91*ec779b8eSAndroid Build Coastguard Worker         // - Application-specified mirroring needs to be applied.
92*ec779b8eSAndroid Build Coastguard Worker         // Note: Flips are applied before rotates; using XOR here as some of these flags are
93*ec779b8eSAndroid Build Coastguard Worker         // composed in terms of other flip/rotation flags, and are not bitwise-ORable.
94*ec779b8eSAndroid Build Coastguard Worker         switch (orientation) {
95*ec779b8eSAndroid Build Coastguard Worker             case 0:
96*ec779b8eSAndroid Build Coastguard Worker                 flags = mirror;
97*ec779b8eSAndroid Build Coastguard Worker                 break;
98*ec779b8eSAndroid Build Coastguard Worker             case 90:
99*ec779b8eSAndroid Build Coastguard Worker                 flags = mirror ^
100*ec779b8eSAndroid Build Coastguard Worker                         NATIVE_WINDOW_TRANSFORM_ROT_270;
101*ec779b8eSAndroid Build Coastguard Worker                 break;
102*ec779b8eSAndroid Build Coastguard Worker             case 180:
103*ec779b8eSAndroid Build Coastguard Worker                 flags = mirror ^
104*ec779b8eSAndroid Build Coastguard Worker                         NATIVE_WINDOW_TRANSFORM_ROT_180;
105*ec779b8eSAndroid Build Coastguard Worker                 break;
106*ec779b8eSAndroid Build Coastguard Worker             case 270:
107*ec779b8eSAndroid Build Coastguard Worker                 flags = mirror ^
108*ec779b8eSAndroid Build Coastguard Worker                         NATIVE_WINDOW_TRANSFORM_ROT_90;
109*ec779b8eSAndroid Build Coastguard Worker                 break;
110*ec779b8eSAndroid Build Coastguard Worker             default:
111*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
112*ec779b8eSAndroid Build Coastguard Worker                       __FUNCTION__, orientation);
113*ec779b8eSAndroid Build Coastguard Worker                 return INVALID_OPERATION;
114*ec779b8eSAndroid Build Coastguard Worker         }
115*ec779b8eSAndroid Build Coastguard Worker 
116*ec779b8eSAndroid Build Coastguard Worker     }
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker     /**
119*ec779b8eSAndroid Build Coastguard Worker      * This magic flag makes surfaceflinger un-rotate the buffers
120*ec779b8eSAndroid Build Coastguard Worker      * to counter the extra global device UI rotation whenever the user
121*ec779b8eSAndroid Build Coastguard Worker      * physically rotates the device.
122*ec779b8eSAndroid Build Coastguard Worker      *
123*ec779b8eSAndroid Build Coastguard Worker      * By doing this, the camera buffer always ends up aligned
124*ec779b8eSAndroid Build Coastguard Worker      * with the physical camera for a "see through" effect.
125*ec779b8eSAndroid Build Coastguard Worker      *
126*ec779b8eSAndroid Build Coastguard Worker      * In essence, the buffer only gets rotated during preview use-cases.
127*ec779b8eSAndroid Build Coastguard Worker      * The user is still responsible to re-create streams of the proper
128*ec779b8eSAndroid Build Coastguard Worker      * aspect ratio, or the preview will end up looking non-uniformly
129*ec779b8eSAndroid Build Coastguard Worker      * stretched.
130*ec779b8eSAndroid Build Coastguard Worker      */
131*ec779b8eSAndroid Build Coastguard Worker     if (enableTransformInverseDisplay) {
132*ec779b8eSAndroid Build Coastguard Worker         flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
133*ec779b8eSAndroid Build Coastguard Worker     }
134*ec779b8eSAndroid Build Coastguard Worker 
135*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker     return OK;
138*ec779b8eSAndroid Build Coastguard Worker }
139*ec779b8eSAndroid Build Coastguard Worker 
isCameraServiceDisabled()140*ec779b8eSAndroid Build Coastguard Worker bool CameraUtils::isCameraServiceDisabled() {
141*ec779b8eSAndroid Build Coastguard Worker     return base::GetBoolProperty(kCameraServiceDisabledProperty, false);
142*ec779b8eSAndroid Build Coastguard Worker }
143*ec779b8eSAndroid Build Coastguard Worker 
144*ec779b8eSAndroid Build Coastguard Worker } /* namespace android */
145