• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013-2018 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(...) if (0) ALOGV(__VA_ARGS__)
26 #endif
27 
28 #include <inttypes.h>
29 
30 #include <utils/Log.h>
31 #include <utils/Trace.h>
32 #include <gui/Surface.h>
33 
34 #include "common/CameraDeviceBase.h"
35 #include "api1/Camera2Client.h"
36 #include "api1/client2/CaptureSequencer.h"
37 #include "api1/client2/ZslProcessor.h"
38 #include "device3/Camera3Device.h"
39 
40 typedef android::RingBufferConsumer::PinnedBufferItem PinnedBufferItem;
41 
42 namespace android {
43 namespace camera2 {
44 
45 namespace {
46 struct TimestampFinder : public RingBufferConsumer::RingBufferComparator {
47     typedef RingBufferConsumer::BufferInfo BufferInfo;
48 
49     enum {
50         SELECT_I1 = -1,
51         SELECT_I2 = 1,
52         SELECT_NEITHER = 0,
53     };
54 
TimestampFinderandroid::camera2::__anon380456cd0111::TimestampFinder55     explicit TimestampFinder(nsecs_t timestamp) : mTimestamp(timestamp) {}
~TimestampFinderandroid::camera2::__anon380456cd0111::TimestampFinder56     ~TimestampFinder() {}
57 
58     template <typename T>
swapandroid::camera2::__anon380456cd0111::TimestampFinder59     static void swap(T& a, T& b) {
60         T tmp = a;
61         a = b;
62         b = tmp;
63     }
64 
65     /**
66      * Try to find the best candidate for a ZSL buffer.
67      * Match priority from best to worst:
68      *  1) Timestamps match.
69      *  2) Timestamp is closest to the needle (and lower).
70      *  3) Timestamp is closest to the needle (and higher).
71      *
72      */
compareandroid::camera2::__anon380456cd0111::TimestampFinder73     virtual int compare(const BufferInfo *i1,
74                         const BufferInfo *i2) const {
75         // Try to select non-null object first.
76         if (i1 == NULL) {
77             return SELECT_I2;
78         } else if (i2 == NULL) {
79             return SELECT_I1;
80         }
81 
82         // Best result: timestamp is identical
83         if (i1->mTimestamp == mTimestamp) {
84             return SELECT_I1;
85         } else if (i2->mTimestamp == mTimestamp) {
86             return SELECT_I2;
87         }
88 
89         const BufferInfo* infoPtrs[2] = {
90             i1,
91             i2
92         };
93         int infoSelectors[2] = {
94             SELECT_I1,
95             SELECT_I2
96         };
97 
98         // Order i1,i2 so that always i1.timestamp < i2.timestamp
99         if (i1->mTimestamp > i2->mTimestamp) {
100             swap(infoPtrs[0], infoPtrs[1]);
101             swap(infoSelectors[0], infoSelectors[1]);
102         }
103 
104         // Second best: closest (lower) timestamp
105         if (infoPtrs[1]->mTimestamp < mTimestamp) {
106             return infoSelectors[1];
107         } else if (infoPtrs[0]->mTimestamp < mTimestamp) {
108             return infoSelectors[0];
109         }
110 
111         // Worst: closest (higher) timestamp
112         return infoSelectors[0];
113 
114         /**
115          * The above cases should cover all the possibilities,
116          * and we get an 'empty' result only if the ring buffer
117          * was empty itself
118          */
119     }
120 
121     const nsecs_t mTimestamp;
122 }; // struct TimestampFinder
123 } // namespace anonymous
124 
ZslProcessor(sp<Camera2Client> client,wp<CaptureSequencer> sequencer)125 ZslProcessor::ZslProcessor(
126     sp<Camera2Client> client,
127     wp<CaptureSequencer> sequencer):
128         Thread(false),
129         mLatestClearedBufferTimestamp(0),
130         mState(RUNNING),
131         mClient(client),
132         mSequencer(sequencer),
133         mId(client->getCameraId()),
134         mZslStreamId(NO_STREAM),
135         mInputStreamId(NO_STREAM),
136         mFrameListHead(0),
137         mHasFocuser(false),
138         mInputBuffer(nullptr),
139         mProducer(nullptr),
140         mInputProducer(nullptr),
141         mInputProducerSlot(-1),
142         mBuffersToDetach(0) {
143     // Initialize buffer queue and frame list based on pipeline max depth.
144     size_t pipelineMaxDepth = kDefaultMaxPipelineDepth;
145     if (client != 0) {
146         sp<Camera3Device> device =
147         static_cast<Camera3Device*>(client->getCameraDevice().get());
148         if (device != 0) {
149             camera_metadata_ro_entry_t entry =
150                 device->info().find(ANDROID_REQUEST_PIPELINE_MAX_DEPTH);
151             if (entry.count == 1) {
152                 pipelineMaxDepth = entry.data.u8[0];
153             } else {
154                 ALOGW("%s: Unable to find the android.request.pipelineMaxDepth,"
155                         " use default pipeline max depth %d", __FUNCTION__,
156                         kDefaultMaxPipelineDepth);
157             }
158 
159             entry = device->info().find(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
160             if (entry.count > 0 && entry.data.f[0] != 0.) {
161                 mHasFocuser = true;
162             }
163         }
164     }
165 
166     ALOGV("%s: Initialize buffer queue and frame list depth based on max pipeline depth (%zu)",
167           __FUNCTION__, pipelineMaxDepth);
168     // Need to keep buffer queue longer than metadata queue because sometimes buffer arrives
169     // earlier than metadata which causes the buffer corresponding to oldest metadata being
170     // removed.
171     mFrameListDepth = pipelineMaxDepth;
172     mBufferQueueDepth = mFrameListDepth + 1;
173 
174     mZslQueue.insertAt(0, mBufferQueueDepth);
175     mFrameList.insertAt(0, mFrameListDepth);
176     sp<CaptureSequencer> captureSequencer = mSequencer.promote();
177     if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
178 }
179 
~ZslProcessor()180 ZslProcessor::~ZslProcessor() {
181     ALOGV("%s: Exit", __FUNCTION__);
182     deleteStream();
183 }
184 
onResultAvailable(const CaptureResult & result)185 void ZslProcessor::onResultAvailable(const CaptureResult &result) {
186     ATRACE_CALL();
187     ALOGV("%s:", __FUNCTION__);
188     Mutex::Autolock l(mInputMutex);
189     camera_metadata_ro_entry_t entry;
190     entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
191     nsecs_t timestamp = entry.data.i64[0];
192     if (entry.count == 0) {
193         ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__);
194         return;
195     }
196 
197     entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
198     if (entry.count == 0) {
199         ALOGE("%s: metadata doesn't have frame number, skip this result", __FUNCTION__);
200         return;
201     }
202     int32_t frameNumber = entry.data.i32[0];
203 
204     ALOGVV("Got preview metadata for frame %d with timestamp %" PRId64, frameNumber, timestamp);
205 
206     if (mState != RUNNING) return;
207 
208     // Corresponding buffer has been cleared. No need to push into mFrameList
209     if (timestamp <= mLatestClearedBufferTimestamp) return;
210 
211     mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
212     mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
213 }
214 
updateStream(const Parameters & params)215 status_t ZslProcessor::updateStream(const Parameters &params) {
216     ATRACE_CALL();
217     ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
218     status_t res;
219 
220     Mutex::Autolock l(mInputMutex);
221 
222     sp<Camera2Client> client = mClient.promote();
223     if (client == 0) {
224         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
225         return INVALID_OPERATION;
226     }
227     sp<Camera3Device> device =
228         static_cast<Camera3Device*>(client->getCameraDevice().get());
229     if (device == 0) {
230         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
231         return INVALID_OPERATION;
232     }
233 
234     if (mInputStreamId == NO_STREAM) {
235         res = device->createInputStream(params.fastInfo.maxZslSize.width,
236             params.fastInfo.maxZslSize.height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
237             &mInputStreamId);
238         if (res != OK) {
239             ALOGE("%s: Camera %d: Can't create input stream: "
240                     "%s (%d)", __FUNCTION__, client->getCameraId(),
241                     strerror(-res), res);
242             return res;
243         }
244     }
245 
246     if (mZslStreamId == NO_STREAM) {
247         // Create stream for HAL production
248         // TODO: Sort out better way to select resolution for ZSL
249 
250         sp<IGraphicBufferProducer> producer;
251         sp<IGraphicBufferConsumer> consumer;
252         BufferQueue::createBufferQueue(&producer, &consumer);
253         mProducer = new RingBufferConsumer(consumer, GRALLOC_USAGE_HW_CAMERA_ZSL,
254             mBufferQueueDepth);
255         mProducer->setName(String8("Camera2-ZslRingBufferConsumer"));
256         sp<Surface> outSurface = new Surface(producer);
257 
258         res = device->createStream(outSurface, params.fastInfo.maxZslSize.width,
259             params.fastInfo.maxZslSize.height, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
260             HAL_DATASPACE_UNKNOWN, CAMERA3_STREAM_ROTATION_0, &mZslStreamId,
261             String8());
262         if (res != OK) {
263             ALOGE("%s: Camera %d: Can't create ZSL stream: "
264                     "%s (%d)", __FUNCTION__, client->getCameraId(),
265                     strerror(-res), res);
266             return res;
267         }
268     }
269 
270     client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
271             Camera2Client::kPreviewRequestIdEnd,
272             this,
273             /*sendPartials*/false);
274 
275     return OK;
276 }
277 
deleteStream()278 status_t ZslProcessor::deleteStream() {
279     ATRACE_CALL();
280     status_t res;
281     sp<Camera3Device> device = nullptr;
282     sp<Camera2Client> client = nullptr;
283 
284     Mutex::Autolock l(mInputMutex);
285 
286     if ((mZslStreamId != NO_STREAM) || (mInputStreamId != NO_STREAM)) {
287         client = mClient.promote();
288         if (client == 0) {
289             ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
290             return INVALID_OPERATION;
291         }
292 
293         device =
294             reinterpret_cast<Camera3Device*>(client->getCameraDevice().get());
295         if (device == 0) {
296             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
297             return INVALID_OPERATION;
298         }
299     }
300 
301     if (mZslStreamId != NO_STREAM) {
302         res = device->deleteStream(mZslStreamId);
303         if (res != OK) {
304             ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
305                     "%s (%d)", __FUNCTION__, client->getCameraId(),
306                     mZslStreamId, strerror(-res), res);
307             return res;
308         }
309 
310         mZslStreamId = NO_STREAM;
311     }
312     if (mInputStreamId != NO_STREAM) {
313         res = device->deleteStream(mInputStreamId);
314         if (res != OK) {
315             ALOGE("%s: Camera %d: Cannot delete input stream %d: "
316                     "%s (%d)", __FUNCTION__, client->getCameraId(),
317                     mInputStreamId, strerror(-res), res);
318             return res;
319         }
320 
321         mInputStreamId = NO_STREAM;
322     }
323 
324     if (nullptr != mInputProducer.get()) {
325         mInputProducer->disconnect(NATIVE_WINDOW_API_CPU);
326         mInputProducer.clear();
327     }
328 
329     return OK;
330 }
331 
getStreamId() const332 int ZslProcessor::getStreamId() const {
333     Mutex::Autolock l(mInputMutex);
334     return mZslStreamId;
335 }
336 
updateRequestWithDefaultStillRequest(CameraMetadata & request) const337 status_t ZslProcessor::updateRequestWithDefaultStillRequest(CameraMetadata &request) const {
338     sp<Camera2Client> client = mClient.promote();
339     if (client == 0) {
340         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
341         return INVALID_OPERATION;
342     }
343     sp<Camera3Device> device =
344         static_cast<Camera3Device*>(client->getCameraDevice().get());
345     if (device == 0) {
346         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
347         return INVALID_OPERATION;
348     }
349 
350     CameraMetadata stillTemplate;
351     device->createDefaultRequest(CAMERA3_TEMPLATE_STILL_CAPTURE, &stillTemplate);
352 
353     // Find some of the post-processing tags, and assign the value from template to the request.
354     // Only check the aberration mode and noise reduction mode for now, as they are very important
355     // for image quality.
356     uint32_t postProcessingTags[] = {
357             ANDROID_NOISE_REDUCTION_MODE,
358             ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
359             ANDROID_COLOR_CORRECTION_MODE,
360             ANDROID_TONEMAP_MODE,
361             ANDROID_SHADING_MODE,
362             ANDROID_HOT_PIXEL_MODE,
363             ANDROID_EDGE_MODE
364     };
365 
366     camera_metadata_entry_t entry;
367     for (size_t i = 0; i < sizeof(postProcessingTags) / sizeof(uint32_t); i++) {
368         entry = stillTemplate.find(postProcessingTags[i]);
369         if (entry.count > 0) {
370             request.update(postProcessingTags[i], entry.data.u8, 1);
371         }
372     }
373 
374     return OK;
375 }
376 
notifyInputReleased()377 void ZslProcessor::notifyInputReleased() {
378     Mutex::Autolock l(mInputMutex);
379 
380     mBuffersToDetach++;
381     mBuffersToDetachSignal.signal();
382 }
383 
doNotifyInputReleasedLocked()384 void ZslProcessor::doNotifyInputReleasedLocked() {
385     assert(nullptr != mInputBuffer.get());
386     assert(nullptr != mInputProducer.get());
387 
388     sp<GraphicBuffer> gb;
389     sp<Fence> fence;
390     auto rc = mInputProducer->detachNextBuffer(&gb, &fence);
391     if (NO_ERROR != rc) {
392         ALOGE("%s: Failed to detach buffer from input producer: %d",
393             __FUNCTION__, rc);
394         return;
395     }
396 
397     BufferItem &item = mInputBuffer->getBufferItem();
398     sp<GraphicBuffer> inputBuffer = item.mGraphicBuffer;
399     if (gb->handle != inputBuffer->handle) {
400         ALOGE("%s: Input mismatch, expected buffer %p received %p", __FUNCTION__,
401             inputBuffer->handle, gb->handle);
402         return;
403     }
404 
405     mInputBuffer.clear();
406     ALOGV("%s: Memory optimization, clearing ZSL queue",
407           __FUNCTION__);
408     clearZslResultQueueLocked();
409 
410     // Required so we accept more ZSL requests
411     mState = RUNNING;
412 }
413 
onBufferReleased()414 void ZslProcessor::InputProducerListener::onBufferReleased() {
415     sp<ZslProcessor> parent = mParent.promote();
416     if (nullptr != parent.get()) {
417         parent->notifyInputReleased();
418     }
419 }
420 
pushToReprocess(int32_t requestId)421 status_t ZslProcessor::pushToReprocess(int32_t requestId) {
422     ALOGV("%s: Send in reprocess request with id %d",
423             __FUNCTION__, requestId);
424     Mutex::Autolock l(mInputMutex);
425     status_t res;
426     sp<Camera2Client> client = mClient.promote();
427 
428     if (client == 0) {
429         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
430         return INVALID_OPERATION;
431     }
432 
433     IF_ALOGV() {
434         dumpZslQueue(-1);
435     }
436 
437     size_t metadataIdx;
438     nsecs_t candidateTimestamp = getCandidateTimestampLocked(&metadataIdx);
439 
440     if (candidateTimestamp == -1) {
441         ALOGV("%s: Could not find good candidate for ZSL reprocessing",
442               __FUNCTION__);
443         return NOT_ENOUGH_DATA;
444     } else {
445         ALOGV("%s: Found good ZSL candidate idx: %u",
446             __FUNCTION__, (unsigned int) metadataIdx);
447     }
448 
449     if (nullptr == mInputProducer.get()) {
450         res = client->getCameraDevice()->getInputBufferProducer(
451             &mInputProducer);
452         if (res != OK) {
453             ALOGE("%s: Camera %d: Unable to retrieve input producer: "
454                     "%s (%d)", __FUNCTION__, client->getCameraId(),
455                     strerror(-res), res);
456             return res;
457         }
458 
459         IGraphicBufferProducer::QueueBufferOutput output;
460         res = mInputProducer->connect(new InputProducerListener(this),
461             NATIVE_WINDOW_API_CPU, false, &output);
462         if (res != OK) {
463             ALOGE("%s: Camera %d: Unable to connect to input producer: "
464                     "%s (%d)", __FUNCTION__, client->getCameraId(),
465                     strerror(-res), res);
466             return res;
467         }
468     }
469 
470     res = enqueueInputBufferByTimestamp(candidateTimestamp,
471         /*actualTimestamp*/NULL);
472     if (res == NO_BUFFER_AVAILABLE) {
473         ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
474         return NOT_ENOUGH_DATA;
475     } else if (res != OK) {
476         ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
477                 __FUNCTION__, strerror(-res), res);
478         return res;
479     }
480 
481     {
482         CameraMetadata request = mFrameList[metadataIdx];
483 
484         // Verify that the frame is reasonable for reprocessing
485 
486         camera_metadata_entry_t entry;
487         entry = request.find(ANDROID_CONTROL_AE_STATE);
488         if (entry.count == 0) {
489             ALOGE("%s: ZSL queue frame has no AE state field!",
490                     __FUNCTION__);
491             return BAD_VALUE;
492         }
493         if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
494                 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
495             ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
496                     __FUNCTION__, entry.data.u8[0]);
497             return NOT_ENOUGH_DATA;
498         }
499 
500         uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
501         res = request.update(ANDROID_REQUEST_TYPE,
502                 &requestType, 1);
503         if (res != OK) {
504             ALOGE("%s: Unable to update request type",
505                   __FUNCTION__);
506             return INVALID_OPERATION;
507         }
508 
509         int32_t inputStreams[1] =
510                 { mInputStreamId };
511         res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
512                 inputStreams, 1);
513         if (res != OK) {
514             ALOGE("%s: Unable to update request input streams",
515                   __FUNCTION__);
516             return INVALID_OPERATION;
517         }
518 
519         uint8_t captureIntent =
520                 static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
521         res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
522                 &captureIntent, 1);
523         if (res != OK ) {
524             ALOGE("%s: Unable to update request capture intent",
525                   __FUNCTION__);
526             return INVALID_OPERATION;
527         }
528 
529         // TODO: Shouldn't we also update the latest preview frame?
530         int32_t outputStreams[1] =
531                 { client->getCaptureStreamId() };
532         res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
533                 outputStreams, 1);
534         if (res != OK) {
535             ALOGE("%s: Unable to update request output streams",
536                   __FUNCTION__);
537             return INVALID_OPERATION;
538         }
539 
540         res = request.update(ANDROID_REQUEST_ID,
541                 &requestId, 1);
542         if (res != OK ) {
543             ALOGE("%s: Unable to update frame to a reprocess request",
544                   __FUNCTION__);
545             return INVALID_OPERATION;
546         }
547 
548         res = client->stopStream();
549         if (res != OK) {
550             ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
551                 "%s (%d)",
552                 __FUNCTION__, client->getCameraId(), strerror(-res), res);
553             return INVALID_OPERATION;
554         }
555 
556         // Update JPEG settings
557         {
558             SharedParameters::Lock l(client->getParameters());
559             res = l.mParameters.updateRequestJpeg(&request);
560             if (res != OK) {
561                 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
562                         "capture request: %s (%d)", __FUNCTION__,
563                         client->getCameraId(),
564                         strerror(-res), res);
565                 return res;
566             }
567         }
568 
569         // Update post-processing settings
570         res = updateRequestWithDefaultStillRequest(request);
571         if (res != OK) {
572             ALOGW("%s: Unable to update post-processing tags, the reprocessed image quality "
573                     "may be compromised", __FUNCTION__);
574         }
575 
576         mLatestCapturedRequest = request;
577         res = client->getCameraDevice()->capture(request);
578         if (res != OK ) {
579             ALOGE("%s: Unable to send ZSL reprocess request to capture: %s"
580                   " (%d)", __FUNCTION__, strerror(-res), res);
581             return res;
582         }
583 
584         mState = LOCKED;
585     }
586 
587     return OK;
588 }
589 
enqueueInputBufferByTimestamp(nsecs_t timestamp,nsecs_t * actualTimestamp)590 status_t ZslProcessor::enqueueInputBufferByTimestamp(
591         nsecs_t timestamp,
592         nsecs_t* actualTimestamp) {
593 
594     TimestampFinder timestampFinder = TimestampFinder(timestamp);
595 
596     mInputBuffer = mProducer->pinSelectedBuffer(timestampFinder,
597         /*waitForFence*/false);
598 
599     if (nullptr == mInputBuffer.get()) {
600         ALOGE("%s: No ZSL buffers were available yet", __FUNCTION__);
601         return NO_BUFFER_AVAILABLE;
602     }
603 
604     nsecs_t actual = mInputBuffer->getBufferItem().mTimestamp;
605 
606     if (actual != timestamp) {
607         // TODO: This is problematic, the metadata queue timestamp should
608         //       usually have a corresponding ZSL buffer with the same timestamp.
609         //       If this is not the case, then it is possible that we will use
610         //       a ZSL buffer from a different request, which can result in
611         //       side effects during the reprocess pass.
612         ALOGW("%s: ZSL buffer candidate search didn't find an exact match --"
613               " requested timestamp = %" PRId64 ", actual timestamp = %" PRId64,
614               __FUNCTION__, timestamp, actual);
615     }
616 
617     if (nullptr != actualTimestamp) {
618         *actualTimestamp = actual;
619     }
620 
621     BufferItem &item = mInputBuffer->getBufferItem();
622     auto rc = mInputProducer->attachBuffer(&mInputProducerSlot,
623         item.mGraphicBuffer);
624     if (OK != rc) {
625         ALOGE("%s: Failed to attach input ZSL buffer to producer: %d",
626             __FUNCTION__, rc);
627         return rc;
628     }
629 
630     IGraphicBufferProducer::QueueBufferOutput output;
631     IGraphicBufferProducer::QueueBufferInput input(item.mTimestamp,
632             item.mIsAutoTimestamp, item.mDataSpace, item.mCrop,
633             item.mScalingMode, item.mTransform, item.mFence);
634     rc = mInputProducer->queueBuffer(mInputProducerSlot, input, &output);
635     if (OK != rc) {
636         ALOGE("%s: Failed to queue ZSL buffer to producer: %d",
637             __FUNCTION__, rc);
638         return rc;
639     }
640 
641     return rc;
642 }
643 
clearInputRingBufferLocked(nsecs_t * latestTimestamp)644 status_t ZslProcessor::clearInputRingBufferLocked(nsecs_t* latestTimestamp) {
645 
646     if (nullptr != latestTimestamp) {
647         *latestTimestamp = mProducer->getLatestTimestamp();
648     }
649     mInputBuffer.clear();
650 
651     return mProducer->clear();
652 }
653 
clearZslQueue()654 status_t ZslProcessor::clearZslQueue() {
655     Mutex::Autolock l(mInputMutex);
656     // If in middle of capture, can't clear out queue
657     if (mState == LOCKED) return OK;
658 
659     return clearZslQueueLocked();
660 }
661 
clearZslQueueLocked()662 status_t ZslProcessor::clearZslQueueLocked() {
663     if (NO_STREAM != mZslStreamId) {
664         // clear result metadata list first.
665         clearZslResultQueueLocked();
666         return clearInputRingBufferLocked(&mLatestClearedBufferTimestamp);
667     }
668     return OK;
669 }
670 
clearZslResultQueueLocked()671 void ZslProcessor::clearZslResultQueueLocked() {
672     mFrameList.clear();
673     mFrameListHead = 0;
674     mFrameList.insertAt(0, mFrameListDepth);
675 }
676 
dump(int fd,const Vector<String16> &) const677 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
678     Mutex::Autolock l(mInputMutex);
679     if (!mLatestCapturedRequest.isEmpty()) {
680         String8 result("    Latest ZSL capture request:\n");
681         write(fd, result.string(), result.size());
682         mLatestCapturedRequest.dump(fd, 2, 6);
683     } else {
684         String8 result("    Latest ZSL capture request: none yet\n");
685         write(fd, result.string(), result.size());
686     }
687     dumpZslQueue(fd);
688 }
689 
threadLoop()690 bool ZslProcessor::threadLoop() {
691     Mutex::Autolock l(mInputMutex);
692 
693     if (mBuffersToDetach == 0) {
694         status_t res = mBuffersToDetachSignal.waitRelative(mInputMutex, kWaitDuration);
695         if (res == TIMED_OUT) return true;
696     }
697     while (mBuffersToDetach > 0) {
698         doNotifyInputReleasedLocked();
699         mBuffersToDetach--;
700     }
701 
702     return true;
703 }
704 
dumpZslQueue(int fd) const705 void ZslProcessor::dumpZslQueue(int fd) const {
706     String8 header("ZSL queue contents:");
707     String8 indent("    ");
708     ALOGV("%s", header.string());
709     if (fd != -1) {
710         header = indent + header + "\n";
711         write(fd, header.string(), header.size());
712     }
713     for (size_t i = 0; i < mZslQueue.size(); i++) {
714         const ZslPair &queueEntry = mZslQueue[i];
715         nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
716         camera_metadata_ro_entry_t entry;
717         nsecs_t frameTimestamp = 0;
718         int frameAeState = -1;
719         if (!queueEntry.frame.isEmpty()) {
720             entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
721             if (entry.count > 0) frameTimestamp = entry.data.i64[0];
722             entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
723             if (entry.count > 0) frameAeState = entry.data.u8[0];
724         }
725         String8 result =
726                 String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
727                         bufferTimestamp, frameTimestamp, frameAeState);
728         ALOGV("%s", result.string());
729         if (fd != -1) {
730             result = indent + result + "\n";
731             write(fd, result.string(), result.size());
732         }
733 
734     }
735 }
736 
isFixedFocusMode(uint8_t afMode) const737 bool ZslProcessor::isFixedFocusMode(uint8_t afMode) const {
738     switch (afMode) {
739         case ANDROID_CONTROL_AF_MODE_AUTO:
740         case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
741         case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
742         case ANDROID_CONTROL_AF_MODE_MACRO:
743             return false;
744             break;
745         case ANDROID_CONTROL_AF_MODE_OFF:
746         case ANDROID_CONTROL_AF_MODE_EDOF:
747             return true;
748         default:
749             ALOGE("%s: unknown focus mode %d", __FUNCTION__, afMode);
750             return false;
751     }
752 }
753 
getCandidateTimestampLocked(size_t * metadataIdx) const754 nsecs_t ZslProcessor::getCandidateTimestampLocked(size_t* metadataIdx) const {
755     /**
756      * Find the smallest timestamp we know about so far
757      * - ensure that aeState is either converged or locked
758      */
759 
760     size_t idx = 0;
761     nsecs_t minTimestamp = -1;
762 
763     size_t emptyCount = mFrameList.size();
764 
765     for (size_t j = 0; j < mFrameList.size(); j++) {
766         const CameraMetadata &frame = mFrameList[j];
767         if (!frame.isEmpty()) {
768 
769             emptyCount--;
770 
771             camera_metadata_ro_entry_t entry;
772             entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
773             if (entry.count == 0) {
774                 ALOGE("%s: Can't find timestamp in frame!",
775                         __FUNCTION__);
776                 continue;
777             }
778             nsecs_t frameTimestamp = entry.data.i64[0];
779             if (minTimestamp > frameTimestamp || minTimestamp == -1) {
780 
781                 entry = frame.find(ANDROID_CONTROL_AE_STATE);
782 
783                 if (entry.count == 0) {
784                     /**
785                      * This is most likely a HAL bug. The aeState field is
786                      * mandatory, so it should always be in a metadata packet.
787                      */
788                     ALOGW("%s: ZSL queue frame has no AE state field!",
789                             __FUNCTION__);
790                     continue;
791                 }
792                 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
793                         entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
794                     ALOGVV("%s: ZSL queue frame AE state is %d, need "
795                            "full capture",  __FUNCTION__, entry.data.u8[0]);
796                     continue;
797                 }
798 
799                 entry = frame.find(ANDROID_CONTROL_AF_MODE);
800                 if (entry.count == 0) {
801                     ALOGW("%s: ZSL queue frame has no AF mode field!",
802                             __FUNCTION__);
803                     continue;
804                 }
805                 // Check AF state if device has focuser and focus mode isn't fixed
806                 if (mHasFocuser) {
807                     uint8_t afMode = entry.data.u8[0];
808                     if (!isFixedFocusMode(afMode)) {
809                         // Make sure the candidate frame has good focus.
810                         entry = frame.find(ANDROID_CONTROL_AF_STATE);
811                         if (entry.count == 0) {
812                             ALOGW("%s: ZSL queue frame has no AF state field!",
813                                     __FUNCTION__);
814                             continue;
815                         }
816                         uint8_t afState = entry.data.u8[0];
817                         if (afState != ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED &&
818                                 afState != ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&
819                                 afState != ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
820                             ALOGVV("%s: ZSL queue frame AF state is %d is not good for capture,"
821                                     " skip it", __FUNCTION__, afState);
822                             continue;
823                         }
824                     }
825                 }
826 
827                 minTimestamp = frameTimestamp;
828                 idx = j;
829             }
830 
831             ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
832         }
833     }
834 
835     if (emptyCount == mFrameList.size()) {
836         /**
837          * This could be mildly bad and means our ZSL was triggered before
838          * there were any frames yet received by the camera framework.
839          *
840          * This is a fairly corner case which can happen under:
841          * + a user presses the shutter button real fast when the camera starts
842          *     (startPreview followed immediately by takePicture).
843          * + burst capture case (hitting shutter button as fast possible)
844          *
845          * If this happens in steady case (preview running for a while, call
846          *     a single takePicture) then this might be a fwk bug.
847          */
848         ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
849     }
850 
851     ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
852           __FUNCTION__, minTimestamp, idx, emptyCount);
853 
854     if (metadataIdx) {
855         *metadataIdx = idx;
856     }
857 
858     return minTimestamp;
859 }
860 
861 }; // namespace camera2
862 }; // namespace android
863