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 "Camera3-Stream"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <utils/Log.h>
22 #include <utils/Trace.h>
23 #include "device3/Camera3Stream.h"
24 #include "device3/StatusTracker.h"
25 
26 #include <cutils/properties.h>
27 
28 namespace android {
29 
30 namespace camera3 {
31 
~Camera3Stream()32 Camera3Stream::~Camera3Stream() {
33     sp<StatusTracker> statusTracker = mStatusTracker.promote();
34     if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
35         statusTracker->removeComponent(mStatusId);
36     }
37 }
38 
cast(camera3_stream * stream)39 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
40     return static_cast<Camera3Stream*>(stream);
41 }
42 
cast(const camera3_stream * stream)43 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
44     return static_cast<const Camera3Stream*>(stream);
45 }
46 
Camera3Stream(int id,camera3_stream_type type,uint32_t width,uint32_t height,size_t maxSize,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,const String8 & physicalCameraId,int setId)47 Camera3Stream::Camera3Stream(int id,
48         camera3_stream_type type,
49         uint32_t width, uint32_t height, size_t maxSize, int format,
50         android_dataspace dataSpace, camera3_stream_rotation_t rotation,
51         const String8& physicalCameraId, int setId) :
52     camera3_stream(),
53     mId(id),
54     mSetId(setId),
55     mName(String8::format("Camera3Stream[%d]", id)),
56     mMaxSize(maxSize),
57     mState(STATE_CONSTRUCTED),
58     mStatusId(StatusTracker::NO_STATUS_ID),
59     mStreamUnpreparable(true),
60     mUsage(0),
61     mOldUsage(0),
62     mOldMaxBuffers(0),
63     mPrepared(false),
64     mPreparedBufferIdx(0),
65     mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
66     mBufferLimitLatency(kBufferLimitLatencyBinSize),
67     mFormatOverridden(false),
68     mOriginalFormat(-1),
69     mPhysicalCameraId(physicalCameraId) {
70 
71     camera3_stream::stream_type = type;
72     camera3_stream::width = width;
73     camera3_stream::height = height;
74     camera3_stream::format = format;
75     camera3_stream::data_space = dataSpace;
76     camera3_stream::rotation = rotation;
77     camera3_stream::max_buffers = 0;
78     camera3_stream::priv = NULL;
79     camera3_stream::physical_camera_id = mPhysicalCameraId.string();
80 
81     if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
82             maxSize == 0) {
83         ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
84         mState = STATE_ERROR;
85     }
86 }
87 
getId() const88 int Camera3Stream::getId() const {
89     return mId;
90 }
91 
getStreamSetId() const92 int Camera3Stream::getStreamSetId() const {
93     return mSetId;
94 }
95 
getWidth() const96 uint32_t Camera3Stream::getWidth() const {
97     return camera3_stream::width;
98 }
99 
getHeight() const100 uint32_t Camera3Stream::getHeight() const {
101     return camera3_stream::height;
102 }
103 
getFormat() const104 int Camera3Stream::getFormat() const {
105     return camera3_stream::format;
106 }
107 
getDataSpace() const108 android_dataspace Camera3Stream::getDataSpace() const {
109     return camera3_stream::data_space;
110 }
111 
getUsage() const112 uint64_t Camera3Stream::getUsage() const {
113     return mUsage;
114 }
115 
setUsage(uint64_t usage)116 void Camera3Stream::setUsage(uint64_t usage) {
117     mUsage = usage;
118 }
119 
setFormatOverride(bool formatOverridden)120 void Camera3Stream::setFormatOverride(bool formatOverridden) {
121     mFormatOverridden = formatOverridden;
122     if (formatOverridden) mOriginalFormat = camera3_stream::format;
123 }
124 
isFormatOverridden() const125 bool Camera3Stream::isFormatOverridden() const {
126     return mFormatOverridden;
127 }
128 
getOriginalFormat() const129 int Camera3Stream::getOriginalFormat() const {
130     return mOriginalFormat;
131 }
132 
setDataSpaceOverride(bool dataSpaceOverridden)133 void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
134     mDataSpaceOverridden = dataSpaceOverridden;
135     if (dataSpaceOverridden) mOriginalDataSpace = camera3_stream::data_space;
136 }
137 
isDataSpaceOverridden() const138 bool Camera3Stream::isDataSpaceOverridden() const {
139     return mDataSpaceOverridden;
140 }
141 
getOriginalDataSpace() const142 android_dataspace Camera3Stream::getOriginalDataSpace() const {
143     return mOriginalDataSpace;
144 }
145 
physicalCameraId() const146 const String8& Camera3Stream::physicalCameraId() const {
147     return mPhysicalCameraId;
148 }
149 
forceToIdle()150 status_t Camera3Stream::forceToIdle() {
151     ATRACE_CALL();
152     Mutex::Autolock l(mLock);
153     status_t res;
154 
155     switch (mState) {
156         case STATE_ERROR:
157         case STATE_CONSTRUCTED:
158         case STATE_IN_CONFIG:
159         case STATE_PREPARING:
160         case STATE_IN_RECONFIG:
161             ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
162             res = NO_INIT;
163             break;
164         case STATE_CONFIGURED:
165             if (hasOutstandingBuffersLocked()) {
166                 sp<StatusTracker> statusTracker = mStatusTracker.promote();
167                 if (statusTracker != 0) {
168                     statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
169                 }
170             }
171 
172             mState = STATE_IN_IDLE;
173             res = OK;
174 
175             break;
176         default:
177             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
178             res = NO_INIT;
179     }
180 
181     return res;
182 }
183 
restoreConfiguredState()184 status_t Camera3Stream::restoreConfiguredState() {
185     ATRACE_CALL();
186     Mutex::Autolock l(mLock);
187     status_t res;
188 
189     switch (mState) {
190         case STATE_ERROR:
191         case STATE_CONSTRUCTED:
192         case STATE_IN_CONFIG:
193         case STATE_PREPARING:
194         case STATE_IN_RECONFIG:
195         case STATE_CONFIGURED:
196             ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
197             res = NO_INIT;
198             break;
199         case STATE_IN_IDLE:
200             if (hasOutstandingBuffersLocked()) {
201                 sp<StatusTracker> statusTracker = mStatusTracker.promote();
202                 if (statusTracker != 0) {
203                     statusTracker->markComponentActive(mStatusId);
204                 }
205             }
206 
207             mState = STATE_CONFIGURED;
208             res = OK;
209 
210             break;
211         default:
212             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
213             res = NO_INIT;
214     }
215 
216     return res;
217 }
218 
startConfiguration()219 camera3_stream* Camera3Stream::startConfiguration() {
220     ATRACE_CALL();
221     Mutex::Autolock l(mLock);
222     status_t res;
223 
224     switch (mState) {
225         case STATE_ERROR:
226             ALOGE("%s: In error state", __FUNCTION__);
227             return NULL;
228         case STATE_CONSTRUCTED:
229         case STATE_IN_IDLE:
230             // OK
231             break;
232         case STATE_IN_CONFIG:
233         case STATE_IN_RECONFIG:
234             // Can start config again with no trouble; but don't redo
235             // mOldUsage/mOldMaxBuffers
236             return this;
237         case STATE_CONFIGURED:
238             if (hasOutstandingBuffersLocked()) {
239                 ALOGE("%s: Cannot configure stream; has outstanding buffers",
240                         __FUNCTION__);
241                 return NULL;
242             }
243             break;
244         default:
245             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
246             return NULL;
247     }
248 
249     mOldUsage = mUsage;
250     mOldMaxBuffers = camera3_stream::max_buffers;
251 
252     res = getEndpointUsage(&mUsage);
253     if (res != OK) {
254         ALOGE("%s: Cannot query consumer endpoint usage!",
255                 __FUNCTION__);
256         return NULL;
257     }
258 
259     if (mState == STATE_IN_IDLE) {
260         // Skip configuration.
261         return this;
262     }
263 
264     // Stop tracking if currently doing so
265     if (mStatusId != StatusTracker::NO_STATUS_ID) {
266         sp<StatusTracker> statusTracker = mStatusTracker.promote();
267         if (statusTracker != 0) {
268             statusTracker->removeComponent(mStatusId);
269         }
270         mStatusId = StatusTracker::NO_STATUS_ID;
271     }
272 
273     if (mState == STATE_CONSTRUCTED) {
274         mState = STATE_IN_CONFIG;
275     } else { // mState == STATE_CONFIGURED
276         LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
277         mState = STATE_IN_RECONFIG;
278     }
279 
280     return this;
281 }
282 
isConfiguring() const283 bool Camera3Stream::isConfiguring() const {
284     Mutex::Autolock l(mLock);
285     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
286 }
287 
finishConfiguration()288 status_t Camera3Stream::finishConfiguration() {
289     ATRACE_CALL();
290     Mutex::Autolock l(mLock);
291     switch (mState) {
292         case STATE_ERROR:
293             ALOGE("%s: In error state", __FUNCTION__);
294             return INVALID_OPERATION;
295         case STATE_IN_CONFIG:
296         case STATE_IN_RECONFIG:
297             // OK
298             break;
299         case STATE_CONSTRUCTED:
300         case STATE_CONFIGURED:
301             ALOGE("%s: Cannot finish configuration that hasn't been started",
302                     __FUNCTION__);
303             return INVALID_OPERATION;
304         case STATE_IN_IDLE:
305             //Skip configuration in this state
306             return OK;
307         default:
308             ALOGE("%s: Unknown state", __FUNCTION__);
309             return INVALID_OPERATION;
310     }
311 
312     // Register for idle tracking
313     sp<StatusTracker> statusTracker = mStatusTracker.promote();
314     if (statusTracker != 0) {
315         mStatusId = statusTracker->addComponent();
316     }
317 
318     // Check if the stream configuration is unchanged, and skip reallocation if
319     // so. As documented in hardware/camera3.h:configure_streams().
320     if (mState == STATE_IN_RECONFIG &&
321             mOldUsage == mUsage &&
322             mOldMaxBuffers == camera3_stream::max_buffers) {
323         mState = STATE_CONFIGURED;
324         return OK;
325     }
326 
327     // Reset prepared state, since buffer config has changed, and existing
328     // allocations are no longer valid
329     mPrepared = false;
330     mStreamUnpreparable = false;
331 
332     status_t res;
333     res = configureQueueLocked();
334     if (res != OK) {
335         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
336                 __FUNCTION__, mId, strerror(-res), res);
337         mState = STATE_ERROR;
338         return res;
339     }
340 
341     mState = STATE_CONFIGURED;
342 
343     return res;
344 }
345 
cancelConfiguration()346 status_t Camera3Stream::cancelConfiguration() {
347     ATRACE_CALL();
348     Mutex::Autolock l(mLock);
349     switch (mState) {
350         case STATE_ERROR:
351             ALOGE("%s: In error state", __FUNCTION__);
352             return INVALID_OPERATION;
353         case STATE_IN_CONFIG:
354         case STATE_IN_RECONFIG:
355         case STATE_IN_IDLE:
356             // OK
357             break;
358         case STATE_CONSTRUCTED:
359         case STATE_CONFIGURED:
360             ALOGE("%s: Cannot cancel configuration that hasn't been started",
361                     __FUNCTION__);
362             return INVALID_OPERATION;
363         default:
364             ALOGE("%s: Unknown state", __FUNCTION__);
365             return INVALID_OPERATION;
366     }
367 
368     mUsage = mOldUsage;
369     camera3_stream::max_buffers = mOldMaxBuffers;
370 
371     mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
372             STATE_CONSTRUCTED;
373 
374     return OK;
375 }
376 
isUnpreparable()377 bool Camera3Stream::isUnpreparable() {
378     ATRACE_CALL();
379 
380     Mutex::Autolock l(mLock);
381     return mStreamUnpreparable;
382 }
383 
startPrepare(int maxCount)384 status_t Camera3Stream::startPrepare(int maxCount) {
385     ATRACE_CALL();
386 
387     Mutex::Autolock l(mLock);
388 
389     if (maxCount < 0) {
390         ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
391                 __FUNCTION__, mId, maxCount);
392         return BAD_VALUE;
393     }
394 
395     // This function should be only called when the stream is configured already.
396     if (mState != STATE_CONFIGURED) {
397         ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
398                 "state %d", __FUNCTION__, mId, mState);
399         return INVALID_OPERATION;
400     }
401 
402     // This function can't be called if the stream has already received filled
403     // buffers
404     if (mStreamUnpreparable) {
405         ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
406                 __FUNCTION__, mId);
407         return INVALID_OPERATION;
408     }
409 
410     if (getHandoutOutputBufferCountLocked() > 0) {
411         ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
412                 __FUNCTION__, mId);
413         return INVALID_OPERATION;
414     }
415 
416 
417 
418     size_t pipelineMax = getBufferCountLocked();
419     size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
420             pipelineMax : static_cast<size_t>(maxCount);
421     size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
422             pipelineMax : clampedCount;
423 
424     mPrepared = bufferCount <= mLastMaxCount;
425 
426     if (mPrepared) return OK;
427 
428     mLastMaxCount = bufferCount;
429 
430     mPreparedBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount);
431     mPreparedBufferIdx = 0;
432 
433     mState = STATE_PREPARING;
434 
435     return NOT_ENOUGH_DATA;
436 }
437 
isPreparing() const438 bool Camera3Stream::isPreparing() const {
439     Mutex::Autolock l(mLock);
440     return mState == STATE_PREPARING;
441 }
442 
isAbandoned() const443 bool Camera3Stream::isAbandoned() const {
444     Mutex::Autolock l(mLock);
445     return mState == STATE_ABANDONED;
446 }
447 
prepareNextBuffer()448 status_t Camera3Stream::prepareNextBuffer() {
449     ATRACE_CALL();
450 
451     Mutex::Autolock l(mLock);
452     status_t res = OK;
453 
454     // This function should be only called when the stream is preparing
455     if (mState != STATE_PREPARING) {
456         ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
457                 "state %d", __FUNCTION__, mId, mState);
458         return INVALID_OPERATION;
459     }
460 
461     // Get next buffer - this may allocate, and take a while for large buffers
462     res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
463     if (res != OK) {
464         ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
465                 __FUNCTION__, mId, mPreparedBufferIdx);
466         return NO_INIT;
467     }
468 
469     mPreparedBufferIdx++;
470 
471     // Check if we still have buffers left to allocate
472     if (mPreparedBufferIdx < mPreparedBuffers.size()) {
473         return NOT_ENOUGH_DATA;
474     }
475 
476     // Done with prepare - mark stream as such, and return all buffers
477     // via cancelPrepare
478     mPrepared = true;
479 
480     return cancelPrepareLocked();
481 }
482 
cancelPrepare()483 status_t Camera3Stream::cancelPrepare() {
484     ATRACE_CALL();
485 
486     Mutex::Autolock l(mLock);
487 
488     return cancelPrepareLocked();
489 }
490 
cancelPrepareLocked()491 status_t Camera3Stream::cancelPrepareLocked() {
492     status_t res = OK;
493 
494     // This function should be only called when the stream is mid-preparing.
495     if (mState != STATE_PREPARING) {
496         ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
497                 "PREPARING state %d", __FUNCTION__, mId, mState);
498         return INVALID_OPERATION;
499     }
500 
501     // Return all valid buffers to stream, in ERROR state to indicate
502     // they weren't filled.
503     for (size_t i = 0; i < mPreparedBufferIdx; i++) {
504         mPreparedBuffers.editItemAt(i).release_fence = -1;
505         mPreparedBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
506         returnBufferLocked(mPreparedBuffers[i], 0);
507     }
508     mPreparedBuffers.clear();
509     mPreparedBufferIdx = 0;
510 
511     mState = STATE_CONFIGURED;
512 
513     return res;
514 }
515 
tearDown()516 status_t Camera3Stream::tearDown() {
517     ATRACE_CALL();
518     Mutex::Autolock l(mLock);
519 
520     status_t res = OK;
521 
522     // This function should be only called when the stream is configured.
523     if (mState != STATE_CONFIGURED) {
524         ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
525                 "CONFIGURED state %d", __FUNCTION__, mId, mState);
526         return INVALID_OPERATION;
527     }
528 
529     // If any buffers have been handed to the HAL, the stream cannot be torn down.
530     if (getHandoutOutputBufferCountLocked() > 0) {
531         ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
532                 __FUNCTION__, mId);
533         return INVALID_OPERATION;
534     }
535 
536     // Free buffers by disconnecting and then reconnecting to the buffer queue
537     // Only unused buffers will be dropped immediately; buffers that have been filled
538     // and are waiting to be acquired by the consumer and buffers that are currently
539     // acquired will be freed once they are released by the consumer.
540 
541     res = disconnectLocked();
542     if (res != OK) {
543         if (res == -ENOTCONN) {
544             // queue has been disconnected, nothing left to do, so exit with success
545             return OK;
546         }
547         ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
548                 __FUNCTION__, mId, strerror(-res), res);
549         return res;
550     }
551 
552     mState = STATE_IN_CONFIG;
553 
554     res = configureQueueLocked();
555     if (res != OK) {
556         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
557                 __FUNCTION__, mId, strerror(-res), res);
558         mState = STATE_ERROR;
559         return res;
560     }
561 
562     // Reset prepared state, since we've reconnected to the queue and can prepare again.
563     mPrepared = false;
564     mStreamUnpreparable = false;
565 
566     mState = STATE_CONFIGURED;
567 
568     return OK;
569 }
570 
getBuffer(camera3_stream_buffer * buffer,const std::vector<size_t> & surface_ids)571 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer,
572         const std::vector<size_t>& surface_ids) {
573     ATRACE_CALL();
574     Mutex::Autolock l(mLock);
575     status_t res = OK;
576 
577     // This function should be only called when the stream is configured already.
578     if (mState != STATE_CONFIGURED) {
579         ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
580                 __FUNCTION__, mId, mState);
581         return INVALID_OPERATION;
582     }
583 
584     // Wait for new buffer returned back if we are running into the limit.
585     if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {
586         ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
587                         __FUNCTION__, camera3_stream::max_buffers);
588         nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
589         res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
590         nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
591         mBufferLimitLatency.add(waitStart, waitEnd);
592         if (res != OK) {
593             if (res == TIMED_OUT) {
594                 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
595                         __FUNCTION__, kWaitForBufferDuration / 1000000LL,
596                         camera3_stream::max_buffers);
597             }
598             return res;
599         }
600     }
601 
602     res = getBufferLocked(buffer, surface_ids);
603     if (res == OK) {
604         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
605         if (buffer->buffer) {
606             Mutex::Autolock l(mOutstandingBuffersLock);
607             mOutstandingBuffers.push_back(*buffer->buffer);
608         }
609     }
610 
611     return res;
612 }
613 
isOutstandingBuffer(const camera3_stream_buffer & buffer) const614 bool Camera3Stream::isOutstandingBuffer(const camera3_stream_buffer &buffer) const{
615     if (buffer.buffer == nullptr) {
616         return false;
617     }
618 
619     Mutex::Autolock l(mOutstandingBuffersLock);
620 
621     for (auto b : mOutstandingBuffers) {
622         if (b == *buffer.buffer) {
623             return true;
624         }
625     }
626     return false;
627 }
628 
removeOutstandingBuffer(const camera3_stream_buffer & buffer)629 void Camera3Stream::removeOutstandingBuffer(const camera3_stream_buffer &buffer) {
630     if (buffer.buffer == nullptr) {
631         return;
632     }
633 
634     Mutex::Autolock l(mOutstandingBuffersLock);
635 
636     for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
637         if (*b == *buffer.buffer) {
638             mOutstandingBuffers.erase(b);
639             return;
640         }
641     }
642 }
643 
returnBuffer(const camera3_stream_buffer & buffer,nsecs_t timestamp)644 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
645         nsecs_t timestamp) {
646     ATRACE_CALL();
647     Mutex::Autolock l(mLock);
648 
649     // Check if this buffer is outstanding.
650     if (!isOutstandingBuffer(buffer)) {
651         ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
652         return BAD_VALUE;
653     }
654 
655     removeOutstandingBuffer(buffer);
656 
657     /**
658      * TODO: Check that the state is valid first.
659      *
660      * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
661      * >= HAL3.2 CONFIGURED only
662      *
663      * Do this for getBuffer as well.
664      */
665     status_t res = returnBufferLocked(buffer, timestamp);
666     if (res == OK) {
667         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
668     }
669 
670     // Even if returning the buffer failed, we still want to signal whoever is waiting for the
671     // buffer to be returned.
672     mOutputBufferReturnedSignal.signal();
673 
674     return res;
675 }
676 
getInputBuffer(camera3_stream_buffer * buffer,bool respectHalLimit)677 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer, bool respectHalLimit) {
678     ATRACE_CALL();
679     Mutex::Autolock l(mLock);
680     status_t res = OK;
681 
682     // This function should be only called when the stream is configured already.
683     if (mState != STATE_CONFIGURED) {
684         ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
685                 __FUNCTION__, mId, mState);
686         return INVALID_OPERATION;
687     }
688 
689     // Wait for new buffer returned back if we are running into the limit.
690     if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers && respectHalLimit) {
691         ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
692                 __FUNCTION__, camera3_stream::max_buffers);
693         res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
694         if (res != OK) {
695             if (res == TIMED_OUT) {
696                 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
697                         kWaitForBufferDuration / 1000000LL);
698             }
699             return res;
700         }
701     }
702 
703     res = getInputBufferLocked(buffer);
704     if (res == OK) {
705         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
706         if (buffer->buffer) {
707             Mutex::Autolock l(mOutstandingBuffersLock);
708             mOutstandingBuffers.push_back(*buffer->buffer);
709         }
710     }
711 
712     return res;
713 }
714 
returnInputBuffer(const camera3_stream_buffer & buffer)715 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
716     ATRACE_CALL();
717     Mutex::Autolock l(mLock);
718 
719     // Check if this buffer is outstanding.
720     if (!isOutstandingBuffer(buffer)) {
721         ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
722         return BAD_VALUE;
723     }
724 
725     removeOutstandingBuffer(buffer);
726 
727     status_t res = returnInputBufferLocked(buffer);
728     if (res == OK) {
729         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
730         mInputBufferReturnedSignal.signal();
731     }
732 
733     return res;
734 }
735 
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)736 status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
737     ATRACE_CALL();
738     Mutex::Autolock l(mLock);
739 
740     return getInputBufferProducerLocked(producer);
741 }
742 
fireBufferListenersLocked(const camera3_stream_buffer & buffer,bool acquired,bool output)743 void Camera3Stream::fireBufferListenersLocked(
744         const camera3_stream_buffer& buffer, bool acquired, bool output) {
745     List<wp<Camera3StreamBufferListener> >::iterator it, end;
746 
747     // TODO: finish implementing
748 
749     Camera3StreamBufferListener::BufferInfo info =
750         Camera3StreamBufferListener::BufferInfo();
751     info.mOutput = output;
752     info.mError = (buffer.status == CAMERA3_BUFFER_STATUS_ERROR);
753     // TODO: rest of fields
754 
755     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
756          it != end;
757          ++it) {
758 
759         sp<Camera3StreamBufferListener> listener = it->promote();
760         if (listener != 0) {
761             if (acquired) {
762                 listener->onBufferAcquired(info);
763             } else {
764                 listener->onBufferReleased(info);
765             }
766         }
767     }
768 }
769 
hasOutstandingBuffers() const770 bool Camera3Stream::hasOutstandingBuffers() const {
771     ATRACE_CALL();
772     Mutex::Autolock l(mLock);
773     return hasOutstandingBuffersLocked();
774 }
775 
setStatusTracker(sp<StatusTracker> statusTracker)776 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
777     Mutex::Autolock l(mLock);
778     sp<StatusTracker> oldTracker = mStatusTracker.promote();
779     if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
780         oldTracker->removeComponent(mStatusId);
781     }
782     mStatusId = StatusTracker::NO_STATUS_ID;
783     mStatusTracker = statusTracker;
784 
785     return OK;
786 }
787 
disconnect()788 status_t Camera3Stream::disconnect() {
789     ATRACE_CALL();
790     Mutex::Autolock l(mLock);
791     ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
792     status_t res = disconnectLocked();
793 
794     mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
795     mBufferLimitLatency.reset();
796 
797     if (res == -ENOTCONN) {
798         // "Already disconnected" -- not an error
799         return OK;
800     } else {
801         return res;
802     }
803 }
804 
dump(int fd,const Vector<String16> & args) const805 void Camera3Stream::dump(int fd, const Vector<String16> &args) const
806 {
807     (void)args;
808     mBufferLimitLatency.dump(fd,
809             "      Latency histogram for wait on max_buffers");
810 }
811 
getBufferLocked(camera3_stream_buffer *,const std::vector<size_t> &)812 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *,
813         const std::vector<size_t>&) {
814     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
815     return INVALID_OPERATION;
816 }
returnBufferLocked(const camera3_stream_buffer &,nsecs_t)817 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
818                                            nsecs_t) {
819     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
820     return INVALID_OPERATION;
821 }
getInputBufferLocked(camera3_stream_buffer *)822 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
823     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
824     return INVALID_OPERATION;
825 }
returnInputBufferLocked(const camera3_stream_buffer &)826 status_t Camera3Stream::returnInputBufferLocked(
827         const camera3_stream_buffer &) {
828     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
829     return INVALID_OPERATION;
830 }
getInputBufferProducerLocked(sp<IGraphicBufferProducer> *)831 status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
832     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
833     return INVALID_OPERATION;
834 }
835 
addBufferListener(wp<Camera3StreamBufferListener> listener)836 void Camera3Stream::addBufferListener(
837         wp<Camera3StreamBufferListener> listener) {
838     Mutex::Autolock l(mLock);
839 
840     List<wp<Camera3StreamBufferListener> >::iterator it, end;
841     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
842          it != end;
843          ) {
844         if (*it == listener) {
845             ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
846             return;
847         }
848         it++;
849     }
850 
851     mBufferListenerList.push_back(listener);
852 }
853 
removeBufferListener(const sp<Camera3StreamBufferListener> & listener)854 void Camera3Stream::removeBufferListener(
855         const sp<Camera3StreamBufferListener>& listener) {
856     Mutex::Autolock l(mLock);
857 
858     bool erased = true;
859     List<wp<Camera3StreamBufferListener> >::iterator it, end;
860     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
861          it != end;
862          ) {
863 
864         if (*it == listener) {
865             it = mBufferListenerList.erase(it);
866             erased = true;
867         } else {
868             ++it;
869         }
870     }
871 
872     if (!erased) {
873         ALOGW("%s: Could not find listener to remove, already removed",
874               __FUNCTION__);
875     }
876 }
877 
setBufferFreedListener(wp<Camera3StreamBufferFreedListener> listener)878 void Camera3Stream::setBufferFreedListener(
879         wp<Camera3StreamBufferFreedListener> listener) {
880     Mutex::Autolock l(mLock);
881     // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
882     // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
883     if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
884         ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
885         return;
886     }
887     mBufferFreedListener = listener;
888 }
889 
890 }; // namespace camera3
891 
892 }; // namespace android
893