[go: nahoru, domu]

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