Loading services/camera/libcameraservice/api2/CameraDeviceClient.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -507,6 +507,14 @@ binder::Status CameraDeviceClient::createStream( return res; if (!isStreamInfoValid) { // Streaming sharing is only supported for IMPLEMENTATION_DEFINED // formats. if (isShared && streamInfo.format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { String8 msg = String8::format("Camera %s: Stream sharing is only supported for " "IMPLEMENTATION_DEFINED format", mCameraIdStr.string()); ALOGW("%s: %s", __FUNCTION__, msg.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string()); } isStreamInfoValid = true; } Loading services/camera/libcameraservice/device3/Camera3Device.cpp +2 −8 Original line number Diff line number Diff line Loading @@ -3956,7 +3956,8 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } } res = outputStream->getBuffer(&outputBuffers->editItemAt(i)); res = outputStream->getBuffer(&outputBuffers->editItemAt(i), captureRequest->mOutputSurfaces[i]); if (res != OK) { // Can't get output buffer from gralloc queue - this could be due to // abandoned queue or other consumer misbehavior, so not a fatal Loading @@ -3968,13 +3969,6 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } halRequest->num_output_buffers++; res = outputStream->notifyRequestedSurfaces(halRequest->frame_number, captureRequest->mOutputSurfaces[i]); if (res != OK) { ALOGE("RequestThread: Cannot register output surfaces: %s (%d)", strerror(-res), res); return INVALID_OPERATION; } } totalNumBuffers += halRequest->num_output_buffers; Loading services/camera/libcameraservice/device3/Camera3DummyStream.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -36,7 +36,8 @@ Camera3DummyStream::~Camera3DummyStream() { } status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *) { status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *, const std::vector<size_t>&) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot produce buffers!", __FUNCTION__, mId); return INVALID_OPERATION; Loading Loading @@ -83,14 +84,6 @@ status_t Camera3DummyStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceF return OK; } status_t Camera3DummyStream::notifyRequestedSurfaces(uint32_t frame_number, const std::vector<size_t>& surface_ids) { (void) frame_number; (void) surface_ids; // Do nothing return OK; } status_t Camera3DummyStream::configureQueueLocked() { // Do nothing return OK; Loading services/camera/libcameraservice/device3/Camera3DummyStream.h +2 −4 Original line number Diff line number Diff line Loading @@ -56,9 +56,6 @@ class Camera3DummyStream : virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd); virtual status_t notifyRequestedSurfaces(uint32_t frame_number, const std::vector<size_t>& surface_ids); /** * Return if this output stream is for video encoding. */ Loading Loading @@ -102,7 +99,8 @@ class Camera3DummyStream : /** * Internal Camera3Stream interface */ virtual status_t getBufferLocked(camera3_stream_buffer *buffer); virtual status_t getBufferLocked(camera3_stream_buffer *buffer, const std::vector<size_t>& surface_ids = std::vector<size_t>()); virtual status_t returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp); Loading services/camera/libcameraservice/device3/Camera3OutputStream.cpp +87 −68 Original line number Diff line number Diff line Loading @@ -148,74 +148,18 @@ Camera3OutputStream::~Camera3OutputStream() { disconnectLocked(); } status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer, const std::vector<size_t>&) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd = -1; bool gotBufferFromManager = false; if (mUseBufferManager) { sp<GraphicBuffer> gb; res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, &fenceFd); if (res == OK) { // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a // successful return. anb = gb.get(); res = mConsumer->attachBuffer(anb); if (res != OK) { ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } gotBufferFromManager = true; ALOGV("Stream %d: Attached new buffer", getId()); } else if (res == ALREADY_EXISTS) { // Have sufficient free buffers already attached, can just // dequeue from buffer queue ALOGV("Stream %d: Reusing attached buffer", getId()); gotBufferFromManager = false; } else if (res != OK) { ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } if (!gotBufferFromManager) { /** * 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(); status_t res; res = getBufferLockedCommon(&anb, &fenceFd); if (res != OK) { ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING, // let prepareNextBuffer handle the error.) if (res == NO_INIT && mState == STATE_CONFIGURED) { mState = STATE_ABANDONED; } return res; } } /** * FenceFD now owned by HAL except in case of error, Loading @@ -227,6 +171,11 @@ status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { return OK; } status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer, ANativeWindowBuffer* buffer, int anwReleaseFence) { return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence); } status_t Camera3OutputStream::returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp) { Loading Loading @@ -269,6 +218,7 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( sp<ANativeWindow> currentConsumer = mConsumer; mLock.unlock(); ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle); /** * Return buffer back to ANativeWindow */ Loading @@ -276,13 +226,14 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( // Cancel buffer ALOGW("A frame is dropped for stream %d", mId); res = currentConsumer->cancelBuffer(currentConsumer.get(), container_of(buffer.buffer, ANativeWindowBuffer, handle), anwBuffer, anwReleaseFence); if (res != OK) { ALOGE("%s: Stream %d: Error cancelling buffer to native window:" " %s (%d)", __FUNCTION__, mId, strerror(-res), res); } notifyBufferReleased(anwBuffer); if (mUseBufferManager) { // Return this buffer back to buffer manager. mBufferReleasedListener->onBufferReleased(); Loading @@ -308,9 +259,7 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( return res; } res = currentConsumer->queueBuffer(currentConsumer.get(), container_of(buffer.buffer, ANativeWindowBuffer, handle), anwReleaseFence); res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence); if (res != OK) { ALOGE("%s: Stream %d: Error queueing buffer to native window: " "%s (%d)", __FUNCTION__, mId, strerror(-res), res); Loading Loading @@ -527,6 +476,76 @@ status_t Camera3OutputStream::configureConsumerQueueLocked() { return OK; } status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } bool gotBufferFromManager = false; if (mUseBufferManager) { sp<GraphicBuffer> gb; res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, fenceFd); if (res == OK) { // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a // successful return. *anb = gb.get(); res = mConsumer->attachBuffer(*anb); if (res != OK) { ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } gotBufferFromManager = true; ALOGV("Stream %d: Attached new buffer", getId()); } else if (res == ALREADY_EXISTS) { // Have sufficient free buffers already attached, can just // dequeue from buffer queue ALOGV("Stream %d: Reusing attached buffer", getId()); gotBufferFromManager = false; } else if (res != OK) { ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } if (!gotBufferFromManager) { /** * 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); // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING, // let prepareNextBuffer handle the error.) if (res == NO_INIT && mState == STATE_CONFIGURED) { mState = STATE_ABANDONED; } return res; } } return res; } status_t Camera3OutputStream::disconnectLocked() { status_t res; Loading Loading @@ -702,8 +721,7 @@ status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fence return OK; } status_t Camera3OutputStream::notifyRequestedSurfaces(uint32_t /*frame_number*/, const std::vector<size_t>& /*surface_ids*/) { status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) { return OK; } Loading @@ -717,6 +735,7 @@ bool Camera3OutputStream::isConsumerConfigurationDeferred(size_t surface_id) con } status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) { Mutex::Autolock l(mLock); if (consumers.size() != 1) { ALOGE("%s: it's illegal to set %zu consumer surfaces!", __FUNCTION__, consumers.size()); Loading Loading
services/camera/libcameraservice/api2/CameraDeviceClient.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -507,6 +507,14 @@ binder::Status CameraDeviceClient::createStream( return res; if (!isStreamInfoValid) { // Streaming sharing is only supported for IMPLEMENTATION_DEFINED // formats. if (isShared && streamInfo.format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { String8 msg = String8::format("Camera %s: Stream sharing is only supported for " "IMPLEMENTATION_DEFINED format", mCameraIdStr.string()); ALOGW("%s: %s", __FUNCTION__, msg.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string()); } isStreamInfoValid = true; } Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +2 −8 Original line number Diff line number Diff line Loading @@ -3956,7 +3956,8 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } } res = outputStream->getBuffer(&outputBuffers->editItemAt(i)); res = outputStream->getBuffer(&outputBuffers->editItemAt(i), captureRequest->mOutputSurfaces[i]); if (res != OK) { // Can't get output buffer from gralloc queue - this could be due to // abandoned queue or other consumer misbehavior, so not a fatal Loading @@ -3968,13 +3969,6 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } halRequest->num_output_buffers++; res = outputStream->notifyRequestedSurfaces(halRequest->frame_number, captureRequest->mOutputSurfaces[i]); if (res != OK) { ALOGE("RequestThread: Cannot register output surfaces: %s (%d)", strerror(-res), res); return INVALID_OPERATION; } } totalNumBuffers += halRequest->num_output_buffers; Loading
services/camera/libcameraservice/device3/Camera3DummyStream.cpp +2 −9 Original line number Diff line number Diff line Loading @@ -36,7 +36,8 @@ Camera3DummyStream::~Camera3DummyStream() { } status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *) { status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *, const std::vector<size_t>&) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot produce buffers!", __FUNCTION__, mId); return INVALID_OPERATION; Loading Loading @@ -83,14 +84,6 @@ status_t Camera3DummyStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceF return OK; } status_t Camera3DummyStream::notifyRequestedSurfaces(uint32_t frame_number, const std::vector<size_t>& surface_ids) { (void) frame_number; (void) surface_ids; // Do nothing return OK; } status_t Camera3DummyStream::configureQueueLocked() { // Do nothing return OK; Loading
services/camera/libcameraservice/device3/Camera3DummyStream.h +2 −4 Original line number Diff line number Diff line Loading @@ -56,9 +56,6 @@ class Camera3DummyStream : virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd); virtual status_t notifyRequestedSurfaces(uint32_t frame_number, const std::vector<size_t>& surface_ids); /** * Return if this output stream is for video encoding. */ Loading Loading @@ -102,7 +99,8 @@ class Camera3DummyStream : /** * Internal Camera3Stream interface */ virtual status_t getBufferLocked(camera3_stream_buffer *buffer); virtual status_t getBufferLocked(camera3_stream_buffer *buffer, const std::vector<size_t>& surface_ids = std::vector<size_t>()); virtual status_t returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp); Loading
services/camera/libcameraservice/device3/Camera3OutputStream.cpp +87 −68 Original line number Diff line number Diff line Loading @@ -148,74 +148,18 @@ Camera3OutputStream::~Camera3OutputStream() { disconnectLocked(); } status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer, const std::vector<size_t>&) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } ANativeWindowBuffer* anb; int fenceFd = -1; bool gotBufferFromManager = false; if (mUseBufferManager) { sp<GraphicBuffer> gb; res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, &fenceFd); if (res == OK) { // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a // successful return. anb = gb.get(); res = mConsumer->attachBuffer(anb); if (res != OK) { ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } gotBufferFromManager = true; ALOGV("Stream %d: Attached new buffer", getId()); } else if (res == ALREADY_EXISTS) { // Have sufficient free buffers already attached, can just // dequeue from buffer queue ALOGV("Stream %d: Reusing attached buffer", getId()); gotBufferFromManager = false; } else if (res != OK) { ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } if (!gotBufferFromManager) { /** * 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(); status_t res; res = getBufferLockedCommon(&anb, &fenceFd); if (res != OK) { ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING, // let prepareNextBuffer handle the error.) if (res == NO_INIT && mState == STATE_CONFIGURED) { mState = STATE_ABANDONED; } return res; } } /** * FenceFD now owned by HAL except in case of error, Loading @@ -227,6 +171,11 @@ status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) { return OK; } status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer, ANativeWindowBuffer* buffer, int anwReleaseFence) { return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence); } status_t Camera3OutputStream::returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp) { Loading Loading @@ -269,6 +218,7 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( sp<ANativeWindow> currentConsumer = mConsumer; mLock.unlock(); ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle); /** * Return buffer back to ANativeWindow */ Loading @@ -276,13 +226,14 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( // Cancel buffer ALOGW("A frame is dropped for stream %d", mId); res = currentConsumer->cancelBuffer(currentConsumer.get(), container_of(buffer.buffer, ANativeWindowBuffer, handle), anwBuffer, anwReleaseFence); if (res != OK) { ALOGE("%s: Stream %d: Error cancelling buffer to native window:" " %s (%d)", __FUNCTION__, mId, strerror(-res), res); } notifyBufferReleased(anwBuffer); if (mUseBufferManager) { // Return this buffer back to buffer manager. mBufferReleasedListener->onBufferReleased(); Loading @@ -308,9 +259,7 @@ status_t Camera3OutputStream::returnBufferCheckedLocked( return res; } res = currentConsumer->queueBuffer(currentConsumer.get(), container_of(buffer.buffer, ANativeWindowBuffer, handle), anwReleaseFence); res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence); if (res != OK) { ALOGE("%s: Stream %d: Error queueing buffer to native window: " "%s (%d)", __FUNCTION__, mId, strerror(-res), res); Loading Loading @@ -527,6 +476,76 @@ status_t Camera3OutputStream::configureConsumerQueueLocked() { return OK; } status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) { ATRACE_CALL(); status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } bool gotBufferFromManager = false; if (mUseBufferManager) { sp<GraphicBuffer> gb; res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, fenceFd); if (res == OK) { // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a // successful return. *anb = gb.get(); res = mConsumer->attachBuffer(*anb); if (res != OK) { ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } gotBufferFromManager = true; ALOGV("Stream %d: Attached new buffer", getId()); } else if (res == ALREADY_EXISTS) { // Have sufficient free buffers already attached, can just // dequeue from buffer queue ALOGV("Stream %d: Reusing attached buffer", getId()); gotBufferFromManager = false; } else if (res != OK) { ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } if (!gotBufferFromManager) { /** * 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); // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING, // let prepareNextBuffer handle the error.) if (res == NO_INIT && mState == STATE_CONFIGURED) { mState = STATE_ABANDONED; } return res; } } return res; } status_t Camera3OutputStream::disconnectLocked() { status_t res; Loading Loading @@ -702,8 +721,7 @@ status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fence return OK; } status_t Camera3OutputStream::notifyRequestedSurfaces(uint32_t /*frame_number*/, const std::vector<size_t>& /*surface_ids*/) { status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) { return OK; } Loading @@ -717,6 +735,7 @@ bool Camera3OutputStream::isConsumerConfigurationDeferred(size_t surface_id) con } status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) { Mutex::Autolock l(mLock); if (consumers.size() != 1) { ALOGE("%s: it's illegal to set %zu consumer surfaces!", __FUNCTION__, consumers.size()); Loading