summaryrefslogtreecommitdiff
path: root/guest/hals/camera/EmulatedCameraDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'guest/hals/camera/EmulatedCameraDevice.cpp')
-rw-r--r--guest/hals/camera/EmulatedCameraDevice.cpp418
1 files changed, 0 insertions, 418 deletions
diff --git a/guest/hals/camera/EmulatedCameraDevice.cpp b/guest/hals/camera/EmulatedCameraDevice.cpp
deleted file mode 100644
index d741b737..00000000
--- a/guest/hals/camera/EmulatedCameraDevice.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Contains implementation of an abstract class EmulatedCameraDevice that
- * defines functionality expected from an emulated physical camera device:
- * - Obtaining and setting camera parameters
- * - Capturing frames
- * - Streaming video
- * - etc.
- */
-
-#define LOG_NDEBUG 0
-#define LOG_TAG "EmulatedCamera_Device"
-#include "EmulatedCameraDevice.h"
-#include <log/log.h>
-#include <sys/select.h>
-#include <algorithm>
-#include <cmath>
-#include "EmulatedCamera.h"
-
-namespace android {
-
-const float GAMMA_CORRECTION = 2.2f;
-EmulatedCameraDevice::EmulatedCameraDevice(EmulatedCamera* camera_hal)
- : mObjectLock(),
- mCurFrameTimestamp(0),
- mCameraHAL(camera_hal),
- mCurrentFrame(NULL),
- mExposureCompensation(1.0f),
- mWhiteBalanceScale(NULL),
- mIsFocusing(false),
- mSupportedWhiteBalanceScale(),
- mState(ECDS_CONSTRUCTED) {}
-
-EmulatedCameraDevice::~EmulatedCameraDevice() {
- ALOGV("EmulatedCameraDevice destructor");
- if (mCurrentFrame != NULL) {
- delete[] mCurrentFrame;
- }
- for (size_t i = 0; i < mSupportedWhiteBalanceScale.size(); ++i) {
- if (mSupportedWhiteBalanceScale.valueAt(i) != NULL) {
- delete[] mSupportedWhiteBalanceScale.valueAt(i);
- }
- }
-}
-
-/****************************************************************************
- * Emulated camera device public API
- ***************************************************************************/
-
-status_t EmulatedCameraDevice::Initialize() {
- if (isInitialized()) {
- ALOGW("%s: Emulated camera device is already initialized: mState = %d",
- __FUNCTION__, mState);
- return NO_ERROR;
- }
-
- /* Instantiate worker thread object. */
- mWorkerThread = new WorkerThread(this);
- if (getWorkerThread() == NULL) {
- ALOGE("%s: Unable to instantiate worker thread object", __FUNCTION__);
- return ENOMEM;
- }
-
- mState = ECDS_INITIALIZED;
-
- return NO_ERROR;
-}
-
-status_t EmulatedCameraDevice::startDeliveringFrames(bool one_burst) {
- ALOGV("%s", __FUNCTION__);
-
- if (!isStarted()) {
- ALOGE("%s: Device is not started", __FUNCTION__);
- return EINVAL;
- }
-
- /* Frames will be delivered from the thread routine. */
- const status_t res = startWorkerThread(one_burst);
- ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__);
- return res;
-}
-
-status_t EmulatedCameraDevice::stopDeliveringFrames() {
- ALOGV("%s", __FUNCTION__);
-
- if (!isStarted()) {
- ALOGW("%s: Device is not started", __FUNCTION__);
- return NO_ERROR;
- }
-
- const status_t res = stopWorkerThread();
- ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__);
- return res;
-}
-
-void EmulatedCameraDevice::setExposureCompensation(const float ev) {
- ALOGV("%s", __FUNCTION__);
-
- if (!isStarted()) {
- ALOGW("%s: Fake camera device is not started.", __FUNCTION__);
- }
-
- mExposureCompensation = std::pow(2.0f, ev / GAMMA_CORRECTION);
- ALOGV("New exposure compensation is %f", mExposureCompensation);
-}
-
-void EmulatedCameraDevice::initializeWhiteBalanceModes(const char* mode,
- const float r_scale,
- const float b_scale) {
- ALOGV("%s with %s, %f, %f", __FUNCTION__, mode, r_scale, b_scale);
- float* value = new float[3];
- value[0] = r_scale;
- value[1] = 1.0f;
- value[2] = b_scale;
- mSupportedWhiteBalanceScale.add(String8(mode), value);
-}
-
-void EmulatedCameraDevice::setWhiteBalanceMode(const char* mode) {
- ALOGV("%s with white balance %s", __FUNCTION__, mode);
- mWhiteBalanceScale = mSupportedWhiteBalanceScale.valueFor(String8(mode));
-}
-
-void EmulatedCameraDevice::startAutoFocus() { mIsFocusing = true; }
-
-/* Computes the pixel value after adjusting the white balance to the current
- * one. The input the y, u, v channel of the pixel and the adjusted value will
- * be stored in place. The adjustment is done in RGB space.
- */
-void EmulatedCameraDevice::changeWhiteBalance(uint8_t& y, uint8_t& u,
- uint8_t& v) const {
- float r_scale = mWhiteBalanceScale[0];
- float b_scale = mWhiteBalanceScale[2];
- int r = static_cast<float>(YUV2R(y, u, v)) / r_scale;
- int g = YUV2G(y, u, v);
- int b = static_cast<float>(YUV2B(y, u, v)) / b_scale;
-
- y = RGB2Y(r, g, b);
- u = RGB2U(r, g, b);
- v = RGB2V(r, g, b);
-}
-
-void EmulatedCameraDevice::simulateAutoFocus() {
- if (mIsFocusing) {
- ALOGV("%s: Simulating auto-focus", __FUNCTION__);
- mCameraHAL->onCameraFocusAcquired();
- mIsFocusing = false;
- }
-}
-
-status_t EmulatedCameraDevice::getCurrentPreviewFrame(void* buffer) {
- if (!isStarted()) {
- ALOGE("%s: Device is not started", __FUNCTION__);
- return EINVAL;
- }
- if (mCurrentFrame == NULL || buffer == NULL) {
- ALOGE("%s: No framebuffer", __FUNCTION__);
- return EINVAL;
- }
-
- /* In emulation the framebuffer is never RGB. */
- switch (mPixelFormat) {
- case V4L2_PIX_FMT_YVU420:
- YV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
- return NO_ERROR;
- case V4L2_PIX_FMT_YUV420:
- YU12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
- return NO_ERROR;
- case V4L2_PIX_FMT_NV21:
- NV21ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
- return NO_ERROR;
- case V4L2_PIX_FMT_NV12:
- NV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight);
- return NO_ERROR;
-
- default:
- ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__,
- reinterpret_cast<const char*>(&mPixelFormat));
- return EINVAL;
- }
-}
-
-/****************************************************************************
- * Emulated camera device private API
- ***************************************************************************/
-
-status_t EmulatedCameraDevice::commonStartDevice(int width, int height,
- uint32_t pix_fmt, int fps) {
- /* Validate pixel format, and calculate framebuffer size at the same time. */
- switch (pix_fmt) {
- case V4L2_PIX_FMT_YVU420:
- case V4L2_PIX_FMT_YUV420:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV12:
- mFrameBufferSize = (width * height * 12) / 8;
- break;
-
- default:
- ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__,
- reinterpret_cast<const char*>(&pix_fmt));
- return EINVAL;
- }
-
- /* Cache framebuffer info. */
- mFrameWidth = width;
- mFrameHeight = height;
- mPixelFormat = pix_fmt;
- mTotalPixels = width * height;
- mTargetFps = fps;
-
- /* Allocate framebuffer. */
- mCurrentFrame = new uint8_t[mFrameBufferSize];
- if (mCurrentFrame == NULL) {
- ALOGE("%s: Unable to allocate framebuffer", __FUNCTION__);
- return ENOMEM;
- }
- ALOGV("%s: Allocated %p %zu bytes for %d pixels in %.4s[%dx%d] frame",
- __FUNCTION__, mCurrentFrame, mFrameBufferSize, mTotalPixels,
- reinterpret_cast<const char*>(&mPixelFormat), mFrameWidth,
- mFrameHeight);
- return NO_ERROR;
-}
-
-void EmulatedCameraDevice::commonStopDevice() {
- mFrameWidth = mFrameHeight = mTotalPixels = 0;
- mPixelFormat = 0;
- mTargetFps = 0;
-
- if (mCurrentFrame != NULL) {
- delete[] mCurrentFrame;
- mCurrentFrame = NULL;
- }
-}
-
-const CameraParameters* EmulatedCameraDevice::getCameraParameters() {
- return mCameraHAL->getCameraParameters();
-}
-
-/****************************************************************************
- * Worker thread management.
- ***************************************************************************/
-
-status_t EmulatedCameraDevice::startWorkerThread(bool one_burst) {
- ALOGV("%s", __FUNCTION__);
-
- if (!isInitialized()) {
- ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__);
- return EINVAL;
- }
-
- const status_t res = getWorkerThread()->startThread(one_burst);
- ALOGE_IF(res != NO_ERROR, "%s: Unable to start worker thread", __FUNCTION__);
- return res;
-}
-
-status_t EmulatedCameraDevice::stopWorkerThread() {
- ALOGV("%s", __FUNCTION__);
-
- if (!isInitialized()) {
- ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__);
- return EINVAL;
- }
-
- const status_t res = getWorkerThread()->stopThread();
- ALOGE_IF(res != NO_ERROR, "%s: Unable to stop worker thread", __FUNCTION__);
- return res;
-}
-
-bool EmulatedCameraDevice::inWorkerThread() {
- /* This will end the thread loop, and will terminate the thread. Derived
- * classes must override this method. */
- return false;
-}
-
-/****************************************************************************
- * Worker thread implementation.
- ***************************************************************************/
-
-status_t EmulatedCameraDevice::WorkerThread::readyToRun() {
- ALOGV("Starting emulated camera device worker thread...");
-
- ALOGW_IF(mThreadControl >= 0 || mControlFD >= 0,
- "%s: Thread control FDs are opened", __FUNCTION__);
- /* Create a pair of FDs that would be used to control the thread. */
- int thread_fds[2];
- status_t ret;
- Mutex::Autolock lock(mCameraDevice->mObjectLock);
- if (pipe(thread_fds) == 0) {
- mThreadControl = thread_fds[1];
- mControlFD = thread_fds[0];
- ALOGV("Emulated device's worker thread has been started.");
- ret = NO_ERROR;
- } else {
- ALOGE("%s: Unable to create thread control FDs: %d -> %s", __FUNCTION__,
- errno, strerror(errno));
- ret = errno;
- }
-
- mSetup.signal();
- return ret;
-}
-
-status_t EmulatedCameraDevice::WorkerThread::stopThread() {
- ALOGV("Stopping emulated camera device's worker thread...");
-
- status_t res = EINVAL;
-
- // Limit the scope of the Autolock
- {
- // If thread is running and readyToRun() has not finished running,
- // then wait until it is done.
- Mutex::Autolock lock(mCameraDevice->mObjectLock);
- if (isRunning() && (mThreadControl < 0 || mControlFD < 0)) {
- mSetup.wait(mCameraDevice->mObjectLock);
- }
- }
-
- if (mThreadControl >= 0) {
- /* Send "stop" message to the thread loop. */
- const ControlMessage msg = THREAD_STOP;
- const int wres =
- TEMP_FAILURE_RETRY(write(mThreadControl, &msg, sizeof(msg)));
- if (wres == sizeof(msg)) {
- /* Stop the thread, and wait till it's terminated. */
- res = requestExitAndWait();
- if (res == NO_ERROR) {
- /* Close control FDs. */
- if (mThreadControl >= 0) {
- close(mThreadControl);
- mThreadControl = -1;
- }
- if (mControlFD >= 0) {
- close(mControlFD);
- mControlFD = -1;
- }
- ALOGV("Emulated camera device's worker thread has been stopped.");
- } else {
- ALOGE("%s: requestExitAndWait failed: %d -> %s", __FUNCTION__, res,
- strerror(-res));
- }
- } else {
- ALOGE("%s: Unable to send THREAD_STOP message: %d -> %s", __FUNCTION__,
- errno, strerror(errno));
- res = errno ? errno : EINVAL;
- }
- } else {
- ALOGE("%s: Thread control FDs are not opened", __FUNCTION__);
- }
-
- return res;
-}
-
-EmulatedCameraDevice::WorkerThread::SelectRes
-EmulatedCameraDevice::WorkerThread::Select(int fd, int timeout) {
- fd_set fds[1];
- struct timeval tv, *tvp = NULL;
-
- mCameraDevice->simulateAutoFocus();
-
- const int fd_num = (fd >= 0) ? std::max(fd, mControlFD) + 1 : mControlFD + 1;
- FD_ZERO(fds);
- FD_SET(mControlFD, fds);
- if (fd >= 0) {
- FD_SET(fd, fds);
- }
- if (timeout) {
- tv.tv_sec = timeout / 1000000;
- tv.tv_usec = timeout % 1000000;
- tvp = &tv;
- }
- int res = TEMP_FAILURE_RETRY(select(fd_num, fds, NULL, NULL, tvp));
- if (res < 0) {
- ALOGE("%s: select returned %d and failed: %d -> %s", __FUNCTION__, res,
- errno, strerror(errno));
- return ERROR;
- } else if (res == 0) {
- /* Timeout. */
- return TIMEOUT;
- } else if (FD_ISSET(mControlFD, fds)) {
- /* A control event. Lets read the message. */
- ControlMessage msg;
- res = TEMP_FAILURE_RETRY(read(mControlFD, &msg, sizeof(msg)));
- if (res != sizeof(msg)) {
- ALOGE("%s: Unexpected message size %d, or an error %d -> %s",
- __FUNCTION__, res, errno, strerror(errno));
- return ERROR;
- }
- /* THREAD_STOP is the only message expected here. */
- if (msg == THREAD_STOP) {
- ALOGV("%s: THREAD_STOP message is received", __FUNCTION__);
- return EXIT_THREAD;
- } else {
- ALOGE("Unknown worker thread message %d", msg);
- return ERROR;
- }
- } else {
- /* Must be an FD. */
- ALOGW_IF(fd < 0 || !FD_ISSET(fd, fds), "%s: Undefined 'select' result",
- __FUNCTION__);
- return READY;
- }
-}
-
-}; /* namespace android */