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 25 namespace android { 26 27 namespace camera3 { 28 29 Camera3Stream::~Camera3Stream() { 30 } 31 32 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) { 33 return static_cast<Camera3Stream*>(stream); 34 } 35 36 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { 37 return static_cast<const Camera3Stream*>(stream); 38 } 39 40 Camera3Stream::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 63 int Camera3Stream::getId() const { 64 return mId; 65 } 66 67 uint32_t Camera3Stream::getWidth() const { 68 return camera3_stream::width; 69 } 70 71 uint32_t Camera3Stream::getHeight() const { 72 return camera3_stream::height; 73 } 74 75 int Camera3Stream::getFormat() const { 76 return camera3_stream::format; 77 } 78 79 camera3_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 122 bool Camera3Stream::isConfiguring() const { 123 Mutex::Autolock l(mLock); 124 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG); 125 } 126 127 status_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 178 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { 179 ATRACE_CALL(); 180 Mutex::Autolock l(mLock); 181 182 status_t res = getBufferLocked(buffer); 183 if (res == OK) { 184 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); 185 } 186 187 return res; 188 } 189 190 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, 191 nsecs_t timestamp) { 192 ATRACE_CALL(); 193 Mutex::Autolock l(mLock); 194 195 status_t res = returnBufferLocked(buffer, timestamp); 196 if (res == OK) { 197 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); 198 } 199 200 return res; 201 } 202 203 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) { 204 ATRACE_CALL(); 205 Mutex::Autolock l(mLock); 206 207 status_t res = getInputBufferLocked(buffer); 208 if (res == OK) { 209 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false); 210 } 211 212 return res; 213 } 214 215 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) { 216 ATRACE_CALL(); 217 Mutex::Autolock l(mLock); 218 219 status_t res = returnInputBufferLocked(buffer); 220 if (res == OK) { 221 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false); 222 } 223 return res; 224 } 225 226 void Camera3Stream::fireBufferListenersLocked( 227 const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) { 228 List<wp<Camera3StreamBufferListener> >::iterator it, end; 229 230 // TODO: finish implementing 231 232 Camera3StreamBufferListener::BufferInfo info = 233 Camera3StreamBufferListener::BufferInfo(); 234 info.mOutput = output; 235 // TODO: rest of fields 236 237 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 238 it != end; 239 ++it) { 240 241 sp<Camera3StreamBufferListener> listener = it->promote(); 242 if (listener != 0) { 243 if (acquired) { 244 listener->onBufferAcquired(info); 245 } else { 246 listener->onBufferReleased(info); 247 } 248 } 249 } 250 } 251 252 bool Camera3Stream::hasOutstandingBuffers() const { 253 ATRACE_CALL(); 254 Mutex::Autolock l(mLock); 255 return hasOutstandingBuffersLocked(); 256 } 257 258 status_t Camera3Stream::disconnect() { 259 ATRACE_CALL(); 260 Mutex::Autolock l(mLock); 261 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId); 262 status_t res = disconnectLocked(); 263 264 if (res == -ENOTCONN) { 265 // "Already disconnected" -- not an error 266 return OK; 267 } else { 268 return res; 269 } 270 } 271 272 status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { 273 ATRACE_CALL(); 274 status_t res; 275 276 size_t bufferCount = getBufferCountLocked(); 277 278 Vector<buffer_handle_t*> buffers; 279 buffers.insertAt(NULL, 0, bufferCount); 280 281 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); 282 bufferSet.stream = this; 283 bufferSet.num_buffers = bufferCount; 284 bufferSet.buffers = buffers.editArray(); 285 286 Vector<camera3_stream_buffer_t> streamBuffers; 287 streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount); 288 289 // Register all buffers with the HAL. This means getting all the buffers 290 // from the stream, providing them to the HAL with the 291 // register_stream_buffers() method, and then returning them back to the 292 // stream in the error state, since they won't have valid data. 293 // 294 // Only registered buffers can be sent to the HAL. 295 296 uint32_t bufferIdx = 0; 297 for (; bufferIdx < bufferCount; bufferIdx++) { 298 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); 299 if (res != OK) { 300 ALOGE("%s: Unable to get buffer %d for registration with HAL", 301 __FUNCTION__, bufferIdx); 302 // Skip registering, go straight to cleanup 303 break; 304 } 305 306 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); 307 fence->waitForever("Camera3Stream::registerBuffers"); 308 309 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; 310 } 311 if (bufferIdx == bufferCount) { 312 // Got all buffers, register with HAL 313 ALOGV("%s: Registering %d buffers with camera HAL", 314 __FUNCTION__, bufferCount); 315 res = hal3Device->ops->register_stream_buffers(hal3Device, 316 &bufferSet); 317 } 318 319 // Return all valid buffers to stream, in ERROR state to indicate 320 // they weren't filled. 321 for (size_t i = 0; i < bufferIdx; i++) { 322 streamBuffers.editItemAt(i).release_fence = -1; 323 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 324 returnBufferLocked(streamBuffers[i], 0); 325 } 326 327 return res; 328 } 329 330 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) { 331 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 332 return INVALID_OPERATION; 333 } 334 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &, 335 nsecs_t) { 336 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 337 return INVALID_OPERATION; 338 } 339 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) { 340 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 341 return INVALID_OPERATION; 342 } 343 status_t Camera3Stream::returnInputBufferLocked( 344 const camera3_stream_buffer &) { 345 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 346 return INVALID_OPERATION; 347 } 348 349 void Camera3Stream::addBufferListener( 350 wp<Camera3StreamBufferListener> listener) { 351 Mutex::Autolock l(mLock); 352 mBufferListenerList.push_back(listener); 353 } 354 355 void Camera3Stream::removeBufferListener( 356 const sp<Camera3StreamBufferListener>& listener) { 357 Mutex::Autolock l(mLock); 358 359 bool erased = true; 360 List<wp<Camera3StreamBufferListener> >::iterator it, end; 361 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 362 it != end; 363 ) { 364 365 if (*it == listener) { 366 it = mBufferListenerList.erase(it); 367 erased = true; 368 } else { 369 ++it; 370 } 371 } 372 373 if (!erased) { 374 ALOGW("%s: Could not find listener to remove, already removed", 375 __FUNCTION__); 376 } 377 } 378 379 }; // namespace camera3 380 381 }; // namespace android 382