status_t Camera3Stream::prepareNextBuffer() { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = OK; // This function should be only called when the stream is preparing if (mState != STATE_PREPARING) { ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING " "state %d", __FUNCTION__, mId, mState); return INVALID_OPERATION; } // Get next buffer - this may allocate, and take a while for large buffers res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) ); if (res != OK) { ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation", __FUNCTION__, mId, mPreparedBufferIdx); return NO_INIT; } mPreparedBufferIdx++; // Check if we still have buffers left to allocate if (mPreparedBufferIdx < mPreparedBuffers.size()) { return NOT_ENOUGH_DATA; } // Done with prepare - mark stream as such, and return all buffers // via cancelPrepare mPrepared = true; return cancelPrepareLocked(); }
status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { ATRACE_CALL(); status_t res; size_t bufferCount = getBufferCountLocked(); Vector<buffer_handle_t*> buffers; buffers.insertAt(NULL, 0, bufferCount); camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); bufferSet.stream = this; bufferSet.num_buffers = bufferCount; bufferSet.buffers = buffers.editArray(); Vector<camera3_stream_buffer_t> streamBuffers; streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount); // Register all buffers with the HAL. This means getting all the buffers // from the stream, providing them to the HAL with the // register_stream_buffers() method, and then returning them back to the // stream in the error state, since they won't have valid data. // // Only registered buffers can be sent to the HAL. uint32_t bufferIdx = 0; for (; bufferIdx < bufferCount; bufferIdx++) { res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); if (res != OK) { ALOGE("%s: Unable to get buffer %d for registration with HAL", __FUNCTION__, bufferIdx); // Skip registering, go straight to cleanup break; } sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); fence->waitForever("Camera3Stream::registerBuffers"); buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; } if (bufferIdx == bufferCount) { // Got all buffers, register with HAL ALOGV("%s: Registering %zu buffers with camera HAL", __FUNCTION__, bufferCount); ATRACE_BEGIN("camera3->register_stream_buffers"); res = hal3Device->ops->register_stream_buffers(hal3Device, &bufferSet); ATRACE_END(); } // Return all valid buffers to stream, in ERROR state to indicate // they weren't filled. for (size_t i = 0; i < bufferIdx; i++) { streamBuffers.editItemAt(i).release_fence = -1; streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; returnBufferLocked(streamBuffers[i], 0); } return res; }
status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = getBufferLocked(buffer); if (res == OK) { fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); } return res; }
status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = OK; // This function should be only called when the stream is configured already. if (mState != STATE_CONFIGURED) { ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d", __FUNCTION__, mId, mState); return INVALID_OPERATION; } // Wait for new buffer returned back if we are running into the limit. if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) { ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.", __FUNCTION__, camera3_stream::max_buffers); res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); if (res != OK) { if (res == TIMED_OUT) { ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)", __FUNCTION__, kWaitForBufferDuration / 1000000LL, camera3_stream::max_buffers); } return res; } } res = getBufferLocked(buffer); if (res == OK) { fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); if (buffer->buffer) { mOutstandingBuffers.push_back(*buffer->buffer); } } return res; }
status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) { ATRACE_CALL(); /** * >= CAMERA_DEVICE_API_VERSION_3_2: * * camera3_device_t->ops->register_stream_buffers() is not called and must * be NULL. */ if (hal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_2) { ALOGV("%s: register_stream_buffers unused as of HAL3.2", __FUNCTION__); if (hal3Device->ops->register_stream_buffers != NULL) { ALOGE("%s: register_stream_buffers is deprecated in HAL3.2; " "must be set to NULL in camera3_device::ops", __FUNCTION__); return INVALID_OPERATION; } return OK; } ALOGV("%s: register_stream_buffers using deprecated code path", __FUNCTION__); status_t res; size_t bufferCount = getBufferCountLocked(); Vector<buffer_handle_t*> buffers; buffers.insertAt(/*prototype_item*/NULL, /*index*/0, bufferCount); camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set(); bufferSet.stream = this; bufferSet.num_buffers = bufferCount; bufferSet.buffers = buffers.editArray(); Vector<camera3_stream_buffer_t> streamBuffers; streamBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount); // Register all buffers with the HAL. This means getting all the buffers // from the stream, providing them to the HAL with the // register_stream_buffers() method, and then returning them back to the // stream in the error state, since they won't have valid data. // // Only registered buffers can be sent to the HAL. uint32_t bufferIdx = 0; for (; bufferIdx < bufferCount; bufferIdx++) { res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) ); if (res != OK) { ALOGE("%s: Unable to get buffer %d for registration with HAL", __FUNCTION__, bufferIdx); // Skip registering, go straight to cleanup break; } sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence); fence->waitForever("Camera3Stream::registerBuffers"); buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer; } if (bufferIdx == bufferCount) { // Got all buffers, register with HAL ALOGV("%s: Registering %zu buffers with camera HAL", __FUNCTION__, bufferCount); ATRACE_BEGIN("camera3->register_stream_buffers"); res = hal3Device->ops->register_stream_buffers(hal3Device, &bufferSet); ATRACE_END(); } // Return all valid buffers to stream, in ERROR state to indicate // they weren't filled. for (size_t i = 0; i < bufferIdx; i++) { streamBuffers.editItemAt(i).release_fence = -1; streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; returnBufferLocked(streamBuffers[i], 0); } mPrepared = true; return res; }