Merge "Mirror the preview for front-facing cameras. do not merge" into gingerbread

This commit is contained in:
Mathias Agopian
2010-10-21 16:20:07 -07:00
committed by Android (Google) Code Review
4 changed files with 58 additions and 22 deletions

View File

@ -779,9 +779,9 @@ public class Camera {
* Set the clockwise rotation of preview display in degrees. This affects * Set the clockwise rotation of preview display in degrees. This affects
* the preview frames and the picture displayed after snapshot. This method * the preview frames and the picture displayed after snapshot. This method
* is useful for portrait mode applications. Note that preview display of * is useful for portrait mode applications. Note that preview display of
* front-facing cameras is flipped horizontally, that is, the image is * front-facing cameras is flipped horizontally before the rotation, that
* reflected along the central vertical axis of the camera sensor. So the * is, the image is reflected along the central vertical axis of the camera
* users can see themselves as looking into a mirror. * sensor. So the users can see themselves as looking into a mirror.
* *
* This does not affect the order of byte array passed in {@link * This does not affect the order of byte array passed in {@link
* PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This * PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This

View File

@ -83,6 +83,18 @@ enum {
enum { enum {
CAMERA_CMD_START_SMOOTH_ZOOM = 1, CAMERA_CMD_START_SMOOTH_ZOOM = 1,
CAMERA_CMD_STOP_SMOOTH_ZOOM = 2, 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, CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
}; };

View File

@ -150,7 +150,10 @@ sp<ICamera> CameraService::connect(
LOGE("Fail to open camera hardware (id=%d)", cameraId); LOGE("Fail to open camera hardware (id=%d)", cameraId);
return NULL; 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,
info.orientation, callingPid);
mClient[cameraId] = client; mClient[cameraId] = client;
LOG1("CameraService::connect X"); LOG1("CameraService::connect X");
return client; return client;
@ -292,7 +295,7 @@ void CameraService::playSound(sound_kind kind) {
CameraService::Client::Client(const sp<CameraService>& cameraService, CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient, const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware, const sp<CameraHardwareInterface>& hardware,
int cameraId, int clientPid) { int cameraId, int cameraFacing, int cameraOrientation, int clientPid) {
int callingPid = getCallingPid(); int callingPid = getCallingPid();
LOG1("Client::Client E (pid %d)", callingPid); LOG1("Client::Client E (pid %d)", callingPid);
@ -300,6 +303,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
mCameraClient = cameraClient; mCameraClient = cameraClient;
mHardware = hardware; mHardware = hardware;
mCameraId = cameraId; mCameraId = cameraId;
mCameraFacing = cameraFacing;
mCameraOrientation = cameraOrientation;
mClientPid = clientPid; mClientPid = clientPid;
mUseOverlay = mHardware->useOverlay(); mUseOverlay = mHardware->useOverlay();
mMsgEnabled = 0; mMsgEnabled = 0;
@ -318,7 +323,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
// Callback is disabled by default // Callback is disabled by default
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
mOrientation = 0; mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
mOrientationChanged = false; mOrientationChanged = false;
cameraService->setCameraBusy(cameraId); cameraService->setCameraBusy(cameraId);
cameraService->loadSound(); cameraService->loadSound();
@ -823,22 +828,10 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a
if (mHardware->previewEnabled()) { if (mHardware->previewEnabled()) {
return INVALID_OPERATION; return INVALID_OPERATION;
} }
switch (arg1) { // Mirror the preview if the camera is front-facing.
case 0: orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
orientation = ISurface::BufferHeap::ROT_0; if (orientation == -1) return BAD_VALUE;
break;
case 90:
orientation = ISurface::BufferHeap::ROT_90;
break;
case 180:
orientation = ISurface::BufferHeap::ROT_180;
break;
case 270:
orientation = ISurface::BufferHeap::ROT_270;
break;
default:
return BAD_VALUE;
}
if (mOrientation != orientation) { if (mOrientation != orientation) {
mOrientation = orientation; mOrientation = orientation;
if (mOverlayRef != 0) mOrientationChanged = true; if (mOverlayRef != 0) mOrientationChanged = true;
@ -1204,6 +1197,31 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(
client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); 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 { // mirror (horizontal flip)
// Now overlay does ROT_90 before FLIP_V or FLIP_H. It should be FLIP_V
// or FLIP_H first.
// TODO: change this after overlay is fixed.
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_ROT_90 | HAL_TRANSFORM_FLIP_V;
} 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_ROT_90 | HAL_TRANSFORM_FLIP_H;
}
}
LOGE("Invalid setDisplayOrientation degrees=%d", degrees);
return -1;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static const int kDumpLockRetries = 50; static const int kDumpLockRetries = 50;

View File

@ -108,6 +108,8 @@ private:
const sp<ICameraClient>& cameraClient, const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware, const sp<CameraHardwareInterface>& hardware,
int cameraId, int cameraId,
int cameraFacing,
int mCameraOrientation,
int clientPid); int clientPid);
~Client(); ~Client();
@ -153,10 +155,14 @@ private:
const sp<IMemoryHeap>& heap, const sp<IMemoryHeap>& heap,
size_t offset, size_t size); size_t offset, size_t size);
int getOrientation(int orientation, bool mirror);
// these are initialized in the constructor. // these are initialized in the constructor.
sp<CameraService> mCameraService; // immutable after constructor sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient; sp<ICameraClient> mCameraClient;
int mCameraId; // immutable after constructor int mCameraId; // immutable after constructor
int mCameraFacing; // immutable after constructor
int mCameraOrientation; // immutable after constructor
pid_t mClientPid; pid_t mClientPid;
sp<CameraHardwareInterface> mHardware; // cleared after disconnect() sp<CameraHardwareInterface> mHardware; // cleared after disconnect()
bool mUseOverlay; // immutable after constructor bool mUseOverlay; // immutable after constructor