From c94cd19694ea0befe2eb22735c50b00070f006d9 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Fri, 15 Jun 2012 12:47:42 -0700 Subject: Camera2: Handle preview orientation changes. - Process sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION) Bug: 6243944 Change-Id: I92d3bb13312d475703325230487d660a1cb7e0e5 --- services/camera/libcameraservice/Camera2Client.cpp | 54 ++++++++++++++++++++++ services/camera/libcameraservice/Camera2Client.h | 3 ++ services/camera/libcameraservice/Camera2Device.cpp | 40 ++++++++++++++-- services/camera/libcameraservice/Camera2Device.h | 7 +++ 4 files changed, 101 insertions(+), 3 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index 37f1220..c90f81a 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -1208,6 +1208,29 @@ String8 Camera2Client::getParameters() const { status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { ATRACE_CALL(); Mutex::Autolock icl(mICameraLock); + + ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId, + cmd, arg1, arg2); + + if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) { + int transform = degToTransform(arg1, + mCameraFacing == CAMERA_FACING_FRONT); + if (transform == -1) { + ALOGE("%s: Camera %d: Error setting %d as display orientation value", + __FUNCTION__, mCameraId, arg1); + return BAD_VALUE; + } + if (transform != mParameters.previewTransform && + mPreviewStreamId != NO_STREAM) { + mDevice->setStreamTransform(mPreviewStreamId, transform); + } + mParameters.previewTransform = transform; + return OK; + } + + ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__, + mCameraId, cmd, arg1, arg2); + return OK; } @@ -1373,6 +1396,9 @@ status_t Camera2Client::buildDefaultParameters() { params.set(CameraParameters::KEY_PREVIEW_FORMAT, formatEnumToString(mParameters.previewFormat)); // NV21 + mParameters.previewTransform = degToTransform(0, + mCameraFacing == CAMERA_FACING_FRONT); + camera_metadata_entry_t availableFormats = staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS); @@ -2045,6 +2071,14 @@ status_t Camera2Client::updatePreviewStream() { } } + res = mDevice->setStreamTransform(mPreviewStreamId, + mParameters.previewTransform); + if (res != OK) { + ALOGE("%s: Camera %d: Unable to set preview stream transform: " + "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); + return res; + } + return OK; } @@ -2672,5 +2706,25 @@ bool Camera2Client::boolFromString(const char *boolStr) { false; } +int Camera2Client::degToTransform(int degrees, bool mirror) { + if (!mirror) { + if (degrees == 0) return 0; + else if (degrees == 90) return HAL_TRANSFORM_ROT_90; + else if (degrees == 180) return HAL_TRANSFORM_ROT_180; + else if (degrees == 270) return HAL_TRANSFORM_ROT_270; + } else { // Do mirror (horizontal flip) + if (degrees == 0) { // FLIP_H and ROT_0 + return HAL_TRANSFORM_FLIP_H; + } else if (degrees == 90) { // FLIP_H and ROT_90 + return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90; + } else if (degrees == 180) { // FLIP_H and ROT_180 + return HAL_TRANSFORM_FLIP_V; + } else if (degrees == 270) { // FLIP_H and ROT_270 + return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90; + } + } + ALOGE("%s: Bad input: %d", __FUNCTION__, degrees); + return -1; +} } // namespace android diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h index 776f981..2dc02bc 100644 --- a/services/camera/libcameraservice/Camera2Client.h +++ b/services/camera/libcameraservice/Camera2Client.h @@ -259,6 +259,9 @@ private: static status_t validateAreas(const Vector &areas, size_t maxRegions); static bool boolFromString(const char *boolStr); + + // Map from camera orientation + facing to gralloc transform enum + static int degToTransform(int degrees, bool mirror); }; }; // namespace android diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp index 08e3cc0..4761263 100644 --- a/services/camera/libcameraservice/Camera2Device.cpp +++ b/services/camera/libcameraservice/Camera2Device.cpp @@ -205,6 +205,27 @@ status_t Camera2Device::getStreamInfo(int id, return OK; } +status_t Camera2Device::setStreamTransform(int id, + int transform) { + ALOGV("%s: E", __FUNCTION__); + bool found = false; + StreamList::iterator streamI; + for (streamI = mStreams.begin(); + streamI != mStreams.end(); streamI++) { + if ((*streamI)->getId() == id) { + found = true; + break; + } + } + if (!found) { + ALOGE("%s: Camera %d: Stream %d does not exist", + __FUNCTION__, mId, id); + return BAD_VALUE; + } + + return (*streamI)->setTransform(transform); +} + status_t Camera2Device::deleteStream(int id) { ALOGV("%s: E", __FUNCTION__); bool found = false; @@ -674,10 +695,8 @@ status_t Camera2Device::StreamAdapter::connectToDevice( return res; } - res = native_window_set_buffers_transform(mConsumerInterface.get(), 0); + res = setTransform(0); if (res != OK) { - ALOGE("%s: Unable to configure stream transform: %s (%d)", - __FUNCTION__, strerror(-res), res); return res; } @@ -802,6 +821,21 @@ status_t Camera2Device::StreamAdapter::disconnect() { return OK; } +status_t Camera2Device::StreamAdapter::setTransform(int transform) { + status_t res; + if (mState < CONNECTED) { + ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__); + return INVALID_OPERATION; + } + res = native_window_set_buffers_transform(mConsumerInterface.get(), + transform); + if (res != OK) { + ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", + __FUNCTION__, transform, strerror(-res), res); + } + return res; +} + status_t Camera2Device::StreamAdapter::dump(int fd, const Vector& args) { String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n", diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h index 569c882..1116be0 100644 --- a/services/camera/libcameraservice/Camera2Device.h +++ b/services/camera/libcameraservice/Camera2Device.h @@ -78,6 +78,11 @@ class Camera2Device : public virtual RefBase { uint32_t *width, uint32_t *height, uint32_t *format); /** + * Set stream gralloc buffer transform + */ + status_t setStreamTransform(int id, int transform); + + /** * Delete stream. Must not be called if there are requests in flight which * reference that stream. */ @@ -216,6 +221,8 @@ class Camera2Device : public virtual RefBase { status_t disconnect(); + status_t setTransform(int transform); + // Get stream parameters. // Only valid after a successful connectToDevice call. int getId() const { return mId; } -- cgit v1.1