camera3: Fix zsl buffers released-while-in-use race condition

Bug: 9007356
Change-Id: I0ced31020410978c549d408b2815f925e9c9ffcf
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor3.cpp b/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
index e2c120c..56525a3 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor3.cpp
@@ -402,6 +402,8 @@
                 minTimestamp = frameTimestamp;
                 idx = j;
             }
+
+            ALOGVV("%s: Saw timestamp %lld", __FUNCTION__, frameTimestamp);
         }
     }
 
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index 2fa78a4..cd39bad 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -101,12 +101,6 @@
 
     } // end scope of mMutex autolock
 
-    if (pinnedBuffer != 0) {
-        BI_LOGV("Pinned buffer frame %lld, timestamp %lld",
-                pinnedBuffer->getBufferItem().mFrameNumber,
-                pinnedBuffer->getBufferItem().mTimestamp);
-    }
-
     if (waitForFence) {
         status_t err = pinnedBuffer->getBufferItem().mFence->waitForever(
                 "RingBufferConsumer::pinSelectedBuffer");
@@ -172,6 +166,9 @@
     if (it == end) {
         BI_LOGE("Failed to pin buffer (timestamp %lld, framenumber %lld)",
                  item.mTimestamp, item.mFrameNumber);
+    } else {
+        BI_LOGV("Pinned buffer (frame %lld, timestamp %lld)",
+                item.mFrameNumber, item.mTimestamp);
     }
 }
 
@@ -182,7 +179,7 @@
 
     it = mBufferItemList.begin();
     end = mBufferItemList.end();
-    accIt = it;
+    accIt = end;
 
     if (it == end) {
         /**
@@ -197,12 +194,17 @@
 
     for (; it != end; ++it) {
         RingBufferItem& find = *it;
-        if (find.mTimestamp < accIt->mTimestamp && find.mPinCount <= 0) {
-            accIt = it;
+
+        if (find.mPinCount > 0) {
+            if (pinnedFrames != NULL) {
+                ++(*pinnedFrames);
+            }
+            // Filter out pinned frame when searching for buffer to release
+            continue;
         }
 
-        if (find.mPinCount > 0 && pinnedFrames != NULL) {
-            ++(*pinnedFrames);
+        if (find.mTimestamp < accIt->mTimestamp || accIt == end) {
+            accIt = it;
         }
     }
 
@@ -323,7 +325,11 @@
     }
 
     if (it == end) {
-        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld",
+        // This should never happen. If it happens, we have a bug.
+        BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld)",
+                 item.mTimestamp, item.mFrameNumber);
+    } else {
+        BI_LOGV("Unpinned buffer (timestamp %lld, framenumber %lld)",
                  item.mTimestamp, item.mFrameNumber);
     }
 }