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