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