Camera: Handling out-of-order request id
For the API1 path, the request id is assumed to be in order when syncing
with the device for the request to apply. This is not always the
case, as errors can cause out-of-order and this can cause delay in the
API1 path.
This change will address this by maintaining the request id list.
Bug: 288065275
Test: Manual test with the app using API1,
atest -c -d cts/tests/camera/src/android/hardware/cts/
Change-Id: Iaacf349408c751e178173d6e03d41f1335749c27
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 8348cd9..5b5892a 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -70,7 +70,9 @@
cameraDeviceId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
/*legacyClient*/ true),
- mParameters(api1CameraId, cameraFacing)
+ mParameters(api1CameraId, cameraFacing),
+ mLatestRequestIds(kMaxRequestIds),
+ mLatestFailedRequestIds(kMaxRequestIds)
{
ATRACE_CALL();
@@ -1843,7 +1845,7 @@
(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT == errorCode)) {
Mutex::Autolock al(mLatestRequestMutex);
- mLatestFailedRequestId = resultExtras.requestId;
+ mLatestFailedRequestIds.add(resultExtras.requestId);
mLatestRequestSignal.signal();
}
mCaptureSequencer->notifyError(errorCode, resultExtras);
@@ -2418,7 +2420,10 @@
status_t Camera2Client::waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout) {
Mutex::Autolock l(mLatestRequestMutex);
- while ((mLatestRequestId != requestId) && (mLatestFailedRequestId != requestId)) {
+ while ((std::find(mLatestRequestIds.begin(), mLatestRequestIds.end(), requestId) ==
+ mLatestRequestIds.end()) &&
+ (std::find(mLatestFailedRequestIds.begin(), mLatestFailedRequestIds.end(), requestId) ==
+ mLatestFailedRequestIds.end())) {
nsecs_t startTime = systemTime();
auto res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
@@ -2427,13 +2432,14 @@
timeout -= (systemTime() - startTime);
}
- return (mLatestRequestId == requestId) ? OK : DEAD_OBJECT;
+ return (std::find(mLatestRequestIds.begin(), mLatestRequestIds.end(), requestId) !=
+ mLatestRequestIds.end()) ? OK : DEAD_OBJECT;
}
void Camera2Client::notifyRequestId(int32_t requestId) {
Mutex::Autolock al(mLatestRequestMutex);
- mLatestRequestId = requestId;
+ mLatestRequestIds.add(requestId);
mLatestRequestSignal.signal();
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 6bdb644..a7ea823 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -22,11 +22,7 @@
#include "common/Camera2ClientBase.h"
#include "api1/client2/Parameters.h"
#include "api1/client2/FrameProcessor.h"
-//#include "api1/client2/StreamingProcessor.h"
-//#include "api1/client2/JpegProcessor.h"
-//#include "api1/client2/ZslProcessor.h"
-//#include "api1/client2/CaptureSequencer.h"
-//#include "api1/client2/CallbackProcessor.h"
+#include <media/RingBuffer.h>
namespace android {
@@ -263,8 +259,8 @@
mutable Mutex mLatestRequestMutex;
Condition mLatestRequestSignal;
- int32_t mLatestRequestId = -1;
- int32_t mLatestFailedRequestId = -1;
+ static constexpr size_t kMaxRequestIds = BufferQueueDefs::NUM_BUFFER_SLOTS;
+ RingBuffer<int32_t> mLatestRequestIds, mLatestFailedRequestIds;
status_t waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout);
status_t waitUntilCurrentRequestIdLocked();
};
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 61c3298..9b5f09f 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3030,6 +3030,7 @@
mNotifyPipelineDrain(false),
mFrameNumber(0),
mLatestRequestId(NAME_NOT_FOUND),
+ mLatestFailedRequestId(NAME_NOT_FOUND),
mCurrentAfTriggerId(0),
mCurrentPreCaptureTriggerId(0),
mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
@@ -3281,7 +3282,7 @@
ATRACE_CALL();
Mutex::Autolock l(mLatestRequestMutex);
status_t res;
- while (mLatestRequestId != requestId) {
+ while (mLatestRequestId != requestId && mLatestFailedRequestId != requestId) {
nsecs_t startTime = systemTime();
res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
@@ -4356,6 +4357,12 @@
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
captureRequest->mResultExtras);
}
+ {
+ Mutex::Autolock al(mLatestRequestMutex);
+
+ mLatestFailedRequestId = captureRequest->mResultExtras.requestId;
+ mLatestRequestSignal.signal();
+ }
}
// Remove yet-to-be submitted inflight request from inflightMap
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index b1dd135..aa1d55a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1142,6 +1142,7 @@
Condition mLatestRequestSignal;
// android.request.id for latest process_capture_request
int32_t mLatestRequestId;
+ int32_t mLatestFailedRequestId;
CameraMetadata mLatestRequest;
std::unordered_map<std::string, CameraMetadata> mLatestPhysicalRequest;