blob: 393adf1ef5d471c17e23791b7421ac1e1e58dd88 [file] [log] [blame]
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Contains implementation of a class EmulatedFakeCamera2 that encapsulates
19 * functionality of an advanced fake camera.
20 */
21
Jorge E. Moreira7737f9a2019-10-01 14:10:49 -070022#include <inttypes.h>
23
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070024#include <algorithm>
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070025#include <cstdint>
26#include <iterator>
27
28#define LOG_NDEBUG 0
29#define LOG_TAG "EmulatedCamera_FakeCamera2"
30#include <utils/Log.h>
31
Greg Hartmanffd70fc2018-01-04 19:32:38 -080032#include "EmulatedCameraFactory.h"
33#include "EmulatedFakeCamera2.h"
34#include "GrallocModule.h"
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070035
36#define ERROR_CAMERA_NOT_PRESENT -EPIPE
37
38#define CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT 0xFFFFFFFF
39
Cody Schuffelen4573f362019-11-22 17:59:09 -080040template <typename T, size_t N>
41char (&ArraySizeHelper(T (&array)[N]))[N];
42
43template <typename T, size_t N>
44char (&ArraySizeHelper(const T (&array)[N]))[N];
45
46#define arraysize(array) (sizeof(ArraySizeHelper(array)))
47
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070048namespace android {
49
50const int64_t USEC = 1000LL;
51const int64_t MSEC = USEC * 1000LL;
52const int64_t SEC = MSEC * 1000LL;
53
54const uint32_t EmulatedFakeCamera2::kAvailableFormats[] = {
Greg Hartmanffd70fc2018-01-04 19:32:38 -080055 HAL_PIXEL_FORMAT_RAW16,
Greg Hartmanffd70fc2018-01-04 19:32:38 -080056 HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888,
57 // HAL_PIXEL_FORMAT_YV12,
58 HAL_PIXEL_FORMAT_YCrCb_420_SP};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070059
60const uint32_t EmulatedFakeCamera2::kAvailableRawSizes[2] = {
61 640, 480
62 // mSensorWidth, mSensorHeight
63};
64
65const uint64_t EmulatedFakeCamera2::kAvailableRawMinDurations[1] = {
Greg Hartmanffd70fc2018-01-04 19:32:38 -080066 static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070067
68const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesBack[4] = {
69 640, 480, 320, 240
70 // mSensorWidth, mSensorHeight
71};
72
73const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesFront[4] = {
74 320, 240, 160, 120
75 // mSensorWidth, mSensorHeight
76};
77
78const uint64_t EmulatedFakeCamera2::kAvailableProcessedMinDurations[1] = {
Greg Hartmanffd70fc2018-01-04 19:32:38 -080079 static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070080
81const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesBack[2] = {
82 640, 480
83 // mSensorWidth, mSensorHeight
84};
85
86const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesFront[2] = {
87 320, 240
88 // mSensorWidth, mSensorHeight
89};
90
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070091const uint64_t EmulatedFakeCamera2::kAvailableJpegMinDurations[1] = {
Greg Hartmanffd70fc2018-01-04 19:32:38 -080092 static_cast<uint64_t>(Sensor::kFrameDurationRange[0])};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -070093
Greg Hartmanffd70fc2018-01-04 19:32:38 -080094EmulatedFakeCamera2::EmulatedFakeCamera2(int cameraId, bool facingBack,
95 struct hw_module_t *module)
96 : EmulatedCamera2(cameraId, module),
97 mFacingBack(facingBack),
98 mIsConnected(false) {
99 ALOGD("Constructing emulated fake camera 2 facing %s",
100 facingBack ? "back" : "front");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700101}
102
103EmulatedFakeCamera2::~EmulatedFakeCamera2() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800104 if (mCameraInfo != NULL) {
105 free_camera_metadata(mCameraInfo);
106 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700107}
108
109/****************************************************************************
110 * Public API overrides
111 ***************************************************************************/
112
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800113status_t EmulatedFakeCamera2::Initialize(const cvd::CameraDefinition &params) {
114 status_t res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700115
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800116 for (size_t index = 0; index < params.resolutions.size(); ++index) {
117 mAvailableRawSizes.push_back(params.resolutions[index].width);
118 mAvailableRawSizes.push_back(params.resolutions[index].height);
119 mAvailableProcessedSizes.push_back(params.resolutions[index].width);
120 mAvailableProcessedSizes.push_back(params.resolutions[index].height);
121 mAvailableJpegSizes.push_back(params.resolutions[index].width);
122 mAvailableJpegSizes.push_back(params.resolutions[index].height);
123 }
124
125 // Find max width/height
126 int32_t width = 0, height = 0;
127 for (size_t index = 0; index < params.resolutions.size(); ++index) {
128 if (width <= params.resolutions[index].width &&
129 height <= params.resolutions[index].height) {
130 width = params.resolutions[index].width;
131 height = params.resolutions[index].height;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700132 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800133 }
134 if (width < 640 || height < 480) {
135 width = 640;
136 height = 480;
137 }
138 mSensorWidth = width;
139 mSensorHeight = height;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700140
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800141 /* TODO(ender): probably should drop this. */
142 std::copy(kAvailableRawSizes,
143 kAvailableRawSizes + arraysize(kAvailableRawSizes),
144 std::back_inserter(mAvailableRawSizes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700145
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800146 if (params.orientation == cvd::CameraDefinition::kFront) {
147 std::copy(kAvailableProcessedSizesFront,
148 kAvailableProcessedSizesFront +
149 arraysize(kAvailableProcessedSizesFront),
150 std::back_inserter(mAvailableProcessedSizes));
151 std::copy(kAvailableJpegSizesFront,
152 kAvailableJpegSizesFront + arraysize(kAvailableJpegSizesFront),
153 std::back_inserter(mAvailableJpegSizes));
154 } else {
155 std::copy(
156 kAvailableProcessedSizesBack,
157 kAvailableProcessedSizesBack + arraysize(kAvailableProcessedSizesBack),
158 mAvailableProcessedSizes.begin());
159 std::copy(kAvailableJpegSizesBack,
160 kAvailableJpegSizesBack + arraysize(kAvailableJpegSizesBack),
161 mAvailableJpegSizes.begin());
162 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700163
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800164 res = constructStaticInfo(&mCameraInfo, true);
165 if (res != OK) {
166 ALOGE("%s: Unable to allocate static info: %s (%d)", __FUNCTION__,
167 strerror(-res), res);
168 return res;
169 }
170 res = constructStaticInfo(&mCameraInfo, false);
171 if (res != OK) {
172 ALOGE("%s: Unable to fill in static info: %s (%d)", __FUNCTION__,
173 strerror(-res), res);
174 return res;
175 }
176 if (res != OK) return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700177
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800178 mNextStreamId = 1;
179 mNextReprocessStreamId = 1;
180 mRawStreamCount = 0;
181 mProcessedStreamCount = 0;
182 mJpegStreamCount = 0;
183 mReprocessStreamCount = 0;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700184
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800185 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700186}
187
188/****************************************************************************
189 * Camera module API overrides
190 ***************************************************************************/
191
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800192status_t EmulatedFakeCamera2::connectCamera(hw_device_t **device) {
193 status_t res;
194 ALOGV("%s", __FUNCTION__);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700195
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800196 {
197 Mutex::Autolock l(mMutex);
198 if (!mStatusPresent) {
199 ALOGE("%s: Camera ID %d is unplugged", __FUNCTION__, mCameraID);
200 return -ENODEV;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700201 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800202 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700203
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800204 mConfigureThread = new ConfigureThread(this);
205 mReadoutThread = new ReadoutThread(this);
206 mControlThread = new ControlThread(this);
207 mSensor = new Sensor(mSensorWidth, mSensorHeight);
208 mJpegCompressor = new JpegCompressor();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700209
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800210 mNextStreamId = 1;
211 mNextReprocessStreamId = 1;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700212
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800213 res = mSensor->startUp();
214 if (res != NO_ERROR) return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700215
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800216 res = mConfigureThread->run("EmulatedFakeCamera2::configureThread");
217 if (res != NO_ERROR) return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700218
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800219 res = mReadoutThread->run("EmulatedFakeCamera2::readoutThread");
220 if (res != NO_ERROR) return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700221
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800222 res = mControlThread->run("EmulatedFakeCamera2::controlThread");
223 if (res != NO_ERROR) return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700224
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800225 status_t ret = EmulatedCamera2::connectCamera(device);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700226
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800227 if (ret >= 0) {
228 mIsConnected = true;
229 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700230
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800231 return ret;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700232}
233
234status_t EmulatedFakeCamera2::plugCamera() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800235 {
236 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700237
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800238 if (!mStatusPresent) {
239 ALOGI("%s: Plugged back in", __FUNCTION__);
240 mStatusPresent = true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700241 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800242 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700243
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800244 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700245}
246
247status_t EmulatedFakeCamera2::unplugCamera() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800248 {
249 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700250
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800251 if (mStatusPresent) {
252 ALOGI("%s: Unplugged camera", __FUNCTION__);
253 mStatusPresent = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700254 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800255 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700256
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800257 return closeCamera();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700258}
259
260camera_device_status_t EmulatedFakeCamera2::getHotplugStatus() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800261 Mutex::Autolock l(mMutex);
262 return mStatusPresent ? CAMERA_DEVICE_STATUS_PRESENT
263 : CAMERA_DEVICE_STATUS_NOT_PRESENT;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700264}
265
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700266status_t EmulatedFakeCamera2::closeCamera() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800267 {
268 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700269
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800270 status_t res;
271 ALOGV("%s", __FUNCTION__);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700272
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800273 if (!mIsConnected) {
274 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700275 }
276
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800277 res = mSensor->shutDown();
278 if (res != NO_ERROR) {
279 ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res);
280 return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700281 }
282
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800283 mConfigureThread->requestExit();
284 mReadoutThread->requestExit();
285 mControlThread->requestExit();
286 mJpegCompressor->cancel();
287 }
288
289 // give up the lock since we will now block and the threads
290 // can call back into this object
291 mConfigureThread->join();
292 mReadoutThread->join();
293 mControlThread->join();
294
295 ALOGV("%s exit", __FUNCTION__);
296
297 {
298 Mutex::Autolock l(mMutex);
299 mIsConnected = false;
300 }
301
302 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700303}
304
305status_t EmulatedFakeCamera2::getCameraInfo(struct camera_info *info) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800306 info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
307 info->orientation =
308 EmulatedCameraFactory::Instance().getFakeCameraOrientation();
309 return EmulatedCamera2::getCameraInfo(info);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700310}
311
312/****************************************************************************
313 * Camera device API overrides
314 ***************************************************************************/
315
316/** Request input queue */
317
318int EmulatedFakeCamera2::requestQueueNotify() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800319 ALOGV("Request queue notification received");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700320
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800321 ALOG_ASSERT(mRequestQueueSrc != NULL,
322 "%s: Request queue src not set, but received queue notification!",
323 __FUNCTION__);
324 ALOG_ASSERT(mFrameQueueDst != NULL,
325 "%s: Request queue src not set, but received queue notification!",
326 __FUNCTION__);
327 ALOG_ASSERT(mStreams.size() != 0,
328 "%s: No streams allocated, but received queue notification!",
329 __FUNCTION__);
330 return mConfigureThread->newRequestAvailable();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700331}
332
333int EmulatedFakeCamera2::getInProgressCount() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800334 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700335
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800336 if (!mStatusPresent) {
337 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
338 return ERROR_CAMERA_NOT_PRESENT;
339 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700340
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800341 int requestCount = 0;
342 requestCount += mConfigureThread->getInProgressCount();
343 requestCount += mReadoutThread->getInProgressCount();
344 requestCount += mJpegCompressor->isBusy() ? 1 : 0;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700345
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800346 return requestCount;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700347}
348
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800349int EmulatedFakeCamera2::constructDefaultRequest(int request_template,
350 camera_metadata_t **request) {
351 if (request == NULL) return BAD_VALUE;
352 if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) {
353 return BAD_VALUE;
354 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700355
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800356 {
357 Mutex::Autolock l(mMutex);
358 if (!mStatusPresent) {
359 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
360 return ERROR_CAMERA_NOT_PRESENT;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700361 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800362 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700363
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800364 status_t res;
365 // Pass 1, calculate size and allocate
366 res = constructDefaultRequest(request_template, request, true);
367 if (res != OK) {
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700368 return res;
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800369 }
370 // Pass 2, build request
371 res = constructDefaultRequest(request_template, request, false);
372 if (res != OK) {
373 ALOGE("Unable to populate new request for template %d", request_template);
374 }
375
376 return res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700377}
378
379int EmulatedFakeCamera2::allocateStream(
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800380 uint32_t width, uint32_t height, int format,
381 const camera2_stream_ops_t *stream_ops, uint32_t *stream_id,
382 uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers) {
383 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700384
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800385 if (!mStatusPresent) {
386 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
387 return ERROR_CAMERA_NOT_PRESENT;
388 }
389
390 // Temporary shim until FORMAT_ZSL is removed
391 if (format == CAMERA2_HAL_PIXEL_FORMAT_ZSL) {
392 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
393 }
394
395 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
396 unsigned int numFormats = sizeof(kAvailableFormats) / sizeof(uint32_t);
397 unsigned int formatIdx = 0;
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800398 for (; formatIdx < numFormats; formatIdx++) {
399 if (format == (int)kAvailableFormats[formatIdx]) break;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700400 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800401 if (formatIdx == numFormats) {
402 ALOGE("%s: Format 0x%x is not supported", __FUNCTION__, format);
403 return BAD_VALUE;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700404 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800405 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700406
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800407 const uint32_t *availableSizes;
408 size_t availableSizeCount;
409 switch (format) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800410 case HAL_PIXEL_FORMAT_RAW16:
411 availableSizes = &mAvailableRawSizes.front();
412 availableSizeCount = mAvailableRawSizes.size();
413 break;
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800414 case HAL_PIXEL_FORMAT_BLOB:
415 availableSizes = &mAvailableJpegSizes.front();
416 availableSizeCount = mAvailableJpegSizes.size();
417 break;
418 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
419 case HAL_PIXEL_FORMAT_RGBA_8888:
420 case HAL_PIXEL_FORMAT_YV12:
421 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
422 availableSizes = &mAvailableProcessedSizes.front();
423 availableSizeCount = mAvailableProcessedSizes.size();
424 break;
425 default:
426 ALOGE("%s: Unknown format 0x%x", __FUNCTION__, format);
427 return BAD_VALUE;
428 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700429
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800430 unsigned int resIdx = 0;
431 for (; resIdx < availableSizeCount; resIdx++) {
432 if (availableSizes[resIdx * 2] == width &&
433 availableSizes[resIdx * 2 + 1] == height)
434 break;
435 }
436 if (resIdx == availableSizeCount) {
437 ALOGE("%s: Format 0x%x does not support resolution %d, %d", __FUNCTION__,
438 format, width, height);
439 return BAD_VALUE;
440 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700441
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800442 switch (format) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800443 case HAL_PIXEL_FORMAT_RAW16:
444 if (mRawStreamCount >= kMaxRawStreamCount) {
445 ALOGE("%s: Cannot allocate another raw stream (%d already allocated)",
446 __FUNCTION__, mRawStreamCount);
447 return INVALID_OPERATION;
448 }
449 mRawStreamCount++;
450 break;
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800451 case HAL_PIXEL_FORMAT_BLOB:
452 if (mJpegStreamCount >= kMaxJpegStreamCount) {
453 ALOGE("%s: Cannot allocate another JPEG stream (%d already allocated)",
454 __FUNCTION__, mJpegStreamCount);
455 return INVALID_OPERATION;
456 }
457 mJpegStreamCount++;
458 break;
459 default:
460 if (mProcessedStreamCount >= kMaxProcessedStreamCount) {
461 ALOGE(
462 "%s: Cannot allocate another processed stream (%d already "
463 "allocated)",
464 __FUNCTION__, mProcessedStreamCount);
465 return INVALID_OPERATION;
466 }
467 mProcessedStreamCount++;
468 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700469
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800470 Stream newStream;
471 newStream.ops = stream_ops;
472 newStream.width = width;
473 newStream.height = height;
474 newStream.format = format;
475 // TODO: Query stride from gralloc
476 newStream.stride = width;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700477
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800478 mStreams.add(mNextStreamId, newStream);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700479
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800480 *stream_id = mNextStreamId;
481 if (format_actual) *format_actual = format;
482 *usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
483 *max_buffers = kMaxBufferCount;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700484
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800485 ALOGV("Stream allocated: %d, %d x %d, 0x%x. U: %x, B: %d", *stream_id, width,
486 height, format, *usage, *max_buffers);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700487
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800488 mNextStreamId++;
489 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700490}
491
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800492int EmulatedFakeCamera2::registerStreamBuffers(uint32_t stream_id,
493 int num_buffers,
Greg Hartman58312bc2018-01-04 19:33:58 -0800494 buffer_handle_t * /*buffers*/) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800495 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700496
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800497 if (!mStatusPresent) {
498 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
499 return ERROR_CAMERA_NOT_PRESENT;
500 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700501
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800502 ALOGV("%s: Stream %d registering %d buffers", __FUNCTION__, stream_id,
503 num_buffers);
504 // Need to find out what the final concrete pixel format for our stream is
505 // Assumes that all buffers have the same format.
506 if (num_buffers < 1) {
507 ALOGE("%s: Stream %d only has %d buffers!", __FUNCTION__, stream_id,
508 num_buffers);
509 return BAD_VALUE;
510 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700511
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800512 ssize_t streamIndex = mStreams.indexOfKey(stream_id);
513 if (streamIndex < 0) {
514 ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
515 return BAD_VALUE;
516 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700517
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800518 Stream &stream = mStreams.editValueAt(streamIndex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700519
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800520 int finalFormat = stream.format;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700521
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800522 if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
523 finalFormat = HAL_PIXEL_FORMAT_RGBA_8888;
524 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700525
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800526 ALOGV("%s: Stream %d format set to %x, previously %x", __FUNCTION__,
527 stream_id, finalFormat, stream.format);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700528
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800529 stream.format = finalFormat;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700530
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800531 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700532}
533
534int EmulatedFakeCamera2::releaseStream(uint32_t stream_id) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800535 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700536
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800537 ssize_t streamIndex = mStreams.indexOfKey(stream_id);
538 if (streamIndex < 0) {
539 ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id);
540 return BAD_VALUE;
541 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700542
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800543 if (isStreamInUse(stream_id)) {
544 ALOGE("%s: Cannot release stream %d; in use!", __FUNCTION__, stream_id);
545 return BAD_VALUE;
546 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700547
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800548 switch (mStreams.valueAt(streamIndex).format) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800549 case HAL_PIXEL_FORMAT_RAW16:
550 mRawStreamCount--;
551 break;
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800552 case HAL_PIXEL_FORMAT_BLOB:
553 mJpegStreamCount--;
554 break;
555 default:
556 mProcessedStreamCount--;
557 break;
558 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700559
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800560 mStreams.removeItemsAt(streamIndex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700561
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800562 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700563}
564
565int EmulatedFakeCamera2::allocateReprocessStreamFromStream(
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800566 uint32_t output_stream_id, const camera2_stream_in_ops_t *stream_ops,
567 uint32_t *stream_id) {
568 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700569
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800570 if (!mStatusPresent) {
571 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
572 return ERROR_CAMERA_NOT_PRESENT;
573 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700574
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800575 ssize_t baseStreamIndex = mStreams.indexOfKey(output_stream_id);
576 if (baseStreamIndex < 0) {
577 ALOGE("%s: Unknown output stream id %d!", __FUNCTION__, output_stream_id);
578 return BAD_VALUE;
579 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700580
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800581 const Stream &baseStream = mStreams[baseStreamIndex];
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700582
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800583 // We'll reprocess anything we produced
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700584
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800585 if (mReprocessStreamCount >= kMaxReprocessStreamCount) {
586 ALOGE("%s: Cannot allocate another reprocess stream (%d already allocated)",
587 __FUNCTION__, mReprocessStreamCount);
588 return INVALID_OPERATION;
589 }
590 mReprocessStreamCount++;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700591
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800592 ReprocessStream newStream;
593 newStream.ops = stream_ops;
594 newStream.width = baseStream.width;
595 newStream.height = baseStream.height;
596 newStream.format = baseStream.format;
597 newStream.stride = baseStream.stride;
598 newStream.sourceStreamId = output_stream_id;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700599
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800600 *stream_id = mNextReprocessStreamId;
601 mReprocessStreams.add(mNextReprocessStreamId, newStream);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700602
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800603 ALOGV("Reprocess stream allocated: %d: %d, %d, 0x%x. Parent stream: %d",
604 *stream_id, newStream.width, newStream.height, newStream.format,
605 output_stream_id);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700606
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800607 mNextReprocessStreamId++;
608 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700609}
610
611int EmulatedFakeCamera2::releaseReprocessStream(uint32_t stream_id) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800612 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700613
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800614 ssize_t streamIndex = mReprocessStreams.indexOfKey(stream_id);
615 if (streamIndex < 0) {
616 ALOGE("%s: Unknown reprocess stream id %d!", __FUNCTION__, stream_id);
617 return BAD_VALUE;
618 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700619
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800620 if (isReprocessStreamInUse(stream_id)) {
621 ALOGE("%s: Cannot release reprocessing stream %d; in use!", __FUNCTION__,
622 stream_id);
623 return BAD_VALUE;
624 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700625
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800626 mReprocessStreamCount--;
627 mReprocessStreams.removeItemsAt(streamIndex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700628
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800629 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700630}
631
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800632int EmulatedFakeCamera2::triggerAction(uint32_t trigger_id, int32_t ext1,
633 int32_t ext2) {
634 Mutex::Autolock l(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700635
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800636 if (trigger_id == CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT) {
637 ALOGI("%s: Disconnect trigger - camera must be closed", __FUNCTION__);
638 mStatusPresent = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700639
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800640 EmulatedCameraFactory::Instance().onStatusChanged(
641 mCameraID, CAMERA_DEVICE_STATUS_NOT_PRESENT);
642 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700643
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800644 if (!mStatusPresent) {
645 ALOGW("%s: Camera was physically disconnected", __FUNCTION__);
646 return ERROR_CAMERA_NOT_PRESENT;
647 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700648
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800649 return mControlThread->triggerAction(trigger_id, ext1, ext2);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700650}
651
652/** Shutdown and debug methods */
653
654int EmulatedFakeCamera2::dump(int fd) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800655 String8 result;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700656
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800657 result.appendFormat(" Camera HAL device: EmulatedFakeCamera2\n");
658 result.appendFormat(" Streams:\n");
659 for (size_t i = 0; i < mStreams.size(); i++) {
660 int id = mStreams.keyAt(i);
661 const Stream &s = mStreams.valueAt(i);
662 result.appendFormat(" Stream %d: %d x %d, format 0x%x, stride %d\n",
663 id, s.width, s.height, s.format, s.stride);
664 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700665
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800666 write(fd, result.string(), result.size());
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700667
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800668 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700669}
670
671void EmulatedFakeCamera2::signalError() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800672 // TODO: Let parent know so we can shut down cleanly
673 ALOGE("Worker thread is signaling a serious error");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700674}
675
676/** Pipeline control worker thread methods */
677
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800678EmulatedFakeCamera2::ConfigureThread::ConfigureThread(
679 EmulatedFakeCamera2 *parent)
680 : Thread(false), mParent(parent), mRequestCount(0), mNextBuffers(NULL) {
681 mRunning = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700682}
683
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800684EmulatedFakeCamera2::ConfigureThread::~ConfigureThread() {}
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700685
686status_t EmulatedFakeCamera2::ConfigureThread::readyToRun() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800687 Mutex::Autolock lock(mInputMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700688
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800689 ALOGV("Starting up ConfigureThread");
690 mRequest = NULL;
691 mActive = false;
692 mRunning = true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700693
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800694 mInputSignal.signal();
695 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700696}
697
698status_t EmulatedFakeCamera2::ConfigureThread::waitUntilRunning() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800699 Mutex::Autolock lock(mInputMutex);
700 if (!mRunning) {
701 ALOGV("Waiting for configure thread to start");
702 mInputSignal.wait(mInputMutex);
703 }
704 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700705}
706
707status_t EmulatedFakeCamera2::ConfigureThread::newRequestAvailable() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800708 waitUntilRunning();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700709
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800710 Mutex::Autolock lock(mInputMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700711
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800712 mActive = true;
713 mInputSignal.signal();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700714
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800715 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700716}
717
718bool EmulatedFakeCamera2::ConfigureThread::isStreamInUse(uint32_t id) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800719 Mutex::Autolock lock(mInternalsMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700720
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800721 if (mNextBuffers == NULL) return false;
722 for (size_t i = 0; i < mNextBuffers->size(); i++) {
723 if ((*mNextBuffers)[i].streamId == (int)id) return true;
724 }
725 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700726}
727
728int EmulatedFakeCamera2::ConfigureThread::getInProgressCount() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800729 Mutex::Autolock lock(mInputMutex);
730 return mRequestCount;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700731}
732
733bool EmulatedFakeCamera2::ConfigureThread::threadLoop() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800734 status_t res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700735
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800736 // Check if we're currently processing or just waiting
737 {
738 Mutex::Autolock lock(mInputMutex);
739 if (!mActive) {
740 // Inactive, keep waiting until we've been signaled
741 status_t res;
742 res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
743 if (res != NO_ERROR && res != TIMED_OUT) {
744 ALOGE("%s: Error waiting for input requests: %d", __FUNCTION__, res);
745 return false;
746 }
747 if (!mActive) return true;
748 ALOGV("New request available");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700749 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800750 // Active
751 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700752
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800753 if (mRequest == NULL) {
754 Mutex::Autolock il(mInternalsMutex);
755
756 ALOGV("Configure: Getting next request");
757 res = mParent->mRequestQueueSrc->dequeue_request(mParent->mRequestQueueSrc,
758 &mRequest);
759 if (res != NO_ERROR) {
760 ALOGE("%s: Error dequeuing next request: %d", __FUNCTION__, res);
761 mParent->signalError();
762 return false;
763 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700764 if (mRequest == NULL) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800765 ALOGV("Configure: Request queue empty, going inactive");
766 // No requests available, go into inactive mode
767 Mutex::Autolock lock(mInputMutex);
768 mActive = false;
769 return true;
770 } else {
771 Mutex::Autolock lock(mInputMutex);
772 mRequestCount++;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700773 }
774
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800775 camera_metadata_entry_t type;
776 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_TYPE, &type);
777 if (res != NO_ERROR) {
778 ALOGE("%s: error reading request type", __FUNCTION__);
779 mParent->signalError();
780 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700781 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800782 bool success = false;
783 ;
784 switch (type.data.u8[0]) {
785 case ANDROID_REQUEST_TYPE_CAPTURE:
786 success = setupCapture();
787 break;
788 case ANDROID_REQUEST_TYPE_REPROCESS:
789 success = setupReprocess();
790 break;
791 default:
792 ALOGE("%s: Unexpected request type %d", __FUNCTION__, type.data.u8[0]);
793 mParent->signalError();
794 break;
795 }
796 if (!success) return false;
797 }
798
799 if (mWaitingForReadout) {
800 bool readoutDone;
801 readoutDone = mParent->mReadoutThread->waitForReady(kWaitPerLoop);
802 if (!readoutDone) return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700803
804 if (mNextNeedsJpeg) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800805 ALOGV("Configure: Waiting for JPEG compressor");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700806 } else {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800807 ALOGV("Configure: Waiting for sensor");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700808 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800809 mWaitingForReadout = false;
810 }
811
812 if (mNextNeedsJpeg) {
813 bool jpegDone;
814 jpegDone = mParent->mJpegCompressor->waitForDone(kWaitPerLoop);
815 if (!jpegDone) return true;
816
817 ALOGV("Configure: Waiting for sensor");
818 mNextNeedsJpeg = false;
819 }
820
821 if (mNextIsCapture) {
822 return configureNextCapture();
823 } else {
824 return configureNextReprocess();
825 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700826}
827
828bool EmulatedFakeCamera2::ConfigureThread::setupCapture() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800829 status_t res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700830
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800831 mNextIsCapture = true;
832 // Get necessary parameters for sensor config
833 mParent->mControlThread->processRequest(mRequest);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700834
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800835 camera_metadata_entry_t streams;
836 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
837 &streams);
838 if (res != NO_ERROR) {
839 ALOGE("%s: error reading output stream tag", __FUNCTION__);
840 mParent->signalError();
841 return false;
842 }
843
844 mNextBuffers = new Buffers;
845 mNextNeedsJpeg = false;
846 ALOGV("Configure: Setting up buffers for capture");
847 for (size_t i = 0; i < streams.count; i++) {
848 int streamId = streams.data.i32[i];
849 const Stream &s = mParent->getStreamInfo(streamId);
850 if (s.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
851 ALOGE(
852 "%s: Stream %d does not have a concrete pixel format, but "
853 "is included in a request!",
854 __FUNCTION__, streamId);
855 mParent->signalError();
856 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700857 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800858 StreamBuffer b;
859 b.streamId = streamId; // streams.data.u8[i];
860 b.width = s.width;
861 b.height = s.height;
862 b.format = s.format;
863 b.stride = s.stride;
864 mNextBuffers->push_back(b);
865 ALOGV(
866 "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, "
867 "stride %d",
868 i, b.streamId, b.width, b.height, b.format, b.stride);
869 if (b.format == HAL_PIXEL_FORMAT_BLOB) {
870 mNextNeedsJpeg = true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700871 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800872 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700873
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800874 camera_metadata_entry_t e;
875 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e);
876 if (res != NO_ERROR) {
877 ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
878 strerror(-res), res);
879 mParent->signalError();
880 return false;
881 }
882 mNextFrameNumber = *e.data.i32;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700883
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800884 res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_EXPOSURE_TIME, &e);
885 if (res != NO_ERROR) {
886 ALOGE("%s: error reading exposure time tag: %s (%d)", __FUNCTION__,
887 strerror(-res), res);
888 mParent->signalError();
889 return false;
890 }
891 mNextExposureTime = *e.data.i64;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700892
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800893 res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_FRAME_DURATION, &e);
894 if (res != NO_ERROR) {
895 ALOGE("%s: error reading frame duration tag", __FUNCTION__);
896 mParent->signalError();
897 return false;
898 }
899 mNextFrameDuration = *e.data.i64;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700900
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800901 if (mNextFrameDuration < mNextExposureTime + Sensor::kMinVerticalBlank) {
902 mNextFrameDuration = mNextExposureTime + Sensor::kMinVerticalBlank;
903 }
904 res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_SENSITIVITY, &e);
905 if (res != NO_ERROR) {
906 ALOGE("%s: error reading sensitivity tag", __FUNCTION__);
907 mParent->signalError();
908 return false;
909 }
910 mNextSensitivity = *e.data.i32;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700911
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800912 // Start waiting on readout thread
913 mWaitingForReadout = true;
914 ALOGV("Configure: Waiting for readout thread");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700915
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800916 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700917}
918
919bool EmulatedFakeCamera2::ConfigureThread::configureNextCapture() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800920 bool vsync = mParent->mSensor->waitForVSync(kWaitPerLoop);
921 if (!vsync) return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700922
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800923 Mutex::Autolock il(mInternalsMutex);
924 ALOGV("Configure: Configuring sensor for capture %d", mNextFrameNumber);
925 mParent->mSensor->setExposureTime(mNextExposureTime);
926 mParent->mSensor->setFrameDuration(mNextFrameDuration);
927 mParent->mSensor->setSensitivity(mNextSensitivity);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700928
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800929 getBuffers();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700930
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800931 ALOGV("Configure: Done configure for capture %d", mNextFrameNumber);
932 mParent->mReadoutThread->setNextOperation(true, mRequest, mNextBuffers);
933 mParent->mSensor->setDestinationBuffers(mNextBuffers);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700934
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800935 mRequest = NULL;
936 mNextBuffers = NULL;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700937
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800938 Mutex::Autolock lock(mInputMutex);
939 mRequestCount--;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700940
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800941 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700942}
943
944bool EmulatedFakeCamera2::ConfigureThread::setupReprocess() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800945 status_t res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700946
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800947 mNextNeedsJpeg = true;
948 mNextIsCapture = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700949
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800950 camera_metadata_entry_t reprocessStreams;
951 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_INPUT_STREAMS,
952 &reprocessStreams);
953 if (res != NO_ERROR) {
954 ALOGE("%s: error reading output stream tag", __FUNCTION__);
955 mParent->signalError();
956 return false;
957 }
958
959 mNextBuffers = new Buffers;
960
961 ALOGV("Configure: Setting up input buffers for reprocess");
962 for (size_t i = 0; i < reprocessStreams.count; i++) {
963 int streamId = reprocessStreams.data.i32[i];
964 const ReprocessStream &s = mParent->getReprocessStreamInfo(streamId);
965 if (s.format != HAL_PIXEL_FORMAT_RGB_888) {
966 ALOGE("%s: Only ZSL reprocessing supported!", __FUNCTION__);
967 mParent->signalError();
968 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700969 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800970 StreamBuffer b;
971 b.streamId = -streamId;
972 b.width = s.width;
973 b.height = s.height;
974 b.format = s.format;
975 b.stride = s.stride;
976 mNextBuffers->push_back(b);
977 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700978
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800979 camera_metadata_entry_t streams;
980 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
981 &streams);
982 if (res != NO_ERROR) {
983 ALOGE("%s: error reading output stream tag", __FUNCTION__);
984 mParent->signalError();
985 return false;
986 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700987
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800988 ALOGV("Configure: Setting up output buffers for reprocess");
989 for (size_t i = 0; i < streams.count; i++) {
990 int streamId = streams.data.i32[i];
991 const Stream &s = mParent->getStreamInfo(streamId);
992 if (s.format != HAL_PIXEL_FORMAT_BLOB) {
993 // TODO: Support reprocess to YUV
994 ALOGE("%s: Non-JPEG output stream %d for reprocess not supported",
995 __FUNCTION__, streamId);
996 mParent->signalError();
997 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -0700998 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -0800999 StreamBuffer b;
1000 b.streamId = streams.data.u8[i];
1001 b.width = s.width;
1002 b.height = s.height;
1003 b.format = s.format;
1004 b.stride = s.stride;
1005 mNextBuffers->push_back(b);
1006 ALOGV(
1007 "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, "
1008 "stride %d",
1009 i, b.streamId, b.width, b.height, b.format, b.stride);
1010 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001011
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001012 camera_metadata_entry_t e;
1013 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e);
1014 if (res != NO_ERROR) {
1015 ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
1016 strerror(-res), res);
1017 mParent->signalError();
1018 return false;
1019 }
1020 mNextFrameNumber = *e.data.i32;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001021
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001022 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001023}
1024
1025bool EmulatedFakeCamera2::ConfigureThread::configureNextReprocess() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001026 Mutex::Autolock il(mInternalsMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001027
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001028 getBuffers();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001029
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001030 ALOGV("Configure: Done configure for reprocess %d", mNextFrameNumber);
1031 mParent->mReadoutThread->setNextOperation(false, mRequest, mNextBuffers);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001032
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001033 mRequest = NULL;
1034 mNextBuffers = NULL;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001035
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001036 Mutex::Autolock lock(mInputMutex);
1037 mRequestCount--;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001038
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001039 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001040}
1041
1042bool EmulatedFakeCamera2::ConfigureThread::getBuffers() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001043 status_t res;
1044 /** Get buffers to fill for this frame */
1045 for (size_t i = 0; i < mNextBuffers->size(); i++) {
1046 StreamBuffer &b = mNextBuffers->editItemAt(i);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001047
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001048 if (b.streamId > 0) {
1049 ALOGV("Configure: Dequeing buffer from stream %d", b.streamId);
1050 Stream s = mParent->getStreamInfo(b.streamId);
1051 res = s.ops->dequeue_buffer(s.ops, &(b.buffer));
1052 if (res != NO_ERROR || b.buffer == NULL) {
1053 ALOGE("%s: Unable to dequeue buffer from stream %d: %s (%d)",
1054 __FUNCTION__, b.streamId, strerror(-res), res);
1055 mParent->signalError();
1056 return false;
1057 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001058
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001059 /* Lock the buffer from the perspective of the graphics mapper */
1060 res = GrallocModule::getInstance().lock(
1061 *(b.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0, s.width, s.height,
1062 (void **)&(b.img));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001063
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001064 if (res != NO_ERROR) {
1065 ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__,
1066 strerror(-res), res);
1067 s.ops->cancel_buffer(s.ops, b.buffer);
1068 mParent->signalError();
1069 return false;
1070 }
1071 } else {
1072 ALOGV("Configure: Acquiring buffer from reprocess stream %d",
1073 -b.streamId);
1074 ReprocessStream s = mParent->getReprocessStreamInfo(-b.streamId);
1075 res = s.ops->acquire_buffer(s.ops, &(b.buffer));
1076 if (res != NO_ERROR || b.buffer == NULL) {
1077 ALOGE(
1078 "%s: Unable to acquire buffer from reprocess stream %d: "
1079 "%s (%d)",
1080 __FUNCTION__, -b.streamId, strerror(-res), res);
1081 mParent->signalError();
1082 return false;
1083 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001084
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001085 /* Lock the buffer from the perspective of the graphics mapper */
1086 res = GrallocModule::getInstance().lock(
1087 *(b.buffer), GRALLOC_USAGE_HW_CAMERA_READ, 0, 0, s.width, s.height,
1088 (void **)&(b.img));
1089 if (res != NO_ERROR) {
1090 ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__,
1091 strerror(-res), res);
1092 s.ops->release_buffer(s.ops, b.buffer);
1093 mParent->signalError();
1094 return false;
1095 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001096 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001097 }
1098 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001099}
1100
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001101EmulatedFakeCamera2::ReadoutThread::ReadoutThread(EmulatedFakeCamera2 *parent)
1102 : Thread(false),
1103 mParent(parent),
1104 mRunning(false),
1105 mActive(false),
1106 mRequestCount(0),
1107 mRequest(NULL),
1108 mBuffers(NULL) {
1109 mInFlightQueue = new InFlightQueue[kInFlightQueueSize];
1110 mInFlightHead = 0;
1111 mInFlightTail = 0;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001112}
1113
1114EmulatedFakeCamera2::ReadoutThread::~ReadoutThread() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001115 delete[] mInFlightQueue;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001116}
1117
1118status_t EmulatedFakeCamera2::ReadoutThread::readyToRun() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001119 Mutex::Autolock lock(mInputMutex);
1120 ALOGV("Starting up ReadoutThread");
1121 mRunning = true;
1122 mInputSignal.signal();
1123 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001124}
1125
1126status_t EmulatedFakeCamera2::ReadoutThread::waitUntilRunning() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001127 Mutex::Autolock lock(mInputMutex);
1128 if (!mRunning) {
1129 ALOGV("Waiting for readout thread to start");
1130 mInputSignal.wait(mInputMutex);
1131 }
1132 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001133}
1134
1135bool EmulatedFakeCamera2::ReadoutThread::waitForReady(nsecs_t timeout) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001136 status_t res;
1137 Mutex::Autolock lock(mInputMutex);
1138 while (!readyForNextCapture()) {
1139 res = mReadySignal.waitRelative(mInputMutex, timeout);
1140 if (res == TIMED_OUT) return false;
1141 if (res != OK) {
1142 ALOGE("%s: Error waiting for ready: %s (%d)", __FUNCTION__,
1143 strerror(-res), res);
1144 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001145 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001146 }
1147 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001148}
1149
1150bool EmulatedFakeCamera2::ReadoutThread::readyForNextCapture() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001151 return (mInFlightTail + 1) % kInFlightQueueSize != mInFlightHead;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001152}
1153
1154void EmulatedFakeCamera2::ReadoutThread::setNextOperation(
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001155 bool isCapture, camera_metadata_t *request, Buffers *buffers) {
1156 Mutex::Autolock lock(mInputMutex);
1157 if (!readyForNextCapture()) {
1158 ALOGE("In flight queue full, dropping captures");
1159 mParent->signalError();
1160 return;
1161 }
1162 mInFlightQueue[mInFlightTail].isCapture = isCapture;
1163 mInFlightQueue[mInFlightTail].request = request;
1164 mInFlightQueue[mInFlightTail].buffers = buffers;
1165 mInFlightTail = (mInFlightTail + 1) % kInFlightQueueSize;
1166 mRequestCount++;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001167
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001168 if (!mActive) {
1169 mActive = true;
1170 mInputSignal.signal();
1171 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001172}
1173
1174bool EmulatedFakeCamera2::ReadoutThread::isStreamInUse(uint32_t id) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001175 // acquire in same order as threadLoop
1176 Mutex::Autolock iLock(mInternalsMutex);
1177 Mutex::Autolock lock(mInputMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001178
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001179 size_t i = mInFlightHead;
1180 while (i != mInFlightTail) {
1181 for (size_t j = 0; j < mInFlightQueue[i].buffers->size(); j++) {
1182 if ((*(mInFlightQueue[i].buffers))[j].streamId == (int)id) return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001183 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001184 i = (i + 1) % kInFlightQueueSize;
1185 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001186
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001187 if (mBuffers != NULL) {
1188 for (i = 0; i < mBuffers->size(); i++) {
1189 if ((*mBuffers)[i].streamId == (int)id) return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001190 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001191 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001192
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001193 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001194}
1195
1196int EmulatedFakeCamera2::ReadoutThread::getInProgressCount() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001197 Mutex::Autolock lock(mInputMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001198
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001199 return mRequestCount;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001200}
1201
1202bool EmulatedFakeCamera2::ReadoutThread::threadLoop() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001203 static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms
1204 status_t res;
1205 int32_t frameNumber;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001206
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001207 // Check if we're currently processing or just waiting
1208 {
1209 Mutex::Autolock lock(mInputMutex);
1210 if (!mActive) {
1211 // Inactive, keep waiting until we've been signaled
1212 res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop);
1213 if (res != NO_ERROR && res != TIMED_OUT) {
1214 ALOGE("%s: Error waiting for capture requests: %d", __FUNCTION__, res);
1215 mParent->signalError();
1216 return false;
1217 }
1218 if (!mActive) return true;
1219 }
1220 // Active, see if we need a new request
1221 if (mRequest == NULL) {
1222 if (mInFlightHead == mInFlightTail) {
1223 // Go inactive
1224 ALOGV("Waiting for sensor data");
1225 mActive = false;
1226 return true;
1227 } else {
1228 Mutex::Autolock iLock(mInternalsMutex);
1229 mReadySignal.signal();
1230 mIsCapture = mInFlightQueue[mInFlightHead].isCapture;
1231 mRequest = mInFlightQueue[mInFlightHead].request;
1232 mBuffers = mInFlightQueue[mInFlightHead].buffers;
1233 mInFlightQueue[mInFlightHead].request = NULL;
1234 mInFlightQueue[mInFlightHead].buffers = NULL;
1235 mInFlightHead = (mInFlightHead + 1) % kInFlightQueueSize;
1236 ALOGV("Ready to read out request %p, %zu buffers", mRequest,
1237 mBuffers->size());
1238 }
1239 }
1240 }
1241
1242 // Active with request, wait on sensor to complete
1243
1244 nsecs_t captureTime;
1245
1246 if (mIsCapture) {
1247 bool gotFrame;
1248 gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime);
1249
1250 if (!gotFrame) return true;
1251 }
1252
1253 Mutex::Autolock iLock(mInternalsMutex);
1254
1255 camera_metadata_entry_t entry;
1256 if (!mIsCapture) {
1257 res =
1258 find_camera_metadata_entry(mRequest, ANDROID_SENSOR_TIMESTAMP, &entry);
1259 if (res != NO_ERROR) {
1260 ALOGE("%s: error reading reprocessing timestamp: %s (%d)", __FUNCTION__,
1261 strerror(-res), res);
1262 mParent->signalError();
1263 return false;
1264 }
1265 captureTime = entry.data.i64[0];
1266 }
1267
1268 res =
1269 find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &entry);
1270 if (res != NO_ERROR) {
1271 ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__,
1272 strerror(-res), res);
1273 mParent->signalError();
1274 return false;
1275 }
1276 frameNumber = *entry.data.i32;
1277
1278 res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_METADATA_MODE,
1279 &entry);
1280 if (res != NO_ERROR) {
1281 ALOGE("%s: error reading metadata mode tag: %s (%d)", __FUNCTION__,
1282 strerror(-res), res);
1283 mParent->signalError();
1284 return false;
1285 }
1286
1287 // Got sensor data and request, construct frame and send it out
1288 ALOGV("Readout: Constructing metadata and frames for request %d",
1289 frameNumber);
1290
1291 if (*entry.data.u8 == ANDROID_REQUEST_METADATA_MODE_FULL) {
1292 ALOGV("Readout: Metadata requested, constructing");
1293
1294 camera_metadata_t *frame = NULL;
1295
1296 size_t frame_entries = get_camera_metadata_entry_count(mRequest);
1297 size_t frame_data = get_camera_metadata_data_count(mRequest);
1298
1299 // TODO: Dynamically calculate based on enabled statistics, etc
1300 frame_entries += 10;
1301 frame_data += 100;
1302
1303 res = mParent->mFrameQueueDst->dequeue_frame(
1304 mParent->mFrameQueueDst, frame_entries, frame_data, &frame);
1305
1306 if (res != NO_ERROR || frame == NULL) {
1307 ALOGE("%s: Unable to dequeue frame metadata buffer", __FUNCTION__);
1308 mParent->signalError();
1309 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001310 }
1311
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001312 res = append_camera_metadata(frame, mRequest);
1313 if (res != NO_ERROR) {
1314 ALOGE("Unable to append request metadata");
1315 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001316
1317 if (mIsCapture) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001318 add_camera_metadata_entry(frame, ANDROID_SENSOR_TIMESTAMP, &captureTime,
1319 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001320
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001321 collectStatisticsMetadata(frame);
1322 // TODO: Collect all final values used from sensor in addition to
1323 // timestamp
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001324 }
1325
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001326 ALOGV("Readout: Enqueue frame %d", frameNumber);
1327 mParent->mFrameQueueDst->enqueue_frame(mParent->mFrameQueueDst, frame);
1328 }
1329 ALOGV("Readout: Free request");
1330 res = mParent->mRequestQueueSrc->free_request(mParent->mRequestQueueSrc,
1331 mRequest);
1332 if (res != NO_ERROR) {
1333 ALOGE("%s: Unable to return request buffer to queue: %d", __FUNCTION__,
1334 res);
1335 mParent->signalError();
1336 return false;
1337 }
1338 mRequest = NULL;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001339
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001340 int compressedBufferIndex = -1;
1341 ALOGV("Readout: Processing %zu buffers", mBuffers->size());
1342 for (size_t i = 0; i < mBuffers->size(); i++) {
1343 const StreamBuffer &b = (*mBuffers)[i];
1344 ALOGV("Readout: Buffer %zu: Stream %d, %d x %d, format 0x%x, stride %d",
1345 i, b.streamId, b.width, b.height, b.format, b.stride);
1346 if (b.streamId > 0) {
1347 if (b.format == HAL_PIXEL_FORMAT_BLOB) {
1348 // Assumes only one BLOB buffer type per capture
1349 compressedBufferIndex = i;
1350 } else {
1351 ALOGV("Readout: Sending image buffer %zu (%p) to output stream %d",
1352 i, (void *)*(b.buffer), b.streamId);
1353 GrallocModule::getInstance().unlock(*(b.buffer));
1354 const Stream &s = mParent->getStreamInfo(b.streamId);
1355 res = s.ops->enqueue_buffer(s.ops, captureTime, b.buffer);
1356 if (res != OK) {
1357 ALOGE("Error enqueuing image buffer %p: %s (%d)", b.buffer,
1358 strerror(-res), res);
1359 mParent->signalError();
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001360 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001361 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001362 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001363 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001364
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001365 if (compressedBufferIndex == -1) {
1366 delete mBuffers;
1367 } else {
1368 ALOGV("Readout: Starting JPEG compression for buffer %d, stream %d",
1369 compressedBufferIndex, (*mBuffers)[compressedBufferIndex].streamId);
1370 mJpegTimestamp = captureTime;
1371 // Takes ownership of mBuffers
1372 mParent->mJpegCompressor->start(mBuffers, this);
1373 }
1374 mBuffers = NULL;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001375
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001376 Mutex::Autolock l(mInputMutex);
1377 mRequestCount--;
1378 ALOGV("Readout: Done with request %d", frameNumber);
1379 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001380}
1381
1382void EmulatedFakeCamera2::ReadoutThread::onJpegDone(
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001383 const StreamBuffer &jpegBuffer, bool success) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001384 if (!success) {
1385 ALOGE("%s: Error queueing compressed image buffer %p", __FUNCTION__,
1386 jpegBuffer.buffer);
1387 mParent->signalError();
1388 return;
1389 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001390
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001391 // Write to JPEG output stream
1392 ALOGV("%s: Compression complete, pushing to stream %d", __FUNCTION__,
1393 jpegBuffer.streamId);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001394
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001395 GrallocModule::getInstance().unlock(*(jpegBuffer.buffer));
1396 const Stream &s = mParent->getStreamInfo(jpegBuffer.streamId);
Greg Hartman58312bc2018-01-04 19:33:58 -08001397 s.ops->enqueue_buffer(s.ops, mJpegTimestamp, jpegBuffer.buffer);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001398}
1399
1400void EmulatedFakeCamera2::ReadoutThread::onJpegInputDone(
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001401 const StreamBuffer &inputBuffer) {
1402 status_t res;
1403 GrallocModule::getInstance().unlock(*(inputBuffer.buffer));
1404 const ReprocessStream &s =
1405 mParent->getReprocessStreamInfo(-inputBuffer.streamId);
1406 res = s.ops->release_buffer(s.ops, inputBuffer.buffer);
1407 if (res != OK) {
1408 ALOGE("Error releasing reprocess buffer %p: %s (%d)", inputBuffer.buffer,
1409 strerror(-res), res);
1410 mParent->signalError();
1411 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001412}
1413
1414status_t EmulatedFakeCamera2::ReadoutThread::collectStatisticsMetadata(
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001415 camera_metadata_t *frame) {
1416 // Completely fake face rectangles, don't correspond to real faces in scene
1417 ALOGV("Readout: Collecting statistics metadata");
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001418
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001419 status_t res;
1420 camera_metadata_entry_t entry;
1421 res = find_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_DETECT_MODE,
1422 &entry);
1423 if (res != OK) {
1424 ALOGE("%s: Unable to find face detect mode!", __FUNCTION__);
1425 return BAD_VALUE;
1426 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001427
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001428 if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001429
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001430 // The coordinate system for the face regions is the raw sensor pixel
1431 // coordinates. Here, we map from the scene coordinates (0-19 in both axis)
1432 // to raw pixels, for the scene defined in fake-pipeline2/Scene.cpp. We
1433 // approximately place two faces on top of the windows of the house. No
1434 // actual faces exist there, but might one day. Note that this doesn't
1435 // account for the offsets used to account for aspect ratio differences, so
1436 // the rectangles don't line up quite right.
1437 const size_t numFaces = 2;
1438 int32_t rects[numFaces * 4] = {
1439 static_cast<int32_t>(mParent->mSensorWidth * 10 / 20),
1440 static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
1441 static_cast<int32_t>(mParent->mSensorWidth * 12 / 20),
1442 static_cast<int32_t>(mParent->mSensorHeight * 17 / 20),
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001443
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001444 static_cast<int32_t>(mParent->mSensorWidth * 16 / 20),
1445 static_cast<int32_t>(mParent->mSensorHeight * 15 / 20),
1446 static_cast<int32_t>(mParent->mSensorWidth * 18 / 20),
1447 static_cast<int32_t>(mParent->mSensorHeight * 17 / 20)};
1448 // To simulate some kind of real detection going on, we jitter the rectangles
1449 // on each frame by a few pixels in each dimension.
1450 for (size_t i = 0; i < numFaces * 4; i++) {
Nick Desaulniers25128ad2019-11-13 15:12:21 -08001451 rects[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 6 - 3);
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001452 }
1453 // The confidence scores (0-100) are similarly jittered.
1454 uint8_t scores[numFaces] = {85, 95};
1455 for (size_t i = 0; i < numFaces; i++) {
Nick Desaulniers25128ad2019-11-13 15:12:21 -08001456 scores[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 10 - 5);
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001457 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001458
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001459 res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_RECTANGLES,
1460 rects, numFaces * 4);
1461 if (res != OK) {
1462 ALOGE("%s: Unable to add face rectangles!", __FUNCTION__);
1463 return BAD_VALUE;
1464 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001465
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001466 res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_SCORES, scores,
1467 numFaces);
1468 if (res != OK) {
1469 ALOGE("%s: Unable to add face scores!", __FUNCTION__);
1470 return BAD_VALUE;
1471 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001472
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001473 if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE) return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001474
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001475 // Advanced face detection options - add eye/mouth coordinates. The
1476 // coordinates in order are (leftEyeX, leftEyeY, rightEyeX, rightEyeY,
1477 // mouthX, mouthY). The mapping is the same as the face rectangles.
1478 int32_t features[numFaces * 6] = {
1479 static_cast<int32_t>(mParent->mSensorWidth * 10.5 / 20),
1480 static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
1481 static_cast<int32_t>(mParent->mSensorWidth * 11.5 / 20),
1482 static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
1483 static_cast<int32_t>(mParent->mSensorWidth * 11 / 20),
1484 static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001485
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001486 static_cast<int32_t>(mParent->mSensorWidth * 16.5 / 20),
1487 static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
1488 static_cast<int32_t>(mParent->mSensorWidth * 17.5 / 20),
1489 static_cast<int32_t>(mParent->mSensorHeight * 16 / 20),
1490 static_cast<int32_t>(mParent->mSensorWidth * 17 / 20),
1491 static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20),
1492 };
1493 // Jitter these a bit less than the rects
1494 for (size_t i = 0; i < numFaces * 6; i++) {
Nick Desaulniers25128ad2019-11-13 15:12:21 -08001495 features[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 4 - 2);
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001496 }
1497 // These are unique IDs that are used to identify each face while it's
1498 // visible to the detector (if a face went away and came back, it'd get a
1499 // new ID).
1500 int32_t ids[numFaces] = {100, 200};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001501
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001502 res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_LANDMARKS,
1503 features, numFaces * 6);
1504 if (res != OK) {
1505 ALOGE("%s: Unable to add face landmarks!", __FUNCTION__);
1506 return BAD_VALUE;
1507 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001508
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001509 res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_IDS, ids,
1510 numFaces);
1511 if (res != OK) {
1512 ALOGE("%s: Unable to add face scores!", __FUNCTION__);
1513 return BAD_VALUE;
1514 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001515
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001516 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001517}
1518
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001519EmulatedFakeCamera2::ControlThread::ControlThread(EmulatedFakeCamera2 *parent)
1520 : Thread(false), mParent(parent) {
1521 mRunning = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001522}
1523
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001524EmulatedFakeCamera2::ControlThread::~ControlThread() {}
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001525
1526status_t EmulatedFakeCamera2::ControlThread::readyToRun() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001527 Mutex::Autolock lock(mInputMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001528
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001529 ALOGV("Starting up ControlThread");
1530 mRunning = true;
1531 mStartAf = false;
1532 mCancelAf = false;
1533 mStartPrecapture = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001534
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001535 mControlMode = ANDROID_CONTROL_MODE_AUTO;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001536
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001537 mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
1538 mSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001539
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001540 mAfMode = ANDROID_CONTROL_AF_MODE_AUTO;
1541 mAfModeChange = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001542
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001543 mAeMode = ANDROID_CONTROL_AE_MODE_ON;
1544 mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001545
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001546 mAfTriggerId = 0;
1547 mPrecaptureTriggerId = 0;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001548
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001549 mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
1550 mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
1551 mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001552
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001553 mExposureTime = kNormalExposureTime;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001554
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001555 mInputSignal.signal();
1556 return NO_ERROR;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001557}
1558
1559status_t EmulatedFakeCamera2::ControlThread::waitUntilRunning() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001560 Mutex::Autolock lock(mInputMutex);
1561 if (!mRunning) {
1562 ALOGV("Waiting for control thread to start");
1563 mInputSignal.wait(mInputMutex);
1564 }
1565 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001566}
1567
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001568// Override android.control.* fields with 3A values before sending request to
1569// sensor
1570status_t EmulatedFakeCamera2::ControlThread::processRequest(
1571 camera_metadata_t *request) {
1572 Mutex::Autolock lock(mInputMutex);
1573 // TODO: Add handling for all android.control.* fields here
1574 camera_metadata_entry_t mode;
1575 status_t res;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001576
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001577#define READ_IF_OK(res, what, def) (((res) == OK) ? (what) : (uint8_t)(def))
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001578
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001579 res = find_camera_metadata_entry(request, ANDROID_CONTROL_MODE, &mode);
1580 mControlMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_MODE_OFF);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001581
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001582 // disable all 3A
1583 if (mControlMode == ANDROID_CONTROL_MODE_OFF) {
1584 mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001585 mSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001586 mAfMode = ANDROID_CONTROL_AF_MODE_OFF;
1587 mAeLock = ANDROID_CONTROL_AE_LOCK_ON;
1588 mAeMode = ANDROID_CONTROL_AE_MODE_OFF;
1589 mAfModeChange = true;
1590 mStartAf = false;
1591 mCancelAf = true;
1592 mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
1593 mAwbMode = ANDROID_CONTROL_AWB_MODE_OFF;
1594 return res;
1595 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001596
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001597 res = find_camera_metadata_entry(request, ANDROID_CONTROL_EFFECT_MODE, &mode);
1598 mEffectMode =
1599 READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_EFFECT_MODE_OFF);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001600
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001601 res = find_camera_metadata_entry(request, ANDROID_CONTROL_SCENE_MODE, &mode);
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001602 mSceneMode =
1603 READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_SCENE_MODE_DISABLED);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001604
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001605 res = find_camera_metadata_entry(request, ANDROID_CONTROL_AF_MODE, &mode);
1606 if (mAfMode != mode.data.u8[0]) {
1607 ALOGV("AF new mode: %d, old mode %d", mode.data.u8[0], mAfMode);
1608 mAfMode = mode.data.u8[0];
1609 mAfModeChange = true;
1610 mStartAf = false;
1611 mCancelAf = false;
1612 }
1613
1614 res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_MODE, &mode);
1615 mAeMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_MODE_OFF);
1616
1617 res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_LOCK, &mode);
1618 uint8_t aeLockVal =
1619 READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_LOCK_ON);
1620 bool aeLock = (aeLockVal == ANDROID_CONTROL_AE_LOCK_ON);
1621 if (mAeLock && !aeLock) {
1622 mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
1623 }
1624 mAeLock = aeLock;
1625
1626 res = find_camera_metadata_entry(request, ANDROID_CONTROL_AWB_MODE, &mode);
1627 mAwbMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AWB_MODE_OFF);
1628
1629 // TODO: Override more control fields
1630
1631 if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) {
1632 camera_metadata_entry_t exposureTime;
1633 res = find_camera_metadata_entry(request, ANDROID_SENSOR_EXPOSURE_TIME,
1634 &exposureTime);
1635 if (res == OK) {
1636 exposureTime.data.i64[0] = mExposureTime;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001637 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001638 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001639
1640#undef READ_IF_OK
1641
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001642 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001643}
1644
1645status_t EmulatedFakeCamera2::ControlThread::triggerAction(uint32_t msgType,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001646 int32_t ext1,
1647 int32_t ext2) {
1648 ALOGV("%s: Triggering %d (%d, %d)", __FUNCTION__, msgType, ext1, ext2);
1649 Mutex::Autolock lock(mInputMutex);
1650 switch (msgType) {
1651 case CAMERA2_TRIGGER_AUTOFOCUS:
1652 mAfTriggerId = ext1;
1653 mStartAf = true;
1654 mCancelAf = false;
1655 break;
1656 case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
1657 mAfTriggerId = ext1;
1658 mStartAf = false;
1659 mCancelAf = true;
1660 break;
1661 case CAMERA2_TRIGGER_PRECAPTURE_METERING:
1662 mPrecaptureTriggerId = ext1;
1663 mStartPrecapture = true;
1664 break;
1665 default:
1666 ALOGE("%s: Unknown action triggered: %d (arguments %d %d)", __FUNCTION__,
1667 msgType, ext1, ext2);
1668 return BAD_VALUE;
1669 }
1670 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001671}
1672
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001673const nsecs_t EmulatedFakeCamera2::ControlThread::kControlCycleDelay =
1674 100 * MSEC;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001675const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAfDuration = 500 * MSEC;
1676const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAfDuration = 900 * MSEC;
1677const float EmulatedFakeCamera2::ControlThread::kAfSuccessRate = 0.9;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001678// Once every 5 seconds
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001679const float EmulatedFakeCamera2::ControlThread::kContinuousAfStartRate =
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001680 kControlCycleDelay / 5.0 * SEC;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001681const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAeDuration = 500 * MSEC;
1682const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAeDuration = 2 * SEC;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001683const nsecs_t EmulatedFakeCamera2::ControlThread::kMinPrecaptureAeDuration =
1684 100 * MSEC;
1685const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxPrecaptureAeDuration =
1686 400 * MSEC;
1687// Once every 3 seconds
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001688const float EmulatedFakeCamera2::ControlThread::kAeScanStartRate =
1689 kControlCycleDelay / 3000000000.0;
1690
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001691const nsecs_t EmulatedFakeCamera2::ControlThread::kNormalExposureTime =
1692 10 * MSEC;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001693const nsecs_t EmulatedFakeCamera2::ControlThread::kExposureJump = 2 * MSEC;
1694const nsecs_t EmulatedFakeCamera2::ControlThread::kMinExposureTime = 1 * MSEC;
1695
1696bool EmulatedFakeCamera2::ControlThread::threadLoop() {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001697 bool afModeChange = false;
1698 bool afTriggered = false;
1699 bool afCancelled = false;
1700 uint8_t afState;
1701 uint8_t afMode;
1702 int32_t afTriggerId;
1703 bool precaptureTriggered = false;
1704 uint8_t aeState;
1705 uint8_t aeMode;
1706 bool aeLock;
1707 int32_t precaptureTriggerId;
1708 nsecs_t nextSleep = kControlCycleDelay;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001709
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001710 {
1711 Mutex::Autolock lock(mInputMutex);
1712 if (mStartAf) {
1713 ALOGD("Starting AF trigger processing");
1714 afTriggered = true;
1715 mStartAf = false;
1716 } else if (mCancelAf) {
1717 ALOGD("Starting cancel AF trigger processing");
1718 afCancelled = true;
1719 mCancelAf = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001720 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001721 afState = mAfState;
1722 afMode = mAfMode;
1723 afModeChange = mAfModeChange;
1724 mAfModeChange = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001725
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001726 afTriggerId = mAfTriggerId;
1727
1728 if (mStartPrecapture) {
1729 ALOGD("Starting precapture trigger processing");
1730 precaptureTriggered = true;
1731 mStartPrecapture = false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001732 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001733 aeState = mAeState;
1734 aeMode = mAeMode;
1735 aeLock = mAeLock;
1736 precaptureTriggerId = mPrecaptureTriggerId;
1737 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001738
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001739 if (afCancelled || afModeChange) {
1740 ALOGV("Resetting AF state due to cancel/mode change");
1741 afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001742 updateAfState(afState, afTriggerId);
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001743 mAfScanDuration = 0;
1744 mLockAfterPassiveScan = false;
1745 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001746
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001747 if (afTriggered) {
1748 afState = processAfTrigger(afMode, afState);
1749 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001750
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001751 afState = maybeStartAfScan(afMode, afState);
1752 afState = updateAfScan(afMode, afState, &nextSleep);
1753 updateAfState(afState, afTriggerId);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001754
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001755 if (precaptureTriggered) {
1756 aeState = processPrecaptureTrigger(aeMode, aeState);
1757 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001758
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001759 aeState = maybeStartAeScan(aeMode, aeLock, aeState);
1760 aeState = updateAeScan(aeMode, aeLock, aeState, &nextSleep);
1761 updateAeState(aeState, precaptureTriggerId);
1762
1763 int ret;
1764 timespec t;
1765 t.tv_sec = 0;
1766 t.tv_nsec = nextSleep;
1767 do {
1768 ret = nanosleep(&t, &t);
1769 } while (ret != 0);
1770
1771 if (mAfScanDuration > 0) {
1772 mAfScanDuration -= nextSleep;
1773 }
1774 if (mAeScanDuration > 0) {
1775 mAeScanDuration -= nextSleep;
1776 }
1777
1778 return true;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001779}
1780
1781int EmulatedFakeCamera2::ControlThread::processAfTrigger(uint8_t afMode,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001782 uint8_t afState) {
1783 switch (afMode) {
1784 case ANDROID_CONTROL_AF_MODE_OFF:
1785 case ANDROID_CONTROL_AF_MODE_EDOF:
1786 // Do nothing
1787 break;
1788 case ANDROID_CONTROL_AF_MODE_MACRO:
1789 case ANDROID_CONTROL_AF_MODE_AUTO:
1790 switch (afState) {
1791 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1792 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1793 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1794 // Start new focusing cycle
1795 mAfScanDuration =
1796 ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) +
1797 kMinAfDuration;
1798 afState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
1799 ALOGV("%s: AF scan start, duration %" PRId64 " ms", __FUNCTION__,
1800 mAfScanDuration / 1000000);
1801 break;
1802 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1803 // Ignore new request, already scanning
1804 break;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001805 default:
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001806 ALOGE("Unexpected AF state in AUTO/MACRO AF mode: %d", afState);
1807 }
1808 break;
1809 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
1810 switch (afState) {
1811 // Picture mode waits for passive scan to complete
1812 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1813 mLockAfterPassiveScan = true;
1814 break;
1815 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1816 afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
1817 break;
1818 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1819 afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
1820 break;
1821 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1822 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1823 // Must cancel to get out of these states
1824 break;
1825 default:
1826 ALOGE("Unexpected AF state in CONTINUOUS_PICTURE AF mode: %d",
1827 afState);
1828 }
1829 break;
1830 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
1831 switch (afState) {
1832 // Video mode does not wait for passive scan to complete
1833 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1834 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1835 afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
1836 break;
1837 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1838 afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
1839 break;
1840 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1841 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1842 // Must cancel to get out of these states
1843 break;
1844 default:
1845 ALOGE("Unexpected AF state in CONTINUOUS_VIDEO AF mode: %d", afState);
1846 }
1847 break;
1848 default:
1849 break;
1850 }
1851 return afState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001852}
1853
1854int EmulatedFakeCamera2::ControlThread::maybeStartAfScan(uint8_t afMode,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001855 uint8_t afState) {
1856 if ((afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO ||
1857 afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) &&
1858 (afState == ANDROID_CONTROL_AF_STATE_INACTIVE ||
1859 afState == ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED)) {
1860 bool startScan = ((double)rand() / RAND_MAX) < kContinuousAfStartRate;
1861 if (startScan) {
1862 // Start new passive focusing cycle
1863 mAfScanDuration =
1864 ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) +
1865 kMinAfDuration;
1866 afState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
1867 ALOGV("%s: AF passive scan start, duration %" PRId64 " ms", __FUNCTION__,
1868 mAfScanDuration / 1000000);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001869 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001870 }
1871 return afState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001872}
1873
1874int EmulatedFakeCamera2::ControlThread::updateAfScan(uint8_t afMode,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001875 uint8_t afState,
1876 nsecs_t *maxSleep) {
1877 if (!(afState == ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN ||
1878 afState == ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN)) {
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001879 return afState;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001880 }
1881
1882 if (mAfScanDuration <= 0) {
1883 ALOGV("%s: AF scan done", __FUNCTION__);
1884 switch (afMode) {
1885 case ANDROID_CONTROL_AF_MODE_MACRO:
1886 case ANDROID_CONTROL_AF_MODE_AUTO: {
1887 bool success = ((double)rand() / RAND_MAX) < kAfSuccessRate;
1888 if (success) {
1889 afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
1890 } else {
1891 afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
1892 }
1893 break;
1894 }
1895 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
1896 if (mLockAfterPassiveScan) {
1897 afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
1898 mLockAfterPassiveScan = false;
1899 } else {
1900 afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
1901 }
1902 break;
1903 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
1904 afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
1905 break;
1906 default:
1907 ALOGE("Unexpected AF mode in scan state");
1908 }
1909 } else {
1910 if (mAfScanDuration <= *maxSleep) {
1911 *maxSleep = mAfScanDuration;
1912 }
1913 }
1914 return afState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001915}
1916
1917void EmulatedFakeCamera2::ControlThread::updateAfState(uint8_t newState,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001918 int32_t triggerId) {
1919 Mutex::Autolock lock(mInputMutex);
1920 if (mAfState != newState) {
1921 ALOGV("%s: Autofocus state now %d, id %d", __FUNCTION__, newState,
1922 triggerId);
1923 mAfState = newState;
1924 mParent->sendNotification(CAMERA2_MSG_AUTOFOCUS, newState, triggerId, 0);
1925 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001926}
1927
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001928int EmulatedFakeCamera2::ControlThread::processPrecaptureTrigger(
1929 uint8_t aeMode, uint8_t aeState) {
1930 switch (aeMode) {
1931 case ANDROID_CONTROL_AE_MODE_OFF:
1932 // Don't do anything for these
1933 return aeState;
1934 case ANDROID_CONTROL_AE_MODE_ON:
1935 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
1936 case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
1937 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
1938 // Trigger a precapture cycle
1939 aeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE;
1940 mAeScanDuration =
1941 ((double)rand() / RAND_MAX) *
1942 (kMaxPrecaptureAeDuration - kMinPrecaptureAeDuration) +
1943 kMinPrecaptureAeDuration;
1944 ALOGD("%s: AE precapture scan start, duration %" PRId64 " ms",
1945 __FUNCTION__, mAeScanDuration / 1000000);
1946 }
1947 return aeState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001948}
1949
1950int EmulatedFakeCamera2::ControlThread::maybeStartAeScan(uint8_t aeMode,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001951 bool aeLocked,
1952 uint8_t aeState) {
1953 if (aeLocked) return aeState;
1954 switch (aeMode) {
1955 case ANDROID_CONTROL_AE_MODE_OFF:
1956 break;
1957 case ANDROID_CONTROL_AE_MODE_ON:
1958 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
1959 case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
1960 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: {
1961 if (aeState != ANDROID_CONTROL_AE_STATE_INACTIVE &&
1962 aeState != ANDROID_CONTROL_AE_STATE_CONVERGED)
1963 break;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001964
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001965 bool startScan = ((double)rand() / RAND_MAX) < kAeScanStartRate;
1966 if (startScan) {
1967 mAeScanDuration =
1968 ((double)rand() / RAND_MAX) * (kMaxAeDuration - kMinAeDuration) +
1969 kMinAeDuration;
1970 aeState = ANDROID_CONTROL_AE_STATE_SEARCHING;
1971 ALOGV("%s: AE scan start, duration %" PRId64 " ms", __FUNCTION__,
1972 mAeScanDuration / 1000000);
1973 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001974 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001975 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001976
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001977 return aeState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001978}
1979
Greg Hartman58312bc2018-01-04 19:33:58 -08001980int EmulatedFakeCamera2::ControlThread::updateAeScan(uint8_t /*aeMode*/,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001981 bool aeLock,
1982 uint8_t aeState,
1983 nsecs_t *maxSleep) {
1984 if (aeLock && aeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
1985 mAeScanDuration = 0;
1986 aeState = ANDROID_CONTROL_AE_STATE_LOCKED;
1987 } else if ((aeState == ANDROID_CONTROL_AE_STATE_SEARCHING) ||
1988 (aeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE)) {
1989 if (mAeScanDuration <= 0) {
1990 ALOGV("%s: AE scan done", __FUNCTION__);
1991 aeState = aeLock ? ANDROID_CONTROL_AE_STATE_LOCKED
1992 : ANDROID_CONTROL_AE_STATE_CONVERGED;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07001993
Greg Hartmanffd70fc2018-01-04 19:32:38 -08001994 Mutex::Autolock lock(mInputMutex);
1995 mExposureTime = kNormalExposureTime;
1996 } else {
1997 if (mAeScanDuration <= *maxSleep) {
1998 *maxSleep = mAeScanDuration;
1999 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002000
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002001 int64_t exposureDelta =
2002 ((double)rand() / RAND_MAX) * 2 * kExposureJump - kExposureJump;
2003 Mutex::Autolock lock(mInputMutex);
2004 mExposureTime = mExposureTime + exposureDelta;
2005 if (mExposureTime < kMinExposureTime) mExposureTime = kMinExposureTime;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002006 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002007 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002008
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002009 return aeState;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002010}
2011
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002012void EmulatedFakeCamera2::ControlThread::updateAeState(uint8_t newState,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002013 int32_t triggerId) {
2014 Mutex::Autolock lock(mInputMutex);
2015 if (mAeState != newState) {
2016 ALOGV("%s: Autoexposure state now %d, id %d", __FUNCTION__, newState,
2017 triggerId);
2018 mAeState = newState;
2019 mParent->sendNotification(CAMERA2_MSG_AUTOEXPOSURE, newState, triggerId, 0);
2020 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002021}
2022
2023/** Private methods */
2024
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002025status_t EmulatedFakeCamera2::constructStaticInfo(camera_metadata_t **info,
2026 bool sizeRequest) const {
2027 size_t entryCount = 0;
2028 size_t dataCount = 0;
2029 status_t ret;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002030
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002031#define ADD_OR_SIZE(tag, data, count) \
2032 if ((ret = addOrSize(*info, sizeRequest, &entryCount, &dataCount, tag, data, \
2033 count)) != OK) \
2034 return ret
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002035
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002036 // android.lens
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002037
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002038 // 5 cm min focus distance for back camera, infinity (fixed focus) for front
2039 const float minFocusDistance = mFacingBack ? 1.0 / 0.05 : 0.0;
2040 ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &minFocusDistance, 1);
2041 // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front
Greg Hartman58312bc2018-01-04 19:33:58 -08002042 // const float hyperFocalDistance = mFacingBack ? 1.0 / 5.0 : 0.0;
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002043 ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &minFocusDistance, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002044
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002045 static const float focalLength = 3.30f; // mm
2046 ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &focalLength, 1);
2047 static const float aperture = 2.8f;
2048 ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &aperture, 1);
2049 static const float filterDensity = 0;
2050 ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, &filterDensity, 1);
2051 static const uint8_t availableOpticalStabilization =
2052 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2053 ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
2054 &availableOpticalStabilization, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002055
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002056 static const int32_t lensShadingMapSize[] = {1, 1};
2057 ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize,
2058 sizeof(lensShadingMapSize) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002059
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002060 int32_t lensFacing =
2061 mFacingBack ? ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
2062 ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002063
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002064 // android.sensor
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002065
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002066 ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
2067 Sensor::kExposureTimeRange, 2);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002068
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002069 ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
2070 &Sensor::kFrameDurationRange[1], 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002071
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002072 ADD_OR_SIZE(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, Sensor::kSensitivityRange,
2073 sizeof(Sensor::kSensitivityRange) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002074
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002075 ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
2076 &Sensor::kColorFilterArrangement, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002077
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002078 static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm
2079 ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002080
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002081 const int32_t pixelArray[] = {mSensorWidth, mSensorHeight};
2082 ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArray, 2);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002083
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002084 ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, pixelArray, 2);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002085
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002086 ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL, &Sensor::kMaxRawValue, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002087
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002088 static const int32_t blackLevelPattern[4] = {
2089 static_cast<int32_t>(Sensor::kBlackLevel),
2090 static_cast<int32_t>(Sensor::kBlackLevel),
2091 static_cast<int32_t>(Sensor::kBlackLevel),
2092 static_cast<int32_t>(Sensor::kBlackLevel)};
2093 ADD_OR_SIZE(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, blackLevelPattern,
2094 sizeof(blackLevelPattern) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002095
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002096 // TODO: sensor color calibration fields
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002097
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002098 // android.flash
2099 static const uint8_t flashAvailable = 0;
2100 ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002101
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002102 static const int64_t flashChargeDuration = 0;
2103 ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002104
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002105 // android.tonemap
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002106
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002107 static const int32_t tonemapCurvePoints = 128;
2108 ADD_OR_SIZE(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002109
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002110 // android.scaler
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002111
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002112 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_FORMATS, kAvailableFormats,
2113 sizeof(kAvailableFormats) / sizeof(uint32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002114
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002115 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_SIZES, &mAvailableRawSizes.front(),
2116 mAvailableRawSizes.size());
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002117
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002118 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
2119 kAvailableRawMinDurations,
2120 sizeof(kAvailableRawMinDurations) / sizeof(uint64_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002121
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002122 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
2123 &mAvailableProcessedSizes.front(),
2124 mAvailableProcessedSizes.size());
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002125
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002126 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
2127 kAvailableProcessedMinDurations,
2128 sizeof(kAvailableProcessedMinDurations) / sizeof(uint64_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002129
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002130 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, &mAvailableJpegSizes.front(),
2131 mAvailableJpegSizes.size());
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002132
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002133 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
2134 kAvailableJpegMinDurations,
2135 sizeof(kAvailableJpegMinDurations) / sizeof(uint64_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002136
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002137 static const float maxZoom = 10;
2138 ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002139
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002140 // android.jpeg
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002141
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002142 static const int32_t jpegThumbnailSizes[] = {0, 0, 160, 120, 320, 240};
2143 ADD_OR_SIZE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes,
2144 sizeof(jpegThumbnailSizes) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002145
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002146 static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize;
2147 ADD_OR_SIZE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002148
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002149 // android.stats
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002150
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002151 static const uint8_t availableFaceDetectModes[] = {
2152 ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
2153 ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
2154 ANDROID_STATISTICS_FACE_DETECT_MODE_FULL};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002155
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002156 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
2157 availableFaceDetectModes, sizeof(availableFaceDetectModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002158
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002159 static const int32_t maxFaceCount = 8;
2160 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002161
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002162 static const int32_t histogramSize = 64;
2163 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, &histogramSize,
2164 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002165
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002166 static const int32_t maxHistogramCount = 1000;
2167 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT, &maxHistogramCount,
2168 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002169
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002170 static const int32_t sharpnessMapSize[2] = {64, 64};
2171 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, sharpnessMapSize,
2172 sizeof(sharpnessMapSize) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002173
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002174 static const int32_t maxSharpnessMapValue = 1000;
2175 ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
2176 &maxSharpnessMapValue, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002177
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002178 // android.control
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002179
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002180 static const uint8_t availableSceneModes[] = {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002181 ANDROID_CONTROL_SCENE_MODE_DISABLED
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002182 };
2183 ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, availableSceneModes,
2184 sizeof(availableSceneModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002185
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002186 static const uint8_t availableEffects[] = {ANDROID_CONTROL_EFFECT_MODE_OFF};
2187 ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects,
2188 sizeof(availableEffects));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002189
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002190 static const int32_t max3aRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0};
2191 ADD_OR_SIZE(ANDROID_CONTROL_MAX_REGIONS, max3aRegions,
2192 sizeof(max3aRegions) / sizeof(max3aRegions[0]));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002193
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002194 static const uint8_t availableAeModes[] = {ANDROID_CONTROL_AE_MODE_OFF,
2195 ANDROID_CONTROL_AE_MODE_ON};
2196 ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_MODES, availableAeModes,
2197 sizeof(availableAeModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002198
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002199 static const camera_metadata_rational exposureCompensationStep = {1, 3};
2200 ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP, &exposureCompensationStep,
2201 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002202
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002203 int32_t exposureCompensationRange[] = {-9, 9};
2204 ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, exposureCompensationRange,
2205 sizeof(exposureCompensationRange) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002206
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002207 static const int32_t availableTargetFpsRanges[] = {5, 30, 15, 30};
2208 ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
2209 availableTargetFpsRanges,
2210 sizeof(availableTargetFpsRanges) / sizeof(int32_t));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002211
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002212 static const uint8_t availableAntibandingModes[] = {
2213 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
2214 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO};
2215 ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
2216 availableAntibandingModes, sizeof(availableAntibandingModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002217
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002218 static const uint8_t availableAwbModes[] = {
2219 ANDROID_CONTROL_AWB_MODE_OFF,
2220 ANDROID_CONTROL_AWB_MODE_AUTO,
2221 ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
2222 ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
2223 ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
2224 ANDROID_CONTROL_AWB_MODE_SHADE};
2225 ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes,
2226 sizeof(availableAwbModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002227
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002228 static const uint8_t availableAfModesBack[] = {
2229 ANDROID_CONTROL_AF_MODE_OFF, ANDROID_CONTROL_AF_MODE_AUTO,
2230 ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
2231 ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002232
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002233 static const uint8_t availableAfModesFront[] = {ANDROID_CONTROL_AF_MODE_OFF};
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002234
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002235 if (mFacingBack) {
2236 ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesBack,
2237 sizeof(availableAfModesBack));
2238 } else {
2239 ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesFront,
2240 sizeof(availableAfModesFront));
2241 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002242
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002243 static const uint8_t availableVstabModes[] = {
2244 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF};
2245 ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
2246 availableVstabModes, sizeof(availableVstabModes));
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002247
2248#undef ADD_OR_SIZE
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002249 /** Allocate metadata if sizing */
2250 if (sizeRequest) {
2251 ALOGV(
2252 "Allocating %zu entries, %zu extra bytes for "
2253 "static camera info",
2254 entryCount, dataCount);
2255 *info = allocate_camera_metadata(entryCount, dataCount);
2256 if (*info == NULL) {
2257 ALOGE(
2258 "Unable to allocate camera static info"
2259 "(%zu entries, %zu bytes extra data)",
2260 entryCount, dataCount);
2261 return NO_MEMORY;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002262 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002263 }
2264 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002265}
2266
2267status_t EmulatedFakeCamera2::constructDefaultRequest(
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002268 int request_template, camera_metadata_t **request, bool sizeRequest) const {
2269 size_t entryCount = 0;
2270 size_t dataCount = 0;
2271 status_t ret;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002272
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002273#define ADD_OR_SIZE(tag, data, count) \
2274 if ((ret = addOrSize(*request, sizeRequest, &entryCount, &dataCount, tag, \
2275 data, count)) != OK) \
2276 return ret
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002277
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002278 /** android.request */
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002279
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002280 static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE;
2281 ADD_OR_SIZE(ANDROID_REQUEST_TYPE, &requestType, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002282
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002283 static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
2284 ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002285
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002286 static const int32_t id = 0;
2287 ADD_OR_SIZE(ANDROID_REQUEST_ID, &id, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002288
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002289 static const int32_t frameCount = 0;
2290 ADD_OR_SIZE(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002291
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002292 // OUTPUT_STREAMS set by user
2293 entryCount += 1;
2294 dataCount += 5; // TODO: Should be maximum stream number
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002295
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002296 /** android.lens */
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002297
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002298 static const float focusDistance = 0;
2299 ADD_OR_SIZE(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002300
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002301 static const float aperture = 2.8f;
2302 ADD_OR_SIZE(ANDROID_LENS_APERTURE, &aperture, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002303
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002304 static const float focalLength = 5.0f;
2305 ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002306
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002307 static const float filterDensity = 0;
2308 ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002309
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002310 static const uint8_t opticalStabilizationMode =
2311 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2312 ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2313 &opticalStabilizationMode, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002314
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002315 // FOCUS_RANGE set only in frame
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002316
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002317 /** android.sensor */
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002318
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002319 static const int64_t exposureTime = 10 * MSEC;
2320 ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002321
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002322 static const int64_t frameDuration = 33333333L; // 1/30 s
2323 ADD_OR_SIZE(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002324
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002325 static const int32_t sensitivity = 100;
2326 ADD_OR_SIZE(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002327
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002328 // TIMESTAMP set only in frame
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002329
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002330 /** android.flash */
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002331
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002332 static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
2333 ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002334
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002335 static const uint8_t flashPower = 10;
2336 ADD_OR_SIZE(ANDROID_FLASH_FIRING_POWER, &flashPower, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002337
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002338 static const int64_t firingTime = 0;
2339 ADD_OR_SIZE(ANDROID_FLASH_FIRING_TIME, &firingTime, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002340
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002341 /** Processing block modes */
2342 uint8_t hotPixelMode = 0;
2343 uint8_t demosaicMode = 0;
2344 uint8_t noiseMode = 0;
2345 uint8_t shadingMode = 0;
2346 uint8_t colorMode = 0;
2347 uint8_t tonemapMode = 0;
2348 uint8_t edgeMode = 0;
2349 switch (request_template) {
2350 case CAMERA2_TEMPLATE_STILL_CAPTURE:
2351 // fall-through
2352 case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
2353 // fall-through
2354 case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
2355 hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY;
2356 demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY;
2357 noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY;
2358 shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY;
2359 colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY;
2360 tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY;
2361 edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;
2362 break;
2363 case CAMERA2_TEMPLATE_PREVIEW:
2364 // fall-through
2365 case CAMERA2_TEMPLATE_VIDEO_RECORD:
2366 // fall-through
2367 default:
2368 hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST;
2369 demosaicMode = ANDROID_DEMOSAIC_MODE_FAST;
2370 noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST;
2371 shadingMode = ANDROID_SHADING_MODE_FAST;
2372 colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST;
2373 tonemapMode = ANDROID_TONEMAP_MODE_FAST;
2374 edgeMode = ANDROID_EDGE_MODE_FAST;
2375 break;
2376 }
2377 ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1);
2378 ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1);
2379 ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1);
2380 ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1);
2381 ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1);
2382 ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1);
2383 ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002384
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002385 /** android.noise */
2386 static const uint8_t noiseStrength = 5;
2387 ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1);
2388
2389 /** android.color */
2390 static const float colorTransform[9] = {1.0f, 0.f, 0.f, 0.f, 1.f,
2391 0.f, 0.f, 0.f, 1.f};
2392 ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9);
2393
2394 /** android.tonemap */
2395 static const float tonemapCurve[4] = {0.f, 0.f, 1.f, 1.f};
2396 ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4);
2397 ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4);
2398 ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4);
2399
2400 /** android.edge */
2401 static const uint8_t edgeStrength = 5;
2402 ADD_OR_SIZE(ANDROID_EDGE_STRENGTH, &edgeStrength, 1);
2403
2404 /** android.scaler */
2405 static const int32_t cropRegion[3] = {0, 0,
2406 static_cast<int32_t>(mSensorWidth)};
2407 ADD_OR_SIZE(ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2408
2409 /** android.jpeg */
2410 static const int32_t jpegQuality = 80;
2411 ADD_OR_SIZE(ANDROID_JPEG_QUALITY, &jpegQuality, 1);
2412
2413 static const int32_t thumbnailSize[2] = {640, 480};
2414 ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);
2415
2416 static const int32_t thumbnailQuality = 80;
2417 ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1);
2418
2419 static const double gpsCoordinates[2] = {0, 0};
2420 ADD_OR_SIZE(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2);
2421
2422 static const uint8_t gpsProcessingMethod[32] = "None";
2423 ADD_OR_SIZE(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, 32);
2424
2425 static const int64_t gpsTimestamp = 0;
2426 ADD_OR_SIZE(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1);
2427
2428 static const int32_t jpegOrientation = 0;
2429 ADD_OR_SIZE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
2430
2431 /** android.stats */
2432
2433 static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2434 ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1);
2435
2436 static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF;
2437 ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1);
2438
2439 static const uint8_t sharpnessMapMode =
2440 ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF;
2441 ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1);
2442
2443 // faceRectangles, faceScores, faceLandmarks, faceIds, histogram,
2444 // sharpnessMap only in frames
2445
2446 /** android.control */
2447
2448 uint8_t controlIntent = 0;
2449 switch (request_template) {
2450 case CAMERA2_TEMPLATE_PREVIEW:
2451 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2452 break;
2453 case CAMERA2_TEMPLATE_STILL_CAPTURE:
2454 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
2455 break;
2456 case CAMERA2_TEMPLATE_VIDEO_RECORD:
2457 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
2458 break;
2459 case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
2460 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
2461 break;
2462 case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
2463 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
2464 break;
2465 default:
2466 controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM;
2467 break;
2468 }
2469 ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1);
2470
2471 static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
2472 ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1);
2473
2474 static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
2475 ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
2476
2477 static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
2478 ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
2479
2480 static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH;
2481 ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2482
2483 static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
2484 ADD_OR_SIZE(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
2485
2486 static const int32_t controlRegions[5] = {
2487 0, 0, static_cast<int32_t>(mSensorWidth),
2488 static_cast<int32_t>(mSensorHeight), 1000};
2489 ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5);
2490
2491 static const int32_t aeExpCompensation = 0;
2492 ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1);
2493
2494 static const int32_t aeTargetFpsRange[2] = {10, 30};
2495 ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2);
2496
2497 static const uint8_t aeAntibandingMode =
2498 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
2499 ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1);
2500
2501 static const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
2502 ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
2503
2504 static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
2505 ADD_OR_SIZE(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
2506
2507 ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5);
2508
2509 uint8_t afMode = 0;
2510 switch (request_template) {
2511 case CAMERA2_TEMPLATE_PREVIEW:
2512 afMode = ANDROID_CONTROL_AF_MODE_AUTO;
2513 break;
2514 case CAMERA2_TEMPLATE_STILL_CAPTURE:
2515 afMode = ANDROID_CONTROL_AF_MODE_AUTO;
2516 break;
2517 case CAMERA2_TEMPLATE_VIDEO_RECORD:
2518 afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
2519 break;
2520 case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT:
2521 afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
2522 break;
2523 case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG:
2524 afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
2525 break;
2526 default:
2527 afMode = ANDROID_CONTROL_AF_MODE_AUTO;
2528 break;
2529 }
2530 ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1);
2531
2532 ADD_OR_SIZE(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5);
2533
2534 static const uint8_t vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2535 ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1);
2536
2537 // aeState, awbState, afState only in frame
2538
2539 /** Allocate metadata if sizing */
2540 if (sizeRequest) {
2541 ALOGV(
2542 "Allocating %zu entries, %zu extra bytes for "
2543 "request template type %d",
2544 entryCount, dataCount, request_template);
2545 *request = allocate_camera_metadata(entryCount, dataCount);
2546 if (*request == NULL) {
2547 ALOGE(
2548 "Unable to allocate new request template type %d "
2549 "(%zu entries, %zu bytes extra data)",
2550 request_template, entryCount, dataCount);
2551 return NO_MEMORY;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002552 }
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002553 }
2554 return OK;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002555#undef ADD_OR_SIZE
2556}
2557
2558status_t EmulatedFakeCamera2::addOrSize(camera_metadata_t *request,
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002559 bool sizeRequest, size_t *entryCount,
2560 size_t *dataCount, uint32_t tag,
2561 const void *entryData,
2562 size_t entryDataCount) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002563 if (!sizeRequest) {
2564 return add_camera_metadata_entry(request, tag, entryData, entryDataCount);
2565 } else {
2566 int type = get_camera_metadata_tag_type(tag);
2567 if (type < 0) return BAD_VALUE;
2568 (*entryCount)++;
2569 (*dataCount) +=
2570 calculate_camera_metadata_entry_data_size(type, entryDataCount);
2571 return OK;
2572 }
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002573}
2574
2575bool EmulatedFakeCamera2::isStreamInUse(uint32_t id) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002576 // Assumes mMutex is locked; otherwise new requests could enter
2577 // configureThread while readoutThread is being checked
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002578
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002579 // Order of isStreamInUse calls matters
2580 if (mConfigureThread->isStreamInUse(id) ||
2581 mReadoutThread->isStreamInUse(id) || mJpegCompressor->isStreamInUse(id)) {
2582 ALOGE("%s: Stream %d is in use in active requests!", __FUNCTION__, id);
2583 return true;
2584 }
2585 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002586}
2587
Greg Hartman58312bc2018-01-04 19:33:58 -08002588bool EmulatedFakeCamera2::isReprocessStreamInUse(uint32_t /*id*/) {
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002589 // TODO: implement
2590 return false;
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002591}
2592
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002593const Stream &EmulatedFakeCamera2::getStreamInfo(uint32_t streamId) {
2594 Mutex::Autolock lock(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002595
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002596 return mStreams.valueFor(streamId);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002597}
2598
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002599const ReprocessStream &EmulatedFakeCamera2::getReprocessStreamInfo(
2600 uint32_t streamId) {
2601 Mutex::Autolock lock(mMutex);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002602
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002603 return mReprocessStreams.valueFor(streamId);
Tomasz Wiszkowski5f73a252017-09-22 11:29:30 -07002604}
2605
Greg Hartmanffd70fc2018-01-04 19:32:38 -08002606}; /* namespace android */