Camera3Stream.cpp revision b97babb8c08969b55af3b6456d15f764c8873d3f
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#include <cutils/properties.h> 27 28namespace android { 29 30namespace camera3 { 31 32Camera3Stream::~Camera3Stream() { 33 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 34 if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) { 35 statusTracker->removeComponent(mStatusId); 36 } 37} 38 39Camera3Stream* Camera3Stream::cast(camera3_stream *stream) { 40 return static_cast<Camera3Stream*>(stream); 41} 42 43const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) { 44 return static_cast<const Camera3Stream*>(stream); 45} 46 47Camera3Stream::Camera3Stream(int id, 48 camera3_stream_type type, 49 uint32_t width, uint32_t height, size_t maxSize, int format, 50 android_dataspace dataSpace, camera3_stream_rotation_t rotation) : 51 camera3_stream(), 52 mId(id), 53 mName(String8::format("Camera3Stream[%d]", id)), 54 mMaxSize(maxSize), 55 mState(STATE_CONSTRUCTED), 56 mStatusId(StatusTracker::NO_STATUS_ID) { 57 58 camera3_stream::stream_type = type; 59 camera3_stream::width = width; 60 camera3_stream::height = height; 61 camera3_stream::format = format; 62 camera3_stream::data_space = dataSpace; 63 camera3_stream::rotation = rotation; 64 camera3_stream::usage = 0; 65 camera3_stream::max_buffers = 0; 66 camera3_stream::priv = NULL; 67 68 if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) { 69 ALOGE("%s: BLOB format with size == 0", __FUNCTION__); 70 mState = STATE_ERROR; 71 } 72} 73 74int Camera3Stream::getId() const { 75 return mId; 76} 77 78uint32_t Camera3Stream::getWidth() const { 79 return camera3_stream::width; 80} 81 82uint32_t Camera3Stream::getHeight() const { 83 return camera3_stream::height; 84} 85 86int Camera3Stream::getFormat() const { 87 return camera3_stream::format; 88} 89 90android_dataspace Camera3Stream::getDataSpace() const { 91 return camera3_stream::data_space; 92} 93 94camera3_stream* Camera3Stream::startConfiguration() { 95 ATRACE_CALL(); 96 Mutex::Autolock l(mLock); 97 status_t res; 98 99 switch (mState) { 100 case STATE_ERROR: 101 ALOGE("%s: In error state", __FUNCTION__); 102 return NULL; 103 case STATE_CONSTRUCTED: 104 // OK 105 break; 106 case STATE_IN_CONFIG: 107 case STATE_IN_RECONFIG: 108 // Can start config again with no trouble; but don't redo 109 // oldUsage/oldMaxBuffers 110 return this; 111 case STATE_CONFIGURED: 112 if (stream_type == CAMERA3_STREAM_INPUT) { 113 ALOGE("%s: Cannot configure an input stream twice", 114 __FUNCTION__); 115 return NULL; 116 } else if (hasOutstandingBuffersLocked()) { 117 ALOGE("%s: Cannot configure stream; has outstanding buffers", 118 __FUNCTION__); 119 return NULL; 120 } 121 break; 122 default: 123 ALOGE("%s: Unknown state %d", __FUNCTION__, mState); 124 return NULL; 125 } 126 127 oldUsage = camera3_stream::usage; 128 oldMaxBuffers = camera3_stream::max_buffers; 129 130 res = getEndpointUsage(&(camera3_stream::usage)); 131 if (res != OK) { 132 ALOGE("%s: Cannot query consumer endpoint usage!", 133 __FUNCTION__); 134 return NULL; 135 } 136 137 // Stop tracking if currently doing so 138 if (mStatusId != StatusTracker::NO_STATUS_ID) { 139 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 140 if (statusTracker != 0) { 141 statusTracker->removeComponent(mStatusId); 142 } 143 mStatusId = StatusTracker::NO_STATUS_ID; 144 } 145 146 if (mState == STATE_CONSTRUCTED) { 147 mState = STATE_IN_CONFIG; 148 } else { // mState == STATE_CONFIGURED 149 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState); 150 mState = STATE_IN_RECONFIG; 151 } 152 153 return this; 154} 155 156bool Camera3Stream::isConfiguring() const { 157 Mutex::Autolock l(mLock); 158 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG); 159} 160 161status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) { 162 ATRACE_CALL(); 163 Mutex::Autolock l(mLock); 164 switch (mState) { 165 case STATE_ERROR: 166 ALOGE("%s: In error state", __FUNCTION__); 167 return INVALID_OPERATION; 168 case STATE_IN_CONFIG: 169 case STATE_IN_RECONFIG: 170 // OK 171 break; 172 case STATE_CONSTRUCTED: 173 case STATE_CONFIGURED: 174 ALOGE("%s: Cannot finish configuration that hasn't been started", 175 __FUNCTION__); 176 return INVALID_OPERATION; 177 default: 178 ALOGE("%s: Unknown state", __FUNCTION__); 179 return INVALID_OPERATION; 180 } 181 182 // Register for idle tracking 183 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 184 if (statusTracker != 0) { 185 mStatusId = statusTracker->addComponent(); 186 } 187 188 // Check if the stream configuration is unchanged, and skip reallocation if 189 // so. As documented in hardware/camera3.h:configure_streams(). 190 if (mState == STATE_IN_RECONFIG && 191 oldUsage == camera3_stream::usage && 192 oldMaxBuffers == camera3_stream::max_buffers) { 193 mState = STATE_CONFIGURED; 194 return OK; 195 } 196 197 status_t res; 198 res = configureQueueLocked(); 199 if (res != OK) { 200 ALOGE("%s: Unable to configure stream %d queue: %s (%d)", 201 __FUNCTION__, mId, strerror(-res), res); 202 mState = STATE_ERROR; 203 return res; 204 } 205 206 res = registerBuffersLocked(hal3Device); 207 if (res != OK) { 208 ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)", 209 __FUNCTION__, strerror(-res), res); 210 mState = STATE_ERROR; 211 return res; 212 } 213 214 mState = STATE_CONFIGURED; 215 216 return res; 217} 218 219status_t Camera3Stream::cancelConfiguration() { 220 ATRACE_CALL(); 221 Mutex::Autolock l(mLock); 222 switch (mState) { 223 case STATE_ERROR: 224 ALOGE("%s: In error state", __FUNCTION__); 225 return INVALID_OPERATION; 226 case STATE_IN_CONFIG: 227 case STATE_IN_RECONFIG: 228 // OK 229 break; 230 case STATE_CONSTRUCTED: 231 case STATE_CONFIGURED: 232 ALOGE("%s: Cannot cancel configuration that hasn't been started", 233 __FUNCTION__); 234 return INVALID_OPERATION; 235 default: 236 ALOGE("%s: Unknown state", __FUNCTION__); 237 return INVALID_OPERATION; 238 } 239 240 camera3_stream::usage = oldUsage; 241 camera3_stream::max_buffers = oldMaxBuffers; 242 243 mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED; 244 return OK; 245} 246 247status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { 248 ATRACE_CALL(); 249 Mutex::Autolock l(mLock); 250 status_t res = OK; 251 252 // This function should be only called when the stream is configured already. 253 if (mState != STATE_CONFIGURED) { 254 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d", 255 __FUNCTION__, mId, mState); 256 return INVALID_OPERATION; 257 } 258 259 // Wait for new buffer returned back if we are running into the limit. 260 if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) { 261 ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.", 262 __FUNCTION__, camera3_stream::max_buffers); 263 res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); 264 if (res != OK) { 265 if (res == TIMED_OUT) { 266 ALOGE("%s: wait for output buffer return timed out after %lldms", __FUNCTION__, 267 kWaitForBufferDuration / 1000000LL); 268 } 269 return res; 270 } 271 } 272 273 res = getBufferLocked(buffer); 274 if (res == OK) { 275 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); 276 } 277 278 return res; 279} 280 281status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, 282 nsecs_t timestamp) { 283 ATRACE_CALL(); 284 Mutex::Autolock l(mLock); 285 286 /** 287 * TODO: Check that the state is valid first. 288 * 289 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED. 290 * >= HAL3.2 CONFIGURED only 291 * 292 * Do this for getBuffer as well. 293 */ 294 status_t res = returnBufferLocked(buffer, timestamp); 295 if (res == OK) { 296 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); 297 mOutputBufferReturnedSignal.signal(); 298 } 299 300 return res; 301} 302 303status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) { 304 ATRACE_CALL(); 305 Mutex::Autolock l(mLock); 306 status_t res = OK; 307 308 // This function should be only called when the stream is configured already. 309 if (mState != STATE_CONFIGURED) { 310 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d", 311 __FUNCTION__, mId, mState); 312 return INVALID_OPERATION; 313 } 314 315 // Wait for new buffer returned back if we are running into the limit. 316 if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers) { 317 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.", 318 __FUNCTION__, camera3_stream::max_buffers); 319 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); 320 if (res != OK) { 321 if (res == TIMED_OUT) { 322 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__, 323 kWaitForBufferDuration / 1000000LL); 324 } 325 return res; 326 } 327 } 328 329 res = getInputBufferLocked(buffer); 330 if (res == OK) { 331 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false); 332 } 333 334 return res; 335} 336 337status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) { 338 ATRACE_CALL(); 339 Mutex::Autolock l(mLock); 340 341 status_t res = returnInputBufferLocked(buffer); 342 if (res == OK) { 343 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false); 344 mInputBufferReturnedSignal.signal(); 345 } 346 return res; 347} 348 349void Camera3Stream::fireBufferListenersLocked( 350 const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) { 351 List<wp<Camera3StreamBufferListener> >::iterator it, end; 352 353 // TODO: finish implementing 354 355 Camera3StreamBufferListener::BufferInfo info = 356 Camera3StreamBufferListener::BufferInfo(); 357 info.mOutput = output; 358 // TODO: rest of fields 359 360 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 361 it != end; 362 ++it) { 363 364 sp<Camera3StreamBufferListener> listener = it->promote(); 365 if (listener != 0) { 366 if (acquired) { 367 listener->onBufferAcquired(info); 368 } else { 369 listener->onBufferReleased(info); 370 } 371 } 372 } 373} 374 375bool Camera3Stream::hasOutstandingBuffers() const { 376 ATRACE_CALL(); 377 Mutex::Autolock l(mLock); 378 return hasOutstandingBuffersLocked(); 379} 380 381status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) { 382 Mutex::Autolock l(mLock); 383 sp<StatusTracker> oldTracker = mStatusTracker.promote(); 384 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) { 385 oldTracker->removeComponent(mStatusId); 386 } 387 mStatusId = StatusTracker::NO_STATUS_ID; 388 mStatusTracker = statusTracker; 389 390 return OK; 391} 392 393status_t Camera3Stream::disconnect() { 394 ATRACE_CALL(); 395 Mutex::Autolock l(mLock); 396 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId); 397 status_t res = disconnectLocked(); 398 399 if (res == -ENOTCONN) { 400 // "Already disconnected" -- not an error 401 return OK; 402 } else { 403 return res; 404 } 405} 406 407status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { 408 ATRACE_CALL(); 409 410 /** 411 * >= CAMERA_DEVICE_API_VERSION_3_2: 412 * 413 * camera3_device_t->ops->register_stream_buffers() is not called and must 414 * be NULL. 415 */ 416 if (hal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_2) { 417 ALOGV("%s: register_stream_buffers unused as of HAL3.2", __FUNCTION__); 418 419 if (hal3Device->ops->register_stream_buffers != NULL) { 420 ALOGE("%s: register_stream_buffers is deprecated in HAL3.2; " 421 "must be set to NULL in camera3_device::ops", __FUNCTION__); 422 return INVALID_OPERATION; 423 } else { 424 ALOGD("%s: Skipping NULL check for deprecated register_stream_buffers", __FUNCTION__); 425 } 426 427 return OK; 428 } else { 429 ALOGV("%s: register_stream_buffers using deprecated code path", __FUNCTION__); 430 } 431 432 status_t res; 433 434 size_t bufferCount = getBufferCountLocked(); 435 436 Vector<buffer_handle_t*> buffers; 437 buffers.insertAt(/*prototype_item*/NULL, /*index*/0, bufferCount); 438 439 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); 440 bufferSet.stream = this; 441 bufferSet.num_buffers = bufferCount; 442 bufferSet.buffers = buffers.editArray(); 443 444 Vector<camera3_stream_buffer_t> streamBuffers; 445 streamBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount); 446 447 // Register all buffers with the HAL. This means getting all the buffers 448 // from the stream, providing them to the HAL with the 449 // register_stream_buffers() method, and then returning them back to the 450 // stream in the error state, since they won't have valid data. 451 // 452 // Only registered buffers can be sent to the HAL. 453 454 uint32_t bufferIdx = 0; 455 for (; bufferIdx < bufferCount; bufferIdx++) { 456 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); 457 if (res != OK) { 458 ALOGE("%s: Unable to get buffer %d for registration with HAL", 459 __FUNCTION__, bufferIdx); 460 // Skip registering, go straight to cleanup 461 break; 462 } 463 464 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); 465 fence->waitForever("Camera3Stream::registerBuffers"); 466 467 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; 468 } 469 if (bufferIdx == bufferCount) { 470 // Got all buffers, register with HAL 471 ALOGV("%s: Registering %zu buffers with camera HAL", 472 __FUNCTION__, bufferCount); 473 ATRACE_BEGIN("camera3->register_stream_buffers"); 474 res = hal3Device->ops->register_stream_buffers(hal3Device, 475 &bufferSet); 476 ATRACE_END(); 477 } 478 479 // Return all valid buffers to stream, in ERROR state to indicate 480 // they weren't filled. 481 for (size_t i = 0; i < bufferIdx; i++) { 482 streamBuffers.editItemAt(i).release_fence = -1; 483 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 484 returnBufferLocked(streamBuffers[i], 0); 485 } 486 487 return res; 488} 489 490status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) { 491 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 492 return INVALID_OPERATION; 493} 494status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &, 495 nsecs_t) { 496 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 497 return INVALID_OPERATION; 498} 499status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) { 500 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 501 return INVALID_OPERATION; 502} 503status_t Camera3Stream::returnInputBufferLocked( 504 const camera3_stream_buffer &) { 505 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 506 return INVALID_OPERATION; 507} 508 509void Camera3Stream::addBufferListener( 510 wp<Camera3StreamBufferListener> listener) { 511 Mutex::Autolock l(mLock); 512 513 List<wp<Camera3StreamBufferListener> >::iterator it, end; 514 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 515 it != end; 516 ) { 517 if (*it == listener) { 518 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__); 519 return; 520 } 521 it++; 522 } 523 524 mBufferListenerList.push_back(listener); 525} 526 527void Camera3Stream::removeBufferListener( 528 const sp<Camera3StreamBufferListener>& listener) { 529 Mutex::Autolock l(mLock); 530 531 bool erased = true; 532 List<wp<Camera3StreamBufferListener> >::iterator it, end; 533 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 534 it != end; 535 ) { 536 537 if (*it == listener) { 538 it = mBufferListenerList.erase(it); 539 erased = true; 540 } else { 541 ++it; 542 } 543 } 544 545 if (!erased) { 546 ALOGW("%s: Could not find listener to remove, already removed", 547 __FUNCTION__); 548 } 549} 550 551}; // namespace camera3 552 553}; // namespace android 554