status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer, nsecs_t timestamp) { ATRACE_CALL(); Mutex::Autolock l(mLock); // Check if this buffer is outstanding. if (!isOutstandingBuffer(buffer)) { ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId); return BAD_VALUE; } /** * TODO: Check that the state is valid first. * * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED. * >= HAL3.2 CONFIGURED only * * Do this for getBuffer as well. */ status_t res = returnBufferLocked(buffer, timestamp); if (res == OK) { fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); } // Even if returning the buffer failed, we still want to signal whoever is waiting for the // buffer to be returned. mOutputBufferReturnedSignal.signal(); removeOutstandingBuffer(buffer); return res; }
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::returnBuffer(const camera3_stream_buffer &buffer, nsecs_t timestamp) { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = returnBufferLocked(buffer, timestamp); if (res == OK) { fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true); } return res; }
status_t Camera3Stream::cancelPrepareLocked() { status_t res = OK; // This function should be only called when the stream is mid-preparing. if (mState != STATE_PREPARING) { ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in " "PREPARING state %d", __FUNCTION__, mId, mState); return INVALID_OPERATION; } // Return all valid buffers to stream, in ERROR state to indicate // they weren't filled. for (size_t i = 0; i < mPreparedBufferIdx; i++) { mPreparedBuffers.editItemAt(i).release_fence = -1; mPreparedBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; returnBufferLocked(mPreparedBuffers[i], 0); } mPreparedBuffers.clear(); mPreparedBufferIdx = 0; mState = STATE_CONFIGURED; 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; }