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