camera2: skip capture result after clearZslQueue

After ZSL queue is cleared, don't add capture result to ZSL queue
if its corresponding buffer has been cleared.

Bug: 17185356
Change-Id: Iddac39ab09b2560e2ce9390895927217c1736d5a
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index 2d31275..227b169 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -44,6 +44,7 @@
     sp<Camera2Client> client,
     wp<CaptureSequencer> sequencer):
         Thread(false),
+        mLatestClearedBufferTimestamp(0),
         mState(RUNNING),
         mClient(client),
         mSequencer(sequencer),
@@ -107,7 +108,6 @@
         ALOGE("%s: metadata doesn't have timestamp, skip this result", __FUNCTION__);
         return;
     }
-    (void)timestamp;
 
     entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
     if (entry.count == 0) {
@@ -120,6 +120,9 @@
 
     if (mState != RUNNING) return;
 
+    // Corresponding buffer has been cleared. No need to push into mFrameList
+    if (timestamp <= mLatestClearedBufferTimestamp) return;
+
     mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
     mFrameListHead = (mFrameListHead + 1) % mFrameListDepth;
 }
@@ -392,7 +395,7 @@
     if (mZslStream != 0) {
         // clear result metadata list first.
         clearZslResultQueueLocked();
-        return mZslStream->clearInputRingBuffer();
+        return mZslStream->clearInputRingBuffer(&mLatestClearedBufferTimestamp);
     }
     return OK;
 }
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
index daa352b..8894364 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
@@ -82,6 +82,7 @@
 
   private:
     static const nsecs_t kWaitDuration = 10000000; // 10 ms
+    nsecs_t mLatestClearedBufferTimestamp;
 
     enum {
         RUNNING,
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
index 92bf81b..81330ea 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
@@ -315,20 +315,24 @@
     return OK;
 }
 
-status_t Camera3ZslStream::clearInputRingBuffer() {
+status_t Camera3ZslStream::clearInputRingBuffer(nsecs_t* latestTimestamp) {
     Mutex::Autolock l(mLock);
 
-    return clearInputRingBufferLocked();
+    return clearInputRingBufferLocked(latestTimestamp);
 }
 
-status_t Camera3ZslStream::clearInputRingBufferLocked() {
+status_t Camera3ZslStream::clearInputRingBufferLocked(nsecs_t* latestTimestamp) {
+
+    if (latestTimestamp) {
+        *latestTimestamp = mProducer->getLatestTimestamp();
+    }
     mInputBufferQueue.clear();
 
     return mProducer->clear();
 }
 
 status_t Camera3ZslStream::disconnectLocked() {
-    clearInputRingBufferLocked();
+    clearInputRingBufferLocked(NULL);
 
     return Camera3OutputStream::disconnectLocked();
 }
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.h b/services/camera/libcameraservice/device3/Camera3ZslStream.h
index d89c38d..5323a49 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.h
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.h
@@ -59,8 +59,10 @@
 
     /**
      * Clears the buffers that can be used by enqueueInputBufferByTimestamp
+     * latestTimestamp will be filled with the largest timestamp of buffers
+     * being cleared, 0 if there is no buffer being clear.
      */
-    status_t clearInputRingBuffer();
+    status_t clearInputRingBuffer(nsecs_t* latestTimestamp);
 
   protected:
 
@@ -100,7 +102,7 @@
     // Disconnet the Camera3ZslStream specific bufferQueues.
     virtual status_t disconnectLocked();
 
-    status_t clearInputRingBufferLocked();
+    status_t clearInputRingBufferLocked(nsecs_t* latestTimestamp);
 
 }; // class Camera3ZslStream
 
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index e4ec5fd..f8562ec 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -41,7 +41,8 @@
         uint32_t consumerUsage,
         int bufferCount) :
     ConsumerBase(consumer),
-    mBufferCount(bufferCount)
+    mBufferCount(bufferCount),
+    mLatestTimestamp(0)
 {
     mConsumer->setConsumerUsageBits(consumerUsage);
     mConsumer->setMaxAcquiredBufferCount(bufferCount);
@@ -152,6 +153,14 @@
     return OK;
 }
 
+nsecs_t RingBufferConsumer::getLatestTimestamp() {
+    Mutex::Autolock _l(mMutex);
+    if (mBufferItemList.size() == 0) {
+        return 0;
+    }
+    return mLatestTimestamp;
+}
+
 void RingBufferConsumer::pinBufferLocked(const BufferItem& item) {
     List<RingBufferItem>::iterator it, end;
 
@@ -302,6 +311,13 @@
                 item.mTimestamp,
                 mBufferItemList.size(), mBufferCount);
 
+        if (item.mTimestamp < mLatestTimestamp) {
+            BI_LOGE("Timestamp  decreases from %" PRId64 " to %" PRId64,
+                    mLatestTimestamp, item.mTimestamp);
+        }
+
+        mLatestTimestamp = item.mTimestamp;
+
         item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer;
     } // end of mMutex lock
 
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h
index a03736d..da97a11 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.h
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h
@@ -159,6 +159,9 @@
     // Release all the non-pinned buffers in the ring buffer
     status_t clear();
 
+    // Return 0 if RingBuffer is empty, otherwise return timestamp of latest buffer.
+    nsecs_t getLatestTimestamp();
+
   private:
 
     // Override ConsumerBase::onFrameAvailable
@@ -180,6 +183,9 @@
     // List of acquired buffers in our ring buffer
     List<RingBufferItem>       mBufferItemList;
     const int                  mBufferCount;
+
+    // Timestamp of latest buffer
+    nsecs_t mLatestTimestamp;
 };
 
 } // namespace android