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>
216773d4777f4ccbbe6377e4ae1b42c117066ae6baPraveen Chavan#include <media/hardware/HardwareAPI.h>
225698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
235698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <system/window.h>
245698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <system/graphics.h>
255698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
265698d4461a260dbf208484383f692b03c6473e74Ruben Brunk#include <utils/Log.h>
275698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
285698d4461a260dbf208484383f692b03c6473e74Ruben Brunknamespace android {
295698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
305698d4461a260dbf208484383f692b03c6473e74Ruben Brunkstatus_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
315698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                /*out*/int32_t* transform) {
325698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    ALOGV("%s", __FUNCTION__);
335698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
345698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (transform == NULL) {
355698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGW("%s: null transform", __FUNCTION__);
365698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return BAD_VALUE;
375698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
385698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
395698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    *transform = 0;
405698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
415698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    camera_metadata_ro_entry_t entry = staticInfo.find(ANDROID_SENSOR_ORIENTATION);
425698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (entry.count == 0) {
435698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGE("%s: Can't find android.sensor.orientation in static metadata!", __FUNCTION__);
445698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return INVALID_OPERATION;
455698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
465698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
475698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    camera_metadata_ro_entry_t entryFacing = staticInfo.find(ANDROID_LENS_FACING);
48d82147029a5f20c921a8134a030cdcca83841df7Ari Hausman-Cohen    if (entryFacing.count == 0) {
495698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        ALOGE("%s: Can't find android.lens.facing in static metadata!", __FUNCTION__);
505698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        return INVALID_OPERATION;
515698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
525698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
535698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    int32_t& flags = *transform;
545698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
555698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    bool mirror = (entryFacing.data.u8[0] == ANDROID_LENS_FACING_FRONT);
565698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    int orientation = entry.data.i32[0];
575698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    if (!mirror) {
585698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        switch (orientation) {
595698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 0:
605698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = 0;
615698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
625698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 90:
635698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
645698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
655698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 180:
665698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
675698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
685698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 270:
695698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
705698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
715698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            default:
725698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
735698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                      __FUNCTION__, orientation);
745698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                return INVALID_OPERATION;
755698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        }
765698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    } else {
77b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // Front camera needs to be horizontally flipped for mirror-like behavior.
78b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // Note: Flips are applied before rotates; using XOR here as some of these flags are
79b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk        // composed in terms of other flip/rotation flags, and are not bitwise-ORable.
805698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        switch (orientation) {
815698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 0:
820ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
835698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
845698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 90:
85b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
860ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_270;
875698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
885698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 180:
89b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
900ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_180;
915698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
925698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            case 270:
93b3afa1e3c2af242e0d31a7619713b170d43c7e88Ruben Brunk                flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
940ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala                        NATIVE_WINDOW_TRANSFORM_ROT_90;
950ccba97ebec0e0c5a20f8859ebac03d5fd14c97fEino-Ville Talvala
965698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                break;
975698d4461a260dbf208484383f692b03c6473e74Ruben Brunk            default:
985698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
995698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                      __FUNCTION__, orientation);
1005698d4461a260dbf208484383f692b03c6473e74Ruben Brunk                return INVALID_OPERATION;
1015698d4461a260dbf208484383f692b03c6473e74Ruben Brunk        }
1025698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1035698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    }
1045698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1055698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    /**
1065698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * This magic flag makes surfaceflinger un-rotate the buffers
1075698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * to counter the extra global device UI rotation whenever the user
1085698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * physically rotates the device.
1095698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     *
1105698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * By doing this, the camera buffer always ends up aligned
1115698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * with the physical camera for a "see through" effect.
1125698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     *
1135698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * In essence, the buffer only gets rotated during preview use-cases.
1145698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * The user is still responsible to re-create streams of the proper
1155698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * aspect ratio, or the preview will end up looking non-uniformly
1165698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     * stretched.
1175698d4461a260dbf208484383f692b03c6473e74Ruben Brunk     */
1185698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    flags |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
1195698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1205698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    ALOGV("%s: final transform = 0x%x", __FUNCTION__, flags);
1215698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1225698d4461a260dbf208484383f692b03c6473e74Ruben Brunk    return OK;
1235698d4461a260dbf208484383f692b03c6473e74Ruben Brunk}
1245698d4461a260dbf208484383f692b03c6473e74Ruben Brunk
1255698d4461a260dbf208484383f692b03c6473e74Ruben Brunk} /* namespace android */
126