summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu-cheng Li <wuchengli@google.com>2010-10-14 20:17:44 +0800
committerWu-cheng Li <wuchengli@google.com>2010-10-25 15:02:44 +0800
commite09591eff55fdff1868b32c3e046c62f800330fc (patch)
treea426ffeb610452b7020a7805f7a8a729b36f5b17
parent9065ce6207730f55566eb3b78f9b487b1a4502b6 (diff)
downloadframeworks_av-e09591eff55fdff1868b32c3e046c62f800330fc.zip
frameworks_av-e09591eff55fdff1868b32c3e046c62f800330fc.tar.gz
frameworks_av-e09591eff55fdff1868b32c3e046c62f800330fc.tar.bz2
Mirror the camera preview if the camera is front-facing.
bug:3095272 Change-Id: Ib1c1d1edc06a33e9d4d2dcb42bc1dd2c25b1310c
-rw-r--r--include/camera/Camera.h12
-rw-r--r--services/camera/libcameraservice/CameraService.cpp61
-rw-r--r--services/camera/libcameraservice/CameraService.h4
3 files changed, 50 insertions, 27 deletions
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 171a3b6..8d8edd6 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -81,6 +81,18 @@ enum {
enum {
CAMERA_CMD_START_SMOOTH_ZOOM = 1,
CAMERA_CMD_STOP_SMOOTH_ZOOM = 2,
+ // Set the clockwise rotation of preview display (setPreviewDisplay) in
+ // degrees. This affects the preview frames and the picture displayed after
+ // snapshot. This method is useful for portrait mode applications. Note that
+ // preview display of front-facing cameras is flipped horizontally before
+ // the rotation, that is, the image is reflected along the central vertical
+ // axis of the camera sensor. So the users can see themselves as looking
+ // into a mirror.
+ //
+ // This does not affect the order of byte array of CAMERA_MSG_PREVIEW_FRAME,
+ // CAMERA_MSG_VIDEO_FRAME, CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE,
+ // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during
+ // preview.
CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
// cmdType to disable/enable shutter sound.
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2bfdc29..535f07f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -151,7 +151,10 @@ sp<ICamera> CameraService::connect(
LOGE("Fail to open camera hardware (id=%d)", cameraId);
return NULL;
}
- client = new Client(this, cameraClient, hardware, cameraId, callingPid);
+ CameraInfo info;
+ HAL_getCameraInfo(cameraId, &info);
+ client = new Client(this, cameraClient, hardware, cameraId, info.facing,
+ callingPid);
mClient[cameraId] = client;
LOG1("CameraService::connect X");
return client;
@@ -293,7 +296,7 @@ void CameraService::playSound(sound_kind kind) {
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware,
- int cameraId, int clientPid) {
+ int cameraId, int cameraFacing, int clientPid) {
int callingPid = getCallingPid();
LOG1("Client::Client E (pid %d)", callingPid);
@@ -301,6 +304,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
mCameraClient = cameraClient;
mHardware = hardware;
mCameraId = cameraId;
+ mCameraFacing = cameraFacing;
mClientPid = clientPid;
mUseOverlay = mHardware->useOverlay();
mMsgEnabled = 0;
@@ -318,8 +322,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
// Callback is disabled by default
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
- mOrientation = 0;
- mPreviewWindowFlag = 0;
+ mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mOrientationChanged = false;
mPlayShutterSound = true;
cameraService->setCameraBusy(cameraId);
@@ -509,7 +512,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
result = setOverlay();
} else if (mPreviewWindow != 0) {
native_window_set_buffers_transform(mPreviewWindow.get(),
- mPreviewWindowFlag);
+ mOrientation);
result = mHardware->setPreviewWindow(mPreviewWindow);
}
}
@@ -637,7 +640,7 @@ status_t CameraService::Client::startPreviewMode() {
} else {
if (mPreviewWindow != 0) {
native_window_set_buffers_transform(mPreviewWindow.get(),
- mPreviewWindowFlag);
+ mOrientation);
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
@@ -844,26 +847,10 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a
if (mHardware->previewEnabled()) {
return INVALID_OPERATION;
}
- switch (arg1) {
- case 0:
- orientation = ISurface::BufferHeap::ROT_0;
- mPreviewWindowFlag = 0;
- break;
- case 90:
- orientation = ISurface::BufferHeap::ROT_90;
- mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_90;
- break;
- case 180:
- orientation = ISurface::BufferHeap::ROT_180;
- mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_180;
- break;
- case 270:
- orientation = ISurface::BufferHeap::ROT_270;
- mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_270;
- break;
- default:
- return BAD_VALUE;
- }
+ // Mirror the preview if the camera is front-facing.
+ orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
+ if (orientation == -1) return BAD_VALUE;
+
if (mOrientation != orientation) {
mOrientation = orientation;
if (mOverlayRef != 0) mOrientationChanged = true;
@@ -1226,6 +1213,28 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(
client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
}
+int CameraService::Client::getOrientation(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;
+ }
+ }
+ LOGE("Invalid setDisplayOrientation degrees=%d", degrees);
+ return -1;
+}
+
+
// ----------------------------------------------------------------------------
static const int kDumpLockRetries = 50;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b5b85bc..60e0d04 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -117,6 +117,7 @@ private:
const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware,
int cameraId,
+ int cameraFacing,
int clientPid);
~Client();
@@ -165,6 +166,8 @@ private:
const sp<IMemoryHeap>& heap,
size_t offset, size_t size);
+ int getOrientation(int orientation, bool mirror);
+
// these are initialized in the constructor.
sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient;
@@ -180,7 +183,6 @@ private:
int mOrientation; // Current display orientation
// True if display orientation has been changed. This is only used in overlay.
int mOrientationChanged;
- int mPreviewWindowFlag;
bool mPlayShutterSound;
// Ensures atomicity among the public methods