status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd; res = mConsumer->dequeueBuffer(mConsumer.get(), &anb, &fenceFd); if (res != OK) { ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK); return OK; }
status_t Camera3ZslStream::getInputBufferLocked(camera3_stream_buffer *buffer) { ATRACE_CALL(); status_t res; // TODO: potentially register from inputBufferLocked // this should be ok, registerBuffersLocked only calls getBuffer for now // register in output mode instead of input mode for ZSL streams. if (mState == STATE_IN_CONFIG || mState == STATE_IN_RECONFIG) { ALOGE("%s: Stream %d: Buffer registration for input streams" " not implemented (state %d)", __FUNCTION__, mId, mState); return INVALID_OPERATION; } if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd; assert(mProducer != 0); sp<PinnedBufferItem> bufferItem; { List<sp<RingBufferConsumer::PinnedBufferItem> >::iterator it, end; it = mInputBufferQueue.begin(); end = mInputBufferQueue.end(); // Need to call enqueueInputBufferByTimestamp as a prerequisite if (it == end) { ALOGE("%s: Stream %d: No input buffer was queued", __FUNCTION__, mId); return INVALID_OPERATION; } bufferItem = *it; mInputBufferQueue.erase(it); } anb = bufferItem->getBufferItem().mGraphicBuffer->getNativeBuffer(); assert(anb != NULL); fenceFd = bufferItem->getBufferItem().mFence->dup(); /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK); mBuffersInFlight.push_back(bufferItem); return OK; }
status_t Camera3InputStream::getInputBufferLocked( camera3_stream_buffer *buffer) { ATRACE_CALL(); status_t res; // FIXME: will not work in (re-)registration if (mState == STATE_IN_CONFIG || mState == STATE_IN_RECONFIG) { ALOGE("%s: Stream %d: Buffer registration for input streams" " not implemented (state %d)", __FUNCTION__, mId, mState); return INVALID_OPERATION; } if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd; assert(mConsumer != 0); BufferItem bufferItem; res = mConsumer->acquireBuffer(&bufferItem, /*waitForFence*/false); if (res != OK) { ALOGE("%s: Stream %d: Can't acquire next output buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } anb = bufferItem.mGraphicBuffer->getNativeBuffer(); assert(anb != NULL); fenceFd = bufferItem.mFence->dup(); /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false); mBuffersInFlight.push_back(bufferItem); return OK; }
status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd; /** * Release the lock briefly to avoid deadlock for below scenario: * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring(). * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock. * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable(). * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock * StreamingProcessor lock. * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock * and try to lock bufferQueue lock. * Then there is circular locking dependency. */ sp<ANativeWindow> currentConsumer = mConsumer; mLock.unlock(); res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd); mLock.lock(); if (res != OK) { ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd, /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true); return OK; }