Merge "Mirror the preview for front-facing cameras. do not merge" into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
0c63605535
@ -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
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user