Camera3OutputStream.cpp revision e8c535e833ed135895e99ca81aa3b85d80d7cf3c
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-OutputStream"
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 "Camera3OutputStream.h"
24
25#ifndef container_of
26#define container_of(ptr, type, member) \
27    (type *)((char*)(ptr) - offsetof(type, member))
28#endif
29
30namespace android {
31
32namespace camera3 {
33
34Camera3OutputStream::Camera3OutputStream(int id,
35        sp<Surface> consumer,
36        uint32_t width, uint32_t height, int format,
37        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
38        nsecs_t timestampOffset, int setId) :
39        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
40                            /*maxSize*/0, format, dataSpace, rotation, setId),
41        mConsumer(consumer),
42        mTransform(0),
43        mTraceFirstBuffer(true),
44        mUseBufferManager(false),
45        mTimestampOffset(timestampOffset) {
46
47    if (mConsumer == NULL) {
48        ALOGE("%s: Consumer is NULL!", __FUNCTION__);
49        mState = STATE_ERROR;
50    }
51
52    if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
53        mBufferReleasedListener = new BufferReleasedListener(this);
54    }
55}
56
57Camera3OutputStream::Camera3OutputStream(int id,
58        sp<Surface> consumer,
59        uint32_t width, uint32_t height, size_t maxSize, int format,
60        android_dataspace dataSpace, camera3_stream_rotation_t rotation,
61        nsecs_t timestampOffset, int setId) :
62        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize,
63                            format, dataSpace, rotation, setId),
64        mConsumer(consumer),
65        mTransform(0),
66        mTraceFirstBuffer(true),
67        mUseMonoTimestamp(false),
68        mUseBufferManager(false),
69        mTimestampOffset(timestampOffset) {
70
71    if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
72        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
73                format);
74        mState = STATE_ERROR;
75    }
76
77    if (mConsumer == NULL) {
78        ALOGE("%s: Consumer is NULL!", __FUNCTION__);
79        mState = STATE_ERROR;
80    }
81
82    if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
83        mBufferReleasedListener = new BufferReleasedListener(this);
84    }
85}
86
87Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
88                                         uint32_t width, uint32_t height,
89                                         int format,
90                                         android_dataspace dataSpace,
91                                         camera3_stream_rotation_t rotation,
92                                         int setId) :
93        Camera3IOStreamBase(id, type, width, height,
94                            /*maxSize*/0,
95                            format, dataSpace, rotation, setId),
96        mTransform(0),
97        mTraceFirstBuffer(true),
98        mUseMonoTimestamp(false),
99        mUseBufferManager(false) {
100
101    if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
102        mBufferReleasedListener = new BufferReleasedListener(this);
103    }
104
105    // Subclasses expected to initialize mConsumer themselves
106}
107
108
109Camera3OutputStream::~Camera3OutputStream() {
110    disconnectLocked();
111}
112
113status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) {
114    ATRACE_CALL();
115    status_t res;
116
117    if ((res = getBufferPreconditionCheckLocked()) != OK) {
118        return res;
119    }
120
121    ANativeWindowBuffer* anb;
122    int fenceFd = -1;
123    if (mUseBufferManager) {
124        sp<GraphicBuffer> gb;
125        res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, &fenceFd);
126        if (res != OK) {
127            ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)",
128                    __FUNCTION__, mId, strerror(-res), res);
129            return res;
130        }
131        // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
132        // successful return.
133        anb = gb.get();
134        res = mConsumer->attachBuffer(anb);
135        if (res != OK) {
136            ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
137                    __FUNCTION__, mId, strerror(-res), res);
138            return res;
139        }
140    } else {
141        /**
142         * Release the lock briefly to avoid deadlock for below scenario:
143         * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
144         * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
145         * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
146         * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
147         * StreamingProcessor lock.
148         * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
149         * and try to lock bufferQueue lock.
150         * Then there is circular locking dependency.
151         */
152        sp<ANativeWindow> currentConsumer = mConsumer;
153        mLock.unlock();
154
155        res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd);
156        mLock.lock();
157        if (res != OK) {
158            ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
159                    __FUNCTION__, mId, strerror(-res), res);
160
161            // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
162            // let prepareNextBuffer handle the error.)
163            if (res == NO_INIT && mState == STATE_CONFIGURED) {
164                mState = STATE_ABANDONED;
165            }
166
167            return res;
168        }
169    }
170
171    /**
172     * FenceFD now owned by HAL except in case of error,
173     * in which case we reassign it to acquire_fence
174     */
175    handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
176                        /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
177
178    return OK;
179}
180
181status_t Camera3OutputStream::returnBufferLocked(
182        const camera3_stream_buffer &buffer,
183        nsecs_t timestamp) {
184    ATRACE_CALL();
185
186    status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
187
188    if (res != OK) {
189        return res;
190    }
191
192    mLastTimestamp = timestamp;
193
194    return OK;
195}
196
197status_t Camera3OutputStream::returnBufferCheckedLocked(
198            const camera3_stream_buffer &buffer,
199            nsecs_t timestamp,
200            bool output,
201            /*out*/
202            sp<Fence> *releaseFenceOut) {
203
204    (void)output;
205    ALOG_ASSERT(output, "Expected output to be true");
206
207    status_t res;
208
209    // Fence management - always honor release fence from HAL
210    sp<Fence> releaseFence = new Fence(buffer.release_fence);
211    int anwReleaseFence = releaseFence->dup();
212
213    /**
214     * Release the lock briefly to avoid deadlock with
215     * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
216     * thread will go into StreamingProcessor::onFrameAvailable) during
217     * queueBuffer
218     */
219    sp<ANativeWindow> currentConsumer = mConsumer;
220    mLock.unlock();
221
222    /**
223     * Return buffer back to ANativeWindow
224     */
225    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
226        // Cancel buffer
227        res = currentConsumer->cancelBuffer(currentConsumer.get(),
228                container_of(buffer.buffer, ANativeWindowBuffer, handle),
229                anwReleaseFence);
230        if (res != OK) {
231            ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
232                  " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
233        }
234
235        if (mUseBufferManager) {
236            // Return this buffer back to buffer manager.
237            mBufferReleasedListener->onBufferReleased();
238        }
239    } else {
240        if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) {
241            {
242                char traceLog[48];
243                snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId);
244                ATRACE_NAME(traceLog);
245            }
246            mTraceFirstBuffer = false;
247        }
248
249        /* Certain consumers (such as AudioSource or HardwareComposer) use
250         * MONOTONIC time, causing time misalignment if camera timestamp is
251         * in BOOTTIME. Do the conversion if necessary. */
252        res = native_window_set_buffers_timestamp(mConsumer.get(),
253                mUseMonoTimestamp ? timestamp - mTimestampOffset : timestamp);
254        if (res != OK) {
255            ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
256                  __FUNCTION__, mId, strerror(-res), res);
257            return res;
258        }
259
260        res = currentConsumer->queueBuffer(currentConsumer.get(),
261                container_of(buffer.buffer, ANativeWindowBuffer, handle),
262                anwReleaseFence);
263        if (res != OK) {
264            ALOGE("%s: Stream %d: Error queueing buffer to native window: "
265                  "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
266        }
267    }
268    mLock.lock();
269
270    // Once a valid buffer has been returned to the queue, can no longer
271    // dequeue all buffers for preallocation.
272    if (buffer.status != CAMERA3_BUFFER_STATUS_ERROR) {
273        mStreamUnpreparable = true;
274    }
275
276    if (res != OK) {
277        close(anwReleaseFence);
278    }
279
280    *releaseFenceOut = releaseFence;
281
282    return res;
283}
284
285void Camera3OutputStream::dump(int fd, const Vector<String16> &args) const {
286    (void) args;
287    String8 lines;
288    lines.appendFormat("    Stream[%d]: Output\n", mId);
289    lines.appendFormat("      Consumer name: %s\n", mConsumerName.string());
290    write(fd, lines.string(), lines.size());
291
292    Camera3IOStreamBase::dump(fd, args);
293}
294
295status_t Camera3OutputStream::setTransform(int transform) {
296    ATRACE_CALL();
297    Mutex::Autolock l(mLock);
298    return setTransformLocked(transform);
299}
300
301status_t Camera3OutputStream::setTransformLocked(int transform) {
302    status_t res = OK;
303    if (mState == STATE_ERROR) {
304        ALOGE("%s: Stream in error state", __FUNCTION__);
305        return INVALID_OPERATION;
306    }
307
308    mTransform = transform;
309    if (mState == STATE_CONFIGURED) {
310        res = native_window_set_buffers_transform(mConsumer.get(),
311                transform);
312        if (res != OK) {
313            ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
314                    __FUNCTION__, transform, strerror(-res), res);
315        }
316    }
317    return res;
318}
319
320status_t Camera3OutputStream::configureQueueLocked() {
321    status_t res;
322
323    mTraceFirstBuffer = true;
324    if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
325        return res;
326    }
327
328    ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");
329
330    // Configure consumer-side ANativeWindow interface. The listener may be used
331    // to notify buffer manager (if it is used) of the returned buffers.
332    res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/mBufferReleasedListener);
333    if (res != OK) {
334        ALOGE("%s: Unable to connect to native window for stream %d",
335                __FUNCTION__, mId);
336        return res;
337    }
338
339    mConsumerName = mConsumer->getConsumerName();
340
341    res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
342    if (res != OK) {
343        ALOGE("%s: Unable to configure usage %08x for stream %d",
344                __FUNCTION__, camera3_stream::usage, mId);
345        return res;
346    }
347
348    res = native_window_set_scaling_mode(mConsumer.get(),
349            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
350    if (res != OK) {
351        ALOGE("%s: Unable to configure stream scaling: %s (%d)",
352                __FUNCTION__, strerror(-res), res);
353        return res;
354    }
355
356    if (mMaxSize == 0) {
357        // For buffers of known size
358        res = native_window_set_buffers_dimensions(mConsumer.get(),
359                camera3_stream::width, camera3_stream::height);
360    } else {
361        // For buffers with bounded size
362        res = native_window_set_buffers_dimensions(mConsumer.get(),
363                mMaxSize, 1);
364    }
365    if (res != OK) {
366        ALOGE("%s: Unable to configure stream buffer dimensions"
367                " %d x %d (maxSize %zu) for stream %d",
368                __FUNCTION__, camera3_stream::width, camera3_stream::height,
369                mMaxSize, mId);
370        return res;
371    }
372    res = native_window_set_buffers_format(mConsumer.get(),
373            camera3_stream::format);
374    if (res != OK) {
375        ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
376                __FUNCTION__, camera3_stream::format, mId);
377        return res;
378    }
379
380    res = native_window_set_buffers_data_space(mConsumer.get(),
381            camera3_stream::data_space);
382    if (res != OK) {
383        ALOGE("%s: Unable to configure stream dataspace %#x for stream %d",
384                __FUNCTION__, camera3_stream::data_space, mId);
385        return res;
386    }
387
388    int maxConsumerBuffers;
389    res = static_cast<ANativeWindow*>(mConsumer.get())->query(
390            mConsumer.get(),
391            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
392    if (res != OK) {
393        ALOGE("%s: Unable to query consumer undequeued"
394                " buffer count for stream %d", __FUNCTION__, mId);
395        return res;
396    }
397
398    ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
399            maxConsumerBuffers, camera3_stream::max_buffers);
400    if (camera3_stream::max_buffers == 0) {
401        ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
402                __FUNCTION__, camera3_stream::max_buffers);
403        return INVALID_OPERATION;
404    }
405
406    mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
407    mHandoutTotalBufferCount = 0;
408    mFrameCount = 0;
409    mLastTimestamp = 0;
410    mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream());
411
412    res = native_window_set_buffer_count(mConsumer.get(),
413            mTotalBufferCount);
414    if (res != OK) {
415        ALOGE("%s: Unable to set buffer count for stream %d",
416                __FUNCTION__, mId);
417        return res;
418    }
419
420    res = native_window_set_buffers_transform(mConsumer.get(),
421            mTransform);
422    if (res != OK) {
423        ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
424                __FUNCTION__, mTransform, strerror(-res), res);
425    }
426
427    /**
428     * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
429     * buffers to be statically allocated for internal static buffer registration, while the
430     * buffers provided by buffer manager are really dynamically allocated. Camera3Device only
431     * sets the mBufferManager if device version is > HAL3.2, which guarantees that the buffer
432     * manager setup is skipped in below code. Note that HAL3.2 is also excluded here, as some
433     * HAL3.2 devices may not support the dynamic buffer registeration.
434     */
435    if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) {
436        StreamInfo streamInfo(
437                getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(),
438                camera3_stream::usage, mTotalBufferCount, /*isConfigured*/true);
439        res = mBufferManager->registerStream(streamInfo);
440        if (res == OK) {
441            // Disable buffer allocation for this BufferQueue, buffer manager will take over
442            // the buffer allocation responsibility.
443            mConsumer->getIGraphicBufferProducer()->allowAllocation(false);
444            mUseBufferManager = true;
445        } else {
446            ALOGE("%s: Unable to register stream %d to camera3 buffer manager, "
447                  "(error %d %s), fall back to BufferQueue for buffer management!",
448                  __FUNCTION__, mId, res, strerror(-res));
449        }
450    }
451
452    return OK;
453}
454
455status_t Camera3OutputStream::disconnectLocked() {
456    status_t res;
457
458    if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) {
459        return res;
460    }
461
462    ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
463
464    res = native_window_api_disconnect(mConsumer.get(),
465                                       NATIVE_WINDOW_API_CAMERA);
466
467    /**
468     * This is not an error. if client calling process dies, the window will
469     * also die and all calls to it will return DEAD_OBJECT, thus it's already
470     * "disconnected"
471     */
472    if (res == DEAD_OBJECT) {
473        ALOGW("%s: While disconnecting stream %d from native window, the"
474                " native window died from under us", __FUNCTION__, mId);
475    }
476    else if (res != OK) {
477        ALOGE("%s: Unable to disconnect stream %d from native window "
478              "(error %d %s)",
479              __FUNCTION__, mId, res, strerror(-res));
480        mState = STATE_ERROR;
481        return res;
482    }
483
484    // Since device is already idle, there is no getBuffer call to buffer manager, unregister the
485    // stream at this point should be safe.
486    if (mUseBufferManager) {
487        res = mBufferManager->unregisterStream(getId(), getStreamSetId());
488        if (res != OK) {
489            ALOGE("%s: Unable to unregister stream %d from buffer manager "
490                    "(error %d %s)", __FUNCTION__, mId, res, strerror(-res));
491            mState = STATE_ERROR;
492            return res;
493        }
494        // Note that, to make prepare/teardown case work, we must not mBufferManager.clear(), as
495        // the stream is still in usable state after this call.
496        mUseBufferManager = false;
497    }
498
499    mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG
500                                           : STATE_CONSTRUCTED;
501    return OK;
502}
503
504status_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) const {
505
506    status_t res;
507    int32_t u = 0;
508    res = static_cast<ANativeWindow*>(mConsumer.get())->query(mConsumer.get(),
509            NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u);
510
511    // If an opaque output stream's endpoint is ImageReader, add
512    // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
513    // for the ZSL use case.
514    // Assume it's for ImageReader if the consumer usage doesn't have any of these bits set:
515    //     1. GRALLOC_USAGE_HW_TEXTURE
516    //     2. GRALLOC_USAGE_HW_RENDER
517    //     3. GRALLOC_USAGE_HW_COMPOSER
518    //     4. GRALLOC_USAGE_HW_VIDEO_ENCODER
519    if (camera3_stream::format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
520            (u & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
521            GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) {
522        u |= GRALLOC_USAGE_HW_CAMERA_ZSL;
523    }
524
525    *usage = u;
526    return res;
527}
528
529bool Camera3OutputStream::isVideoStream() const {
530    uint32_t usage = 0;
531    status_t res = getEndpointUsage(&usage);
532    if (res != OK) {
533        ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
534        return false;
535    }
536
537    return (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0;
538}
539
540status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) {
541    Mutex::Autolock l(mLock);
542    if (mState != STATE_CONSTRUCTED) {
543        ALOGE("%s: this method can only be called when stream in in CONSTRUCTED state.",
544                __FUNCTION__);
545        return INVALID_OPERATION;
546    }
547    mBufferManager = bufferManager;
548
549    return OK;
550}
551
552void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
553    sp<Camera3OutputStream> stream = mParent.promote();
554    if (stream == nullptr) {
555        ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
556        return;
557    }
558
559    Mutex::Autolock l(stream->mLock);
560    if (!(stream->mUseBufferManager)) {
561        return;
562    }
563
564    sp<Fence> fence;
565    sp<GraphicBuffer> buffer;
566    int fenceFd = -1;
567    status_t res = stream->mConsumer->detachNextBuffer(&buffer, &fence);
568    if (res == NO_MEMORY) {
569        // This may rarely happen, which indicates that the released buffer was freed by other
570        // call (e.g., attachBuffer, dequeueBuffer etc.) before reaching here. We should notify the
571        // buffer manager that this buffer has been freed. It's not fatal, but should be avoided,
572        // therefore log a warning.
573        buffer = 0;
574        ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
575    } else if (res != OK) {
576        // Other errors are fatal.
577        ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
578        stream->mState = STATE_ERROR;
579        return;
580    }
581
582    if (fence!= 0 && fence->isValid()) {
583        fenceFd = fence->dup();
584    }
585    res = stream->mBufferManager->returnBufferForStream(stream->getId(), stream->getStreamSetId(),
586                buffer, fenceFd);
587    if (res != OK) {
588        ALOGE("%s: return buffer to buffer manager failed: %s (%d).", __FUNCTION__,
589                strerror(-res), res);
590       stream->mState = STATE_ERROR;
591    }
592}
593
594bool Camera3OutputStream::isConsumedByHWComposer() const {
595    uint32_t usage = 0;
596    status_t res = getEndpointUsage(&usage);
597    if (res != OK) {
598        ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
599        return false;
600    }
601
602    return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
603}
604
605}; // namespace camera3
606
607}; // namespace android
608