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-OutputStream" 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 "Camera3OutputStream.h" 24 25 #ifndef container_of 26 #define container_of(ptr, type, member) \ 27 (type *)((char*)(ptr) - offsetof(type, member)) 28 #endif 29 30 namespace android { 31 32 namespace camera3 { 33 34 Camera3OutputStream::Camera3OutputStream(int id, 35 sp<Surface> consumer, 36 uint32_t width, uint32_t height, int format, 37 android_dataspace dataSpace, camera3_stream_rotation_t rotation, 38 nsecs_t timestampOffset, int setId) : 39 Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, 40 /*maxSize*/0, format, dataSpace, rotation, setId), 41 mConsumer(consumer), 42 mTransform(0), 43 mTraceFirstBuffer(true), 44 mUseBufferManager(false), 45 mTimestampOffset(timestampOffset), 46 mConsumerUsage(0) { 47 48 if (mConsumer == NULL) { 49 ALOGE("%s: Consumer is NULL!", __FUNCTION__); 50 mState = STATE_ERROR; 51 } 52 53 if (setId > CAMERA3_STREAM_SET_ID_INVALID) { 54 mBufferReleasedListener = new BufferReleasedListener(this); 55 } 56 } 57 58 Camera3OutputStream::Camera3OutputStream(int id, 59 sp<Surface> consumer, 60 uint32_t width, uint32_t height, size_t maxSize, int format, 61 android_dataspace dataSpace, camera3_stream_rotation_t rotation, 62 nsecs_t timestampOffset, int setId) : 63 Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize, 64 format, dataSpace, rotation, setId), 65 mConsumer(consumer), 66 mTransform(0), 67 mTraceFirstBuffer(true), 68 mUseMonoTimestamp(false), 69 mUseBufferManager(false), 70 mTimestampOffset(timestampOffset), 71 mConsumerUsage(0) { 72 73 if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) { 74 ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__, 75 format); 76 mState = STATE_ERROR; 77 } 78 79 if (mConsumer == NULL) { 80 ALOGE("%s: Consumer is NULL!", __FUNCTION__); 81 mState = STATE_ERROR; 82 } 83 84 if (setId > CAMERA3_STREAM_SET_ID_INVALID) { 85 mBufferReleasedListener = new BufferReleasedListener(this); 86 } 87 } 88 89 Camera3OutputStream::Camera3OutputStream(int id, 90 uint32_t width, uint32_t height, int format, 91 uint32_t consumerUsage, android_dataspace dataSpace, 92 camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) : 93 Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, 94 /*maxSize*/0, format, dataSpace, rotation, setId), 95 mConsumer(nullptr), 96 mTransform(0), 97 mTraceFirstBuffer(true), 98 mUseBufferManager(false), 99 mTimestampOffset(timestampOffset), 100 mConsumerUsage(consumerUsage) { 101 // Deferred consumer only support preview surface format now. 102 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 103 ALOGE("%s: Deferred consumer only supports IMPLEMENTATION_DEFINED format now!", 104 __FUNCTION__); 105 mState = STATE_ERROR; 106 } 107 108 // Sanity check for the consumer usage flag. 109 if ((consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) == 0 && 110 (consumerUsage & GraphicBuffer::USAGE_HW_COMPOSER) == 0) { 111 ALOGE("%s: Deferred consumer usage flag is illegal (0x%x)!", __FUNCTION__, consumerUsage); 112 mState = STATE_ERROR; 113 } 114 115 mConsumerName = String8("Deferred"); 116 if (setId > CAMERA3_STREAM_SET_ID_INVALID) { 117 mBufferReleasedListener = new BufferReleasedListener(this); 118 } 119 120 } 121 122 Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, 123 uint32_t width, uint32_t height, 124 int format, 125 android_dataspace dataSpace, 126 camera3_stream_rotation_t rotation, 127 int setId) : 128 Camera3IOStreamBase(id, type, width, height, 129 /*maxSize*/0, 130 format, dataSpace, rotation, setId), 131 mTransform(0), 132 mTraceFirstBuffer(true), 133 mUseMonoTimestamp(false), 134 mUseBufferManager(false), 135 mConsumerUsage(0) { 136 137 if (setId > CAMERA3_STREAM_SET_ID_INVALID) { 138 mBufferReleasedListener = new BufferReleasedListener(this); 139 } 140 141 // Subclasses expected to initialize mConsumer themselves 142 } 143 144 145 Camera3OutputStream::~Camera3OutputStream() { 146 disconnectLocked(); 147 } 148 149 status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { 150 ATRACE_CALL(); 151 status_t res; 152 153 if ((res = getBufferPreconditionCheckLocked()) != OK) { 154 return res; 155 } 156 157 ANativeWindowBuffer* anb; 158 int fenceFd = -1; 159 bool gotBufferFromManager = false; 160 161 if (mUseBufferManager) { 162 sp<GraphicBuffer> gb; 163 res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, &fenceFd); 164 if (res == OK) { 165 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a 166 // successful return. 167 anb = gb.get(); 168 res = mConsumer->attachBuffer(anb); 169 if (res != OK) { 170 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)", 171 __FUNCTION__, mId, strerror(-res), res); 172 return res; 173 } 174 gotBufferFromManager = true; 175 ALOGV("Stream %d: Attached new buffer", getId()); 176 } else if (res == ALREADY_EXISTS) { 177 // Have sufficient free buffers already attached, can just 178 // dequeue from buffer queue 179 ALOGV("Stream %d: Reusing attached buffer", getId()); 180 gotBufferFromManager = false; 181 } else if (res != OK) { 182 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)", 183 __FUNCTION__, mId, strerror(-res), res); 184 return res; 185 } 186 } 187 if (!gotBufferFromManager) { 188 /** 189 * Release the lock briefly to avoid deadlock for below scenario: 190 * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring(). 191 * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock. 192 * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable(). 193 * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock 194 * StreamingProcessor lock. 195 * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock 196 * and try to lock bufferQueue lock. 197 * Then there is circular locking dependency. 198 */ 199 sp<ANativeWindow> currentConsumer = mConsumer; 200 mLock.unlock(); 201 202 res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd); 203 mLock.lock(); 204 if (res != OK) { 205 ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", 206 __FUNCTION__, mId, strerror(-res), res); 207 208 // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING, 209 // let prepareNextBuffer handle the error.) 210 if (res == NO_INIT && mState == STATE_CONFIGURED) { 211 mState = STATE_ABANDONED; 212 } 213 214 return res; 215 } 216 } 217 218 /** 219 * FenceFD now owned by HAL except in case of error, 220 * in which case we reassign it to acquire_fence 221 */ 222 handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, 223 /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true); 224 225 return OK; 226 } 227 228 status_t Camera3OutputStream::returnBufferLocked( 229 const camera3_stream_buffer &buffer, 230 nsecs_t timestamp) { 231 ATRACE_CALL(); 232 233 status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true); 234 235 if (res != OK) { 236 return res; 237 } 238 239 mLastTimestamp = timestamp; 240 241 return OK; 242 } 243 244 status_t Camera3OutputStream::returnBufferCheckedLocked( 245 const camera3_stream_buffer &buffer, 246 nsecs_t timestamp, 247 bool output, 248 /*out*/ 249 sp<Fence> *releaseFenceOut) { 250 251 (void)output; 252 ALOG_ASSERT(output, "Expected output to be true"); 253 254 status_t res; 255 256 // Fence management - always honor release fence from HAL 257 sp<Fence> releaseFence = new Fence(buffer.release_fence); 258 int anwReleaseFence = releaseFence->dup(); 259 260 /** 261 * Release the lock briefly to avoid deadlock with 262 * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this 263 * thread will go into StreamingProcessor::onFrameAvailable) during 264 * queueBuffer 265 */ 266 sp<ANativeWindow> currentConsumer = mConsumer; 267 mLock.unlock(); 268 269 /** 270 * Return buffer back to ANativeWindow 271 */ 272 if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) { 273 // Cancel buffer 274 ALOGW("A frame is dropped for stream %d", mId); 275 res = currentConsumer->cancelBuffer(currentConsumer.get(), 276 container_of(buffer.buffer, ANativeWindowBuffer, handle), 277 anwReleaseFence); 278 if (res != OK) { 279 ALOGE("%s: Stream %d: Error cancelling buffer to native window:" 280 " %s (%d)", __FUNCTION__, mId, strerror(-res), res); 281 } 282 283 if (mUseBufferManager) { 284 // Return this buffer back to buffer manager. 285 mBufferReleasedListener->onBufferReleased(); 286 } 287 } else { 288 if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) { 289 { 290 char traceLog[48]; 291 snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId); 292 ATRACE_NAME(traceLog); 293 } 294 mTraceFirstBuffer = false; 295 } 296 297 /* Certain consumers (such as AudioSource or HardwareComposer) use 298 * MONOTONIC time, causing time misalignment if camera timestamp is 299 * in BOOTTIME. Do the conversion if necessary. */ 300 res = native_window_set_buffers_timestamp(mConsumer.get(), 301 mUseMonoTimestamp ? timestamp - mTimestampOffset : timestamp); 302 if (res != OK) { 303 ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)", 304 __FUNCTION__, mId, strerror(-res), res); 305 return res; 306 } 307 308 res = currentConsumer->queueBuffer(currentConsumer.get(), 309 container_of(buffer.buffer, ANativeWindowBuffer, handle), 310 anwReleaseFence); 311 if (res != OK) { 312 ALOGE("%s: Stream %d: Error queueing buffer to native window: " 313 "%s (%d)", __FUNCTION__, mId, strerror(-res), res); 314 } 315 } 316 mLock.lock(); 317 318 // Once a valid buffer has been returned to the queue, can no longer 319 // dequeue all buffers for preallocation. 320 if (buffer.status != CAMERA3_BUFFER_STATUS_ERROR) { 321 mStreamUnpreparable = true; 322 } 323 324 if (res != OK) { 325 close(anwReleaseFence); 326 } 327 328 *releaseFenceOut = releaseFence; 329 330 return res; 331 } 332 333 void Camera3OutputStream::dump(int fd, const Vector<String16> &args) const { 334 (void) args; 335 String8 lines; 336 lines.appendFormat(" Stream[%d]: Output\n", mId); 337 lines.appendFormat(" Consumer name: %s\n", mConsumerName.string()); 338 write(fd, lines.string(), lines.size()); 339 340 Camera3IOStreamBase::dump(fd, args); 341 } 342 343 status_t Camera3OutputStream::setTransform(int transform) { 344 ATRACE_CALL(); 345 Mutex::Autolock l(mLock); 346 return setTransformLocked(transform); 347 } 348 349 status_t Camera3OutputStream::setTransformLocked(int transform) { 350 status_t res = OK; 351 if (mState == STATE_ERROR) { 352 ALOGE("%s: Stream in error state", __FUNCTION__); 353 return INVALID_OPERATION; 354 } 355 356 mTransform = transform; 357 if (mState == STATE_CONFIGURED) { 358 res = native_window_set_buffers_transform(mConsumer.get(), 359 transform); 360 if (res != OK) { 361 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 362 __FUNCTION__, transform, strerror(-res), res); 363 } 364 } 365 return res; 366 } 367 368 status_t Camera3OutputStream::configureQueueLocked() { 369 status_t res; 370 371 mTraceFirstBuffer = true; 372 if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) { 373 return res; 374 } 375 376 ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL"); 377 378 // Configure consumer-side ANativeWindow interface. The listener may be used 379 // to notify buffer manager (if it is used) of the returned buffers. 380 res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/mBufferReleasedListener); 381 if (res != OK) { 382 ALOGE("%s: Unable to connect to native window for stream %d", 383 __FUNCTION__, mId); 384 return res; 385 } 386 387 mConsumerName = mConsumer->getConsumerName(); 388 389 res = native_window_set_usage(mConsumer.get(), camera3_stream::usage); 390 if (res != OK) { 391 ALOGE("%s: Unable to configure usage %08x for stream %d", 392 __FUNCTION__, camera3_stream::usage, mId); 393 return res; 394 } 395 396 res = native_window_set_scaling_mode(mConsumer.get(), 397 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 398 if (res != OK) { 399 ALOGE("%s: Unable to configure stream scaling: %s (%d)", 400 __FUNCTION__, strerror(-res), res); 401 return res; 402 } 403 404 if (mMaxSize == 0) { 405 // For buffers of known size 406 res = native_window_set_buffers_dimensions(mConsumer.get(), 407 camera3_stream::width, camera3_stream::height); 408 } else { 409 // For buffers with bounded size 410 res = native_window_set_buffers_dimensions(mConsumer.get(), 411 mMaxSize, 1); 412 } 413 if (res != OK) { 414 ALOGE("%s: Unable to configure stream buffer dimensions" 415 " %d x %d (maxSize %zu) for stream %d", 416 __FUNCTION__, camera3_stream::width, camera3_stream::height, 417 mMaxSize, mId); 418 return res; 419 } 420 res = native_window_set_buffers_format(mConsumer.get(), 421 camera3_stream::format); 422 if (res != OK) { 423 ALOGE("%s: Unable to configure stream buffer format %#x for stream %d", 424 __FUNCTION__, camera3_stream::format, mId); 425 return res; 426 } 427 428 res = native_window_set_buffers_data_space(mConsumer.get(), 429 camera3_stream::data_space); 430 if (res != OK) { 431 ALOGE("%s: Unable to configure stream dataspace %#x for stream %d", 432 __FUNCTION__, camera3_stream::data_space, mId); 433 return res; 434 } 435 436 int maxConsumerBuffers; 437 res = static_cast<ANativeWindow*>(mConsumer.get())->query( 438 mConsumer.get(), 439 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 440 if (res != OK) { 441 ALOGE("%s: Unable to query consumer undequeued" 442 " buffer count for stream %d", __FUNCTION__, mId); 443 return res; 444 } 445 446 ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__, 447 maxConsumerBuffers, camera3_stream::max_buffers); 448 if (camera3_stream::max_buffers == 0) { 449 ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1", 450 __FUNCTION__, camera3_stream::max_buffers); 451 return INVALID_OPERATION; 452 } 453 454 mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers; 455 mHandoutTotalBufferCount = 0; 456 mFrameCount = 0; 457 mLastTimestamp = 0; 458 mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream()); 459 460 res = native_window_set_buffer_count(mConsumer.get(), 461 mTotalBufferCount); 462 if (res != OK) { 463 ALOGE("%s: Unable to set buffer count for stream %d", 464 __FUNCTION__, mId); 465 return res; 466 } 467 468 res = native_window_set_buffers_transform(mConsumer.get(), 469 mTransform); 470 if (res != OK) { 471 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 472 __FUNCTION__, mTransform, strerror(-res), res); 473 } 474 475 // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture. 476 // We need skip these cases as timeout will disable the non-blocking (async) mode. 477 if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) { 478 mConsumer->setDequeueTimeout(kDequeueBufferTimeout); 479 } 480 481 /** 482 * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires 483 * buffers to be statically allocated for internal static buffer registration, while the 484 * buffers provided by buffer manager are really dynamically allocated. Camera3Device only 485 * sets the mBufferManager if device version is > HAL3.2, which guarantees that the buffer 486 * manager setup is skipped in below code. Note that HAL3.2 is also excluded here, as some 487 * HAL3.2 devices may not support the dynamic buffer registeration. 488 */ 489 if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) { 490 uint32_t consumerUsage = 0; 491 getEndpointUsage(&consumerUsage); 492 StreamInfo streamInfo( 493 getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(), 494 camera3_stream::usage | consumerUsage, mTotalBufferCount, 495 /*isConfigured*/true); 496 wp<Camera3OutputStream> weakThis(this); 497 res = mBufferManager->registerStream(weakThis, 498 streamInfo); 499 if (res == OK) { 500 // Disable buffer allocation for this BufferQueue, buffer manager will take over 501 // the buffer allocation responsibility. 502 mConsumer->getIGraphicBufferProducer()->allowAllocation(false); 503 mUseBufferManager = true; 504 } else { 505 ALOGE("%s: Unable to register stream %d to camera3 buffer manager, " 506 "(error %d %s), fall back to BufferQueue for buffer management!", 507 __FUNCTION__, mId, res, strerror(-res)); 508 } 509 } 510 511 return OK; 512 } 513 514 status_t Camera3OutputStream::disconnectLocked() { 515 status_t res; 516 517 if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) { 518 return res; 519 } 520 521 // Stream configuration was not finished (can only be in STATE_IN_CONFIG or STATE_CONSTRUCTED 522 // state), don't need change the stream state, return OK. 523 if (mConsumer == nullptr) { 524 return OK; 525 } 526 527 ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId()); 528 529 res = native_window_api_disconnect(mConsumer.get(), 530 NATIVE_WINDOW_API_CAMERA); 531 /** 532 * This is not an error. if client calling process dies, the window will 533 * also die and all calls to it will return DEAD_OBJECT, thus it's already 534 * "disconnected" 535 */ 536 if (res == DEAD_OBJECT) { 537 ALOGW("%s: While disconnecting stream %d from native window, the" 538 " native window died from under us", __FUNCTION__, mId); 539 } 540 else if (res != OK) { 541 ALOGE("%s: Unable to disconnect stream %d from native window " 542 "(error %d %s)", 543 __FUNCTION__, mId, res, strerror(-res)); 544 mState = STATE_ERROR; 545 return res; 546 } 547 548 // Since device is already idle, there is no getBuffer call to buffer manager, unregister the 549 // stream at this point should be safe. 550 if (mUseBufferManager) { 551 res = mBufferManager->unregisterStream(getId(), getStreamSetId()); 552 if (res != OK) { 553 ALOGE("%s: Unable to unregister stream %d from buffer manager " 554 "(error %d %s)", __FUNCTION__, mId, res, strerror(-res)); 555 mState = STATE_ERROR; 556 return res; 557 } 558 // Note that, to make prepare/teardown case work, we must not mBufferManager.clear(), as 559 // the stream is still in usable state after this call. 560 mUseBufferManager = false; 561 } 562 563 mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG 564 : STATE_CONSTRUCTED; 565 return OK; 566 } 567 568 status_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) const { 569 570 status_t res; 571 int32_t u = 0; 572 if (mConsumer == nullptr) { 573 // mConsumerUsage was sanitized before the Camera3OutputStream was constructed. 574 *usage = mConsumerUsage; 575 return OK; 576 } 577 578 res = static_cast<ANativeWindow*>(mConsumer.get())->query(mConsumer.get(), 579 NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u); 580 581 // If an opaque output stream's endpoint is ImageReader, add 582 // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used 583 // for the ZSL use case. 584 // Assume it's for ImageReader if the consumer usage doesn't have any of these bits set: 585 // 1. GRALLOC_USAGE_HW_TEXTURE 586 // 2. GRALLOC_USAGE_HW_RENDER 587 // 3. GRALLOC_USAGE_HW_COMPOSER 588 // 4. GRALLOC_USAGE_HW_VIDEO_ENCODER 589 if (camera3_stream::format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED && 590 (u & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | 591 GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) { 592 u |= GRALLOC_USAGE_HW_CAMERA_ZSL; 593 } 594 595 *usage = u; 596 return res; 597 } 598 599 bool Camera3OutputStream::isVideoStream() const { 600 uint32_t usage = 0; 601 status_t res = getEndpointUsage(&usage); 602 if (res != OK) { 603 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res); 604 return false; 605 } 606 607 return (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0; 608 } 609 610 status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) { 611 Mutex::Autolock l(mLock); 612 if (mState != STATE_CONSTRUCTED) { 613 ALOGE("%s: this method can only be called when stream in CONSTRUCTED state.", 614 __FUNCTION__); 615 return INVALID_OPERATION; 616 } 617 mBufferManager = bufferManager; 618 619 return OK; 620 } 621 622 void Camera3OutputStream::BufferReleasedListener::onBufferReleased() { 623 sp<Camera3OutputStream> stream = mParent.promote(); 624 if (stream == nullptr) { 625 ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__); 626 return; 627 } 628 629 Mutex::Autolock l(stream->mLock); 630 if (!(stream->mUseBufferManager)) { 631 return; 632 } 633 634 ALOGV("Stream %d: Buffer released", stream->getId()); 635 status_t res = stream->mBufferManager->onBufferReleased( 636 stream->getId(), stream->getStreamSetId()); 637 if (res != OK) { 638 ALOGE("%s: signaling buffer release to buffer manager failed: %s (%d).", __FUNCTION__, 639 strerror(-res), res); 640 stream->mState = STATE_ERROR; 641 } 642 } 643 644 status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) { 645 Mutex::Autolock l(mLock); 646 647 ALOGV("Stream %d: detachBuffer", getId()); 648 if (buffer == nullptr) { 649 return BAD_VALUE; 650 } 651 652 sp<Fence> fence; 653 status_t res = mConsumer->detachNextBuffer(buffer, &fence); 654 if (res == NO_MEMORY) { 655 // This may rarely happen, which indicates that the released buffer was freed by other 656 // call (e.g., attachBuffer, dequeueBuffer etc.) before reaching here. We should notify the 657 // buffer manager that this buffer has been freed. It's not fatal, but should be avoided, 658 // therefore log a warning. 659 *buffer = 0; 660 ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__); 661 } else if (res != OK) { 662 // Treat other errors as abandonment 663 ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res); 664 mState = STATE_ABANDONED; 665 return res; 666 } 667 668 if (fenceFd != nullptr) { 669 if (fence!= 0 && fence->isValid()) { 670 *fenceFd = fence->dup(); 671 } else { 672 *fenceFd = -1; 673 } 674 } 675 676 return OK; 677 } 678 679 bool Camera3OutputStream::isConsumerConfigurationDeferred() const { 680 Mutex::Autolock l(mLock); 681 return mConsumer == nullptr; 682 } 683 684 status_t Camera3OutputStream::setConsumer(sp<Surface> consumer) { 685 if (consumer == nullptr) { 686 ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__); 687 return INVALID_OPERATION; 688 } 689 690 if (mConsumer != nullptr) { 691 ALOGE("%s: consumer surface was already set!", __FUNCTION__); 692 return INVALID_OPERATION; 693 } 694 695 mConsumer = consumer; 696 return OK; 697 } 698 699 bool Camera3OutputStream::isConsumedByHWComposer() const { 700 uint32_t usage = 0; 701 status_t res = getEndpointUsage(&usage); 702 if (res != OK) { 703 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res); 704 return false; 705 } 706 707 return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0; 708 } 709 710 bool Camera3OutputStream::isConsumedByHWTexture() const { 711 uint32_t usage = 0; 712 status_t res = getEndpointUsage(&usage); 713 if (res != OK) { 714 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res); 715 return false; 716 } 717 718 return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0; 719 } 720 721 }; // namespace camera3 722 723 }; // namespace android 724