Camera3Stream.cpp revision e9154ced1216ceb06a82140ed65051c0397e8abc
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 mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) { 58 59 camera3_stream::stream_type = type; 60 camera3_stream::width = width; 61 camera3_stream::height = height; 62 camera3_stream::format = format; 63 camera3_stream::data_space = dataSpace; 64 camera3_stream::rotation = rotation; 65 camera3_stream::usage = 0; 66 camera3_stream::max_buffers = 0; 67 camera3_stream::priv = NULL; 68 69 if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) && 70 maxSize == 0) { 71 ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__); 72 mState = STATE_ERROR; 73 } 74} 75 76int Camera3Stream::getId() const { 77 return mId; 78} 79 80uint32_t Camera3Stream::getWidth() const { 81 return camera3_stream::width; 82} 83 84uint32_t Camera3Stream::getHeight() const { 85 return camera3_stream::height; 86} 87 88int Camera3Stream::getFormat() const { 89 return camera3_stream::format; 90} 91 92android_dataspace Camera3Stream::getDataSpace() const { 93 return camera3_stream::data_space; 94} 95 96camera3_stream* Camera3Stream::startConfiguration() { 97 ATRACE_CALL(); 98 Mutex::Autolock l(mLock); 99 status_t res; 100 101 switch (mState) { 102 case STATE_ERROR: 103 ALOGE("%s: In error state", __FUNCTION__); 104 return NULL; 105 case STATE_CONSTRUCTED: 106 // OK 107 break; 108 case STATE_IN_CONFIG: 109 case STATE_IN_RECONFIG: 110 // Can start config again with no trouble; but don't redo 111 // oldUsage/oldMaxBuffers 112 return this; 113 case STATE_CONFIGURED: 114 if (hasOutstandingBuffersLocked()) { 115 ALOGE("%s: Cannot configure stream; has outstanding buffers", 116 __FUNCTION__); 117 return NULL; 118 } 119 break; 120 default: 121 ALOGE("%s: Unknown state %d", __FUNCTION__, mState); 122 return NULL; 123 } 124 125 oldUsage = camera3_stream::usage; 126 oldMaxBuffers = camera3_stream::max_buffers; 127 128 res = getEndpointUsage(&(camera3_stream::usage)); 129 if (res != OK) { 130 ALOGE("%s: Cannot query consumer endpoint usage!", 131 __FUNCTION__); 132 return NULL; 133 } 134 135 // Stop tracking if currently doing so 136 if (mStatusId != StatusTracker::NO_STATUS_ID) { 137 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 138 if (statusTracker != 0) { 139 statusTracker->removeComponent(mStatusId); 140 } 141 mStatusId = StatusTracker::NO_STATUS_ID; 142 } 143 144 if (mState == STATE_CONSTRUCTED) { 145 mState = STATE_IN_CONFIG; 146 } else { // mState == STATE_CONFIGURED 147 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState); 148 mState = STATE_IN_RECONFIG; 149 } 150 151 return this; 152} 153 154bool Camera3Stream::isConfiguring() const { 155 Mutex::Autolock l(mLock); 156 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG); 157} 158 159status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) { 160 ATRACE_CALL(); 161 Mutex::Autolock l(mLock); 162 switch (mState) { 163 case STATE_ERROR: 164 ALOGE("%s: In error state", __FUNCTION__); 165 return INVALID_OPERATION; 166 case STATE_IN_CONFIG: 167 case STATE_IN_RECONFIG: 168 // OK 169 break; 170 case STATE_CONSTRUCTED: 171 case STATE_CONFIGURED: 172 ALOGE("%s: Cannot finish configuration that hasn't been started", 173 __FUNCTION__); 174 return INVALID_OPERATION; 175 default: 176 ALOGE("%s: Unknown state", __FUNCTION__); 177 return INVALID_OPERATION; 178 } 179 180 // Register for idle tracking 181 sp<StatusTracker> statusTracker = mStatusTracker.promote(); 182 if (statusTracker != 0) { 183 mStatusId = statusTracker->addComponent(); 184 } 185 186 // Check if the stream configuration is unchanged, and skip reallocation if 187 // so. As documented in hardware/camera3.h:configure_streams(). 188 if (mState == STATE_IN_RECONFIG && 189 oldUsage == camera3_stream::usage && 190 oldMaxBuffers == camera3_stream::max_buffers) { 191 mState = STATE_CONFIGURED; 192 return OK; 193 } 194 195 // Reset prepared state, since buffer config has changed, and existing 196 // allocations are no longer valid 197 mPrepared = false; 198 mStreamUnpreparable = false; 199 200 status_t res; 201 res = configureQueueLocked(); 202 if (res != OK) { 203 ALOGE("%s: Unable to configure stream %d queue: %s (%d)", 204 __FUNCTION__, mId, strerror(-res), res); 205 mState = STATE_ERROR; 206 return res; 207 } 208 209 res = registerBuffersLocked(hal3Device); 210 if (res != OK) { 211 ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)", 212 __FUNCTION__, strerror(-res), res); 213 mState = STATE_ERROR; 214 return res; 215 } 216 217 mState = STATE_CONFIGURED; 218 219 return res; 220} 221 222status_t Camera3Stream::cancelConfiguration() { 223 ATRACE_CALL(); 224 Mutex::Autolock l(mLock); 225 switch (mState) { 226 case STATE_ERROR: 227 ALOGE("%s: In error state", __FUNCTION__); 228 return INVALID_OPERATION; 229 case STATE_IN_CONFIG: 230 case STATE_IN_RECONFIG: 231 // OK 232 break; 233 case STATE_CONSTRUCTED: 234 case STATE_CONFIGURED: 235 ALOGE("%s: Cannot cancel configuration that hasn't been started", 236 __FUNCTION__); 237 return INVALID_OPERATION; 238 default: 239 ALOGE("%s: Unknown state", __FUNCTION__); 240 return INVALID_OPERATION; 241 } 242 243 camera3_stream::usage = oldUsage; 244 camera3_stream::max_buffers = oldMaxBuffers; 245 246 mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED; 247 return OK; 248} 249 250bool Camera3Stream::isUnpreparable() { 251 ATRACE_CALL(); 252 253 Mutex::Autolock l(mLock); 254 return mStreamUnpreparable; 255} 256 257status_t Camera3Stream::startPrepare(int maxCount) { 258 ATRACE_CALL(); 259 260 Mutex::Autolock l(mLock); 261 status_t res = OK; 262 263 if (maxCount < 0) { 264 ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0", 265 __FUNCTION__, mId, maxCount); 266 return BAD_VALUE; 267 } 268 269 // This function should be only called when the stream is configured already. 270 if (mState != STATE_CONFIGURED) { 271 ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED " 272 "state %d", __FUNCTION__, mId, mState); 273 return INVALID_OPERATION; 274 } 275 276 // This function can't be called if the stream has already received filled 277 // buffers 278 if (mStreamUnpreparable) { 279 ALOGE("%s: Stream %d: Can't prepare stream that's already in use", 280 __FUNCTION__, mId); 281 return INVALID_OPERATION; 282 } 283 284 if (getHandoutOutputBufferCountLocked() > 0) { 285 ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers", 286 __FUNCTION__, mId); 287 return INVALID_OPERATION; 288 } 289 290 291 292 size_t pipelineMax = getBufferCountLocked(); 293 size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ? 294 pipelineMax : static_cast<size_t>(maxCount); 295 size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ? 296 pipelineMax : clampedCount; 297 298 mPrepared = bufferCount <= mLastMaxCount; 299 300 if (mPrepared) return OK; 301 302 mLastMaxCount = bufferCount; 303 304 mPreparedBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount); 305 mPreparedBufferIdx = 0; 306 307 mState = STATE_PREPARING; 308 309 return NOT_ENOUGH_DATA; 310} 311 312bool Camera3Stream::isPreparing() const { 313 Mutex::Autolock l(mLock); 314 return mState == STATE_PREPARING; 315} 316 317status_t Camera3Stream::prepareNextBuffer() { 318 ATRACE_CALL(); 319 320 Mutex::Autolock l(mLock); 321 status_t res = OK; 322 323 // This function should be only called when the stream is preparing 324 if (mState != STATE_PREPARING) { 325 ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING " 326 "state %d", __FUNCTION__, mId, mState); 327 return INVALID_OPERATION; 328 } 329 330 // Get next buffer - this may allocate, and take a while for large buffers 331 res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) ); 332 if (res != OK) { 333 ALOGE("%s: Stream %d: Unable to allocate buffer %d during preparation", 334 __FUNCTION__, mId, mPreparedBufferIdx); 335 return NO_INIT; 336 } 337 338 mPreparedBufferIdx++; 339 340 // Check if we still have buffers left to allocate 341 if (mPreparedBufferIdx < mPreparedBuffers.size()) { 342 return NOT_ENOUGH_DATA; 343 } 344 345 // Done with prepare - mark stream as such, and return all buffers 346 // via cancelPrepare 347 mPrepared = true; 348 349 return cancelPrepareLocked(); 350} 351 352status_t Camera3Stream::cancelPrepare() { 353 ATRACE_CALL(); 354 355 Mutex::Autolock l(mLock); 356 357 return cancelPrepareLocked(); 358} 359 360status_t Camera3Stream::cancelPrepareLocked() { 361 status_t res = OK; 362 363 // This function should be only called when the stream is mid-preparing. 364 if (mState != STATE_PREPARING) { 365 ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in " 366 "PREPARING state %d", __FUNCTION__, mId, mState); 367 return INVALID_OPERATION; 368 } 369 370 // Return all valid buffers to stream, in ERROR state to indicate 371 // they weren't filled. 372 for (size_t i = 0; i < mPreparedBufferIdx; i++) { 373 mPreparedBuffers.editItemAt(i).release_fence = -1; 374 mPreparedBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 375 returnBufferLocked(mPreparedBuffers[i], 0); 376 } 377 mPreparedBuffers.clear(); 378 mPreparedBufferIdx = 0; 379 380 mState = STATE_CONFIGURED; 381 382 return res; 383} 384 385status_t Camera3Stream::tearDown() { 386 ATRACE_CALL(); 387 Mutex::Autolock l(mLock); 388 389 status_t res = OK; 390 391 // This function should be only called when the stream is configured. 392 if (mState != STATE_CONFIGURED) { 393 ALOGE("%s: Stream %d: Can't tear down stream if stream is not in " 394 "CONFIGURED state %d", __FUNCTION__, mId, mState); 395 return INVALID_OPERATION; 396 } 397 398 // If any buffers have been handed to the HAL, the stream cannot be torn down. 399 if (getHandoutOutputBufferCountLocked() > 0) { 400 ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers", 401 __FUNCTION__, mId); 402 return INVALID_OPERATION; 403 } 404 405 // Free buffers by disconnecting and then reconnecting to the buffer queue 406 // Only unused buffers will be dropped immediately; buffers that have been filled 407 // and are waiting to be acquired by the consumer and buffers that are currently 408 // acquired will be freed once they are released by the consumer. 409 410 res = disconnectLocked(); 411 if (res != OK) { 412 if (res == -ENOTCONN) { 413 // queue has been disconnected, nothing left to do, so exit with success 414 return OK; 415 } 416 ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)", 417 __FUNCTION__, mId, strerror(-res), res); 418 return res; 419 } 420 421 mState = STATE_IN_CONFIG; 422 423 res = configureQueueLocked(); 424 if (res != OK) { 425 ALOGE("%s: Unable to configure stream %d queue: %s (%d)", 426 __FUNCTION__, mId, strerror(-res), res); 427 mState = STATE_ERROR; 428 return res; 429 } 430 431 // Reset prepared state, since we've reconnected to the queue and can prepare again. 432 mPrepared = false; 433 mStreamUnpreparable = false; 434 435 mState = STATE_CONFIGURED; 436 437 return OK; 438} 439 440status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { 441 ATRACE_CALL(); 442 Mutex::Autolock l(mLock); 443 status_t res = OK; 444 445 // This function should be only called when the stream is configured already. 446 if (mState != STATE_CONFIGURED) { 447 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d", 448 __FUNCTION__, mId, mState); 449 return INVALID_OPERATION; 450 } 451 452 // Wait for new buffer returned back if we are running into the limit. 453 if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) { 454 ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.", 455 __FUNCTION__, camera3_stream::max_buffers); 456 res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); 457 if (res != OK) { 458 if (res == TIMED_OUT) { 459 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)", 460 __FUNCTION__, kWaitForBufferDuration / 1000000LL, 461 camera3_stream::max_buffers); 462 } 463 return res; 464 } 465 } 466 467 res = getBufferLocked(buffer); 468 if (res == OK) { 469 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); 470 } 471 472 return res; 473} 474 475status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, 476 nsecs_t timestamp) { 477 ATRACE_CALL(); 478 Mutex::Autolock l(mLock); 479 480 /** 481 * TODO: Check that the state is valid first. 482 * 483 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED. 484 * >= HAL3.2 CONFIGURED only 485 * 486 * Do this for getBuffer as well. 487 */ 488 status_t res = returnBufferLocked(buffer, timestamp); 489 if (res == OK) { 490 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); 491 } 492 493 // Even if returning the buffer failed, we still want to signal whoever is waiting for the 494 // buffer to be returned. 495 mOutputBufferReturnedSignal.signal(); 496 497 return res; 498} 499 500status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) { 501 ATRACE_CALL(); 502 Mutex::Autolock l(mLock); 503 status_t res = OK; 504 505 // This function should be only called when the stream is configured already. 506 if (mState != STATE_CONFIGURED) { 507 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d", 508 __FUNCTION__, mId, mState); 509 return INVALID_OPERATION; 510 } 511 512 // Wait for new buffer returned back if we are running into the limit. 513 if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers) { 514 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.", 515 __FUNCTION__, camera3_stream::max_buffers); 516 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); 517 if (res != OK) { 518 if (res == TIMED_OUT) { 519 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__, 520 kWaitForBufferDuration / 1000000LL); 521 } 522 return res; 523 } 524 } 525 526 res = getInputBufferLocked(buffer); 527 if (res == OK) { 528 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false); 529 } 530 531 return res; 532} 533 534status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) { 535 ATRACE_CALL(); 536 Mutex::Autolock l(mLock); 537 538 status_t res = returnInputBufferLocked(buffer); 539 if (res == OK) { 540 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false); 541 mInputBufferReturnedSignal.signal(); 542 } 543 return res; 544} 545 546status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) { 547 ATRACE_CALL(); 548 Mutex::Autolock l(mLock); 549 550 return getInputBufferProducerLocked(producer); 551} 552 553void Camera3Stream::fireBufferListenersLocked( 554 const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) { 555 List<wp<Camera3StreamBufferListener> >::iterator it, end; 556 557 // TODO: finish implementing 558 559 Camera3StreamBufferListener::BufferInfo info = 560 Camera3StreamBufferListener::BufferInfo(); 561 info.mOutput = output; 562 // TODO: rest of fields 563 564 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 565 it != end; 566 ++it) { 567 568 sp<Camera3StreamBufferListener> listener = it->promote(); 569 if (listener != 0) { 570 if (acquired) { 571 listener->onBufferAcquired(info); 572 } else { 573 listener->onBufferReleased(info); 574 } 575 } 576 } 577} 578 579bool Camera3Stream::hasOutstandingBuffers() const { 580 ATRACE_CALL(); 581 Mutex::Autolock l(mLock); 582 return hasOutstandingBuffersLocked(); 583} 584 585status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) { 586 Mutex::Autolock l(mLock); 587 sp<StatusTracker> oldTracker = mStatusTracker.promote(); 588 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) { 589 oldTracker->removeComponent(mStatusId); 590 } 591 mStatusId = StatusTracker::NO_STATUS_ID; 592 mStatusTracker = statusTracker; 593 594 return OK; 595} 596 597status_t Camera3Stream::disconnect() { 598 ATRACE_CALL(); 599 Mutex::Autolock l(mLock); 600 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId); 601 status_t res = disconnectLocked(); 602 603 if (res == -ENOTCONN) { 604 // "Already disconnected" -- not an error 605 return OK; 606 } else { 607 return res; 608 } 609} 610 611status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { 612 ATRACE_CALL(); 613 614 /** 615 * >= CAMERA_DEVICE_API_VERSION_3_2: 616 * 617 * camera3_device_t->ops->register_stream_buffers() is not called and must 618 * be NULL. 619 */ 620 if (hal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_2) { 621 ALOGV("%s: register_stream_buffers unused as of HAL3.2", __FUNCTION__); 622 623 if (hal3Device->ops->register_stream_buffers != NULL) { 624 ALOGE("%s: register_stream_buffers is deprecated in HAL3.2; " 625 "must be set to NULL in camera3_device::ops", __FUNCTION__); 626 return INVALID_OPERATION; 627 } 628 629 return OK; 630 } 631 632 ALOGV("%s: register_stream_buffers using deprecated code path", __FUNCTION__); 633 634 status_t res; 635 636 size_t bufferCount = getBufferCountLocked(); 637 638 Vector<buffer_handle_t*> buffers; 639 buffers.insertAt(/*prototype_item*/NULL, /*index*/0, bufferCount); 640 641 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); 642 bufferSet.stream = this; 643 bufferSet.num_buffers = bufferCount; 644 bufferSet.buffers = buffers.editArray(); 645 646 Vector<camera3_stream_buffer_t> streamBuffers; 647 streamBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount); 648 649 // Register all buffers with the HAL. This means getting all the buffers 650 // from the stream, providing them to the HAL with the 651 // register_stream_buffers() method, and then returning them back to the 652 // stream in the error state, since they won't have valid data. 653 // 654 // Only registered buffers can be sent to the HAL. 655 656 uint32_t bufferIdx = 0; 657 for (; bufferIdx < bufferCount; bufferIdx++) { 658 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); 659 if (res != OK) { 660 ALOGE("%s: Unable to get buffer %d for registration with HAL", 661 __FUNCTION__, bufferIdx); 662 // Skip registering, go straight to cleanup 663 break; 664 } 665 666 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); 667 fence->waitForever("Camera3Stream::registerBuffers"); 668 669 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; 670 } 671 if (bufferIdx == bufferCount) { 672 // Got all buffers, register with HAL 673 ALOGV("%s: Registering %zu buffers with camera HAL", 674 __FUNCTION__, bufferCount); 675 ATRACE_BEGIN("camera3->register_stream_buffers"); 676 res = hal3Device->ops->register_stream_buffers(hal3Device, 677 &bufferSet); 678 ATRACE_END(); 679 } 680 681 // Return all valid buffers to stream, in ERROR state to indicate 682 // they weren't filled. 683 for (size_t i = 0; i < bufferIdx; i++) { 684 streamBuffers.editItemAt(i).release_fence = -1; 685 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; 686 returnBufferLocked(streamBuffers[i], 0); 687 } 688 689 mPrepared = true; 690 691 return res; 692} 693 694status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) { 695 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 696 return INVALID_OPERATION; 697} 698status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &, 699 nsecs_t) { 700 ALOGE("%s: This type of stream does not support output", __FUNCTION__); 701 return INVALID_OPERATION; 702} 703status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) { 704 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 705 return INVALID_OPERATION; 706} 707status_t Camera3Stream::returnInputBufferLocked( 708 const camera3_stream_buffer &) { 709 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 710 return INVALID_OPERATION; 711} 712status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer> *producer) { 713 ALOGE("%s: This type of stream does not support input", __FUNCTION__); 714 return INVALID_OPERATION; 715} 716 717void Camera3Stream::addBufferListener( 718 wp<Camera3StreamBufferListener> listener) { 719 Mutex::Autolock l(mLock); 720 721 List<wp<Camera3StreamBufferListener> >::iterator it, end; 722 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 723 it != end; 724 ) { 725 if (*it == listener) { 726 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__); 727 return; 728 } 729 it++; 730 } 731 732 mBufferListenerList.push_back(listener); 733} 734 735void Camera3Stream::removeBufferListener( 736 const sp<Camera3StreamBufferListener>& listener) { 737 Mutex::Autolock l(mLock); 738 739 bool erased = true; 740 List<wp<Camera3StreamBufferListener> >::iterator it, end; 741 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end(); 742 it != end; 743 ) { 744 745 if (*it == listener) { 746 it = mBufferListenerList.erase(it); 747 erased = true; 748 } else { 749 ++it; 750 } 751 } 752 753 if (!erased) { 754 ALOGW("%s: Could not find listener to remove, already removed", 755 __FUNCTION__); 756 } 757} 758 759}; // namespace camera3 760 761}; // namespace android 762