Loading services/camera/libcameraservice/device3/Camera3OutputStream.cpp +0 −59 Original line number Diff line number Diff line Loading @@ -235,65 +235,6 @@ status_t Camera3OutputStream::getBufferLocked(camera_stream_buffer *buffer, return OK; } status_t Camera3OutputStream::getBuffersLocked(std::vector<OutstandingBuffer>* outBuffers) { status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } if (mUseBufferManager) { ALOGE("%s: stream %d is managed by buffer manager and does not support batch operation", __FUNCTION__, mId); return INVALID_OPERATION; } sp<Surface> consumer = mConsumer; /** * 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. */ mLock.unlock(); size_t numBuffersRequested = outBuffers->size(); std::vector<Surface::BatchBuffer> buffers(numBuffersRequested); nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC); res = consumer->dequeueBuffers(&buffers); nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC); mDequeueBufferLatency.add(dequeueStart, dequeueEnd); mLock.lock(); if (res != OK) { if (shouldLogError(res, mState)) { ALOGE("%s: Stream %d: Can't dequeue %zu output buffers: %s (%d)", __FUNCTION__, mId, numBuffersRequested, strerror(-res), res); } checkRetAndSetAbandonedLocked(res); return res; } checkRemovedBuffersLocked(); /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ for (size_t i = 0; i < numBuffersRequested; i++) { handoutBufferLocked(*(outBuffers->at(i).outBuffer), &(buffers[i].buffer->handle), /*acquireFence*/buffers[i].fenceFd, /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true); } return OK; } status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer, ANativeWindowBuffer* buffer, int anwReleaseFence, const std::vector<size_t>&) { Loading services/camera/libcameraservice/device3/Camera3OutputStream.h +0 −2 Original line number Diff line number Diff line Loading @@ -388,8 +388,6 @@ class Camera3OutputStream : virtual status_t getBufferLocked(camera_stream_buffer *buffer, const std::vector<size_t>& surface_ids); virtual status_t getBuffersLocked(/*out*/std::vector<OutstandingBuffer>* buffers) override; virtual status_t returnBufferLocked( const camera_stream_buffer &buffer, nsecs_t timestamp, nsecs_t readoutTimestamp, Loading services/camera/libcameraservice/device3/Camera3Stream.cpp +0 −91 Original line number Diff line number Diff line Loading @@ -969,11 +969,6 @@ status_t Camera3Stream::getBufferLocked(camera_stream_buffer *, return INVALID_OPERATION; } status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) { ALOGE("%s: This type of stream does not support output", __FUNCTION__); return INVALID_OPERATION; } status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &, nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) { ALOGE("%s: This type of stream does not support output", __FUNCTION__); Loading Loading @@ -1047,92 +1042,6 @@ void Camera3Stream::setBufferFreedListener( mBufferFreedListener = listener; } status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout) { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = OK; if (buffers == nullptr) { ALOGI("%s: buffers must not be null!", __FUNCTION__); return BAD_VALUE; } size_t numBuffersRequested = buffers->size(); if (numBuffersRequested == 0) { ALOGE("%s: 0 buffers are requested!", __FUNCTION__); return BAD_VALUE; } // 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); if (mState == STATE_ABANDONED) { return DEAD_OBJECT; } else { return INVALID_OPERATION; } } size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked(); size_t numCachedBuffers = getCachedOutputBufferCountLocked(); size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked(); // Wait for new buffer returned back if we are running into the limit. There // are 2 limits: // 1. The number of HAL buffers is greater than max_buffers // 2. The number of HAL buffers + cached buffers is greater than max_buffers // + maxCachedBuffers while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers || numOutstandingBuffers + numCachedBuffers + numBuffersRequested > camera_stream::max_buffers + maxNumCachedBuffers) { ALOGV("%s: Already dequeued %zu(+%zu) output buffers and requesting %zu " "(max is %d(+%zu)), waiting.", __FUNCTION__, numOutstandingBuffers, numCachedBuffers, numBuffersRequested, camera_stream::max_buffers, maxNumCachedBuffers); nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC); if (waitBufferTimeout < kWaitForBufferDuration) { waitBufferTimeout = kWaitForBufferDuration; } res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout); nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC); mBufferLimitLatency.add(waitStart, waitEnd); if (res != OK) { if (res == TIMED_OUT) { ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)", __FUNCTION__, waitBufferTimeout / 1000000LL, camera_stream::max_buffers); } return res; } size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked(); size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked(); if (updatedNumOutstandingBuffers >= numOutstandingBuffers && updatedNumCachedBuffers == numCachedBuffers) { ALOGE("%s: outstanding buffer count goes from %zu to %zu, " "getBuffer(s) call must not run in parallel!", __FUNCTION__, numOutstandingBuffers, updatedNumOutstandingBuffers); return INVALID_OPERATION; } numOutstandingBuffers = updatedNumOutstandingBuffers; numCachedBuffers = updatedNumCachedBuffers; } res = getBuffersLocked(buffers); if (res == OK) { for (auto& outstandingBuffer : *buffers) { camera_stream_buffer* buffer = outstandingBuffer.outBuffer; fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); if (buffer->buffer) { Mutex::Autolock l(mOutstandingBuffersLock); mOutstandingBuffers.push_back(*buffer->buffer); } } } return res; } void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw, int64_t dynamicRangeProfile) { auto& mapper = GraphicBufferMapper::get(); Loading services/camera/libcameraservice/device3/Camera3Stream.h +0 −8 Original line number Diff line number Diff line Loading @@ -342,12 +342,6 @@ class Camera3Stream : nsecs_t waitBufferTimeout, const std::vector<size_t>& surface_ids = std::vector<size_t>()); /** * Similar to getBuffer() except this method fills multiple buffers. */ status_t getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout); /** * Return a buffer to the stream after use by the HAL. * Loading Loading @@ -535,8 +529,6 @@ class Camera3Stream : nsecs_t timestamp, nsecs_t readoutTimestamp, int32_t transform, const std::vector<size_t>& surface_ids = std::vector<size_t>()); virtual status_t getBuffersLocked(std::vector<OutstandingBuffer>*); virtual status_t getInputBufferLocked(camera_stream_buffer *buffer, Size* size); virtual status_t returnInputBufferLocked( Loading services/camera/libcameraservice/device3/Camera3StreamInterface.h +0 −5 Original line number Diff line number Diff line Loading @@ -395,11 +395,6 @@ class Camera3StreamInterface : public virtual RefBase { */ std::vector<size_t> surface_ids; }; /** * Similar to getBuffer() except this method fills multiple buffers. */ virtual status_t getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout) = 0; /** * Return a buffer to the stream after use by the HAL. Loading Loading
services/camera/libcameraservice/device3/Camera3OutputStream.cpp +0 −59 Original line number Diff line number Diff line Loading @@ -235,65 +235,6 @@ status_t Camera3OutputStream::getBufferLocked(camera_stream_buffer *buffer, return OK; } status_t Camera3OutputStream::getBuffersLocked(std::vector<OutstandingBuffer>* outBuffers) { status_t res; if ((res = getBufferPreconditionCheckLocked()) != OK) { return res; } if (mUseBufferManager) { ALOGE("%s: stream %d is managed by buffer manager and does not support batch operation", __FUNCTION__, mId); return INVALID_OPERATION; } sp<Surface> consumer = mConsumer; /** * 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. */ mLock.unlock(); size_t numBuffersRequested = outBuffers->size(); std::vector<Surface::BatchBuffer> buffers(numBuffersRequested); nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC); res = consumer->dequeueBuffers(&buffers); nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC); mDequeueBufferLatency.add(dequeueStart, dequeueEnd); mLock.lock(); if (res != OK) { if (shouldLogError(res, mState)) { ALOGE("%s: Stream %d: Can't dequeue %zu output buffers: %s (%d)", __FUNCTION__, mId, numBuffersRequested, strerror(-res), res); } checkRetAndSetAbandonedLocked(res); return res; } checkRemovedBuffersLocked(); /** * FenceFD now owned by HAL except in case of error, * in which case we reassign it to acquire_fence */ for (size_t i = 0; i < numBuffersRequested; i++) { handoutBufferLocked(*(outBuffers->at(i).outBuffer), &(buffers[i].buffer->handle), /*acquireFence*/buffers[i].fenceFd, /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true); } return OK; } status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer, ANativeWindowBuffer* buffer, int anwReleaseFence, const std::vector<size_t>&) { Loading
services/camera/libcameraservice/device3/Camera3OutputStream.h +0 −2 Original line number Diff line number Diff line Loading @@ -388,8 +388,6 @@ class Camera3OutputStream : virtual status_t getBufferLocked(camera_stream_buffer *buffer, const std::vector<size_t>& surface_ids); virtual status_t getBuffersLocked(/*out*/std::vector<OutstandingBuffer>* buffers) override; virtual status_t returnBufferLocked( const camera_stream_buffer &buffer, nsecs_t timestamp, nsecs_t readoutTimestamp, Loading
services/camera/libcameraservice/device3/Camera3Stream.cpp +0 −91 Original line number Diff line number Diff line Loading @@ -969,11 +969,6 @@ status_t Camera3Stream::getBufferLocked(camera_stream_buffer *, return INVALID_OPERATION; } status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) { ALOGE("%s: This type of stream does not support output", __FUNCTION__); return INVALID_OPERATION; } status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &, nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) { ALOGE("%s: This type of stream does not support output", __FUNCTION__); Loading Loading @@ -1047,92 +1042,6 @@ void Camera3Stream::setBufferFreedListener( mBufferFreedListener = listener; } status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout) { ATRACE_CALL(); Mutex::Autolock l(mLock); status_t res = OK; if (buffers == nullptr) { ALOGI("%s: buffers must not be null!", __FUNCTION__); return BAD_VALUE; } size_t numBuffersRequested = buffers->size(); if (numBuffersRequested == 0) { ALOGE("%s: 0 buffers are requested!", __FUNCTION__); return BAD_VALUE; } // 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); if (mState == STATE_ABANDONED) { return DEAD_OBJECT; } else { return INVALID_OPERATION; } } size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked(); size_t numCachedBuffers = getCachedOutputBufferCountLocked(); size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked(); // Wait for new buffer returned back if we are running into the limit. There // are 2 limits: // 1. The number of HAL buffers is greater than max_buffers // 2. The number of HAL buffers + cached buffers is greater than max_buffers // + maxCachedBuffers while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers || numOutstandingBuffers + numCachedBuffers + numBuffersRequested > camera_stream::max_buffers + maxNumCachedBuffers) { ALOGV("%s: Already dequeued %zu(+%zu) output buffers and requesting %zu " "(max is %d(+%zu)), waiting.", __FUNCTION__, numOutstandingBuffers, numCachedBuffers, numBuffersRequested, camera_stream::max_buffers, maxNumCachedBuffers); nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC); if (waitBufferTimeout < kWaitForBufferDuration) { waitBufferTimeout = kWaitForBufferDuration; } res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout); nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC); mBufferLimitLatency.add(waitStart, waitEnd); if (res != OK) { if (res == TIMED_OUT) { ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)", __FUNCTION__, waitBufferTimeout / 1000000LL, camera_stream::max_buffers); } return res; } size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked(); size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked(); if (updatedNumOutstandingBuffers >= numOutstandingBuffers && updatedNumCachedBuffers == numCachedBuffers) { ALOGE("%s: outstanding buffer count goes from %zu to %zu, " "getBuffer(s) call must not run in parallel!", __FUNCTION__, numOutstandingBuffers, updatedNumOutstandingBuffers); return INVALID_OPERATION; } numOutstandingBuffers = updatedNumOutstandingBuffers; numCachedBuffers = updatedNumCachedBuffers; } res = getBuffersLocked(buffers); if (res == OK) { for (auto& outstandingBuffer : *buffers) { camera_stream_buffer* buffer = outstandingBuffer.outBuffer; fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true); if (buffer->buffer) { Mutex::Autolock l(mOutstandingBuffersLock); mOutstandingBuffers.push_back(*buffer->buffer); } } } return res; } void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw, int64_t dynamicRangeProfile) { auto& mapper = GraphicBufferMapper::get(); Loading
services/camera/libcameraservice/device3/Camera3Stream.h +0 −8 Original line number Diff line number Diff line Loading @@ -342,12 +342,6 @@ class Camera3Stream : nsecs_t waitBufferTimeout, const std::vector<size_t>& surface_ids = std::vector<size_t>()); /** * Similar to getBuffer() except this method fills multiple buffers. */ status_t getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout); /** * Return a buffer to the stream after use by the HAL. * Loading Loading @@ -535,8 +529,6 @@ class Camera3Stream : nsecs_t timestamp, nsecs_t readoutTimestamp, int32_t transform, const std::vector<size_t>& surface_ids = std::vector<size_t>()); virtual status_t getBuffersLocked(std::vector<OutstandingBuffer>*); virtual status_t getInputBufferLocked(camera_stream_buffer *buffer, Size* size); virtual status_t returnInputBufferLocked( Loading
services/camera/libcameraservice/device3/Camera3StreamInterface.h +0 −5 Original line number Diff line number Diff line Loading @@ -395,11 +395,6 @@ class Camera3StreamInterface : public virtual RefBase { */ std::vector<size_t> surface_ids; }; /** * Similar to getBuffer() except this method fills multiple buffers. */ virtual status_t getBuffers(std::vector<OutstandingBuffer>* buffers, nsecs_t waitBufferTimeout) = 0; /** * Return a buffer to the stream after use by the HAL. Loading