From 031b92f4c7edf17aa6e75e6c4ec3582e0413b744 Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Wed, 23 Nov 2011 11:26:11 -0800 Subject: [PATCH] Pass white balance and exposure compensation to webcam emulator Using fake camera implementation for WB/exposure, implement the same functionality on frames comming from webcam emulator. Note that due to heavy computations that are involved in implementing this, we will do all that math in the emulator application in order to provide a decent performance. Change-Id: Id6c37b472860674c91e6ca37522fc61f497515a3 --- .../emulator/system/camera/EmulatedCamera.cpp | 32 +++++++++++++------ .../system/camera/EmulatedFakeCamera.cpp | 27 ---------------- .../camera/EmulatedFakeCameraDevice.cpp | 11 +++++-- .../camera/EmulatedQemuCameraDevice.cpp | 6 +++- tools/emulator/system/camera/QemuClient.cpp | 11 +++++-- tools/emulator/system/camera/QemuClient.h | 8 ++++- 6 files changed, 52 insertions(+), 43 deletions(-) diff --git a/tools/emulator/system/camera/EmulatedCamera.cpp b/tools/emulator/system/camera/EmulatedCamera.cpp index 25847a4e2..0cdb99cb7 100755 --- a/tools/emulator/system/camera/EmulatedCamera.cpp +++ b/tools/emulator/system/camera/EmulatedCamera.cpp @@ -133,19 +133,33 @@ status_t EmulatedCamera::Initialize() CameraParameters::PIXEL_FORMAT_JPEG); mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG); - /* Sets the default exposure compensation support to be disabled. */ - mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "0"); - mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "0"); + /* Set exposure compensation. */ + mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6"); + mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); - /* Sets auto white balance as default. */ - getCameraDevice()->initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f); + /* Sets the white balance modes and the device-dependent scale factors. */ + char supported_white_balance[1024]; + snprintf(supported_white_balance, sizeof(supported_white_balance), + "%s,%s,%s,%s", + CameraParameters::WHITE_BALANCE_AUTO, + CameraParameters::WHITE_BALANCE_INCANDESCENT, + CameraParameters::WHITE_BALANCE_DAYLIGHT, + CameraParameters::WHITE_BALANCE_TWILIGHT); mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, - CameraParameters::WHITE_BALANCE_AUTO); + supported_white_balance); mParameters.set(CameraParameters::KEY_WHITE_BALANCE, CameraParameters::WHITE_BALANCE_AUTO); - getCameraDevice()->setWhiteBalanceMode( - mParameters.get(CameraParameters::KEY_WHITE_BALANCE)); + getCameraDevice()->initializeWhiteBalanceModes( + CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f); + getCameraDevice()->initializeWhiteBalanceModes( + CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f); + getCameraDevice()->initializeWhiteBalanceModes( + CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f); + getCameraDevice()->initializeWhiteBalanceModes( + CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f); + getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO); /* Not supported features */ diff --git a/tools/emulator/system/camera/EmulatedFakeCamera.cpp b/tools/emulator/system/camera/EmulatedFakeCamera.cpp index beb632917..86b9d08a5 100755 --- a/tools/emulator/system/camera/EmulatedFakeCamera.cpp +++ b/tools/emulator/system/camera/EmulatedFakeCamera.cpp @@ -61,33 +61,6 @@ status_t EmulatedFakeCamera::Initialize() gEmulatedCameraFactory.getFakeCameraOrientation()); res = EmulatedCamera::Initialize(); - - mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6"); - mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6"); - mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5"); - mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); - ALOGV("Set camera supported exposure values"); - - // Sets the white balance modes and the device-dependent scale factors. - mFakeCameraDevice.initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f); - mFakeCameraDevice.initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f); - mFakeCameraDevice.initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f); - - char supported_white_balance[1024]; - snprintf(supported_white_balance, sizeof(supported_white_balance), - "%s,%s,%s,%s", - mParameters.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE), - CameraParameters::WHITE_BALANCE_INCANDESCENT, - CameraParameters::WHITE_BALANCE_DAYLIGHT, - CameraParameters::WHITE_BALANCE_TWILIGHT); - mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, - supported_white_balance); - - ALOGV("Set camera supported white balance modes"); - if (res != NO_ERROR) { return res; } diff --git a/tools/emulator/system/camera/EmulatedFakeCameraDevice.cpp b/tools/emulator/system/camera/EmulatedFakeCameraDevice.cpp index 051c28aa6..fdc0dbe59 100755 --- a/tools/emulator/system/camera/EmulatedFakeCameraDevice.cpp +++ b/tools/emulator/system/camera/EmulatedFakeCameraDevice.cpp @@ -312,6 +312,9 @@ void EmulatedFakeCameraDevice::drawSquare(int x, const int square_ystop = min(mFrameHeight, y + size); uint8_t* Y_pos = mCurrentFrame + y * mFrameWidth + x; + YUVPixel adjustedColor = *color; + changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); + // Draw the square. for (; y < square_ystop; y++) { const int iUV = (y / 2) * mUVInRow + (x / 2) * mUVStep; @@ -319,7 +322,7 @@ void EmulatedFakeCameraDevice::drawSquare(int x, uint8_t* sqV = mFrameV + iUV; uint8_t* sqY = Y_pos; for (int i = x; i < square_xstop; i += 2) { - color->get(sqY, sqU, sqV); + adjustedColor.get(sqY, sqU, sqV); *sqY = changeExposure(*sqY); sqY[1] = *sqY; sqY += 2; sqU += mUVStep; sqV += mUVStep; @@ -332,8 +335,11 @@ void EmulatedFakeCameraDevice::drawSquare(int x, void EmulatedFakeCameraDevice::drawSolid(YUVPixel* color) { + YUVPixel adjustedColor = *color; + changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); + /* All Ys are the same. */ - memset(mCurrentFrame, changeExposure(color->Y), mTotalPixels); + memset(mCurrentFrame, changeExposure(adjustedColor.Y), mTotalPixels); /* Fill U, and V panes. */ uint8_t* U = mFrameU; @@ -367,6 +373,7 @@ void EmulatedFakeCameraDevice::drawStripes() /* And the blue stripe at the bottom. */ color = &mBlueYUV; } + changeWhiteBalance(color->Y, color->U, color->V); /* All Ys at the row are the same. */ memset(pY, changeExposure(color->Y), mFrameWidth); diff --git a/tools/emulator/system/camera/EmulatedQemuCameraDevice.cpp b/tools/emulator/system/camera/EmulatedQemuCameraDevice.cpp index d95307db9..9c279a289 100755 --- a/tools/emulator/system/camera/EmulatedQemuCameraDevice.cpp +++ b/tools/emulator/system/camera/EmulatedQemuCameraDevice.cpp @@ -244,7 +244,11 @@ bool EmulatedQemuCameraDevice::inWorkerThread() /* Query frames from the service. */ status_t query_res = mQemuClient.queryFrame(mCurrentFrame, mPreviewFrame, mFrameBufferSize, - mTotalPixels * 4); + mTotalPixels * 4, + mWhiteBalanceScale[0], + mWhiteBalanceScale[1], + mWhiteBalanceScale[2], + mExposureCompensation); if (query_res == NO_ERROR) { /* Timestamp the current frame, and notify the camera HAL. */ mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); diff --git a/tools/emulator/system/camera/QemuClient.cpp b/tools/emulator/system/camera/QemuClient.cpp index fe761b08d..4e1d12a03 100755 --- a/tools/emulator/system/camera/QemuClient.cpp +++ b/tools/emulator/system/camera/QemuClient.cpp @@ -503,14 +503,19 @@ status_t CameraQemuClient::queryStop() status_t CameraQemuClient::queryFrame(void* vframe, void* pframe, size_t vframe_size, - size_t pframe_size) + size_t pframe_size, + float r_scale, + float g_scale, + float b_scale, + float exposure_comp) { ALOGV("%s", __FUNCTION__); char query_str[256]; - snprintf(query_str, sizeof(query_str), "%s video=%d preview=%d", + snprintf(query_str, sizeof(query_str), "%s video=%d preview=%d whiteb=%g,%g,%g expcomp=%g", mQueryFrame, (vframe && vframe_size) ? vframe_size : 0, - (pframe && pframe_size) ? pframe_size : 0); + (pframe && pframe_size) ? pframe_size : 0, r_scale, g_scale, b_scale, + exposure_comp); QemuQuery query(query_str); doQuery(&query); const status_t res = query.getCompletionStatus(); diff --git a/tools/emulator/system/camera/QemuClient.h b/tools/emulator/system/camera/QemuClient.h index c0b8e618a..16443211f 100755 --- a/tools/emulator/system/camera/QemuClient.h +++ b/tools/emulator/system/camera/QemuClient.h @@ -401,13 +401,19 @@ public: * pframe, pframe_size - Define buffer, allocated to receive a preview frame. * Any of these parameters can be 0, indicating that the caller is * interested only in video frame. + * r_scale, g_scale, b_scale - White balance scale. + * exposure_comp - Expsoure compensation. * Return: * NO_ERROR on success, or an appropriate error status on failure. */ status_t queryFrame(void* vframe, void* pframe, size_t vframe_size, - size_t pframe_size); + size_t pframe_size, + float r_scale, + float g_scale, + float b_scale, + float exposure_comp); /**************************************************************************** * Names of the queries available for the emulated camera.