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