Camera2: Fix ZSL bugs.
The ZSL processor was discarding buffers too often, and waiting for
new buffers with mutexes held.
Also adds basic fallback to regular capture in case the ZSL queue
doesn't contain a suitable buffer.
Bug: 7147043
Change-Id: I5721267ef08dbc87ef9d8ec47f333db5f67e41c1
diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
index 2f8b7db..678f114 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
@@ -253,6 +253,7 @@
CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
sp<Camera2Client> &client) {
+ ALOGV("%s", __FUNCTION__);
status_t res;
sp<ZslProcessor> processor = mZslProcessor.promote();
if (processor == 0) {
@@ -271,7 +272,12 @@
return DONE;
}
// TODO: Actually select the right thing here.
- processor->pushToReprocess(mCaptureId);
+ res = processor->pushToReprocess(mCaptureId);
+ if (res != OK) {
+ ALOGW("%s: Camera %d: Failed to use ZSL queue, falling back to standard capture",
+ __FUNCTION__, client->getCameraId());
+ return STANDARD_START;
+ }
mTimeoutCount = kMaxTimeoutsForCaptureEnd;
return STANDARD_CAPTURE_WAIT;
@@ -279,11 +285,13 @@
CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
sp<Camera2Client> &client) {
+ ALOGV("%s", __FUNCTION__);
return DONE;
}
CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
sp<Camera2Client> &client) {
+ ALOGV("%s", __FUNCTION__);
return START;
}
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
index 0771872..58e820c 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
@@ -235,9 +235,19 @@
if (client == 0) return false;
if (mZslQueueTail != mZslQueueHead) {
+ CameraMetadata request;
+ size_t index = mZslQueueTail;
+ while (request.isEmpty() && index != mZslQueueHead) {
+ request = mZslQueue[index].frame;
+ index = (index + 1) % kZslBufferDepth;
+ }
+ if (request.isEmpty()) {
+ ALOGE("No request in ZSL queue to send!");
+ return BAD_VALUE;
+ }
buffer_handle_t *handle =
- &(mZslQueue[mZslQueueTail].buffer.mGraphicBuffer->handle);
- CameraMetadata request = mZslQueue[mZslQueueTail].frame;
+ &(mZslQueue[index].buffer.mGraphicBuffer->handle);
+
uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
res = request.update(ANDROID_REQUEST_TYPE,
&requestType, 1);
@@ -306,19 +316,25 @@
status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) {
ATRACE_CALL();
status_t res;
+
+ ALOGVV("Trying to get next buffer");
+ BufferItemConsumer::BufferItem item;
+ res = mZslConsumer->acquireBuffer(&item);
+ if (res != OK) {
+ if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
+ ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
+ "%s (%d)", __FUNCTION__,
+ client->getCameraId(), strerror(-res), res);
+ } else {
+ ALOGVV(" No buffer");
+ }
+ return res;
+ }
+
Mutex::Autolock l(mInputMutex);
if (mState == LOCKED) {
- BufferItemConsumer::BufferItem item;
- res = mZslConsumer->acquireBuffer(&item);
- if (res != OK) {
- if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
- ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
- "%s (%d)", __FUNCTION__,
- client->getCameraId(), strerror(-res), res);
- }
- return res;
- }
+ ALOGVV("In capture, discarding new ZSL buffers");
mZslConsumer->releaseBuffer(item);
return OK;
}
@@ -326,6 +342,7 @@
ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
+ ALOGVV("Releasing oldest buffer");
mZslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
mZslQueue.replaceAt(mZslQueueTail);
mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
@@ -333,20 +350,12 @@
ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
- res = mZslConsumer->acquireBuffer(&(queueHead.buffer));
- if (res != OK) {
- if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
- ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
- "%s (%d)", __FUNCTION__,
- client->getCameraId(), strerror(-res), res);
- }
- return res;
- }
+ queueHead.buffer = item;
queueHead.frame.release();
mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
- ALOGVV(" Added buffer, timestamp %lld", queueHead.buffer.mTimestamp);
+ ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
findMatchesLocked();
@@ -354,9 +363,20 @@
}
void ZslProcessor::findMatchesLocked() {
+ ALOGVV("Scanning");
for (size_t i = 0; i < mZslQueue.size(); i++) {
ZslPair &queueEntry = mZslQueue.editItemAt(i);
nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
+ IF_ALOGV() {
+ camera_metadata_entry_t entry;
+ nsecs_t frameTimestamp = 0;
+ if (!queueEntry.frame.isEmpty()) {
+ entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
+ frameTimestamp = entry.data.i64[0];
+ }
+ ALOGVV(" %d: b: %lld\tf: %lld", i,
+ bufferTimestamp, frameTimestamp );
+ }
if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
// Have buffer, no matching frame. Look for one
for (size_t j = 0; j < mFrameList.size(); j++) {
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.h b/services/camera/libcameraservice/camera2/ZslProcessor.h
index 74921a3..b60f61b 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.h
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.h
@@ -93,7 +93,7 @@
CameraMetadata frame;
};
- static const size_t kZslBufferDepth = 3;
+ static const size_t kZslBufferDepth = 4;
static const size_t kFrameListDepth = kZslBufferDepth * 2;
Vector<CameraMetadata> mFrameList;
size_t mFrameListHead;