CameraUtils.cpp revision d82147029a5f20c921a8134a030cdcca83841df7
15698d4461a260dbf208484383f692b03c6473e74Ruben Brunk/*
25698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * Copyright (C) 2014 The Android Open Source Project
35698d4461a260dbf208484383f692b03c6473e74Ruben Brunk *
45698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
55698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * you may not use this file except in compliance with the License.
65698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * You may obtain a copy of the License at
75698d4461a260dbf208484383f692b03c6473e74Ruben Brunk *
85698d4461a260dbf208484383f692b03c6473e74Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
95698d4461a260dbf208484383f692b03c6473e74Ruben Brunk *
105698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * Unless required by applicable law or agreed to in writing, software
115698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
125698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * See the License for the specific language governing permissions and
145698d4461a260dbf208484383f692b03c6473e74Ruben Brunk * limitations under the License.
155698d4461a260dbf208484383f692b03c6473e74Ruben Brunk */
165698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
175698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#define LOG_TAG "CameraUtils"
185698d4461a260dbf208484383f692b03c6473e74Ruben Brunk//#define LOG_NDEBUG 0
195698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
205698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <camera/CameraUtils.h>
215698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
225698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <system/window.h>
235698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <system/graphics.h>
245698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
255698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <utils/Log.h>
265698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
275698d4461a260dbf208484383f692b03c6473e74Ruben Brunknamespace android {
285698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
295698d4461a260dbf208484383f692b03c6473e74Ruben Brunkstatus_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
305698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                /*out*/int32_t* transform) {
315698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    ALOGV("%s", __FUNCTION__);
325698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
335698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (transform == NULL) {
345698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGW("%s: null transform", __FUNCTION__);
355698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return BAD_VALUE;
365698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
375698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
385698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    *transform = 0;
395698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
405698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
415698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (entry.count == 0) {
425698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__);
435698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return INVALID_OPERATION;
445698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
455698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
465698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
47d82147029a5f20c921a8134a030cdcca83841df7Ari Hausman-Cohen    if (entryFacing.count == 0) {
485698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__);
495698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return INVALID_OPERATION;
505698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
515698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
525698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    int32_t& flags = *transform;
535698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
545698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
555698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    int orientation = entry.data.i32[0];
565698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (!mirror) {
575698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        switch (orientation) {
585698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 0:
595698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = 0;
605698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
615698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 90:
625698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
635698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
645698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 180:
655698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
665698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
675698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 270:
685698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
695698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
705698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            default:
715698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
725698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                      __FUNCTION__, orientation);
735698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                return INVALID_OPERATION;
745698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        }
755698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    } else {
76b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // Front camera needs to be horizontally flipped for mirror-like behavior.
77b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // Note: Flips are applied before rotates; using XOR here as some of these flags are
78b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // composed in terms of other flip/rotation flags, and are not bitwise-ORable.
795698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        switch (orientation) {
805698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 0:
810ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
825698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
835698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 90:
84b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
850ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_270;
865698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
875698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 180:
88b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
890ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_180;
905698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
915698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 270:
92b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
930ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_90;
940ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala
955698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
965698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            default:
975698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
985698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                      __FUNCTION__, orientation);
995698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                return INVALID_OPERATION;
1005698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        }
1015698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1025698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
1035698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1045698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    /**
1055698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * This magic flag makes surfaceflinger un-rotate the buffers
1065698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * to counter the extra global device UI rotation whenever the user
1075698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * physically rotates the device.
1085698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     *
1095698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * By doing this, the camera buffer always ends up aligned
1105698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * with the physical camera for a "see through" effect.
1115698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     *
1125698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * In essence, the buffer only gets rotated during preview use-cases.
1135698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * The user is still responsible to re-create streams of the proper
1145698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * aspect ratio, or the preview will end up looking non-uniformly
1155698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * stretched.
1165698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     */
1175698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
1185698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1195698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
1205698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1215698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    return OK;
1225698d4461a260dbf208484383f692b03c6473e74Ruben Brunk}
1235698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1245698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1255698d4461a260dbf208484383f692b03c6473e74Ruben Brunk} /* namespace android */
126