• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "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 namespace android {
41 namespace camera2 {
42 
ZslProcessor(sp<Camera2Client> client,wp<CaptureSequencer> sequencer)43 ZslProcessor::ZslProcessor(
44     sp<Camera2Client> client,
45     wp<CaptureSequencer> sequencer):
46         Thread(false),
47         mLatestClearedBufferTimestamp(0),
48         mState(RUNNING),
49         mClient(client),
50         mSequencer(sequencer),
51         mId(client->getCameraId()),
52         mZslStreamId(NO_STREAM),
53         mFrameListHead(0),
54         mHasFocuser(false) {
55     // Initialize buffer queue and frame list based on pipeline max depth.
56     size_t pipelineMaxDepth = kDefaultMaxPipelineDepth;
57     if (client != 0) {
58         sp<Camera3Device> device =
59         static_cast<Camera3Device*>(client->getCameraDevice().get());
60         if (device != 0) {
61             camera_metadata_ro_entry_t entry =
62                 device->info().find(ANDROID_REQUEST_PIPELINE_MAX_DEPTH);
63             if (entry.count == 1) {
64                 pipelineMaxDepth = entry.data.u8[0];
65             } else {
66                 ALOGW("%s: Unable to find the android.request.pipelineMaxDepth,"
67                         " use default pipeline max depth %d", __FUNCTION__,
68                         kDefaultMaxPipelineDepth);
69             }
70 
71             entry = device->info().find(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
72             if (entry.count > 0 && entry.data.f[0] != 0.) {
73                 mHasFocuser = true;
74             }
75         }
76     }
77 
78     ALOGV("%s: Initialize buffer queue and frame list depth based on max pipeline depth (%zu)",
79           __FUNCTION__, pipelineMaxDepth);
80     // Need to keep buffer queue longer than metadata queue because sometimes buffer arrives
81     // earlier than metadata which causes the buffer corresponding to oldest metadata being
82     // removed.
83     mFrameListDepth = pipelineMaxDepth;
84     mBufferQueueDepth = mFrameListDepth + 1;
85 
86 
87     mZslQueue.insertAt(0, mBufferQueueDepth);
88     mFrameList.insertAt(0, mFrameListDepth);
89     sp<CaptureSequencer> captureSequencer = mSequencer.promote();
90     if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
91 }
92 
~ZslProcessor()93 ZslProcessor::~ZslProcessor() {
94     ALOGV("%s: Exit", __FUNCTION__);
95     deleteStream();
96 }
97 
onResultAvailable(const CaptureResult & result)98 void ZslProcessor::onResultAvailable(const CaptureResult &result) {
99     ATRACE_CALL();
100     ALOGV("%s:", __FUNCTION__);
101     Mutex::Autolock l(mInputMutex);
102     camera_metadata_ro_entry_t entry;
103     entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
104     nsecs_t timestamp = entry.data.i64[0];
105     if (entry.count == 0) {
106         ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__);
107         return;
108     }
109 
110     entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
111     if (entry.count == 0) {
112         ALOGE("%s: metadata doesn't have frame number, skip this result", __FUNCTION__);
113         return;
114     }
115     int32_t frameNumber = entry.data.i32[0];
116 
117     ALOGVV("Got preview metadata for frame %d with timestamp %" PRId64, frameNumber, timestamp);
118 
119     if (mState != RUNNING) return;
120 
121     // Corresponding buffer has been cleared. No need to push into mFrameList
122     if (timestamp <= mLatestClearedBufferTimestamp) return;
123 
124     mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
125     mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
126 }
127 
updateStream(const Parameters & params)128 status_t ZslProcessor::updateStream(const Parameters &params) {
129     ATRACE_CALL();
130     ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
131     status_t res;
132 
133     Mutex::Autolock l(mInputMutex);
134 
135     sp<Camera2Client> client = mClient.promote();
136     if (client == 0) {
137         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
138         return INVALID_OPERATION;
139     }
140     sp<Camera3Device> device =
141         static_cast<Camera3Device*>(client->getCameraDevice().get());
142     if (device == 0) {
143         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
144         return INVALID_OPERATION;
145     }
146 
147     if (mZslStreamId != NO_STREAM) {
148         // Check if stream parameters have to change
149         uint32_t currentWidth, currentHeight;
150         res = device->getStreamInfo(mZslStreamId,
151                 &currentWidth, &currentHeight, 0, 0);
152         if (res != OK) {
153             ALOGE("%s: Camera %d: Error querying capture output stream info: "
154                     "%s (%d)", __FUNCTION__,
155                     client->getCameraId(), strerror(-res), res);
156             return res;
157         }
158         if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
159                 currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
160             ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
161                   "dimensions changed",
162                 __FUNCTION__, client->getCameraId(), mZslStreamId);
163             res = device->deleteStream(mZslStreamId);
164             if (res == -EBUSY) {
165                 ALOGV("%s: Camera %d: Device is busy, call updateStream again "
166                       " after it becomes idle", __FUNCTION__, mId);
167                 return res;
168             } else if(res != OK) {
169                 ALOGE("%s: Camera %d: Unable to delete old output stream "
170                         "for ZSL: %s (%d)", __FUNCTION__,
171                         client->getCameraId(), strerror(-res), res);
172                 return res;
173             }
174             mZslStreamId = NO_STREAM;
175         }
176     }
177 
178     if (mZslStreamId == NO_STREAM) {
179         // Create stream for HAL production
180         // TODO: Sort out better way to select resolution for ZSL
181 
182         // Note that format specified internally in Camera3ZslStream
183         res = device->createZslStream(
184                 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
185                 mBufferQueueDepth,
186                 &mZslStreamId,
187                 &mZslStream);
188         if (res != OK) {
189             ALOGE("%s: Camera %d: Can't create ZSL stream: "
190                     "%s (%d)", __FUNCTION__, client->getCameraId(),
191                     strerror(-res), res);
192             return res;
193         }
194 
195         // Only add the camera3 buffer listener when the stream is created.
196         mZslStream->addBufferListener(this);
197     }
198 
199     client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
200             Camera2Client::kPreviewRequestIdEnd,
201             this,
202             /*sendPartials*/false);
203 
204     return OK;
205 }
206 
deleteStream()207 status_t ZslProcessor::deleteStream() {
208     ATRACE_CALL();
209     status_t res;
210 
211     Mutex::Autolock l(mInputMutex);
212 
213     if (mZslStreamId != NO_STREAM) {
214         sp<Camera2Client> client = mClient.promote();
215         if (client == 0) {
216             ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
217             return INVALID_OPERATION;
218         }
219 
220         sp<Camera3Device> device =
221             reinterpret_cast<Camera3Device*>(client->getCameraDevice().get());
222         if (device == 0) {
223             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
224             return INVALID_OPERATION;
225         }
226 
227         res = device->deleteStream(mZslStreamId);
228         if (res != OK) {
229             ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
230                     "%s (%d)", __FUNCTION__, client->getCameraId(),
231                     mZslStreamId, strerror(-res), res);
232             return res;
233         }
234 
235         mZslStreamId = NO_STREAM;
236     }
237     return OK;
238 }
239 
getStreamId() const240 int ZslProcessor::getStreamId() const {
241     Mutex::Autolock l(mInputMutex);
242     return mZslStreamId;
243 }
244 
updateRequestWithDefaultStillRequest(CameraMetadata & request) const245 status_t ZslProcessor::updateRequestWithDefaultStillRequest(CameraMetadata &request) const {
246     sp<Camera2Client> client = mClient.promote();
247     if (client == 0) {
248         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
249         return INVALID_OPERATION;
250     }
251     sp<Camera3Device> device =
252         static_cast<Camera3Device*>(client->getCameraDevice().get());
253     if (device == 0) {
254         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
255         return INVALID_OPERATION;
256     }
257 
258     CameraMetadata stillTemplate;
259     device->createDefaultRequest(CAMERA3_TEMPLATE_STILL_CAPTURE, &stillTemplate);
260 
261     // Find some of the post-processing tags, and assign the value from template to the request.
262     // Only check the aberration mode and noise reduction mode for now, as they are very important
263     // for image quality.
264     uint32_t postProcessingTags[] = {
265             ANDROID_NOISE_REDUCTION_MODE,
266             ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
267             ANDROID_COLOR_CORRECTION_MODE,
268             ANDROID_TONEMAP_MODE,
269             ANDROID_SHADING_MODE,
270             ANDROID_HOT_PIXEL_MODE,
271             ANDROID_EDGE_MODE
272     };
273 
274     camera_metadata_entry_t entry;
275     for (size_t i = 0; i < sizeof(postProcessingTags) / sizeof(uint32_t); i++) {
276         entry = stillTemplate.find(postProcessingTags[i]);
277         if (entry.count > 0) {
278             request.update(postProcessingTags[i], entry.data.u8, 1);
279         }
280     }
281 
282     return OK;
283 }
284 
pushToReprocess(int32_t requestId)285 status_t ZslProcessor::pushToReprocess(int32_t requestId) {
286     ALOGV("%s: Send in reprocess request with id %d",
287             __FUNCTION__, requestId);
288     Mutex::Autolock l(mInputMutex);
289     status_t res;
290     sp<Camera2Client> client = mClient.promote();
291 
292     if (client == 0) {
293         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
294         return INVALID_OPERATION;
295     }
296 
297     IF_ALOGV() {
298         dumpZslQueue(-1);
299     }
300 
301     size_t metadataIdx;
302     nsecs_t candidateTimestamp = getCandidateTimestampLocked(&metadataIdx);
303 
304     if (candidateTimestamp == -1) {
305         ALOGE("%s: Could not find good candidate for ZSL reprocessing",
306               __FUNCTION__);
307         return NOT_ENOUGH_DATA;
308     }
309 
310     res = mZslStream->enqueueInputBufferByTimestamp(candidateTimestamp,
311                                                     /*actualTimestamp*/NULL);
312 
313     if (res == mZslStream->NO_BUFFER_AVAILABLE) {
314         ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
315         return NOT_ENOUGH_DATA;
316     } else if (res != OK) {
317         ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
318                 __FUNCTION__, strerror(-res), res);
319         return res;
320     }
321 
322     {
323         CameraMetadata request = mFrameList[metadataIdx];
324 
325         // Verify that the frame is reasonable for reprocessing
326 
327         camera_metadata_entry_t entry;
328         entry = request.find(ANDROID_CONTROL_AE_STATE);
329         if (entry.count == 0) {
330             ALOGE("%s: ZSL queue frame has no AE state field!",
331                     __FUNCTION__);
332             return BAD_VALUE;
333         }
334         if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
335                 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
336             ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
337                     __FUNCTION__, entry.data.u8[0]);
338             return NOT_ENOUGH_DATA;
339         }
340 
341         uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
342         res = request.update(ANDROID_REQUEST_TYPE,
343                 &requestType, 1);
344         if (res != OK) {
345             ALOGE("%s: Unable to update request type",
346                   __FUNCTION__);
347             return INVALID_OPERATION;
348         }
349 
350         int32_t inputStreams[1] =
351                 { mZslStreamId };
352         res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
353                 inputStreams, 1);
354         if (res != OK) {
355             ALOGE("%s: Unable to update request input streams",
356                   __FUNCTION__);
357             return INVALID_OPERATION;
358         }
359 
360         uint8_t captureIntent =
361                 static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
362         res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
363                 &captureIntent, 1);
364         if (res != OK ) {
365             ALOGE("%s: Unable to update request capture intent",
366                   __FUNCTION__);
367             return INVALID_OPERATION;
368         }
369 
370         // TODO: Shouldn't we also update the latest preview frame?
371         int32_t outputStreams[1] =
372                 { client->getCaptureStreamId() };
373         res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
374                 outputStreams, 1);
375         if (res != OK) {
376             ALOGE("%s: Unable to update request output streams",
377                   __FUNCTION__);
378             return INVALID_OPERATION;
379         }
380 
381         res = request.update(ANDROID_REQUEST_ID,
382                 &requestId, 1);
383         if (res != OK ) {
384             ALOGE("%s: Unable to update frame to a reprocess request",
385                   __FUNCTION__);
386             return INVALID_OPERATION;
387         }
388 
389         res = client->stopStream();
390         if (res != OK) {
391             ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
392                 "%s (%d)",
393                 __FUNCTION__, client->getCameraId(), strerror(-res), res);
394             return INVALID_OPERATION;
395         }
396 
397         // Update JPEG settings
398         {
399             SharedParameters::Lock l(client->getParameters());
400             res = l.mParameters.updateRequestJpeg(&request);
401             if (res != OK) {
402                 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
403                         "capture request: %s (%d)", __FUNCTION__,
404                         client->getCameraId(),
405                         strerror(-res), res);
406                 return res;
407             }
408         }
409 
410         // Update post-processing settings
411         res = updateRequestWithDefaultStillRequest(request);
412         if (res != OK) {
413             ALOGW("%s: Unable to update post-processing tags, the reprocessed image quality "
414                     "may be compromised", __FUNCTION__);
415         }
416 
417         mLatestCapturedRequest = request;
418         res = client->getCameraDevice()->capture(request);
419         if (res != OK ) {
420             ALOGE("%s: Unable to send ZSL reprocess request to capture: %s"
421                   " (%d)", __FUNCTION__, strerror(-res), res);
422             return res;
423         }
424 
425         mState = LOCKED;
426     }
427 
428     return OK;
429 }
430 
clearZslQueue()431 status_t ZslProcessor::clearZslQueue() {
432     Mutex::Autolock l(mInputMutex);
433     // If in middle of capture, can't clear out queue
434     if (mState == LOCKED) return OK;
435 
436     return clearZslQueueLocked();
437 }
438 
clearZslQueueLocked()439 status_t ZslProcessor::clearZslQueueLocked() {
440     if (mZslStream != 0) {
441         // clear result metadata list first.
442         clearZslResultQueueLocked();
443         return mZslStream->clearInputRingBuffer(&mLatestClearedBufferTimestamp);
444     }
445     return OK;
446 }
447 
clearZslResultQueueLocked()448 void ZslProcessor::clearZslResultQueueLocked() {
449     mFrameList.clear();
450     mFrameListHead = 0;
451     mFrameList.insertAt(0, mFrameListDepth);
452 }
453 
dump(int fd,const Vector<String16> &) const454 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
455     Mutex::Autolock l(mInputMutex);
456     if (!mLatestCapturedRequest.isEmpty()) {
457         String8 result("    Latest ZSL capture request:\n");
458         write(fd, result.string(), result.size());
459         mLatestCapturedRequest.dump(fd, 2, 6);
460     } else {
461         String8 result("    Latest ZSL capture request: none yet\n");
462         write(fd, result.string(), result.size());
463     }
464     dumpZslQueue(fd);
465 }
466 
threadLoop()467 bool ZslProcessor::threadLoop() {
468     // TODO: remove dependency on thread. For now, shut thread down right
469     // away.
470     return false;
471 }
472 
dumpZslQueue(int fd) const473 void ZslProcessor::dumpZslQueue(int fd) const {
474     String8 header("ZSL queue contents:");
475     String8 indent("    ");
476     ALOGV("%s", header.string());
477     if (fd != -1) {
478         header = indent + header + "\n";
479         write(fd, header.string(), header.size());
480     }
481     for (size_t i = 0; i < mZslQueue.size(); i++) {
482         const ZslPair &queueEntry = mZslQueue[i];
483         nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
484         camera_metadata_ro_entry_t entry;
485         nsecs_t frameTimestamp = 0;
486         int frameAeState = -1;
487         if (!queueEntry.frame.isEmpty()) {
488             entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
489             if (entry.count > 0) frameTimestamp = entry.data.i64[0];
490             entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
491             if (entry.count > 0) frameAeState = entry.data.u8[0];
492         }
493         String8 result =
494                 String8::format("   %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
495                         bufferTimestamp, frameTimestamp, frameAeState);
496         ALOGV("%s", result.string());
497         if (fd != -1) {
498             result = indent + result + "\n";
499             write(fd, result.string(), result.size());
500         }
501 
502     }
503 }
504 
isFixedFocusMode(uint8_t afMode) const505 bool ZslProcessor::isFixedFocusMode(uint8_t afMode) const {
506     switch (afMode) {
507         case ANDROID_CONTROL_AF_MODE_AUTO:
508         case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
509         case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
510         case ANDROID_CONTROL_AF_MODE_MACRO:
511             return false;
512             break;
513         case ANDROID_CONTROL_AF_MODE_OFF:
514         case ANDROID_CONTROL_AF_MODE_EDOF:
515             return true;
516         default:
517             ALOGE("%s: unknown focus mode %d", __FUNCTION__, afMode);
518             return false;
519     }
520 }
521 
getCandidateTimestampLocked(size_t * metadataIdx) const522 nsecs_t ZslProcessor::getCandidateTimestampLocked(size_t* metadataIdx) const {
523     /**
524      * Find the smallest timestamp we know about so far
525      * - ensure that aeState is either converged or locked
526      */
527 
528     size_t idx = 0;
529     nsecs_t minTimestamp = -1;
530 
531     size_t emptyCount = mFrameList.size();
532 
533     for (size_t j = 0; j < mFrameList.size(); j++) {
534         const CameraMetadata &frame = mFrameList[j];
535         if (!frame.isEmpty()) {
536 
537             emptyCount--;
538 
539             camera_metadata_ro_entry_t entry;
540             entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
541             if (entry.count == 0) {
542                 ALOGE("%s: Can't find timestamp in frame!",
543                         __FUNCTION__);
544                 continue;
545             }
546             nsecs_t frameTimestamp = entry.data.i64[0];
547             if (minTimestamp > frameTimestamp || minTimestamp == -1) {
548 
549                 entry = frame.find(ANDROID_CONTROL_AE_STATE);
550 
551                 if (entry.count == 0) {
552                     /**
553                      * This is most likely a HAL bug. The aeState field is
554                      * mandatory, so it should always be in a metadata packet.
555                      */
556                     ALOGW("%s: ZSL queue frame has no AE state field!",
557                             __FUNCTION__);
558                     continue;
559                 }
560                 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
561                         entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
562                     ALOGVV("%s: ZSL queue frame AE state is %d, need "
563                            "full capture",  __FUNCTION__, entry.data.u8[0]);
564                     continue;
565                 }
566 
567                 entry = frame.find(ANDROID_CONTROL_AF_MODE);
568                 if (entry.count == 0) {
569                     ALOGW("%s: ZSL queue frame has no AF mode field!",
570                             __FUNCTION__);
571                     continue;
572                 }
573                 uint8_t afMode = entry.data.u8[0];
574                 if (afMode == ANDROID_CONTROL_AF_MODE_OFF) {
575                     // Skip all the ZSL buffer for manual AF mode, as we don't really
576                     // know the af state.
577                     continue;
578                 }
579 
580                 // Check AF state if device has focuser and focus mode isn't fixed
581                 if (mHasFocuser && !isFixedFocusMode(afMode)) {
582                     // Make sure the candidate frame has good focus.
583                     entry = frame.find(ANDROID_CONTROL_AF_STATE);
584                     if (entry.count == 0) {
585                         ALOGW("%s: ZSL queue frame has no AF state field!",
586                                 __FUNCTION__);
587                         continue;
588                     }
589                     uint8_t afState = entry.data.u8[0];
590                     if (afState != ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED &&
591                             afState != ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&
592                             afState != ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
593                         ALOGVV("%s: ZSL queue frame AF state is %d is not good for capture, skip it",
594                                 __FUNCTION__, afState);
595                         continue;
596                     }
597                 }
598 
599                 minTimestamp = frameTimestamp;
600                 idx = j;
601             }
602 
603             ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
604         }
605     }
606 
607     if (emptyCount == mFrameList.size()) {
608         /**
609          * This could be mildly bad and means our ZSL was triggered before
610          * there were any frames yet received by the camera framework.
611          *
612          * This is a fairly corner case which can happen under:
613          * + a user presses the shutter button real fast when the camera starts
614          *     (startPreview followed immediately by takePicture).
615          * + burst capture case (hitting shutter button as fast possible)
616          *
617          * If this happens in steady case (preview running for a while, call
618          *     a single takePicture) then this might be a fwk bug.
619          */
620         ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
621     }
622 
623     ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
624           __FUNCTION__, minTimestamp, idx, emptyCount);
625 
626     if (metadataIdx) {
627         *metadataIdx = idx;
628     }
629 
630     return minTimestamp;
631 }
632 
onBufferAcquired(const BufferInfo &)633 void ZslProcessor::onBufferAcquired(const BufferInfo& /*bufferInfo*/) {
634     // Intentionally left empty
635     // Although theoretically we could use this to get better dump info
636 }
637 
onBufferReleased(const BufferInfo & bufferInfo)638 void ZslProcessor::onBufferReleased(const BufferInfo& bufferInfo) {
639 
640     // ignore output buffers
641     if (bufferInfo.mOutput) {
642         return;
643     }
644 
645     // Lock mutex only once we know this is an input buffer returned to avoid
646     // potential deadlock
647     Mutex::Autolock l(mInputMutex);
648     // TODO: Verify that the buffer is in our queue by looking at timestamp
649     // theoretically unnecessary unless we change the following assumptions:
650     // -- only 1 buffer reprocessed at a time (which is the case now)
651 
652     // Erase entire ZSL queue since we've now completed the capture and preview
653     // is stopped.
654     //
655     // We need to guarantee that if we do two back-to-back captures,
656     // the second won't use a buffer that's older/the same as the first, which
657     // is theoretically possible if we don't clear out the queue and the
658     // selection criteria is something like 'newest'. Clearing out the result
659     // metadata queue on a completed capture ensures we'll only use new timestamp.
660     // Calling clearZslQueueLocked is a guaranteed deadlock because this callback
661     // holds the Camera3Stream internal lock (mLock), and clearZslQueueLocked requires
662     // to hold the same lock.
663     // TODO: need figure out a way to clear the Zsl buffer queue properly. Right now
664     // it is safe not to do so, as back to back ZSL capture requires stop and start
665     // preview, which will flush ZSL queue automatically.
666     ALOGV("%s: Memory optimization, clearing ZSL queue",
667           __FUNCTION__);
668     clearZslResultQueueLocked();
669 
670     // Required so we accept more ZSL requests
671     mState = RUNNING;
672 }
673 
674 }; // namespace camera2
675 }; // namespace android
676