blob: 08aef833e21c08419469b4471b09b835354dc04e [file] [log] [blame]
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001/*
2 * Copyright (C) 2013 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#define LOG_TAG "Camera3-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -070028// Convenience macro for transient errors
29#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \
30 ##__VA_ARGS__)
31
32// Convenience macros for transitioning to the error state
33#define SET_ERR(fmt, ...) setErrorState( \
34 "%s: " fmt, __FUNCTION__, \
35 ##__VA_ARGS__)
36#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
37 "%s: " fmt, __FUNCTION__, \
38 ##__VA_ARGS__)
39
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080040#include <utils/Log.h>
41#include <utils/Trace.h>
42#include <utils/Timers.h>
43#include "Camera3Device.h"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080044#include "camera3/Camera3OutputStream.h"
45
46using namespace android::camera3;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080047
48namespace android {
49
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080050Camera3Device::Camera3Device(int id):
51 mId(id),
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080052 mHal3Device(NULL),
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -070053 mStatus(STATUS_UNINITIALIZED),
54 mListener(NULL)
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080055{
56 ATRACE_CALL();
57 camera3_callback_ops::notify = &sNotify;
58 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
59 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
60}
61
62Camera3Device::~Camera3Device()
63{
64 ATRACE_CALL();
65 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
66 disconnect();
67}
68
Igor Murashkince124da2013-03-04 14:53:08 -080069int Camera3Device::getId() const {
70 return mId;
71}
72
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080073/**
74 * CameraDeviceBase interface
75 */
76
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080077status_t Camera3Device::initialize(camera_module_t *module)
78{
79 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080080 Mutex::Autolock l(mLock);
81
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080082 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080083 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -070084 CLOGE("Already initialized!");
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080085 return INVALID_OPERATION;
86 }
87
88 /** Open HAL device */
89
90 status_t res;
91 String8 deviceName = String8::format("%d", mId);
92
93 camera3_device_t *device;
94
95 res = module->common.methods->open(&module->common, deviceName.string(),
96 reinterpret_cast<hw_device_t**>(&device));
97
98 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -070099 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800100 return res;
101 }
102
103 /** Cross-check device version */
104
105 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700106 SET_ERR_L("Could not open camera: "
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800107 "Camera device is not version %x, reports %x instead",
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700108 CAMERA_DEVICE_API_VERSION_3_0,
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800109 device->common.version);
110 device->common.close(&device->common);
111 return BAD_VALUE;
112 }
113
114 camera_info info;
115 res = module->get_camera_info(mId, &info);
116 if (res != OK) return res;
117
118 if (info.device_version != device->common.version) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700119 SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
120 " and device version (%x).",
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800121 device->common.version, info.device_version);
122 device->common.close(&device->common);
123 return BAD_VALUE;
124 }
125
126 /** Initialize device with callback functions */
127
128 res = device->ops->initialize(device, this);
129 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700130 SET_ERR_L("Unable to initialize HAL device: %s (%d)",
131 strerror(-res), res);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800132 device->common.close(&device->common);
133 return BAD_VALUE;
134 }
135
136 /** Get vendor metadata tags */
137
138 mVendorTagOps.get_camera_vendor_section_name = NULL;
139
140 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
141
142 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
143 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
144 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700145 SET_ERR_L("Unable to set tag ops: %s (%d)",
146 strerror(-res), res);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800147 device->common.close(&device->common);
148 return res;
149 }
150 }
151
152 /** Start up request queue thread */
153
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800154 mRequestThread = new RequestThread(this, device);
155 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800156 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700157 SET_ERR_L("Unable to start request queue thread: %s (%d)",
158 strerror(-res), res);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800159 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800160 mRequestThread.clear();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800161 return res;
162 }
163
164 /** Everything is good to go */
165
166 mDeviceInfo = info.static_camera_characteristics;
167 mHal3Device = device;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800168 mStatus = STATUS_IDLE;
169 mNextStreamId = 0;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800170
171 return OK;
172}
173
174status_t Camera3Device::disconnect() {
175 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800176 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800177
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800178 ALOGV("%s: E", __FUNCTION__);
179
180 status_t res;
181 if (mStatus == STATUS_UNINITIALIZED) return OK;
182
183 if (mStatus == STATUS_ACTIVE ||
184 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
185 res = mRequestThread->clearRepeatingRequests();
186 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700187 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800188 return res;
189 }
190 res = waitUntilDrainedLocked();
191 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700192 SET_ERR_L("Timeout waiting for HAL to drain");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800193 return res;
194 }
195 }
196 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
197
198 if (mRequestThread != NULL) {
199 mRequestThread->requestExit();
200 }
201
202 mOutputStreams.clear();
203 mInputStream.clear();
204
205 if (mRequestThread != NULL) {
206 mRequestThread->join();
207 mRequestThread.clear();
208 }
209
210 if (mHal3Device != NULL) {
211 mHal3Device->common.close(&mHal3Device->common);
212 mHal3Device = NULL;
213 }
214
215 mStatus = STATUS_UNINITIALIZED;
216
217 ALOGV("%s: X", __FUNCTION__);
218 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800219}
220
221status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
222 ATRACE_CALL();
223 (void)args;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800224 String8 lines;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800225
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800226 const char *status =
227 mStatus == STATUS_ERROR ? "ERROR" :
228 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
229 mStatus == STATUS_IDLE ? "IDLE" :
230 mStatus == STATUS_ACTIVE ? "ACTIVE" :
231 "Unknown";
232 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700233 if (mStatus == STATUS_ERROR) {
234 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
235 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800236 lines.appendFormat(" Stream configuration:\n");
237
238 if (mInputStream != NULL) {
239 write(fd, lines.string(), lines.size());
240 mInputStream->dump(fd, args);
241 } else {
242 lines.appendFormat(" No input stream.\n");
243 write(fd, lines.string(), lines.size());
244 }
245 for (size_t i = 0; i < mOutputStreams.size(); i++) {
246 mOutputStreams[i]->dump(fd,args);
247 }
248
249 if (mHal3Device != NULL) {
250 lines = String8(" HAL device dump:\n");
251 write(fd, lines.string(), lines.size());
252 mHal3Device->ops->dump(mHal3Device, fd);
253 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800254
255 return OK;
256}
257
258const CameraMetadata& Camera3Device::info() const {
259 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800260 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
261 mStatus == STATUS_ERROR)) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700262 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800263 mStatus == STATUS_ERROR ?
264 "when in error state" : "before init");
265 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800266 return mDeviceInfo;
267}
268
269status_t Camera3Device::capture(CameraMetadata &request) {
270 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800271 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800272
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700273 // TODO: take ownership of the request
274
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800275 switch (mStatus) {
276 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700277 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800278 return INVALID_OPERATION;
279 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700280 CLOGE("Device not initialized");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800281 return INVALID_OPERATION;
282 case STATUS_IDLE:
283 case STATUS_ACTIVE:
284 // OK
285 break;
286 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700287 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800288 return INVALID_OPERATION;
289 }
290
291 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
292 if (newRequest == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700293 CLOGE("Can't create capture request");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800294 return BAD_VALUE;
295 }
296
297 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800298}
299
300
301status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
302 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800303 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800304
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800305 switch (mStatus) {
306 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700307 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800308 return INVALID_OPERATION;
309 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700310 CLOGE("Device not initialized");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800311 return INVALID_OPERATION;
312 case STATUS_IDLE:
313 case STATUS_ACTIVE:
314 // OK
315 break;
316 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700317 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800318 return INVALID_OPERATION;
319 }
320
321 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
322 if (newRepeatingRequest == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700323 CLOGE("Can't create repeating request");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800324 return BAD_VALUE;
325 }
326
327 RequestList newRepeatingRequests;
328 newRepeatingRequests.push_back(newRepeatingRequest);
329
330 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
331}
332
333
334sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
335 const CameraMetadata &request) {
336 status_t res;
337
338 if (mStatus == STATUS_IDLE) {
339 res = configureStreamsLocked();
340 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700341 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800342 return NULL;
343 }
344 }
345
346 sp<CaptureRequest> newRequest = createCaptureRequest(request);
347 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800348}
349
350status_t Camera3Device::clearStreamingRequest() {
351 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800352 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800353
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800354 switch (mStatus) {
355 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700356 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800357 return INVALID_OPERATION;
358 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700359 CLOGE("Device not initialized");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800360 return INVALID_OPERATION;
361 case STATUS_IDLE:
362 case STATUS_ACTIVE:
363 // OK
364 break;
365 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700366 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800367 return INVALID_OPERATION;
368 }
369
370 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800371}
372
373status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
374 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800375
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700376 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800377}
378
379status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
380 uint32_t width, uint32_t height, int format, size_t size, int *id) {
381 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800382 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800383
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800384 status_t res;
385 bool wasActive = false;
386
387 switch (mStatus) {
388 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700389 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800390 return INVALID_OPERATION;
391 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700392 CLOGE("Device not initialized");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800393 return INVALID_OPERATION;
394 case STATUS_IDLE:
395 // OK
396 break;
397 case STATUS_ACTIVE:
398 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
399 mRequestThread->setPaused(true);
400 res = waitUntilDrainedLocked();
401 if (res != OK) {
402 ALOGE("%s: Can't pause captures to reconfigure streams!",
403 __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800404 return res;
405 }
406 wasActive = true;
407 break;
408 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700409 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800410 return INVALID_OPERATION;
411 }
412 assert(mStatus == STATUS_IDLE);
413
414 sp<Camera3OutputStream> newStream;
415 if (format == HAL_PIXEL_FORMAT_BLOB) {
416 newStream = new Camera3OutputStream(mNextStreamId, consumer,
417 width, height, size, format);
418 } else {
419 newStream = new Camera3OutputStream(mNextStreamId, consumer,
420 width, height, format);
421 }
422
423 res = mOutputStreams.add(mNextStreamId, newStream);
424 if (res < 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700425 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800426 return res;
427 }
428
429 *id = mNextStreamId++;
430
431 // Continue captures if active at start
432 if (wasActive) {
433 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
434 res = configureStreamsLocked();
435 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700436 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
437 mNextStreamId, strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800438 return res;
439 }
440 mRequestThread->setPaused(false);
441 }
442
443 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800444}
445
446status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
447 ATRACE_CALL();
448 (void)outputId; (void)id;
449
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700450 CLOGE("Unimplemented");
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800451 return INVALID_OPERATION;
452}
453
454
455status_t Camera3Device::getStreamInfo(int id,
456 uint32_t *width, uint32_t *height, uint32_t *format) {
457 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800458 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800459
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800460 switch (mStatus) {
461 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700462 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800463 return INVALID_OPERATION;
464 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700465 CLOGE("Device not initialized!");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800466 return INVALID_OPERATION;
467 case STATUS_IDLE:
468 case STATUS_ACTIVE:
469 // OK
470 break;
471 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700472 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800473 return INVALID_OPERATION;
474 }
475
476 ssize_t idx = mOutputStreams.indexOfKey(id);
477 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700478 CLOGE("Stream %d is unknown", id);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800479 return idx;
480 }
481
482 if (width) *width = mOutputStreams[idx]->getWidth();
483 if (height) *height = mOutputStreams[idx]->getHeight();
484 if (format) *format = mOutputStreams[idx]->getFormat();
485
486 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800487}
488
489status_t Camera3Device::setStreamTransform(int id,
490 int transform) {
491 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800492 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800493
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800494 switch (mStatus) {
495 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700496 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800497 return INVALID_OPERATION;
498 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700499 CLOGE("Device not initialized");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800500 return INVALID_OPERATION;
501 case STATUS_IDLE:
502 case STATUS_ACTIVE:
503 // OK
504 break;
505 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700506 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800507 return INVALID_OPERATION;
508 }
509
510 ssize_t idx = mOutputStreams.indexOfKey(id);
511 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700512 CLOGE("Stream %d does not exist",
513 id);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800514 return BAD_VALUE;
515 }
516
517 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800518}
519
520status_t Camera3Device::deleteStream(int id) {
521 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800522 Mutex::Autolock l(mLock);
523 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800524
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800525 // CameraDevice semantics require device to already be idle before
526 // deleteStream is called, unlike for createStream.
527 if (mStatus != STATUS_IDLE) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700528 CLOGE("Device not idle");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800529 return INVALID_OPERATION;
530 }
531
532 sp<Camera3Stream> deletedStream;
533 if (mInputStream != NULL && id == mInputStream->getId()) {
534 deletedStream = mInputStream;
535 mInputStream.clear();
536 } else {
537 ssize_t idx = mOutputStreams.indexOfKey(id);
538 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700539 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800540 return BAD_VALUE;
541 }
542 deletedStream = mOutputStreams.editValueAt(idx);
543 mOutputStreams.removeItem(id);
544 }
545
546 // Free up the stream endpoint so that it can be used by some other stream
547 res = deletedStream->disconnect();
548 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700549 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800550 // fall through since we want to still list the stream as deleted.
551 }
552 mDeletedStreams.add(deletedStream);
553
554 return res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800555}
556
557status_t Camera3Device::deleteReprocessStream(int id) {
558 ATRACE_CALL();
559 (void)id;
560
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700561 CLOGE("Unimplemented");
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800562 return INVALID_OPERATION;
563}
564
565
566status_t Camera3Device::createDefaultRequest(int templateId,
567 CameraMetadata *request) {
568 ATRACE_CALL();
569 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800570 Mutex::Autolock l(mLock);
571
572 switch (mStatus) {
573 case STATUS_ERROR:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700574 CLOGE("Device has encountered a serious error");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800575 return INVALID_OPERATION;
576 case STATUS_UNINITIALIZED:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700577 CLOGE("Device is not initialized!");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800578 return INVALID_OPERATION;
579 case STATUS_IDLE:
580 case STATUS_ACTIVE:
581 // OK
582 break;
583 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700584 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800585 return INVALID_OPERATION;
586 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800587
588 const camera_metadata_t *rawRequest;
589 rawRequest = mHal3Device->ops->construct_default_request_settings(
590 mHal3Device, templateId);
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700591 if (rawRequest == NULL) {
592 SET_ERR_L("HAL is unable to construct default settings for template %d",
593 templateId);
594 return DEAD_OBJECT;
595 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800596 *request = rawRequest;
597
598 return OK;
599}
600
601status_t Camera3Device::waitUntilDrained() {
602 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800603 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800604
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800605 return waitUntilDrainedLocked();
606}
607
608status_t Camera3Device::waitUntilDrainedLocked() {
609 ATRACE_CALL();
610 status_t res;
611
612 switch (mStatus) {
613 case STATUS_UNINITIALIZED:
614 case STATUS_IDLE:
615 ALOGV("%s: Already idle", __FUNCTION__);
616 return OK;
617 case STATUS_ERROR:
618 case STATUS_ACTIVE:
619 // Need to shut down
620 break;
621 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700622 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800623 return INVALID_OPERATION;
624 }
625
626 if (mRequestThread != NULL) {
627 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
628 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700629 SET_ERR_L("Can't stop request thread in %f seconds!",
630 kShutdownTimeout/1e9);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800631 return res;
632 }
633 }
634 if (mInputStream != NULL) {
635 res = mInputStream->waitUntilIdle(kShutdownTimeout);
636 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700637 SET_ERR_L("Can't idle input stream %d in %f seconds!",
638 mInputStream->getId(), kShutdownTimeout/1e9);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800639 return res;
640 }
641 }
642 for (size_t i = 0; i < mOutputStreams.size(); i++) {
643 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
644 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700645 SET_ERR_L("Can't idle output stream %d in %f seconds!",
646 mOutputStreams.keyAt(i), kShutdownTimeout/1e9);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800647 return res;
648 }
649 }
650
651 if (mStatus != STATUS_ERROR) {
652 mStatus = STATUS_IDLE;
653 }
654
655 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800656}
657
658status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
659 ATRACE_CALL();
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700660 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800661
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700662 if (listener != NULL && mListener != NULL) {
663 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
664 }
665 mListener = listener;
666
667 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800668}
669
670status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700671 ATRACE_CALL();
672 status_t res;
673 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800674
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700675 while (mResultQueue.empty()) {
676 res = mResultSignal.waitRelative(mOutputLock, timeout);
677 if (res == TIMED_OUT) {
678 return res;
679 } else if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700680 ALOGW("%s: Camera %d: No frame in %lld ns: %s (%d)",
681 __FUNCTION__, mId, timeout, strerror(-res), res);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700682 return res;
683 }
684 }
685 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800686}
687
688status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
689 ATRACE_CALL();
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700690 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800691
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700692 if (mResultQueue.empty()) {
693 return NOT_ENOUGH_DATA;
694 }
695
696 CameraMetadata &result = *(mResultQueue.begin());
697 frame->acquire(result);
698 mResultQueue.erase(mResultQueue.begin());
699
700 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800701}
702
703status_t Camera3Device::triggerAutofocus(uint32_t id) {
704 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800705
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700706 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
707 // Mix-in this trigger into the next request and only the next request.
708 RequestTrigger trigger[] = {
709 {
710 ANDROID_CONTROL_AF_TRIGGER,
711 ANDROID_CONTROL_AF_TRIGGER_START
712 },
713 {
714 ANDROID_CONTROL_AF_TRIGGER_ID,
715 static_cast<int32_t>(id)
716 },
717 };
718
719 return mRequestThread->queueTrigger(trigger,
720 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800721}
722
723status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
724 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800725
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700726 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
727 // Mix-in this trigger into the next request and only the next request.
728 RequestTrigger trigger[] = {
729 {
730 ANDROID_CONTROL_AF_TRIGGER,
731 ANDROID_CONTROL_AF_TRIGGER_CANCEL
732 },
733 {
734 ANDROID_CONTROL_AF_TRIGGER_ID,
735 static_cast<int32_t>(id)
736 },
737 };
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800738
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700739 return mRequestThread->queueTrigger(trigger,
740 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800741}
742
743status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
744 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800745
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700746 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
747 // Mix-in this trigger into the next request and only the next request.
748 RequestTrigger trigger[] = {
749 {
750 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
751 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
752 },
753 {
754 ANDROID_CONTROL_AE_PRECAPTURE_ID,
755 static_cast<int32_t>(id)
756 },
757 };
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800758
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700759 return mRequestThread->queueTrigger(trigger,
760 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800761}
762
763status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
764 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
765 ATRACE_CALL();
766 (void)reprocessStreamId; (void)buffer; (void)listener;
767
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700768 CLOGE("Unimplemented");
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800769 return INVALID_OPERATION;
770}
771
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800772/**
773 * Camera3Device private methods
774 */
775
776sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
777 const CameraMetadata &request) {
778 ATRACE_CALL();
779 status_t res;
780
781 sp<CaptureRequest> newRequest = new CaptureRequest;
782 newRequest->mSettings = request;
783
784 camera_metadata_entry_t inputStreams =
785 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
786 if (inputStreams.count > 0) {
787 if (mInputStream == NULL ||
788 mInputStream->getId() != inputStreams.data.u8[0]) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700789 CLOGE("Request references unknown input stream %d",
790 inputStreams.data.u8[0]);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800791 return NULL;
792 }
793 // Lazy completion of stream configuration (allocation/registration)
794 // on first use
795 if (mInputStream->isConfiguring()) {
796 res = mInputStream->finishConfiguration(mHal3Device);
797 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700798 SET_ERR_L("Unable to finish configuring input stream %d:"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800799 " %s (%d)",
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700800 mInputStream->getId(), strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800801 return NULL;
802 }
803 }
804
805 newRequest->mInputStream = mInputStream;
806 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
807 }
808
809 camera_metadata_entry_t streams =
810 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
811 if (streams.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700812 CLOGE("Zero output streams specified!");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800813 return NULL;
814 }
815
816 for (size_t i = 0; i < streams.count; i++) {
817 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
818 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700819 CLOGE("Request references unknown stream %d",
820 streams.data.u8[i]);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800821 return NULL;
822 }
823 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
824
825 // Lazy completion of stream configuration (allocation/registration)
826 // on first use
827 if (stream->isConfiguring()) {
828 res = stream->finishConfiguration(mHal3Device);
829 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700830 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
831 stream->getId(), strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800832 return NULL;
833 }
834 }
835
836 newRequest->mOutputStreams.push(stream);
837 }
838 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
839
840 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800841}
842
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800843status_t Camera3Device::configureStreamsLocked() {
844 ATRACE_CALL();
845 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800846
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800847 if (mStatus != STATUS_IDLE) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700848 CLOGE("Not idle");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800849 return INVALID_OPERATION;
850 }
851
852 // Start configuring the streams
853
854 camera3_stream_configuration config;
855
856 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
857
858 Vector<camera3_stream_t*> streams;
859 streams.setCapacity(config.num_streams);
860
861 if (mInputStream != NULL) {
862 camera3_stream_t *inputStream;
863 inputStream = mInputStream->startConfiguration();
864 if (inputStream == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700865 SET_ERR_L("Can't start input stream configuration");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800866 return INVALID_OPERATION;
867 }
868 streams.add(inputStream);
869 }
870
871 for (size_t i = 0; i < mOutputStreams.size(); i++) {
872 camera3_stream_t *outputStream;
873 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
874 if (outputStream == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700875 SET_ERR_L("Can't start output stream configuration");
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800876 return INVALID_OPERATION;
877 }
878 streams.add(outputStream);
879 }
880
881 config.streams = streams.editArray();
882
883 // Do the HAL configuration; will potentially touch stream
884 // max_buffers, usage, priv fields.
885
886 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
887
888 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700889 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
890 strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800891 return res;
892 }
893
894 // Request thread needs to know to avoid using repeat-last-settings protocol
895 // across configure_streams() calls
896 mRequestThread->configurationComplete();
897
898 // Finish configuring the streams lazily on first reference
899
900 mStatus = STATUS_ACTIVE;
901
902 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800903}
904
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700905void Camera3Device::setErrorState(const char *fmt, ...) {
906 Mutex::Autolock l(mLock);
907 va_list args;
908 va_start(args, fmt);
909
910 setErrorStateLockedV(fmt, args);
911
912 va_end(args);
913}
914
915void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
916 Mutex::Autolock l(mLock);
917 setErrorStateLockedV(fmt, args);
918}
919
920void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
921 va_list args;
922 va_start(args, fmt);
923
924 setErrorStateLockedV(fmt, args);
925
926 va_end(args);
927}
928
929void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
930 // Only accept the first failure cause
931 if (mStatus == STATUS_ERROR) return;
932
933 mErrorCause = String8::formatV(fmt, args);
934 ALOGE("Camera %d: %s", mId, mErrorCause.string());
935 mStatus = STATUS_ERROR;
936}
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800937
938/**
939 * Camera HAL device callback methods
940 */
941
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800942void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700943 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800944
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700945 status_t res;
946
947 if (result->result == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700948 SET_ERR("No metadata provided by HAL for frame %d",
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700949 result->frame_number);
950 return;
951 }
952
953 nsecs_t timestamp = 0;
954 AlgState cur3aState;
955 AlgState new3aState;
956 int32_t aeTriggerId = 0;
957 int32_t afTriggerId = 0;
958
959 NotificationListener *listener;
960
961 {
962 Mutex::Autolock l(mOutputLock);
963
964 // Push result metadata into queue
965 mResultQueue.push_back(CameraMetadata());
Igor Murashkinb7c9d612013-04-02 12:32:32 -0700966 // Lets avoid copies! Too bad there's not a #back method
967 CameraMetadata &captureResult = *(--mResultQueue.end());
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700968
969 captureResult = result->result;
Igor Murashkinb7c9d612013-04-02 12:32:32 -0700970 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700971 (int32_t*)&result->frame_number, 1) != OK) {
972 SET_ERR("Failed to set frame# in metadata (%d)",
973 result->frame_number);
Igor Murashkinb7c9d612013-04-02 12:32:32 -0700974 } else {
975 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700976 __FUNCTION__, mId, result->frame_number);
Igor Murashkinb7c9d612013-04-02 12:32:32 -0700977 }
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700978
979 // Get timestamp from result metadata
980
981 camera_metadata_entry entry =
982 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
983 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700984 SET_ERR("No timestamp provided by HAL for frame %d!",
985 result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700986 } else {
987 timestamp = entry.data.i64[0];
988 }
989
990 // Get 3A states from result metadata
991
992 entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
993 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -0700994 CLOGE("No AE state provided by HAL for frame %d!",
995 result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700996 } else {
997 new3aState.aeState =
998 static_cast<camera_metadata_enum_android_control_ae_state>(
999 entry.data.u8[0]);
1000 }
1001
1002 entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
1003 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001004 CLOGE("No AF state provided by HAL for frame %d!",
1005 result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001006 } else {
1007 new3aState.afState =
1008 static_cast<camera_metadata_enum_android_control_af_state>(
1009 entry.data.u8[0]);
1010 }
1011
1012 entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
1013 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001014 CLOGE("No AWB state provided by HAL for frame %d!",
1015 result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001016 } else {
1017 new3aState.awbState =
1018 static_cast<camera_metadata_enum_android_control_awb_state>(
1019 entry.data.u8[0]);
1020 }
1021
1022 entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
1023 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001024 CLOGE("No AF trigger ID provided by HAL for frame %d!",
1025 result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001026 } else {
1027 afTriggerId = entry.data.i32[0];
1028 }
1029
1030 entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
1031 if (entry.count == 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001032 CLOGE("No AE precapture trigger ID provided by HAL"
1033 " for frame %d!", result->frame_number);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001034 } else {
1035 aeTriggerId = entry.data.i32[0];
1036 }
1037
1038 listener = mListener;
1039 cur3aState = m3AState;
1040
1041 m3AState = new3aState;
1042 } // scope for mOutputLock
1043
1044 // Return completed buffers to their streams
1045 for (size_t i = 0; i < result->num_output_buffers; i++) {
1046 Camera3Stream *stream =
1047 Camera3Stream::cast(result->output_buffers[i].stream);
1048 res = stream->returnBuffer(result->output_buffers[i], timestamp);
1049 // Note: stream may be deallocated at this point, if this buffer was the
1050 // last reference to it.
1051 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001052 SET_ERR("Can't return buffer %d for frame %d to its stream: "
1053 " %s (%d)", i, result->frame_number, strerror(-res), res);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001054 }
1055 }
1056
1057 // Dispatch any 3A change events to listeners
1058 if (listener != NULL) {
1059 if (new3aState.aeState != cur3aState.aeState) {
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001060 ALOGVV("%s: AE state changed from 0x%x to 0x%x",
1061 __FUNCTION__, cur3aState.aeState, new3aState.aeState);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001062 listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
1063 }
1064 if (new3aState.afState != cur3aState.afState) {
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001065 ALOGVV("%s: AF state changed from 0x%x to 0x%x",
1066 __FUNCTION__, cur3aState.afState, new3aState.afState);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001067 listener->notifyAutoFocus(new3aState.afState, afTriggerId);
1068 }
1069 if (new3aState.awbState != cur3aState.awbState) {
1070 listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
1071 }
1072 }
1073
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001074}
1075
1076void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001077 NotificationListener *listener;
1078 {
1079 Mutex::Autolock l(mOutputLock);
1080 if (mListener == NULL) return;
1081 listener = mListener;
1082 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001083
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001084 if (msg == NULL) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001085 SET_ERR_L("HAL sent NULL notify message!");
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001086 return;
1087 }
1088
1089 switch (msg->type) {
1090 case CAMERA3_MSG_ERROR: {
1091 int streamId = 0;
1092 if (msg->message.error.error_stream != NULL) {
1093 Camera3Stream *stream =
1094 Camera3Stream::cast(
1095 msg->message.error.error_stream);
1096 streamId = stream->getId();
1097 }
1098 listener->notifyError(msg->message.error.error_code,
1099 msg->message.error.frame_number, streamId);
1100 break;
1101 }
1102 case CAMERA3_MSG_SHUTTER: {
1103 listener->notifyShutter(msg->message.shutter.frame_number,
1104 msg->message.shutter.timestamp);
1105 break;
1106 }
1107 default:
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001108 SET_ERR_L("Unknown notify message from HAL: %d",
1109 msg->type);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001110 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001111}
1112
1113/**
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001114 * RequestThread inner class methods
1115 */
1116
1117Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1118 camera3_device_t *hal3Device) :
1119 Thread(false),
1120 mParent(parent),
1121 mHal3Device(hal3Device),
1122 mReconfigured(false),
1123 mDoPause(false),
1124 mPaused(true),
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001125 mFrameNumber(0),
1126 mLatestRequestId(NAME_NOT_FOUND) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001127}
1128
1129void Camera3Device::RequestThread::configurationComplete() {
1130 Mutex::Autolock l(mRequestLock);
1131 mReconfigured = true;
1132}
1133
1134status_t Camera3Device::RequestThread::queueRequest(
1135 sp<CaptureRequest> request) {
1136 Mutex::Autolock l(mRequestLock);
1137 mRequestQueue.push_back(request);
1138
1139 return OK;
1140}
1141
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001142
1143status_t Camera3Device::RequestThread::queueTrigger(
1144 RequestTrigger trigger[],
1145 size_t count) {
1146
1147 Mutex::Autolock l(mTriggerMutex);
1148 status_t ret;
1149
1150 for (size_t i = 0; i < count; ++i) {
1151 ret = queueTriggerLocked(trigger[i]);
1152
1153 if (ret != OK) {
1154 return ret;
1155 }
1156 }
1157
1158 return OK;
1159}
1160
1161status_t Camera3Device::RequestThread::queueTriggerLocked(
1162 RequestTrigger trigger) {
1163
1164 uint32_t tag = trigger.metadataTag;
1165 ssize_t index = mTriggerMap.indexOfKey(tag);
1166
1167 switch (trigger.getTagType()) {
1168 case TYPE_BYTE:
1169 // fall-through
1170 case TYPE_INT32:
1171 break;
1172 default:
1173 ALOGE("%s: Type not supported: 0x%x",
1174 __FUNCTION__,
1175 trigger.getTagType());
1176 return INVALID_OPERATION;
1177 }
1178
1179 /**
1180 * Collect only the latest trigger, since we only have 1 field
1181 * in the request settings per trigger tag, and can't send more than 1
1182 * trigger per request.
1183 */
1184 if (index != NAME_NOT_FOUND) {
1185 mTriggerMap.editValueAt(index) = trigger;
1186 } else {
1187 mTriggerMap.add(tag, trigger);
1188 }
1189
1190 return OK;
1191}
1192
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001193status_t Camera3Device::RequestThread::setRepeatingRequests(
1194 const RequestList &requests) {
1195 Mutex::Autolock l(mRequestLock);
1196 mRepeatingRequests.clear();
1197 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1198 requests.begin(), requests.end());
1199 return OK;
1200}
1201
1202status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1203 Mutex::Autolock l(mRequestLock);
1204 mRepeatingRequests.clear();
1205 return OK;
1206}
1207
1208void Camera3Device::RequestThread::setPaused(bool paused) {
1209 Mutex::Autolock l(mPauseLock);
1210 mDoPause = paused;
1211 mDoPauseSignal.signal();
1212}
1213
1214status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
1215 status_t res;
1216 Mutex::Autolock l(mPauseLock);
1217 while (!mPaused) {
1218 res = mPausedSignal.waitRelative(mPauseLock, timeout);
1219 if (res == TIMED_OUT) {
1220 return res;
1221 }
1222 }
1223 return OK;
1224}
1225
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001226status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1227 int32_t requestId, nsecs_t timeout) {
1228 Mutex::Autolock l(mLatestRequestMutex);
1229 status_t res;
1230 while (mLatestRequestId != requestId) {
1231 nsecs_t startTime = systemTime();
1232
1233 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1234 if (res != OK) return res;
1235
1236 timeout -= (systemTime() - startTime);
1237 }
1238
1239 return OK;
1240}
1241
1242
1243
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001244bool Camera3Device::RequestThread::threadLoop() {
1245
1246 status_t res;
1247
1248 // Handle paused state.
1249 if (waitIfPaused()) {
1250 return true;
1251 }
1252
1253 // Get work to do
1254
1255 sp<CaptureRequest> nextRequest = waitForNextRequest();
1256 if (nextRequest == NULL) {
1257 return true;
1258 }
1259
1260 // Create request to HAL
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001261 camera3_capture_request_t request = camera3_capture_request_t();
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001262 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001263
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001264 // Insert any queued triggers (before metadata is locked)
1265 int32_t triggerCount;
1266 res = insertTriggers(nextRequest);
1267 if (res < 0) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001268 SET_ERR("RequestThread: Unable to insert triggers "
1269 "(capture request %d, HAL device: %s (%d)",
1270 (mFrameNumber+1), strerror(-res), res);
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001271 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1272 return false;
1273 }
1274 triggerCount = res;
1275
1276 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
1277
1278 // If the request is the same as last, or we had triggers last time
1279 if (mPrevRequest != nextRequest || triggersMixedIn) {
1280 /**
1281 * The request should be presorted so accesses in HAL
1282 * are O(logn). Sidenote, sorting a sorted metadata is nop.
1283 */
1284 nextRequest->mSettings.sort();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001285 request.settings = nextRequest->mSettings.getAndLock();
1286 mPrevRequest = nextRequest;
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001287 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
1288
1289 IF_ALOGV() {
1290 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
1291 find_camera_metadata_ro_entry(
1292 request.settings,
1293 ANDROID_CONTROL_AF_TRIGGER,
1294 &e
1295 );
1296 if (e.count > 0) {
1297 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
1298 __FUNCTION__,
1299 mFrameNumber+1,
1300 e.data.u8[0]);
1301 }
1302 }
1303 } else {
1304 // leave request.settings NULL to indicate 'reuse latest given'
1305 ALOGVV("%s: Request settings are REUSED",
1306 __FUNCTION__);
1307 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001308
1309 camera3_stream_buffer_t inputBuffer;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001310
1311 // Fill in buffers
1312
1313 if (nextRequest->mInputStream != NULL) {
1314 request.input_buffer = &inputBuffer;
1315 res = nextRequest->mInputStream->getBuffer(&inputBuffer);
1316 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001317 SET_ERR("RequestThread: Can't get input buffer, skipping request:"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001318 " %s (%d)", strerror(-res), res);
1319 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1320 return true;
1321 }
1322 } else {
1323 request.input_buffer = NULL;
1324 }
1325
1326 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1327 nextRequest->mOutputStreams.size());
1328 request.output_buffers = outputBuffers.array();
1329 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1330 res = nextRequest->mOutputStreams.editItemAt(i)->
1331 getBuffer(&outputBuffers.editItemAt(i));
1332 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001333 SET_ERR("RequestThread: Can't get output buffer, skipping request:"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001334 "%s (%d)", strerror(-res), res);
1335 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1336 return true;
1337 }
1338 request.num_output_buffers++;
1339 }
1340
1341 request.frame_number = mFrameNumber++;
1342
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001343
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001344 // Submit request and block until ready for next one
1345
1346 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1347 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001348 SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001349 " device: %s (%d)", request.frame_number, strerror(-res), res);
1350 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1351 return false;
1352 }
1353
1354 if (request.settings != NULL) {
1355 nextRequest->mSettings.unlock(request.settings);
1356 }
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001357
1358 // Remove any previously queued triggers (after unlock)
1359 res = removeTriggers(mPrevRequest);
1360 if (res != OK) {
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001361 SET_ERR("RequestThread: Unable to remove triggers "
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001362 "(capture request %d, HAL device: %s (%d)",
1363 request.frame_number, strerror(-res), res);
1364 return false;
1365 }
1366 mPrevTriggers = triggerCount;
1367
1368 // Read android.request.id from the request settings metadata
1369 // - inform waitUntilRequestProcessed thread of a new request ID
1370 {
1371 Mutex::Autolock al(mLatestRequestMutex);
1372
1373 camera_metadata_entry_t requestIdEntry =
1374 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
1375 if (requestIdEntry.count > 0) {
1376 mLatestRequestId = requestIdEntry.data.i32[0];
1377 } else {
1378 ALOGW("%s: Did not have android.request.id set in the request",
1379 __FUNCTION__);
1380 mLatestRequestId = NAME_NOT_FOUND;
1381 }
1382
1383 mLatestRequestSignal.signal();
1384 }
1385
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001386 return true;
1387}
1388
1389void Camera3Device::RequestThread::cleanUpFailedRequest(
1390 camera3_capture_request_t &request,
1391 sp<CaptureRequest> &nextRequest,
1392 Vector<camera3_stream_buffer_t> &outputBuffers) {
1393
1394 if (request.settings != NULL) {
1395 nextRequest->mSettings.unlock(request.settings);
1396 }
1397 if (request.input_buffer != NULL) {
1398 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1399 nextRequest->mInputStream->returnBuffer(*(request.input_buffer), 0);
1400 }
1401 for (size_t i = 0; i < request.num_output_buffers; i++) {
1402 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1403 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1404 outputBuffers[i], 0);
1405 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001406}
1407
1408sp<Camera3Device::CaptureRequest>
1409 Camera3Device::RequestThread::waitForNextRequest() {
1410 status_t res;
1411 sp<CaptureRequest> nextRequest;
1412
1413 // Optimized a bit for the simple steady-state case (single repeating
1414 // request), to avoid putting that request in the queue temporarily.
1415 Mutex::Autolock l(mRequestLock);
1416
1417 while (mRequestQueue.empty()) {
1418 if (!mRepeatingRequests.empty()) {
1419 // Always atomically enqueue all requests in a repeating request
1420 // list. Guarantees a complete in-sequence set of captures to
1421 // application.
1422 const RequestList &requests = mRepeatingRequests;
1423 RequestList::const_iterator firstRequest =
1424 requests.begin();
1425 nextRequest = *firstRequest;
1426 mRequestQueue.insert(mRequestQueue.end(),
1427 ++firstRequest,
1428 requests.end());
1429 // No need to wait any longer
1430 break;
1431 }
1432
1433 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1434
1435 if (res == TIMED_OUT) {
1436 // Signal that we're paused by starvation
1437 Mutex::Autolock pl(mPauseLock);
1438 if (mPaused == false) {
1439 mPaused = true;
1440 mPausedSignal.signal();
1441 }
1442 // Stop waiting for now and let thread management happen
1443 return NULL;
1444 }
1445 }
1446
1447 if (nextRequest == NULL) {
1448 // Don't have a repeating request already in hand, so queue
1449 // must have an entry now.
1450 RequestList::iterator firstRequest =
1451 mRequestQueue.begin();
1452 nextRequest = *firstRequest;
1453 mRequestQueue.erase(firstRequest);
1454 }
1455
1456 // Not paused
1457 Mutex::Autolock pl(mPauseLock);
1458 mPaused = false;
1459
1460 // Check if we've reconfigured since last time, and reset the preview
1461 // request if so. Can't use 'NULL request == repeat' across configure calls.
1462 if (mReconfigured) {
1463 mPrevRequest.clear();
1464 mReconfigured = false;
1465 }
1466
1467 return nextRequest;
1468}
1469
1470bool Camera3Device::RequestThread::waitIfPaused() {
1471 status_t res;
1472 Mutex::Autolock l(mPauseLock);
1473 while (mDoPause) {
1474 // Signal that we're paused by request
1475 if (mPaused == false) {
1476 mPaused = true;
1477 mPausedSignal.signal();
1478 }
1479 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1480 if (res == TIMED_OUT) {
1481 return true;
1482 }
1483 }
1484 // We don't set mPaused to false here, because waitForNextRequest needs
1485 // to further manage the paused state in case of starvation.
1486 return false;
1487}
1488
Eino-Ville Talvala13ec8c42013-04-09 13:49:56 -07001489void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
1490 sp<Camera3Device> parent = mParent.promote();
1491 if (parent != NULL) {
1492 va_list args;
1493 va_start(args, fmt);
1494
1495 parent->setErrorStateV(fmt, args);
1496
1497 va_end(args);
1498 }
1499}
1500
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001501status_t Camera3Device::RequestThread::insertTriggers(
1502 const sp<CaptureRequest> &request) {
1503
1504 Mutex::Autolock al(mTriggerMutex);
1505
1506 CameraMetadata &metadata = request->mSettings;
1507 size_t count = mTriggerMap.size();
1508
1509 for (size_t i = 0; i < count; ++i) {
1510 RequestTrigger trigger = mTriggerMap.valueAt(i);
1511
1512 uint32_t tag = trigger.metadataTag;
1513 camera_metadata_entry entry = metadata.find(tag);
1514
1515 if (entry.count > 0) {
1516 /**
1517 * Already has an entry for this trigger in the request.
1518 * Rewrite it with our requested trigger value.
1519 */
1520 RequestTrigger oldTrigger = trigger;
1521
1522 oldTrigger.entryValue = entry.data.u8[0];
1523
1524 mTriggerReplacedMap.add(tag, oldTrigger);
1525 } else {
1526 /**
1527 * More typical, no trigger entry, so we just add it
1528 */
1529 mTriggerRemovedMap.add(tag, trigger);
1530 }
1531
1532 status_t res;
1533
1534 switch (trigger.getTagType()) {
1535 case TYPE_BYTE: {
1536 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1537 res = metadata.update(tag,
1538 &entryValue,
1539 /*count*/1);
1540 break;
1541 }
1542 case TYPE_INT32:
1543 res = metadata.update(tag,
1544 &trigger.entryValue,
1545 /*count*/1);
1546 break;
1547 default:
1548 ALOGE("%s: Type not supported: 0x%x",
1549 __FUNCTION__,
1550 trigger.getTagType());
1551 return INVALID_OPERATION;
1552 }
1553
1554 if (res != OK) {
1555 ALOGE("%s: Failed to update request metadata with trigger tag %s"
1556 ", value %d", __FUNCTION__, trigger.getTagName(),
1557 trigger.entryValue);
1558 return res;
1559 }
1560
1561 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
1562 trigger.getTagName(),
1563 trigger.entryValue);
1564 }
1565
1566 mTriggerMap.clear();
1567
1568 return count;
1569}
1570
1571status_t Camera3Device::RequestThread::removeTriggers(
1572 const sp<CaptureRequest> &request) {
1573 Mutex::Autolock al(mTriggerMutex);
1574
1575 CameraMetadata &metadata = request->mSettings;
1576
1577 /**
1578 * Replace all old entries with their old values.
1579 */
1580 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
1581 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
1582
1583 status_t res;
1584
1585 uint32_t tag = trigger.metadataTag;
1586 switch (trigger.getTagType()) {
1587 case TYPE_BYTE: {
1588 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1589 res = metadata.update(tag,
1590 &entryValue,
1591 /*count*/1);
1592 break;
1593 }
1594 case TYPE_INT32:
1595 res = metadata.update(tag,
1596 &trigger.entryValue,
1597 /*count*/1);
1598 break;
1599 default:
1600 ALOGE("%s: Type not supported: 0x%x",
1601 __FUNCTION__,
1602 trigger.getTagType());
1603 return INVALID_OPERATION;
1604 }
1605
1606 if (res != OK) {
1607 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
1608 ", trigger value %d", __FUNCTION__,
1609 trigger.getTagName(), trigger.entryValue);
1610 return res;
1611 }
1612 }
1613 mTriggerReplacedMap.clear();
1614
1615 /**
1616 * Remove all new entries.
1617 */
1618 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
1619 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
1620 status_t res = metadata.erase(trigger.metadataTag);
1621
1622 if (res != OK) {
1623 ALOGE("%s: Failed to erase metadata with trigger tag %s"
1624 ", trigger value %d", __FUNCTION__,
1625 trigger.getTagName(), trigger.entryValue);
1626 return res;
1627 }
1628 }
1629 mTriggerRemovedMap.clear();
1630
1631 return OK;
1632}
1633
1634
1635
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001636/**
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001637 * Static callback forwarding methods from HAL to instance
1638 */
1639
1640void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1641 const camera3_capture_result *result) {
1642 Camera3Device *d =
1643 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1644 d->processCaptureResult(result);
1645}
1646
1647void Camera3Device::sNotify(const camera3_callback_ops *cb,
1648 const camera3_notify_msg *msg) {
1649 Camera3Device *d =
1650 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1651 d->notify(msg);
1652}
1653
1654}; // namespace android