From: Bjoern Johansson Date: Fri, 7 Oct 2016 18:25:00 +0000 (-0700) Subject: Make fake camera frames resolution independent X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=04cbc984baf63ea505917af30213fa7896164e70;p=android-x86%2Fdevice-generic-goldfish.git Make fake camera frames resolution independent Make the generation of the checkerboard frames resolution independent so that the frames look the same after changing resolution. This allows seamless switches between resolutions without any noticable differences. This change also modifies the animation of the moving square so that it now bounces off the edges of the frame instead of a 255x255 invisible square. This is to ensure that the square ends up in a place that does not depend on a fixed pixel location. Instead it will appear in a similar location regardless of resolution. This satisfies a newly added test in the N CTS tests that will compare preview frames at certain resolutions with the JPEG created when taking a picture. BUG: 31913409 Test: ran camera CTS tests Change-Id: I12fc47aaf3ed678383b70d6e91060e05aaf41452 (cherry picked from commit 1ac0584457f60b314a90fa6233c52c0d8ebb1ade) --- diff --git a/camera/EmulatedFakeCameraDevice.cpp b/camera/EmulatedFakeCameraDevice.cpp index a5f8b1d..d59cdbf 100755 --- a/camera/EmulatedFakeCameraDevice.cpp +++ b/camera/EmulatedFakeCameraDevice.cpp @@ -31,6 +31,14 @@ namespace android { +static const double kCheckXSpeed = 0.00000000096; +static const double kCheckYSpeed = 0.00000000032; + +static const double kSquareXSpeed = 0.000000000096; +static const double kSquareYSpeed = 0.000000000160; + +static const nsecs_t kSquareColorChangeIntervalNs = seconds(5); + EmulatedFakeCameraDevice::EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_hal) : EmulatedCameraDevice(camera_hal), mBlackYUV(kBlack32), @@ -38,10 +46,15 @@ EmulatedFakeCameraDevice::EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_ha mRedYUV(kRed8), mGreenYUV(kGreen8), mBlueYUV(kBlue8), + mSquareColor(&mRedYUV), mLastRedrawn(0), + mLastColorChange(0), mCheckX(0), mCheckY(0), - mCcounter(0) + mSquareX(0), + mSquareY(0), + mSquareXSpeed(kSquareXSpeed), + mSquareYSpeed(kSquareYSpeed) #if EFCD_ROTATE_FRAME , mLastRotatedAt(0), mCurrentFrameType(0), @@ -158,6 +171,8 @@ status_t EmulatedFakeCameraDevice::startDevice(int width, reinterpret_cast(&mPixelFormat)); return EINVAL; } + mLastRedrawn = systemTime(SYSTEM_TIME_MONOTONIC); + mLastColorChange = mLastRedrawn; /* Number of items in a single row inside U/V panes. */ mUVInRow = (width / 2) * mUVStep; mState = ECDS_STARTED; @@ -215,11 +230,13 @@ bool EmulatedFakeCameraDevice::produceFrame(void* buffer) void EmulatedFakeCameraDevice::drawCheckerboard(void* buffer) { + nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); + nsecs_t elapsed = now - mLastRedrawn; uint8_t* currentFrame = reinterpret_cast(buffer); uint8_t* frameU = currentFrame + mFrameUOffset; uint8_t* frameV = currentFrame + mFrameVOffset; - const int size = mFrameWidth / 10; + const int size = std::min(mFrameWidth, mFrameHeight) / 10; bool black = true; if (size == 0) { @@ -228,17 +245,34 @@ void EmulatedFakeCameraDevice::drawCheckerboard(void* buffer) return; } + mCheckX += kCheckXSpeed * elapsed; + mCheckY += kCheckYSpeed * elapsed; + + // Allow the X and Y values to transition across two checkerboard boxes + // before resetting it back. This allows for the gray to black transition. + // Note that this is in screen size independent coordinates so that frames + // will look similar regardless of resolution + if (mCheckX > 2.0) { + mCheckX -= 2.0; + } + if (mCheckY > 2.0) { + mCheckY -= 2.0; + } - if((mCheckX / size) & 1) + // Are we in the gray or black zone? + if (mCheckX >= 1.0) black = false; - if((mCheckY / size) & 1) + if (mCheckY >= 1.0) black = !black; - int county = mCheckY % size; - int checkxremainder = mCheckX % size; + int county = static_cast(mCheckY * size) % size; + int checkxremainder = static_cast(mCheckX * size) % size; YUVPixel adjustedWhite = YUVPixel(mWhiteYUV); changeWhiteBalance(adjustedWhite.Y, adjustedWhite.U, adjustedWhite.V); + adjustedWhite.Y = changeExposure(adjustedWhite.Y); + YUVPixel adjustedBlack = YUVPixel(mBlackYUV); + adjustedBlack.Y = changeExposure(adjustedBlack.Y); for(int y = 0; y < mFrameHeight; y++) { int countx = checkxremainder; @@ -248,11 +282,10 @@ void EmulatedFakeCameraDevice::drawCheckerboard(void* buffer) uint8_t* V = frameV + mUVStride * (y / 2); for(int x = 0; x < mFrameWidth; x += 2) { if (current) { - mBlackYUV.get(Y, U, V); + adjustedBlack.get(Y, U, V); } else { adjustedWhite.get(Y, U, V); } - *Y = changeExposure(*Y); Y[1] = *Y; Y += 2; U += mUVStep; V += mUVStep; countx += 2; @@ -266,18 +299,35 @@ void EmulatedFakeCameraDevice::drawCheckerboard(void* buffer) black = !black; } } - mCheckX += 3; - mCheckY++; /* Run the square. */ - int sqx = ((mCcounter * 3) & 255); - if(sqx > 128) sqx = 255 - sqx; - int sqy = ((mCcounter * 5) & 255); - if(sqy > 128) sqy = 255 - sqy; - const int sqsize = mFrameWidth / 10; - drawSquare(buffer, sqx * sqsize / 32, sqy * sqsize / 32, (sqsize * 5) >> 1, - (mCcounter & 0x100) ? &mRedYUV : &mGreenYUV); - mCcounter++; + const int squareSize = std::min(mFrameWidth, mFrameHeight) / 4; + mSquareX += mSquareXSpeed * elapsed; + mSquareY += mSquareYSpeed * elapsed; + int squareX = mSquareX * mFrameWidth; + int squareY = mSquareY * mFrameHeight; + if (squareX + squareSize > mFrameWidth) { + mSquareXSpeed = -mSquareXSpeed; + squareX -= 2 * (squareX + squareSize - mFrameWidth); + } else if (squareX < 0) { + mSquareXSpeed = -mSquareXSpeed; + squareX = -squareX; + } + if (squareY + squareSize > mFrameHeight) { + mSquareYSpeed = -mSquareYSpeed; + squareY -= 2 * (squareY + squareSize - mFrameHeight); + } else if (squareY < 0) { + mSquareYSpeed = -mSquareYSpeed; + squareY = -squareY; + } + + if (now - mLastColorChange > kSquareColorChangeIntervalNs) { + mLastColorChange = now; + mSquareColor = mSquareColor == &mRedYUV ? &mGreenYUV : &mRedYUV; + } + + drawSquare(buffer, squareX, squareY, squareSize, mSquareColor); + mLastRedrawn = now; } void EmulatedFakeCameraDevice::drawSquare(void* buffer, diff --git a/camera/EmulatedFakeCameraDevice.h b/camera/EmulatedFakeCameraDevice.h index fabe550..a3e9201 100755 --- a/camera/EmulatedFakeCameraDevice.h +++ b/camera/EmulatedFakeCameraDevice.h @@ -125,6 +125,7 @@ private: YUVPixel mRedYUV; YUVPixel mGreenYUV; YUVPixel mBlueYUV; + YUVPixel* mSquareColor; /* Last time the frame has been redrawn. */ nsecs_t mLastRedrawn; @@ -150,14 +151,14 @@ private: /* * Checkerboard drawing related stuff */ - - int mCheckX; - int mCheckY; - int mCcounter; - - /* Defines time (in nanoseconds) between redrawing the checker board. - * We will redraw the checker board every 15 milliseconds. */ - static const nsecs_t mRedrawAfter = 15000000LL; + nsecs_t mLastColorChange; + + double mCheckX; + double mCheckY; + double mSquareX; + double mSquareY; + double mSquareXSpeed; + double mSquareYSpeed; #if EFCD_ROTATE_FRAME /* Frame rotation frequency in nanosec (currently - 3 sec) */