Merge changes I86ba4225,I04d8e19a into main
* changes:
ExternalCameraHAL: fix CTS failures with callback for errors
ExternalCameraHAL: improve buffer and error handling
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index 479167c..91196d4 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -1726,8 +1726,8 @@
result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
result.outputBuffers[i].status = BufferStatus::ERROR;
if (req->buffers[i].acquireFence >= 0) {
- native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
- handle->data[0] = req->buffers[i].acquireFence;
+ // numFds = 0 for error
+ native_handle_t* handle = native_handle_create(/*numFds*/ 0, /*numInts*/ 0);
result.outputBuffers[i].releaseFence = android::dupToAidl(handle);
native_handle_delete(handle);
}
@@ -1961,9 +1961,16 @@
std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqProcTimeoutMs);
auto st = mRequestDoneCond.wait_for(lk, timeout);
if (st == std::cv_status::timeout) {
+ mRequestingBuffer = false;
ALOGE("%s: wait for buffer request finish timeout!", __FUNCTION__);
return -1;
}
+
+ if (mPendingReturnBufferReqs.empty()) {
+ mRequestingBuffer = false;
+ ALOGE("%s: cameraservice did not return any buffers!", __FUNCTION__);
+ return -1;
+ }
}
mRequestingBuffer = false;
*outBufReqs = std::move(mPendingReturnBufferReqs);
@@ -2013,6 +2020,8 @@
if (!ret.isOk()) {
ALOGE("%s: Transaction error: %d:%d", __FUNCTION__, ret.getExceptionCode(),
ret.getServiceSpecificError());
+ mBufferReqs.clear();
+ mRequestDoneCond.notify_one();
return false;
}
@@ -2021,17 +2030,24 @@
if (bufRets.size() != mHalBufferReqs.size()) {
ALOGE("%s: expect %zu buffer requests returned, only got %zu", __FUNCTION__,
mHalBufferReqs.size(), bufRets.size());
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
return false;
}
auto parent = mParent.lock();
if (parent == nullptr) {
ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
return false;
}
std::vector<int> importedFences;
importedFences.resize(bufRets.size());
+ bool hasError = false;
for (size_t i = 0; i < bufRets.size(); i++) {
int streamId = bufRets[i].streamId;
switch (bufRets[i].val.getTag()) {
@@ -2042,7 +2058,8 @@
bufRets[i].val.get<StreamBuffersVal::Tag::buffers>();
if (hBufs.size() != 1) {
ALOGE("%s: expect 1 buffer returned, got %zu!", __FUNCTION__, hBufs.size());
- return false;
+ hasError = true;
+ break;
}
const StreamBuffer& hBuf = hBufs[0];
@@ -2059,25 +2076,38 @@
if (s != Status::OK) {
ALOGE("%s: stream %d import buffer failed!", __FUNCTION__, streamId);
cleanupInflightFences(importedFences, i - 1);
- return false;
+ hasError = true;
+ break;
}
h = makeFromAidl(hBuf.acquireFence);
if (!sHandleImporter.importFence(h, mBufferReqs[i].acquireFence)) {
ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
cleanupInflightFences(importedFences, i - 1);
native_handle_delete(h);
- return false;
+ hasError = true;
+ break;
}
native_handle_delete(h);
importedFences[i] = mBufferReqs[i].acquireFence;
} break;
default:
ALOGE("%s: Unknown StreamBuffersVal!", __FUNCTION__);
- return false;
+ hasError = true;
+ break;
+ }
+ if (hasError) {
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+ return true;
}
}
} else {
ALOGE("%s: requestStreamBuffers call failed!", __FUNCTION__);
+ mBufferReqs.clear();
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+ return true;
}
mPendingReturnBufferReqs = std::move(mBufferReqs);
@@ -2782,6 +2812,11 @@
if (res != 0) {
// For some webcam, the first few V4L2 frames might be malformed...
ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
+
+ ATRACE_BEGIN("Wait for BufferRequest done");
+ res = waitForBufferRequestDone(&req->buffers);
+ ATRACE_END();
+
lk.unlock();
Status st = parent->processCaptureRequestError(req);
if (st != Status::OK) {
@@ -2797,9 +2832,15 @@
ATRACE_END();
if (res != 0) {
+ // HAL buffer management buffer request can fail
ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
lk.unlock();
- return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+ Status st = parent->processCaptureRequestError(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
}
ALOGV("%s processing new request", __FUNCTION__);