summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2012-09-12 10:42:10 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-09-12 17:57:53 -0700
commitbdde5f884eaf270ab4b806849f3122a46cd872ce (patch)
treebeacea0f676d48325e2d9ae6cb63b44debfc9474 /services
parent359cf1cac2a7851a59dfe4960a1a5992ac6fdb84 (diff)
downloadframeworks_av-bdde5f884eaf270ab4b806849f3122a46cd872ce.zip
frameworks_av-bdde5f884eaf270ab4b806849f3122a46cd872ce.tar.gz
frameworks_av-bdde5f884eaf270ab4b806849f3122a46cd872ce.tar.bz2
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
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/camera2/CaptureSequencer.cpp10
-rw-r--r--services/camera/libcameraservice/camera2/ZslProcessor.cpp64
-rw-r--r--services/camera/libcameraservice/camera2/ZslProcessor.h2
3 files changed, 52 insertions, 24 deletions
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<Camera2Client> &client) {
+ ALOGV("%s", __FUNCTION__);
status_t res;
sp<ZslProcessor> 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<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 @@ 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<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 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &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<Camera2Client> &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<Camera2Client> &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<CameraMetadata> mFrameList;
size_t mFrameListHead;