Camera3Stream.cpp revision 5a269fa72b419e7fe4bf6bf9b27eec8782b3a963
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera3-Stream" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23#include "Camera3Stream.h" 24 25namespace android { 26 27namespace camera3 { 28 29Camera3Stream::~Camera3Stream() { 30} 31 32Camera3Stream* Camera3Stream::cast(camera3_stream *stream) { 33 return static_cast<Camera3Stream*>(stream); 34} 35 36const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { 37 return static_cast<const Camera3Stream*>(stream); 38} 39 40Camera3Stream::Camera3Stream(int id, 41 camera3_stream_type type, 42 uint32_t width, uint32_t height, size_t maxSize, int format) : 43 camera3_stream(), 44 mId(id), 45 mName(String8::format("Camera3Stream[%d]", id)), 46 mMaxSize(maxSize), 47 mState(STATE_CONSTRUCTED) { 48 49 camera3_stream::stream_type = type; 50 camera3_stream::width = width; 51 camera3_stream::height = height; 52 camera3_stream::format = format; 53 camera3_stream::usage = 0; 54 camera3_stream::max_buffers = 0; 55 camera3_stream::priv = NULL; 56 57 if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) { 58 ALOGE("%s: BLOB format with size == 0", __FUNCTION__); 59 mState = STATE_ERROR; 60 } 61} 62 63int Camera3Stream::getId() const { 64 return mId; 65} 66 67uint32_t Camera3Stream::getWidth() const { 68 return camera3_stream::width; 69} 70 71uint32_t Camera3Stream::getHeight() const { 72 return camera3_stream::height; 73} 74 75int Camera3Stream::getFormat() const { 76 return camera3_stream::format; 77} 78 79camera3_stream* Camera3Stream::startConfiguration() { 80 Mutex::Autolock l(mLock); 81 82 switch (mState) { 83 case STATE_ERROR: 84 ALOGE("%s: In error state", __FUNCTION__); 85 return NULL; 86 case STATE_CONSTRUCTED: 87 // OK 88 break; 89 case STATE_IN_CONFIG: 90 case STATE_IN_RECONFIG: 91 // Can start config again with no trouble; but don't redo 92 // oldUsage/oldMaxBuffers 93 return this; 94 case STATE_CONFIGURED: 95 if (stream_type == CAMERA3_STREAM_INPUT) { 96 ALOGE("%s: Cannot configure an input stream twice", 97 __FUNCTION__); 98 return NULL; 99 } else if (hasOutstandingBuffersLocked()) { 100 ALOGE("%s: Cannot configure stream; has outstanding buffers", 101 __FUNCTION__); 102 return NULL; 103 } 104 break; 105 default: 106 ALOGE("%s: Unknown state %d", __FUNCTION__, mState); 107 return NULL; 108 } 109 110 oldUsage = usage; 111 oldMaxBuffers = max_buffers; 112 113 if (mState == STATE_CONSTRUCTED) { 114 mState = STATE_IN_CONFIG; 115 } else { // mState == STATE_CONFIGURED 116 mState = STATE_IN_RECONFIG; 117 } 118 119 return this; 120} 121 122bool Camera3Stream::isConfiguring() const { 123 Mutex::Autolock l(mLock); 124 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG); 125} 126 127status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) { 128 Mutex::Autolock l(mLock); 129 switch (mState) { 130 case STATE_ERROR: 131 ALOGE("%s: In error state", __FUNCTION__); 132 return INVALID_OPERATION; 133 case STATE_IN_CONFIG: 134 case STATE_IN_RECONFIG: 135 // OK 136 break; 137 case STATE_CONSTRUCTED: 138 case STATE_CONFIGURED: 139 ALOGE("%s: Cannot finish configuration that hasn't been started", 140 __FUNCTION__); 141 return INVALID_OPERATION; 142 default: 143 ALOGE("%s: Unknown state", __FUNCTION__); 144 return INVALID_OPERATION; 145 } 146 147 // Check if the stream configuration is unchanged, and skip reallocation if 148 // so. As documented in hardware/camera3.h:configure_streams(). 149 if (mState == STATE_IN_RECONFIG && 150 oldUsage == usage && 151 oldMaxBuffers == max_buffers) { 152 mState = STATE_CONFIGURED; 153 return OK; 154 } 155 156 status_t res; 157 res = configureQueueLocked(); 158 if (res != OK) { 159 ALOGE("%s: Unable to configure stream %d queue: %s (%d)", 160 __FUNCTION__, mId, strerror(-res), res); 161 mState = STATE_ERROR; 162 return res; 163 } 164 165 res = registerBuffersLocked(hal3Device); 166 if (res != OK) { 167 ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)", 168 __FUNCTION__, strerror(-res), res); 169 mState = STATE_ERROR; 170 return res; 171 } 172 173 mState = STATE_CONFIGURED; 174 175 return res; 176} 177 178status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { 179 ATRACE_CALL(); 180 Mutex::Autolock l(mLock); 181 return getBufferLocked(buffer); 182} 183 184status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, 185 nsecs_t timestamp) { 186 ATRACE_CALL(); 187 Mutex::Autolock l(mLock); 188 return returnBufferLocked(buffer, timestamp); 189} 190 191status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) { 192 ATRACE_CALL(); 193 Mutex::Autolock l(mLock); 194 return getInputBufferLocked(buffer); 195} 196 197status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) { 198 ATRACE_CALL(); 199 Mutex::Autolock l(mLock); 200 return returnInputBufferLocked(buffer); 201} 202 203bool Camera3Stream::hasOutstandingBuffers() const { 204 ATRACE_CALL(); 205 Mutex::Autolock l(mLock); 206 return hasOutstandingBuffersLocked(); 207} 208 209status_t Camera3Stream::disconnect() { 210 ATRACE_CALL(); 211 Mutex::Autolock l(mLock); 212 return disconnectLocked(); 213} 214 215status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { 216 ATRACE_CALL(); 217 status_t res; 218 219 size_t bufferCount = getBufferCountLocked(); 220 221 Vector<buffer_handle_t*> buffers; 222 buffers.insertAt(NULL, 0, bufferCount); 223 224 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); 225 bufferSet.stream = this; 226 bufferSet.num_buffers = bufferCount; 227 bufferSet.buffers = buffers.editArray(); 228 229 Vector<camera3_stream_buffer_t> streamBuffers; 230 streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount); 231 232 // Register all buffers with the HAL. This means getting all the buffers 233 // from the stream, providing them to the HAL with the 234 // register_stream_buffers() method, and then returning them back to the 235 // stream in the error state, since they won't have valid data. 236 // 237 // Only registered buffers can be sent to the HAL. 238 239 uint32_t bufferIdx = 0; 240 for (; bufferIdx < bufferCount; bufferIdx++) { 241 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); 242 if (res != OK) { 243 ALOGE("%s: Unable to get buffer %d for registration with HAL", 244 __FUNCTION__, bufferIdx); 245 // Skip registering, go straight to cleanup 246 break; 247 } 248 249 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); 250 fence->waitForever(kRegisterFenceTimeoutMs, 251 "Camera3Stream::registerBuffers"); 252 253 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; 254 } 255 if (bufferIdx == bufferCount) { 256 // Got all buffers, register with HAL 257 ALOGV("%s: Registering %d buffers with camera HAL", 258 __FUNCTION__, bufferCount); 259 res = hal3Device->ops->register_stream_buffers(hal3Device, 260 &bufferSet); 261 } 262 263 // Return all valid buffers to stream, in ERROR state to indicate 264 // they weren't filled. 265 for (size_t i = 0; i < bufferIdx; i++) { 266 streamBuffers.editItemAt(i).release_fence = -1; 267 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 268 returnBufferLocked(streamBuffers[i], 0); 269 } 270 271 return res; 272} 273 274status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) { 275 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 276 return INVALID_OPERATION; 277} 278status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &, 279 nsecs_t) { 280 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 281 return INVALID_OPERATION; 282} 283status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) { 284 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 285 return INVALID_OPERATION; 286} 287status_t Camera3Stream::returnInputBufferLocked( 288 const camera3_stream_buffer &) { 289 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 290 return INVALID_OPERATION; 291} 292 293}; // namespace camera3 294 295}; // namespace android 296