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 "device3/Camera3Stream.h" 24 #include "device3/StatusTracker.h" 25 26 namespace android { 27 28 namespace camera3 { 29 30 Camera3Stream::~Camera3Stream() { 31 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 32 if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) { 33 statusTracker->removeComponent(mStatusId); 34 } 35 } 36 37 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) { 38 return static_cast<Camera3Stream*>(stream); 39 } 40 41 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { 42 return static_cast<const Camera3Stream*>(stream); 43 } 44 45 Camera3Stream::Camera3Stream(int id, 46 camera3_stream_type type, 47 uint32_t width, uint32_t height, size_t maxSize, int format) : 48 camera3_stream(), 49 mId(id), 50 mName(String8::format("Camera3Stream[%d]", id)), 51 mMaxSize(maxSize), 52 mState(STATE_CONSTRUCTED), 53 mStatusId(StatusTracker::NO_STATUS_ID) { 54 55 camera3_stream::stream_type = type; 56 camera3_stream::width = width; 57 camera3_stream::height = height; 58 camera3_stream::format = format; 59 camera3_stream::usage = 0; 60 camera3_stream::max_buffers = 0; 61 camera3_stream::priv = NULL; 62 63 if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) { 64 ALOGE("%s: BLOB format with size == 0", __FUNCTION__); 65 mState = STATE_ERROR; 66 } 67 } 68 69 int Camera3Stream::getId() const { 70 return mId; 71 } 72 73 uint32_t Camera3Stream::getWidth() const { 74 return camera3_stream::width; 75 } 76 77 uint32_t Camera3Stream::getHeight() const { 78 return camera3_stream::height; 79 } 80 81 int Camera3Stream::getFormat() const { 82 return camera3_stream::format; 83 } 84 85 camera3_stream* Camera3Stream::startConfiguration() { 86 ATRACE_CALL(); 87 Mutex::Autolock l(mLock); 88 status_t res; 89 90 switch (mState) { 91 case STATE_ERROR: 92 ALOGE("%s: In error state", __FUNCTION__); 93 return NULL; 94 case STATE_CONSTRUCTED: 95 // OK 96 break; 97 case STATE_IN_CONFIG: 98 case STATE_IN_RECONFIG: 99 // Can start config again with no trouble; but don't redo 100 // oldUsage/oldMaxBuffers 101 return this; 102 case STATE_CONFIGURED: 103 if (stream_type == CAMERA3_STREAM_INPUT) { 104 ALOGE("%s: Cannot configure an input stream twice", 105 __FUNCTION__); 106 return NULL; 107 } else if (hasOutstandingBuffersLocked()) { 108 ALOGE("%s: Cannot configure stream; has outstanding buffers", 109 __FUNCTION__); 110 return NULL; 111 } 112 break; 113 default: 114 ALOGE("%s: Unknown state %d", __FUNCTION__, mState); 115 return NULL; 116 } 117 118 oldUsage = camera3_stream::usage; 119 oldMaxBuffers = camera3_stream::max_buffers; 120 121 res = getEndpointUsage(&(camera3_stream::usage)); 122 if (res != OK) { 123 ALOGE("%s: Cannot query consumer endpoint usage!", 124 __FUNCTION__); 125 return NULL; 126 } 127 128 // Stop tracking if currently doing so 129 if (mStatusId != StatusTracker::NO_STATUS_ID) { 130 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 131 if (statusTracker != 0) { 132 statusTracker->removeComponent(mStatusId); 133 } 134 mStatusId = StatusTracker::NO_STATUS_ID; 135 } 136 137 if (mState == STATE_CONSTRUCTED) { 138 mState = STATE_IN_CONFIG; 139 } else { // mState == STATE_CONFIGURED 140 mState = STATE_IN_RECONFIG; 141 } 142 143 return this; 144 } 145 146 bool Camera3Stream::isConfiguring() const { 147 Mutex::Autolock l(mLock); 148 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG); 149 } 150 151 status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) { 152 ATRACE_CALL(); 153 Mutex::Autolock l(mLock); 154 switch (mState) { 155 case STATE_ERROR: 156 ALOGE("%s: In error state", __FUNCTION__); 157 return INVALID_OPERATION; 158 case STATE_IN_CONFIG: 159 case STATE_IN_RECONFIG: 160 // OK 161 break; 162 case STATE_CONSTRUCTED: 163 case STATE_CONFIGURED: 164 ALOGE("%s: Cannot finish configuration that hasn't been started", 165 __FUNCTION__); 166 return INVALID_OPERATION; 167 default: 168 ALOGE("%s: Unknown state", __FUNCTION__); 169 return INVALID_OPERATION; 170 } 171 172 // Register for idle tracking 173 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 174 if (statusTracker != 0) { 175 mStatusId = statusTracker->addComponent(); 176 } 177 178 // Check if the stream configuration is unchanged, and skip reallocation if 179 // so. As documented in hardware/camera3.h:configure_streams(). 180 if (mState == STATE_IN_RECONFIG && 181 oldUsage == camera3_stream::usage && 182 oldMaxBuffers == camera3_stream::max_buffers) { 183 mState = STATE_CONFIGURED; 184 return OK; 185 } 186 187 status_t res; 188 res = configureQueueLocked(); 189 if (res != OK) { 190 ALOGE("%s: Unable to configure stream %d queue: %s (%d)", 191 __FUNCTION__, mId, strerror(-res), res); 192 mState = STATE_ERROR; 193 return res; 194 } 195 196 res = registerBuffersLocked(hal3Device); 197 if (res != OK) { 198 ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)", 199 __FUNCTION__, strerror(-res), res); 200 mState = STATE_ERROR; 201 return res; 202 } 203 204 mState = STATE_CONFIGURED; 205 206 return res; 207 } 208 209 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { 210 ATRACE_CALL(); 211 Mutex::Autolock l(mLock); 212 213 status_t res = getBufferLocked(buffer); 214 if (res == OK) { 215 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); 216 } 217 218 return res; 219 } 220 221 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, 222 nsecs_t timestamp) { 223 ATRACE_CALL(); 224 Mutex::Autolock l(mLock); 225 226 status_t res = returnBufferLocked(buffer, timestamp); 227 if (res == OK) { 228 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); 229 } 230 231 return res; 232 } 233 234 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) { 235 ATRACE_CALL(); 236 Mutex::Autolock l(mLock); 237 238 status_t res = getInputBufferLocked(buffer); 239 if (res == OK) { 240 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false); 241 } 242 243 return res; 244 } 245 246 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) { 247 ATRACE_CALL(); 248 Mutex::Autolock l(mLock); 249 250 status_t res = returnInputBufferLocked(buffer); 251 if (res == OK) { 252 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false); 253 } 254 return res; 255 } 256 257 void Camera3Stream::fireBufferListenersLocked( 258 const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) { 259 List<wp<Camera3StreamBufferListener> >::iterator it, end; 260 261 // TODO: finish implementing 262 263 Camera3StreamBufferListener::BufferInfo info = 264 Camera3StreamBufferListener::BufferInfo(); 265 info.mOutput = output; 266 // TODO: rest of fields 267 268 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 269 it != end; 270 ++it) { 271 272 sp<Camera3StreamBufferListener> listener = it->promote(); 273 if (listener != 0) { 274 if (acquired) { 275 listener->onBufferAcquired(info); 276 } else { 277 listener->onBufferReleased(info); 278 } 279 } 280 } 281 } 282 283 bool Camera3Stream::hasOutstandingBuffers() const { 284 ATRACE_CALL(); 285 Mutex::Autolock l(mLock); 286 return hasOutstandingBuffersLocked(); 287 } 288 289 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) { 290 Mutex::Autolock l(mLock); 291 sp<StatusTracker> oldTracker = mStatusTracker.promote(); 292 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) { 293 oldTracker->removeComponent(mStatusId); 294 } 295 mStatusId = StatusTracker::NO_STATUS_ID; 296 mStatusTracker = statusTracker; 297 298 return OK; 299 } 300 301 status_t Camera3Stream::disconnect() { 302 ATRACE_CALL(); 303 Mutex::Autolock l(mLock); 304 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId); 305 status_t res = disconnectLocked(); 306 307 if (res == -ENOTCONN) { 308 // "Already disconnected" -- not an error 309 return OK; 310 } else { 311 return res; 312 } 313 } 314 315 status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { 316 ATRACE_CALL(); 317 status_t res; 318 319 size_t bufferCount = getBufferCountLocked(); 320 321 Vector<buffer_handle_t*> buffers; 322 buffers.insertAt(NULL, 0, bufferCount); 323 324 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); 325 bufferSet.stream = this; 326 bufferSet.num_buffers = bufferCount; 327 bufferSet.buffers = buffers.editArray(); 328 329 Vector<camera3_stream_buffer_t> streamBuffers; 330 streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount); 331 332 // Register all buffers with the HAL. This means getting all the buffers 333 // from the stream, providing them to the HAL with the 334 // register_stream_buffers() method, and then returning them back to the 335 // stream in the error state, since they won't have valid data. 336 // 337 // Only registered buffers can be sent to the HAL. 338 339 uint32_t bufferIdx = 0; 340 for (; bufferIdx < bufferCount; bufferIdx++) { 341 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); 342 if (res != OK) { 343 ALOGE("%s: Unable to get buffer %d for registration with HAL", 344 __FUNCTION__, bufferIdx); 345 // Skip registering, go straight to cleanup 346 break; 347 } 348 349 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); 350 fence->waitForever("Camera3Stream::registerBuffers"); 351 352 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; 353 } 354 if (bufferIdx == bufferCount) { 355 // Got all buffers, register with HAL 356 ALOGV("%s: Registering %d buffers with camera HAL", 357 __FUNCTION__, bufferCount); 358 ATRACE_BEGIN("camera3->register_stream_buffers"); 359 res = hal3Device->ops->register_stream_buffers(hal3Device, 360 &bufferSet); 361 ATRACE_END(); 362 } 363 364 // Return all valid buffers to stream, in ERROR state to indicate 365 // they weren't filled. 366 for (size_t i = 0; i < bufferIdx; i++) { 367 streamBuffers.editItemAt(i).release_fence = -1; 368 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 369 returnBufferLocked(streamBuffers[i], 0); 370 } 371 372 return res; 373 } 374 375 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) { 376 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 377 return INVALID_OPERATION; 378 } 379 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &, 380 nsecs_t) { 381 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 382 return INVALID_OPERATION; 383 } 384 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) { 385 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 386 return INVALID_OPERATION; 387 } 388 status_t Camera3Stream::returnInputBufferLocked( 389 const camera3_stream_buffer &) { 390 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 391 return INVALID_OPERATION; 392 } 393 394 void Camera3Stream::addBufferListener( 395 wp<Camera3StreamBufferListener> listener) { 396 Mutex::Autolock l(mLock); 397 mBufferListenerList.push_back(listener); 398 } 399 400 void Camera3Stream::removeBufferListener( 401 const sp<Camera3StreamBufferListener>& listener) { 402 Mutex::Autolock l(mLock); 403 404 bool erased = true; 405 List<wp<Camera3StreamBufferListener> >::iterator it, end; 406 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 407 it != end; 408 ) { 409 410 if (*it == listener) { 411 it = mBufferListenerList.erase(it); 412 erased = true; 413 } else { 414 ++it; 415 } 416 } 417 418 if (!erased) { 419 ALOGW("%s: Could not find listener to remove, already removed", 420 __FUNCTION__); 421 } 422 } 423 424 }; // namespace camera3 425 426 }; // namespace android 427