From 2274549ec18f63a285db871fa67abf42124d116e Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 17 Sep 2012 17:55:07 -0700 Subject: [PATCH] Camera2: ZSL: Do regular capture if AE is not satisfied. - Check the AE state of the selected ZSL buffer; if it's not reporting as CONVERGED or LOCKED, fall back to normal capture sequence - Add more debugging for the ZSL queue. Bug: 6910087 Change-Id: I77a4287580aa9ddbd58438477c40ce829555d0ca --- services/camera/libcameraservice/Camera2Client.cpp | 2 + .../libcameraservice/camera2/CaptureSequencer.cpp | 10 ++- .../libcameraservice/camera2/ZslProcessor.cpp | 78 +++++++++++++++++++--- .../camera/libcameraservice/camera2/ZslProcessor.h | 2 + 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index eb72412fe0..4fad83e759 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -345,6 +345,8 @@ status_t Camera2Client::dump(int fd, const Vector& args) { mFrameProcessor->dump(fd, args); + mZslProcessor->dump(fd, args); + result = " Device dump:\n"; write(fd, result.string(), result.size()); diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp index 981fdb41fa..eb9eb5b1c9 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp @@ -274,8 +274,14 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( // TODO: Actually select the right thing here. res = processor->pushToReprocess(mCaptureId); if (res != OK) { - ALOGW("%s: Camera %d: Failed to use ZSL queue, falling back to standard capture", - __FUNCTION__, client->getCameraId()); + if (res == NOT_ENOUGH_DATA) { + ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, " + "falling back to normal capture", __FUNCTION__, + client->getCameraId()); + } else { + ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)", + __FUNCTION__, client->getCameraId(), strerror(-res), res); + } return STANDARD_START; } diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp index f17b5d3417..8906cd74c2 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp @@ -87,12 +87,14 @@ void ZslProcessor::onFrameAvailable(int32_t frameId, CameraMetadata &frame) { void ZslProcessor::onBufferReleased(buffer_handle_t *handle) { Mutex::Autolock l(mInputMutex); - buffer_handle_t *expectedHandle = - &(mZslQueue[mZslQueueTail].buffer.mGraphicBuffer->handle); - - if (handle != expectedHandle) { - ALOGE("%s: Expected buffer %p, got buffer %p", - __FUNCTION__, expectedHandle, handle); + // Verify that the buffer is in our queue + size_t i = 0; + for (; i < mZslQueue.size(); i++) { + if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break; + } + if (i == mZslQueue.size()) { + ALOGW("%s: Released buffer %p not found in queue", + __FUNCTION__, handle); } mState = RUNNING; @@ -232,7 +234,12 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { status_t res; sp client = mClient.promote(); - if (client == 0) return false; + if (client == 0) return INVALID_OPERATION; + + IF_ALOGV() { + dumpZslQueue(-1); + } + if (mZslQueueTail != mZslQueueHead) { CameraMetadata request; @@ -242,9 +249,26 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { index = (index + 1) % kZslBufferDepth; } if (request.isEmpty()) { - ALOGE("No request in ZSL queue to send!"); + ALOGV("%s: ZSL queue has no valid frames to send yet.", + __FUNCTION__); + return NOT_ENOUGH_DATA; + } + // Verify that the frame is reasonable for reprocessing + + camera_metadata_entry_t entry; + entry = request.find(ANDROID_CONTROL_AE_STATE); + if (entry.count == 0) { + ALOGE("%s: ZSL queue frame has no AE state field!", + __FUNCTION__); return BAD_VALUE; } + if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED && + entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) { + ALOGV("%s: ZSL queue frame AE state is %d, need full capture", + __FUNCTION__, entry.data.u8[0]); + return NOT_ENOUGH_DATA; + } + buffer_handle_t *handle = &(mZslQueue[index].buffer.mGraphicBuffer->handle); @@ -282,13 +306,15 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { mState = LOCKED; } else { - ALOGE("%s: Nothing to push", __FUNCTION__); - return BAD_VALUE; + ALOGV("%s: No ZSL buffers yet", __FUNCTION__); + return NOT_ENOUGH_DATA; } return OK; } void ZslProcessor::dump(int fd, const Vector& args) const { + Mutex::Autolock l(mInputMutex); + dumpZslQueue(fd); } bool ZslProcessor::threadLoop() { @@ -413,5 +439,37 @@ void ZslProcessor::findMatchesLocked() { } } +void ZslProcessor::dumpZslQueue(int fd) const { + String8 header("ZSL queue contents:"); + String8 indent(" "); + ALOGV("%s", header.string()); + if (fd != -1) { + header = indent + header + "\n"; + write(fd, header.string(), header.size()); + } + for (size_t i = 0; i < mZslQueue.size(); i++) { + const ZslPair &queueEntry = mZslQueue[i]; + nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; + camera_metadata_ro_entry_t entry; + nsecs_t frameTimestamp = 0; + int frameAeState = -1; + if (!queueEntry.frame.isEmpty()) { + entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); + if (entry.count > 0) frameTimestamp = entry.data.i64[0]; + entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE); + if (entry.count > 0) frameAeState = entry.data.u8[0]; + } + String8 result = + String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i, + bufferTimestamp, frameTimestamp, frameAeState); + ALOGV("%s", result.string()); + if (fd != -1) { + result = indent + result + "\n"; + write(fd, result.string(), result.size()); + } + + } +} + }; // namespace camera2 }; // namespace android diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.h b/services/camera/libcameraservice/camera2/ZslProcessor.h index b60f61b6d8..268f4f5cfd 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.h +++ b/services/camera/libcameraservice/camera2/ZslProcessor.h @@ -110,6 +110,8 @@ class ZslProcessor: // Match up entries from frame list to buffers in ZSL queue void findMatchesLocked(); + + void dumpZslQueue(int id) const; }; -- 2.11.0