Camera3: block until get an available buffer

Camera3Stream shouldn't error out when the max number of buffers are already
dequeued. It should block until next buffer returned from camera device.

Bug: 11595505
Change-Id: If65a70c29cb04219e14ded0744059c0ab783444b
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index 2257682..50a2c10 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,7 +34,8 @@
         Camera3Stream(id, type,
                 width, height, maxSize, format),
         mTotalBufferCount(0),
-        mDequeuedBufferCount(0),
+        mHandoutTotalBufferCount(0),
+        mHandoutOutputBufferCount(0),
         mFrameCount(0),
         mLastTimestamp(0) {
 
@@ -55,8 +56,8 @@
     nsecs_t signalTime = mCombinedFence->getSignalTime();
     ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
             " buffer signal time is %" PRId64,
-            __FUNCTION__, mId, mDequeuedBufferCount, signalTime);
-    if (mDequeuedBufferCount > 0 || signalTime == INT64_MAX) {
+            __FUNCTION__, mId, mHandoutTotalBufferCount, signalTime);
+    if (mHandoutTotalBufferCount > 0 || signalTime == INT64_MAX) {
         return true;
     }
     return false;
@@ -75,7 +76,7 @@
     lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
             mFrameCount, mLastTimestamp);
     lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
-            mTotalBufferCount, mDequeuedBufferCount);
+            mTotalBufferCount, mHandoutTotalBufferCount);
     write(fd, lines.string(), lines.size());
 }
 
@@ -104,6 +105,14 @@
     return mTotalBufferCount;
 }
 
+size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
+    return mHandoutOutputBufferCount;
+}
+
+size_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
+    return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
+}
+
 status_t Camera3IOStreamBase::disconnectLocked() {
     switch (mState) {
         case STATE_IN_RECONFIG:
@@ -117,9 +126,9 @@
             return -ENOTCONN;
     }
 
-    if (mDequeuedBufferCount > 0) {
+    if (mHandoutTotalBufferCount > 0) {
         ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
-                __FUNCTION__, mDequeuedBufferCount);
+                __FUNCTION__, mHandoutTotalBufferCount);
         return INVALID_OPERATION;
     }
 
@@ -130,7 +139,8 @@
                                               buffer_handle_t *handle,
                                               int acquireFence,
                                               int releaseFence,
-                                              camera3_buffer_status_t status) {
+                                              camera3_buffer_status_t status,
+                                              bool output) {
     /**
      * Note that all fences are now owned by HAL.
      */
@@ -144,7 +154,7 @@
     buffer.status = status;
 
     // Inform tracker about becoming busy
-    if (mDequeuedBufferCount == 0 && mState != STATE_IN_CONFIG &&
+    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
             mState != STATE_IN_RECONFIG) {
         /**
          * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
@@ -158,7 +168,11 @@
             statusTracker->markComponentActive(mStatusId);
         }
     }
-    mDequeuedBufferCount++;
+    mHandoutTotalBufferCount++;
+
+    if (output) {
+        mHandoutOutputBufferCount++;
+    }
 }
 
 status_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
@@ -172,7 +186,7 @@
 
     // Only limit dequeue amount when fully configured
     if (mState == STATE_CONFIGURED &&
-            mDequeuedBufferCount == camera3_stream::max_buffers) {
+            mHandoutTotalBufferCount == camera3_stream::max_buffers) {
         ALOGE("%s: Stream %d: Already dequeued maximum number of simultaneous"
                 " buffers (%d)", __FUNCTION__, mId,
                 camera3_stream::max_buffers);
@@ -190,7 +204,7 @@
                 __FUNCTION__, mId, mState);
         return INVALID_OPERATION;
     }
-    if (mDequeuedBufferCount == 0) {
+    if (mHandoutTotalBufferCount == 0) {
         ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
                 mId);
         return INVALID_OPERATION;
@@ -228,8 +242,12 @@
         mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
     }
 
-    mDequeuedBufferCount--;
-    if (mDequeuedBufferCount == 0 && mState != STATE_IN_CONFIG &&
+    if (output) {
+        mHandoutOutputBufferCount--;
+    }
+
+    mHandoutTotalBufferCount--;
+    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
             mState != STATE_IN_RECONFIG) {
         /**
          * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers