1734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen/* 2734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Copyright (C) 2016 The Android Open Source Project 3734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * 4734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Licensed under the Apache License, Version 2.0 (the "License"); 5734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * you may not use this file except in compliance with the License. 6734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * You may obtain a copy of the License at 7734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * 8734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * http://www.apache.org/licenses/LICENSE-2.0 9734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * 10734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * Unless required by applicable law or agreed to in writing, software 11734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * distributed under the License is distributed on an "AS IS" BASIS, 12734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * See the License for the specific language governing permissions and 14734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen * limitations under the License. 15734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen */ 16734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 17734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Modified from hardware/libhardware/modules/camera/Camera.cpp 18734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 19734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <cstdlib> 2024e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen#include <memory> 2124e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen#include <vector> 22734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <stdio.h> 23734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <hardware/camera3.h> 24734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <sync/sync.h> 25734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <system/camera_metadata.h> 26734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <system/graphics.h> 27734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <utils/Mutex.h> 28abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen 29abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen#include "metadata/metadata_common.h" 30734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 31734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen//#define LOG_NDEBUG 0 32734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define LOG_TAG "Camera" 33734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <cutils/log.h> 34734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 35734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL) 36734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#include <utils/Trace.h> 37734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 383841a7f4951fe1498bf5ba88466def3ea18f8867Ari Hausman-Cohen#include "camera.h" 39734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 40734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen#define CAMERA_SYNC_TIMEOUT 5000 // in msecs 41734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 42734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohennamespace default_camera_hal { 43734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 44734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenextern "C" { 45734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Shim passed to the framework to close an opened device. 46734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int close_device(hw_device_t* dev) 47734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 48734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev); 49734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen Camera* cam = static_cast<Camera*>(cam_dev->priv); 50734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return cam->close(); 51734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 52734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} // extern "C" 53734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 54734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-CohenCamera::Camera(int id) 55734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen : mId(id), 56abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen mSettingsSet(false), 57734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mBusy(false), 58734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mCallbackOps(NULL), 590b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen mInFlightTracker(new RequestTracker) 60734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 61734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen memset(&mTemplates, 0, sizeof(mTemplates)); 62734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen memset(&mDevice, 0, sizeof(mDevice)); 63734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mDevice.common.tag = HARDWARE_DEVICE_TAG; 64900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4; 65734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mDevice.common.close = close_device; 66734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps); 67734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mDevice.priv = this; 68734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 69734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 70734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-CohenCamera::~Camera() 71734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 72734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 73734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 74345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohenint Camera::openDevice(const hw_module_t *module, hw_device_t **device) 75734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 76734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGI("%s:%d: Opening camera device", __func__, mId); 77734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ATRACE_CALL(); 78734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen android::Mutex::Autolock al(mDeviceLock); 79734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 80734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (mBusy) { 81734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Error! Camera device already opened", __func__, mId); 82734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return -EBUSY; 83734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 84734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 85345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen int connectResult = connect(); 86345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen if (connectResult != 0) { 87345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen return connectResult; 88345bd3a19b0723fd078b97487516ad98e277a8f4Ari Hausman-Cohen } 89734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mBusy = true; 90734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mDevice.common.module = const_cast<hw_module_t*>(module); 91734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen *device = &mDevice.common; 92734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 93734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 94734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 95734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::getInfo(struct camera_info *info) 96734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 97734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen info->device_version = mDevice.common.version; 98734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen initDeviceInfo(info); 99e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (!mStaticInfo) { 100e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen int res = loadStaticInfo(); 101e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (res) { 102e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return res; 103abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen } 104abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen } 105e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen info->static_camera_characteristics = mStaticInfo->raw_metadata(); 106e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen info->facing = mStaticInfo->facing(); 107e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen info->orientation = mStaticInfo->orientation(); 108abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen 109734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 110734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 111734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 112e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohenint Camera::loadStaticInfo() { 113e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen // Using a lock here ensures |mStaticInfo| will only ever be set once, 114e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen // even in concurrent situations. 115e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen android::Mutex::Autolock al(mStaticInfoLock); 116e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 117e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (mStaticInfo) { 118e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return 0; 119e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen } 120e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 121e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen std::unique_ptr<android::CameraMetadata> static_metadata = 122e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen std::make_unique<android::CameraMetadata>(); 123e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen int res = initStaticInfo(static_metadata.get()); 124e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (res) { 125e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen ALOGE("%s:%d: Failed to get static info from device.", 126e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen __func__, mId); 127e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return res; 128e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen } 129e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 130e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen mStaticInfo.reset(StaticProperties::NewStaticProperties( 131e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen std::move(static_metadata))); 132e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (!mStaticInfo) { 133e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen ALOGE("%s:%d: Failed to initialize static properties from device metadata.", 134e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen __func__, mId); 135e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return -ENODEV; 136e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen } 137e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 138e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return 0; 139e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen} 140e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 141734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::close() 142734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 143734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGI("%s:%d: Closing camera device", __func__, mId); 144734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ATRACE_CALL(); 145734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen android::Mutex::Autolock al(mDeviceLock); 146734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 147734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (!mBusy) { 148734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Error! Camera device not open", __func__, mId); 149734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return -EINVAL; 150734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 151734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 152c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen flush(); 1535acb400d18d40220df829193355736a0df782ab7Ari Hausman-Cohen disconnect(); 154734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mBusy = false; 155734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 156734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 157734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 158734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::initialize(const camera3_callback_ops_t *callback_ops) 159734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 160734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen int res; 161734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 162734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops); 163734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen mCallbackOps = callback_ops; 164734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen // per-device specific initialization 165734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen res = initDevice(); 166734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (res != 0) { 167734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Failed to initialize device!", __func__, mId); 168734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return res; 169734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 170734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 171734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 172734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 173734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenint Camera::configureStreams(camera3_stream_configuration_t *stream_config) 174734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 175ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen android::Mutex::Autolock al(mDeviceLock); 176abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen 177734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config); 178734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ATRACE_CALL(); 179734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 180ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Check that there are no in-flight requests. 181ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!mInFlightTracker->Empty()) { 182ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Can't configure streams while frames are in flight.", 183ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen __func__, mId); 184734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return -EINVAL; 185734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 186734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 187ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Verify the set of streams in aggregate, and perform configuration if valid. 188ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen int res = validateStreamConfiguration(stream_config); 18972fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen if (res) { 190ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Failed to validate stream set", __func__, mId); 191ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } else { 192ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Set up all streams. Since they've been validated, 193ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // this should only result in fatal (-ENODEV) errors. 194ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // This occurs after validation to ensure that if there 195ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // is a non-fatal error, the stream configuration doesn't change states. 196ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen res = setupStreams(stream_config); 197ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (res) { 198ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Failed to setup stream set", __func__, mId); 199ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } 20072fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen } 201734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 202ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Set trackers based on result. 20372fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen if (!res) { 204ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Success, set up the in-flight trackers for the new streams. 205ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen mInFlightTracker->SetStreamConfiguration(*stream_config); 206ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Must provide new settings for the new configuration. 207ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen mSettingsSet = false; 2080b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen } else if (res != -EINVAL) { 209ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Fatal error, the old configuration is invalid. 2100b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen mInFlightTracker->ClearStreamConfiguration(); 21172fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen } 212ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // On a non-fatal error the old configuration, if any, remains valid. 21372fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen return res; 214734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 215734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 216ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohenint Camera::validateStreamConfiguration( 217ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen const camera3_stream_configuration_t* stream_config) 218734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 219ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Check that the configuration is well-formed. 220ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (stream_config == nullptr) { 221ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: NULL stream configuration array", __func__, mId); 222ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 223ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } else if (stream_config->num_streams == 0) { 224ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Empty stream configuration array", __func__, mId); 225ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 226ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } else if (stream_config->streams == nullptr) { 227734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: NULL stream configuration streams", __func__, mId); 228ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 229734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 23072fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen 231ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Check that the configuration is supported. 232ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Make sure static info has been initialized before trying to use it. 233ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!mStaticInfo) { 234ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen int res = loadStaticInfo(); 23572fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen if (res) { 236ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return res; 23772fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen } 238734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 239ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!mStaticInfo->StreamConfigurationSupported(stream_config)) { 240ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Stream configuration does not match static " 241ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen "metadata restrictions.", __func__, mId); 242ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 243ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } 244ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen 245ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Dataspace support is poorly documented - unclear if the expectation 246ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // is that a device supports ALL dataspaces that could match a given 247ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // format. For now, defer to child class implementation. 248ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Rotation support isn't described by metadata, so must defer to device. 249ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!validateDataspacesAndRotations(stream_config)) { 250ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Device can not handle configuration " 251ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen "dataspaces or rotations.", __func__, mId); 252ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 253ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } 254ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen 25572fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen return 0; 256734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 257734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 258734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenbool Camera::isValidTemplateType(int type) 259734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 260900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen return type > 0 && type < CAMERA3_TEMPLATE_COUNT; 261734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 262734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 263734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst camera_metadata_t* Camera::constructDefaultRequestSettings(int type) 264734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 265734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: type=%d", __func__, mId, type); 266734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 267734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (!isValidTemplateType(type)) { 268734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type); 269734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return NULL; 270734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 271499258437667b7aaaf31d27c1dbe0bfa0281c75dAri Hausman-Cohen 272abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen if (!mTemplates[type]) { 273e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen // Check if the device has the necessary features 274e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen // for the requested template. If not, don't bother. 275e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen if (!mStaticInfo->TemplateSupported(type)) { 276e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen ALOGW("%s:%d: Camera does not support template type %d", 277e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen __func__, mId, type); 278e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen return NULL; 279e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen } 280e31e1f33b482b7459b63bf1f2198556020c95332Ari Hausman-Cohen 281abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen // Initialize this template if it hasn't been initialized yet. 282abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen std::unique_ptr<android::CameraMetadata> new_template = 283abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen std::make_unique<android::CameraMetadata>(); 284abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen int res = initTemplate(type, new_template.get()); 285abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen if (res || !new_template) { 286abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen ALOGE("%s:%d: Failed to generate template of type: %d", 287abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen __func__, mId, type); 288abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen return NULL; 289abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen } 290abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen mTemplates[type] = std::move(new_template); 291abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen } 292abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen 293abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen // The "locking" here only causes non-const methods to fail, 294abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen // which is not a problem since the CameraMetadata being locked 295abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen // is already const. Destructing automatically "unlocks". 296abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen return mTemplates[type]->getAndLock(); 297734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 298734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 2992738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenint Camera::processCaptureRequest(camera3_capture_request_t *temp_request) 300734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 30124e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen int res; 302c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // TODO(b/32917568): A capture request submitted or ongoing during a flush 303c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // should be returned with an error; for now they are mutually exclusive. 304c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen android::Mutex::Autolock al(mFlushLock); 305734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 306734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ATRACE_CALL(); 307734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3082738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen if (temp_request == NULL) { 309734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: NULL request recieved", __func__, mId); 310734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return -EINVAL; 311734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 312734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3132738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Make a persistent copy of request, since otherwise it won't live 3142738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // past the end of this method. 3152738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request); 316734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 317ad6fe2b033997ab0401b0a519b18cea6e957dac0Ari Hausman-Cohen ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number); 3182738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen 319ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!mInFlightTracker->CanAddRequest(*request)) { 320ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Streams are full or frame number is not unique. 321ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Can not add request.", __func__, mId); 322ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen return -EINVAL; 323ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen } 324ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen 3252738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Null/Empty indicates use last settings 3262738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen if (request->settings.isEmpty() && !mSettingsSet) { 3272738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen ALOGE("%s:%d: NULL settings without previous set Frame:%d", 3282738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen __func__, mId, request->frame_number); 329abbf9cc0bd4160642c36f7bd47c0277a8bf17adfAri Hausman-Cohen return -EINVAL; 330734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 331734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 332734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (request->input_buffer != NULL) { 333734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId, 3342738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen request->input_buffer.get()); 335734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } else { 336734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: Capturing new frame.", __func__, mId); 3372738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen } 338734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 339ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen if (!isValidRequestSettings(request->settings)) { 340ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen ALOGE("%s:%d: Invalid request settings.", __func__, mId); 3412738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen return -EINVAL; 342734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 343734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3442738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Pre-process output buffers. 3452738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen if (request->output_buffers.size() <= 0) { 346734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId, 3472738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen request->output_buffers.size()); 348734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return -EINVAL; 349734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 3502738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen for (auto& output_buffer : request->output_buffers) { 3512738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen res = preprocessCaptureBuffer(&output_buffer); 352734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (res) 35324e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen return -ENODEV; 35424e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen } 355734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3560b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen // Add the request to tracking. 3570b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen if (!mInFlightTracker->Add(request)) { 3580b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen ALOGE("%s:%d: Failed to track request for frame %d.", 3590b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen __func__, mId, request->frame_number); 3600b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen return -ENODEV; 3610b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen } 3620b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen 363ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // Valid settings have been provided (mSettingsSet is a misnomer; 364ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // all that matters is that a previous request with valid settings 365ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen // has been passed to the device, not that they've been set). 366ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen mSettingsSet = true; 367ef52310613342dd51a928af92e3287f6783ae8c7Ari Hausman-Cohen 3682738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Send the request off to the device for completion. 3692738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen enqueueRequest(request); 370734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3712738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Request is now in flight. The device will call completeRequest 3722738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // asynchronously when it is done filling buffers and metadata. 373734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 374734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 375734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 3762738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenvoid Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err) 377734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 3780b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen if (!mInFlightTracker->Remove(request)) { 379c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen ALOGE("%s:%d: Completed request %p is not being tracked. " 380c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen "It may have been cleared out during a flush.", 3810b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen __func__, mId, request.get()); 3822738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen return; 3832738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen } 3842738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen 3850b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen // Since |request| has been removed from the tracking, this method 3860b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen // MUST call sendResult (can still return a result in an error state, e.g. 3870b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen // through completeRequestWithError) so the frame doesn't get lost. 3880b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen 3890b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen if (err) { 3900b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen ALOGE("%s:%d: Error completing request for frame %d.", 3910b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen __func__, mId, request->frame_number); 3920b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen completeRequestWithError(request); 3930b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen return; 3940b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen } 3950b2113c54f716e710aff60989cba5d5f0b080f0fAri Hausman-Cohen 3962738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Notify the framework with the shutter time (extracted from the result). 3972738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen int64_t timestamp = 0; 3982738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // TODO(b/31360070): The general metadata methods should be part of the 3992738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // default_camera_hal namespace, not the v4l2_camera_hal namespace. 4002738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen int res = v4l2_camera_hal::SingleTagValue( 4012738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen request->settings, ANDROID_SENSOR_TIMESTAMP, ×tamp); 4022738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen if (res) { 4032738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen ALOGE("%s:%d: Request for frame %d is missing required metadata.", 4042738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen __func__, mId, request->frame_number); 405fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // TODO(b/31653322): Send RESULT error. 406fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // For now sending REQUEST error instead. 407fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen completeRequestWithError(request); 4082738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen return; 4092738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen } 4102738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen notifyShutter(request->frame_number, timestamp); 4112738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen 4122738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // TODO(b/31653322): Check all returned buffers for errors 4132738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // (if any, send BUFFER error). 4142738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen 415fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen sendResult(request); 416734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 417734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 418c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohenint Camera::flush() 419c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen{ 420c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen ALOGV("%s:%d: Flushing.", __func__, mId); 421c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // TODO(b/32917568): Synchronization. Behave "appropriately" 422c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // (i.e. according to camera3.h) if process_capture_request() 423c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // is called concurrently with this (in either order). 424c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // Since the callback to completeRequest also may happen on a separate 425c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // thread, this function should behave nicely concurrently with that too. 426c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen android::Mutex::Autolock al(mFlushLock); 427c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen 428c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen std::set<std::shared_ptr<CaptureRequest>> requests; 429c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen mInFlightTracker->Clear(&requests); 430c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen for (auto& request : requests) { 431c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // TODO(b/31653322): See camera3.h. Should return different error 432c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // depending on status of the request. 433c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen completeRequestWithError(request); 434c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen } 435c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen 436c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size()); 437c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen 438c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen // Call down into the device flushing. 439c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen return flushBuffers(); 440c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen} 441c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen 4422738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohenint Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer) 443734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 44424e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen int res; 4452738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // TODO(b/29334616): This probably should be non-blocking; part 4462738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // of the asynchronous request processing. 4472738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen if (buffer->acquire_fence != -1) { 4482738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT); 449734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen if (res == -ETIME) { 450734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Timeout waiting on buffer acquire fence", 451734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen __func__, mId); 452734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return res; 453734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } else if (res) { 454734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)", 455734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen __func__, mId, strerror(-res), res); 456734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return res; 457734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 458eadafff6aeee592ba373c1465f5d8feac3ef9d48Eric Jeong ::close(buffer->acquire_fence); 459734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 460734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 4612738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // Acquire fence has been waited upon. 4622738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen buffer->acquire_fence = -1; 4632738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen // No release fence waiting unless the device sets it. 4642738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen buffer->release_fence = -1; 46524e541c9258e9b11a0fb92f7a70b9e3b56b15f6fAri Hausman-Cohen 4662738a9c3b5f8f1dfc208841e72035c72d8a8ebb5Ari Hausman-Cohen buffer->status = CAMERA3_BUFFER_STATUS_OK; 467734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return 0; 468734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 469734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 470734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenvoid Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp) 471734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 472fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen camera3_notify_msg_t message; 473fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen memset(&message, 0, sizeof(message)); 474fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.type = CAMERA3_MSG_SHUTTER; 475fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.message.shutter.frame_number = frame_number; 476fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.message.shutter.timestamp = timestamp; 477fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen mCallbackOps->notify(mCallbackOps, &message); 478fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen} 479fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen 480fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohenvoid Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request) 481fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen{ 482fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // Send an error notification. 483fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen camera3_notify_msg_t message; 484fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen memset(&message, 0, sizeof(message)); 485fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.type = CAMERA3_MSG_ERROR; 486fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.message.error.frame_number = request->frame_number; 487fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.message.error.error_stream = nullptr; 488fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST; 489fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen mCallbackOps->notify(mCallbackOps, &message); 490fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen 491fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // TODO(b/31856611): Ensure all the buffers indicate their error status. 492fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen 493fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // Send the errored out result. 494fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen sendResult(request); 495fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen} 496fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen 497fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohenvoid Camera::sendResult(std::shared_ptr<CaptureRequest> request) { 498fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // Fill in the result struct 499fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // (it only needs to live until the end of the framework callback). 500fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen camera3_capture_result_t result { 501fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen request->frame_number, 502fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen request->settings.getAndLock(), 5039df082e93368ae2cc86e706f1f106a4422df1e42Dmitry Shmidt static_cast<uint32_t>(request->output_buffers.size()), 504fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen request->output_buffers.data(), 505fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen request->input_buffer.get(), 506fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen 1 // Total result; only 1 part. 507fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen }; 508fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen // Make the framework callback. 509fb161115c80816a90f252313d53bbb599b90dd6cAri Hausman-Cohen mCallbackOps->process_capture_result(mCallbackOps, &result); 510734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 511734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 512734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenvoid Camera::dump(int fd) 513734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 514734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd); 515734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen ATRACE_CALL(); 516734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen android::Mutex::Autolock al(mDeviceLock); 517734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 518734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy); 519734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 520734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen // TODO: dump all settings 521734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 522734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 523734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst char* Camera::templateToString(int type) 524734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 525734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen switch (type) { 526734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen case CAMERA3_TEMPLATE_PREVIEW: 527734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "CAMERA3_TEMPLATE_PREVIEW"; 528734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen case CAMERA3_TEMPLATE_STILL_CAPTURE: 529734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "CAMERA3_TEMPLATE_STILL_CAPTURE"; 530734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen case CAMERA3_TEMPLATE_VIDEO_RECORD: 531734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "CAMERA3_TEMPLATE_VIDEO_RECORD"; 532734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: 533734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT"; 534734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: 535734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG"; 536734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen } 537734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen // TODO: support vendor templates 538734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return "Invalid template type!"; 539734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 540734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 541734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenextern "C" { 542734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen// Get handle to camera from device priv data 543734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic Camera *camdev_to_camera(const camera3_device_t *dev) 544734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 545734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return reinterpret_cast<Camera*>(dev->priv); 546734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 547734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 548734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int initialize(const camera3_device_t *dev, 549734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen const camera3_callback_ops_t *callback_ops) 550734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 551734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return camdev_to_camera(dev)->initialize(callback_ops); 552734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 553734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 554734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int configure_streams(const camera3_device_t *dev, 555734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen camera3_stream_configuration_t *stream_list) 556734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 557734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return camdev_to_camera(dev)->configureStreams(stream_list); 558734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 559734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 560734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic const camera_metadata_t *construct_default_request_settings( 561734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen const camera3_device_t *dev, int type) 562734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 563734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return camdev_to_camera(dev)->constructDefaultRequestSettings(type); 564734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 565734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 566734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic int process_capture_request(const camera3_device_t *dev, 567734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen camera3_capture_request_t *request) 568734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 569734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen return camdev_to_camera(dev)->processCaptureRequest(request); 570734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 571734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 572734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenstatic void dump(const camera3_device_t *dev, int fd) 573734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 574734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen camdev_to_camera(dev)->dump(fd); 575734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 576734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 577c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohenstatic int flush(const camera3_device_t *dev) 578734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen{ 579c5a485245169c1da02c4a5bfb80876cff68882ebAri Hausman-Cohen return camdev_to_camera(dev)->flush(); 580734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} 581734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 582734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen} // extern "C" 583734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 584734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohenconst camera3_device_ops_t Camera::sOps = { 585734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .initialize = default_camera_hal::initialize, 586734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .configure_streams = default_camera_hal::configure_streams, 587900c1e3a0c7eda1c630ff72414f061975a4e8379Ari Hausman-Cohen .register_stream_buffers = nullptr, 588734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .construct_default_request_settings 589734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen = default_camera_hal::construct_default_request_settings, 590734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .process_capture_request = default_camera_hal::process_capture_request, 59172fddb3db4bf04e87f0f68b38dfc6782598a6214Ari Hausman-Cohen .get_metadata_vendor_tag_ops = nullptr, 592734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .dump = default_camera_hal::dump, 593734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .flush = default_camera_hal::flush, 594734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen .reserved = {0}, 595734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen}; 596734421538c99e1910fc7ea998670d976aa96b107Ari Hausman-Cohen 5973841a7f4951fe1498bf5ba88466def3ea18f8867Ari Hausman-Cohen} // namespace default_camera_hal 598