blob: 2c12fb06c228dbd7a91fee48733b71dd3176c7ae [file] [log] [blame]
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -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
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-ZslProcessor"
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
28#include <utils/Log.h>
29#include <utils/Trace.h>
30
31#include "ZslProcessor.h"
Mathias Agopian1a2952a2013-02-14 17:11:27 -080032#include <gui/Surface.h>
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080033#include "../CameraDeviceBase.h"
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070034#include "../Camera2Client.h"
35
36
37namespace android {
38namespace camera2 {
39
40ZslProcessor::ZslProcessor(
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070041 sp<Camera2Client> client,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070042 wp<CaptureSequencer> sequencer):
43 Thread(false),
44 mState(RUNNING),
45 mClient(client),
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070046 mDevice(client->getCameraDevice()),
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070047 mSequencer(sequencer),
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070048 mId(client->getCameraId()),
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070049 mZslBufferAvailable(false),
50 mZslStreamId(NO_STREAM),
51 mZslReprocessStreamId(NO_STREAM),
52 mFrameListHead(0),
53 mZslQueueHead(0),
54 mZslQueueTail(0) {
55 mZslQueue.insertAt(0, kZslBufferDepth);
56 mFrameList.insertAt(0, kFrameListDepth);
57 sp<CaptureSequencer> captureSequencer = mSequencer.promote();
58 if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
59}
60
61ZslProcessor::~ZslProcessor() {
62 ALOGV("%s: Exit", __FUNCTION__);
Eino-Ville Talvalacf70d342012-09-05 19:02:43 -070063 deleteStream();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070064}
65
66void ZslProcessor::onFrameAvailable() {
67 Mutex::Autolock l(mInputMutex);
68 if (!mZslBufferAvailable) {
69 mZslBufferAvailable = true;
70 mZslBufferAvailableSignal.signal();
71 }
72}
73
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070074void ZslProcessor::onFrameAvailable(int32_t /*frameId*/,
75 const CameraMetadata &frame) {
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070076 Mutex::Autolock l(mInputMutex);
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070077 camera_metadata_ro_entry_t entry;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070078 entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
79 nsecs_t timestamp = entry.data.i64[0];
Igor Murashkinddf3c502012-10-12 16:56:11 -070080 (void)timestamp;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070081 ALOGVV("Got preview frame for timestamp %lld", timestamp);
82
83 if (mState != RUNNING) return;
84
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070085 mFrameList.editItemAt(mFrameListHead) = frame;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -070086 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
87
88 findMatchesLocked();
89}
90
91void ZslProcessor::onBufferReleased(buffer_handle_t *handle) {
92 Mutex::Autolock l(mInputMutex);
93
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -070094 // Verify that the buffer is in our queue
95 size_t i = 0;
96 for (; i < mZslQueue.size(); i++) {
97 if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break;
98 }
99 if (i == mZslQueue.size()) {
100 ALOGW("%s: Released buffer %p not found in queue",
101 __FUNCTION__, handle);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700102 }
103
Eino-Ville Talvala768cf092012-09-19 17:11:04 -0700104 // Erase entire ZSL queue since we've now completed the capture and preview
105 // is stopped.
106 clearZslQueueLocked();
107
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700108 mState = RUNNING;
109}
110
111status_t ZslProcessor::updateStream(const Parameters &params) {
112 ATRACE_CALL();
113 ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
114 status_t res;
115
116 Mutex::Autolock l(mInputMutex);
117
118 sp<Camera2Client> client = mClient.promote();
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700119 if (client == 0) {
120 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
121 return INVALID_OPERATION;
122 }
123 sp<CameraDeviceBase> device = mDevice.promote();
124 if (device == 0) {
125 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
126 return INVALID_OPERATION;
127 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700128
129 if (mZslConsumer == 0) {
130 // Create CPU buffer queue endpoint
131 mZslConsumer = new BufferItemConsumer(
132 GRALLOC_USAGE_HW_CAMERA_ZSL,
133 kZslBufferDepth,
134 true);
135 mZslConsumer->setFrameAvailableListener(this);
136 mZslConsumer->setName(String8("Camera2Client::ZslConsumer"));
Mathias Agopian1a2952a2013-02-14 17:11:27 -0800137 mZslWindow = new Surface(
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700138 mZslConsumer->getProducerInterface());
139 }
140
141 if (mZslStreamId != NO_STREAM) {
142 // Check if stream parameters have to change
143 uint32_t currentWidth, currentHeight;
144 res = device->getStreamInfo(mZslStreamId,
145 &currentWidth, &currentHeight, 0);
146 if (res != OK) {
147 ALOGE("%s: Camera %d: Error querying capture output stream info: "
148 "%s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700149 mId, strerror(-res), res);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700150 return res;
151 }
Eino-Ville Talvala6e4db892012-09-11 17:23:48 -0700152 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
153 currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
Eino-Ville Talvala47512a72012-09-10 13:30:43 -0700154 res = device->deleteReprocessStream(mZslReprocessStreamId);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700155 if (res != OK) {
156 ALOGE("%s: Camera %d: Unable to delete old reprocess stream "
157 "for ZSL: %s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700158 mId, strerror(-res), res);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700159 return res;
160 }
Igor Murashkinecf17e82012-10-02 16:05:11 -0700161 ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700162 __FUNCTION__, mId, mZslStreamId);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700163 res = device->deleteStream(mZslStreamId);
164 if (res != OK) {
165 ALOGE("%s: Camera %d: Unable to delete old output stream "
166 "for ZSL: %s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700167 mId, strerror(-res), res);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700168 return res;
169 }
170 mZslStreamId = NO_STREAM;
171 }
172 }
173
174 if (mZslStreamId == NO_STREAM) {
175 // Create stream for HAL production
Eino-Ville Talvala6e4db892012-09-11 17:23:48 -0700176 // TODO: Sort out better way to select resolution for ZSL
Eino-Ville Talvalae382ee22012-10-02 18:14:49 -0700177 int streamType = params.quirks.useZslFormat ?
178 (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL :
179 (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700180 res = device->createStream(mZslWindow,
Eino-Ville Talvala6e4db892012-09-11 17:23:48 -0700181 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
Eino-Ville Talvalae382ee22012-10-02 18:14:49 -0700182 streamType, 0,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700183 &mZslStreamId);
184 if (res != OK) {
185 ALOGE("%s: Camera %d: Can't create output stream for ZSL: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700186 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700187 strerror(-res), res);
188 return res;
189 }
190 res = device->createReprocessStreamFromStream(mZslStreamId,
191 &mZslReprocessStreamId);
192 if (res != OK) {
193 ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700194 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700195 strerror(-res), res);
196 return res;
197 }
198 }
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700199 client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
200 Camera2Client::kPreviewRequestIdEnd,
201 this);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700202
203 return OK;
204}
205
206status_t ZslProcessor::deleteStream() {
207 ATRACE_CALL();
208 status_t res;
209
210 Mutex::Autolock l(mInputMutex);
211
212 if (mZslStreamId != NO_STREAM) {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700213 sp<CameraDeviceBase> device = mDevice.promote();
214 if (device == 0) {
215 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
216 return INVALID_OPERATION;
217 }
218
219 clearZslQueueLocked();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700220
Eino-Ville Talvala47512a72012-09-10 13:30:43 -0700221 res = device->deleteReprocessStream(mZslReprocessStreamId);
222 if (res != OK) {
223 ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700224 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala47512a72012-09-10 13:30:43 -0700225 mZslReprocessStreamId, strerror(-res), res);
226 return res;
227 }
228
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700229 mZslReprocessStreamId = NO_STREAM;
Eino-Ville Talvala47512a72012-09-10 13:30:43 -0700230 res = device->deleteStream(mZslStreamId);
231 if (res != OK) {
232 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700233 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala47512a72012-09-10 13:30:43 -0700234 mZslStreamId, strerror(-res), res);
235 return res;
236 }
Eino-Ville Talvalacf70d342012-09-05 19:02:43 -0700237
238 mZslWindow.clear();
239 mZslConsumer.clear();
240
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700241 mZslStreamId = NO_STREAM;
242 }
243 return OK;
244}
245
246int ZslProcessor::getStreamId() const {
247 Mutex::Autolock l(mInputMutex);
248 return mZslStreamId;
249}
250
251int ZslProcessor::getReprocessStreamId() const {
252 Mutex::Autolock l(mInputMutex);
253 return mZslReprocessStreamId;
254}
255
256status_t ZslProcessor::pushToReprocess(int32_t requestId) {
257 ALOGV("%s: Send in reprocess request with id %d",
258 __FUNCTION__, requestId);
259 Mutex::Autolock l(mInputMutex);
260 status_t res;
261 sp<Camera2Client> client = mClient.promote();
262
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700263 if (client == 0) {
264 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
265 return INVALID_OPERATION;
266 }
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700267
268 IF_ALOGV() {
269 dumpZslQueue(-1);
270 }
271
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700272 if (mZslQueueTail != mZslQueueHead) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700273 CameraMetadata request;
274 size_t index = mZslQueueTail;
Eino-Ville Talvala4d410ed2012-10-06 13:50:31 -0700275 while (index != mZslQueueHead) {
276 if (!mZslQueue[index].frame.isEmpty()) {
277 request = mZslQueue[index].frame;
278 break;
279 }
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700280 index = (index + 1) % kZslBufferDepth;
281 }
Eino-Ville Talvala4d410ed2012-10-06 13:50:31 -0700282 if (index == mZslQueueHead) {
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700283 ALOGV("%s: ZSL queue has no valid frames to send yet.",
284 __FUNCTION__);
285 return NOT_ENOUGH_DATA;
286 }
287 // Verify that the frame is reasonable for reprocessing
288
289 camera_metadata_entry_t entry;
290 entry = request.find(ANDROID_CONTROL_AE_STATE);
291 if (entry.count == 0) {
292 ALOGE("%s: ZSL queue frame has no AE state field!",
293 __FUNCTION__);
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700294 return BAD_VALUE;
295 }
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700296 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
297 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
298 ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
299 __FUNCTION__, entry.data.u8[0]);
300 return NOT_ENOUGH_DATA;
301 }
302
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700303 buffer_handle_t *handle =
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700304 &(mZslQueue[index].buffer.mGraphicBuffer->handle);
305
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700306 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
307 res = request.update(ANDROID_REQUEST_TYPE,
308 &requestType, 1);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800309 uint8_t inputStreams[1] =
310 { static_cast<uint8_t>(mZslReprocessStreamId) };
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700311 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
312 inputStreams, 1);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800313 uint8_t outputStreams[1] =
314 { static_cast<uint8_t>(client->getCaptureStreamId()) };
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700315 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
316 outputStreams, 1);
317 res = request.update(ANDROID_REQUEST_ID,
318 &requestId, 1);
319
320 if (res != OK ) {
321 ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__);
322 return INVALID_OPERATION;
323 }
324
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700325 res = client->stopStream();
Alex Rayc2063052012-10-02 23:30:07 -0700326 if (res != OK) {
327 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
328 "%s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700329 __FUNCTION__, mId, strerror(-res), res);
Alex Rayc2063052012-10-02 23:30:07 -0700330 return INVALID_OPERATION;
331 }
332 // TODO: have push-and-clear be atomic
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700333 res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId,
334 handle, this);
335 if (res != OK) {
336 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
337 __FUNCTION__, strerror(-res), res);
338 return res;
339 }
340
Eino-Ville Talvalaec771082012-10-04 13:21:08 -0700341 // Update JPEG settings
342 {
343 SharedParameters::Lock l(client->getParameters());
344 res = l.mParameters.updateRequestJpeg(&request);
345 if (res != OK) {
346 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
347 "capture request: %s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700348 mId,
Eino-Ville Talvalaec771082012-10-04 13:21:08 -0700349 strerror(-res), res);
350 return res;
351 }
352 }
353
354 mLatestCapturedRequest = request;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700355 res = client->getCameraDevice()->capture(request);
356 if (res != OK ) {
357 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)",
358 __FUNCTION__, strerror(-res), res);
359 return res;
360 }
361
362 mState = LOCKED;
363 } else {
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700364 ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
365 return NOT_ENOUGH_DATA;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700366 }
367 return OK;
368}
369
Eino-Ville Talvala768cf092012-09-19 17:11:04 -0700370status_t ZslProcessor::clearZslQueue() {
371 Mutex::Autolock l(mInputMutex);
372 // If in middle of capture, can't clear out queue
373 if (mState == LOCKED) return OK;
374
375 return clearZslQueueLocked();
376}
377
378status_t ZslProcessor::clearZslQueueLocked() {
379 for (size_t i = 0; i < mZslQueue.size(); i++) {
380 if (mZslQueue[i].buffer.mTimestamp != 0) {
381 mZslConsumer->releaseBuffer(mZslQueue[i].buffer);
382 }
383 mZslQueue.replaceAt(i);
384 }
385 mZslQueueHead = 0;
386 mZslQueueTail = 0;
387 return OK;
388}
389
Igor Murashkinddf3c502012-10-12 16:56:11 -0700390void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700391 Mutex::Autolock l(mInputMutex);
Eino-Ville Talvalaec771082012-10-04 13:21:08 -0700392 if (!mLatestCapturedRequest.isEmpty()) {
393 String8 result(" Latest ZSL capture request:\n");
394 write(fd, result.string(), result.size());
395 mLatestCapturedRequest.dump(fd, 2, 6);
396 } else {
397 String8 result(" Latest ZSL capture request: none yet\n");
398 write(fd, result.string(), result.size());
399 }
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700400 dumpZslQueue(fd);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700401}
402
403bool ZslProcessor::threadLoop() {
404 status_t res;
405
406 {
407 Mutex::Autolock l(mInputMutex);
408 while (!mZslBufferAvailable) {
409 res = mZslBufferAvailableSignal.waitRelative(mInputMutex,
410 kWaitDuration);
411 if (res == TIMED_OUT) return true;
412 }
413 mZslBufferAvailable = false;
414 }
415
416 do {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700417 res = processNewZslBuffer();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700418 } while (res == OK);
419
420 return true;
421}
422
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700423status_t ZslProcessor::processNewZslBuffer() {
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700424 ATRACE_CALL();
425 status_t res;
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700426 sp<BufferItemConsumer> zslConsumer;
427 {
428 Mutex::Autolock l(mInputMutex);
429 if (mZslConsumer == 0) return OK;
430 zslConsumer = mZslConsumer;
431 }
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700432 ALOGVV("Trying to get next buffer");
433 BufferItemConsumer::BufferItem item;
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700434 res = zslConsumer->acquireBuffer(&item);
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700435 if (res != OK) {
436 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
437 ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
438 "%s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700439 mId, strerror(-res), res);
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700440 } else {
441 ALOGVV(" No buffer");
442 }
443 return res;
444 }
445
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700446 Mutex::Autolock l(mInputMutex);
447
448 if (mState == LOCKED) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700449 ALOGVV("In capture, discarding new ZSL buffers");
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700450 zslConsumer->releaseBuffer(item);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700451 return OK;
452 }
453
454 ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
455
456 if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700457 ALOGVV("Releasing oldest buffer");
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700458 zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700459 mZslQueue.replaceAt(mZslQueueTail);
460 mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
461 }
462
463 ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
464
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700465 queueHead.buffer = item;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700466 queueHead.frame.release();
467
468 mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
469
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700470 ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700471
472 findMatchesLocked();
473
474 return OK;
475}
476
477void ZslProcessor::findMatchesLocked() {
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700478 ALOGVV("Scanning");
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700479 for (size_t i = 0; i < mZslQueue.size(); i++) {
480 ZslPair &queueEntry = mZslQueue.editItemAt(i);
481 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
Eino-Ville Talvalabdde5f82012-09-12 10:42:10 -0700482 IF_ALOGV() {
483 camera_metadata_entry_t entry;
484 nsecs_t frameTimestamp = 0;
485 if (!queueEntry.frame.isEmpty()) {
486 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
487 frameTimestamp = entry.data.i64[0];
488 }
489 ALOGVV(" %d: b: %lld\tf: %lld", i,
490 bufferTimestamp, frameTimestamp );
491 }
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700492 if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
493 // Have buffer, no matching frame. Look for one
494 for (size_t j = 0; j < mFrameList.size(); j++) {
495 bool match = false;
496 CameraMetadata &frame = mFrameList.editItemAt(j);
497 if (!frame.isEmpty()) {
498 camera_metadata_entry_t entry;
499 entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
500 if (entry.count == 0) {
501 ALOGE("%s: Can't find timestamp in frame!",
502 __FUNCTION__);
503 continue;
504 }
505 nsecs_t frameTimestamp = entry.data.i64[0];
506 if (bufferTimestamp == frameTimestamp) {
507 ALOGVV("%s: Found match %lld", __FUNCTION__,
508 frameTimestamp);
509 match = true;
510 } else {
511 int64_t delta = abs(bufferTimestamp - frameTimestamp);
512 if ( delta < 1000000) {
513 ALOGVV("%s: Found close match %lld (delta %lld)",
514 __FUNCTION__, bufferTimestamp, delta);
515 match = true;
516 }
517 }
518 }
519 if (match) {
520 queueEntry.frame.acquire(frame);
521 break;
522 }
523 }
524 }
525 }
526}
527
Eino-Ville Talvala97b38a82012-09-17 17:55:07 -0700528void ZslProcessor::dumpZslQueue(int fd) const {
529 String8 header("ZSL queue contents:");
530 String8 indent(" ");
531 ALOGV("%s", header.string());
532 if (fd != -1) {
533 header = indent + header + "\n";
534 write(fd, header.string(), header.size());
535 }
536 for (size_t i = 0; i < mZslQueue.size(); i++) {
537 const ZslPair &queueEntry = mZslQueue[i];
538 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
539 camera_metadata_ro_entry_t entry;
540 nsecs_t frameTimestamp = 0;
541 int frameAeState = -1;
542 if (!queueEntry.frame.isEmpty()) {
543 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
544 if (entry.count > 0) frameTimestamp = entry.data.i64[0];
545 entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
546 if (entry.count > 0) frameAeState = entry.data.u8[0];
547 }
548 String8 result =
549 String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i,
550 bufferTimestamp, frameTimestamp, frameAeState);
551 ALOGV("%s", result.string());
552 if (fd != -1) {
553 result = indent + result + "\n";
554 write(fd, result.string(), result.size());
555 }
556
557 }
558}
559
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700560}; // namespace camera2
561}; // namespace android