1 /*
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 #define LOG_TAG "Camera2-ZslProcessor"
18 #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 #include <gui/Surface.h>
31
32 #include "common/CameraDeviceBase.h"
33 #include "api1/Camera2Client.h"
34 #include "api1/client2/CaptureSequencer.h"
35 #include "api1/client2/ZslProcessor.h"
36
37 namespace android {
38 namespace camera2 {
39
ZslProcessor(sp<Camera2Client> client,wp<CaptureSequencer> sequencer)40 ZslProcessor::ZslProcessor(
41 sp<Camera2Client> client,
42 wp<CaptureSequencer> sequencer):
43 Thread(false),
44 mState(RUNNING),
45 mClient(client),
46 mDevice(client->getCameraDevice()),
47 mSequencer(sequencer),
48 mId(client->getCameraId()),
49 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
~ZslProcessor()61 ZslProcessor::~ZslProcessor() {
62 ALOGV("%s: Exit", __FUNCTION__);
63 deleteStream();
64 }
65
onFrameAvailable()66 void ZslProcessor::onFrameAvailable() {
67 Mutex::Autolock l(mInputMutex);
68 if (!mZslBufferAvailable) {
69 mZslBufferAvailable = true;
70 mZslBufferAvailableSignal.signal();
71 }
72 }
73
onFrameAvailable(int32_t,const CameraMetadata & frame)74 void ZslProcessor::onFrameAvailable(int32_t /*requestId*/,
75 const CameraMetadata &frame) {
76 Mutex::Autolock l(mInputMutex);
77 camera_metadata_ro_entry_t entry;
78 entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
79 nsecs_t timestamp = entry.data.i64[0];
80 (void)timestamp;
81 ALOGVV("Got preview frame for timestamp %lld", timestamp);
82
83 if (mState != RUNNING) return;
84
85 mFrameList.editItemAt(mFrameListHead) = frame;
86 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
87
88 findMatchesLocked();
89 }
90
onBufferReleased(buffer_handle_t * handle)91 void ZslProcessor::onBufferReleased(buffer_handle_t *handle) {
92 Mutex::Autolock l(mInputMutex);
93
94 // 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);
102 }
103
104 // Erase entire ZSL queue since we've now completed the capture and preview
105 // is stopped.
106 clearZslQueueLocked();
107
108 mState = RUNNING;
109 }
110
updateStream(const Parameters & params)111 status_t ZslProcessor::updateStream(const Parameters ¶ms) {
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();
119 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 }
128
129 if (mZslConsumer == 0) {
130 // Create CPU buffer queue endpoint
131 sp<BufferQueue> bq = new BufferQueue();
132 mZslConsumer = new BufferItemConsumer(bq,
133 GRALLOC_USAGE_HW_CAMERA_ZSL,
134 kZslBufferDepth);
135 mZslConsumer->setFrameAvailableListener(this);
136 mZslConsumer->setName(String8("Camera2Client::ZslConsumer"));
137 mZslWindow = new Surface(bq);
138 }
139
140 if (mZslStreamId != NO_STREAM) {
141 // Check if stream parameters have to change
142 uint32_t currentWidth, currentHeight;
143 res = device->getStreamInfo(mZslStreamId,
144 ¤tWidth, ¤tHeight, 0);
145 if (res != OK) {
146 ALOGE("%s: Camera %d: Error querying capture output stream info: "
147 "%s (%d)", __FUNCTION__,
148 mId, strerror(-res), res);
149 return res;
150 }
151 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
152 currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
153 res = device->deleteReprocessStream(mZslReprocessStreamId);
154 if (res != OK) {
155 ALOGE("%s: Camera %d: Unable to delete old reprocess stream "
156 "for ZSL: %s (%d)", __FUNCTION__,
157 mId, strerror(-res), res);
158 return res;
159 }
160 ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
161 __FUNCTION__, mId, mZslStreamId);
162 res = device->deleteStream(mZslStreamId);
163 if (res != OK) {
164 ALOGE("%s: Camera %d: Unable to delete old output stream "
165 "for ZSL: %s (%d)", __FUNCTION__,
166 mId, strerror(-res), res);
167 return res;
168 }
169 mZslStreamId = NO_STREAM;
170 }
171 }
172
173 if (mZslStreamId == NO_STREAM) {
174 // Create stream for HAL production
175 // TODO: Sort out better way to select resolution for ZSL
176 int streamType = params.quirks.useZslFormat ?
177 (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL :
178 (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
179 res = device->createStream(mZslWindow,
180 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
181 streamType, 0,
182 &mZslStreamId);
183 if (res != OK) {
184 ALOGE("%s: Camera %d: Can't create output stream for ZSL: "
185 "%s (%d)", __FUNCTION__, mId,
186 strerror(-res), res);
187 return res;
188 }
189 res = device->createReprocessStreamFromStream(mZslStreamId,
190 &mZslReprocessStreamId);
191 if (res != OK) {
192 ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: "
193 "%s (%d)", __FUNCTION__, mId,
194 strerror(-res), res);
195 return res;
196 }
197 }
198 client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
199 Camera2Client::kPreviewRequestIdEnd,
200 this);
201
202 return OK;
203 }
204
deleteStream()205 status_t ZslProcessor::deleteStream() {
206 ATRACE_CALL();
207 status_t res;
208
209 Mutex::Autolock l(mInputMutex);
210
211 if (mZslStreamId != NO_STREAM) {
212 sp<CameraDeviceBase> device = mDevice.promote();
213 if (device == 0) {
214 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
215 return INVALID_OPERATION;
216 }
217
218 clearZslQueueLocked();
219
220 res = device->deleteReprocessStream(mZslReprocessStreamId);
221 if (res != OK) {
222 ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: "
223 "%s (%d)", __FUNCTION__, mId,
224 mZslReprocessStreamId, strerror(-res), res);
225 return res;
226 }
227
228 mZslReprocessStreamId = NO_STREAM;
229 res = device->deleteStream(mZslStreamId);
230 if (res != OK) {
231 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
232 "%s (%d)", __FUNCTION__, mId,
233 mZslStreamId, strerror(-res), res);
234 return res;
235 }
236
237 mZslWindow.clear();
238 mZslConsumer.clear();
239
240 mZslStreamId = NO_STREAM;
241 }
242 return OK;
243 }
244
getStreamId() const245 int ZslProcessor::getStreamId() const {
246 Mutex::Autolock l(mInputMutex);
247 return mZslStreamId;
248 }
249
pushToReprocess(int32_t requestId)250 status_t ZslProcessor::pushToReprocess(int32_t requestId) {
251 ALOGV("%s: Send in reprocess request with id %d",
252 __FUNCTION__, requestId);
253 Mutex::Autolock l(mInputMutex);
254 status_t res;
255 sp<Camera2Client> client = mClient.promote();
256
257 if (client == 0) {
258 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
259 return INVALID_OPERATION;
260 }
261
262 IF_ALOGV() {
263 dumpZslQueue(-1);
264 }
265
266 if (mZslQueueTail != mZslQueueHead) {
267 CameraMetadata request;
268 size_t index = mZslQueueTail;
269 while (index != mZslQueueHead) {
270 if (!mZslQueue[index].frame.isEmpty()) {
271 request = mZslQueue[index].frame;
272 break;
273 }
274 index = (index + 1) % kZslBufferDepth;
275 }
276 if (index == mZslQueueHead) {
277 ALOGV("%s: ZSL queue has no valid frames to send yet.",
278 __FUNCTION__);
279 return NOT_ENOUGH_DATA;
280 }
281 // Verify that the frame is reasonable for reprocessing
282
283 camera_metadata_entry_t entry;
284 entry = request.find(ANDROID_CONTROL_AE_STATE);
285 if (entry.count == 0) {
286 ALOGE("%s: ZSL queue frame has no AE state field!",
287 __FUNCTION__);
288 return BAD_VALUE;
289 }
290 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
291 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
292 ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
293 __FUNCTION__, entry.data.u8[0]);
294 return NOT_ENOUGH_DATA;
295 }
296
297 buffer_handle_t *handle =
298 &(mZslQueue[index].buffer.mGraphicBuffer->handle);
299
300 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
301 res = request.update(ANDROID_REQUEST_TYPE,
302 &requestType, 1);
303 int32_t inputStreams[1] =
304 { mZslReprocessStreamId };
305 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
306 inputStreams, 1);
307 int32_t outputStreams[1] =
308 { client->getCaptureStreamId() };
309 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
310 outputStreams, 1);
311 res = request.update(ANDROID_REQUEST_ID,
312 &requestId, 1);
313
314 if (res != OK ) {
315 ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__);
316 return INVALID_OPERATION;
317 }
318
319 res = client->stopStream();
320 if (res != OK) {
321 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
322 "%s (%d)",
323 __FUNCTION__, mId, strerror(-res), res);
324 return INVALID_OPERATION;
325 }
326 // TODO: have push-and-clear be atomic
327 res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId,
328 handle, this);
329 if (res != OK) {
330 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
331 __FUNCTION__, strerror(-res), res);
332 return res;
333 }
334
335 // Update JPEG settings
336 {
337 SharedParameters::Lock l(client->getParameters());
338 res = l.mParameters.updateRequestJpeg(&request);
339 if (res != OK) {
340 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
341 "capture request: %s (%d)", __FUNCTION__,
342 mId,
343 strerror(-res), res);
344 return res;
345 }
346 }
347
348 mLatestCapturedRequest = request;
349 res = client->getCameraDevice()->capture(request);
350 if (res != OK ) {
351 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)",
352 __FUNCTION__, strerror(-res), res);
353 return res;
354 }
355
356 mState = LOCKED;
357 } else {
358 ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
359 return NOT_ENOUGH_DATA;
360 }
361 return OK;
362 }
363
clearZslQueue()364 status_t ZslProcessor::clearZslQueue() {
365 Mutex::Autolock l(mInputMutex);
366 // If in middle of capture, can't clear out queue
367 if (mState == LOCKED) return OK;
368
369 return clearZslQueueLocked();
370 }
371
clearZslQueueLocked()372 status_t ZslProcessor::clearZslQueueLocked() {
373 for (size_t i = 0; i < mZslQueue.size(); i++) {
374 if (mZslQueue[i].buffer.mTimestamp != 0) {
375 mZslConsumer->releaseBuffer(mZslQueue[i].buffer);
376 }
377 mZslQueue.replaceAt(i);
378 }
379 mZslQueueHead = 0;
380 mZslQueueTail = 0;
381 return OK;
382 }
383
dump(int fd,const Vector<String16> &) const384 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
385 Mutex::Autolock l(mInputMutex);
386 if (!mLatestCapturedRequest.isEmpty()) {
387 String8 result(" Latest ZSL capture request:\n");
388 write(fd, result.string(), result.size());
389 mLatestCapturedRequest.dump(fd, 2, 6);
390 } else {
391 String8 result(" Latest ZSL capture request: none yet\n");
392 write(fd, result.string(), result.size());
393 }
394 dumpZslQueue(fd);
395 }
396
threadLoop()397 bool ZslProcessor::threadLoop() {
398 status_t res;
399
400 {
401 Mutex::Autolock l(mInputMutex);
402 while (!mZslBufferAvailable) {
403 res = mZslBufferAvailableSignal.waitRelative(mInputMutex,
404 kWaitDuration);
405 if (res == TIMED_OUT) return true;
406 }
407 mZslBufferAvailable = false;
408 }
409
410 do {
411 res = processNewZslBuffer();
412 } while (res == OK);
413
414 return true;
415 }
416
processNewZslBuffer()417 status_t ZslProcessor::processNewZslBuffer() {
418 ATRACE_CALL();
419 status_t res;
420 sp<BufferItemConsumer> zslConsumer;
421 {
422 Mutex::Autolock l(mInputMutex);
423 if (mZslConsumer == 0) return OK;
424 zslConsumer = mZslConsumer;
425 }
426 ALOGVV("Trying to get next buffer");
427 BufferItemConsumer::BufferItem item;
428 res = zslConsumer->acquireBuffer(&item, 0);
429 if (res != OK) {
430 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
431 ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
432 "%s (%d)", __FUNCTION__,
433 mId, strerror(-res), res);
434 } else {
435 ALOGVV(" No buffer");
436 }
437 return res;
438 }
439
440 Mutex::Autolock l(mInputMutex);
441
442 if (mState == LOCKED) {
443 ALOGVV("In capture, discarding new ZSL buffers");
444 zslConsumer->releaseBuffer(item);
445 return OK;
446 }
447
448 ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
449
450 if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
451 ALOGVV("Releasing oldest buffer");
452 zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
453 mZslQueue.replaceAt(mZslQueueTail);
454 mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
455 }
456
457 ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
458
459 queueHead.buffer = item;
460 queueHead.frame.release();
461
462 mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
463
464 ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
465
466 findMatchesLocked();
467
468 return OK;
469 }
470
findMatchesLocked()471 void ZslProcessor::findMatchesLocked() {
472 ALOGVV("Scanning");
473 for (size_t i = 0; i < mZslQueue.size(); i++) {
474 ZslPair &queueEntry = mZslQueue.editItemAt(i);
475 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
476 IF_ALOGV() {
477 camera_metadata_entry_t entry;
478 nsecs_t frameTimestamp = 0;
479 if (!queueEntry.frame.isEmpty()) {
480 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
481 frameTimestamp = entry.data.i64[0];
482 }
483 ALOGVV(" %d: b: %lld\tf: %lld", i,
484 bufferTimestamp, frameTimestamp );
485 }
486 if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
487 // Have buffer, no matching frame. Look for one
488 for (size_t j = 0; j < mFrameList.size(); j++) {
489 bool match = false;
490 CameraMetadata &frame = mFrameList.editItemAt(j);
491 if (!frame.isEmpty()) {
492 camera_metadata_entry_t entry;
493 entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
494 if (entry.count == 0) {
495 ALOGE("%s: Can't find timestamp in frame!",
496 __FUNCTION__);
497 continue;
498 }
499 nsecs_t frameTimestamp = entry.data.i64[0];
500 if (bufferTimestamp == frameTimestamp) {
501 ALOGVV("%s: Found match %lld", __FUNCTION__,
502 frameTimestamp);
503 match = true;
504 } else {
505 int64_t delta = abs(bufferTimestamp - frameTimestamp);
506 if ( delta < 1000000) {
507 ALOGVV("%s: Found close match %lld (delta %lld)",
508 __FUNCTION__, bufferTimestamp, delta);
509 match = true;
510 }
511 }
512 }
513 if (match) {
514 queueEntry.frame.acquire(frame);
515 break;
516 }
517 }
518 }
519 }
520 }
521
dumpZslQueue(int fd) const522 void ZslProcessor::dumpZslQueue(int fd) const {
523 String8 header("ZSL queue contents:");
524 String8 indent(" ");
525 ALOGV("%s", header.string());
526 if (fd != -1) {
527 header = indent + header + "\n";
528 write(fd, header.string(), header.size());
529 }
530 for (size_t i = 0; i < mZslQueue.size(); i++) {
531 const ZslPair &queueEntry = mZslQueue[i];
532 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
533 camera_metadata_ro_entry_t entry;
534 nsecs_t frameTimestamp = 0;
535 int frameAeState = -1;
536 if (!queueEntry.frame.isEmpty()) {
537 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
538 if (entry.count > 0) frameTimestamp = entry.data.i64[0];
539 entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
540 if (entry.count > 0) frameAeState = entry.data.u8[0];
541 }
542 String8 result =
543 String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i,
544 bufferTimestamp, frameTimestamp, frameAeState);
545 ALOGV("%s", result.string());
546 if (fd != -1) {
547 result = indent + result + "\n";
548 write(fd, result.string(), result.size());
549 }
550
551 }
552 }
553
554 }; // namespace camera2
555 }; // namespace android
556