• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &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();
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                 &currentWidth, &currentHeight, 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