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), 40e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTransform(0), 41e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTraceFirstBuffer(true) { 42fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 43fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (mConsumer == NULL) { 44fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Consumer is NULL!", __FUNCTION__); 45fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mState = STATE_ERROR; 46fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 47fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 48fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 49fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville TalvalaCamera3OutputStream::Camera3OutputStream(int id, 50fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala sp<ANativeWindow> consumer, 51fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala uint32_t width, uint32_t height, size_t maxSize, int format) : 52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, 53e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin format), 54a55b545ef3d8624123efe0e04c2a7d3a30b56b48Igor Murashkin mConsumer(consumer), 55e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTransform(0), 56e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTraceFirstBuffer(true) { 57fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 58fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (format != HAL_PIXEL_FORMAT_BLOB) { 59fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__, 60fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala format); 61fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mState = STATE_ERROR; 62fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 63fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 64fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (mConsumer == NULL) { 65fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Consumer is NULL!", __FUNCTION__); 66fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mState = STATE_ERROR; 67fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 68fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 69fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 70e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, 71e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin uint32_t width, uint32_t height, 72e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin int format) : 73e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin Camera3IOStreamBase(id, type, width, height, 74e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin /*maxSize*/0, 75e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin format), 76e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin mTransform(0) { 77e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 78e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin // Subclasses expected to initialize mConsumer themselves 79e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin} 80e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 81e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 82fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville TalvalaCamera3OutputStream::~Camera3OutputStream() { 83fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala disconnectLocked(); 84fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 85fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 86fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { 87fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ATRACE_CALL(); 88fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala status_t res; 89fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin if ((res = getBufferPreconditionCheckLocked()) != OK) { 91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin return res; 92fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 93fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 94fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ANativeWindowBuffer* anb; 95fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala int fenceFd; 96fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 9715ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He /** 9815ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * Release the lock briefly to avoid deadlock for below scenario: 9915ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring(). 10015ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock. 10115ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable(). 10215ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock 10315ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * StreamingProcessor lock. 10415ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock 10515ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * and try to lock bufferQueue lock. 10615ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He * Then there is circular locking dependency. 107124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He */ 108124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He sp<ANativeWindow> currentConsumer = mConsumer; 109124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He mLock.unlock(); 110124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He 11115ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd); 11215ad2470b2f2ac34473eb568b606ad75e8e63ac6Zhijun He mLock.lock(); 113fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 114fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", 115fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, mId, strerror(-res), res); 116fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 117fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 118fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 1192fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin /** 1202fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * FenceFD now owned by HAL except in case of error, 1212fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin * in which case we reassign it to acquire_fence 1222fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin */ 123e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, 1246adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true); 125fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 126fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return OK; 127fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 128fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 129fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::returnBufferLocked( 130fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala const camera3_stream_buffer &buffer, 131fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala nsecs_t timestamp) { 132fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ATRACE_CALL(); 133fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 134e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true); 135e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 136e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin if (res != OK) { 137e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin return res; 138fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 1395a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin 140fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mLastTimestamp = timestamp; 141fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 142fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return OK; 143fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 144fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3OutputStream::returnBufferCheckedLocked( 146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin const camera3_stream_buffer &buffer, 147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin nsecs_t timestamp, 148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin bool output, 149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin /*out*/ 150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin sp<Fence> *releaseFenceOut) { 151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin (void)output; 153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin ALOG_ASSERT(output, "Expected output to be true"); 154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin status_t res; 1565a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin sp<Fence> releaseFence; 1575a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin 1585a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin /** 1595a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin * Fence management - calculate Release Fence 1605a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin */ 161fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) { 1622fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin if (buffer.release_fence != -1) { 1632fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin ALOGE("%s: Stream %d: HAL should not set release_fence(%d) when " 1642fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin "there is an error", __FUNCTION__, mId, buffer.release_fence); 1652fba584544e8687b526e3388bf7160b696da1dbaIgor Murashkin close(buffer.release_fence); 166fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 1675a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin 1685a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin /** 1695a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin * Reassign release fence as the acquire fence in case of error 1705a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin */ 1715a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin releaseFence = new Fence(buffer.acquire_fence); 172fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } else { 173fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_buffers_timestamp(mConsumer.get(), timestamp); 174fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 175fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)", 176e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin __FUNCTION__, mId, strerror(-res), res); 177fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 178fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 179fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 1805a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin releaseFence = new Fence(buffer.release_fence); 1815a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin } 1825a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin 1835a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin int anwReleaseFence = releaseFence->dup(); 184fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 1855a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin /** 186124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He * Release the lock briefly to avoid deadlock with 187124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this 188124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He * thread will go into StreamingProcessor::onFrameAvailable) during 189124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He * queueBuffer 190124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He */ 191124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He sp<ANativeWindow> currentConsumer = mConsumer; 192124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He mLock.unlock(); 193124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He 194124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He /** 1955a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin * Return buffer back to ANativeWindow 1965a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin */ 1975a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) { 1985a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin // Cancel buffer 199124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He res = currentConsumer->cancelBuffer(currentConsumer.get(), 200fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala container_of(buffer.buffer, ANativeWindowBuffer, handle), 201fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala anwReleaseFence); 202fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 2035a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin ALOGE("%s: Stream %d: Error cancelling buffer to native window:" 204e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin " %s (%d)", __FUNCTION__, mId, strerror(-res), res); 2055a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin } 2065a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin } else { 207e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) { 208e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma { 209e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma char traceLog[48]; 210e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId); 211e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma ATRACE_NAME(traceLog); 212e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma } 213e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTraceFirstBuffer = false; 214e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma } 215e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma 216124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He res = currentConsumer->queueBuffer(currentConsumer.get(), 217fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala container_of(buffer.buffer, ANativeWindowBuffer, handle), 218fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala anwReleaseFence); 219fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin ALOGE("%s: Stream %d: Error queueing buffer to native window: " 221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 222fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 2235a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin } 224124ccf4b5023a40c57b49981123e6c9b61408a5dZhijun He mLock.lock(); 2255a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin if (res != OK) { 2265a1798ad24c73212c6614cf9f11de5fa86a20148Igor Murashkin close(anwReleaseFence); 227fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 228fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin *releaseFenceOut = releaseFence; 230fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 231f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala return res; 232fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 233fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 234fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalavoid Camera3OutputStream::dump(int fd, const Vector<String16> &args) const { 235fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala (void) args; 236fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala String8 lines; 237fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala lines.appendFormat(" Stream[%d]: Output\n", mId); 238fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala write(fd, lines.string(), lines.size()); 239e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 240e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin Camera3IOStreamBase::dump(fd, args); 241fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 242fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 243fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::setTransform(int transform) { 244fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ATRACE_CALL(); 245fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala Mutex::Autolock l(mLock); 246fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return setTransformLocked(transform); 247fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 248fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 249fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::setTransformLocked(int transform) { 250fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala status_t res = OK; 251fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (mState == STATE_ERROR) { 252fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Stream in error state", __FUNCTION__); 253fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return INVALID_OPERATION; 254fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 255fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 256fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mTransform = transform; 257fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (mState == STATE_CONFIGURED) { 258fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_buffers_transform(mConsumer.get(), 259fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala transform); 260fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 261fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 262fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, transform, strerror(-res), res); 263fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 264fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 265fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 266fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 267fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 268fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::configureQueueLocked() { 269fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala status_t res; 270fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 271e0711f2651121754a10c784e3b149024d17fa4d5Ruchit Sharma mTraceFirstBuffer = true; 272e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) { 273e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin return res; 274fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 275fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 276e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL"); 277e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin 278fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala // Configure consumer-side ANativeWindow interface 279fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_api_connect(mConsumer.get(), 280fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala NATIVE_WINDOW_API_CAMERA); 281fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 282fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to connect to native window for stream %d", 283fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, mId); 284fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 285fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 286fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 287fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_usage(mConsumer.get(), camera3_stream::usage); 288fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 289fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to configure usage %08x for stream %d", 290fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, camera3_stream::usage, mId); 291fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 292fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 293fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 294fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_scaling_mode(mConsumer.get(), 295fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 296fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 297fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to configure stream scaling: %s (%d)", 298fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, strerror(-res), res); 299fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 300fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 301fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 302fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (mMaxSize == 0) { 303fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala // For buffers of known size 3047d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala res = native_window_set_buffers_dimensions(mConsumer.get(), 3057d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala camera3_stream::width, camera3_stream::height); 306fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } else { 307fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala // For buffers with bounded size 3087d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala res = native_window_set_buffers_dimensions(mConsumer.get(), 3097d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala mMaxSize, 1); 310fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 311fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 3127d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala ALOGE("%s: Unable to configure stream buffer dimensions" 3137d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala " %d x %d (maxSize %zu) for stream %d", 314fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, camera3_stream::width, camera3_stream::height, 3157d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala mMaxSize, mId); 3167d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala return res; 3177d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala } 3187d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala res = native_window_set_buffers_format(mConsumer.get(), 3197d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala camera3_stream::format); 3207d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala if (res != OK) { 3217d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala ALOGE("%s: Unable to configure stream buffer format %#x for stream %d", 3227d70c5e5fe787ae5d7af8830864d208749d6337fEino-Ville Talvala __FUNCTION__, camera3_stream::format, mId); 323fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 324fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 325fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 326fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala int maxConsumerBuffers; 327fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = mConsumer->query(mConsumer.get(), 328fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 329fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 330fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to query consumer undequeued" 331fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala " buffer count for stream %d", __FUNCTION__, mId); 332fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 333fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 334fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 33520cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__, 33620cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray maxConsumerBuffers, camera3_stream::max_buffers); 33720cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray if (camera3_stream::max_buffers == 0) { 3382ab500c632569e2f131a1a2288459933da70c4eeZhijun He ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1", 33920cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray __FUNCTION__, camera3_stream::max_buffers); 34020cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray return INVALID_OPERATION; 34120cb300bce9a2b80966a422ef2de35b18533e1ddAlex Ray } 342fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 343fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers; 3446adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He mHandoutTotalBufferCount = 0; 345fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mFrameCount = 0; 346fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mLastTimestamp = 0; 347fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 348fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_buffer_count(mConsumer.get(), 349fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mTotalBufferCount); 350fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 351fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to set buffer count for stream %d", 352fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, mId); 353fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 354fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 355fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 356fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala res = native_window_set_buffers_transform(mConsumer.get(), 357fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mTransform); 358fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res != OK) { 359fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 360fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala __FUNCTION__, mTransform, strerror(-res), res); 361fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 362fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 363fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return OK; 364fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 365fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 366fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvalastatus_t Camera3OutputStream::disconnectLocked() { 367fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala status_t res; 368fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 369e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) { 370e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin return res; 371fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 372fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 373e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin res = native_window_api_disconnect(mConsumer.get(), 374e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin NATIVE_WINDOW_API_CAMERA); 375fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 376fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala /** 377fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * This is not an error. if client calling process dies, the window will 378fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * also die and all calls to it will return DEAD_OBJECT, thus it's already 379fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala * "disconnected" 380fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala */ 381fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala if (res == DEAD_OBJECT) { 382fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala ALOGW("%s: While disconnecting stream %d from native window, the" 383fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala " native window died from under us", __FUNCTION__, mId); 384fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 385fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala else if (res != OK) { 386e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin ALOGE("%s: Unable to disconnect stream %d from native window " 387e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin "(error %d %s)", 388e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin __FUNCTION__, mId, res, strerror(-res)); 389fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala mState = STATE_ERROR; 390fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return res; 391fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala } 392fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 393e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG 394e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin : STATE_CONSTRUCTED; 395fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala return OK; 396fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala} 397fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 398b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvalastatus_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) { 399b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala 400b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala status_t res; 401b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala int32_t u = 0; 402b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala res = mConsumer->query(mConsumer.get(), 403b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u); 404b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala *usage = u; 405b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala 406b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala return res; 407b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala} 408b2f5b19e5b6e1408a259add23dba91037756a943Eino-Ville Talvala 409fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}; // namespace camera3 410fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala 411fd58f1a10a749ca72fec1012920d6e94a664cd70Eino-Ville Talvala}; // namespace android 412