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
This commit is contained in:
Vladimir Chtchetkine
2011-11-23 11:26:11 -08:00
parent 629fb72e6f
commit 031b92f4c7
6 changed files with 52 additions and 43 deletions

View File

@@ -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
*/

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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.