[PATCH v4 5/7] android: Drop notify CAMERA3_MSG_ERROR_REQUEST when a request fails
Harvey Yang
chenghaoyang at chromium.org
Tue Dec 10 15:23:58 CET 2024
According to Android Camera API v3.2, CAMERA3_MSG_ERROR_REQUEST is used
for requests that have not done any processing. When a request is
completed with failure, CAMERA3_MSG_ERROR_RESULT should be used instead.
To avoid code duplication, when CameraMetadata cannot be generated,
CAMERA3_MSG_ERROR_RESULT is notified after process_capture_result.
Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang at chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
---
src/android/camera_device.cpp | 40 ++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index f3f570544..3b10f207e 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -1182,6 +1182,18 @@ void CameraDevice::requestComplete(Request *request)
* post-processing/compression fails.
*/
for (auto &buffer : descriptor->buffers_) {
+ for (auto &[_, frameBuffer] : request->buffers()) {
+ if (buffer.srcBuffer != frameBuffer &&
+ buffer.frameBuffer.get() != frameBuffer)
+ continue;
+
+ StreamBuffer::Status status = StreamBuffer::Status::Success;
+ if (frameBuffer->metadata().status != FrameMetadata::FrameSuccess) {
+ status = StreamBuffer::Status::Error;
+ }
+ setBufferStatus(buffer, status);
+ }
+
CameraStream *stream = buffer.stream;
/*
@@ -1198,22 +1210,18 @@ void CameraDevice::requestComplete(Request *request)
if (fence)
buffer.fence = fence->release();
}
- buffer.status = StreamBuffer::Status::Success;
}
/*
- * If the Request has failed, abort the request by notifying the error
- * and complete the request with all buffers in error state.
+ * If the Request has failed, complete the request with all buffers in
+ * error state and notify an error result.
*/
if (request->status() != Request::RequestComplete) {
LOG(HAL, Error) << "Request " << request->cookie()
<< " not successfully completed: "
<< request->status();
- abortRequest(descriptor);
- completeDescriptor(descriptor);
-
- return;
+ descriptor->status_ = Camera3RequestDescriptor::Status::Error;
}
/*
@@ -1238,7 +1246,7 @@ void CameraDevice::requestComplete(Request *request)
*/
descriptor->resultMetadata_ = getResultMetadata(*descriptor);
if (!descriptor->resultMetadata_) {
- notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
+ descriptor->status_ = Camera3RequestDescriptor::Status::Error;
/*
* The camera framework expects an empty metadata pack on error.
@@ -1271,7 +1279,13 @@ void CameraDevice::requestComplete(Request *request)
continue;
}
+ if (buffer->status == StreamBuffer::Status::Error) {
+ iter = descriptor->pendingStreamsToProcess_.erase(iter);
+ continue;
+ }
+
++iter;
+
int ret = stream->process(buffer);
if (ret) {
setBufferStatus(*buffer, StreamBuffer::Status::Error);
@@ -1324,6 +1338,16 @@ void CameraDevice::sendCaptureResults()
descriptors_.pop();
sendCaptureResult(descriptor.get());
+
+ /*
+ * Call notify with CAMERA3_MSG_ERROR_RESULT to indicate some
+ * of the expected result metadata might not be available
+ * because the capture is cancelled by the camera. Only notify
+ * it when the final result is sent, since Android will ignore
+ * the following metadata.
+ */
+ if (descriptor->status_ == Camera3RequestDescriptor::Status::Error)
+ notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT);
}
}
--
2.47.0.338.g60cca15819-goog
More information about the libcamera-devel
mailing list