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
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index eb72412..4fad83e 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -345,6 +345,8 @@
 
     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 981fdb4..eb9eb5b 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
@@ -274,8 +274,14 @@
     // 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 f17b5d3..8906cd7 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
@@ -87,12 +87,14 @@
 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 res;
     sp<Camera2Client> 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 @@
             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 @@
 
         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<String16>& args) const {
+    Mutex::Autolock l(mInputMutex);
+    dumpZslQueue(fd);
 }
 
 bool ZslProcessor::threadLoop() {
@@ -413,5 +439,37 @@
     }
 }
 
+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 b60f61b..268f4f5 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.h
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.h
@@ -110,6 +110,8 @@
 
     // Match up entries from frame list to buffers in ZSL queue
     void findMatchesLocked();
+
+    void dumpZslQueue(int id) const;
 };