From bdde5f884eaf270ab4b806849f3122a46cd872ce Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 12 Sep 2012 10:42:10 -0700 Subject: 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 --- .../libcameraservice/camera2/CaptureSequencer.cpp | 10 +++- .../libcameraservice/camera2/ZslProcessor.cpp | 64 ++++++++++++++-------- .../camera/libcameraservice/camera2/ZslProcessor.h | 2 +- 3 files changed, 52 insertions(+), 24 deletions(-) (limited to 'services') 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::manageStart( CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( sp &client) { + ALOGV("%s", __FUNCTION__); status_t res; sp processor = mZslProcessor.promote(); if (processor == 0) { @@ -271,7 +272,12 @@ CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( 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::manageZslStart( CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( sp &client) { + ALOGV("%s", __FUNCTION__); return DONE; } CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( sp &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 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { 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 @@ bool ZslProcessor::threadLoop() { status_t ZslProcessor::processNewZslBuffer(sp &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 @@ status_t ZslProcessor::processNewZslBuffer(sp &client) { 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 @@ status_t ZslProcessor::processNewZslBuffer(sp &client) { 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 @@ status_t ZslProcessor::processNewZslBuffer(sp &client) { } 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 @@ class ZslProcessor: CameraMetadata frame; }; - static const size_t kZslBufferDepth = 3; + static const size_t kZslBufferDepth = 4; static const size_t kFrameListDepth = kZslBufferDepth * 2; Vector mFrameList; size_t mFrameListHead; -- cgit v1.1