diff options
Diffstat (limited to 'services/camera/libcameraservice/device3/Camera3Device.cpp')
-rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.cpp | 90 |
1 files changed, 63 insertions, 27 deletions
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 445c9c2..45d9421 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -2613,6 +2613,21 @@ status_t Camera3Device::RequestThread::clear( if (listener != NULL) { for (RequestList::iterator it = mRequestQueue.begin(); it != mRequestQueue.end(); ++it) { + // Abort the input buffers for reprocess requests. + if ((*it)->mInputStream != NULL) { + camera3_stream_buffer_t inputBuffer; + status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer); + if (res != OK) { + ALOGW("%s: %d: couldn't get input buffer while clearing the request " + "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res); + } else { + res = (*it)->mInputStream->returnInputBuffer(inputBuffer); + if (res != OK) { + ALOGE("%s: %d: couldn't return input buffer while clearing the request " + "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res); + } + } + } // Set the frame number this request would have had, if it // had been submitted; this frame number will not be reused. // The requestId and burstId fields were set when the request was @@ -2752,29 +2767,11 @@ bool Camera3Device::RequestThread::threadLoop() { __FUNCTION__); } - camera3_stream_buffer_t inputBuffer; uint32_t totalNumBuffers = 0; // Fill in buffers - if (nextRequest->mInputStream != NULL) { - res = nextRequest->mInputStream->getInputBuffer(&inputBuffer); - if (res != OK) { - // Can't get input buffer from gralloc queue - this could be due to - // disconnected queue or other producer misbehavior, so not a fatal - // error - ALOGE("RequestThread: Can't get input buffer, skipping request:" - " %s (%d)", strerror(-res), res); - Mutex::Autolock l(mRequestLock); - if (mListener != NULL) { - mListener->notifyError( - ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST, - nextRequest->mResultExtras); - } - cleanUpFailedRequest(request, nextRequest, outputBuffers); - return true; - } - request.input_buffer = &inputBuffer; + request.input_buffer = &nextRequest->mInputBuffer; totalNumBuffers += 1; } else { request.input_buffer = NULL; @@ -2792,11 +2789,13 @@ bool Camera3Device::RequestThread::threadLoop() { // error ALOGE("RequestThread: Can't get output buffer, skipping request:" " %s (%d)", strerror(-res), res); - Mutex::Autolock l(mRequestLock); - if (mListener != NULL) { - mListener->notifyError( - ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST, - nextRequest->mResultExtras); + { + Mutex::Autolock l(mRequestLock); + if (mListener != NULL) { + mListener->notifyError( + ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST, + nextRequest->mResultExtras); + } } cleanUpFailedRequest(request, nextRequest, outputBuffers); return true; @@ -2865,6 +2864,12 @@ bool Camera3Device::RequestThread::threadLoop() { nextRequest->mSettings.unlock(request.settings); } + // Unset as current request + { + Mutex::Autolock l(mRequestLock); + mNextRequest.clear(); + } + // Remove any previously queued triggers (after unlock) res = removeTriggers(mPrevRequest); if (res != OK) { @@ -2890,6 +2895,13 @@ bool Camera3Device::RequestThread::isStreamPending( sp<Camera3StreamInterface>& stream) { Mutex::Autolock l(mRequestLock); + if (mNextRequest != nullptr) { + for (const auto& s : mNextRequest->mOutputStreams) { + if (stream == s) return true; + } + if (stream == mNextRequest->mInputStream) return true; + } + for (const auto& request : mRequestQueue) { for (const auto& s : request->mOutputStreams) { if (stream == s) return true; @@ -2915,15 +2927,18 @@ void Camera3Device::RequestThread::cleanUpFailedRequest( if (request.settings != NULL) { nextRequest->mSettings.unlock(request.settings); } - if (request.input_buffer != NULL) { - request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR; - nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer)); + if (nextRequest->mInputStream != NULL) { + nextRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR; + nextRequest->mInputStream->returnInputBuffer(nextRequest->mInputBuffer); } for (size_t i = 0; i < request.num_output_buffers; i++) { outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR; nextRequest->mOutputStreams.editItemAt(i)->returnBuffer( outputBuffers[i], 0); } + + Mutex::Autolock l(mRequestLock); + mNextRequest.clear(); } sp<Camera3Device::CaptureRequest> @@ -3006,7 +3021,28 @@ sp<Camera3Device::CaptureRequest> nextRequest->mResultExtras.frameNumber = mFrameNumber++; nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId; nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId; + + // Since RequestThread::clear() removes buffers from the input stream, + // get the right buffer here before unlocking mRequestLock + if (nextRequest->mInputStream != NULL) { + res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer); + if (res != OK) { + // Can't get input buffer from gralloc queue - this could be due to + // disconnected queue or other producer misbehavior, so not a fatal + // error + ALOGE("%s: Can't get input buffer, skipping request:" + " %s (%d)", __FUNCTION__, strerror(-res), res); + if (mListener != NULL) { + mListener->notifyError( + ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST, + nextRequest->mResultExtras); + } + return NULL; + } + } } + mNextRequest = nextRequest; + return nextRequest; } |