Merge "CameraSource: Wait before dropping a frame" into nyc-dev
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 3d00d30..64c3044 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -244,12 +244,15 @@
      * The following variables are used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
      */
     static const size_t kConsumerBufferCount = 8;
+    static const nsecs_t kMemoryBaseAvailableTimeoutNs = 200000000; // 200ms
     // Consumer and producer of the buffer queue between this class and camera.
     sp<BufferItemConsumer> mVideoBufferConsumer;
     sp<IGraphicBufferProducer> mVideoBufferProducer;
     // Memory used to send the buffers to encoder, where sp<IMemory> stores VideoNativeMetadata.
     sp<IMemoryHeap> mMemoryHeapBase;
     List<sp<IMemory>> mMemoryBases;
+    // The condition that will be signaled when there is an entry available in mMemoryBases.
+    Condition mMemoryBaseAvailableCond;
     // A mapping from ANativeWindowBuffer sent to encoder to BufferItem received from camera.
     // This is protected by mLock.
     KeyedVector<ANativeWindowBuffer*, BufferItem> mReceivedBufferItemMap;
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 64d4302..4f88d9c 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -919,6 +919,7 @@
         mReceivedBufferItemMap.removeItemsAt(index);
         mVideoBufferConsumer->releaseBuffer(buffer);
         mMemoryBases.push_back(frame);
+        mMemoryBaseAvailableCond.signal();
     } else if (mCameraRecordingProxy != NULL) {
         mCameraRecordingProxy->releaseRecordingFrame(frame);
     } else if (mCamera != NULL) {
@@ -1122,10 +1123,13 @@
         return;
     }
 
-    if (mMemoryBases.empty()) {
-        ALOGW("%s: No available memory base. Dropping a recording frame.", __FUNCTION__);
-        mVideoBufferConsumer->releaseBuffer(buffer);
-        return;
+    while (mMemoryBases.empty()) {
+        if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) ==
+                TIMED_OUT) {
+            ALOGW("Waiting on an available memory base timed out. Dropping a recording frame.");
+            mVideoBufferConsumer->releaseBuffer(buffer);
+            return;
+        }
     }
 
     ++mNumFramesReceived;