summaryrefslogtreecommitdiff
path: root/guest/hals/camera/EmulatedFakeCamera2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'guest/hals/camera/EmulatedFakeCamera2.cpp')
-rw-r--r--guest/hals/camera/EmulatedFakeCamera2.cpp2606
1 files changed, 0 insertions, 2606 deletions
diff --git a/guest/hals/camera/EmulatedFakeCamera2.cpp b/guest/hals/camera/EmulatedFakeCamera2.cpp
deleted file mode 100644
index 393adf1e..00000000
--- a/guest/hals/camera/EmulatedFakeCamera2.cpp
+++ /dev/null
@@ -1,2606 +0,0 @@
-/*
- * Copyright (C) 2012 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 a class EmulatedFakeCamera2 that encapsulates
- * functionality of an advanced fake camera.
- */
-
-#include <inttypes.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <iterator>
-
-#define LOG_NDEBUG 0
-#define LOG_TAG "EmulatedCamera_FakeCamera2"
-#include <utils/Log.h>
-
-#include "EmulatedCameraFactory.h"
-#include "EmulatedFakeCamera2.h"
-#include "GrallocModule.h"
-
-#define ERROR_CAMERA_NOT_PRESENT -EPIPE
-
-#define CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT 0xFFFFFFFF
-
-template <typename T, size_t N>
-char (&ArraySizeHelper(T (&array)[N]))[N];
-
-template <typename T, size_t N>
-char (&ArraySizeHelper(const T (&array)[N]))[N];
-
-#define arraysize(array) (sizeof(ArraySizeHelper(array)))
-
-namespace android {
-
-const int64_t USEC = 1000LL;
-const int64_t MSEC = USEC * 1000LL;
-const int64_t SEC = MSEC * 1000LL;
-
-const uint32_t EmulatedFakeCamera2::kAvailableFormats[] = {
- HAL_PIXEL_FORMAT_RAW16,
- HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888,
- // HAL_PIXEL_FORMAT_YV12,
- HAL_PIXEL_FORMAT_YCrCb_420_SP};
-
-const uint32_t EmulatedFakeCamera2::kAvailableRawSizes[2] = {
- 640, 480
- // mSensorWidth, mSensorHeight
-};
-
-const uint64_t EmulatedFakeCamera2::kAvailableRawMinDurations[1] = {
- static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
-
-const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesBack[4] = {
- 640, 480, 320, 240
- // mSensorWidth, mSensorHeight
-};
-
-const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesFront[4] = {
- 320, 240, 160, 120
- // mSensorWidth, mSensorHeight
-};
-
-const uint64_t EmulatedFakeCamera2::kAvailableProcessedMinDurations[1] = {
- static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
-
-const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesBack[2] = {
- 640, 480
- // mSensorWidth, mSensorHeight
-};
-
-const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesFront[2] = {
- 320, 240
- // mSensorWidth, mSensorHeight
-};
-
-const uint64_t EmulatedFakeCamera2::kAvailableJpegMinDurations[1] = {
- static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
-
-EmulatedFakeCamera2::EmulatedFakeCamera2(int cameraId, bool facingBack,
- struct hw_module_t *module)
- : EmulatedCamera2(cameraId, module),
- mFacingBack(facingBack),
- mIsConnected(false) {
- ALOGD("Constructing emulated fake camera 2 facing %s",
- facingBack ? "back" : "front");
-}
-
-EmulatedFakeCamera2::~EmulatedFakeCamera2() {
- if (mCameraInfo != NULL) {
- free_camera_metadata(mCameraInfo);
- }
-}
-
-/****************************************************************************
- * Public API overrides
- ***************************************************************************/
-
-status_t EmulatedFakeCamera2::Initialize(const cvd::CameraDefinition &params) {
- status_t res;
-
- for (size_t index = 0; index < params.resolutions.size(); ++index) {
- mAvailableRawSizes.push_back(params.resolutions[index].width);
- mAvailableRawSizes.push_back(params.resolutions[index].height);
- mAvailableProcessedSizes.push_back(params.resolutions[index].width);
- mAvailableProcessedSizes.push_back(params.resolutions[index].height);
- mAvailableJpegSizes.push_back(params.resolutions[index].width);
- mAvailableJpegSizes.push_back(params.resolutions[index].height);
- }
-
- // Find max width/height
- int32_t width = 0, height = 0;
- for (size_t index = 0; index < params.resolutions.size(); ++index) {
- if (width <= params.resolutions[index].width &&
- height <= params.resolutions[index].height) {
- width = params.resolutions[index].width;
- height = params.resolutions[index].height;
- }
- }
- if (width < 640 || height < 480) {
- width = 640;
- height = 480;
- }
- mSensorWidth = width;
- mSensorHeight = height;
-
- /* TODO(ender): probably should drop this. */
- std::copy(kAvailableRawSizes,
- kAvailableRawSizes + arraysize(kAvailableRawSizes),
- std::back_inserter(mAvailableRawSizes));
-
- if (params.orientation == cvd::CameraDefinition::kFront) {
- std::copy(kAvailableProcessedSizesFront,
- kAvailableProcessedSizesFront +
- arraysize(kAvailableProcessedSizesFront),
- std::back_inserter(mAvailableProcessedSizes));
- std::copy(kAvailableJpegSizesFront,
- kAvailableJpegSizesFront + arraysize(kAvailableJpegSizesFront),
- std::back_inserter(mAvailableJpegSizes));
- } else {
- std::copy(
- kAvailableProcessedSizesBack,
- kAvailableProcessedSizesBack + arraysize(kAvailableProcessedSizesBack),
- mAvailableProcessedSizes.begin());
- std::copy(kAvailableJpegSizesBack,
- kAvailableJpegSizesBack + arraysize(kAvailableJpegSizesBack),
- mAvailableJpegSizes.begin());
- }
-
- res = constructStaticInfo(&mCameraInfo, true);
- if (res != OK) {
- ALOGE("%s: Unable to allocate static info: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- return res;
- }
- res = constructStaticInfo(&mCameraInfo, false);
- if (res != OK) {
- ALOGE("%s: Unable to fill in static info: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- return res;
- }
- if (res != OK) return res;
-
- mNextStreamId = 1;
- mNextReprocessStreamId = 1;
- mRawStreamCount = 0;
- mProcessedStreamCount = 0;
- mJpegStreamCount = 0;
- mReprocessStreamCount = 0;
-
- return NO_ERROR;
-}
-
-/****************************************************************************
- * Camera module API overrides
- ***************************************************************************/
-
-status_t EmulatedFakeCamera2::connectCamera(hw_device_t **device) {
- status_t res;
- ALOGV("%s", __FUNCTION__);
-
- {
- Mutex::Autolock l(mMutex);
- if (!mStatusPresent) {
- ALOGE("%s: Camera ID %d is unplugged", __FUNCTION__, mCameraID);
- return -ENODEV;
- }
- }
-
- mConfigureThread = new ConfigureThread(this);
- mReadoutThread = new ReadoutThread(this);
- mControlThread = new ControlThread(this);
- mSensor = new Sensor(mSensorWidth, mSensorHeight);
- mJpegCompressor = new JpegCompressor();
-
- mNextStreamId = 1;
- mNextReprocessStreamId = 1;
-
- res = mSensor->startUp();
- if (res != NO_ERROR) return res;
-
- res = mConfigureThread->run("EmulatedFakeCamera2::configureThread");
- if (res != NO_ERROR) return res;
-
- res = mReadoutThread->run("EmulatedFakeCamera2::readoutThread");
- if (res != NO_ERROR) return res;
-
- res = mControlThread->run("EmulatedFakeCamera2::controlThread");
- if (res != NO_ERROR) return res;
-
- status_t ret = EmulatedCamera2::connectCamera(device);
-
- if (ret >= 0) {
- mIsConnected = true;
- }
-
- return ret;
-}
-
-status_t EmulatedFakeCamera2::plugCamera() {
- {
- Mutex::Autolock l(mMutex);
-
- if (!mStatusPresent) {
- ALOGI("%s: Plugged back in", __FUNCTION__);
- mStatusPresent = true;
- }
- }
-
- return NO_ERROR;
-}
-
-status_t EmulatedFakeCamera2::unplugCamera() {
- {
- Mutex::Autolock l(mMutex);
-
- if (mStatusPresent) {
- ALOGI("%s: Unplugged camera", __FUNCTION__);
- mStatusPresent = false;
- }
- }
-
- return closeCamera();
-}
-
-camera_device_status_t EmulatedFakeCamera2::getHotplugStatus() {
- Mutex::Autolock l(mMutex);
- return mStatusPresent ? CAMERA_DEVICE_STATUS_PRESENT
- : CAMERA_DEVICE_STATUS_NOT_PRESENT;
-}
-
-status_t EmulatedFakeCamera2::closeCamera() {
- {
- Mutex::Autolock l(mMutex);
-
- status_t res;
- ALOGV("%s", __FUNCTION__);
-
- if (!mIsConnected) {
- return NO_ERROR;
- }
-
- res = mSensor->shutDown();
- if (res != NO_ERROR) {
- ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res);
- return res;
- }
-
- mConfigureThread->requestExit();
- mReadoutThread->requestExit();
- mControlThread->requestExit();
- mJpegCompressor->cancel();
- }
-
- // give up the lock since we will now block and the threads
- // can call back into this object
- mConfigureThread->join();
- mReadoutThread->join();
- mControlThread->join();
-
- ALOGV("%s exit", __FUNCTION__);
-
- {
- Mutex::Autolock l(mMutex);
- mIsConnected = false;
- }
-
- return NO_ERROR;
-}
-
-status_t EmulatedFakeCamera2::getCameraInfo(struct camera_info *info) {
- info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
- info->orientation =
- EmulatedCameraFactory::Instance().getFakeCameraOrientation();
- return EmulatedCamera2::getCameraInfo(info);
-}
-
-/****************************************************************************
- * Camera device API overrides
- ***************************************************************************/
-
-/** Request input queue */
-
-int EmulatedFakeCamera2::requestQueueNotify() {
- ALOGV("Request queue notification received");
-
- ALOG_ASSERT(mRequestQueueSrc != NULL,
- "%s: Request queue src not set, but received queue notification!",
- __FUNCTION__);
- ALOG_ASSERT(mFrameQueueDst != NULL,
- "%s: Request queue src not set, but received queue notification!",
- __FUNCTION__);
- ALOG_ASSERT(mStreams.size() != 0,
- "%s: No streams allocated, but received queue notification!",
- __FUNCTION__);
- return mConfigureThread->newRequestAvailable();
-}
-
-int EmulatedFakeCamera2::getInProgressCount() {
- Mutex::Autolock l(mMutex);
-
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
-
- int requestCount = 0;
- requestCount += mConfigureThread->getInProgressCount();
- requestCount += mReadoutThread->getInProgressCount();
- requestCount += mJpegCompressor->isBusy() ? 1 : 0;
-
- return requestCount;
-}
-
-int EmulatedFakeCamera2::constructDefaultRequest(int request_template,
- camera_metadata_t **request) {
- if (request == NULL) return BAD_VALUE;
- if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
- return BAD_VALUE;
- }
-
- {
- Mutex::Autolock l(mMutex);
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
- }
-
- status_t res;
- // Pass 1, calculate size and allocate
- res = constructDefaultRequest(request_template, request, true);
- if (res != OK) {
- return res;
- }
- // Pass 2, build request
- res = constructDefaultRequest(request_template, request, false);
- if (res != OK) {
- ALOGE("Unable to populate new request for template %d", request_template);
- }
-
- return res;
-}
-
-int EmulatedFakeCamera2::allocateStream(
- uint32_t width, uint32_t height, int format,
- const camera2_stream_ops_t *stream_ops, uint32_t *stream_id,
- uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers) {
- Mutex::Autolock l(mMutex);
-
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
-
- // Temporary shim until FORMAT_ZSL is removed
- if (format == CAMERA2_HAL_PIXEL_FORMAT_ZSL) {
- format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
- }
-
- if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
- unsigned int numFormats = sizeof(kAvailableFormats) / sizeof(uint32_t);
- unsigned int formatIdx = 0;
- for (; formatIdx < numFormats; formatIdx++) {
- if (format == (int)kAvailableFormats[formatIdx]) break;
- }
- if (formatIdx == numFormats) {
- ALOGE("%s: Format 0x%x is not supported", __FUNCTION__, format);
- return BAD_VALUE;
- }
- }
-
- const uint32_t *availableSizes;
- size_t availableSizeCount;
- switch (format) {
- case HAL_PIXEL_FORMAT_RAW16:
- availableSizes = &mAvailableRawSizes.front();
- availableSizeCount = mAvailableRawSizes.size();
- break;
- case HAL_PIXEL_FORMAT_BLOB:
- availableSizes = &mAvailableJpegSizes.front();
- availableSizeCount = mAvailableJpegSizes.size();
- break;
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_YV12:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- availableSizes = &mAvailableProcessedSizes.front();
- availableSizeCount = mAvailableProcessedSizes.size();
- break;
- default:
- ALOGE("%s: Unknown format 0x%x", __FUNCTION__, format);
- return BAD_VALUE;
- }
-
- unsigned int resIdx = 0;
- for (; resIdx < availableSizeCount; resIdx++) {
- if (availableSizes[resIdx * 2] == width &&
- availableSizes[resIdx * 2 + 1] == height)
- break;
- }
- if (resIdx == availableSizeCount) {
- ALOGE("%s: Format 0x%x does not support resolution %d, %d", __FUNCTION__,
- format, width, height);
- return BAD_VALUE;
- }
-
- switch (format) {
- case HAL_PIXEL_FORMAT_RAW16:
- if (mRawStreamCount >= kMaxRawStreamCount) {
- ALOGE("%s: Cannot allocate another raw stream (%d already allocated)",
- __FUNCTION__, mRawStreamCount);
- return INVALID_OPERATION;
- }
- mRawStreamCount++;
- break;
- case HAL_PIXEL_FORMAT_BLOB:
- if (mJpegStreamCount >= kMaxJpegStreamCount) {
- ALOGE("%s: Cannot allocate another JPEG stream (%d already allocated)",
- __FUNCTION__, mJpegStreamCount);
- return INVALID_OPERATION;
- }
- mJpegStreamCount++;
- break;
- default:
- if (mProcessedStreamCount >= kMaxProcessedStreamCount) {
- ALOGE(
- "%s: Cannot allocate another processed stream (%d already "
- "allocated)",
- __FUNCTION__, mProcessedStreamCount);
- return INVALID_OPERATION;
- }
- mProcessedStreamCount++;
- }
-
- Stream newStream;
- newStream.ops = stream_ops;
- newStream.width = width;
- newStream.height = height;
- newStream.format = format;
- // TODO: Query stride from gralloc
- newStream.stride = width;
-
- mStreams.add(mNextStreamId, newStream);
-
- *stream_id = mNextStreamId;
- if (format_actual) *format_actual = format;
- *usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
- *max_buffers = kMaxBufferCount;
-
- ALOGV("Stream allocated: %d, %d x %d, 0x%x. U: %x, B: %d", *stream_id, width,
- height, format, *usage, *max_buffers);
-
- mNextStreamId++;
- return NO_ERROR;
-}
-
-int EmulatedFakeCamera2::registerStreamBuffers(uint32_t stream_id,
- int num_buffers,
- buffer_handle_t * /*buffers*/) {
- Mutex::Autolock l(mMutex);
-
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
-
- ALOGV("%s: Stream %d registering %d buffers", __FUNCTION__, stream_id,
- num_buffers);
- // Need to find out what the final concrete pixel format for our stream is
- // Assumes that all buffers have the same format.
- if (num_buffers < 1) {
- ALOGE("%s: Stream %d only has %d buffers!", __FUNCTION__, stream_id,
- num_buffers);
- return BAD_VALUE;
- }
-
- ssize_t streamIndex = mStreams.indexOfKey(stream_id);
- if (streamIndex < 0) {
- ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
- return BAD_VALUE;
- }
-
- Stream &stream = mStreams.editValueAt(streamIndex);
-
- int finalFormat = stream.format;
-
- if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
- finalFormat = HAL_PIXEL_FORMAT_RGBA_8888;
- }
-
- ALOGV("%s: Stream %d format set to %x, previously %x", __FUNCTION__,
- stream_id, finalFormat, stream.format);
-
- stream.format = finalFormat;
-
- return NO_ERROR;
-}
-
-int EmulatedFakeCamera2::releaseStream(uint32_t stream_id) {
- Mutex::Autolock l(mMutex);
-
- ssize_t streamIndex = mStreams.indexOfKey(stream_id);
- if (streamIndex < 0) {
- ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
- return BAD_VALUE;
- }
-
- if (isStreamInUse(stream_id)) {
- ALOGE("%s: Cannot release stream %d; in use!", __FUNCTION__, stream_id);
- return BAD_VALUE;
- }
-
- switch (mStreams.valueAt(streamIndex).format) {
- case HAL_PIXEL_FORMAT_RAW16:
- mRawStreamCount--;
- break;
- case HAL_PIXEL_FORMAT_BLOB:
- mJpegStreamCount--;
- break;
- default:
- mProcessedStreamCount--;
- break;
- }
-
- mStreams.removeItemsAt(streamIndex);
-
- return NO_ERROR;
-}
-
-int EmulatedFakeCamera2::allocateReprocessStreamFromStream(
- uint32_t output_stream_id, const camera2_stream_in_ops_t *stream_ops,
- uint32_t *stream_id) {
- Mutex::Autolock l(mMutex);
-
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
-
- ssize_t baseStreamIndex = mStreams.indexOfKey(output_stream_id);
- if (baseStreamIndex < 0) {
- ALOGE("%s: Unknown output stream id %d!", __FUNCTION__, output_stream_id);
- return BAD_VALUE;
- }
-
- const Stream &baseStream = mStreams[baseStreamIndex];
-
- // We'll reprocess anything we produced
-
- if (mReprocessStreamCount >= kMaxReprocessStreamCount) {
- ALOGE("%s: Cannot allocate another reprocess stream (%d already allocated)",
- __FUNCTION__, mReprocessStreamCount);
- return INVALID_OPERATION;
- }
- mReprocessStreamCount++;
-
- ReprocessStream newStream;
- newStream.ops = stream_ops;
- newStream.width = baseStream.width;
- newStream.height = baseStream.height;
- newStream.format = baseStream.format;
- newStream.stride = baseStream.stride;
- newStream.sourceStreamId = output_stream_id;
-
- *stream_id = mNextReprocessStreamId;
- mReprocessStreams.add(mNextReprocessStreamId, newStream);
-
- ALOGV("Reprocess stream allocated: %d: %d, %d, 0x%x. Parent stream: %d",
- *stream_id, newStream.width, newStream.height, newStream.format,
- output_stream_id);
-
- mNextReprocessStreamId++;
- return NO_ERROR;
-}
-
-int EmulatedFakeCamera2::releaseReprocessStream(uint32_t stream_id) {
- Mutex::Autolock l(mMutex);
-
- ssize_t streamIndex = mReprocessStreams.indexOfKey(stream_id);
- if (streamIndex < 0) {
- ALOGE("%s: Unknown reprocess stream id %d!", __FUNCTION__, stream_id);
- return BAD_VALUE;
- }
-
- if (isReprocessStreamInUse(stream_id)) {
- ALOGE("%s: Cannot release reprocessing stream %d; in use!", __FUNCTION__,
- stream_id);
- return BAD_VALUE;
- }
-
- mReprocessStreamCount--;
- mReprocessStreams.removeItemsAt(streamIndex);
-
- return NO_ERROR;
-}
-
-int EmulatedFakeCamera2::triggerAction(uint32_t trigger_id, int32_t ext1,
- int32_t ext2) {
- Mutex::Autolock l(mMutex);
-
- if (trigger_id == CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT) {
- ALOGI("%s: Disconnect trigger - camera must be closed", __FUNCTION__);
- mStatusPresent = false;
-
- EmulatedCameraFactory::Instance().onStatusChanged(
- mCameraID, CAMERA_DEVICE_STATUS_NOT_PRESENT);
- }
-
- if (!mStatusPresent) {
- ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
- return ERROR_CAMERA_NOT_PRESENT;
- }
-
- return mControlThread->triggerAction(trigger_id, ext1, ext2);
-}
-
-/** Shutdown and debug methods */
-
-int EmulatedFakeCamera2::dump(int fd) {
- String8 result;
-
- result.appendFormat(" Camera HAL device: EmulatedFakeCamera2\n");
- result.appendFormat(" Streams:\n");
- for (size_t i = 0; i < mStreams.size(); i++) {
- int id = mStreams.keyAt(i);
- const Stream &s = mStreams.valueAt(i);
- result.appendFormat(" Stream %d: %d x %d, format 0x%x, stride %d\n",
- id, s.width, s.height, s.format, s.stride);
- }
-
- write(fd, result.string(), result.size());
-
- return NO_ERROR;
-}
-
-void EmulatedFakeCamera2::signalError() {
- // TODO: Let parent know so we can shut down cleanly
- ALOGE("Worker thread is signaling a serious error");
-}
-
-/** Pipeline control worker thread methods */
-
-EmulatedFakeCamera2::ConfigureThread::ConfigureThread(
- EmulatedFakeCamera2 *parent)
- : Thread(false), mParent(parent), mRequestCount(0), mNextBuffers(NULL) {
- mRunning = false;
-}
-
-EmulatedFakeCamera2::ConfigureThread::~ConfigureThread() {}
-
-status_t EmulatedFakeCamera2::ConfigureThread::readyToRun() {
- Mutex::Autolock lock(mInputMutex);
-
- ALOGV("Starting up ConfigureThread");
- mRequest = NULL;
- mActive = false;
- mRunning = true;
-
- mInputSignal.signal();
- return NO_ERROR;
-}
-
-status_t EmulatedFakeCamera2::ConfigureThread::waitUntilRunning() {
- Mutex::Autolock lock(mInputMutex);
- if (!mRunning) {
- ALOGV("Waiting for configure thread to start");
- mInputSignal.wait(mInputMutex);
- }
- return OK;
-}
-
-status_t EmulatedFakeCamera2::ConfigureThread::newRequestAvailable() {
- waitUntilRunning();
-
- Mutex::Autolock lock(mInputMutex);
-
- mActive = true;
- mInputSignal.signal();
-
- return OK;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::isStreamInUse(uint32_t id) {
- Mutex::Autolock lock(mInternalsMutex);
-
- if (mNextBuffers == NULL) return false;
- for (size_t i = 0; i < mNextBuffers->size(); i++) {
- if ((*mNextBuffers)[i].streamId == (int)id) return true;
- }
- return false;
-}
-
-int EmulatedFakeCamera2::ConfigureThread::getInProgressCount() {
- Mutex::Autolock lock(mInputMutex);
- return mRequestCount;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::threadLoop() {
- status_t res;
-
- // Check if we're currently processing or just waiting
- {
- Mutex::Autolock lock(mInputMutex);
- if (!mActive) {
- // Inactive, keep waiting until we've been signaled
- status_t res;
- res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
- if (res != NO_ERROR && res != TIMED_OUT) {
- ALOGE("%s: Error waiting for input requests: %d", __FUNCTION__, res);
- return false;
- }
- if (!mActive) return true;
- ALOGV("New request available");
- }
- // Active
- }
-
- if (mRequest == NULL) {
- Mutex::Autolock il(mInternalsMutex);
-
- ALOGV("Configure: Getting next request");
- res = mParent->mRequestQueueSrc->dequeue_request(mParent->mRequestQueueSrc,
- &mRequest);
- if (res != NO_ERROR) {
- ALOGE("%s: Error dequeuing next request: %d", __FUNCTION__, res);
- mParent->signalError();
- return false;
- }
- if (mRequest == NULL) {
- ALOGV("Configure: Request queue empty, going inactive");
- // No requests available, go into inactive mode
- Mutex::Autolock lock(mInputMutex);
- mActive = false;
- return true;
- } else {
- Mutex::Autolock lock(mInputMutex);
- mRequestCount++;
- }
-
- camera_metadata_entry_t type;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_TYPE, &type);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading request type", __FUNCTION__);
- mParent->signalError();
- return false;
- }
- bool success = false;
- ;
- switch (type.data.u8[0]) {
- case ANDROID_REQUEST_TYPE_CAPTURE:
- success = setupCapture();
- break;
- case ANDROID_REQUEST_TYPE_REPROCESS:
- success = setupReprocess();
- break;
- default:
- ALOGE("%s: Unexpected request type %d", __FUNCTION__, type.data.u8[0]);
- mParent->signalError();
- break;
- }
- if (!success) return false;
- }
-
- if (mWaitingForReadout) {
- bool readoutDone;
- readoutDone = mParent->mReadoutThread->waitForReady(kWaitPerLoop);
- if (!readoutDone) return true;
-
- if (mNextNeedsJpeg) {
- ALOGV("Configure: Waiting for JPEG compressor");
- } else {
- ALOGV("Configure: Waiting for sensor");
- }
- mWaitingForReadout = false;
- }
-
- if (mNextNeedsJpeg) {
- bool jpegDone;
- jpegDone = mParent->mJpegCompressor->waitForDone(kWaitPerLoop);
- if (!jpegDone) return true;
-
- ALOGV("Configure: Waiting for sensor");
- mNextNeedsJpeg = false;
- }
-
- if (mNextIsCapture) {
- return configureNextCapture();
- } else {
- return configureNextReprocess();
- }
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::setupCapture() {
- status_t res;
-
- mNextIsCapture = true;
- // Get necessary parameters for sensor config
- mParent->mControlThread->processRequest(mRequest);
-
- camera_metadata_entry_t streams;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
- &streams);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading output stream tag", __FUNCTION__);
- mParent->signalError();
- return false;
- }
-
- mNextBuffers = new Buffers;
- mNextNeedsJpeg = false;
- ALOGV("Configure: Setting up buffers for capture");
- for (size_t i = 0; i < streams.count; i++) {
- int streamId = streams.data.i32[i];
- const Stream &s = mParent->getStreamInfo(streamId);
- if (s.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
- ALOGE(
- "%s: Stream %d does not have a concrete pixel format, but "
- "is included in a request!",
- __FUNCTION__, streamId);
- mParent->signalError();
- return false;
- }
- StreamBuffer b;
- b.streamId = streamId; // streams.data.u8[i];
- b.width = s.width;
- b.height = s.height;
- b.format = s.format;
- b.stride = s.stride;
- mNextBuffers->push_back(b);
- ALOGV(
- "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, "
- "stride %d",
- i, b.streamId, b.width, b.height, b.format, b.stride);
- if (b.format == HAL_PIXEL_FORMAT_BLOB) {
- mNextNeedsJpeg = true;
- }
- }
-
- camera_metadata_entry_t e;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
- mNextFrameNumber = *e.data.i32;
-
- res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_EXPOSURE_TIME, &e);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading exposure time tag: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
- mNextExposureTime = *e.data.i64;
-
- res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_FRAME_DURATION, &e);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading frame duration tag", __FUNCTION__);
- mParent->signalError();
- return false;
- }
- mNextFrameDuration = *e.data.i64;
-
- if (mNextFrameDuration < mNextExposureTime + Sensor::kMinVerticalBlank) {
- mNextFrameDuration = mNextExposureTime + Sensor::kMinVerticalBlank;
- }
- res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_SENSITIVITY, &e);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading sensitivity tag", __FUNCTION__);
- mParent->signalError();
- return false;
- }
- mNextSensitivity = *e.data.i32;
-
- // Start waiting on readout thread
- mWaitingForReadout = true;
- ALOGV("Configure: Waiting for readout thread");
-
- return true;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::configureNextCapture() {
- bool vsync = mParent->mSensor->waitForVSync(kWaitPerLoop);
- if (!vsync) return true;
-
- Mutex::Autolock il(mInternalsMutex);
- ALOGV("Configure: Configuring sensor for capture %d", mNextFrameNumber);
- mParent->mSensor->setExposureTime(mNextExposureTime);
- mParent->mSensor->setFrameDuration(mNextFrameDuration);
- mParent->mSensor->setSensitivity(mNextSensitivity);
-
- getBuffers();
-
- ALOGV("Configure: Done configure for capture %d", mNextFrameNumber);
- mParent->mReadoutThread->setNextOperation(true, mRequest, mNextBuffers);
- mParent->mSensor->setDestinationBuffers(mNextBuffers);
-
- mRequest = NULL;
- mNextBuffers = NULL;
-
- Mutex::Autolock lock(mInputMutex);
- mRequestCount--;
-
- return true;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::setupReprocess() {
- status_t res;
-
- mNextNeedsJpeg = true;
- mNextIsCapture = false;
-
- camera_metadata_entry_t reprocessStreams;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_INPUT_STREAMS,
- &reprocessStreams);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading output stream tag", __FUNCTION__);
- mParent->signalError();
- return false;
- }
-
- mNextBuffers = new Buffers;
-
- ALOGV("Configure: Setting up input buffers for reprocess");
- for (size_t i = 0; i < reprocessStreams.count; i++) {
- int streamId = reprocessStreams.data.i32[i];
- const ReprocessStream &s = mParent->getReprocessStreamInfo(streamId);
- if (s.format != HAL_PIXEL_FORMAT_RGB_888) {
- ALOGE("%s: Only ZSL reprocessing supported!", __FUNCTION__);
- mParent->signalError();
- return false;
- }
- StreamBuffer b;
- b.streamId = -streamId;
- b.width = s.width;
- b.height = s.height;
- b.format = s.format;
- b.stride = s.stride;
- mNextBuffers->push_back(b);
- }
-
- camera_metadata_entry_t streams;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
- &streams);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading output stream tag", __FUNCTION__);
- mParent->signalError();
- return false;
- }
-
- ALOGV("Configure: Setting up output buffers for reprocess");
- for (size_t i = 0; i < streams.count; i++) {
- int streamId = streams.data.i32[i];
- const Stream &s = mParent->getStreamInfo(streamId);
- if (s.format != HAL_PIXEL_FORMAT_BLOB) {
- // TODO: Support reprocess to YUV
- ALOGE("%s: Non-JPEG output stream %d for reprocess not supported",
- __FUNCTION__, streamId);
- mParent->signalError();
- return false;
- }
- StreamBuffer b;
- b.streamId = streams.data.u8[i];
- b.width = s.width;
- b.height = s.height;
- b.format = s.format;
- b.stride = s.stride;
- mNextBuffers->push_back(b);
- ALOGV(
- "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, "
- "stride %d",
- i, b.streamId, b.width, b.height, b.format, b.stride);
- }
-
- camera_metadata_entry_t e;
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
- mNextFrameNumber = *e.data.i32;
-
- return true;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::configureNextReprocess() {
- Mutex::Autolock il(mInternalsMutex);
-
- getBuffers();
-
- ALOGV("Configure: Done configure for reprocess %d", mNextFrameNumber);
- mParent->mReadoutThread->setNextOperation(false, mRequest, mNextBuffers);
-
- mRequest = NULL;
- mNextBuffers = NULL;
-
- Mutex::Autolock lock(mInputMutex);
- mRequestCount--;
-
- return true;
-}
-
-bool EmulatedFakeCamera2::ConfigureThread::getBuffers() {
- status_t res;
- /** Get buffers to fill for this frame */
- for (size_t i = 0; i < mNextBuffers->size(); i++) {
- StreamBuffer &b = mNextBuffers->editItemAt(i);
-
- if (b.streamId > 0) {
- ALOGV("Configure: Dequeing buffer from stream %d", b.streamId);
- Stream s = mParent->getStreamInfo(b.streamId);
- res = s.ops->dequeue_buffer(s.ops, &(b.buffer));
- if (res != NO_ERROR || b.buffer == NULL) {
- ALOGE("%s: Unable to dequeue buffer from stream %d: %s (%d)",
- __FUNCTION__, b.streamId, strerror(-res), res);
- mParent->signalError();
- return false;
- }
-
- /* Lock the buffer from the perspective of the graphics mapper */
- res = GrallocModule::getInstance().lock(
- *(b.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0, s.width, s.height,
- (void **)&(b.img));
-
- if (res != NO_ERROR) {
- ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- s.ops->cancel_buffer(s.ops, b.buffer);
- mParent->signalError();
- return false;
- }
- } else {
- ALOGV("Configure: Acquiring buffer from reprocess stream %d",
- -b.streamId);
- ReprocessStream s = mParent->getReprocessStreamInfo(-b.streamId);
- res = s.ops->acquire_buffer(s.ops, &(b.buffer));
- if (res != NO_ERROR || b.buffer == NULL) {
- ALOGE(
- "%s: Unable to acquire buffer from reprocess stream %d: "
- "%s (%d)",
- __FUNCTION__, -b.streamId, strerror(-res), res);
- mParent->signalError();
- return false;
- }
-
- /* Lock the buffer from the perspective of the graphics mapper */
- res = GrallocModule::getInstance().lock(
- *(b.buffer), GRALLOC_USAGE_HW_CAMERA_READ, 0, 0, s.width, s.height,
- (void **)&(b.img));
- if (res != NO_ERROR) {
- ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- s.ops->release_buffer(s.ops, b.buffer);
- mParent->signalError();
- return false;
- }
- }
- }
- return true;
-}
-
-EmulatedFakeCamera2::ReadoutThread::ReadoutThread(EmulatedFakeCamera2 *parent)
- : Thread(false),
- mParent(parent),
- mRunning(false),
- mActive(false),
- mRequestCount(0),
- mRequest(NULL),
- mBuffers(NULL) {
- mInFlightQueue = new InFlightQueue[kInFlightQueueSize];
- mInFlightHead = 0;
- mInFlightTail = 0;
-}
-
-EmulatedFakeCamera2::ReadoutThread::~ReadoutThread() {
- delete[] mInFlightQueue;
-}
-
-status_t EmulatedFakeCamera2::ReadoutThread::readyToRun() {
- Mutex::Autolock lock(mInputMutex);
- ALOGV("Starting up ReadoutThread");
- mRunning = true;
- mInputSignal.signal();
- return NO_ERROR;
-}
-
-status_t EmulatedFakeCamera2::ReadoutThread::waitUntilRunning() {
- Mutex::Autolock lock(mInputMutex);
- if (!mRunning) {
- ALOGV("Waiting for readout thread to start");
- mInputSignal.wait(mInputMutex);
- }
- return OK;
-}
-
-bool EmulatedFakeCamera2::ReadoutThread::waitForReady(nsecs_t timeout) {
- status_t res;
- Mutex::Autolock lock(mInputMutex);
- while (!readyForNextCapture()) {
- res = mReadySignal.waitRelative(mInputMutex, timeout);
- if (res == TIMED_OUT) return false;
- if (res != OK) {
- ALOGE("%s: Error waiting for ready: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- return false;
- }
- }
- return true;
-}
-
-bool EmulatedFakeCamera2::ReadoutThread::readyForNextCapture() {
- return (mInFlightTail + 1) % kInFlightQueueSize != mInFlightHead;
-}
-
-void EmulatedFakeCamera2::ReadoutThread::setNextOperation(
- bool isCapture, camera_metadata_t *request, Buffers *buffers) {
- Mutex::Autolock lock(mInputMutex);
- if (!readyForNextCapture()) {
- ALOGE("In flight queue full, dropping captures");
- mParent->signalError();
- return;
- }
- mInFlightQueue[mInFlightTail].isCapture = isCapture;
- mInFlightQueue[mInFlightTail].request = request;
- mInFlightQueue[mInFlightTail].buffers = buffers;
- mInFlightTail = (mInFlightTail + 1) % kInFlightQueueSize;
- mRequestCount++;
-
- if (!mActive) {
- mActive = true;
- mInputSignal.signal();
- }
-}
-
-bool EmulatedFakeCamera2::ReadoutThread::isStreamInUse(uint32_t id) {
- // acquire in same order as threadLoop
- Mutex::Autolock iLock(mInternalsMutex);
- Mutex::Autolock lock(mInputMutex);
-
- size_t i = mInFlightHead;
- while (i != mInFlightTail) {
- for (size_t j = 0; j < mInFlightQueue[i].buffers->size(); j++) {
- if ((*(mInFlightQueue[i].buffers))[j].streamId == (int)id) return true;
- }
- i = (i + 1) % kInFlightQueueSize;
- }
-
- if (mBuffers != NULL) {
- for (i = 0; i < mBuffers->size(); i++) {
- if ((*mBuffers)[i].streamId == (int)id) return true;
- }
- }
-
- return false;
-}
-
-int EmulatedFakeCamera2::ReadoutThread::getInProgressCount() {
- Mutex::Autolock lock(mInputMutex);
-
- return mRequestCount;
-}
-
-bool EmulatedFakeCamera2::ReadoutThread::threadLoop() {
- static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms
- status_t res;
- int32_t frameNumber;
-
- // Check if we're currently processing or just waiting
- {
- Mutex::Autolock lock(mInputMutex);
- if (!mActive) {
- // Inactive, keep waiting until we've been signaled
- res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
- if (res != NO_ERROR && res != TIMED_OUT) {
- ALOGE("%s: Error waiting for capture requests: %d", __FUNCTION__, res);
- mParent->signalError();
- return false;
- }
- if (!mActive) return true;
- }
- // Active, see if we need a new request
- if (mRequest == NULL) {
- if (mInFlightHead == mInFlightTail) {
- // Go inactive
- ALOGV("Waiting for sensor data");
- mActive = false;
- return true;
- } else {
- Mutex::Autolock iLock(mInternalsMutex);
- mReadySignal.signal();
- mIsCapture = mInFlightQueue[mInFlightHead].isCapture;
- mRequest = mInFlightQueue[mInFlightHead].request;
- mBuffers = mInFlightQueue[mInFlightHead].buffers;
- mInFlightQueue[mInFlightHead].request = NULL;
- mInFlightQueue[mInFlightHead].buffers = NULL;
- mInFlightHead = (mInFlightHead + 1) % kInFlightQueueSize;
- ALOGV("Ready to read out request %p, %zu buffers", mRequest,
- mBuffers->size());
- }
- }
- }
-
- // Active with request, wait on sensor to complete
-
- nsecs_t captureTime;
-
- if (mIsCapture) {
- bool gotFrame;
- gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime);
-
- if (!gotFrame) return true;
- }
-
- Mutex::Autolock iLock(mInternalsMutex);
-
- camera_metadata_entry_t entry;
- if (!mIsCapture) {
- res =
- find_camera_metadata_entry(mRequest, ANDROID_SENSOR_TIMESTAMP, &entry);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading reprocessing timestamp: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
- captureTime = entry.data.i64[0];
- }
-
- res =
- find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &entry);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
- frameNumber = *entry.data.i32;
-
- res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_METADATA_MODE,
- &entry);
- if (res != NO_ERROR) {
- ALOGE("%s: error reading metadata mode tag: %s (%d)", __FUNCTION__,
- strerror(-res), res);
- mParent->signalError();
- return false;
- }
-
- // Got sensor data and request, construct frame and send it out
- ALOGV("Readout: Constructing metadata and frames for request %d",
- frameNumber);
-
- if (*entry.data.u8 == ANDROID_REQUEST_METADATA_MODE_FULL) {
- ALOGV("Readout: Metadata requested, constructing");
-
- camera_metadata_t *frame = NULL;
-
- size_t frame_entries = get_camera_metadata_entry_count(mRequest);
- size_t frame_data = get_camera_metadata_data_count(mRequest);
-
- // TODO: Dynamically calculate based on enabled statistics, etc
- frame_entries += 10;
- frame_data += 100;
-
- res = mParent->mFrameQueueDst->dequeue_frame(
- mParent->mFrameQueueDst, frame_entries, frame_data, &frame);
-
- if (res != NO_ERROR || frame == NULL) {
- ALOGE("%s: Unable to dequeue frame metadata buffer", __FUNCTION__);
- mParent->signalError();
- return false;
- }
-
- res = append_camera_metadata(frame, mRequest);
- if (res != NO_ERROR) {
- ALOGE("Unable to append request metadata");
- }
-
- if (mIsCapture) {
- add_camera_metadata_entry(frame, ANDROID_SENSOR_TIMESTAMP, &captureTime,
- 1);
-
- collectStatisticsMetadata(frame);
- // TODO: Collect all final values used from sensor in addition to
- // timestamp
- }
-
- ALOGV("Readout: Enqueue frame %d", frameNumber);
- mParent->mFrameQueueDst->enqueue_frame(mParent->mFrameQueueDst, frame);
- }
- ALOGV("Readout: Free request");
- res = mParent->mRequestQueueSrc->free_request(mParent->mRequestQueueSrc,
- mRequest);
- if (res != NO_ERROR) {
- ALOGE("%s: Unable to return request buffer to queue: %d", __FUNCTION__,
- res);
- mParent->signalError();
- return false;
- }
- mRequest = NULL;
-
- int compressedBufferIndex = -1;
- ALOGV("Readout: Processing %zu buffers", mBuffers->size());
- for (size_t i = 0; i < mBuffers->size(); i++) {
- const StreamBuffer &b = (*mBuffers)[i];
- ALOGV("Readout: Buffer %zu: Stream %d, %d x %d, format 0x%x, stride %d",
- i, b.streamId, b.width, b.height, b.format, b.stride);
- if (b.streamId > 0) {
- if (b.format == HAL_PIXEL_FORMAT_BLOB) {
- // Assumes only one BLOB buffer type per capture
- compressedBufferIndex = i;
- } else {
- ALOGV("Readout: Sending image buffer %zu (%p) to output stream %d",
- i, (void *)*(b.buffer), b.streamId);
- GrallocModule::getInstance().unlock(*(b.buffer));
- const Stream &s = mParent->getStreamInfo(b.streamId);
- res = s.ops->enqueue_buffer(s.ops, captureTime, b.buffer);
- if (res != OK) {
- ALOGE("Error enqueuing image buffer %p: %s (%d)", b.buffer,
- strerror(-res), res);
- mParent->signalError();
- }
- }
- }
- }
-
- if (compressedBufferIndex == -1) {
- delete mBuffers;
- } else {
- ALOGV("Readout: Starting JPEG compression for buffer %d, stream %d",
- compressedBufferIndex, (*mBuffers)[compressedBufferIndex].streamId);
- mJpegTimestamp = captureTime;
- // Takes ownership of mBuffers
- mParent->mJpegCompressor->start(mBuffers, this);
- }
- mBuffers = NULL;
-
- Mutex::Autolock l(mInputMutex);
- mRequestCount--;
- ALOGV("Readout: Done with request %d", frameNumber);
- return true;
-}
-
-void EmulatedFakeCamera2::ReadoutThread::onJpegDone(
- const StreamBuffer &jpegBuffer, bool success) {
- if (!success) {
- ALOGE("%s: Error queueing compressed image buffer %p", __FUNCTION__,
- jpegBuffer.buffer);
- mParent->signalError();
- return;
- }
-
- // Write to JPEG output stream
- ALOGV("%s: Compression complete, pushing to stream %d", __FUNCTION__,
- jpegBuffer.streamId);
-
- GrallocModule::getInstance().unlock(*(jpegBuffer.buffer));
- const Stream &s = mParent->getStreamInfo(jpegBuffer.streamId);
- s.ops->enqueue_buffer(s.ops, mJpegTimestamp, jpegBuffer.buffer);
-}
-
-void EmulatedFakeCamera2::ReadoutThread::onJpegInputDone(
- const StreamBuffer &inputBuffer) {
- status_t res;
- GrallocModule::getInstance().unlock(*(inputBuffer.buffer));
- const ReprocessStream &s =
- mParent->getReprocessStreamInfo(-inputBuffer.streamId);
- res = s.ops->release_buffer(s.ops, inputBuffer.buffer);
- if (res != OK) {
- ALOGE("Error releasing reprocess buffer %p: %s (%d)", inputBuffer.buffer,
- strerror(-res), res);
- mParent->signalError();
- }
-}
-
-status_t EmulatedFakeCamera2::ReadoutThread::collectStatisticsMetadata(
- camera_metadata_t *frame) {
- // Completely fake face rectangles, don't correspond to real faces in scene
- ALOGV("Readout: Collecting statistics metadata");
-
- status_t res;
- camera_metadata_entry_t entry;
- res = find_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_DETECT_MODE,
- &entry);
- if (res != OK) {
- ALOGE("%s: Unable to find face detect mode!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) return OK;
-
- // The coordinate system for the face regions is the raw sensor pixel
- // coordinates. Here, we map from the scene coordinates (0-19 in both axis)
- // to raw pixels, for the scene defined in fake-pipeline2/Scene.cpp. We
- // approximately place two faces on top of the windows of the house. No
- // actual faces exist there, but might one day. Note that this doesn't
- // account for the offsets used to account for aspect ratio differences, so
- // the rectangles don't line up quite right.
- const size_t numFaces = 2;
- int32_t rects[numFaces * 4] = {
- static_cast<int32_t>(mParent->mSensorWidth * 10 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 12 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 17 / 20),
-
- static_cast<int32_t>(mParent->mSensorWidth * 16 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 18 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 17 / 20)};
- // To simulate some kind of real detection going on, we jitter the rectangles
- // on each frame by a few pixels in each dimension.
- for (size_t i = 0; i < numFaces * 4; i++) {
- rects[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 6 - 3);
- }
- // The confidence scores (0-100) are similarly jittered.
- uint8_t scores[numFaces] = {85, 95};
- for (size_t i = 0; i < numFaces; i++) {
- scores[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 10 - 5);
- }
-
- res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_RECTANGLES,
- rects, numFaces * 4);
- if (res != OK) {
- ALOGE("%s: Unable to add face rectangles!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_SCORES, scores,
- numFaces);
- if (res != OK) {
- ALOGE("%s: Unable to add face scores!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE) return OK;
-
- // Advanced face detection options - add eye/mouth coordinates. The
- // coordinates in order are (leftEyeX, leftEyeY, rightEyeX, rightEyeY,
- // mouthX, mouthY). The mapping is the same as the face rectangles.
- int32_t features[numFaces * 6] = {
- static_cast<int32_t>(mParent->mSensorWidth * 10.5 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 11.5 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 11 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
-
- static_cast<int32_t>(mParent->mSensorWidth * 16.5 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 17.5 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
- static_cast<int32_t>(mParent->mSensorWidth * 17 / 20),
- static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
- };
- // Jitter these a bit less than the rects
- for (size_t i = 0; i < numFaces * 6; i++) {
- features[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 4 - 2);
- }
- // These are unique IDs that are used to identify each face while it's
- // visible to the detector (if a face went away and came back, it'd get a
- // new ID).
- int32_t ids[numFaces] = {100, 200};
-
- res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_LANDMARKS,
- features, numFaces * 6);
- if (res != OK) {
- ALOGE("%s: Unable to add face landmarks!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_IDS, ids,
- numFaces);
- if (res != OK) {
- ALOGE("%s: Unable to add face scores!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- return OK;
-}
-
-EmulatedFakeCamera2::ControlThread::ControlThread(EmulatedFakeCamera2 *parent)
- : Thread(false), mParent(parent) {
- mRunning = false;
-}
-
-EmulatedFakeCamera2::ControlThread::~ControlThread() {}
-
-status_t EmulatedFakeCamera2::ControlThread::readyToRun() {
- Mutex::Autolock lock(mInputMutex);
-
- ALOGV("Starting up ControlThread");
- mRunning = true;
- mStartAf = false;
- mCancelAf = false;
- mStartPrecapture = false;
-
- mControlMode = ANDROID_CONTROL_MODE_AUTO;
-
- mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
- mSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
-
- mAfMode = ANDROID_CONTROL_AF_MODE_AUTO;
- mAfModeChange = false;
-
- mAeMode = ANDROID_CONTROL_AE_MODE_ON;
- mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
-
- mAfTriggerId = 0;
- mPrecaptureTriggerId = 0;
-
- mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
- mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
- mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
-
- mExposureTime = kNormalExposureTime;
-
- mInputSignal.signal();
- return NO_ERROR;
-}
-
-status_t EmulatedFakeCamera2::ControlThread::waitUntilRunning() {
- Mutex::Autolock lock(mInputMutex);
- if (!mRunning) {
- ALOGV("Waiting for control thread to start");
- mInputSignal.wait(mInputMutex);
- }
- return OK;
-}
-
-// Override android.control.* fields with 3A values before sending request to
-// sensor
-status_t EmulatedFakeCamera2::ControlThread::processRequest(
- camera_metadata_t *request) {
- Mutex::Autolock lock(mInputMutex);
- // TODO: Add handling for all android.control.* fields here
- camera_metadata_entry_t mode;
- status_t res;
-
-#define READ_IF_OK(res, what, def) (((res) == OK) ? (what) : (uint8_t)(def))
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_MODE, &mode);
- mControlMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_MODE_OFF);
-
- // disable all 3A
- if (mControlMode == ANDROID_CONTROL_MODE_OFF) {
- mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
- mSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
- mAfMode = ANDROID_CONTROL_AF_MODE_OFF;
- mAeLock = ANDROID_CONTROL_AE_LOCK_ON;
- mAeMode = ANDROID_CONTROL_AE_MODE_OFF;
- mAfModeChange = true;
- mStartAf = false;
- mCancelAf = true;
- mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
- mAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;
- return res;
- }
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_EFFECT_MODE, &mode);
- mEffectMode =
- READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_EFFECT_MODE_OFF);
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_SCENE_MODE, &mode);
- mSceneMode =
- READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_SCENE_MODE_DISABLED);
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_AF_MODE, &mode);
- if (mAfMode != mode.data.u8[0]) {
- ALOGV("AF new mode: %d, old mode %d", mode.data.u8[0], mAfMode);
- mAfMode = mode.data.u8[0];
- mAfModeChange = true;
- mStartAf = false;
- mCancelAf = false;
- }
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_MODE, &mode);
- mAeMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_MODE_OFF);
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_LOCK, &mode);
- uint8_t aeLockVal =
- READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_LOCK_ON);
- bool aeLock = (aeLockVal == ANDROID_CONTROL_AE_LOCK_ON);
- if (mAeLock && !aeLock) {
- mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
- }
- mAeLock = aeLock;
-
- res = find_camera_metadata_entry(request, ANDROID_CONTROL_AWB_MODE, &mode);
- mAwbMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AWB_MODE_OFF);
-
- // TODO: Override more control fields
-
- if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) {
- camera_metadata_entry_t exposureTime;
- res = find_camera_metadata_entry(request, ANDROID_SENSOR_EXPOSURE_TIME,
- &exposureTime);
- if (res == OK) {
- exposureTime.data.i64[0] = mExposureTime;
- }
- }
-
-#undef READ_IF_OK
-
- return OK;
-}
-
-status_t EmulatedFakeCamera2::ControlThread::triggerAction(uint32_t msgType,
- int32_t ext1,
- int32_t ext2) {
- ALOGV("%s: Triggering %d (%d, %d)", __FUNCTION__, msgType, ext1, ext2);
- Mutex::Autolock lock(mInputMutex);
- switch (msgType) {
- case CAMERA2_TRIGGER_AUTOFOCUS:
- mAfTriggerId = ext1;
- mStartAf = true;
- mCancelAf = false;
- break;
- case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
- mAfTriggerId = ext1;
- mStartAf = false;
- mCancelAf = true;
- break;
- case CAMERA2_TRIGGER_PRECAPTURE_METERING:
- mPrecaptureTriggerId = ext1;
- mStartPrecapture = true;
- break;
- default:
- ALOGE("%s: Unknown action triggered: %d (arguments %d %d)", __FUNCTION__,
- msgType, ext1, ext2);
- return BAD_VALUE;
- }
- return OK;
-}
-
-const nsecs_t EmulatedFakeCamera2::ControlThread::kControlCycleDelay =
- 100 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAfDuration = 500 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAfDuration = 900 * MSEC;
-const float EmulatedFakeCamera2::ControlThread::kAfSuccessRate = 0.9;
-// Once every 5 seconds
-const float EmulatedFakeCamera2::ControlThread::kContinuousAfStartRate =
- kControlCycleDelay / 5.0 * SEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAeDuration = 500 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAeDuration = 2 * SEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMinPrecaptureAeDuration =
- 100 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxPrecaptureAeDuration =
- 400 * MSEC;
-// Once every 3 seconds
-const float EmulatedFakeCamera2::ControlThread::kAeScanStartRate =
- kControlCycleDelay / 3000000000.0;
-
-const nsecs_t EmulatedFakeCamera2::ControlThread::kNormalExposureTime =
- 10 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kExposureJump = 2 * MSEC;
-const nsecs_t EmulatedFakeCamera2::ControlThread::kMinExposureTime = 1 * MSEC;
-
-bool EmulatedFakeCamera2::ControlThread::threadLoop() {
- bool afModeChange = false;
- bool afTriggered = false;
- bool afCancelled = false;
- uint8_t afState;
- uint8_t afMode;
- int32_t afTriggerId;
- bool precaptureTriggered = false;
- uint8_t aeState;
- uint8_t aeMode;
- bool aeLock;
- int32_t precaptureTriggerId;
- nsecs_t nextSleep = kControlCycleDelay;
-
- {
- Mutex::Autolock lock(mInputMutex);
- if (mStartAf) {
- ALOGD("Starting AF trigger processing");
- afTriggered = true;
- mStartAf = false;
- } else if (mCancelAf) {
- ALOGD("Starting cancel AF trigger processing");
- afCancelled = true;
- mCancelAf = false;
- }
- afState = mAfState;
- afMode = mAfMode;
- afModeChange = mAfModeChange;
- mAfModeChange = false;
-
- afTriggerId = mAfTriggerId;
-
- if (mStartPrecapture) {
- ALOGD("Starting precapture trigger processing");
- precaptureTriggered = true;
- mStartPrecapture = false;
- }
- aeState = mAeState;
- aeMode = mAeMode;
- aeLock = mAeLock;
- precaptureTriggerId = mPrecaptureTriggerId;
- }
-
- if (afCancelled || afModeChange) {
- ALOGV("Resetting AF state due to cancel/mode change");
- afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
- updateAfState(afState, afTriggerId);
- mAfScanDuration = 0;
- mLockAfterPassiveScan = false;
- }
-
- if (afTriggered) {
- afState = processAfTrigger(afMode, afState);
- }
-
- afState = maybeStartAfScan(afMode, afState);
- afState = updateAfScan(afMode, afState, &nextSleep);
- updateAfState(afState, afTriggerId);
-
- if (precaptureTriggered) {
- aeState = processPrecaptureTrigger(aeMode, aeState);
- }
-
- aeState = maybeStartAeScan(aeMode, aeLock, aeState);
- aeState = updateAeScan(aeMode, aeLock, aeState, &nextSleep);
- updateAeState(aeState, precaptureTriggerId);
-
- int ret;
- timespec t;
- t.tv_sec = 0;
- t.tv_nsec = nextSleep;
- do {
- ret = nanosleep(&t, &t);
- } while (ret != 0);
-
- if (mAfScanDuration > 0) {
- mAfScanDuration -= nextSleep;
- }
- if (mAeScanDuration > 0) {
- mAeScanDuration -= nextSleep;
- }
-
- return true;
-}
-
-int EmulatedFakeCamera2::ControlThread::processAfTrigger(uint8_t afMode,
- uint8_t afState) {
- switch (afMode) {
- case ANDROID_CONTROL_AF_MODE_OFF:
- case ANDROID_CONTROL_AF_MODE_EDOF:
- // Do nothing
- break;
- case ANDROID_CONTROL_AF_MODE_MACRO:
- case ANDROID_CONTROL_AF_MODE_AUTO:
- switch (afState) {
- case ANDROID_CONTROL_AF_STATE_INACTIVE:
- case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
- case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
- // Start new focusing cycle
- mAfScanDuration =
- ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) +
- kMinAfDuration;
- afState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
- ALOGV("%s: AF scan start, duration %" PRId64 " ms", __FUNCTION__,
- mAfScanDuration / 1000000);
- break;
- case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
- // Ignore new request, already scanning
- break;
- default:
- ALOGE("Unexpected AF state in AUTO/MACRO AF mode: %d", afState);
- }
- break;
- case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
- switch (afState) {
- // Picture mode waits for passive scan to complete
- case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
- mLockAfterPassiveScan = true;
- break;
- case ANDROID_CONTROL_AF_STATE_INACTIVE:
- afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
- break;
- case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
- afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
- break;
- case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
- case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
- // Must cancel to get out of these states
- break;
- default:
- ALOGE("Unexpected AF state in CONTINUOUS_PICTURE AF mode: %d",
- afState);
- }
- break;
- case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
- switch (afState) {
- // Video mode does not wait for passive scan to complete
- case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
- case ANDROID_CONTROL_AF_STATE_INACTIVE:
- afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
- break;
- case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
- afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
- break;
- case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
- case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
- // Must cancel to get out of these states
- break;
- default:
- ALOGE("Unexpected AF state in CONTINUOUS_VIDEO AF mode: %d", afState);
- }
- break;
- default:
- break;
- }
- return afState;
-}
-
-int EmulatedFakeCamera2::ControlThread::maybeStartAfScan(uint8_t afMode,
- uint8_t afState) {
- if ((afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO ||
- afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) &&
- (afState == ANDROID_CONTROL_AF_STATE_INACTIVE ||
- afState == ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED)) {
- bool startScan = ((double)rand() / RAND_MAX) < kContinuousAfStartRate;
- if (startScan) {
- // Start new passive focusing cycle
- mAfScanDuration =
- ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) +
- kMinAfDuration;
- afState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
- ALOGV("%s: AF passive scan start, duration %" PRId64 " ms", __FUNCTION__,
- mAfScanDuration / 1000000);
- }
- }
- return afState;
-}
-
-int EmulatedFakeCamera2::ControlThread::updateAfScan(uint8_t afMode,
- uint8_t afState,
- nsecs_t *maxSleep) {
- if (!(afState == ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN ||
- afState == ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN)) {
- return afState;
- }
-
- if (mAfScanDuration <= 0) {
- ALOGV("%s: AF scan done", __FUNCTION__);
- switch (afMode) {
- case ANDROID_CONTROL_AF_MODE_MACRO:
- case ANDROID_CONTROL_AF_MODE_AUTO: {
- bool success = ((double)rand() / RAND_MAX) < kAfSuccessRate;
- if (success) {
- afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
- } else {
- afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
- }
- break;
- }
- case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
- if (mLockAfterPassiveScan) {
- afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
- mLockAfterPassiveScan = false;
- } else {
- afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
- }
- break;
- case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
- afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
- break;
- default:
- ALOGE("Unexpected AF mode in scan state");
- }
- } else {
- if (mAfScanDuration <= *maxSleep) {
- *maxSleep = mAfScanDuration;
- }
- }
- return afState;
-}
-
-void EmulatedFakeCamera2::ControlThread::updateAfState(uint8_t newState,
- int32_t triggerId) {
- Mutex::Autolock lock(mInputMutex);
- if (mAfState != newState) {
- ALOGV("%s: Autofocus state now %d, id %d", __FUNCTION__, newState,
- triggerId);
- mAfState = newState;
- mParent->sendNotification(CAMERA2_MSG_AUTOFOCUS, newState, triggerId, 0);
- }
-}
-
-int EmulatedFakeCamera2::ControlThread::processPrecaptureTrigger(
- uint8_t aeMode, uint8_t aeState) {
- switch (aeMode) {
- case ANDROID_CONTROL_AE_MODE_OFF:
- // Don't do anything for these
- return aeState;
- case ANDROID_CONTROL_AE_MODE_ON:
- case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
- case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
- case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
- // Trigger a precapture cycle
- aeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE;
- mAeScanDuration =
- ((double)rand() / RAND_MAX) *
- (kMaxPrecaptureAeDuration - kMinPrecaptureAeDuration) +
- kMinPrecaptureAeDuration;
- ALOGD("%s: AE precapture scan start, duration %" PRId64 " ms",
- __FUNCTION__, mAeScanDuration / 1000000);
- }
- return aeState;
-}
-
-int EmulatedFakeCamera2::ControlThread::maybeStartAeScan(uint8_t aeMode,
- bool aeLocked,
- uint8_t aeState) {
- if (aeLocked) return aeState;
- switch (aeMode) {
- case ANDROID_CONTROL_AE_MODE_OFF:
- break;
- case ANDROID_CONTROL_AE_MODE_ON:
- case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
- case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
- case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: {
- if (aeState != ANDROID_CONTROL_AE_STATE_INACTIVE &&
- aeState != ANDROID_CONTROL_AE_STATE_CONVERGED)
- break;
-
- bool startScan = ((double)rand() / RAND_MAX) < kAeScanStartRate;
- if (startScan) {
- mAeScanDuration =
- ((double)rand() / RAND_MAX) * (kMaxAeDuration - kMinAeDuration) +
- kMinAeDuration;
- aeState = ANDROID_CONTROL_AE_STATE_SEARCHING;
- ALOGV("%s: AE scan start, duration %" PRId64 " ms", __FUNCTION__,
- mAeScanDuration / 1000000);
- }
- }
- }
-
- return aeState;
-}
-
-int EmulatedFakeCamera2::ControlThread::updateAeScan(uint8_t /*aeMode*/,
- bool aeLock,
- uint8_t aeState,
- nsecs_t *maxSleep) {
- if (aeLock && aeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
- mAeScanDuration = 0;
- aeState = ANDROID_CONTROL_AE_STATE_LOCKED;
- } else if ((aeState == ANDROID_CONTROL_AE_STATE_SEARCHING) ||
- (aeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE)) {
- if (mAeScanDuration <= 0) {
- ALOGV("%s: AE scan done", __FUNCTION__);
- aeState = aeLock ? ANDROID_CONTROL_AE_STATE_LOCKED
- : ANDROID_CONTROL_AE_STATE_CONVERGED;
-
- Mutex::Autolock lock(mInputMutex);
- mExposureTime = kNormalExposureTime;
- } else {
- if (mAeScanDuration <= *maxSleep) {
- *maxSleep = mAeScanDuration;
- }
-
- int64_t exposureDelta =
- ((double)rand() / RAND_MAX) * 2 * kExposureJump - kExposureJump;
- Mutex::Autolock lock(mInputMutex);
- mExposureTime = mExposureTime + exposureDelta;
- if (mExposureTime < kMinExposureTime) mExposureTime = kMinExposureTime;
- }
- }
-
- return aeState;
-}
-
-void EmulatedFakeCamera2::ControlThread::updateAeState(uint8_t newState,
- int32_t triggerId) {
- Mutex::Autolock lock(mInputMutex);
- if (mAeState != newState) {
- ALOGV("%s: Autoexposure state now %d, id %d", __FUNCTION__, newState,
- triggerId);
- mAeState = newState;
- mParent->sendNotification(CAMERA2_MSG_AUTOEXPOSURE, newState, triggerId, 0);
- }
-}
-
-/** Private methods */
-
-status_t EmulatedFakeCamera2::constructStaticInfo(camera_metadata_t **info,
- bool sizeRequest) const {
- size_t entryCount = 0;
- size_t dataCount = 0;
- status_t ret;
-
-#define ADD_OR_SIZE(tag, data, count) \
- if ((ret = addOrSize(*info, sizeRequest, &entryCount, &dataCount, tag, data, \
- count)) != OK) \
- return ret
-
- // android.lens
-
- // 5 cm min focus distance for back camera, infinity (fixed focus) for front
- const float minFocusDistance = mFacingBack ? 1.0 / 0.05 : 0.0;
- ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &minFocusDistance, 1);
- // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front
- // const float hyperFocalDistance = mFacingBack ? 1.0 / 5.0 : 0.0;
- ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &minFocusDistance, 1);
-
- static const float focalLength = 3.30f; // mm
- ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &focalLength, 1);
- static const float aperture = 2.8f;
- ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &aperture, 1);
- static const float filterDensity = 0;
- ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, &filterDensity, 1);
- static const uint8_t availableOpticalStabilization =
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
- ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
- &availableOpticalStabilization, 1);
-
- static const int32_t lensShadingMapSize[] = {1, 1};
- ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize,
- sizeof(lensShadingMapSize) / sizeof(int32_t));
-
- int32_t lensFacing =
- mFacingBack ? ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
- ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1);
-
- // android.sensor
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
- Sensor::kExposureTimeRange, 2);
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
- &Sensor::kFrameDurationRange[1], 1);
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, Sensor::kSensitivityRange,
- sizeof(Sensor::kSensitivityRange) / sizeof(int32_t));
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
- &Sensor::kColorFilterArrangement, 1);
-
- static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2);
-
- const int32_t pixelArray[] = {mSensorWidth, mSensorHeight};
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArray, 2);
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, pixelArray, 2);
-
- ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL, &Sensor::kMaxRawValue, 1);
-
- static const int32_t blackLevelPattern[4] = {
- static_cast<int32_t>(Sensor::kBlackLevel),
- static_cast<int32_t>(Sensor::kBlackLevel),
- static_cast<int32_t>(Sensor::kBlackLevel),
- static_cast<int32_t>(Sensor::kBlackLevel)};
- ADD_OR_SIZE(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, blackLevelPattern,
- sizeof(blackLevelPattern) / sizeof(int32_t));
-
- // TODO: sensor color calibration fields
-
- // android.flash
- static const uint8_t flashAvailable = 0;
- ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1);
-
- static const int64_t flashChargeDuration = 0;
- ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1);
-
- // android.tonemap
-
- static const int32_t tonemapCurvePoints = 128;
- ADD_OR_SIZE(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1);
-
- // android.scaler
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_FORMATS, kAvailableFormats,
- sizeof(kAvailableFormats) / sizeof(uint32_t));
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_SIZES, &mAvailableRawSizes.front(),
- mAvailableRawSizes.size());
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
- kAvailableRawMinDurations,
- sizeof(kAvailableRawMinDurations) / sizeof(uint64_t));
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
- &mAvailableProcessedSizes.front(),
- mAvailableProcessedSizes.size());
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
- kAvailableProcessedMinDurations,
- sizeof(kAvailableProcessedMinDurations) / sizeof(uint64_t));
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, &mAvailableJpegSizes.front(),
- mAvailableJpegSizes.size());
-
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
- kAvailableJpegMinDurations,
- sizeof(kAvailableJpegMinDurations) / sizeof(uint64_t));
-
- static const float maxZoom = 10;
- ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1);
-
- // android.jpeg
-
- static const int32_t jpegThumbnailSizes[] = {0, 0, 160, 120, 320, 240};
- ADD_OR_SIZE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes,
- sizeof(jpegThumbnailSizes) / sizeof(int32_t));
-
- static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize;
- ADD_OR_SIZE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
-
- // android.stats
-
- static const uint8_t availableFaceDetectModes[] = {
- ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
- ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
- ANDROID_STATISTICS_FACE_DETECT_MODE_FULL};
-
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
- availableFaceDetectModes, sizeof(availableFaceDetectModes));
-
- static const int32_t maxFaceCount = 8;
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1);
-
- static const int32_t histogramSize = 64;
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, &histogramSize,
- 1);
-
- static const int32_t maxHistogramCount = 1000;
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT, &maxHistogramCount,
- 1);
-
- static const int32_t sharpnessMapSize[2] = {64, 64};
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, sharpnessMapSize,
- sizeof(sharpnessMapSize) / sizeof(int32_t));
-
- static const int32_t maxSharpnessMapValue = 1000;
- ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
- &maxSharpnessMapValue, 1);
-
- // android.control
-
- static const uint8_t availableSceneModes[] = {
- ANDROID_CONTROL_SCENE_MODE_DISABLED
- };
- ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, availableSceneModes,
- sizeof(availableSceneModes));
-
- static const uint8_t availableEffects[] = {ANDROID_CONTROL_EFFECT_MODE_OFF};
- ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects,
- sizeof(availableEffects));
-
- static const int32_t max3aRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0};
- ADD_OR_SIZE(ANDROID_CONTROL_MAX_REGIONS, max3aRegions,
- sizeof(max3aRegions) / sizeof(max3aRegions[0]));
-
- static const uint8_t availableAeModes[] = {ANDROID_CONTROL_AE_MODE_OFF,
- ANDROID_CONTROL_AE_MODE_ON};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_MODES, availableAeModes,
- sizeof(availableAeModes));
-
- static const camera_metadata_rational exposureCompensationStep = {1, 3};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP, &exposureCompensationStep,
- 1);
-
- int32_t exposureCompensationRange[] = {-9, 9};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, exposureCompensationRange,
- sizeof(exposureCompensationRange) / sizeof(int32_t));
-
- static const int32_t availableTargetFpsRanges[] = {5, 30, 15, 30};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
- availableTargetFpsRanges,
- sizeof(availableTargetFpsRanges) / sizeof(int32_t));
-
- static const uint8_t availableAntibandingModes[] = {
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
- availableAntibandingModes, sizeof(availableAntibandingModes));
-
- static const uint8_t availableAwbModes[] = {
- ANDROID_CONTROL_AWB_MODE_OFF,
- ANDROID_CONTROL_AWB_MODE_AUTO,
- ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
- ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
- ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
- ANDROID_CONTROL_AWB_MODE_SHADE};
- ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes,
- sizeof(availableAwbModes));
-
- static const uint8_t availableAfModesBack[] = {
- ANDROID_CONTROL_AF_MODE_OFF, ANDROID_CONTROL_AF_MODE_AUTO,
- ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
- ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE};
-
- static const uint8_t availableAfModesFront[] = {ANDROID_CONTROL_AF_MODE_OFF};
-
- if (mFacingBack) {
- ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesBack,
- sizeof(availableAfModesBack));
- } else {
- ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesFront,
- sizeof(availableAfModesFront));
- }
-
- static const uint8_t availableVstabModes[] = {
- ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF};
- ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
- availableVstabModes, sizeof(availableVstabModes));
-
-#undef ADD_OR_SIZE
- /** Allocate metadata if sizing */
- if (sizeRequest) {
- ALOGV(
- "Allocating %zu entries, %zu extra bytes for "
- "static camera info",
- entryCount, dataCount);
- *info = allocate_camera_metadata(entryCount, dataCount);
- if (*info == NULL) {
- ALOGE(
- "Unable to allocate camera static info"
- "(%zu entries, %zu bytes extra data)",
- entryCount, dataCount);
- return NO_MEMORY;
- }
- }
- return OK;
-}
-
-status_t EmulatedFakeCamera2::constructDefaultRequest(
- int request_template, camera_metadata_t **request, bool sizeRequest) const {
- size_t entryCount = 0;
- size_t dataCount = 0;
- status_t ret;
-
-#define ADD_OR_SIZE(tag, data, count) \
- if ((ret = addOrSize(*request, sizeRequest, &entryCount, &dataCount, tag, \
- data, count)) != OK) \
- return ret
-
- /** android.request */
-
- static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
- ADD_OR_SIZE(ANDROID_REQUEST_TYPE, &requestType, 1);
-
- static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
- ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);
-
- static const int32_t id = 0;
- ADD_OR_SIZE(ANDROID_REQUEST_ID, &id, 1);
-
- static const int32_t frameCount = 0;
- ADD_OR_SIZE(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1);
-
- // OUTPUT_STREAMS set by user
- entryCount += 1;
- dataCount += 5; // TODO: Should be maximum stream number
-
- /** android.lens */
-
- static const float focusDistance = 0;
- ADD_OR_SIZE(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
-
- static const float aperture = 2.8f;
- ADD_OR_SIZE(ANDROID_LENS_APERTURE, &aperture, 1);
-
- static const float focalLength = 5.0f;
- ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1);
-
- static const float filterDensity = 0;
- ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);
-
- static const uint8_t opticalStabilizationMode =
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
- ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
- &opticalStabilizationMode, 1);
-
- // FOCUS_RANGE set only in frame
-
- /** android.sensor */
-
- static const int64_t exposureTime = 10 * MSEC;
- ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1);
-
- static const int64_t frameDuration = 33333333L; // 1/30 s
- ADD_OR_SIZE(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1);
-
- static const int32_t sensitivity = 100;
- ADD_OR_SIZE(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1);
-
- // TIMESTAMP set only in frame
-
- /** android.flash */
-
- static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
- ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1);
-
- static const uint8_t flashPower = 10;
- ADD_OR_SIZE(ANDROID_FLASH_FIRING_POWER, &flashPower, 1);
-
- static const int64_t firingTime = 0;
- ADD_OR_SIZE(ANDROID_FLASH_FIRING_TIME, &firingTime, 1);
-
- /** Processing block modes */
- uint8_t hotPixelMode = 0;
- uint8_t demosaicMode = 0;
- uint8_t noiseMode = 0;
- uint8_t shadingMode = 0;
- uint8_t colorMode = 0;
- uint8_t tonemapMode = 0;
- uint8_t edgeMode = 0;
- switch (request_template) {
- case CAMERA2_TEMPLATE_STILL_CAPTURE:
- // fall-through
- case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
- // fall-through
- case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
- hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
- demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY;
- noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
- shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
- colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY;
- tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
- edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
- break;
- case CAMERA2_TEMPLATE_PREVIEW:
- // fall-through
- case CAMERA2_TEMPLATE_VIDEO_RECORD:
- // fall-through
- default:
- hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
- demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
- noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST;
- shadingMode = ANDROID_SHADING_MODE_FAST;
- colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST;
- tonemapMode = ANDROID_TONEMAP_MODE_FAST;
- edgeMode = ANDROID_EDGE_MODE_FAST;
- break;
- }
- ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
- ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
- ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1);
- ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1);
- ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1);
- ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
- ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1);
-
- /** android.noise */
- static const uint8_t noiseStrength = 5;
- ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1);
-
- /** android.color */
- static const float colorTransform[9] = {1.0f, 0.f, 0.f, 0.f, 1.f,
- 0.f, 0.f, 0.f, 1.f};
- ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9);
-
- /** android.tonemap */
- static const float tonemapCurve[4] = {0.f, 0.f, 1.f, 1.f};
- ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4);
- ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4);
- ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4);
-
- /** android.edge */
- static const uint8_t edgeStrength = 5;
- ADD_OR_SIZE(ANDROID_EDGE_STRENGTH, &edgeStrength, 1);
-
- /** android.scaler */
- static const int32_t cropRegion[3] = {0, 0,
- static_cast<int32_t>(mSensorWidth)};
- ADD_OR_SIZE(ANDROID_SCALER_CROP_REGION, cropRegion, 3);
-
- /** android.jpeg */
- static const int32_t jpegQuality = 80;
- ADD_OR_SIZE(ANDROID_JPEG_QUALITY, &jpegQuality, 1);
-
- static const int32_t thumbnailSize[2] = {640, 480};
- ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);
-
- static const int32_t thumbnailQuality = 80;
- ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1);
-
- static const double gpsCoordinates[2] = {0, 0};
- ADD_OR_SIZE(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2);
-
- static const uint8_t gpsProcessingMethod[32] = "None";
- ADD_OR_SIZE(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, 32);
-
- static const int64_t gpsTimestamp = 0;
- ADD_OR_SIZE(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1);
-
- static const int32_t jpegOrientation = 0;
- ADD_OR_SIZE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
-
- /** android.stats */
-
- static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
- ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
-
- static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
- ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
-
- static const uint8_t sharpnessMapMode =
- ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;
- ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
-
- // faceRectangles, faceScores, faceLandmarks, faceIds, histogram,
- // sharpnessMap only in frames
-
- /** android.control */
-
- uint8_t controlIntent = 0;
- switch (request_template) {
- case CAMERA2_TEMPLATE_PREVIEW:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
- break;
- case CAMERA2_TEMPLATE_STILL_CAPTURE:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
- break;
- case CAMERA2_TEMPLATE_VIDEO_RECORD:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
- break;
- case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
- break;
- case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
- break;
- default:
- controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
- break;
- }
- ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
-
- static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
- ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1);
-
- static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
- ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
-
- static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
- ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
-
- static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH;
- ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
-
- static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
- ADD_OR_SIZE(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
-
- static const int32_t controlRegions[5] = {
- 0, 0, static_cast<int32_t>(mSensorWidth),
- static_cast<int32_t>(mSensorHeight), 1000};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);
-
- static const int32_t aeExpCompensation = 0;
- ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1);
-
- static const int32_t aeTargetFpsRange[2] = {10, 30};
- ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2);
-
- static const uint8_t aeAntibandingMode =
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
- ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);
-
- static const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
- ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
-
- static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
- ADD_OR_SIZE(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
-
- ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5);
-
- uint8_t afMode = 0;
- switch (request_template) {
- case CAMERA2_TEMPLATE_PREVIEW:
- afMode = ANDROID_CONTROL_AF_MODE_AUTO;
- break;
- case CAMERA2_TEMPLATE_STILL_CAPTURE:
- afMode = ANDROID_CONTROL_AF_MODE_AUTO;
- break;
- case CAMERA2_TEMPLATE_VIDEO_RECORD:
- afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
- break;
- case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
- afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
- break;
- case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
- afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
- break;
- default:
- afMode = ANDROID_CONTROL_AF_MODE_AUTO;
- break;
- }
- ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1);
-
- ADD_OR_SIZE(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5);
-
- static const uint8_t vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
- ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1);
-
- // aeState, awbState, afState only in frame
-
- /** Allocate metadata if sizing */
- if (sizeRequest) {
- ALOGV(
- "Allocating %zu entries, %zu extra bytes for "
- "request template type %d",
- entryCount, dataCount, request_template);
- *request = allocate_camera_metadata(entryCount, dataCount);
- if (*request == NULL) {
- ALOGE(
- "Unable to allocate new request template type %d "
- "(%zu entries, %zu bytes extra data)",
- request_template, entryCount, dataCount);
- return NO_MEMORY;
- }
- }
- return OK;
-#undef ADD_OR_SIZE
-}
-
-status_t EmulatedFakeCamera2::addOrSize(camera_metadata_t *request,
- bool sizeRequest, size_t *entryCount,
- size_t *dataCount, uint32_t tag,
- const void *entryData,
- size_t entryDataCount) {
- if (!sizeRequest) {
- return add_camera_metadata_entry(request, tag, entryData, entryDataCount);
- } else {
- int type = get_camera_metadata_tag_type(tag);
- if (type < 0) return BAD_VALUE;
- (*entryCount)++;
- (*dataCount) +=
- calculate_camera_metadata_entry_data_size(type, entryDataCount);
- return OK;
- }
-}
-
-bool EmulatedFakeCamera2::isStreamInUse(uint32_t id) {
- // Assumes mMutex is locked; otherwise new requests could enter
- // configureThread while readoutThread is being checked
-
- // Order of isStreamInUse calls matters
- if (mConfigureThread->isStreamInUse(id) ||
- mReadoutThread->isStreamInUse(id) || mJpegCompressor->isStreamInUse(id)) {
- ALOGE("%s: Stream %d is in use in active requests!", __FUNCTION__, id);
- return true;
- }
- return false;
-}
-
-bool EmulatedFakeCamera2::isReprocessStreamInUse(uint32_t /*id*/) {
- // TODO: implement
- return false;
-}
-
-const Stream &EmulatedFakeCamera2::getStreamInfo(uint32_t streamId) {
- Mutex::Autolock lock(mMutex);
-
- return mStreams.valueFor(streamId);
-}
-
-const ReprocessStream &EmulatedFakeCamera2::getReprocessStreamInfo(
- uint32_t streamId) {
- Mutex::Autolock lock(mMutex);
-
- return mReprocessStreams.valueFor(streamId);
-}
-
-}; /* namespace android */