• 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 #include <vector>
18 #include "system/window.h"
19 #define LOG_TAG "Camera3-Stream"
20 #define ATRACE_TAG ATRACE_TAG_CAMERA
21 //#define LOG_NDEBUG 0
22 
23 #include <utils/Log.h>
24 #include <utils/Trace.h>
25 #include "device3/Camera3Stream.h"
26 #include "device3/StatusTracker.h"
27 #include "utils/TraceHFR.h"
28 #include "ui/GraphicBufferMapper.h"
29 
30 #include <cutils/properties.h>
31 
32 namespace android {
33 
34 namespace camera3 {
35 
~Camera3Stream()36 Camera3Stream::~Camera3Stream() {
37     sp<StatusTracker> statusTracker = mStatusTracker.promote();
38     if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
39         statusTracker->removeComponent(mStatusId);
40     }
41 }
42 
cast(camera_stream * stream)43 Camera3Stream* Camera3Stream::cast(camera_stream *stream) {
44     return static_cast<Camera3Stream*>(stream);
45 }
46 
cast(const camera_stream * stream)47 const Camera3Stream* Camera3Stream::cast(const camera_stream *stream) {
48     return static_cast<const Camera3Stream*>(stream);
49 }
50 
Camera3Stream(int id,camera_stream_type type,uint32_t width,uint32_t height,size_t maxSize,int format,android_dataspace dataSpace,camera_stream_rotation_t rotation,const String8 & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,int setId,bool isMultiResolution,int64_t dynamicRangeProfile,int64_t streamUseCase,bool deviceTimeBaseIsRealtime,int timestampBase,int32_t colorSpace)51 Camera3Stream::Camera3Stream(int id,
52         camera_stream_type type,
53         uint32_t width, uint32_t height, size_t maxSize, int format,
54         android_dataspace dataSpace, camera_stream_rotation_t rotation,
55         const String8& physicalCameraId,
56         const std::unordered_set<int32_t> &sensorPixelModesUsed,
57         int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
58         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
59         int32_t colorSpace) :
60     camera_stream(),
61     mId(id),
62     mSetId(setId),
63     mName(String8::format("Camera3Stream[%d]", id)),
64     mMaxSize(maxSize),
65     mState(STATE_CONSTRUCTED),
66     mStatusId(StatusTracker::NO_STATUS_ID),
67     mStreamUnpreparable(true),
68     mUsage(0),
69     mOldUsage(0),
70     mOldMaxBuffers(0),
71     mOldFormat(-1),
72     mOldDataSpace(HAL_DATASPACE_UNKNOWN),
73     mPrepared(false),
74     mPrepareBlockRequest(true),
75     mPreparedBufferIdx(0),
76     mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
77     mBufferLimitLatency(kBufferLimitLatencyBinSize),
78     mFormatOverridden(false),
79     mOriginalFormat(format),
80     mDataSpaceOverridden(false),
81     mOriginalDataSpace(dataSpace),
82     mPhysicalCameraId(physicalCameraId),
83     mLastTimestamp(0),
84     mIsMultiResolution(isMultiResolution),
85     mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
86     mTimestampBase(timestampBase) {
87 
88     camera_stream::stream_type = type;
89     camera_stream::width = width;
90     camera_stream::height = height;
91     camera_stream::format = format;
92     camera_stream::data_space = dataSpace;
93     camera_stream::rotation = rotation;
94     camera_stream::max_buffers = 0;
95     camera_stream::physical_camera_id = mPhysicalCameraId.string();
96     camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
97     camera_stream::dynamic_range_profile = dynamicRangeProfile;
98     camera_stream::use_case = streamUseCase;
99     camera_stream::color_space = colorSpace;
100 
101     if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
102             maxSize == 0) {
103         ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
104         mState = STATE_ERROR;
105     }
106 }
107 
getId() const108 int Camera3Stream::getId() const {
109     return mId;
110 }
111 
getStreamSetId() const112 int Camera3Stream::getStreamSetId() const {
113     return mSetId;
114 }
115 
getHalStreamGroupId() const116 int Camera3Stream::getHalStreamGroupId() const {
117     return mIsMultiResolution ? mSetId : -1;
118 }
119 
isMultiResolution() const120 bool Camera3Stream::isMultiResolution() const {
121     return mIsMultiResolution;
122 }
123 
getWidth() const124 uint32_t Camera3Stream::getWidth() const {
125     return camera_stream::width;
126 }
127 
getHeight() const128 uint32_t Camera3Stream::getHeight() const {
129     return camera_stream::height;
130 }
131 
getFormat() const132 int Camera3Stream::getFormat() const {
133     return camera_stream::format;
134 }
135 
getDataSpace() const136 android_dataspace Camera3Stream::getDataSpace() const {
137     return camera_stream::data_space;
138 }
139 
getColorSpace() const140 int32_t Camera3Stream::getColorSpace() const {
141     return camera_stream::color_space;
142 }
143 
getUsage() const144 uint64_t Camera3Stream::getUsage() const {
145     return mUsage;
146 }
147 
setUsage(uint64_t usage)148 void Camera3Stream::setUsage(uint64_t usage) {
149     mUsage = usage;
150 }
151 
setFormatOverride(bool formatOverridden)152 void Camera3Stream::setFormatOverride(bool formatOverridden) {
153     mFormatOverridden = formatOverridden;
154 }
155 
isFormatOverridden() const156 bool Camera3Stream::isFormatOverridden() const {
157     return mFormatOverridden;
158 }
159 
getOriginalFormat() const160 int Camera3Stream::getOriginalFormat() const {
161     return mOriginalFormat;
162 }
163 
getDynamicRangeProfile() const164 int64_t Camera3Stream::getDynamicRangeProfile() const {
165     return camera_stream::dynamic_range_profile;
166 }
167 
setDataSpaceOverride(bool dataSpaceOverridden)168 void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
169     mDataSpaceOverridden = dataSpaceOverridden;
170 }
171 
isDataSpaceOverridden() const172 bool Camera3Stream::isDataSpaceOverridden() const {
173     return mDataSpaceOverridden;
174 }
175 
getOriginalDataSpace() const176 android_dataspace Camera3Stream::getOriginalDataSpace() const {
177     return mOriginalDataSpace;
178 }
179 
physicalCameraId() const180 const String8& Camera3Stream::physicalCameraId() const {
181     return mPhysicalCameraId;
182 }
183 
getMaxHalBuffers() const184 int Camera3Stream::getMaxHalBuffers() const {
185     return camera_stream::max_buffers;
186 }
187 
getStreamUseCase() const188 int64_t Camera3Stream::getStreamUseCase() const {
189     return camera_stream::use_case;
190 }
191 
getTimestampBase() const192 int Camera3Stream::getTimestampBase() const {
193     return mTimestampBase;
194 }
195 
isDeviceTimeBaseRealtime() const196 bool Camera3Stream::isDeviceTimeBaseRealtime() const {
197     return mDeviceTimeBaseIsRealtime;
198 }
199 
setOfflineProcessingSupport(bool support)200 void Camera3Stream::setOfflineProcessingSupport(bool support) {
201     mSupportOfflineProcessing = support;
202 }
203 
getOfflineProcessingSupport() const204 bool Camera3Stream::getOfflineProcessingSupport() const {
205     return mSupportOfflineProcessing;
206 }
207 
forceToIdle()208 status_t Camera3Stream::forceToIdle() {
209     ATRACE_CALL();
210     Mutex::Autolock l(mLock);
211     status_t res;
212 
213     switch (mState) {
214         case STATE_ERROR:
215         case STATE_CONSTRUCTED:
216         case STATE_IN_CONFIG:
217         case STATE_PREPARING:
218         case STATE_IN_RECONFIG:
219             ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
220             res = NO_INIT;
221             break;
222         case STATE_CONFIGURED:
223             if (hasOutstandingBuffersLocked()) {
224                 sp<StatusTracker> statusTracker = mStatusTracker.promote();
225                 if (statusTracker != 0) {
226                     statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
227                 }
228             }
229 
230             mState = STATE_IN_IDLE;
231             res = OK;
232 
233             break;
234         default:
235             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
236             res = NO_INIT;
237     }
238 
239     return res;
240 }
241 
restoreConfiguredState()242 status_t Camera3Stream::restoreConfiguredState() {
243     ATRACE_CALL();
244     Mutex::Autolock l(mLock);
245     status_t res;
246 
247     switch (mState) {
248         case STATE_ERROR:
249         case STATE_CONSTRUCTED:
250         case STATE_IN_CONFIG:
251         case STATE_PREPARING:
252         case STATE_IN_RECONFIG:
253         case STATE_CONFIGURED:
254             ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
255             res = NO_INIT;
256             break;
257         case STATE_IN_IDLE:
258             if (hasOutstandingBuffersLocked()) {
259                 sp<StatusTracker> statusTracker = mStatusTracker.promote();
260                 if (statusTracker != 0) {
261                     statusTracker->markComponentActive(mStatusId);
262                 }
263             }
264 
265             mState = STATE_CONFIGURED;
266             res = OK;
267 
268             break;
269         default:
270             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
271             res = NO_INIT;
272     }
273 
274     return res;
275 }
276 
startConfiguration()277 camera_stream* Camera3Stream::startConfiguration() {
278     ATRACE_CALL();
279     Mutex::Autolock l(mLock);
280     status_t res;
281 
282     switch (mState) {
283         case STATE_ERROR:
284             ALOGE("%s: In error state", __FUNCTION__);
285             return NULL;
286         case STATE_CONSTRUCTED:
287         case STATE_IN_IDLE:
288             // OK
289             break;
290         case STATE_IN_CONFIG:
291         case STATE_IN_RECONFIG:
292             // Can start config again with no trouble; but don't redo
293             // mOldUsage/mOldMaxBuffers
294             return this;
295         case STATE_CONFIGURED:
296             if (hasOutstandingBuffersLocked()) {
297                 ALOGE("%s: Cannot configure stream; has outstanding buffers",
298                         __FUNCTION__);
299                 return NULL;
300             }
301             break;
302         default:
303             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
304             return NULL;
305     }
306 
307     mOldUsage = mUsage;
308     mOldMaxBuffers = camera_stream::max_buffers;
309     mOldFormat = camera_stream::format;
310     mOldDataSpace = camera_stream::data_space;
311 
312     res = getEndpointUsage(&mUsage);
313     if (res != OK) {
314         ALOGE("%s: Cannot query consumer endpoint usage!",
315                 __FUNCTION__);
316         return NULL;
317     }
318 
319     if (mState == STATE_IN_IDLE) {
320         // Skip configuration.
321         return this;
322     }
323 
324     // Stop tracking if currently doing so
325     if (mStatusId != StatusTracker::NO_STATUS_ID) {
326         sp<StatusTracker> statusTracker = mStatusTracker.promote();
327         if (statusTracker != 0) {
328             statusTracker->removeComponent(mStatusId);
329         }
330         mStatusId = StatusTracker::NO_STATUS_ID;
331     }
332 
333     if (mState == STATE_CONSTRUCTED) {
334         mState = STATE_IN_CONFIG;
335     } else { // mState == STATE_CONFIGURED
336         LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
337         mState = STATE_IN_RECONFIG;
338     }
339 
340     return this;
341 }
342 
isConfiguring() const343 bool Camera3Stream::isConfiguring() const {
344     Mutex::Autolock l(mLock);
345     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
346 }
347 
finishConfiguration(bool * streamReconfigured)348 status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
349     ATRACE_CALL();
350     if (streamReconfigured != nullptr) {
351         *streamReconfigured = false;
352     }
353     Mutex::Autolock l(mLock);
354     switch (mState) {
355         case STATE_ERROR:
356             ALOGE("%s: In error state", __FUNCTION__);
357             return INVALID_OPERATION;
358         case STATE_IN_CONFIG:
359         case STATE_IN_RECONFIG:
360             // OK
361             break;
362         case STATE_CONSTRUCTED:
363         case STATE_CONFIGURED:
364             ALOGE("%s: Cannot finish configuration that hasn't been started",
365                     __FUNCTION__);
366             return INVALID_OPERATION;
367         case STATE_IN_IDLE:
368             //Skip configuration in this state
369             return OK;
370         default:
371             ALOGE("%s: Unknown state", __FUNCTION__);
372             return INVALID_OPERATION;
373     }
374 
375     // Register for idle tracking
376     sp<StatusTracker> statusTracker = mStatusTracker.promote();
377     if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
378         std::string name = std::string("Stream ") + std::to_string(mId);
379         mStatusId = statusTracker->addComponent(name.c_str());
380     }
381 
382     // Check if the stream configuration is unchanged, and skip reallocation if
383     // so.
384     if (mState == STATE_IN_RECONFIG &&
385             mOldUsage == mUsage &&
386             mOldMaxBuffers == camera_stream::max_buffers &&
387             mOldDataSpace == camera_stream::data_space &&
388             mOldFormat == camera_stream::format) {
389         mState = STATE_CONFIGURED;
390         return OK;
391     }
392 
393     // Reset prepared state, since buffer config has changed, and existing
394     // allocations are no longer valid
395     mPrepared = false;
396     mPrepareBlockRequest = true;
397     mStreamUnpreparable = false;
398 
399     bool reconfiguring = (mState == STATE_IN_RECONFIG);
400     status_t res;
401     res = configureQueueLocked();
402     // configureQueueLocked could return error in case of abandoned surface.
403     // Treat as non-fatal error.
404     if (res == NO_INIT || res == DEAD_OBJECT) {
405         ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)",
406                 __FUNCTION__, mId, strerror(-res), res);
407         mState = STATE_ABANDONED;
408         return res;
409     } else if (res != OK) {
410         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
411                 __FUNCTION__, mId, strerror(-res), res);
412         mState = STATE_ERROR;
413         return res;
414     }
415 
416     if (reconfiguring && streamReconfigured != nullptr) {
417         *streamReconfigured = true;
418     }
419     mState = STATE_CONFIGURED;
420 
421     return res;
422 }
423 
cancelConfiguration()424 status_t Camera3Stream::cancelConfiguration() {
425     ATRACE_CALL();
426     Mutex::Autolock l(mLock);
427     switch (mState) {
428         case STATE_ERROR:
429             ALOGE("%s: In error state", __FUNCTION__);
430             return INVALID_OPERATION;
431         case STATE_IN_CONFIG:
432         case STATE_IN_RECONFIG:
433         case STATE_IN_IDLE:
434             // OK
435             break;
436         case STATE_CONSTRUCTED:
437         case STATE_CONFIGURED:
438             ALOGE("%s: Cannot cancel configuration that hasn't been started",
439                     __FUNCTION__);
440             return INVALID_OPERATION;
441         default:
442             ALOGE("%s: Unknown state", __FUNCTION__);
443             return INVALID_OPERATION;
444     }
445 
446     mUsage = mOldUsage;
447     camera_stream::max_buffers = mOldMaxBuffers;
448 
449     mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
450             STATE_CONSTRUCTED;
451 
452     return OK;
453 }
454 
isUnpreparable()455 bool Camera3Stream::isUnpreparable() {
456     ATRACE_CALL();
457 
458     Mutex::Autolock l(mLock);
459     return mStreamUnpreparable;
460 }
461 
markUnpreparable()462 void Camera3Stream::markUnpreparable() {
463     ATRACE_CALL();
464 
465     Mutex::Autolock l(mLock);
466     mStreamUnpreparable = true;
467 }
468 
startPrepare(int maxCount,bool blockRequest)469 status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
470     ATRACE_CALL();
471 
472     Mutex::Autolock l(mLock);
473 
474     if (maxCount < 0) {
475         ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
476                 __FUNCTION__, mId, maxCount);
477         return BAD_VALUE;
478     }
479 
480     // This function should be only called when the stream is configured already.
481     if (mState != STATE_CONFIGURED) {
482         ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
483                 "state %d", __FUNCTION__, mId, mState);
484         return INVALID_OPERATION;
485     }
486 
487     // This function can't be called if the stream has already received filled
488     // buffers
489     if (mStreamUnpreparable) {
490         ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
491                 __FUNCTION__, mId);
492         return INVALID_OPERATION;
493     }
494 
495     if (getHandoutOutputBufferCountLocked() > 0) {
496         ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
497                 __FUNCTION__, mId);
498         return INVALID_OPERATION;
499     }
500 
501     size_t pipelineMax = getBufferCountLocked();
502     size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
503             pipelineMax : static_cast<size_t>(maxCount);
504     size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
505             pipelineMax : clampedCount;
506 
507     mPrepared = bufferCount <= mLastMaxCount;
508     mPrepareBlockRequest = blockRequest;
509 
510     if (mPrepared) return OK;
511 
512     mLastMaxCount = bufferCount;
513 
514     mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
515     mPreparedBufferIdx = 0;
516 
517     mState = STATE_PREPARING;
518 
519     return NOT_ENOUGH_DATA;
520 }
521 
isBlockedByPrepare() const522 bool Camera3Stream::isBlockedByPrepare() const {
523     Mutex::Autolock l(mLock);
524     return mState == STATE_PREPARING && mPrepareBlockRequest;
525 }
526 
isAbandoned() const527 bool Camera3Stream::isAbandoned() const {
528     Mutex::Autolock l(mLock);
529     return mState == STATE_ABANDONED;
530 }
531 
prepareNextBuffer()532 status_t Camera3Stream::prepareNextBuffer() {
533     ATRACE_CALL();
534 
535     Mutex::Autolock l(mLock);
536     status_t res = OK;
537 
538     // This function should be only called when the stream is preparing
539     if (mState != STATE_PREPARING) {
540         ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
541                 "state %d", __FUNCTION__, mId, mState);
542         return INVALID_OPERATION;
543     }
544 
545     // Get next buffer - this may allocate, and take a while for large buffers
546     res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
547     if (res != OK) {
548         ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
549                 __FUNCTION__, mId, mPreparedBufferIdx);
550         return NO_INIT;
551     }
552 
553     mPreparedBufferIdx++;
554 
555     // Check if we still have buffers left to allocate
556     if (mPreparedBufferIdx < mPreparedBuffers.size()) {
557         return NOT_ENOUGH_DATA;
558     }
559 
560     // Done with prepare - mark stream as such, and return all buffers
561     // via cancelPrepare
562     mPrepared = true;
563 
564     return cancelPrepareLocked();
565 }
566 
cancelPrepare()567 status_t Camera3Stream::cancelPrepare() {
568     ATRACE_CALL();
569 
570     Mutex::Autolock l(mLock);
571 
572     return cancelPrepareLocked();
573 }
574 
cancelPrepareLocked()575 status_t Camera3Stream::cancelPrepareLocked() {
576     status_t res = OK;
577 
578     // This function should be only called when the stream is mid-preparing.
579     if (mState != STATE_PREPARING) {
580         ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
581                 "PREPARING state %d", __FUNCTION__, mId, mState);
582         return INVALID_OPERATION;
583     }
584 
585     // Return all valid buffers to stream, in ERROR state to indicate
586     // they weren't filled.
587     for (size_t i = 0; i < mPreparedBufferIdx; i++) {
588         mPreparedBuffers.editItemAt(i).release_fence = -1;
589         mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
590         returnBufferLocked(mPreparedBuffers[i], /*timestamp*/0, /*readoutTimestamp*/0,
591                 /*transform*/ -1);
592     }
593     mPreparedBuffers.clear();
594     mPreparedBufferIdx = 0;
595 
596     mState = STATE_CONFIGURED;
597 
598     return res;
599 }
600 
tearDown()601 status_t Camera3Stream::tearDown() {
602     ATRACE_CALL();
603     Mutex::Autolock l(mLock);
604 
605     status_t res = OK;
606 
607     // This function should be only called when the stream is configured.
608     if (mState != STATE_CONFIGURED) {
609         ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
610                 "CONFIGURED state %d", __FUNCTION__, mId, mState);
611         return INVALID_OPERATION;
612     }
613 
614     // If any buffers have been handed to the HAL, the stream cannot be torn down.
615     if (getHandoutOutputBufferCountLocked() > 0) {
616         ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
617                 __FUNCTION__, mId);
618         return INVALID_OPERATION;
619     }
620 
621     // Free buffers by disconnecting and then reconnecting to the buffer queue
622     // Only unused buffers will be dropped immediately; buffers that have been filled
623     // and are waiting to be acquired by the consumer and buffers that are currently
624     // acquired will be freed once they are released by the consumer.
625 
626     res = disconnectLocked();
627     if (res != OK) {
628         if (res == -ENOTCONN) {
629             // queue has been disconnected, nothing left to do, so exit with success
630             return OK;
631         }
632         ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
633                 __FUNCTION__, mId, strerror(-res), res);
634         return res;
635     }
636 
637     mState = STATE_IN_CONFIG;
638 
639     res = configureQueueLocked();
640     if (res != OK) {
641         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
642                 __FUNCTION__, mId, strerror(-res), res);
643         mState = STATE_ERROR;
644         return res;
645     }
646 
647     // Reset prepared state, since we've reconnected to the queue and can prepare again.
648     mPrepared = false;
649     mStreamUnpreparable = false;
650 
651     mState = STATE_CONFIGURED;
652 
653     return OK;
654 }
655 
getBuffer(camera_stream_buffer * buffer,nsecs_t waitBufferTimeout,const std::vector<size_t> & surface_ids)656 status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
657         nsecs_t waitBufferTimeout,
658         const std::vector<size_t>& surface_ids) {
659     ATRACE_HFR_CALL();
660     Mutex::Autolock l(mLock);
661     status_t res = OK;
662 
663     // This function should be only called when the stream is configured already.
664     if (mState != STATE_CONFIGURED) {
665         ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
666                 __FUNCTION__, mId, mState);
667         if (mState == STATE_ABANDONED) {
668             return DEAD_OBJECT;
669         } else {
670             return INVALID_OPERATION;
671         }
672     }
673 
674     // Wait for new buffer returned back if we are running into the limit. There
675     // are 2 limits:
676     // 1. The number of HAL buffers is greater than max_buffers
677     // 2. The number of HAL buffers + cached buffers is greater than max_buffers
678     //    + maxCachedBuffers
679     size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
680     size_t numCachedBuffers = getCachedOutputBufferCountLocked();
681     size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
682     while (numOutstandingBuffers == camera_stream::max_buffers ||
683             numOutstandingBuffers + numCachedBuffers ==
684             camera_stream::max_buffers + maxNumCachedBuffers) {
685         ALOGV("%s: Already dequeued max output buffers (%d(+%zu)), wait for next returned one.",
686                         __FUNCTION__, camera_stream::max_buffers, maxNumCachedBuffers);
687         nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
688         if (waitBufferTimeout < kWaitForBufferDuration) {
689             waitBufferTimeout = kWaitForBufferDuration;
690         }
691         res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
692         nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
693         mBufferLimitLatency.add(waitStart, waitEnd);
694         if (res != OK) {
695             if (res == TIMED_OUT) {
696                 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
697                         __FUNCTION__, waitBufferTimeout / 1000000LL,
698                         camera_stream::max_buffers);
699             }
700             return res;
701         }
702 
703         size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
704         size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
705         if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
706                 updatedNumCachedBuffers == numCachedBuffers) {
707             ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
708                     "getBuffer(s) call must not run in parallel!", __FUNCTION__,
709                     numOutstandingBuffers, updatedNumOutstandingBuffers);
710             return INVALID_OPERATION;
711         }
712         numOutstandingBuffers = updatedNumOutstandingBuffers;
713         numCachedBuffers = updatedNumCachedBuffers;
714     }
715 
716     res = getBufferLocked(buffer, surface_ids);
717     if (res == OK) {
718         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
719         if (buffer->buffer) {
720             Mutex::Autolock l(mOutstandingBuffersLock);
721             mOutstandingBuffers.push_back(*buffer->buffer);
722         }
723     }
724 
725     return res;
726 }
727 
isOutstandingBuffer(const camera_stream_buffer & buffer) const728 bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
729     if (buffer.buffer == nullptr) {
730         return false;
731     }
732 
733     Mutex::Autolock l(mOutstandingBuffersLock);
734 
735     for (auto b : mOutstandingBuffers) {
736         if (b == *buffer.buffer) {
737             return true;
738         }
739     }
740     return false;
741 }
742 
removeOutstandingBuffer(const camera_stream_buffer & buffer)743 void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
744     if (buffer.buffer == nullptr) {
745         return;
746     }
747 
748     Mutex::Autolock l(mOutstandingBuffersLock);
749 
750     for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
751         if (*b == *buffer.buffer) {
752             mOutstandingBuffers.erase(b);
753             return;
754         }
755     }
756 }
757 
returnBuffer(const camera_stream_buffer & buffer,nsecs_t timestamp,nsecs_t readoutTimestamp,bool timestampIncreasing,const std::vector<size_t> & surface_ids,uint64_t frameNumber,int32_t transform)758 status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
759         nsecs_t timestamp, nsecs_t readoutTimestamp, bool timestampIncreasing,
760          const std::vector<size_t>& surface_ids, uint64_t frameNumber, int32_t transform) {
761     ATRACE_HFR_CALL();
762     Mutex::Autolock l(mLock);
763 
764     // Check if this buffer is outstanding.
765     if (!isOutstandingBuffer(buffer)) {
766         ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
767         return BAD_VALUE;
768     }
769 
770     removeOutstandingBuffer(buffer);
771 
772     // Buffer status may be changed, so make a copy of the stream_buffer struct.
773     camera_stream_buffer b = buffer;
774     if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
775         ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
776                 __FUNCTION__, mId, timestamp, mLastTimestamp);
777         b.status = CAMERA_BUFFER_STATUS_ERROR;
778     }
779     mLastTimestamp = timestamp;
780 
781     /**
782      * TODO: Check that the state is valid first.
783      *
784      * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
785      * >= HAL3.2 CONFIGURED only
786      *
787      * Do this for getBuffer as well.
788      */
789     status_t res = returnBufferLocked(b, timestamp, readoutTimestamp, transform, surface_ids);
790     if (res == OK) {
791         fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
792     }
793 
794     // Even if returning the buffer failed, we still want to signal whoever is waiting for the
795     // buffer to be returned.
796     mOutputBufferReturnedSignal.signal();
797 
798     return res;
799 }
800 
getInputBuffer(camera_stream_buffer * buffer,Size * size,bool respectHalLimit)801 status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
802         Size* size, bool respectHalLimit) {
803     ATRACE_CALL();
804     Mutex::Autolock l(mLock);
805     status_t res = OK;
806 
807     if (size == nullptr) {
808         ALOGE("%s: size must not be null", __FUNCTION__);
809         return BAD_VALUE;
810     }
811     // This function should be only called when the stream is configured already.
812     if (mState != STATE_CONFIGURED) {
813         ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
814                 __FUNCTION__, mId, mState);
815         return INVALID_OPERATION;
816     }
817 
818     // Wait for new buffer returned back if we are running into the limit.
819     if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
820         ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
821                 __FUNCTION__, camera_stream::max_buffers);
822         res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
823         if (res != OK) {
824             if (res == TIMED_OUT) {
825                 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
826                         kWaitForBufferDuration / 1000000LL);
827             }
828             return res;
829         }
830     }
831 
832     res = getInputBufferLocked(buffer, size);
833     if (res == OK) {
834         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
835         if (buffer->buffer) {
836             Mutex::Autolock l(mOutstandingBuffersLock);
837             mOutstandingBuffers.push_back(*buffer->buffer);
838         }
839     }
840 
841     return res;
842 }
843 
returnInputBuffer(const camera_stream_buffer & buffer)844 status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
845     ATRACE_CALL();
846     Mutex::Autolock l(mLock);
847 
848     // Check if this buffer is outstanding.
849     if (!isOutstandingBuffer(buffer)) {
850         ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
851         return BAD_VALUE;
852     }
853 
854     removeOutstandingBuffer(buffer);
855 
856     status_t res = returnInputBufferLocked(buffer);
857     if (res == OK) {
858         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
859         mInputBufferReturnedSignal.signal();
860     }
861 
862     return res;
863 }
864 
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)865 status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
866     ATRACE_CALL();
867     Mutex::Autolock l(mLock);
868 
869     return getInputBufferProducerLocked(producer);
870 }
871 
fireBufferRequestForFrameNumber(uint64_t frameNumber,const CameraMetadata & settings)872 void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
873         const CameraMetadata& settings) {
874     ATRACE_CALL();
875     Mutex::Autolock l(mLock);
876 
877     for (auto &it : mBufferListenerList) {
878         sp<Camera3StreamBufferListener> listener = it.promote();
879         if (listener.get() != nullptr) {
880             listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
881         }
882     }
883 }
884 
fireBufferListenersLocked(const camera_stream_buffer & buffer,bool acquired,bool output,nsecs_t timestamp,uint64_t frameNumber)885 void Camera3Stream::fireBufferListenersLocked(
886         const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
887         uint64_t frameNumber) {
888     List<wp<Camera3StreamBufferListener> >::iterator it, end;
889 
890     // TODO: finish implementing
891 
892     Camera3StreamBufferListener::BufferInfo info =
893         Camera3StreamBufferListener::BufferInfo();
894     info.mOutput = output;
895     info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
896     info.mFrameNumber = frameNumber;
897     info.mTimestamp = timestamp;
898     info.mStreamId = getId();
899 
900     // TODO: rest of fields
901 
902     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
903          it != end;
904          ++it) {
905 
906         sp<Camera3StreamBufferListener> listener = it->promote();
907         if (listener != 0) {
908             if (acquired) {
909                 listener->onBufferAcquired(info);
910             } else {
911                 listener->onBufferReleased(info);
912             }
913         }
914     }
915 }
916 
hasOutstandingBuffers() const917 bool Camera3Stream::hasOutstandingBuffers() const {
918     ATRACE_CALL();
919     Mutex::Autolock l(mLock);
920     return hasOutstandingBuffersLocked();
921 }
922 
getOutstandingBuffersCount() const923 size_t Camera3Stream::getOutstandingBuffersCount() const {
924     ATRACE_CALL();
925     Mutex::Autolock l(mLock);
926     return getHandoutOutputBufferCountLocked();
927 }
928 
setStatusTracker(sp<StatusTracker> statusTracker)929 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
930     Mutex::Autolock l(mLock);
931     sp<StatusTracker> oldTracker = mStatusTracker.promote();
932     if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
933         oldTracker->removeComponent(mStatusId);
934     }
935     mStatusId = StatusTracker::NO_STATUS_ID;
936     mStatusTracker = statusTracker;
937 
938     return OK;
939 }
940 
disconnect()941 status_t Camera3Stream::disconnect() {
942     ATRACE_CALL();
943     Mutex::Autolock l(mLock);
944     ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
945     status_t res = disconnectLocked();
946 
947     mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
948     mBufferLimitLatency.reset();
949 
950     if (res == -ENOTCONN) {
951         // "Already disconnected" -- not an error
952         return OK;
953     } else {
954         return res;
955     }
956 }
957 
dump(int fd,const Vector<String16> & args) const958 void Camera3Stream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const
959 {
960     mBufferLimitLatency.dump(fd,
961             "      Latency histogram for wait on max_buffers");
962 }
963 
getBufferLocked(camera_stream_buffer *,const std::vector<size_t> &)964 status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
965         const std::vector<size_t>&) {
966     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
967     return INVALID_OPERATION;
968 }
969 
getBuffersLocked(std::vector<OutstandingBuffer> *)970 status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) {
971     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
972     return INVALID_OPERATION;
973 }
974 
returnBufferLocked(const camera_stream_buffer &,nsecs_t,nsecs_t,int32_t,const std::vector<size_t> &)975 status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
976                                            nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
977     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
978     return INVALID_OPERATION;
979 }
getInputBufferLocked(camera_stream_buffer *,Size *)980 status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
981     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
982     return INVALID_OPERATION;
983 }
returnInputBufferLocked(const camera_stream_buffer &)984 status_t Camera3Stream::returnInputBufferLocked(
985         const camera_stream_buffer &) {
986     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
987     return INVALID_OPERATION;
988 }
getInputBufferProducerLocked(sp<IGraphicBufferProducer> *)989 status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
990     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
991     return INVALID_OPERATION;
992 }
993 
addBufferListener(wp<Camera3StreamBufferListener> listener)994 void Camera3Stream::addBufferListener(
995         wp<Camera3StreamBufferListener> listener) {
996     Mutex::Autolock l(mLock);
997 
998     List<wp<Camera3StreamBufferListener> >::iterator it, end;
999     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1000          it != end;
1001          ) {
1002         if (*it == listener) {
1003             ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
1004             return;
1005         }
1006         it++;
1007     }
1008 
1009     mBufferListenerList.push_back(listener);
1010 }
1011 
removeBufferListener(const sp<Camera3StreamBufferListener> & listener)1012 void Camera3Stream::removeBufferListener(
1013         const sp<Camera3StreamBufferListener>& listener) {
1014     Mutex::Autolock l(mLock);
1015 
1016     bool erased = true;
1017     List<wp<Camera3StreamBufferListener> >::iterator it, end;
1018     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1019          it != end;
1020          ) {
1021 
1022         if (*it == listener) {
1023             it = mBufferListenerList.erase(it);
1024             erased = true;
1025         } else {
1026             ++it;
1027         }
1028     }
1029 
1030     if (!erased) {
1031         ALOGW("%s: Could not find listener to remove, already removed",
1032               __FUNCTION__);
1033     }
1034 }
1035 
setBufferFreedListener(wp<Camera3StreamBufferFreedListener> listener)1036 void Camera3Stream::setBufferFreedListener(
1037         wp<Camera3StreamBufferFreedListener> listener) {
1038     Mutex::Autolock l(mLock);
1039     // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
1040     // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
1041     if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
1042         ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
1043         return;
1044     }
1045     mBufferFreedListener = listener;
1046 }
1047 
getBuffers(std::vector<OutstandingBuffer> * buffers,nsecs_t waitBufferTimeout)1048 status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers,
1049         nsecs_t waitBufferTimeout) {
1050     ATRACE_CALL();
1051     Mutex::Autolock l(mLock);
1052     status_t res = OK;
1053 
1054     if (buffers == nullptr) {
1055         ALOGI("%s: buffers must not be null!", __FUNCTION__);
1056         return BAD_VALUE;
1057     }
1058 
1059     size_t numBuffersRequested = buffers->size();
1060     if (numBuffersRequested == 0) {
1061         ALOGE("%s: 0 buffers are requested!", __FUNCTION__);
1062         return BAD_VALUE;
1063     }
1064 
1065     // This function should be only called when the stream is configured already.
1066     if (mState != STATE_CONFIGURED) {
1067         ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
1068                 __FUNCTION__, mId, mState);
1069         if (mState == STATE_ABANDONED) {
1070             return DEAD_OBJECT;
1071         } else {
1072             return INVALID_OPERATION;
1073         }
1074     }
1075 
1076     size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
1077     size_t numCachedBuffers = getCachedOutputBufferCountLocked();
1078     size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
1079     // Wait for new buffer returned back if we are running into the limit. There
1080     // are 2 limits:
1081     // 1. The number of HAL buffers is greater than max_buffers
1082     // 2. The number of HAL buffers + cached buffers is greater than max_buffers
1083     //    + maxCachedBuffers
1084     while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers ||
1085             numOutstandingBuffers + numCachedBuffers + numBuffersRequested >
1086             camera_stream::max_buffers + maxNumCachedBuffers) {
1087         ALOGV("%s: Already dequeued %zu(+%zu) output buffers and requesting %zu "
1088                 "(max is %d(+%zu)), waiting.", __FUNCTION__, numOutstandingBuffers,
1089                 numCachedBuffers, numBuffersRequested, camera_stream::max_buffers,
1090                 maxNumCachedBuffers);
1091         nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
1092         if (waitBufferTimeout < kWaitForBufferDuration) {
1093             waitBufferTimeout = kWaitForBufferDuration;
1094         }
1095         res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
1096         nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
1097         mBufferLimitLatency.add(waitStart, waitEnd);
1098         if (res != OK) {
1099             if (res == TIMED_OUT) {
1100                 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
1101                         __FUNCTION__, waitBufferTimeout / 1000000LL,
1102                         camera_stream::max_buffers);
1103             }
1104             return res;
1105         }
1106         size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
1107         size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
1108         if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
1109                 updatedNumCachedBuffers == numCachedBuffers) {
1110             ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
1111                     "getBuffer(s) call must not run in parallel!", __FUNCTION__,
1112                     numOutstandingBuffers, updatedNumOutstandingBuffers);
1113             return INVALID_OPERATION;
1114         }
1115         numOutstandingBuffers = updatedNumOutstandingBuffers;
1116         numCachedBuffers = updatedNumCachedBuffers;
1117     }
1118 
1119     res = getBuffersLocked(buffers);
1120     if (res == OK) {
1121         for (auto& outstandingBuffer : *buffers) {
1122             camera_stream_buffer* buffer = outstandingBuffer.outBuffer;
1123             fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
1124             if (buffer->buffer) {
1125                 Mutex::Autolock l(mOutstandingBuffersLock);
1126                 mOutstandingBuffers.push_back(*buffer->buffer);
1127             }
1128         }
1129     }
1130 
1131     return res;
1132 }
1133 
queueHDRMetadata(buffer_handle_t buffer,sp<ANativeWindow> & anw,int64_t dynamicRangeProfile)1134 void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
1135         int64_t dynamicRangeProfile) {
1136     auto& mapper = GraphicBufferMapper::get();
1137     switch (dynamicRangeProfile) {
1138         case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
1139             std::optional<ui::Smpte2086> smpte2086;
1140             auto res = mapper.getSmpte2086(buffer, &smpte2086);
1141             if ((res == OK) && smpte2086.has_value()) {
1142                 const auto& metaValue = smpte2086.value();
1143                 android_smpte2086_metadata meta = {
1144                     .displayPrimaryRed.x = metaValue.primaryRed.x,
1145                     .displayPrimaryRed.y = metaValue.primaryRed.y,
1146                     .displayPrimaryGreen.x = metaValue.primaryGreen.x,
1147                     .displayPrimaryGreen.y = metaValue.primaryGreen.y,
1148                     .displayPrimaryBlue.x = metaValue.primaryBlue.x,
1149                     .displayPrimaryBlue.y = metaValue.primaryBlue.y,
1150                     .whitePoint.x = metaValue.whitePoint.x,
1151                     .whitePoint.y = metaValue.whitePoint.y,
1152                     .maxLuminance = metaValue.maxLuminance,
1153                     .minLuminance = metaValue.minLuminance};
1154                 native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
1155             } else {
1156                 ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
1157                         __FUNCTION__, strerror(-res), res);
1158             }
1159             break;
1160         }
1161         case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
1162             std::optional<std::vector<uint8_t>> smpte2094_40;
1163             auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
1164             if ((res == OK) && smpte2094_40.has_value()) {
1165                 native_window_set_buffers_hdr10_plus_metadata(anw.get(),
1166                         smpte2094_40.value().size(), smpte2094_40.value().data());
1167             } else {
1168                 ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
1169                         __FUNCTION__, strerror(-res), res);
1170             }
1171             break;
1172         }
1173         default:
1174             // No-op
1175             break;
1176     }
1177 }
1178 
1179 
1180 }; // namespace camera3
1181 
1182 }; // namespace android
1183