From b3a80b1c627035a05eda702e7f8ad6d18b7d54f5 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Tue, 4 Sep 2018 12:13:05 -0700 Subject: [PATCH] Camera: extend getBuffer wait timeout In extreme cases, HAL needs to wait until all inflight requests are fulfilled before it can return a buffer, so extend the getBuffer wait accordingly. Test: partner testing, smoke test Pixel Bug: 113660745 Change-Id: I363098004e70b75e11651fe0f1c75efcfda970f4 --- .../libcameraservice/device3/Camera3Device.cpp | 17 ++++++++++------- .../libcameraservice/device3/Camera3Device.h | 1 + .../libcameraservice/device3/Camera3Stream.cpp | 8 ++++++-- .../libcameraservice/device3/Camera3Stream.h | 1 + .../device3/Camera3StreamInterface.h | 1 + 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 0db5642030..25c9d3c30e 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -4854,6 +4854,15 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { captureRequest->mOutputStreams.size()); halRequest->output_buffers = outputBuffers->array(); std::set requestedPhysicalCameras; + + sp parent = mParent.promote(); + if (parent == NULL) { + // Should not happen, and nowhere to send errors to, so just log it + CLOGE("RequestThread: Parent is gone"); + return INVALID_OPERATION; + } + nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration(); + for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) { sp outputStream = captureRequest->mOutputStreams.editItemAt(j); @@ -4874,6 +4883,7 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { } res = outputStream->getBuffer(&outputBuffers->editItemAt(j), + waitDuration, captureRequest->mOutputSurfaces[j]); if (res != OK) { // Can't get output buffer from gralloc queue - this could be due to @@ -4900,13 +4910,6 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { totalNumBuffers += halRequest->num_output_buffers; // Log request in the in-flight queue - sp parent = mParent.promote(); - if (parent == NULL) { - // Should not happen, and nowhere to send errors to, so just log it - CLOGE("RequestThread: Parent is gone"); - return INVALID_OPERATION; - } - // If this request list is for constrained high speed recording (not // preview), and the current request is not the last one in the batch, // do not send callback to the app. diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index ef3cbc4e9c..131d62f5d6 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -221,6 +221,7 @@ class Camera3Device : static const size_t kInFlightWarnLimitHighSpeed = 256; // batch size 32 * pipe depth 8 static const nsecs_t kDefaultExpectedDuration = 100000000; // 100 ms static const nsecs_t kMinInflightDuration = 5000000000; // 5 s + static const nsecs_t kBaseGetBufferWait = 3000000000; // 3 sec. // SCHED_FIFO priority for request submission thread in HFR mode static const int kRequestThreadPriority = 1; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 1105b754fa..87476612a4 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -569,6 +569,7 @@ status_t Camera3Stream::tearDown() { } status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer, + nsecs_t waitBufferTimeout, const std::vector& surface_ids) { ATRACE_CALL(); Mutex::Autolock l(mLock); @@ -586,13 +587,16 @@ status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer, ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.", __FUNCTION__, camera3_stream::max_buffers); nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC); - res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration); + 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__, kWaitForBufferDuration / 1000000LL, + __FUNCTION__, waitBufferTimeout / 1000000LL, camera3_stream::max_buffers); } return res; diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h index a60cb56818..e6fb7f9f42 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.h +++ b/services/camera/libcameraservice/device3/Camera3Stream.h @@ -311,6 +311,7 @@ class Camera3Stream : * */ status_t getBuffer(camera3_stream_buffer *buffer, + nsecs_t waitBufferTimeout, const std::vector& surface_ids = std::vector()); /** diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h index 9ed7184203..2dde1c3258 100644 --- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h +++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h @@ -237,6 +237,7 @@ class Camera3StreamInterface : public virtual RefBase { * */ virtual status_t getBuffer(camera3_stream_buffer *buffer, + nsecs_t waitBufferTimeout, const std::vector& surface_ids = std::vector()) = 0; /**