Camera3OutputStream.cpp revision 15ad2470b2f2ac34473eb568b606ad75e8e63ac6
1fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala/*
2fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project
3fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala *
4fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * you may not use this file except in compliance with the License.
6fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * You may obtain a copy of the License at
7fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala *
8fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala *
10fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * See the License for the specific language governing permissions and
14fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * limitations under the License.
15fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala */
16fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
17fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#define LOG_TAG "Camera3-OutputStream"
18fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
19fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala//#define LOG_NDEBUG 0
20fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
21fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#include <utils/Log.h>
22fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#include <utils/Trace.h>
23fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#include "Camera3OutputStream.h"
24fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
25fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#ifndef container_of
26fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#define container_of(ptr, type, member) \
27fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    (type *)((char*)(ptr) - offsetof(type, member))
28fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala#endif
29fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
30fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalanamespace android {
31fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
32fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalanamespace camera3 {
33fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
34fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville TalvalaCamera3OutputStream::Camera3OutputStream(int id,
35fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        sp<ANativeWindow> consumer,
36fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        uint32_t width, uint32_t height, int format) :
37e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
38e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            /*maxSize*/0, format),
39fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        mConsumer(consumer),
40e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mTransform(0) {
41fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
42fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (mConsumer == NULL) {
43fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Consumer is NULL!", __FUNCTION__);
44fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        mState = STATE_ERROR;
45fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
46fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
47fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
48fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville TalvalaCamera3OutputStream::Camera3OutputStream(int id,
49fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        sp<ANativeWindow> consumer,
50fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        uint32_t width, uint32_t height, size_t maxSize, int format) :
51e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize,
52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            format),
53a55b545ef3d8624123efe0e04c2a7d3a30b56b48Igor Murashkin        mConsumer(consumer),
54e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mTransform(0) {
55fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
56fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (format != HAL_PIXEL_FORMAT_BLOB) {
57fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
58fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                format);
59fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        mState = STATE_ERROR;
60fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
61fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
62fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (mConsumer == NULL) {
63fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Consumer is NULL!", __FUNCTION__);
64fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        mState = STATE_ERROR;
65fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
66fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
67fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
68e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
69e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                         uint32_t width, uint32_t height,
70e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                         int format) :
71e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3IOStreamBase(id, type, width, height,
72e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            /*maxSize*/0,
73e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            format),
74e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mTransform(0) {
75e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
76e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Subclasses expected to initialize mConsumer themselves
77e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
78e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
79e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
80fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville TalvalaCamera3OutputStream::~Camera3OutputStream() {
81fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    disconnectLocked();
82fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
83fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
84fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) {
85fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    ATRACE_CALL();
86fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    status_t res;
87fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
88e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = getBufferPreconditionCheckLocked()) != OK) {
89e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
90fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
91fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
92fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    ANativeWindowBuffer* anb;
93fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    int fenceFd;
94fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
9515ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He    /**
9615ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * Release the lock briefly to avoid deadlock for below scenario:
9715ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
9815ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
9915ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
10015ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
10115ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * StreamingProcessor lock.
10215ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
10315ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * and try to lock bufferQueue lock.
10415ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     * Then there is circular locking dependency.
10515ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He     */
10615ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He    sp<ANativeWindow> currentConsumer = mConsumer;
10715ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He    mLock.unlock();
10815ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He
10915ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He    res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd);
11015ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He    mLock.lock();
111fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
112fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
113fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, mId, strerror(-res), res);
114fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
115fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
116fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
117e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
118e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * FenceFD now owned by HAL except in case of error,
119e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * in which case we reassign it to acquire_fence
120e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
121e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
122e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                        /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK);
123fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
124fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    return OK;
125fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
126fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
127fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::returnBufferLocked(
128fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        const camera3_stream_buffer &buffer,
129fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        nsecs_t timestamp) {
130fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    ATRACE_CALL();
131fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
132e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
133e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
134e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (res != OK) {
135e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
136fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
1375a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin
138e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mLastTimestamp = timestamp;
139e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
140e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
141e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
142e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
143e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3OutputStream::returnBufferCheckedLocked(
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            const camera3_stream_buffer &buffer,
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            nsecs_t timestamp,
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            bool output,
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            /*out*/
148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            sp<Fence> *releaseFenceOut) {
149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    (void)output;
151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    ALOG_ASSERT(output, "Expected output to be true");
152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
1545a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    sp<Fence> releaseFence;
1555a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin
1565a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    /**
1575a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin     * Fence management - calculate Release Fence
1585a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin     */
159fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
1605a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        if (buffer.release_fence != -1) {
1615a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin            ALOGE("%s: Stream %d: HAL should not set release_fence(%d) when "
1625a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin                  "there is an error", __FUNCTION__, mId, buffer.release_fence);
1635a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin            close(buffer.release_fence);
164fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        }
1655a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin
1665a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        /**
1675a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin         * Reassign release fence as the acquire fence in case of error
1685a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin         */
1695a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        releaseFence = new Fence(buffer.acquire_fence);
170fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    } else {
171fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        res = native_window_set_buffers_timestamp(mConsumer.get(), timestamp);
172fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        if (res != OK) {
173fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
174e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                  __FUNCTION__, mId, strerror(-res), res);
175fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            return res;
176fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        }
177fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
1785a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        releaseFence = new Fence(buffer.release_fence);
1795a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    }
1805a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin
1815a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    int anwReleaseFence = releaseFence->dup();
182fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
1835a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    /**
184124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He     * Release the lock briefly to avoid deadlock with
185124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He     * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
186124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He     * thread will go into StreamingProcessor::onFrameAvailable) during
187124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He     * queueBuffer
188124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He     */
189124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He    sp<ANativeWindow> currentConsumer = mConsumer;
190124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He    mLock.unlock();
191124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He
192124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He    /**
1935a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin     * Return buffer back to ANativeWindow
1945a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin     */
1955a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
1965a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        // Cancel buffer
197124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He        res = currentConsumer->cancelBuffer(currentConsumer.get(),
1985a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin                container_of(buffer.buffer, ANativeWindowBuffer, handle),
1995a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin                anwReleaseFence);
2005a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        if (res != OK) {
2015a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin            ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                  " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
2035a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        }
2045a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    } else {
205124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He        res = currentConsumer->queueBuffer(currentConsumer.get(),
206fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                container_of(buffer.buffer, ANativeWindowBuffer, handle),
207fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                anwReleaseFence);
208fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        if (res != OK) {
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Stream %d: Error queueing buffer to native window: "
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                  "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
211fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        }
2125a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    }
213124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He    mLock.lock();
2145a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin    if (res != OK) {
2155a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin        close(anwReleaseFence);
216fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
217fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    *releaseFenceOut = releaseFence;
219fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
220f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    return res;
221fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
222fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
223fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalavoid Camera3OutputStream::dump(int fd, const Vector<String16> &args) const {
224fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    (void) args;
225fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    String8 lines;
226fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    lines.appendFormat("    Stream[%d]: Output\n", mId);
227fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    write(fd, lines.string(), lines.size());
228e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    Camera3IOStreamBase::dump(fd, args);
230fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
231fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
232fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::setTransform(int transform) {
233fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    ATRACE_CALL();
234fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    Mutex::Autolock l(mLock);
235fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    return setTransformLocked(transform);
236fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
237fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
238fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::setTransformLocked(int transform) {
239fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    status_t res = OK;
240fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (mState == STATE_ERROR) {
241fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Stream in error state", __FUNCTION__);
242fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return INVALID_OPERATION;
243fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
244fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
245fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    mTransform = transform;
246fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (mState == STATE_CONFIGURED) {
247fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        res = native_window_set_buffers_transform(mConsumer.get(),
248fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                transform);
249fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        if (res != OK) {
250fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
251fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                    __FUNCTION__, transform, strerror(-res), res);
252fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        }
253fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
254fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    return res;
255fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
256fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
257fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::configureQueueLocked() {
258fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    status_t res;
259fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
260e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
261e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
262fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
263fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
264e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");
265e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
266fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    // Configure consumer-side ANativeWindow interface
267fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = native_window_api_connect(mConsumer.get(),
268fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            NATIVE_WINDOW_API_CAMERA);
269fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
270fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to connect to native window for stream %d",
271fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, mId);
272fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
273fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
274fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
275fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
276fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
277fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to configure usage %08x for stream %d",
278fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, camera3_stream::usage, mId);
279fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
280fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
281fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
282fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = native_window_set_scaling_mode(mConsumer.get(),
283fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
284fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
285fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to configure stream scaling: %s (%d)",
286fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, strerror(-res), res);
287fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
288fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
289fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
290fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (mMaxSize == 0) {
291fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        // For buffers of known size
292fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        res = native_window_set_buffers_geometry(mConsumer.get(),
293fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                camera3_stream::width, camera3_stream::height,
294fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                camera3_stream::format);
295fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    } else {
296fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        // For buffers with bounded size
297fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        res = native_window_set_buffers_geometry(mConsumer.get(),
298fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                mMaxSize, 1,
299fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                camera3_stream::format);
300fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
301fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
302fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to configure stream buffer geometry"
303fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                " %d x %d, format %x for stream %d",
304fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, camera3_stream::width, camera3_stream::height,
305fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                camera3_stream::format, mId);
306fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
307fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
308fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
309fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    int maxConsumerBuffers;
310fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = mConsumer->query(mConsumer.get(),
311fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
312fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
313fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to query consumer undequeued"
314fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                " buffer count for stream %d", __FUNCTION__, mId);
315fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
316fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
317fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
31820cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray    ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
31920cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray            maxConsumerBuffers, camera3_stream::max_buffers);
32020cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray    if (camera3_stream::max_buffers == 0) {
3212ab500c632569e2f131a1a2288459933da70c4eeZhijun He        ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
32220cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray                __FUNCTION__, camera3_stream::max_buffers);
32320cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray        return INVALID_OPERATION;
32420cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray    }
325fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
326fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
327fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    mDequeuedBufferCount = 0;
328fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    mFrameCount = 0;
329fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    mLastTimestamp = 0;
330fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
331fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = native_window_set_buffer_count(mConsumer.get(),
332fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            mTotalBufferCount);
333fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
334fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to set buffer count for stream %d",
335fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, mId);
336fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
337fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
338fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
339fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    res = native_window_set_buffers_transform(mConsumer.get(),
340fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala            mTransform);
341fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res != OK) {
342fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
343fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                __FUNCTION__, mTransform, strerror(-res), res);
344fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
345fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
346fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    return OK;
347fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
348fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
349fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::disconnectLocked() {
350fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    status_t res;
351fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
352e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) {
353e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
354fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
355fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
356e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = native_window_api_disconnect(mConsumer.get(),
357e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                       NATIVE_WINDOW_API_CAMERA);
358fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
359fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    /**
360fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala     * This is not an error. if client calling process dies, the window will
361fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala     * also die and all calls to it will return DEAD_OBJECT, thus it's already
362fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala     * "disconnected"
363fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala     */
364fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    if (res == DEAD_OBJECT) {
365fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        ALOGW("%s: While disconnecting stream %d from native window, the"
366fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala                " native window died from under us", __FUNCTION__, mId);
367fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
368fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    else if (res != OK) {
369e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Unable to disconnect stream %d from native window "
370e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin              "(error %d %s)",
371e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin              __FUNCTION__, mId, res, strerror(-res));
372fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        mState = STATE_ERROR;
373fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala        return res;
374fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    }
375fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
376e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG
377e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                           : STATE_CONSTRUCTED;
378fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala    return OK;
379fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}
380fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
381b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvalastatus_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) {
382b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala
383b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala    status_t res;
384b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala    int32_t u = 0;
385b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala    res = mConsumer->query(mConsumer.get(),
386b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala            NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u);
387b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala    *usage = u;
388b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala
389b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala    return res;
390b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala}
391b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala
392fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}; // namespace camera3
393fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala
394fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}; // namespace android
395