18a94683196406b83b14218d1beef66067f126a16keunyoung/* 28a94683196406b83b14218d1beef66067f126a16keunyoung * Copyright (C) 2011 The Android Open Source Project 38a94683196406b83b14218d1beef66067f126a16keunyoung * 48a94683196406b83b14218d1beef66067f126a16keunyoung * Licensed under the Apache License, Version 2.0 (the "License"); 58a94683196406b83b14218d1beef66067f126a16keunyoung * you may not use this file except in compliance with the License. 68a94683196406b83b14218d1beef66067f126a16keunyoung * You may obtain a copy of the License at 78a94683196406b83b14218d1beef66067f126a16keunyoung * 88a94683196406b83b14218d1beef66067f126a16keunyoung * http://www.apache.org/licenses/LICENSE-2.0 98a94683196406b83b14218d1beef66067f126a16keunyoung * 108a94683196406b83b14218d1beef66067f126a16keunyoung * Unless required by applicable law or agreed to in writing, software 118a94683196406b83b14218d1beef66067f126a16keunyoung * distributed under the License is distributed on an "AS IS" BASIS, 128a94683196406b83b14218d1beef66067f126a16keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a94683196406b83b14218d1beef66067f126a16keunyoung * See the License for the specific language governing permissions and 148a94683196406b83b14218d1beef66067f126a16keunyoung * limitations under the License. 158a94683196406b83b14218d1beef66067f126a16keunyoung */ 168a94683196406b83b14218d1beef66067f126a16keunyoung 178a94683196406b83b14218d1beef66067f126a16keunyoung/* 188a94683196406b83b14218d1beef66067f126a16keunyoung * Contains implementation of a class EmulatedFakeCameraDevice that encapsulates 198a94683196406b83b14218d1beef66067f126a16keunyoung * fake camera device. 208a94683196406b83b14218d1beef66067f126a16keunyoung */ 218a94683196406b83b14218d1beef66067f126a16keunyoung 228a94683196406b83b14218d1beef66067f126a16keunyoung#define LOG_NDEBUG 0 238a94683196406b83b14218d1beef66067f126a16keunyoung#define LOG_TAG "EmulatedCamera_FakeDevice" 248a94683196406b83b14218d1beef66067f126a16keunyoung#include <cutils/log.h> 258a94683196406b83b14218d1beef66067f126a16keunyoung#include "EmulatedFakeCamera.h" 268a94683196406b83b14218d1beef66067f126a16keunyoung#include "EmulatedFakeCameraDevice.h" 278a94683196406b83b14218d1beef66067f126a16keunyoung 288a94683196406b83b14218d1beef66067f126a16keunyoungnamespace android { 298a94683196406b83b14218d1beef66067f126a16keunyoung 308a94683196406b83b14218d1beef66067f126a16keunyoungEmulatedFakeCameraDevice::EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_hal) 318a94683196406b83b14218d1beef66067f126a16keunyoung : EmulatedCameraDevice(camera_hal), 328a94683196406b83b14218d1beef66067f126a16keunyoung mBlackYUV(kBlack32), 338a94683196406b83b14218d1beef66067f126a16keunyoung mWhiteYUV(kWhite32), 348a94683196406b83b14218d1beef66067f126a16keunyoung mRedYUV(kRed8), 358a94683196406b83b14218d1beef66067f126a16keunyoung mGreenYUV(kGreen8), 368a94683196406b83b14218d1beef66067f126a16keunyoung mBlueYUV(kBlue8), 378a94683196406b83b14218d1beef66067f126a16keunyoung mLastRedrawn(0), 388a94683196406b83b14218d1beef66067f126a16keunyoung mCheckX(0), 398a94683196406b83b14218d1beef66067f126a16keunyoung mCheckY(0), 408a94683196406b83b14218d1beef66067f126a16keunyoung mCcounter(0) 418a94683196406b83b14218d1beef66067f126a16keunyoung#if EFCD_ROTATE_FRAME 428a94683196406b83b14218d1beef66067f126a16keunyoung , mLastRotatedAt(0), 438a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentFrameType(0), 448a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentColor(&mWhiteYUV) 458a94683196406b83b14218d1beef66067f126a16keunyoung#endif // EFCD_ROTATE_FRAME 468a94683196406b83b14218d1beef66067f126a16keunyoung{ 478a94683196406b83b14218d1beef66067f126a16keunyoung // Makes the image with the original exposure compensation darker. 488a94683196406b83b14218d1beef66067f126a16keunyoung // So the effects of changing the exposure compensation can be seen. 498a94683196406b83b14218d1beef66067f126a16keunyoung mBlackYUV.Y = mBlackYUV.Y / 2; 508a94683196406b83b14218d1beef66067f126a16keunyoung mWhiteYUV.Y = mWhiteYUV.Y / 2; 518a94683196406b83b14218d1beef66067f126a16keunyoung mRedYUV.Y = mRedYUV.Y / 2; 528a94683196406b83b14218d1beef66067f126a16keunyoung mGreenYUV.Y = mGreenYUV.Y / 2; 538a94683196406b83b14218d1beef66067f126a16keunyoung mBlueYUV.Y = mBlueYUV.Y / 2; 548a94683196406b83b14218d1beef66067f126a16keunyoung} 558a94683196406b83b14218d1beef66067f126a16keunyoung 568a94683196406b83b14218d1beef66067f126a16keunyoungEmulatedFakeCameraDevice::~EmulatedFakeCameraDevice() 578a94683196406b83b14218d1beef66067f126a16keunyoung{ 588a94683196406b83b14218d1beef66067f126a16keunyoung} 598a94683196406b83b14218d1beef66067f126a16keunyoung 608a94683196406b83b14218d1beef66067f126a16keunyoung/**************************************************************************** 618a94683196406b83b14218d1beef66067f126a16keunyoung * Emulated camera device abstract interface implementation. 628a94683196406b83b14218d1beef66067f126a16keunyoung ***************************************************************************/ 638a94683196406b83b14218d1beef66067f126a16keunyoung 648a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t EmulatedFakeCameraDevice::connectDevice() 658a94683196406b83b14218d1beef66067f126a16keunyoung{ 668a94683196406b83b14218d1beef66067f126a16keunyoung ALOGV("%s", __FUNCTION__); 678a94683196406b83b14218d1beef66067f126a16keunyoung 688a94683196406b83b14218d1beef66067f126a16keunyoung Mutex::Autolock locker(&mObjectLock); 698a94683196406b83b14218d1beef66067f126a16keunyoung if (!isInitialized()) { 708a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: Fake camera device is not initialized.", __FUNCTION__); 718a94683196406b83b14218d1beef66067f126a16keunyoung return EINVAL; 728a94683196406b83b14218d1beef66067f126a16keunyoung } 738a94683196406b83b14218d1beef66067f126a16keunyoung if (isConnected()) { 748a94683196406b83b14218d1beef66067f126a16keunyoung ALOGW("%s: Fake camera device is already connected.", __FUNCTION__); 758a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 768a94683196406b83b14218d1beef66067f126a16keunyoung } 778a94683196406b83b14218d1beef66067f126a16keunyoung 788a94683196406b83b14218d1beef66067f126a16keunyoung /* There is no device to connect to. */ 798a94683196406b83b14218d1beef66067f126a16keunyoung mState = ECDS_CONNECTED; 808a94683196406b83b14218d1beef66067f126a16keunyoung 818a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 828a94683196406b83b14218d1beef66067f126a16keunyoung} 838a94683196406b83b14218d1beef66067f126a16keunyoung 848a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t EmulatedFakeCameraDevice::disconnectDevice() 858a94683196406b83b14218d1beef66067f126a16keunyoung{ 868a94683196406b83b14218d1beef66067f126a16keunyoung ALOGV("%s", __FUNCTION__); 878a94683196406b83b14218d1beef66067f126a16keunyoung 888a94683196406b83b14218d1beef66067f126a16keunyoung Mutex::Autolock locker(&mObjectLock); 898a94683196406b83b14218d1beef66067f126a16keunyoung if (!isConnected()) { 908a94683196406b83b14218d1beef66067f126a16keunyoung ALOGW("%s: Fake camera device is already disconnected.", __FUNCTION__); 918a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 928a94683196406b83b14218d1beef66067f126a16keunyoung } 938a94683196406b83b14218d1beef66067f126a16keunyoung if (isStarted()) { 948a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: Cannot disconnect from the started device.", __FUNCTION__); 958a94683196406b83b14218d1beef66067f126a16keunyoung return EINVAL; 968a94683196406b83b14218d1beef66067f126a16keunyoung } 978a94683196406b83b14218d1beef66067f126a16keunyoung 988a94683196406b83b14218d1beef66067f126a16keunyoung /* There is no device to disconnect from. */ 998a94683196406b83b14218d1beef66067f126a16keunyoung mState = ECDS_INITIALIZED; 1008a94683196406b83b14218d1beef66067f126a16keunyoung 1018a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 1028a94683196406b83b14218d1beef66067f126a16keunyoung} 1038a94683196406b83b14218d1beef66067f126a16keunyoung 1048a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t EmulatedFakeCameraDevice::startDevice(int width, 1058a94683196406b83b14218d1beef66067f126a16keunyoung int height, 1068a94683196406b83b14218d1beef66067f126a16keunyoung uint32_t pix_fmt) 1078a94683196406b83b14218d1beef66067f126a16keunyoung{ 1088a94683196406b83b14218d1beef66067f126a16keunyoung ALOGV("%s", __FUNCTION__); 1098a94683196406b83b14218d1beef66067f126a16keunyoung 1108a94683196406b83b14218d1beef66067f126a16keunyoung Mutex::Autolock locker(&mObjectLock); 1118a94683196406b83b14218d1beef66067f126a16keunyoung if (!isConnected()) { 1128a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: Fake camera device is not connected.", __FUNCTION__); 1138a94683196406b83b14218d1beef66067f126a16keunyoung return EINVAL; 1148a94683196406b83b14218d1beef66067f126a16keunyoung } 1158a94683196406b83b14218d1beef66067f126a16keunyoung if (isStarted()) { 1168a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: Fake camera device is already started.", __FUNCTION__); 1178a94683196406b83b14218d1beef66067f126a16keunyoung return EINVAL; 1188a94683196406b83b14218d1beef66067f126a16keunyoung } 1198a94683196406b83b14218d1beef66067f126a16keunyoung 1208a94683196406b83b14218d1beef66067f126a16keunyoung /* Initialize the base class. */ 1218a94683196406b83b14218d1beef66067f126a16keunyoung const status_t res = 1228a94683196406b83b14218d1beef66067f126a16keunyoung EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt); 1238a94683196406b83b14218d1beef66067f126a16keunyoung if (res == NO_ERROR) { 1248a94683196406b83b14218d1beef66067f126a16keunyoung /* Calculate U/V panes inside the framebuffer. */ 1258a94683196406b83b14218d1beef66067f126a16keunyoung switch (mPixelFormat) { 1268a94683196406b83b14218d1beef66067f126a16keunyoung case V4L2_PIX_FMT_YVU420: 1278a94683196406b83b14218d1beef66067f126a16keunyoung mFrameV = mCurrentFrame + mTotalPixels; 1288a94683196406b83b14218d1beef66067f126a16keunyoung mFrameU = mFrameU + mTotalPixels / 4; 1298a94683196406b83b14218d1beef66067f126a16keunyoung mUVStep = 1; 1308a94683196406b83b14218d1beef66067f126a16keunyoung mUVTotalNum = mTotalPixels / 4; 1318a94683196406b83b14218d1beef66067f126a16keunyoung break; 1328a94683196406b83b14218d1beef66067f126a16keunyoung 1338a94683196406b83b14218d1beef66067f126a16keunyoung case V4L2_PIX_FMT_YUV420: 1348a94683196406b83b14218d1beef66067f126a16keunyoung mFrameU = mCurrentFrame + mTotalPixels; 1358a94683196406b83b14218d1beef66067f126a16keunyoung mFrameV = mFrameU + mTotalPixels / 4; 1368a94683196406b83b14218d1beef66067f126a16keunyoung mUVStep = 1; 1378a94683196406b83b14218d1beef66067f126a16keunyoung mUVTotalNum = mTotalPixels / 4; 1388a94683196406b83b14218d1beef66067f126a16keunyoung break; 1398a94683196406b83b14218d1beef66067f126a16keunyoung 1408a94683196406b83b14218d1beef66067f126a16keunyoung case V4L2_PIX_FMT_NV21: 1418a94683196406b83b14218d1beef66067f126a16keunyoung /* Interleaved UV pane, V first. */ 1428a94683196406b83b14218d1beef66067f126a16keunyoung mFrameV = mCurrentFrame + mTotalPixels; 1438a94683196406b83b14218d1beef66067f126a16keunyoung mFrameU = mFrameV + 1; 1448a94683196406b83b14218d1beef66067f126a16keunyoung mUVStep = 2; 1458a94683196406b83b14218d1beef66067f126a16keunyoung mUVTotalNum = mTotalPixels / 4; 1468a94683196406b83b14218d1beef66067f126a16keunyoung break; 1478a94683196406b83b14218d1beef66067f126a16keunyoung 1488a94683196406b83b14218d1beef66067f126a16keunyoung case V4L2_PIX_FMT_NV12: 1498a94683196406b83b14218d1beef66067f126a16keunyoung /* Interleaved UV pane, U first. */ 1508a94683196406b83b14218d1beef66067f126a16keunyoung mFrameU = mCurrentFrame + mTotalPixels; 1518a94683196406b83b14218d1beef66067f126a16keunyoung mFrameV = mFrameU + 1; 1528a94683196406b83b14218d1beef66067f126a16keunyoung mUVStep = 2; 1538a94683196406b83b14218d1beef66067f126a16keunyoung mUVTotalNum = mTotalPixels / 4; 1548a94683196406b83b14218d1beef66067f126a16keunyoung break; 1558a94683196406b83b14218d1beef66067f126a16keunyoung 1568a94683196406b83b14218d1beef66067f126a16keunyoung default: 1578a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__, 1588a94683196406b83b14218d1beef66067f126a16keunyoung reinterpret_cast<const char*>(&mPixelFormat)); 1598a94683196406b83b14218d1beef66067f126a16keunyoung return EINVAL; 1608a94683196406b83b14218d1beef66067f126a16keunyoung } 1618a94683196406b83b14218d1beef66067f126a16keunyoung /* Number of items in a single row inside U/V panes. */ 1628a94683196406b83b14218d1beef66067f126a16keunyoung mUVInRow = (width / 2) * mUVStep; 1638a94683196406b83b14218d1beef66067f126a16keunyoung mState = ECDS_STARTED; 1648a94683196406b83b14218d1beef66067f126a16keunyoung } else { 1658a94683196406b83b14218d1beef66067f126a16keunyoung ALOGE("%s: commonStartDevice failed", __FUNCTION__); 1668a94683196406b83b14218d1beef66067f126a16keunyoung } 1678a94683196406b83b14218d1beef66067f126a16keunyoung 1688a94683196406b83b14218d1beef66067f126a16keunyoung return res; 1698a94683196406b83b14218d1beef66067f126a16keunyoung} 1708a94683196406b83b14218d1beef66067f126a16keunyoung 1718a94683196406b83b14218d1beef66067f126a16keunyoungstatus_t EmulatedFakeCameraDevice::stopDevice() 1728a94683196406b83b14218d1beef66067f126a16keunyoung{ 1738a94683196406b83b14218d1beef66067f126a16keunyoung ALOGV("%s", __FUNCTION__); 1748a94683196406b83b14218d1beef66067f126a16keunyoung 1758a94683196406b83b14218d1beef66067f126a16keunyoung Mutex::Autolock locker(&mObjectLock); 1768a94683196406b83b14218d1beef66067f126a16keunyoung if (!isStarted()) { 1778a94683196406b83b14218d1beef66067f126a16keunyoung ALOGW("%s: Fake camera device is not started.", __FUNCTION__); 1788a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 1798a94683196406b83b14218d1beef66067f126a16keunyoung } 1808a94683196406b83b14218d1beef66067f126a16keunyoung 1818a94683196406b83b14218d1beef66067f126a16keunyoung mFrameU = mFrameV = NULL; 1828a94683196406b83b14218d1beef66067f126a16keunyoung EmulatedCameraDevice::commonStopDevice(); 1838a94683196406b83b14218d1beef66067f126a16keunyoung mState = ECDS_CONNECTED; 1848a94683196406b83b14218d1beef66067f126a16keunyoung 1858a94683196406b83b14218d1beef66067f126a16keunyoung return NO_ERROR; 1868a94683196406b83b14218d1beef66067f126a16keunyoung} 1878a94683196406b83b14218d1beef66067f126a16keunyoung 1888a94683196406b83b14218d1beef66067f126a16keunyoung/**************************************************************************** 1898a94683196406b83b14218d1beef66067f126a16keunyoung * Worker thread management overrides. 1908a94683196406b83b14218d1beef66067f126a16keunyoung ***************************************************************************/ 1918a94683196406b83b14218d1beef66067f126a16keunyoung 1928a94683196406b83b14218d1beef66067f126a16keunyoungbool EmulatedFakeCameraDevice::inWorkerThread() 1938a94683196406b83b14218d1beef66067f126a16keunyoung{ 1948a94683196406b83b14218d1beef66067f126a16keunyoung /* Wait till FPS timeout expires, or thread exit message is received. */ 1958a94683196406b83b14218d1beef66067f126a16keunyoung WorkerThread::SelectRes res = 1968a94683196406b83b14218d1beef66067f126a16keunyoung getWorkerThread()->Select(-1, 1000000 / mEmulatedFPS); 1978a94683196406b83b14218d1beef66067f126a16keunyoung if (res == WorkerThread::EXIT_THREAD) { 1988a94683196406b83b14218d1beef66067f126a16keunyoung ALOGV("%s: Worker thread has been terminated.", __FUNCTION__); 1998a94683196406b83b14218d1beef66067f126a16keunyoung return false; 2008a94683196406b83b14218d1beef66067f126a16keunyoung } 2018a94683196406b83b14218d1beef66067f126a16keunyoung 2028a94683196406b83b14218d1beef66067f126a16keunyoung /* Lets see if we need to generate a new frame. */ 2038a94683196406b83b14218d1beef66067f126a16keunyoung if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRedrawn) >= mRedrawAfter) { 2048a94683196406b83b14218d1beef66067f126a16keunyoung /* 2058a94683196406b83b14218d1beef66067f126a16keunyoung * Time to generate a new frame. 2068a94683196406b83b14218d1beef66067f126a16keunyoung */ 2078a94683196406b83b14218d1beef66067f126a16keunyoung 2088a94683196406b83b14218d1beef66067f126a16keunyoung#if EFCD_ROTATE_FRAME 2098a94683196406b83b14218d1beef66067f126a16keunyoung const int frame_type = rotateFrame(); 2108a94683196406b83b14218d1beef66067f126a16keunyoung switch (frame_type) { 2118a94683196406b83b14218d1beef66067f126a16keunyoung case 0: 2128a94683196406b83b14218d1beef66067f126a16keunyoung drawCheckerboard(); 2138a94683196406b83b14218d1beef66067f126a16keunyoung break; 2148a94683196406b83b14218d1beef66067f126a16keunyoung case 1: 2158a94683196406b83b14218d1beef66067f126a16keunyoung drawStripes(); 2168a94683196406b83b14218d1beef66067f126a16keunyoung break; 2178a94683196406b83b14218d1beef66067f126a16keunyoung case 2: 2188a94683196406b83b14218d1beef66067f126a16keunyoung drawSolid(mCurrentColor); 2198a94683196406b83b14218d1beef66067f126a16keunyoung break; 2208a94683196406b83b14218d1beef66067f126a16keunyoung } 2218a94683196406b83b14218d1beef66067f126a16keunyoung#else 2228a94683196406b83b14218d1beef66067f126a16keunyoung /* Draw the checker board. */ 2238a94683196406b83b14218d1beef66067f126a16keunyoung drawCheckerboard(); 2248a94683196406b83b14218d1beef66067f126a16keunyoung 2258a94683196406b83b14218d1beef66067f126a16keunyoung#endif // EFCD_ROTATE_FRAME 2268a94683196406b83b14218d1beef66067f126a16keunyoung 2278a94683196406b83b14218d1beef66067f126a16keunyoung mLastRedrawn = systemTime(SYSTEM_TIME_MONOTONIC); 2288a94683196406b83b14218d1beef66067f126a16keunyoung } 2298a94683196406b83b14218d1beef66067f126a16keunyoung 2308a94683196406b83b14218d1beef66067f126a16keunyoung /* Timestamp the current frame, and notify the camera HAL about new frame. */ 2318a94683196406b83b14218d1beef66067f126a16keunyoung mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); 2328a94683196406b83b14218d1beef66067f126a16keunyoung mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this); 2338a94683196406b83b14218d1beef66067f126a16keunyoung 2348a94683196406b83b14218d1beef66067f126a16keunyoung return true; 2358a94683196406b83b14218d1beef66067f126a16keunyoung} 2368a94683196406b83b14218d1beef66067f126a16keunyoung 2378a94683196406b83b14218d1beef66067f126a16keunyoung/**************************************************************************** 2388a94683196406b83b14218d1beef66067f126a16keunyoung * Fake camera device private API 2398a94683196406b83b14218d1beef66067f126a16keunyoung ***************************************************************************/ 2408a94683196406b83b14218d1beef66067f126a16keunyoung 2418a94683196406b83b14218d1beef66067f126a16keunyoungvoid EmulatedFakeCameraDevice::drawCheckerboard() 2428a94683196406b83b14218d1beef66067f126a16keunyoung{ 2438a94683196406b83b14218d1beef66067f126a16keunyoung const int size = mFrameWidth / 10; 2448a94683196406b83b14218d1beef66067f126a16keunyoung bool black = true; 2458a94683196406b83b14218d1beef66067f126a16keunyoung 246b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung if (size == 0) { 247b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung // When this happens, it happens at a very high rate, 248b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung // so don't log any messages and just return. 249b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung return; 250b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung } 251b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung 252b0b6afb44269263afa080ecc643f2c4866adfb38Douglas Leung 2538a94683196406b83b14218d1beef66067f126a16keunyoung if((mCheckX / size) & 1) 2548a94683196406b83b14218d1beef66067f126a16keunyoung black = false; 2558a94683196406b83b14218d1beef66067f126a16keunyoung if((mCheckY / size) & 1) 2568a94683196406b83b14218d1beef66067f126a16keunyoung black = !black; 2578a94683196406b83b14218d1beef66067f126a16keunyoung 2588a94683196406b83b14218d1beef66067f126a16keunyoung int county = mCheckY % size; 2598a94683196406b83b14218d1beef66067f126a16keunyoung int checkxremainder = mCheckX % size; 2608a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* Y = mCurrentFrame; 2618a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* U_pos = mFrameU; 2628a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* V_pos = mFrameV; 2638a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* U = U_pos; 2648a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* V = V_pos; 2658a94683196406b83b14218d1beef66067f126a16keunyoung 2668a94683196406b83b14218d1beef66067f126a16keunyoung YUVPixel adjustedWhite = YUVPixel(mWhiteYUV); 2678a94683196406b83b14218d1beef66067f126a16keunyoung changeWhiteBalance(adjustedWhite.Y, adjustedWhite.U, adjustedWhite.V); 2688a94683196406b83b14218d1beef66067f126a16keunyoung 2698a94683196406b83b14218d1beef66067f126a16keunyoung for(int y = 0; y < mFrameHeight; y++) { 2708a94683196406b83b14218d1beef66067f126a16keunyoung int countx = checkxremainder; 2718a94683196406b83b14218d1beef66067f126a16keunyoung bool current = black; 2728a94683196406b83b14218d1beef66067f126a16keunyoung for(int x = 0; x < mFrameWidth; x += 2) { 2738a94683196406b83b14218d1beef66067f126a16keunyoung if (current) { 2748a94683196406b83b14218d1beef66067f126a16keunyoung mBlackYUV.get(Y, U, V); 2758a94683196406b83b14218d1beef66067f126a16keunyoung } else { 2768a94683196406b83b14218d1beef66067f126a16keunyoung adjustedWhite.get(Y, U, V); 2778a94683196406b83b14218d1beef66067f126a16keunyoung } 2788a94683196406b83b14218d1beef66067f126a16keunyoung *Y = changeExposure(*Y); 2798a94683196406b83b14218d1beef66067f126a16keunyoung Y[1] = *Y; 2808a94683196406b83b14218d1beef66067f126a16keunyoung Y += 2; U += mUVStep; V += mUVStep; 2818a94683196406b83b14218d1beef66067f126a16keunyoung countx += 2; 2828a94683196406b83b14218d1beef66067f126a16keunyoung if(countx >= size) { 2838a94683196406b83b14218d1beef66067f126a16keunyoung countx = 0; 2848a94683196406b83b14218d1beef66067f126a16keunyoung current = !current; 2858a94683196406b83b14218d1beef66067f126a16keunyoung } 2868a94683196406b83b14218d1beef66067f126a16keunyoung } 2878a94683196406b83b14218d1beef66067f126a16keunyoung if (y & 0x1) { 2888a94683196406b83b14218d1beef66067f126a16keunyoung U_pos = U; 2898a94683196406b83b14218d1beef66067f126a16keunyoung V_pos = V; 2908a94683196406b83b14218d1beef66067f126a16keunyoung } else { 2918a94683196406b83b14218d1beef66067f126a16keunyoung U = U_pos; 2928a94683196406b83b14218d1beef66067f126a16keunyoung V = V_pos; 2938a94683196406b83b14218d1beef66067f126a16keunyoung } 2948a94683196406b83b14218d1beef66067f126a16keunyoung if(county++ >= size) { 2958a94683196406b83b14218d1beef66067f126a16keunyoung county = 0; 2968a94683196406b83b14218d1beef66067f126a16keunyoung black = !black; 2978a94683196406b83b14218d1beef66067f126a16keunyoung } 2988a94683196406b83b14218d1beef66067f126a16keunyoung } 2998a94683196406b83b14218d1beef66067f126a16keunyoung mCheckX += 3; 3008a94683196406b83b14218d1beef66067f126a16keunyoung mCheckY++; 3018a94683196406b83b14218d1beef66067f126a16keunyoung 3028a94683196406b83b14218d1beef66067f126a16keunyoung /* Run the square. */ 3038a94683196406b83b14218d1beef66067f126a16keunyoung int sqx = ((mCcounter * 3) & 255); 3048a94683196406b83b14218d1beef66067f126a16keunyoung if(sqx > 128) sqx = 255 - sqx; 3058a94683196406b83b14218d1beef66067f126a16keunyoung int sqy = ((mCcounter * 5) & 255); 3068a94683196406b83b14218d1beef66067f126a16keunyoung if(sqy > 128) sqy = 255 - sqy; 3078a94683196406b83b14218d1beef66067f126a16keunyoung const int sqsize = mFrameWidth / 10; 3088a94683196406b83b14218d1beef66067f126a16keunyoung drawSquare(sqx * sqsize / 32, sqy * sqsize / 32, (sqsize * 5) >> 1, 3098a94683196406b83b14218d1beef66067f126a16keunyoung (mCcounter & 0x100) ? &mRedYUV : &mGreenYUV); 3108a94683196406b83b14218d1beef66067f126a16keunyoung mCcounter++; 3118a94683196406b83b14218d1beef66067f126a16keunyoung} 3128a94683196406b83b14218d1beef66067f126a16keunyoung 3138a94683196406b83b14218d1beef66067f126a16keunyoungvoid EmulatedFakeCameraDevice::drawSquare(int x, 3148a94683196406b83b14218d1beef66067f126a16keunyoung int y, 3158a94683196406b83b14218d1beef66067f126a16keunyoung int size, 3168a94683196406b83b14218d1beef66067f126a16keunyoung const YUVPixel* color) 3178a94683196406b83b14218d1beef66067f126a16keunyoung{ 3188a94683196406b83b14218d1beef66067f126a16keunyoung const int square_xstop = min(mFrameWidth, x + size); 3198a94683196406b83b14218d1beef66067f126a16keunyoung const int square_ystop = min(mFrameHeight, y + size); 3208a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* Y_pos = mCurrentFrame + y * mFrameWidth + x; 3218a94683196406b83b14218d1beef66067f126a16keunyoung 3228a94683196406b83b14218d1beef66067f126a16keunyoung YUVPixel adjustedColor = *color; 3238a94683196406b83b14218d1beef66067f126a16keunyoung changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); 3248a94683196406b83b14218d1beef66067f126a16keunyoung 3258a94683196406b83b14218d1beef66067f126a16keunyoung // Draw the square. 3268a94683196406b83b14218d1beef66067f126a16keunyoung for (; y < square_ystop; y++) { 3278a94683196406b83b14218d1beef66067f126a16keunyoung const int iUV = (y / 2) * mUVInRow + (x / 2) * mUVStep; 3288a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* sqU = mFrameU + iUV; 3298a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* sqV = mFrameV + iUV; 3308a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* sqY = Y_pos; 3318a94683196406b83b14218d1beef66067f126a16keunyoung for (int i = x; i < square_xstop; i += 2) { 3328a94683196406b83b14218d1beef66067f126a16keunyoung adjustedColor.get(sqY, sqU, sqV); 3338a94683196406b83b14218d1beef66067f126a16keunyoung *sqY = changeExposure(*sqY); 3348a94683196406b83b14218d1beef66067f126a16keunyoung sqY[1] = *sqY; 3358a94683196406b83b14218d1beef66067f126a16keunyoung sqY += 2; sqU += mUVStep; sqV += mUVStep; 3368a94683196406b83b14218d1beef66067f126a16keunyoung } 3378a94683196406b83b14218d1beef66067f126a16keunyoung Y_pos += mFrameWidth; 3388a94683196406b83b14218d1beef66067f126a16keunyoung } 3398a94683196406b83b14218d1beef66067f126a16keunyoung} 3408a94683196406b83b14218d1beef66067f126a16keunyoung 3418a94683196406b83b14218d1beef66067f126a16keunyoung#if EFCD_ROTATE_FRAME 3428a94683196406b83b14218d1beef66067f126a16keunyoung 3438a94683196406b83b14218d1beef66067f126a16keunyoungvoid EmulatedFakeCameraDevice::drawSolid(YUVPixel* color) 3448a94683196406b83b14218d1beef66067f126a16keunyoung{ 3458a94683196406b83b14218d1beef66067f126a16keunyoung YUVPixel adjustedColor = *color; 3468a94683196406b83b14218d1beef66067f126a16keunyoung changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); 3478a94683196406b83b14218d1beef66067f126a16keunyoung 3488a94683196406b83b14218d1beef66067f126a16keunyoung /* All Ys are the same. */ 3498a94683196406b83b14218d1beef66067f126a16keunyoung memset(mCurrentFrame, changeExposure(adjustedColor.Y), mTotalPixels); 3508a94683196406b83b14218d1beef66067f126a16keunyoung 3518a94683196406b83b14218d1beef66067f126a16keunyoung /* Fill U, and V panes. */ 3528a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* U = mFrameU; 3538a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* V = mFrameV; 3548a94683196406b83b14218d1beef66067f126a16keunyoung for (int k = 0; k < mUVTotalNum; k++, U += mUVStep, V += mUVStep) { 3558a94683196406b83b14218d1beef66067f126a16keunyoung *U = color->U; 3568a94683196406b83b14218d1beef66067f126a16keunyoung *V = color->V; 3578a94683196406b83b14218d1beef66067f126a16keunyoung } 3588a94683196406b83b14218d1beef66067f126a16keunyoung} 3598a94683196406b83b14218d1beef66067f126a16keunyoung 3608a94683196406b83b14218d1beef66067f126a16keunyoungvoid EmulatedFakeCameraDevice::drawStripes() 3618a94683196406b83b14218d1beef66067f126a16keunyoung{ 3628a94683196406b83b14218d1beef66067f126a16keunyoung /* Divide frame into 4 stripes. */ 3638a94683196406b83b14218d1beef66067f126a16keunyoung const int change_color_at = mFrameHeight / 4; 3648a94683196406b83b14218d1beef66067f126a16keunyoung const int each_in_row = mUVInRow / mUVStep; 3658a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* pY = mCurrentFrame; 3668a94683196406b83b14218d1beef66067f126a16keunyoung for (int y = 0; y < mFrameHeight; y++, pY += mFrameWidth) { 3678a94683196406b83b14218d1beef66067f126a16keunyoung /* Select the color. */ 3688a94683196406b83b14218d1beef66067f126a16keunyoung YUVPixel* color; 3698a94683196406b83b14218d1beef66067f126a16keunyoung const int color_index = y / change_color_at; 3708a94683196406b83b14218d1beef66067f126a16keunyoung if (color_index == 0) { 3718a94683196406b83b14218d1beef66067f126a16keunyoung /* White stripe on top. */ 3728a94683196406b83b14218d1beef66067f126a16keunyoung color = &mWhiteYUV; 3738a94683196406b83b14218d1beef66067f126a16keunyoung } else if (color_index == 1) { 3748a94683196406b83b14218d1beef66067f126a16keunyoung /* Then the red stripe. */ 3758a94683196406b83b14218d1beef66067f126a16keunyoung color = &mRedYUV; 3768a94683196406b83b14218d1beef66067f126a16keunyoung } else if (color_index == 2) { 3778a94683196406b83b14218d1beef66067f126a16keunyoung /* Then the green stripe. */ 3788a94683196406b83b14218d1beef66067f126a16keunyoung color = &mGreenYUV; 3798a94683196406b83b14218d1beef66067f126a16keunyoung } else { 3808a94683196406b83b14218d1beef66067f126a16keunyoung /* And the blue stripe at the bottom. */ 3818a94683196406b83b14218d1beef66067f126a16keunyoung color = &mBlueYUV; 3828a94683196406b83b14218d1beef66067f126a16keunyoung } 3838a94683196406b83b14218d1beef66067f126a16keunyoung changeWhiteBalance(color->Y, color->U, color->V); 3848a94683196406b83b14218d1beef66067f126a16keunyoung 3858a94683196406b83b14218d1beef66067f126a16keunyoung /* All Ys at the row are the same. */ 3868a94683196406b83b14218d1beef66067f126a16keunyoung memset(pY, changeExposure(color->Y), mFrameWidth); 3878a94683196406b83b14218d1beef66067f126a16keunyoung 3888a94683196406b83b14218d1beef66067f126a16keunyoung /* Offset of the current row inside U/V panes. */ 3898a94683196406b83b14218d1beef66067f126a16keunyoung const int uv_off = (y / 2) * mUVInRow; 3908a94683196406b83b14218d1beef66067f126a16keunyoung /* Fill U, and V panes. */ 3918a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* U = mFrameU + uv_off; 3928a94683196406b83b14218d1beef66067f126a16keunyoung uint8_t* V = mFrameV + uv_off; 3938a94683196406b83b14218d1beef66067f126a16keunyoung for (int k = 0; k < each_in_row; k++, U += mUVStep, V += mUVStep) { 3948a94683196406b83b14218d1beef66067f126a16keunyoung *U = color->U; 3958a94683196406b83b14218d1beef66067f126a16keunyoung *V = color->V; 3968a94683196406b83b14218d1beef66067f126a16keunyoung } 3978a94683196406b83b14218d1beef66067f126a16keunyoung } 3988a94683196406b83b14218d1beef66067f126a16keunyoung} 3998a94683196406b83b14218d1beef66067f126a16keunyoung 4008a94683196406b83b14218d1beef66067f126a16keunyoungint EmulatedFakeCameraDevice::rotateFrame() 4018a94683196406b83b14218d1beef66067f126a16keunyoung{ 4028a94683196406b83b14218d1beef66067f126a16keunyoung if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRotatedAt) >= mRotateFreq) { 4038a94683196406b83b14218d1beef66067f126a16keunyoung mLastRotatedAt = systemTime(SYSTEM_TIME_MONOTONIC); 4048a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentFrameType++; 4058a94683196406b83b14218d1beef66067f126a16keunyoung if (mCurrentFrameType > 2) { 4068a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentFrameType = 0; 4078a94683196406b83b14218d1beef66067f126a16keunyoung } 4088a94683196406b83b14218d1beef66067f126a16keunyoung if (mCurrentFrameType == 2) { 4098a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("********** Rotated to the SOLID COLOR frame **********"); 4108a94683196406b83b14218d1beef66067f126a16keunyoung /* Solid color: lets rotate color too. */ 4118a94683196406b83b14218d1beef66067f126a16keunyoung if (mCurrentColor == &mWhiteYUV) { 4128a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("----- Painting a solid RED frame -----"); 4138a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentColor = &mRedYUV; 4148a94683196406b83b14218d1beef66067f126a16keunyoung } else if (mCurrentColor == &mRedYUV) { 4158a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("----- Painting a solid GREEN frame -----"); 4168a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentColor = &mGreenYUV; 4178a94683196406b83b14218d1beef66067f126a16keunyoung } else if (mCurrentColor == &mGreenYUV) { 4188a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("----- Painting a solid BLUE frame -----"); 4198a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentColor = &mBlueYUV; 4208a94683196406b83b14218d1beef66067f126a16keunyoung } else { 4218a94683196406b83b14218d1beef66067f126a16keunyoung /* Back to white. */ 4228a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("----- Painting a solid WHITE frame -----"); 4238a94683196406b83b14218d1beef66067f126a16keunyoung mCurrentColor = &mWhiteYUV; 4248a94683196406b83b14218d1beef66067f126a16keunyoung } 4258a94683196406b83b14218d1beef66067f126a16keunyoung } else if (mCurrentFrameType == 0) { 4268a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("********** Rotated to the CHECKERBOARD frame **********"); 4278a94683196406b83b14218d1beef66067f126a16keunyoung } else if (mCurrentFrameType == 1) { 4288a94683196406b83b14218d1beef66067f126a16keunyoung ALOGD("********** Rotated to the STRIPED frame **********"); 4298a94683196406b83b14218d1beef66067f126a16keunyoung } 4308a94683196406b83b14218d1beef66067f126a16keunyoung } 4318a94683196406b83b14218d1beef66067f126a16keunyoung 4328a94683196406b83b14218d1beef66067f126a16keunyoung return mCurrentFrameType; 4338a94683196406b83b14218d1beef66067f126a16keunyoung} 4348a94683196406b83b14218d1beef66067f126a16keunyoung 4358a94683196406b83b14218d1beef66067f126a16keunyoung#endif // EFCD_ROTATE_FRAME 4368a94683196406b83b14218d1beef66067f126a16keunyoung 4378a94683196406b83b14218d1beef66067f126a16keunyoung}; /* namespace android */ 438