diff options
Diffstat (limited to 'guest/hals/camera/EmulatedFakeCamera2.cpp')
-rw-r--r-- | guest/hals/camera/EmulatedFakeCamera2.cpp | 2606 |
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 ¶ms) { - 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 */ |